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