1 /* 2 * drivers/s390/char/tape_char.c 3 * character device frontend for tape device driver 4 * 5 * S390 and zSeries version 6 * Copyright IBM Corp. 2001,2006 7 * Author(s): Carsten Otte <cotte@de.ibm.com> 8 * Michael Holzheu <holzheu@de.ibm.com> 9 * Tuan Ngo-Anh <ngoanh@de.ibm.com> 10 * Martin Schwidefsky <schwidefsky@de.ibm.com> 11 */ 12 13 #define KMSG_COMPONENT "tape" 14 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 15 16 #include <linux/module.h> 17 #include <linux/types.h> 18 #include <linux/proc_fs.h> 19 #include <linux/mtio.h> 20 #include <linux/compat.h> 21 22 #include <asm/uaccess.h> 23 24 #define TAPE_DBF_AREA tape_core_dbf 25 26 #include "tape.h" 27 #include "tape_std.h" 28 #include "tape_class.h" 29 30 #define TAPECHAR_MAJOR 0 /* get dynamic major */ 31 32 /* 33 * file operation structure for tape character frontend 34 */ 35 static ssize_t tapechar_read(struct file *, char __user *, size_t, loff_t *); 36 static ssize_t tapechar_write(struct file *, const char __user *, size_t, loff_t *); 37 static int tapechar_open(struct inode *,struct file *); 38 static int tapechar_release(struct inode *,struct file *); 39 static long tapechar_ioctl(struct file *, unsigned int, unsigned long); 40 #ifdef CONFIG_COMPAT 41 static long tapechar_compat_ioctl(struct file *, unsigned int, unsigned long); 42 #endif 43 44 static const struct file_operations tape_fops = 45 { 46 .owner = THIS_MODULE, 47 .read = tapechar_read, 48 .write = tapechar_write, 49 .unlocked_ioctl = tapechar_ioctl, 50 #ifdef CONFIG_COMPAT 51 .compat_ioctl = tapechar_compat_ioctl, 52 #endif 53 .open = tapechar_open, 54 .release = tapechar_release, 55 .llseek = no_llseek, 56 }; 57 58 static int tapechar_major = TAPECHAR_MAJOR; 59 60 /* 61 * This function is called for every new tapedevice 62 */ 63 int 64 tapechar_setup_device(struct tape_device * device) 65 { 66 char device_name[20]; 67 68 sprintf(device_name, "ntibm%i", device->first_minor / 2); 69 device->nt = register_tape_dev( 70 &device->cdev->dev, 71 MKDEV(tapechar_major, device->first_minor), 72 &tape_fops, 73 device_name, 74 "non-rewinding" 75 ); 76 device_name[0] = 'r'; 77 device->rt = register_tape_dev( 78 &device->cdev->dev, 79 MKDEV(tapechar_major, device->first_minor + 1), 80 &tape_fops, 81 device_name, 82 "rewinding" 83 ); 84 85 return 0; 86 } 87 88 void 89 tapechar_cleanup_device(struct tape_device *device) 90 { 91 unregister_tape_dev(&device->cdev->dev, device->rt); 92 device->rt = NULL; 93 unregister_tape_dev(&device->cdev->dev, device->nt); 94 device->nt = NULL; 95 } 96 97 static int 98 tapechar_check_idalbuffer(struct tape_device *device, size_t block_size) 99 { 100 struct idal_buffer *new; 101 102 if (device->char_data.idal_buf != NULL && 103 device->char_data.idal_buf->size == block_size) 104 return 0; 105 106 if (block_size > MAX_BLOCKSIZE) { 107 DBF_EVENT(3, "Invalid blocksize (%zd > %d)\n", 108 block_size, MAX_BLOCKSIZE); 109 return -EINVAL; 110 } 111 112 /* The current idal buffer is not correct. Allocate a new one. */ 113 new = idal_buffer_alloc(block_size, 0); 114 if (IS_ERR(new)) 115 return -ENOMEM; 116 117 if (device->char_data.idal_buf != NULL) 118 idal_buffer_free(device->char_data.idal_buf); 119 120 device->char_data.idal_buf = new; 121 122 return 0; 123 } 124 125 /* 126 * Tape device read function 127 */ 128 static ssize_t 129 tapechar_read(struct file *filp, char __user *data, size_t count, loff_t *ppos) 130 { 131 struct tape_device *device; 132 struct tape_request *request; 133 size_t block_size; 134 int rc; 135 136 DBF_EVENT(6, "TCHAR:read\n"); 137 device = (struct tape_device *) filp->private_data; 138 139 /* 140 * If the tape isn't terminated yet, do it now. And since we then 141 * are at the end of the tape there wouldn't be anything to read 142 * anyways. So we return immediatly. 143 */ 144 if(device->required_tapemarks) { 145 return tape_std_terminate_write(device); 146 } 147 148 /* Find out block size to use */ 149 if (device->char_data.block_size != 0) { 150 if (count < device->char_data.block_size) { 151 DBF_EVENT(3, "TCHAR:read smaller than block " 152 "size was requested\n"); 153 return -EINVAL; 154 } 155 block_size = device->char_data.block_size; 156 } else { 157 block_size = count; 158 } 159 160 rc = tapechar_check_idalbuffer(device, block_size); 161 if (rc) 162 return rc; 163 164 #ifdef CONFIG_S390_TAPE_BLOCK 165 /* Changes position. */ 166 device->blk_data.medium_changed = 1; 167 #endif 168 169 DBF_EVENT(6, "TCHAR:nbytes: %lx\n", block_size); 170 /* Let the discipline build the ccw chain. */ 171 request = device->discipline->read_block(device, block_size); 172 if (IS_ERR(request)) 173 return PTR_ERR(request); 174 /* Execute it. */ 175 rc = tape_do_io(device, request); 176 if (rc == 0) { 177 rc = block_size - request->rescnt; 178 DBF_EVENT(6, "TCHAR:rbytes: %x\n", rc); 179 /* Copy data from idal buffer to user space. */ 180 if (idal_buffer_to_user(device->char_data.idal_buf, 181 data, rc) != 0) 182 rc = -EFAULT; 183 } 184 tape_free_request(request); 185 return rc; 186 } 187 188 /* 189 * Tape device write function 190 */ 191 static ssize_t 192 tapechar_write(struct file *filp, const char __user *data, size_t count, loff_t *ppos) 193 { 194 struct tape_device *device; 195 struct tape_request *request; 196 size_t block_size; 197 size_t written; 198 int nblocks; 199 int i, rc; 200 201 DBF_EVENT(6, "TCHAR:write\n"); 202 device = (struct tape_device *) filp->private_data; 203 /* Find out block size and number of blocks */ 204 if (device->char_data.block_size != 0) { 205 if (count < device->char_data.block_size) { 206 DBF_EVENT(3, "TCHAR:write smaller than block " 207 "size was requested\n"); 208 return -EINVAL; 209 } 210 block_size = device->char_data.block_size; 211 nblocks = count / block_size; 212 } else { 213 block_size = count; 214 nblocks = 1; 215 } 216 217 rc = tapechar_check_idalbuffer(device, block_size); 218 if (rc) 219 return rc; 220 221 #ifdef CONFIG_S390_TAPE_BLOCK 222 /* Changes position. */ 223 device->blk_data.medium_changed = 1; 224 #endif 225 226 DBF_EVENT(6,"TCHAR:nbytes: %lx\n", block_size); 227 DBF_EVENT(6, "TCHAR:nblocks: %x\n", nblocks); 228 /* Let the discipline build the ccw chain. */ 229 request = device->discipline->write_block(device, block_size); 230 if (IS_ERR(request)) 231 return PTR_ERR(request); 232 rc = 0; 233 written = 0; 234 for (i = 0; i < nblocks; i++) { 235 /* Copy data from user space to idal buffer. */ 236 if (idal_buffer_from_user(device->char_data.idal_buf, 237 data, block_size)) { 238 rc = -EFAULT; 239 break; 240 } 241 rc = tape_do_io(device, request); 242 if (rc) 243 break; 244 DBF_EVENT(6, "TCHAR:wbytes: %lx\n", 245 block_size - request->rescnt); 246 written += block_size - request->rescnt; 247 if (request->rescnt != 0) 248 break; 249 data += block_size; 250 } 251 tape_free_request(request); 252 if (rc == -ENOSPC) { 253 /* 254 * Ok, the device has no more space. It has NOT written 255 * the block. 256 */ 257 if (device->discipline->process_eov) 258 device->discipline->process_eov(device); 259 if (written > 0) 260 rc = 0; 261 262 } 263 264 /* 265 * After doing a write we always need two tapemarks to correctly 266 * terminate the tape (one to terminate the file, the second to 267 * flag the end of recorded data. 268 * Since process_eov positions the tape in front of the written 269 * tapemark it doesn't hurt to write two marks again. 270 */ 271 if (!rc) 272 device->required_tapemarks = 2; 273 274 return rc ? rc : written; 275 } 276 277 /* 278 * Character frontend tape device open function. 279 */ 280 static int 281 tapechar_open (struct inode *inode, struct file *filp) 282 { 283 struct tape_device *device; 284 int minor, rc; 285 286 DBF_EVENT(6, "TCHAR:open: %i:%i\n", 287 imajor(filp->f_path.dentry->d_inode), 288 iminor(filp->f_path.dentry->d_inode)); 289 290 if (imajor(filp->f_path.dentry->d_inode) != tapechar_major) 291 return -ENODEV; 292 293 minor = iminor(filp->f_path.dentry->d_inode); 294 device = tape_find_device(minor / TAPE_MINORS_PER_DEV); 295 if (IS_ERR(device)) { 296 DBF_EVENT(3, "TCHAR:open: tape_find_device() failed\n"); 297 return PTR_ERR(device); 298 } 299 300 rc = tape_open(device); 301 if (rc == 0) { 302 filp->private_data = device; 303 nonseekable_open(inode, filp); 304 } else 305 tape_put_device(device); 306 307 return rc; 308 } 309 310 /* 311 * Character frontend tape device release function. 312 */ 313 314 static int 315 tapechar_release(struct inode *inode, struct file *filp) 316 { 317 struct tape_device *device; 318 319 DBF_EVENT(6, "TCHAR:release: %x\n", iminor(inode)); 320 device = (struct tape_device *) filp->private_data; 321 322 /* 323 * If this is the rewinding tape minor then rewind. In that case we 324 * write all required tapemarks. Otherwise only one to terminate the 325 * file. 326 */ 327 if ((iminor(inode) & 1) != 0) { 328 if (device->required_tapemarks) 329 tape_std_terminate_write(device); 330 tape_mtop(device, MTREW, 1); 331 } else { 332 if (device->required_tapemarks > 1) { 333 if (tape_mtop(device, MTWEOF, 1) == 0) 334 device->required_tapemarks--; 335 } 336 } 337 338 if (device->char_data.idal_buf != NULL) { 339 idal_buffer_free(device->char_data.idal_buf); 340 device->char_data.idal_buf = NULL; 341 } 342 tape_release(device); 343 filp->private_data = NULL; 344 tape_put_device(device); 345 346 return 0; 347 } 348 349 /* 350 * Tape device io controls. 351 */ 352 static int 353 __tapechar_ioctl(struct tape_device *device, 354 unsigned int no, unsigned long data) 355 { 356 int rc; 357 358 if (no == MTIOCTOP) { 359 struct mtop op; 360 361 if (copy_from_user(&op, (char __user *) data, sizeof(op)) != 0) 362 return -EFAULT; 363 if (op.mt_count < 0) 364 return -EINVAL; 365 366 /* 367 * Operations that change tape position should write final 368 * tapemarks. 369 */ 370 switch (op.mt_op) { 371 case MTFSF: 372 case MTBSF: 373 case MTFSR: 374 case MTBSR: 375 case MTREW: 376 case MTOFFL: 377 case MTEOM: 378 case MTRETEN: 379 case MTBSFM: 380 case MTFSFM: 381 case MTSEEK: 382 #ifdef CONFIG_S390_TAPE_BLOCK 383 device->blk_data.medium_changed = 1; 384 #endif 385 if (device->required_tapemarks) 386 tape_std_terminate_write(device); 387 default: 388 ; 389 } 390 rc = tape_mtop(device, op.mt_op, op.mt_count); 391 392 if (op.mt_op == MTWEOF && rc == 0) { 393 if (op.mt_count > device->required_tapemarks) 394 device->required_tapemarks = 0; 395 else 396 device->required_tapemarks -= op.mt_count; 397 } 398 return rc; 399 } 400 if (no == MTIOCPOS) { 401 /* MTIOCPOS: query the tape position. */ 402 struct mtpos pos; 403 404 rc = tape_mtop(device, MTTELL, 1); 405 if (rc < 0) 406 return rc; 407 pos.mt_blkno = rc; 408 if (copy_to_user((char __user *) data, &pos, sizeof(pos)) != 0) 409 return -EFAULT; 410 return 0; 411 } 412 if (no == MTIOCGET) { 413 /* MTIOCGET: query the tape drive status. */ 414 struct mtget get; 415 416 memset(&get, 0, sizeof(get)); 417 get.mt_type = MT_ISUNKNOWN; 418 get.mt_resid = 0 /* device->devstat.rescnt */; 419 get.mt_dsreg = device->tape_state; 420 /* FIXME: mt_gstat, mt_erreg, mt_fileno */ 421 get.mt_gstat = 0; 422 get.mt_erreg = 0; 423 get.mt_fileno = 0; 424 get.mt_gstat = device->tape_generic_status; 425 426 if (device->medium_state == MS_LOADED) { 427 rc = tape_mtop(device, MTTELL, 1); 428 429 if (rc < 0) 430 return rc; 431 432 if (rc == 0) 433 get.mt_gstat |= GMT_BOT(~0); 434 435 get.mt_blkno = rc; 436 } 437 438 if (copy_to_user((char __user *) data, &get, sizeof(get)) != 0) 439 return -EFAULT; 440 441 return 0; 442 } 443 /* Try the discipline ioctl function. */ 444 if (device->discipline->ioctl_fn == NULL) 445 return -EINVAL; 446 return device->discipline->ioctl_fn(device, no, data); 447 } 448 449 static long 450 tapechar_ioctl(struct file *filp, unsigned int no, unsigned long data) 451 { 452 struct tape_device *device; 453 long rc; 454 455 DBF_EVENT(6, "TCHAR:ioct\n"); 456 457 device = (struct tape_device *) filp->private_data; 458 mutex_lock(&device->mutex); 459 rc = __tapechar_ioctl(device, no, data); 460 mutex_unlock(&device->mutex); 461 return rc; 462 } 463 464 #ifdef CONFIG_COMPAT 465 static long 466 tapechar_compat_ioctl(struct file *filp, unsigned int no, unsigned long data) 467 { 468 struct tape_device *device = filp->private_data; 469 int rval = -ENOIOCTLCMD; 470 unsigned long argp; 471 472 /* The 'arg' argument of any ioctl function may only be used for 473 * pointers because of the compat pointer conversion. 474 * Consider this when adding new ioctls. 475 */ 476 argp = (unsigned long) compat_ptr(data); 477 if (device->discipline->ioctl_fn) { 478 mutex_lock(&device->mutex); 479 rval = device->discipline->ioctl_fn(device, no, argp); 480 mutex_unlock(&device->mutex); 481 if (rval == -EINVAL) 482 rval = -ENOIOCTLCMD; 483 } 484 485 return rval; 486 } 487 #endif /* CONFIG_COMPAT */ 488 489 /* 490 * Initialize character device frontend. 491 */ 492 int 493 tapechar_init (void) 494 { 495 dev_t dev; 496 497 if (alloc_chrdev_region(&dev, 0, 256, "tape") != 0) 498 return -1; 499 500 tapechar_major = MAJOR(dev); 501 502 return 0; 503 } 504 505 /* 506 * cleanup 507 */ 508 void 509 tapechar_exit(void) 510 { 511 unregister_chrdev_region(MKDEV(tapechar_major, 0), 256); 512 } 513