aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/ch.c5
-rw-r--r--drivers/scsi/osst.c6
-rw-r--r--drivers/scsi/scsi_ioctl.c47
-rw-r--r--drivers/scsi/sd.c6
-rw-r--r--drivers/scsi/sg.c33
-rw-r--r--drivers/scsi/sr.c15
-rw-r--r--drivers/scsi/st.c7
-rw-r--r--include/scsi/scsi_ioctl.h4
8 files changed, 49 insertions, 74 deletions
diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c
index 226ef771efff..4f502f95f3b8 100644
--- a/drivers/scsi/ch.c
+++ b/drivers/scsi/ch.c
@@ -616,6 +616,11 @@ static long ch_ioctl(struct file *file,
616 int retval; 616 int retval;
617 void __user *argp = (void __user *)arg; 617 void __user *argp = (void __user *)arg;
618 618
619 retval = scsi_ioctl_block_when_processing_errors(ch->device, cmd,
620 file->f_flags & O_NDELAY);
621 if (retval)
622 return retval;
623
619 switch (cmd) { 624 switch (cmd) {
620 case CHIOGPARAMS: 625 case CHIOGPARAMS:
621 { 626 {
diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c
index 3d0d13c4da15..b6d63d636692 100644
--- a/drivers/scsi/osst.c
+++ b/drivers/scsi/osst.c
@@ -4969,10 +4969,10 @@ static long osst_ioctl(struct file * file,
4969 * may try and take the device offline, in which case all further 4969 * may try and take the device offline, in which case all further
4970 * access to the device is prohibited. 4970 * access to the device is prohibited.
4971 */ 4971 */
4972 if( !scsi_block_when_processing_errors(STp->device) ) { 4972 retval = scsi_ioctl_block_when_processing_errors(STp->device, cmd_in,
4973 retval = (-ENXIO); 4973 file->f_flags & O_NDELAY);
4974 if (retval)
4974 goto out; 4975 goto out;
4975 }
4976 4976
4977 cmd_type = _IOC_TYPE(cmd_in); 4977 cmd_type = _IOC_TYPE(cmd_in);
4978 cmd_nr = _IOC_NR(cmd_in); 4978 cmd_nr = _IOC_NR(cmd_in);
diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c
index 5ddc08f39987..712f159ebb69 100644
--- a/drivers/scsi/scsi_ioctl.c
+++ b/drivers/scsi/scsi_ioctl.c
@@ -200,19 +200,6 @@ int scsi_ioctl(struct scsi_device *sdev, int cmd, void __user *arg)
200{ 200{
201 char scsi_cmd[MAX_COMMAND_SIZE]; 201 char scsi_cmd[MAX_COMMAND_SIZE];
202 202
203 /* No idea how this happens.... */
204 if (!sdev)
205 return -ENXIO;
206
207 /*
208 * If we are in the middle of error recovery, don't let anyone
209 * else try and use this device. Also, if error recovery fails, it
210 * may try and take the device offline, in which case all further
211 * access to the device is prohibited.
212 */
213 if (!scsi_block_when_processing_errors(sdev))
214 return -ENODEV;
215
216 /* Check for deprecated ioctls ... all the ioctls which don't 203 /* Check for deprecated ioctls ... all the ioctls which don't
217 * follow the new unique numbering scheme are deprecated */ 204 * follow the new unique numbering scheme are deprecated */
218 switch (cmd) { 205 switch (cmd) {
@@ -273,6 +260,8 @@ int scsi_ioctl(struct scsi_device *sdev, int cmd, void __user *arg)
273 START_STOP_TIMEOUT, NORMAL_RETRIES); 260 START_STOP_TIMEOUT, NORMAL_RETRIES);
274 case SCSI_IOCTL_GET_PCI: 261 case SCSI_IOCTL_GET_PCI:
275 return scsi_ioctl_get_pci(sdev, arg); 262 return scsi_ioctl_get_pci(sdev, arg);
263 case SG_SCSI_RESET:
264 return scsi_ioctl_reset(sdev, arg);
276 default: 265 default:
277 if (sdev->host->hostt->ioctl) 266 if (sdev->host->hostt->ioctl)
278 return sdev->host->hostt->ioctl(sdev, cmd, arg); 267 return sdev->host->hostt->ioctl(sdev, cmd, arg);
@@ -281,30 +270,20 @@ int scsi_ioctl(struct scsi_device *sdev, int cmd, void __user *arg)
281} 270}
282EXPORT_SYMBOL(scsi_ioctl); 271EXPORT_SYMBOL(scsi_ioctl);
283 272
284/** 273/*
285 * scsi_nonblockable_ioctl() - Handle SG_SCSI_RESET 274 * We can process a reset even when a device isn't fully operable.
286 * @sdev: scsi device receiving ioctl
287 * @cmd: Must be SC_SCSI_RESET
288 * @arg: pointer to int containing SG_SCSI_RESET_{DEVICE,TARGET,BUS,HOST}
289 * possibly OR-ed with SG_SCSI_RESET_NO_ESCALATE
290 * @ndelay: file mode O_NDELAY flag
291 */ 275 */
292int scsi_nonblockable_ioctl(struct scsi_device *sdev, int cmd, 276int scsi_ioctl_block_when_processing_errors(struct scsi_device *sdev, int cmd,
293 void __user *arg, int ndelay) 277 bool ndelay)
294{ 278{
295 /* The first set of iocts may be executed even if we're doing 279 if (cmd == SG_SCSI_RESET && ndelay) {
296 * error processing, as long as the device was opened
297 * non-blocking */
298 if (ndelay) {
299 if (scsi_host_in_recovery(sdev->host)) 280 if (scsi_host_in_recovery(sdev->host))
300 return -ENODEV; 281 return -ENODEV;
301 } else if (!scsi_block_when_processing_errors(sdev)) 282 } else {
302 return -ENODEV; 283 if (!scsi_block_when_processing_errors(sdev))
303 284 return -ENODEV;
304 switch (cmd) {
305 case SG_SCSI_RESET:
306 return scsi_ioctl_reset(sdev, arg);
307 } 285 }
308 return -ENODEV; 286
287 return 0;
309} 288}
310EXPORT_SYMBOL(scsi_nonblockable_ioctl); 289EXPORT_SYMBOL_GPL(scsi_ioctl_block_when_processing_errors);
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 242f9b177285..ddf763ad3b83 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1334,9 +1334,9 @@ static int sd_ioctl(struct block_device *bdev, fmode_t mode,
1334 * may try and take the device offline, in which case all further 1334 * may try and take the device offline, in which case all further
1335 * access to the device is prohibited. 1335 * access to the device is prohibited.
1336 */ 1336 */
1337 error = scsi_nonblockable_ioctl(sdp, cmd, p, 1337 error = scsi_ioctl_block_when_processing_errors(sdp, cmd,
1338 (mode & FMODE_NDELAY) != 0); 1338 (mode & FMODE_NDELAY) != 0);
1339 if (!scsi_block_when_processing_errors(sdp) || !error) 1339 if (error)
1340 goto out; 1340 goto out;
1341 1341
1342 /* 1342 /*
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 7c55cacceb7c..b14f64cb9724 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1071,16 +1071,6 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
1071 if (atomic_read(&sdp->detaching)) 1071 if (atomic_read(&sdp->detaching))
1072 return -ENODEV; 1072 return -ENODEV;
1073 return put_user(sdp->device->host->hostt->emulated, ip); 1073 return put_user(sdp->device->host->hostt->emulated, ip);
1074 case SG_SCSI_RESET:
1075 if (atomic_read(&sdp->detaching))
1076 return -ENODEV;
1077 if (filp->f_flags & O_NONBLOCK) {
1078 if (scsi_host_in_recovery(sdp->device->host))
1079 return -EBUSY;
1080 } else if (!scsi_block_when_processing_errors(sdp->device))
1081 return -EBUSY;
1082
1083 return scsi_ioctl_reset(sdp->device, ip);
1084 case SCSI_IOCTL_SEND_COMMAND: 1074 case SCSI_IOCTL_SEND_COMMAND:
1085 if (atomic_read(&sdp->detaching)) 1075 if (atomic_read(&sdp->detaching))
1086 return -ENODEV; 1076 return -ENODEV;
@@ -1100,13 +1090,6 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
1100 return result; 1090 return result;
1101 sdp->sgdebug = (char) val; 1091 sdp->sgdebug = (char) val;
1102 return 0; 1092 return 0;
1103 case SCSI_IOCTL_GET_IDLUN:
1104 case SCSI_IOCTL_GET_BUS_NUMBER:
1105 case SCSI_IOCTL_PROBE_HOST:
1106 case SG_GET_TRANSFORM:
1107 if (atomic_read(&sdp->detaching))
1108 return -ENODEV;
1109 return scsi_ioctl(sdp->device, cmd_in, p);
1110 case BLKSECTGET: 1093 case BLKSECTGET:
1111 return put_user(max_sectors_bytes(sdp->device->request_queue), 1094 return put_user(max_sectors_bytes(sdp->device->request_queue),
1112 ip); 1095 ip);
@@ -1122,11 +1105,25 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
1122 return blk_trace_startstop(sdp->device->request_queue, 0); 1105 return blk_trace_startstop(sdp->device->request_queue, 0);
1123 case BLKTRACETEARDOWN: 1106 case BLKTRACETEARDOWN:
1124 return blk_trace_remove(sdp->device->request_queue); 1107 return blk_trace_remove(sdp->device->request_queue);
1108 case SCSI_IOCTL_GET_IDLUN:
1109 case SCSI_IOCTL_GET_BUS_NUMBER:
1110 case SCSI_IOCTL_PROBE_HOST:
1111 case SG_GET_TRANSFORM:
1112 case SG_SCSI_RESET:
1113 if (atomic_read(&sdp->detaching))
1114 return -ENODEV;
1115 break;
1125 default: 1116 default:
1126 if (read_only) 1117 if (read_only)
1127 return -EPERM; /* don't know so take safe approach */ 1118 return -EPERM; /* don't know so take safe approach */
1128 return scsi_ioctl(sdp->device, cmd_in, p); 1119 break;
1129 } 1120 }
1121
1122 result = scsi_ioctl_block_when_processing_errors(sdp->device,
1123 cmd_in, filp->f_flags & O_NDELAY);
1124 if (result)
1125 return result;
1126 return scsi_ioctl(sdp->device, cmd_in, p);
1130} 1127}
1131 1128
1132#ifdef CONFIG_COMPAT 1129#ifdef CONFIG_COMPAT
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index 2de44cc58b1a..3d5399e341af 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -549,6 +549,11 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
549 549
550 mutex_lock(&sr_mutex); 550 mutex_lock(&sr_mutex);
551 551
552 ret = scsi_ioctl_block_when_processing_errors(sdev, cmd,
553 (mode & FMODE_NDELAY) != 0);
554 if (ret)
555 goto out;
556
552 /* 557 /*
553 * Send SCSI addressing ioctls directly to mid level, send other 558 * Send SCSI addressing ioctls directly to mid level, send other
554 * ioctls to cdrom/block level. 559 * ioctls to cdrom/block level.
@@ -564,16 +569,6 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
564 if (ret != -ENOSYS) 569 if (ret != -ENOSYS)
565 goto out; 570 goto out;
566 571
567 /*
568 * ENODEV means that we didn't recognise the ioctl, or that we
569 * cannot execute it in the current device state. In either
570 * case fall through to scsi_ioctl, which will return ENDOEV again
571 * if it doesn't recognise the ioctl
572 */
573 ret = scsi_nonblockable_ioctl(sdev, cmd, argp,
574 (mode & FMODE_NDELAY) != 0);
575 if (ret != -ENODEV)
576 goto out;
577 ret = scsi_ioctl(sdev, cmd, argp); 572 ret = scsi_ioctl(sdev, cmd, argp);
578 573
579out: 574out:
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 63c35ed3c88d..7d2e036c75c1 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -3376,11 +3376,10 @@ static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)
3376 * may try and take the device offline, in which case all further 3376 * may try and take the device offline, in which case all further
3377 * access to the device is prohibited. 3377 * access to the device is prohibited.
3378 */ 3378 */
3379 retval = scsi_nonblockable_ioctl(STp->device, cmd_in, p, 3379 retval = scsi_ioctl_block_when_processing_errors(STp->device, cmd_in,
3380 file->f_flags & O_NDELAY); 3380 file->f_flags & O_NDELAY);
3381 if (!scsi_block_when_processing_errors(STp->device) || retval != -ENODEV) 3381 if (retval)
3382 goto out; 3382 goto out;
3383 retval = 0;
3384 3383
3385 cmd_type = _IOC_TYPE(cmd_in); 3384 cmd_type = _IOC_TYPE(cmd_in);
3386 cmd_nr = _IOC_NR(cmd_in); 3385 cmd_nr = _IOC_NR(cmd_in);
diff --git a/include/scsi/scsi_ioctl.h b/include/scsi/scsi_ioctl.h
index b9006848b813..8d19d1d233c3 100644
--- a/include/scsi/scsi_ioctl.h
+++ b/include/scsi/scsi_ioctl.h
@@ -40,9 +40,9 @@ typedef struct scsi_fctargaddress {
40 unsigned char host_wwn[8]; // include NULL term. 40 unsigned char host_wwn[8]; // include NULL term.
41} Scsi_FCTargAddress; 41} Scsi_FCTargAddress;
42 42
43int scsi_ioctl_block_when_processing_errors(struct scsi_device *sdev,
44 int cmd, bool ndelay);
43extern int scsi_ioctl(struct scsi_device *, int, void __user *); 45extern int scsi_ioctl(struct scsi_device *, int, void __user *);
44extern int scsi_nonblockable_ioctl(struct scsi_device *sdev, int cmd,
45 void __user *arg, int ndelay);
46 46
47#endif /* __KERNEL__ */ 47#endif /* __KERNEL__ */
48#endif /* _SCSI_IOCTL_H */ 48#endif /* _SCSI_IOCTL_H */