diff options
Diffstat (limited to 'drivers/scsi/scsi_ioctl.c')
| -rw-r--r-- | drivers/scsi/scsi_ioctl.c | 74 | 
1 files changed, 14 insertions, 60 deletions
diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c index 1aaaf43c6803..c4f7b56fa6f6 100644 --- a/drivers/scsi/scsi_ioctl.c +++ b/drivers/scsi/scsi_ioctl.c @@ -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);  |