scsi: refactor scsi_reset_provider handling

Pull the common code from the two callers into the function,
and rename it to scsi_ioctl_reset.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Reviewed-by: Hannes Reinecke <hare@suse.de>
This commit is contained in:
Christoph Hellwig
2014-10-11 12:06:47 +02:00
parent 1ee8e889d9
commit 176aa9d6ee
4 changed files with 41 additions and 117 deletions

View File

@@ -36,6 +36,7 @@
#include <scsi/scsi_transport.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_ioctl.h>
#include <scsi/sg.h>
#include "scsi_priv.h"
#include "scsi_logging.h"
@@ -2311,39 +2312,36 @@ scsi_reset_provider_done_command(struct scsi_cmnd *scmd)
{
}
/*
* Function: scsi_reset_provider
*
* Purpose: Send requested reset to a bus or device at any phase.
*
* Arguments: device - device to send reset to
* flag - reset type (see scsi.h)
*
* Returns: SUCCESS/FAILURE.
*
* Notes: This is used by the SCSI Generic driver to provide
* Bus/Device reset capability.
/**
* scsi_ioctl_reset: explicitly reset a host/bus/target/device
* @dev: scsi_device to operate on
* @arg: reset type (see sg.h)
*/
int
scsi_reset_provider(struct scsi_device *dev, int flag)
scsi_ioctl_reset(struct scsi_device *dev, int __user *arg)
{
struct scsi_cmnd *scmd;
struct Scsi_Host *shost = dev->host;
struct request req;
unsigned long flags;
int rtn;
int error = 0, rtn, val;
if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
return -EACCES;
error = get_user(val, arg);
if (error)
return error;
if (scsi_autopm_get_host(shost) < 0)
return FAILED;
return -EIO;
if (!get_device(&dev->sdev_gendev)) {
rtn = FAILED;
error = -EIO;
if (!get_device(&dev->sdev_gendev))
goto out_put_autopm_host;
}
scmd = scsi_get_command(dev, GFP_KERNEL);
if (!scmd) {
rtn = FAILED;
put_device(&dev->sdev_gendev);
goto out_put_autopm_host;
}
@@ -2364,39 +2362,37 @@ scsi_reset_provider(struct scsi_device *dev, int flag)
shost->tmf_in_progress = 1;
spin_unlock_irqrestore(shost->host_lock, flags);
switch (flag) {
case SCSI_TRY_RESET_DEVICE:
switch (val & ~SG_SCSI_RESET_NO_ESCALATE) {
case SG_SCSI_RESET_NOTHING:
rtn = SUCCESS;
break;
case SG_SCSI_RESET_DEVICE:
rtn = scsi_try_bus_device_reset(scmd);
if (rtn == SUCCESS)
if (rtn == SUCCESS || (val & SG_SCSI_RESET_NO_ESCALATE))
break;
/* FALLTHROUGH */
case SCSI_TRY_RESET_TARGET:
case SG_SCSI_RESET_TARGET:
rtn = scsi_try_target_reset(scmd);
if (rtn == SUCCESS)
if (rtn == SUCCESS || (val & SG_SCSI_RESET_NO_ESCALATE))
break;
/* FALLTHROUGH */
case SCSI_TRY_RESET_BUS:
case SG_SCSI_RESET_BUS:
rtn = scsi_try_bus_reset(scmd);
if (rtn == SUCCESS)
if (rtn == SUCCESS || (val & SG_SCSI_RESET_NO_ESCALATE))
break;
/* FALLTHROUGH */
case SCSI_TRY_RESET_HOST:
case SCSI_TRY_RESET_HOST | SCSI_TRY_RESET_NO_ESCALATE:
case SG_SCSI_RESET_HOST:
rtn = scsi_try_host_reset(scmd);
break;
case SCSI_TRY_RESET_DEVICE | SCSI_TRY_RESET_NO_ESCALATE:
rtn = scsi_try_bus_device_reset(scmd);
break;
case SCSI_TRY_RESET_TARGET | SCSI_TRY_RESET_NO_ESCALATE:
rtn = scsi_try_target_reset(scmd);
break;
case SCSI_TRY_RESET_BUS | SCSI_TRY_RESET_NO_ESCALATE:
rtn = scsi_try_bus_reset(scmd);
break;
if (rtn == SUCCESS)
break;
default:
/* FALLTHROUGH */
rtn = FAILED;
break;
}
error = (rtn == SUCCESS) ? 0 : -EIO;
spin_lock_irqsave(shost->host_lock, flags);
shost->tmf_in_progress = 0;
spin_unlock_irqrestore(shost->host_lock, flags);
@@ -2416,9 +2412,9 @@ scsi_reset_provider(struct scsi_device *dev, int flag)
scsi_next_command(scmd);
out_put_autopm_host:
scsi_autopm_put_host(shost);
return rtn;
return error;
}
EXPORT_SYMBOL(scsi_reset_provider);
EXPORT_SYMBOL(scsi_ioctl_reset);
/**
* scsi_normalize_sense - normalize main elements from either fixed or