|
@@ -200,19 +200,6 @@ int scsi_ioctl(struct scsi_device *sdev, int cmd, void __user *arg)
|
|
|
{
|
|
|
char scsi_cmd[MAX_COMMAND_SIZE];
|
|
|
|
|
|
- /* No idea how this happens.... */
|
|
|
- if (!sdev)
|
|
|
- return -ENXIO;
|
|
|
-
|
|
|
- /*
|
|
|
- * If we are in the middle of error recovery, don't let anyone
|
|
|
- * else try and use this device. Also, if error recovery fails, it
|
|
|
- * may try and take the device offline, in which case all further
|
|
|
- * access to the device is prohibited.
|
|
|
- */
|
|
|
- if (!scsi_block_when_processing_errors(sdev))
|
|
|
- return -ENODEV;
|
|
|
-
|
|
|
/* Check for deprecated ioctls ... all the ioctls which don't
|
|
|
* follow the new unique numbering scheme are deprecated */
|
|
|
switch (cmd) {
|
|
@@ -273,6 +260,8 @@ int scsi_ioctl(struct scsi_device *sdev, int cmd, void __user *arg)
|
|
|
START_STOP_TIMEOUT, NORMAL_RETRIES);
|
|
|
case SCSI_IOCTL_GET_PCI:
|
|
|
return scsi_ioctl_get_pci(sdev, arg);
|
|
|
+ case SG_SCSI_RESET:
|
|
|
+ return scsi_ioctl_reset(sdev, arg);
|
|
|
default:
|
|
|
if (sdev->host->hostt->ioctl)
|
|
|
return sdev->host->hostt->ioctl(sdev, cmd, arg);
|
|
@@ -281,30 +270,20 @@ int scsi_ioctl(struct scsi_device *sdev, int cmd, void __user *arg)
|
|
|
}
|
|
|
EXPORT_SYMBOL(scsi_ioctl);
|
|
|
|
|
|
-/**
|
|
|
- * scsi_nonblockable_ioctl() - Handle SG_SCSI_RESET
|
|
|
- * @sdev: scsi device receiving ioctl
|
|
|
- * @cmd: Must be SC_SCSI_RESET
|
|
|
- * @arg: pointer to int containing SG_SCSI_RESET_{DEVICE,TARGET,BUS,HOST}
|
|
|
- * possibly OR-ed with SG_SCSI_RESET_NO_ESCALATE
|
|
|
- * @ndelay: file mode O_NDELAY flag
|
|
|
+/*
|
|
|
+ * We can process a reset even when a device isn't fully operable.
|
|
|
*/
|
|
|
-int scsi_nonblockable_ioctl(struct scsi_device *sdev, int cmd,
|
|
|
- void __user *arg, int ndelay)
|
|
|
+int scsi_ioctl_block_when_processing_errors(struct scsi_device *sdev, int cmd,
|
|
|
+ bool ndelay)
|
|
|
{
|
|
|
- /* The first set of iocts may be executed even if we're doing
|
|
|
- * error processing, as long as the device was opened
|
|
|
- * non-blocking */
|
|
|
- if (ndelay) {
|
|
|
+ if (cmd == SG_SCSI_RESET && ndelay) {
|
|
|
if (scsi_host_in_recovery(sdev->host))
|
|
|
return -ENODEV;
|
|
|
- } else if (!scsi_block_when_processing_errors(sdev))
|
|
|
- return -ENODEV;
|
|
|
-
|
|
|
- switch (cmd) {
|
|
|
- case SG_SCSI_RESET:
|
|
|
- return scsi_ioctl_reset(sdev, arg);
|
|
|
+ } else {
|
|
|
+ if (!scsi_block_when_processing_errors(sdev))
|
|
|
+ return -ENODEV;
|
|
|
}
|
|
|
- return -ENODEV;
|
|
|
+
|
|
|
+ return 0;
|
|
|
}
|
|
|
-EXPORT_SYMBOL(scsi_nonblockable_ioctl);
|
|
|
+EXPORT_SYMBOL_GPL(scsi_ioctl_block_when_processing_errors);
|