tree: https://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux-next.git 20210817-add-disk-error-handling-next head: 3d00c210d7fd616243af9cf41829f4a56f116ba8 commit: 7692839b26192b737a64c87970b6589e6a909d38 [2/89] st: do not allocate a gendisk config: i386-randconfig-a011-20210816 (attached as .config) compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project d2b574a4dea5b718e4386bf2e26af0126e5978ce) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux-next.git/commit/?id=7692839b26192b737a64c87970b6589e6a909d38 git remote add mcgrof-next https://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux-next.git git fetch --no-tags mcgrof-next 20210817-add-disk-error-handling-next git checkout 7692839b26192b737a64c87970b6589e6a909d38 # save the attached .config to linux build tree mkdir build_dir COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross O=build_dir ARCH=i386 SHELL=/bin/bash If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All errors (new ones prefixed by >>): >> drivers/scsi/st.c:3830:40: error: no member named 'disk' in 'struct scsi_tape' retval = scsi_ioctl(STp->device, STp->disk, file->f_mode, cmd_in, p); ~~~ ^ 1 error generated. vim +3830 drivers/scsi/st.c 8038e6456a3e6f Kai Makisara 2016-02-09 3348 8038e6456a3e6f Kai Makisara 2016-02-09 3349 ^1da177e4c3f41 Linus Torvalds 2005-04-16 3350 /* Partition the tape into two partitions if size > 0 or one partition if ^1da177e4c3f41 Linus Torvalds 2005-04-16 3351 size == 0. ^1da177e4c3f41 Linus Torvalds 2005-04-16 3352 ^1da177e4c3f41 Linus Torvalds 2005-04-16 3353 The block descriptors are read and written because Sony SDT-7000 does not ^1da177e4c3f41 Linus Torvalds 2005-04-16 3354 work without this (suggestion from Michael Schaefer ). ^1da177e4c3f41 Linus Torvalds 2005-04-16 3355 ^1da177e4c3f41 Linus Torvalds 2005-04-16 3356 My HP C1533A drive returns only one partition size field. This is used to ^1da177e4c3f41 Linus Torvalds 2005-04-16 3357 set the size of partition 1. There is no size field for the default partition. ^1da177e4c3f41 Linus Torvalds 2005-04-16 3358 Michael Schaefer's Sony SDT-7000 returns two descriptors and the second is ^1da177e4c3f41 Linus Torvalds 2005-04-16 3359 used to set the size of partition 1 (this is what the SCSI-3 standard specifies). ^1da177e4c3f41 Linus Torvalds 2005-04-16 3360 The following algorithm is used to accommodate both drives: if the number of ^1da177e4c3f41 Linus Torvalds 2005-04-16 3361 partition size fields is greater than the maximum number of additional partitions ^1da177e4c3f41 Linus Torvalds 2005-04-16 3362 in the mode page, the second field is used. Otherwise the first field is used. ^1da177e4c3f41 Linus Torvalds 2005-04-16 3363 ^1da177e4c3f41 Linus Torvalds 2005-04-16 3364 For Seagate DDS drives the page length must be 8 when no partitions is defined ^1da177e4c3f41 Linus Torvalds 2005-04-16 3365 and 10 when 1 partition is defined (information from Eric Lee Green). This is ^1da177e4c3f41 Linus Torvalds 2005-04-16 3366 is acceptable also to some other old drives and enforced if the first partition ^1da177e4c3f41 Linus Torvalds 2005-04-16 3367 size field is used for the first additional partition size. 8038e6456a3e6f Kai Makisara 2016-02-09 3368 8038e6456a3e6f Kai Makisara 2016-02-09 3369 For drives that advertize SCSI-3 or newer, use the SSC-3 methods. ^1da177e4c3f41 Linus Torvalds 2005-04-16 3370 */ ^1da177e4c3f41 Linus Torvalds 2005-04-16 3371 static int partition_tape(struct scsi_tape *STp, int size) ^1da177e4c3f41 Linus Torvalds 2005-04-16 3372 { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3373 int result; 8038e6456a3e6f Kai Makisara 2016-02-09 3374 int target_partition; 8038e6456a3e6f Kai Makisara 2016-02-09 3375 bool scsi3 = STp->device->scsi_level >= SCSI_3, needs_format = false; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3376 int pgo, psd_cnt, psdo; 8038e6456a3e6f Kai Makisara 2016-02-09 3377 int psum = PP_MSK_PSUM_MB, units = 0; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3378 unsigned char *bp; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3379 ^1da177e4c3f41 Linus Torvalds 2005-04-16 3380 result = read_mode_page(STp, PART_PAGE, 0); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3381 if (result) { b30d8bca5b525b Hannes Reinecke 2014-06-25 3382 DEBC_printk(STp, "Can't read partition mode page.\n"); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3383 return result; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3384 } 8038e6456a3e6f Kai Makisara 2016-02-09 3385 target_partition = 1; 8038e6456a3e6f Kai Makisara 2016-02-09 3386 if (size < 0) { 8038e6456a3e6f Kai Makisara 2016-02-09 3387 target_partition = 0; 8038e6456a3e6f Kai Makisara 2016-02-09 3388 size = -size; 8038e6456a3e6f Kai Makisara 2016-02-09 3389 } 8038e6456a3e6f Kai Makisara 2016-02-09 3390 ^1da177e4c3f41 Linus Torvalds 2005-04-16 3391 /* The mode page is in the buffer. Let's modify it and write it. */ ^1da177e4c3f41 Linus Torvalds 2005-04-16 3392 bp = (STp->buffer)->b_data; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3393 pgo = MODE_HEADER_LENGTH + bp[MH_OFF_BDESCS_LENGTH]; b30d8bca5b525b Hannes Reinecke 2014-06-25 3394 DEBC_printk(STp, "Partition page length is %d bytes.\n", b30d8bca5b525b Hannes Reinecke 2014-06-25 3395 bp[pgo + MP_OFF_PAGE_LENGTH] + 2); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3396 ^1da177e4c3f41 Linus Torvalds 2005-04-16 3397 psd_cnt = (bp[pgo + MP_OFF_PAGE_LENGTH] + 2 - PART_PAGE_FIXED_LENGTH) / 2; 8038e6456a3e6f Kai Makisara 2016-02-09 3398 8038e6456a3e6f Kai Makisara 2016-02-09 3399 if (scsi3) { 8038e6456a3e6f Kai Makisara 2016-02-09 3400 needs_format = (bp[pgo + PP_OFF_FLAGS] & PP_MSK_POFM) != 0; 8038e6456a3e6f Kai Makisara 2016-02-09 3401 if (needs_format && size == 0) { 8038e6456a3e6f Kai Makisara 2016-02-09 3402 /* No need to write the mode page when clearing 8038e6456a3e6f Kai Makisara 2016-02-09 3403 * partitioning 8038e6456a3e6f Kai Makisara 2016-02-09 3404 */ 8038e6456a3e6f Kai Makisara 2016-02-09 3405 DEBC_printk(STp, "Formatting tape with one partition.\n"); 8038e6456a3e6f Kai Makisara 2016-02-09 3406 result = format_medium(STp, 0); 8038e6456a3e6f Kai Makisara 2016-02-09 3407 goto out; 8038e6456a3e6f Kai Makisara 2016-02-09 3408 } 8038e6456a3e6f Kai Makisara 2016-02-09 3409 if (needs_format) /* Leave the old value for HP DATs claiming SCSI_3 */ 8038e6456a3e6f Kai Makisara 2016-02-09 3410 psd_cnt = 2; 8038e6456a3e6f Kai Makisara 2016-02-09 3411 if ((bp[pgo + PP_OFF_FLAGS] & PP_MSK_PSUM_UNITS) == PP_MSK_PSUM_UNITS) { 8038e6456a3e6f Kai Makisara 2016-02-09 3412 /* Use units scaling for large partitions if the device 8038e6456a3e6f Kai Makisara 2016-02-09 3413 * suggests it and no precision lost. Required for IBM 8038e6456a3e6f Kai Makisara 2016-02-09 3414 * TS1140/50 drives that don't support MB units. 8038e6456a3e6f Kai Makisara 2016-02-09 3415 */ 8038e6456a3e6f Kai Makisara 2016-02-09 3416 if (size >= 1000 && (size % 1000) == 0) { 8038e6456a3e6f Kai Makisara 2016-02-09 3417 size /= 1000; 8038e6456a3e6f Kai Makisara 2016-02-09 3418 psum = PP_MSK_PSUM_UNITS; 8038e6456a3e6f Kai Makisara 2016-02-09 3419 units = 9; /* GB */ 8038e6456a3e6f Kai Makisara 2016-02-09 3420 } 8038e6456a3e6f Kai Makisara 2016-02-09 3421 } 8038e6456a3e6f Kai Makisara 2016-02-09 3422 /* Try it anyway if too large to specify in MB */ 8038e6456a3e6f Kai Makisara 2016-02-09 3423 if (psum == PP_MSK_PSUM_MB && size >= 65534) { 8038e6456a3e6f Kai Makisara 2016-02-09 3424 size /= 1000; 8038e6456a3e6f Kai Makisara 2016-02-09 3425 psum = PP_MSK_PSUM_UNITS; 8038e6456a3e6f Kai Makisara 2016-02-09 3426 units = 9; /* GB */ 8038e6456a3e6f Kai Makisara 2016-02-09 3427 } 8038e6456a3e6f Kai Makisara 2016-02-09 3428 } 8038e6456a3e6f Kai Makisara 2016-02-09 3429 8038e6456a3e6f Kai Makisara 2016-02-09 3430 if (size >= 65535 || /* Does not fit into two bytes */ 8038e6456a3e6f Kai Makisara 2016-02-09 3431 (target_partition == 0 && psd_cnt < 2)) { 8038e6456a3e6f Kai Makisara 2016-02-09 3432 result = -EINVAL; 8038e6456a3e6f Kai Makisara 2016-02-09 3433 goto out; 8038e6456a3e6f Kai Makisara 2016-02-09 3434 } 8038e6456a3e6f Kai Makisara 2016-02-09 3435 ^1da177e4c3f41 Linus Torvalds 2005-04-16 3436 psdo = pgo + PART_PAGE_FIXED_LENGTH; 8038e6456a3e6f Kai Makisara 2016-02-09 3437 /* The second condition is for HP DDS which use only one partition size 8038e6456a3e6f Kai Makisara 2016-02-09 3438 * descriptor 8038e6456a3e6f Kai Makisara 2016-02-09 3439 */ 8038e6456a3e6f Kai Makisara 2016-02-09 3440 if (target_partition > 0 && 8038e6456a3e6f Kai Makisara 2016-02-09 3441 (psd_cnt > bp[pgo + PP_OFF_MAX_ADD_PARTS] || 8038e6456a3e6f Kai Makisara 2016-02-09 3442 bp[pgo + PP_OFF_MAX_ADD_PARTS] != 1)) { 8038e6456a3e6f Kai Makisara 2016-02-09 3443 bp[psdo] = bp[psdo + 1] = 0xff; /* Rest to partition 0 */ ^1da177e4c3f41 Linus Torvalds 2005-04-16 3444 psdo += 2; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3445 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 3446 memset(bp + psdo, 0, bp[pgo + PP_OFF_NBR_ADD_PARTS] * 2); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3447 b30d8bca5b525b Hannes Reinecke 2014-06-25 3448 DEBC_printk(STp, "psd_cnt %d, max.parts %d, nbr_parts %d\n", ^1da177e4c3f41 Linus Torvalds 2005-04-16 3449 psd_cnt, bp[pgo + PP_OFF_MAX_ADD_PARTS], b30d8bca5b525b Hannes Reinecke 2014-06-25 3450 bp[pgo + PP_OFF_NBR_ADD_PARTS]); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3451 8038e6456a3e6f Kai Makisara 2016-02-09 3452 if (size == 0) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3453 bp[pgo + PP_OFF_NBR_ADD_PARTS] = 0; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3454 if (psd_cnt <= bp[pgo + PP_OFF_MAX_ADD_PARTS]) ^1da177e4c3f41 Linus Torvalds 2005-04-16 3455 bp[pgo + MP_OFF_PAGE_LENGTH] = 6; b30d8bca5b525b Hannes Reinecke 2014-06-25 3456 DEBC_printk(STp, "Formatting tape with one partition.\n"); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3457 } else { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3458 bp[psdo] = (size >> 8) & 0xff; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3459 bp[psdo + 1] = size & 0xff; 8038e6456a3e6f Kai Makisara 2016-02-09 3460 if (target_partition == 0) 8038e6456a3e6f Kai Makisara 2016-02-09 3461 bp[psdo + 2] = bp[psdo + 3] = 0xff; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3462 bp[pgo + 3] = 1; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3463 if (bp[pgo + MP_OFF_PAGE_LENGTH] < 8) ^1da177e4c3f41 Linus Torvalds 2005-04-16 3464 bp[pgo + MP_OFF_PAGE_LENGTH] = 8; 8038e6456a3e6f Kai Makisara 2016-02-09 3465 DEBC_printk(STp, 8038e6456a3e6f Kai Makisara 2016-02-09 3466 "Formatting tape with two partitions (%i = %d MB).\n", 8038e6456a3e6f Kai Makisara 2016-02-09 3467 target_partition, units > 0 ? size * 1000 : size); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3468 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 3469 bp[pgo + PP_OFF_PART_UNITS] = 0; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3470 bp[pgo + PP_OFF_RESERVED] = 0; 8038e6456a3e6f Kai Makisara 2016-02-09 3471 if (size != 1 || units != 0) { 8038e6456a3e6f Kai Makisara 2016-02-09 3472 bp[pgo + PP_OFF_FLAGS] = PP_BIT_IDP | psum | 8038e6456a3e6f Kai Makisara 2016-02-09 3473 (bp[pgo + PP_OFF_FLAGS] & 0x07); 8038e6456a3e6f Kai Makisara 2016-02-09 3474 bp[pgo + PP_OFF_PART_UNITS] = units; 8038e6456a3e6f Kai Makisara 2016-02-09 3475 } else 8038e6456a3e6f Kai Makisara 2016-02-09 3476 bp[pgo + PP_OFF_FLAGS] = PP_BIT_FDP | 8038e6456a3e6f Kai Makisara 2016-02-09 3477 (bp[pgo + PP_OFF_FLAGS] & 0x1f); 8038e6456a3e6f Kai Makisara 2016-02-09 3478 bp[pgo + MP_OFF_PAGE_LENGTH] = 6 + psd_cnt * 2; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3479 ^1da177e4c3f41 Linus Torvalds 2005-04-16 3480 result = write_mode_page(STp, PART_PAGE, 1); 8038e6456a3e6f Kai Makisara 2016-02-09 3481 8038e6456a3e6f Kai Makisara 2016-02-09 3482 if (!result && needs_format) 8038e6456a3e6f Kai Makisara 2016-02-09 3483 result = format_medium(STp, 1); 8038e6456a3e6f Kai Makisara 2016-02-09 3484 ^1da177e4c3f41 Linus Torvalds 2005-04-16 3485 if (result) { b30d8bca5b525b Hannes Reinecke 2014-06-25 3486 st_printk(KERN_INFO, STp, "Partitioning of tape failed.\n"); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3487 result = (-EIO); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3488 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 3489 8038e6456a3e6f Kai Makisara 2016-02-09 3490 out: ^1da177e4c3f41 Linus Torvalds 2005-04-16 3491 return result; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3492 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 3493 ^1da177e4c3f41 Linus Torvalds 2005-04-16 3494 ^1da177e4c3f41 Linus Torvalds 2005-04-16 3495 ^1da177e4c3f41 Linus Torvalds 2005-04-16 3496 /* The ioctl command */ dba7688fc9037c Christoph Hellwig 2021-07-24 3497 static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg) ^1da177e4c3f41 Linus Torvalds 2005-04-16 3498 { dba7688fc9037c Christoph Hellwig 2021-07-24 3499 void __user *p = (void __user *)arg; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3500 int i, cmd_nr, cmd_type, bt; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3501 int retval = 0; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3502 unsigned int blk; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3503 struct scsi_tape *STp = file->private_data; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3504 struct st_modedef *STm; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3505 struct st_partstat *STps; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3506 28f85009e0cf6a Matthias Kaehlcke 2007-07-29 3507 if (mutex_lock_interruptible(&STp->lock)) ^1da177e4c3f41 Linus Torvalds 2005-04-16 3508 return -ERESTARTSYS; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3509 ^1da177e4c3f41 Linus Torvalds 2005-04-16 3510 DEB( ^1da177e4c3f41 Linus Torvalds 2005-04-16 3511 if (debugging && !STp->in_use) { b30d8bca5b525b Hannes Reinecke 2014-06-25 3512 st_printk(ST_DEB_MSG, STp, "Incorrect device.\n"); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3513 retval = (-EIO); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3514 goto out; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3515 } ) /* end DEB */ ^1da177e4c3f41 Linus Torvalds 2005-04-16 3516 ^1da177e4c3f41 Linus Torvalds 2005-04-16 3517 STm = &(STp->modes[STp->current_mode]); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3518 STps = &(STp->ps[STp->partition]); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3519 ^1da177e4c3f41 Linus Torvalds 2005-04-16 3520 /* ^1da177e4c3f41 Linus Torvalds 2005-04-16 3521 * If we are in the middle of error recovery, don't let anyone ^1da177e4c3f41 Linus Torvalds 2005-04-16 3522 * else try and use this device. Also, if error recovery fails, it ^1da177e4c3f41 Linus Torvalds 2005-04-16 3523 * may try and take the device offline, in which case all further ^1da177e4c3f41 Linus Torvalds 2005-04-16 3524 * access to the device is prohibited. ^1da177e4c3f41 Linus Torvalds 2005-04-16 3525 */ 906d15fbd23c12 Christoph Hellwig 2014-10-11 3526 retval = scsi_ioctl_block_when_processing_errors(STp->device, cmd_in, 83ff6fe8580a7c Al Viro 2008-03-02 3527 file->f_flags & O_NDELAY); 906d15fbd23c12 Christoph Hellwig 2014-10-11 3528 if (retval) ^1da177e4c3f41 Linus Torvalds 2005-04-16 3529 goto out; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3530 ^1da177e4c3f41 Linus Torvalds 2005-04-16 3531 cmd_type = _IOC_TYPE(cmd_in); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3532 cmd_nr = _IOC_NR(cmd_in); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3533 ^1da177e4c3f41 Linus Torvalds 2005-04-16 3534 if (cmd_type == _IOC_TYPE(MTIOCTOP) && cmd_nr == _IOC_NR(MTIOCTOP)) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3535 struct mtop mtc; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3536 ^1da177e4c3f41 Linus Torvalds 2005-04-16 3537 if (_IOC_SIZE(cmd_in) != sizeof(mtc)) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3538 retval = (-EINVAL); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3539 goto out; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3540 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 3541 ^1da177e4c3f41 Linus Torvalds 2005-04-16 3542 i = copy_from_user(&mtc, p, sizeof(struct mtop)); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3543 if (i) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3544 retval = (-EFAULT); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3545 goto out; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3546 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 3547 ^1da177e4c3f41 Linus Torvalds 2005-04-16 3548 if (mtc.mt_op == MTSETDRVBUFFER && !capable(CAP_SYS_ADMIN)) { b30d8bca5b525b Hannes Reinecke 2014-06-25 3549 st_printk(KERN_WARNING, STp, b30d8bca5b525b Hannes Reinecke 2014-06-25 3550 "MTSETDRVBUFFER only allowed for root.\n"); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3551 retval = (-EPERM); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3552 goto out; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3553 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 3554 if (!STm->defined && ^1da177e4c3f41 Linus Torvalds 2005-04-16 3555 (mtc.mt_op != MTSETDRVBUFFER && ^1da177e4c3f41 Linus Torvalds 2005-04-16 3556 (mtc.mt_count & MT_ST_OPTIONS) == 0)) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3557 retval = (-ENXIO); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3558 goto out; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3559 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 3560 ^1da177e4c3f41 Linus Torvalds 2005-04-16 3561 if (!STp->pos_unknown) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3562 ^1da177e4c3f41 Linus Torvalds 2005-04-16 3563 if (STps->eof == ST_FM_HIT) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3564 if (mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM || ^1da177e4c3f41 Linus Torvalds 2005-04-16 3565 mtc.mt_op == MTEOM) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3566 mtc.mt_count -= 1; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3567 if (STps->drv_file >= 0) ^1da177e4c3f41 Linus Torvalds 2005-04-16 3568 STps->drv_file += 1; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3569 } else if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3570 mtc.mt_count += 1; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3571 if (STps->drv_file >= 0) ^1da177e4c3f41 Linus Torvalds 2005-04-16 3572 STps->drv_file += 1; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3573 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 3574 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 3575 ^1da177e4c3f41 Linus Torvalds 2005-04-16 3576 if (mtc.mt_op == MTSEEK) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3577 /* Old position must be restored if partition will be ^1da177e4c3f41 Linus Torvalds 2005-04-16 3578 changed */ ^1da177e4c3f41 Linus Torvalds 2005-04-16 3579 i = !STp->can_partitions || ^1da177e4c3f41 Linus Torvalds 2005-04-16 3580 (STp->new_partition != STp->partition); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3581 } else { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3582 i = mtc.mt_op == MTREW || mtc.mt_op == MTOFFL || ^1da177e4c3f41 Linus Torvalds 2005-04-16 3583 mtc.mt_op == MTRETEN || mtc.mt_op == MTEOM || ^1da177e4c3f41 Linus Torvalds 2005-04-16 3584 mtc.mt_op == MTLOCK || mtc.mt_op == MTLOAD || ^1da177e4c3f41 Linus Torvalds 2005-04-16 3585 mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM || ^1da177e4c3f41 Linus Torvalds 2005-04-16 3586 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM || ^1da177e4c3f41 Linus Torvalds 2005-04-16 3587 mtc.mt_op == MTCOMPRESSION; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3588 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 3589 i = flush_buffer(STp, i); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3590 if (i < 0) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3591 retval = i; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3592 goto out; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3593 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 3594 if (STps->rw == ST_WRITING && ^1da177e4c3f41 Linus Torvalds 2005-04-16 3595 (mtc.mt_op == MTREW || mtc.mt_op == MTOFFL || ^1da177e4c3f41 Linus Torvalds 2005-04-16 3596 mtc.mt_op == MTSEEK || ^1da177e4c3f41 Linus Torvalds 2005-04-16 3597 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM)) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3598 i = st_int_ioctl(STp, MTWEOF, 1); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3599 if (i < 0) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3600 retval = i; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3601 goto out; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3602 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 3603 if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM) ^1da177e4c3f41 Linus Torvalds 2005-04-16 3604 mtc.mt_count++; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3605 STps->rw = ST_IDLE; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3606 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 3607 ^1da177e4c3f41 Linus Torvalds 2005-04-16 3608 } else { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3609 /* ^1da177e4c3f41 Linus Torvalds 2005-04-16 3610 * If there was a bus reset, block further access ^1da177e4c3f41 Linus Torvalds 2005-04-16 3611 * to this device. If the user wants to rewind the tape, ^1da177e4c3f41 Linus Torvalds 2005-04-16 3612 * then reset the flag and allow access again. ^1da177e4c3f41 Linus Torvalds 2005-04-16 3613 */ ^1da177e4c3f41 Linus Torvalds 2005-04-16 3614 if (mtc.mt_op != MTREW && ^1da177e4c3f41 Linus Torvalds 2005-04-16 3615 mtc.mt_op != MTOFFL && ^1da177e4c3f41 Linus Torvalds 2005-04-16 3616 mtc.mt_op != MTRETEN && ^1da177e4c3f41 Linus Torvalds 2005-04-16 3617 mtc.mt_op != MTERASE && ^1da177e4c3f41 Linus Torvalds 2005-04-16 3618 mtc.mt_op != MTSEEK && ^1da177e4c3f41 Linus Torvalds 2005-04-16 3619 mtc.mt_op != MTEOM) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3620 retval = (-EIO); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3621 goto out; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3622 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 3623 reset_state(STp); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3624 /* remove this when the midlevel properly clears was_reset */ ^1da177e4c3f41 Linus Torvalds 2005-04-16 3625 STp->device->was_reset = 0; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3626 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 3627 ^1da177e4c3f41 Linus Torvalds 2005-04-16 3628 if (mtc.mt_op != MTNOP && mtc.mt_op != MTSETBLK && ^1da177e4c3f41 Linus Torvalds 2005-04-16 3629 mtc.mt_op != MTSETDENSITY && mtc.mt_op != MTWSM && ^1da177e4c3f41 Linus Torvalds 2005-04-16 3630 mtc.mt_op != MTSETDRVBUFFER && mtc.mt_op != MTSETPART) ^1da177e4c3f41 Linus Torvalds 2005-04-16 3631 STps->rw = ST_IDLE; /* Prevent automatic WEOF and fsf */ ^1da177e4c3f41 Linus Torvalds 2005-04-16 3632 ^1da177e4c3f41 Linus Torvalds 2005-04-16 3633 if (mtc.mt_op == MTOFFL && STp->door_locked != ST_UNLOCKED) ^1da177e4c3f41 Linus Torvalds 2005-04-16 3634 do_door_lock(STp, 0); /* Ignore result! */ ^1da177e4c3f41 Linus Torvalds 2005-04-16 3635 ^1da177e4c3f41 Linus Torvalds 2005-04-16 3636 if (mtc.mt_op == MTSETDRVBUFFER && ^1da177e4c3f41 Linus Torvalds 2005-04-16 3637 (mtc.mt_count & MT_ST_OPTIONS) != 0) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3638 retval = st_set_options(STp, mtc.mt_count); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3639 goto out; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3640 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 3641 ^1da177e4c3f41 Linus Torvalds 2005-04-16 3642 if (mtc.mt_op == MTSETPART) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3643 if (!STp->can_partitions || ^1da177e4c3f41 Linus Torvalds 2005-04-16 3644 mtc.mt_count < 0 || mtc.mt_count >= ST_NBR_PARTITIONS) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3645 retval = (-EINVAL); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3646 goto out; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3647 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 3648 if (mtc.mt_count >= STp->nbr_partitions && ^1da177e4c3f41 Linus Torvalds 2005-04-16 3649 (STp->nbr_partitions = nbr_partitions(STp)) < 0) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3650 retval = (-EIO); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3651 goto out; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3652 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 3653 if (mtc.mt_count >= STp->nbr_partitions) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3654 retval = (-EINVAL); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3655 goto out; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3656 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 3657 STp->new_partition = mtc.mt_count; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3658 retval = 0; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3659 goto out; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3660 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 3661 ^1da177e4c3f41 Linus Torvalds 2005-04-16 3662 if (mtc.mt_op == MTMKPART) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3663 if (!STp->can_partitions) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3664 retval = (-EINVAL); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3665 goto out; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3666 } 8038e6456a3e6f Kai Makisara 2016-02-09 3667 i = do_load_unload(STp, file, 1); 8038e6456a3e6f Kai Makisara 2016-02-09 3668 if (i < 0) { 8038e6456a3e6f Kai Makisara 2016-02-09 3669 retval = i; 8038e6456a3e6f Kai Makisara 2016-02-09 3670 goto out; 8038e6456a3e6f Kai Makisara 2016-02-09 3671 } 8038e6456a3e6f Kai Makisara 2016-02-09 3672 i = partition_tape(STp, mtc.mt_count); 8038e6456a3e6f Kai Makisara 2016-02-09 3673 if (i < 0) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3674 retval = i; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3675 goto out; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3676 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 3677 for (i = 0; i < ST_NBR_PARTITIONS; i++) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3678 STp->ps[i].rw = ST_IDLE; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3679 STp->ps[i].at_sm = 0; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3680 STp->ps[i].last_block_valid = 0; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3681 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 3682 STp->partition = STp->new_partition = 0; 8038e6456a3e6f Kai Makisara 2016-02-09 3683 STp->nbr_partitions = mtc.mt_count != 0 ? 2 : 1; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3684 STps->drv_block = STps->drv_file = 0; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3685 retval = 0; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3686 goto out; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3687 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 3688 ^1da177e4c3f41 Linus Torvalds 2005-04-16 3689 if (mtc.mt_op == MTSEEK) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3690 i = set_location(STp, mtc.mt_count, STp->new_partition, 0); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3691 if (!STp->can_partitions) ^1da177e4c3f41 Linus Torvalds 2005-04-16 3692 STp->ps[0].rw = ST_IDLE; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3693 retval = i; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3694 goto out; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3695 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 3696 ^1da177e4c3f41 Linus Torvalds 2005-04-16 3697 if (mtc.mt_op == MTUNLOAD || mtc.mt_op == MTOFFL) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3698 retval = do_load_unload(STp, file, 0); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3699 goto out; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3700 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 3701 ^1da177e4c3f41 Linus Torvalds 2005-04-16 3702 if (mtc.mt_op == MTLOAD) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3703 retval = do_load_unload(STp, file, max(1, mtc.mt_count)); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3704 goto out; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3705 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 3706 ^1da177e4c3f41 Linus Torvalds 2005-04-16 3707 if (mtc.mt_op == MTLOCK || mtc.mt_op == MTUNLOCK) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3708 retval = do_door_lock(STp, (mtc.mt_op == MTLOCK)); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3709 goto out; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3710 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 3711 ^1da177e4c3f41 Linus Torvalds 2005-04-16 3712 if (STp->can_partitions && STp->ready == ST_READY && ^1da177e4c3f41 Linus Torvalds 2005-04-16 3713 (i = switch_partition(STp)) < 0) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3714 retval = i; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3715 goto out; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3716 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 3717 ^1da177e4c3f41 Linus Torvalds 2005-04-16 3718 if (mtc.mt_op == MTCOMPRESSION) ^1da177e4c3f41 Linus Torvalds 2005-04-16 3719 retval = st_compression(STp, (mtc.mt_count & 1)); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3720 else ^1da177e4c3f41 Linus Torvalds 2005-04-16 3721 retval = st_int_ioctl(STp, mtc.mt_op, mtc.mt_count); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3722 goto out; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3723 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 3724 if (!STm->defined) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3725 retval = (-ENXIO); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3726 goto out; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3727 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 3728 ^1da177e4c3f41 Linus Torvalds 2005-04-16 3729 if ((i = flush_buffer(STp, 0)) < 0) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3730 retval = i; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3731 goto out; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3732 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 3733 if (STp->can_partitions && ^1da177e4c3f41 Linus Torvalds 2005-04-16 3734 (i = switch_partition(STp)) < 0) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3735 retval = i; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3736 goto out; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3737 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 3738 ^1da177e4c3f41 Linus Torvalds 2005-04-16 3739 if (cmd_type == _IOC_TYPE(MTIOCGET) && cmd_nr == _IOC_NR(MTIOCGET)) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3740 struct mtget mt_status; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3741 ^1da177e4c3f41 Linus Torvalds 2005-04-16 3742 if (_IOC_SIZE(cmd_in) != sizeof(struct mtget)) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3743 retval = (-EINVAL); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3744 goto out; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3745 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 3746 ^1da177e4c3f41 Linus Torvalds 2005-04-16 3747 mt_status.mt_type = STp->tape_type; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3748 mt_status.mt_dsreg = ^1da177e4c3f41 Linus Torvalds 2005-04-16 3749 ((STp->block_size << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK) | ^1da177e4c3f41 Linus Torvalds 2005-04-16 3750 ((STp->density << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3751 mt_status.mt_blkno = STps->drv_block; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3752 mt_status.mt_fileno = STps->drv_file; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3753 if (STp->block_size != 0) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3754 if (STps->rw == ST_WRITING) ^1da177e4c3f41 Linus Torvalds 2005-04-16 3755 mt_status.mt_blkno += ^1da177e4c3f41 Linus Torvalds 2005-04-16 3756 (STp->buffer)->buffer_bytes / STp->block_size; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3757 else if (STps->rw == ST_READING) ^1da177e4c3f41 Linus Torvalds 2005-04-16 3758 mt_status.mt_blkno -= ^1da177e4c3f41 Linus Torvalds 2005-04-16 3759 ((STp->buffer)->buffer_bytes + ^1da177e4c3f41 Linus Torvalds 2005-04-16 3760 STp->block_size - 1) / STp->block_size; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3761 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 3762 ^1da177e4c3f41 Linus Torvalds 2005-04-16 3763 mt_status.mt_gstat = 0; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3764 if (STp->drv_write_prot) ^1da177e4c3f41 Linus Torvalds 2005-04-16 3765 mt_status.mt_gstat |= GMT_WR_PROT(0xffffffff); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3766 if (mt_status.mt_blkno == 0) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3767 if (mt_status.mt_fileno == 0) ^1da177e4c3f41 Linus Torvalds 2005-04-16 3768 mt_status.mt_gstat |= GMT_BOT(0xffffffff); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3769 else ^1da177e4c3f41 Linus Torvalds 2005-04-16 3770 mt_status.mt_gstat |= GMT_EOF(0xffffffff); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3771 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 3772 mt_status.mt_erreg = (STp->recover_reg << MT_ST_SOFTERR_SHIFT); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3773 mt_status.mt_resid = STp->partition; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3774 if (STps->eof == ST_EOM_OK || STps->eof == ST_EOM_ERROR) ^1da177e4c3f41 Linus Torvalds 2005-04-16 3775 mt_status.mt_gstat |= GMT_EOT(0xffffffff); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3776 else if (STps->eof >= ST_EOM_OK) ^1da177e4c3f41 Linus Torvalds 2005-04-16 3777 mt_status.mt_gstat |= GMT_EOD(0xffffffff); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3778 if (STp->density == 1) ^1da177e4c3f41 Linus Torvalds 2005-04-16 3779 mt_status.mt_gstat |= GMT_D_800(0xffffffff); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3780 else if (STp->density == 2) ^1da177e4c3f41 Linus Torvalds 2005-04-16 3781 mt_status.mt_gstat |= GMT_D_1600(0xffffffff); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3782 else if (STp->density == 3) ^1da177e4c3f41 Linus Torvalds 2005-04-16 3783 mt_status.mt_gstat |= GMT_D_6250(0xffffffff); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3784 if (STp->ready == ST_READY) ^1da177e4c3f41 Linus Torvalds 2005-04-16 3785 mt_status.mt_gstat |= GMT_ONLINE(0xffffffff); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3786 if (STp->ready == ST_NO_TAPE) ^1da177e4c3f41 Linus Torvalds 2005-04-16 3787 mt_status.mt_gstat |= GMT_DR_OPEN(0xffffffff); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3788 if (STps->at_sm) ^1da177e4c3f41 Linus Torvalds 2005-04-16 3789 mt_status.mt_gstat |= GMT_SM(0xffffffff); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3790 if (STm->do_async_writes || ^1da177e4c3f41 Linus Torvalds 2005-04-16 3791 (STm->do_buffer_writes && STp->block_size != 0) || ^1da177e4c3f41 Linus Torvalds 2005-04-16 3792 STp->drv_buffer != 0) ^1da177e4c3f41 Linus Torvalds 2005-04-16 3793 mt_status.mt_gstat |= GMT_IM_REP_EN(0xffffffff); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3794 if (STp->cleaning_req) ^1da177e4c3f41 Linus Torvalds 2005-04-16 3795 mt_status.mt_gstat |= GMT_CLN(0xffffffff); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3796 1207045da5a7c9 Arnd Bergmann 2018-09-07 3797 retval = put_user_mtget(p, &mt_status); 1207045da5a7c9 Arnd Bergmann 2018-09-07 3798 if (retval) ^1da177e4c3f41 Linus Torvalds 2005-04-16 3799 goto out; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3800 ^1da177e4c3f41 Linus Torvalds 2005-04-16 3801 STp->recover_reg = 0; /* Clear after read */ ^1da177e4c3f41 Linus Torvalds 2005-04-16 3802 goto out; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3803 } /* End of MTIOCGET */ ^1da177e4c3f41 Linus Torvalds 2005-04-16 3804 if (cmd_type == _IOC_TYPE(MTIOCPOS) && cmd_nr == _IOC_NR(MTIOCPOS)) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3805 struct mtpos mt_pos; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3806 if (_IOC_SIZE(cmd_in) != sizeof(struct mtpos)) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3807 retval = (-EINVAL); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3808 goto out; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3809 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 3810 if ((i = get_location(STp, &blk, &bt, 0)) < 0) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3811 retval = i; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3812 goto out; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3813 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 3814 mt_pos.mt_blkno = blk; 1207045da5a7c9 Arnd Bergmann 2018-09-07 3815 retval = put_user_mtpos(p, &mt_pos); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3816 goto out; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3817 } 28f85009e0cf6a Matthias Kaehlcke 2007-07-29 3818 mutex_unlock(&STp->lock); d320a9551e394c Arnd Bergmann 2019-03-15 3819 dba7688fc9037c Christoph Hellwig 2021-07-24 3820 switch (cmd_in) { dba7688fc9037c Christoph Hellwig 2021-07-24 3821 case SG_IO: dba7688fc9037c Christoph Hellwig 2021-07-24 3822 case SCSI_IOCTL_SEND_COMMAND: dba7688fc9037c Christoph Hellwig 2021-07-24 3823 case CDROM_SEND_PACKET: dba7688fc9037c Christoph Hellwig 2021-07-24 3824 if (!capable(CAP_SYS_RAWIO)) dba7688fc9037c Christoph Hellwig 2021-07-24 3825 return -EPERM; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3826 default: ^1da177e4c3f41 Linus Torvalds 2005-04-16 3827 break; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3828 } dba7688fc9037c Christoph Hellwig 2021-07-24 3829 2e27f576abc6f0 Christoph Hellwig 2021-07-24 @3830 retval = scsi_ioctl(STp->device, STp->disk, file->f_mode, cmd_in, p); dba7688fc9037c Christoph Hellwig 2021-07-24 3831 if (!retval && cmd_in == SCSI_IOCTL_STOP_UNIT) { dba7688fc9037c Christoph Hellwig 2021-07-24 3832 /* unload */ dba7688fc9037c Christoph Hellwig 2021-07-24 3833 STp->rew_at_close = 0; dba7688fc9037c Christoph Hellwig 2021-07-24 3834 STp->ready = ST_NO_TAPE; dba7688fc9037c Christoph Hellwig 2021-07-24 3835 } dba7688fc9037c Christoph Hellwig 2021-07-24 3836 return retval; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3837 ^1da177e4c3f41 Linus Torvalds 2005-04-16 3838 out: 28f85009e0cf6a Matthias Kaehlcke 2007-07-29 3839 mutex_unlock(&STp->lock); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3840 return retval; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3841 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 3842 :::::: The code at line 3830 was first introduced by commit :::::: 2e27f576abc6f056e63ef207b9911b1a04d07020 scsi: scsi_ioctl: Call scsi_cmd_ioctl() from scsi_ioctl() :::::: TO: Christoph Hellwig :::::: CC: Martin K. Petersen --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org