1 // SPDX-License-Identifier: GPL-2.0 2 /* 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 <linux/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 }; 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 stream_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, void __user *data) 344 { 345 int rc; 346 347 if (no == MTIOCTOP) { 348 struct mtop op; 349 350 if (copy_from_user(&op, 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 } 374 rc = tape_mtop(device, op.mt_op, op.mt_count); 375 376 if (op.mt_op == MTWEOF && rc == 0) { 377 if (op.mt_count > device->required_tapemarks) 378 device->required_tapemarks = 0; 379 else 380 device->required_tapemarks -= op.mt_count; 381 } 382 return rc; 383 } 384 if (no == MTIOCPOS) { 385 /* MTIOCPOS: query the tape position. */ 386 struct mtpos pos; 387 388 rc = tape_mtop(device, MTTELL, 1); 389 if (rc < 0) 390 return rc; 391 pos.mt_blkno = rc; 392 return put_user_mtpos(data, &pos); 393 } 394 if (no == MTIOCGET) { 395 /* MTIOCGET: query the tape drive status. */ 396 struct mtget get; 397 398 memset(&get, 0, sizeof(get)); 399 get.mt_type = MT_ISUNKNOWN; 400 get.mt_resid = 0 /* device->devstat.rescnt */; 401 get.mt_dsreg = 402 ((device->char_data.block_size << MT_ST_BLKSIZE_SHIFT) 403 & MT_ST_BLKSIZE_MASK); 404 /* FIXME: mt_gstat, mt_erreg, mt_fileno */ 405 get.mt_gstat = 0; 406 get.mt_erreg = 0; 407 get.mt_fileno = 0; 408 get.mt_gstat = device->tape_generic_status; 409 410 if (device->medium_state == MS_LOADED) { 411 rc = tape_mtop(device, MTTELL, 1); 412 413 if (rc < 0) 414 return rc; 415 416 if (rc == 0) 417 get.mt_gstat |= GMT_BOT(~0); 418 419 get.mt_blkno = rc; 420 } 421 422 return put_user_mtget(data, &get); 423 } 424 /* Try the discipline ioctl function. */ 425 if (device->discipline->ioctl_fn == NULL) 426 return -EINVAL; 427 return device->discipline->ioctl_fn(device, no, (unsigned long)data); 428 } 429 430 static long 431 tapechar_ioctl(struct file *filp, unsigned int no, unsigned long data) 432 { 433 struct tape_device *device; 434 long rc; 435 436 DBF_EVENT(6, "TCHAR:ioct\n"); 437 438 device = (struct tape_device *) filp->private_data; 439 mutex_lock(&device->mutex); 440 rc = __tapechar_ioctl(device, no, (void __user *)data); 441 mutex_unlock(&device->mutex); 442 return rc; 443 } 444 445 #ifdef CONFIG_COMPAT 446 static long 447 tapechar_compat_ioctl(struct file *filp, unsigned int no, unsigned long data) 448 { 449 struct tape_device *device = filp->private_data; 450 long rc; 451 452 if (no == MTIOCPOS32) 453 no = MTIOCPOS; 454 else if (no == MTIOCGET32) 455 no = MTIOCGET; 456 457 mutex_lock(&device->mutex); 458 rc = __tapechar_ioctl(device, no, compat_ptr(data)); 459 mutex_unlock(&device->mutex); 460 return rc; 461 } 462 #endif /* CONFIG_COMPAT */ 463 464 /* 465 * Initialize character device frontend. 466 */ 467 int 468 tapechar_init (void) 469 { 470 dev_t dev; 471 472 if (alloc_chrdev_region(&dev, 0, 256, "tape") != 0) 473 return -1; 474 475 tapechar_major = MAJOR(dev); 476 477 return 0; 478 } 479 480 /* 481 * cleanup 482 */ 483 void 484 tapechar_exit(void) 485 { 486 unregister_chrdev_region(MKDEV(tapechar_major, 0), 256); 487 } 488