Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi...
[cascardo/linux.git] / drivers / scsi / scsi_ioctl.c
index 1aaaf43..c4f7b56 100644 (file)
@@ -126,7 +126,7 @@ static int ioctl_internal_command(struct scsi_device *sdev, char *cmd,
                        sdev_printk(KERN_INFO, sdev,
                                    "ioctl_internal_command return code = %x\n",
                                    result);
-                       scsi_print_sense_hdr("   ", &sshdr);
+                       scsi_print_sense_hdr(sdev, NULL, &sshdr);
                        break;
                }
        }
@@ -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,55 +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,BUS,HOST}
- * @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)
 {
-       int val, result;
-
-       /* 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 -EAGAIN;
+       } else {
+               if (!scsi_block_when_processing_errors(sdev))
                        return -ENODEV;
-       } else if (!scsi_block_when_processing_errors(sdev))
-               return -ENODEV;
-
-       switch (cmd) {
-       case SG_SCSI_RESET:
-               result = get_user(val, (int __user *)arg);
-               if (result)
-                       return result;
-               if (val == SG_SCSI_RESET_NOTHING)
-                       return 0;
-               switch (val) {
-               case SG_SCSI_RESET_DEVICE:
-                       val = SCSI_TRY_RESET_DEVICE;
-                       break;
-               case SG_SCSI_RESET_TARGET:
-                       val = SCSI_TRY_RESET_TARGET;
-                       break;
-               case SG_SCSI_RESET_BUS:
-                       val = SCSI_TRY_RESET_BUS;
-                       break;
-               case SG_SCSI_RESET_HOST:
-                       val = SCSI_TRY_RESET_HOST;
-                       break;
-               default:
-                       return -EINVAL;
-               }
-               if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
-                       return -EACCES;
-               return (scsi_reset_provider(sdev, val) ==
-                       SUCCESS) ? 0 : -EIO;
        }
-       return -ENODEV;
+
+       return 0;
 }
-EXPORT_SYMBOL(scsi_nonblockable_ioctl);
+EXPORT_SYMBOL_GPL(scsi_ioctl_block_when_processing_errors);