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