Merge patch series "scsi: Add struct for args to execution functions"
Mike Christie <michael.christie@oracle.com> says: The following patches were made over Martin's scsi-staging/next branch. They add a struct that contains optinal arguments to the scsi_execute* functions. This will be needed for the patches that allow the SCSI passthrough users to control retries because I'm adding a new optional argument. I separated the 2 sets to make it easier to review and post. Link: https://lore.kernel.org/r/20221229190154.7467-1-michael.christie@oracle.com Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
@ -383,8 +383,12 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
|
|||||||
u8 scsi_cmd[MAX_COMMAND_SIZE];
|
u8 scsi_cmd[MAX_COMMAND_SIZE];
|
||||||
u8 args[4], *argbuf = NULL;
|
u8 args[4], *argbuf = NULL;
|
||||||
int argsize = 0;
|
int argsize = 0;
|
||||||
enum dma_data_direction data_dir;
|
|
||||||
struct scsi_sense_hdr sshdr;
|
struct scsi_sense_hdr sshdr;
|
||||||
|
const struct scsi_exec_args exec_args = {
|
||||||
|
.sshdr = &sshdr,
|
||||||
|
.sense = sensebuf,
|
||||||
|
.sense_len = sizeof(sensebuf),
|
||||||
|
};
|
||||||
int cmd_result;
|
int cmd_result;
|
||||||
|
|
||||||
if (arg == NULL)
|
if (arg == NULL)
|
||||||
@ -407,11 +411,9 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
|
|||||||
scsi_cmd[1] = (4 << 1); /* PIO Data-in */
|
scsi_cmd[1] = (4 << 1); /* PIO Data-in */
|
||||||
scsi_cmd[2] = 0x0e; /* no off.line or cc, read from dev,
|
scsi_cmd[2] = 0x0e; /* no off.line or cc, read from dev,
|
||||||
block count in sector count field */
|
block count in sector count field */
|
||||||
data_dir = DMA_FROM_DEVICE;
|
|
||||||
} else {
|
} else {
|
||||||
scsi_cmd[1] = (3 << 1); /* Non-data */
|
scsi_cmd[1] = (3 << 1); /* Non-data */
|
||||||
scsi_cmd[2] = 0x20; /* cc but no off.line or data xfer */
|
scsi_cmd[2] = 0x20; /* cc but no off.line or data xfer */
|
||||||
data_dir = DMA_NONE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
scsi_cmd[0] = ATA_16;
|
scsi_cmd[0] = ATA_16;
|
||||||
@ -429,9 +431,8 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
|
|||||||
|
|
||||||
/* Good values for timeout and retries? Values below
|
/* Good values for timeout and retries? Values below
|
||||||
from scsi_ioctl_send_command() for default case... */
|
from scsi_ioctl_send_command() for default case... */
|
||||||
cmd_result = scsi_execute(scsidev, scsi_cmd, data_dir, argbuf, argsize,
|
cmd_result = scsi_execute_cmd(scsidev, scsi_cmd, REQ_OP_DRV_IN, argbuf,
|
||||||
sensebuf, &sshdr, (10*HZ), 5, 0, 0, NULL);
|
argsize, 10 * HZ, 5, &exec_args);
|
||||||
|
|
||||||
if (cmd_result < 0) {
|
if (cmd_result < 0) {
|
||||||
rc = cmd_result;
|
rc = cmd_result;
|
||||||
goto error;
|
goto error;
|
||||||
@ -491,6 +492,11 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg)
|
|||||||
u8 args[7];
|
u8 args[7];
|
||||||
struct scsi_sense_hdr sshdr;
|
struct scsi_sense_hdr sshdr;
|
||||||
int cmd_result;
|
int cmd_result;
|
||||||
|
const struct scsi_exec_args exec_args = {
|
||||||
|
.sshdr = &sshdr,
|
||||||
|
.sense = sensebuf,
|
||||||
|
.sense_len = sizeof(sensebuf),
|
||||||
|
};
|
||||||
|
|
||||||
if (arg == NULL)
|
if (arg == NULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -513,9 +519,8 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg)
|
|||||||
|
|
||||||
/* Good values for timeout and retries? Values below
|
/* Good values for timeout and retries? Values below
|
||||||
from scsi_ioctl_send_command() for default case... */
|
from scsi_ioctl_send_command() for default case... */
|
||||||
cmd_result = scsi_execute(scsidev, scsi_cmd, DMA_NONE, NULL, 0,
|
cmd_result = scsi_execute_cmd(scsidev, scsi_cmd, REQ_OP_DRV_IN, NULL,
|
||||||
sensebuf, &sshdr, (10*HZ), 5, 0, 0, NULL);
|
0, 10 * HZ, 5, &exec_args);
|
||||||
|
|
||||||
if (cmd_result < 0) {
|
if (cmd_result < 0) {
|
||||||
rc = cmd_result;
|
rc = cmd_result;
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -164,7 +164,7 @@ static int drivetemp_scsi_command(struct drivetemp_data *st,
|
|||||||
u8 lba_low, u8 lba_mid, u8 lba_high)
|
u8 lba_low, u8 lba_mid, u8 lba_high)
|
||||||
{
|
{
|
||||||
u8 scsi_cmd[MAX_COMMAND_SIZE];
|
u8 scsi_cmd[MAX_COMMAND_SIZE];
|
||||||
int data_dir;
|
enum req_op op;
|
||||||
|
|
||||||
memset(scsi_cmd, 0, sizeof(scsi_cmd));
|
memset(scsi_cmd, 0, sizeof(scsi_cmd));
|
||||||
scsi_cmd[0] = ATA_16;
|
scsi_cmd[0] = ATA_16;
|
||||||
@ -175,7 +175,7 @@ static int drivetemp_scsi_command(struct drivetemp_data *st,
|
|||||||
* field.
|
* field.
|
||||||
*/
|
*/
|
||||||
scsi_cmd[2] = 0x06;
|
scsi_cmd[2] = 0x06;
|
||||||
data_dir = DMA_TO_DEVICE;
|
op = REQ_OP_DRV_OUT;
|
||||||
} else {
|
} else {
|
||||||
scsi_cmd[1] = (4 << 1); /* PIO Data-in */
|
scsi_cmd[1] = (4 << 1); /* PIO Data-in */
|
||||||
/*
|
/*
|
||||||
@ -183,7 +183,7 @@ static int drivetemp_scsi_command(struct drivetemp_data *st,
|
|||||||
* field.
|
* field.
|
||||||
*/
|
*/
|
||||||
scsi_cmd[2] = 0x0e;
|
scsi_cmd[2] = 0x0e;
|
||||||
data_dir = DMA_FROM_DEVICE;
|
op = REQ_OP_DRV_IN;
|
||||||
}
|
}
|
||||||
scsi_cmd[4] = feature;
|
scsi_cmd[4] = feature;
|
||||||
scsi_cmd[6] = 1; /* 1 sector */
|
scsi_cmd[6] = 1; /* 1 sector */
|
||||||
@ -192,9 +192,8 @@ static int drivetemp_scsi_command(struct drivetemp_data *st,
|
|||||||
scsi_cmd[12] = lba_high;
|
scsi_cmd[12] = lba_high;
|
||||||
scsi_cmd[14] = ata_command;
|
scsi_cmd[14] = ata_command;
|
||||||
|
|
||||||
return scsi_execute_req(st->sdev, scsi_cmd, data_dir,
|
return scsi_execute_cmd(st->sdev, scsi_cmd, op, st->smartdata,
|
||||||
st->smartdata, ATA_SECT_SIZE, NULL, HZ, 5,
|
ATA_SECT_SIZE, HZ, 5, NULL);
|
||||||
NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int drivetemp_ata_command(struct drivetemp_data *st, u8 feature,
|
static int drivetemp_ata_command(struct drivetemp_data *st, u8 feature,
|
||||||
|
@ -184,20 +184,21 @@ static int ch_find_errno(struct scsi_sense_hdr *sshdr)
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
ch_do_scsi(scsi_changer *ch, unsigned char *cmd, int cmd_len,
|
ch_do_scsi(scsi_changer *ch, unsigned char *cmd, int cmd_len,
|
||||||
void *buffer, unsigned buflength,
|
void *buffer, unsigned int buflength, enum req_op op)
|
||||||
enum dma_data_direction direction)
|
|
||||||
{
|
{
|
||||||
int errno, retries = 0, timeout, result;
|
int errno, retries = 0, timeout, result;
|
||||||
struct scsi_sense_hdr sshdr;
|
struct scsi_sense_hdr sshdr;
|
||||||
|
const struct scsi_exec_args exec_args = {
|
||||||
|
.sshdr = &sshdr,
|
||||||
|
};
|
||||||
|
|
||||||
timeout = (cmd[0] == INITIALIZE_ELEMENT_STATUS)
|
timeout = (cmd[0] == INITIALIZE_ELEMENT_STATUS)
|
||||||
? timeout_init : timeout_move;
|
? timeout_init : timeout_move;
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
errno = 0;
|
errno = 0;
|
||||||
result = scsi_execute_req(ch->device, cmd, direction, buffer,
|
result = scsi_execute_cmd(ch->device, cmd, op, buffer, buflength,
|
||||||
buflength, &sshdr, timeout * HZ,
|
timeout * HZ, MAX_RETRIES, &exec_args);
|
||||||
MAX_RETRIES, NULL);
|
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
return result;
|
return result;
|
||||||
if (scsi_sense_valid(&sshdr)) {
|
if (scsi_sense_valid(&sshdr)) {
|
||||||
@ -254,7 +255,7 @@ ch_read_element_status(scsi_changer *ch, u_int elem, char *data)
|
|||||||
cmd[5] = 1;
|
cmd[5] = 1;
|
||||||
cmd[9] = 255;
|
cmd[9] = 255;
|
||||||
if (0 == (result = ch_do_scsi(ch, cmd, 12,
|
if (0 == (result = ch_do_scsi(ch, cmd, 12,
|
||||||
buffer, 256, DMA_FROM_DEVICE))) {
|
buffer, 256, REQ_OP_DRV_IN))) {
|
||||||
if (((buffer[16] << 8) | buffer[17]) != elem) {
|
if (((buffer[16] << 8) | buffer[17]) != elem) {
|
||||||
DPRINTK("asked for element 0x%02x, got 0x%02x\n",
|
DPRINTK("asked for element 0x%02x, got 0x%02x\n",
|
||||||
elem,(buffer[16] << 8) | buffer[17]);
|
elem,(buffer[16] << 8) | buffer[17]);
|
||||||
@ -284,7 +285,7 @@ ch_init_elem(scsi_changer *ch)
|
|||||||
memset(cmd,0,sizeof(cmd));
|
memset(cmd,0,sizeof(cmd));
|
||||||
cmd[0] = INITIALIZE_ELEMENT_STATUS;
|
cmd[0] = INITIALIZE_ELEMENT_STATUS;
|
||||||
cmd[1] = (ch->device->lun & 0x7) << 5;
|
cmd[1] = (ch->device->lun & 0x7) << 5;
|
||||||
err = ch_do_scsi(ch, cmd, 6, NULL, 0, DMA_NONE);
|
err = ch_do_scsi(ch, cmd, 6, NULL, 0, REQ_OP_DRV_IN);
|
||||||
VPRINTK(KERN_INFO, "... finished\n");
|
VPRINTK(KERN_INFO, "... finished\n");
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -306,10 +307,10 @@ ch_readconfig(scsi_changer *ch)
|
|||||||
cmd[1] = (ch->device->lun & 0x7) << 5;
|
cmd[1] = (ch->device->lun & 0x7) << 5;
|
||||||
cmd[2] = 0x1d;
|
cmd[2] = 0x1d;
|
||||||
cmd[4] = 255;
|
cmd[4] = 255;
|
||||||
result = ch_do_scsi(ch, cmd, 10, buffer, 255, DMA_FROM_DEVICE);
|
result = ch_do_scsi(ch, cmd, 10, buffer, 255, REQ_OP_DRV_IN);
|
||||||
if (0 != result) {
|
if (0 != result) {
|
||||||
cmd[1] |= (1<<3);
|
cmd[1] |= (1<<3);
|
||||||
result = ch_do_scsi(ch, cmd, 10, buffer, 255, DMA_FROM_DEVICE);
|
result = ch_do_scsi(ch, cmd, 10, buffer, 255, REQ_OP_DRV_IN);
|
||||||
}
|
}
|
||||||
if (0 == result) {
|
if (0 == result) {
|
||||||
ch->firsts[CHET_MT] =
|
ch->firsts[CHET_MT] =
|
||||||
@ -434,7 +435,7 @@ ch_position(scsi_changer *ch, u_int trans, u_int elem, int rotate)
|
|||||||
cmd[4] = (elem >> 8) & 0xff;
|
cmd[4] = (elem >> 8) & 0xff;
|
||||||
cmd[5] = elem & 0xff;
|
cmd[5] = elem & 0xff;
|
||||||
cmd[8] = rotate ? 1 : 0;
|
cmd[8] = rotate ? 1 : 0;
|
||||||
return ch_do_scsi(ch, cmd, 10, NULL, 0, DMA_NONE);
|
return ch_do_scsi(ch, cmd, 10, NULL, 0, REQ_OP_DRV_IN);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -455,7 +456,7 @@ ch_move(scsi_changer *ch, u_int trans, u_int src, u_int dest, int rotate)
|
|||||||
cmd[6] = (dest >> 8) & 0xff;
|
cmd[6] = (dest >> 8) & 0xff;
|
||||||
cmd[7] = dest & 0xff;
|
cmd[7] = dest & 0xff;
|
||||||
cmd[10] = rotate ? 1 : 0;
|
cmd[10] = rotate ? 1 : 0;
|
||||||
return ch_do_scsi(ch, cmd, 12, NULL,0, DMA_NONE);
|
return ch_do_scsi(ch, cmd, 12, NULL, 0, REQ_OP_DRV_IN);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -481,7 +482,7 @@ ch_exchange(scsi_changer *ch, u_int trans, u_int src,
|
|||||||
cmd[9] = dest2 & 0xff;
|
cmd[9] = dest2 & 0xff;
|
||||||
cmd[10] = (rotate1 ? 1 : 0) | (rotate2 ? 2 : 0);
|
cmd[10] = (rotate1 ? 1 : 0) | (rotate2 ? 2 : 0);
|
||||||
|
|
||||||
return ch_do_scsi(ch, cmd, 12, NULL, 0, DMA_NONE);
|
return ch_do_scsi(ch, cmd, 12, NULL, 0, REQ_OP_DRV_IN);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -531,7 +532,7 @@ ch_set_voltag(scsi_changer *ch, u_int elem,
|
|||||||
memcpy(buffer,tag,32);
|
memcpy(buffer,tag,32);
|
||||||
ch_check_voltag(buffer);
|
ch_check_voltag(buffer);
|
||||||
|
|
||||||
result = ch_do_scsi(ch, cmd, 12, buffer, 256, DMA_TO_DEVICE);
|
result = ch_do_scsi(ch, cmd, 12, buffer, 256, REQ_OP_DRV_OUT);
|
||||||
kfree(buffer);
|
kfree(buffer);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -799,8 +800,7 @@ static long ch_ioctl(struct file *file,
|
|||||||
ch_cmd[5] = 1;
|
ch_cmd[5] = 1;
|
||||||
ch_cmd[9] = 255;
|
ch_cmd[9] = 255;
|
||||||
|
|
||||||
result = ch_do_scsi(ch, ch_cmd, 12,
|
result = ch_do_scsi(ch, ch_cmd, 12, buffer, 256, REQ_OP_DRV_IN);
|
||||||
buffer, 256, DMA_FROM_DEVICE);
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
cge.cge_status = buffer[18];
|
cge.cge_status = buffer[18];
|
||||||
cge.cge_flags = 0;
|
cge.cge_flags = 0;
|
||||||
|
@ -308,19 +308,19 @@ out:
|
|||||||
* @lli: LUN destined for capacity request.
|
* @lli: LUN destined for capacity request.
|
||||||
*
|
*
|
||||||
* The READ_CAP16 can take quite a while to complete. Should an EEH occur while
|
* The READ_CAP16 can take quite a while to complete. Should an EEH occur while
|
||||||
* in scsi_execute(), the EEH handler will attempt to recover. As part of the
|
* in scsi_execute_cmd(), the EEH handler will attempt to recover. As part of
|
||||||
* recovery, the handler drains all currently running ioctls, waiting until they
|
* the recovery, the handler drains all currently running ioctls, waiting until
|
||||||
* have completed before proceeding with a reset. As this routine is used on the
|
* they have completed before proceeding with a reset. As this routine is used
|
||||||
* ioctl path, this can create a condition where the EEH handler becomes stuck,
|
* on the ioctl path, this can create a condition where the EEH handler becomes
|
||||||
* infinitely waiting for this ioctl thread. To avoid this behavior, temporarily
|
* stuck, infinitely waiting for this ioctl thread. To avoid this behavior,
|
||||||
* unmark this thread as an ioctl thread by releasing the ioctl read semaphore.
|
* temporarily unmark this thread as an ioctl thread by releasing the ioctl
|
||||||
* This will allow the EEH handler to proceed with a recovery while this thread
|
* read semaphore. This will allow the EEH handler to proceed with a recovery
|
||||||
* is still running. Once the scsi_execute() returns, reacquire the ioctl read
|
* while this thread is still running. Once the scsi_execute_cmd() returns,
|
||||||
* semaphore and check the adapter state in case it changed while inside of
|
* reacquire the ioctl read semaphore and check the adapter state in case it
|
||||||
* scsi_execute(). The state check will wait if the adapter is still being
|
* changed while inside of scsi_execute_cmd(). The state check will wait if the
|
||||||
* recovered or return a failure if the recovery failed. In the event that the
|
* adapter is still being recovered or return a failure if the recovery failed.
|
||||||
* adapter reset failed, simply return the failure as the ioctl would be unable
|
* In the event that the adapter reset failed, simply return the failure as the
|
||||||
* to continue.
|
* ioctl would be unable to continue.
|
||||||
*
|
*
|
||||||
* Note that the above puts a requirement on this routine to only be called on
|
* Note that the above puts a requirement on this routine to only be called on
|
||||||
* an ioctl thread.
|
* an ioctl thread.
|
||||||
@ -333,6 +333,9 @@ static int read_cap16(struct scsi_device *sdev, struct llun_info *lli)
|
|||||||
struct device *dev = &cfg->dev->dev;
|
struct device *dev = &cfg->dev->dev;
|
||||||
struct glun_info *gli = lli->parent;
|
struct glun_info *gli = lli->parent;
|
||||||
struct scsi_sense_hdr sshdr;
|
struct scsi_sense_hdr sshdr;
|
||||||
|
const struct scsi_exec_args exec_args = {
|
||||||
|
.sshdr = &sshdr,
|
||||||
|
};
|
||||||
u8 *cmd_buf = NULL;
|
u8 *cmd_buf = NULL;
|
||||||
u8 *scsi_cmd = NULL;
|
u8 *scsi_cmd = NULL;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
@ -357,9 +360,8 @@ retry:
|
|||||||
|
|
||||||
/* Drop the ioctl read semahpore across lengthy call */
|
/* Drop the ioctl read semahpore across lengthy call */
|
||||||
up_read(&cfg->ioctl_rwsem);
|
up_read(&cfg->ioctl_rwsem);
|
||||||
result = scsi_execute(sdev, scsi_cmd, DMA_FROM_DEVICE, cmd_buf,
|
result = scsi_execute_cmd(sdev, scsi_cmd, REQ_OP_DRV_IN, cmd_buf,
|
||||||
CMD_BUFSIZE, NULL, &sshdr, to, CMD_RETRIES,
|
CMD_BUFSIZE, to, CMD_RETRIES, &exec_args);
|
||||||
0, 0, NULL);
|
|
||||||
down_read(&cfg->ioctl_rwsem);
|
down_read(&cfg->ioctl_rwsem);
|
||||||
rc = check_state(cfg);
|
rc = check_state(cfg);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
|
@ -397,19 +397,19 @@ static int init_vlun(struct llun_info *lli)
|
|||||||
* @nblks: Number of logical blocks to write same.
|
* @nblks: Number of logical blocks to write same.
|
||||||
*
|
*
|
||||||
* The SCSI WRITE_SAME16 can take quite a while to complete. Should an EEH occur
|
* The SCSI WRITE_SAME16 can take quite a while to complete. Should an EEH occur
|
||||||
* while in scsi_execute(), the EEH handler will attempt to recover. As part of
|
* while in scsi_execute_cmd(), the EEH handler will attempt to recover. As
|
||||||
* the recovery, the handler drains all currently running ioctls, waiting until
|
* part of the recovery, the handler drains all currently running ioctls,
|
||||||
* they have completed before proceeding with a reset. As this routine is used
|
* waiting until they have completed before proceeding with a reset. As this
|
||||||
* on the ioctl path, this can create a condition where the EEH handler becomes
|
* routine is used on the ioctl path, this can create a condition where the
|
||||||
* stuck, infinitely waiting for this ioctl thread. To avoid this behavior,
|
* EEH handler becomes stuck, infinitely waiting for this ioctl thread. To
|
||||||
* temporarily unmark this thread as an ioctl thread by releasing the ioctl read
|
* avoid this behavior, temporarily unmark this thread as an ioctl thread by
|
||||||
* semaphore. This will allow the EEH handler to proceed with a recovery while
|
* releasing the ioctl read semaphore. This will allow the EEH handler to
|
||||||
* this thread is still running. Once the scsi_execute() returns, reacquire the
|
* proceed with a recovery while this thread is still running. Once the
|
||||||
* ioctl read semaphore and check the adapter state in case it changed while
|
* scsi_execute_cmd() returns, reacquire the ioctl read semaphore and check the
|
||||||
* inside of scsi_execute(). The state check will wait if the adapter is still
|
* adapter state in case it changed while inside of scsi_execute_cmd(). The
|
||||||
* being recovered or return a failure if the recovery failed. In the event that
|
* state check will wait if the adapter is still being recovered or return a
|
||||||
* the adapter reset failed, simply return the failure as the ioctl would be
|
* failure if the recovery failed. In the event that the adapter reset failed,
|
||||||
* unable to continue.
|
* simply return the failure as the ioctl would be unable to continue.
|
||||||
*
|
*
|
||||||
* Note that the above puts a requirement on this routine to only be called on
|
* Note that the above puts a requirement on this routine to only be called on
|
||||||
* an ioctl thread.
|
* an ioctl thread.
|
||||||
@ -450,9 +450,9 @@ static int write_same16(struct scsi_device *sdev,
|
|||||||
|
|
||||||
/* Drop the ioctl read semahpore across lengthy call */
|
/* Drop the ioctl read semahpore across lengthy call */
|
||||||
up_read(&cfg->ioctl_rwsem);
|
up_read(&cfg->ioctl_rwsem);
|
||||||
result = scsi_execute(sdev, scsi_cmd, DMA_TO_DEVICE, cmd_buf,
|
result = scsi_execute_cmd(sdev, scsi_cmd, REQ_OP_DRV_OUT,
|
||||||
CMD_BUFSIZE, NULL, NULL, to,
|
cmd_buf, CMD_BUFSIZE, to,
|
||||||
CMD_RETRIES, 0, 0, NULL);
|
CMD_RETRIES, NULL);
|
||||||
down_read(&cfg->ioctl_rwsem);
|
down_read(&cfg->ioctl_rwsem);
|
||||||
rc = check_state(cfg);
|
rc = check_state(cfg);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
|
@ -127,8 +127,11 @@ static int submit_rtpg(struct scsi_device *sdev, unsigned char *buff,
|
|||||||
int bufflen, struct scsi_sense_hdr *sshdr, int flags)
|
int bufflen, struct scsi_sense_hdr *sshdr, int flags)
|
||||||
{
|
{
|
||||||
u8 cdb[MAX_COMMAND_SIZE];
|
u8 cdb[MAX_COMMAND_SIZE];
|
||||||
blk_opf_t req_flags = REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
|
blk_opf_t opf = REQ_OP_DRV_IN | REQ_FAILFAST_DEV |
|
||||||
REQ_FAILFAST_DRIVER;
|
REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER;
|
||||||
|
const struct scsi_exec_args exec_args = {
|
||||||
|
.sshdr = sshdr,
|
||||||
|
};
|
||||||
|
|
||||||
/* Prepare the command. */
|
/* Prepare the command. */
|
||||||
memset(cdb, 0x0, MAX_COMMAND_SIZE);
|
memset(cdb, 0x0, MAX_COMMAND_SIZE);
|
||||||
@ -139,9 +142,9 @@ static int submit_rtpg(struct scsi_device *sdev, unsigned char *buff,
|
|||||||
cdb[1] = MI_REPORT_TARGET_PGS;
|
cdb[1] = MI_REPORT_TARGET_PGS;
|
||||||
put_unaligned_be32(bufflen, &cdb[6]);
|
put_unaligned_be32(bufflen, &cdb[6]);
|
||||||
|
|
||||||
return scsi_execute(sdev, cdb, DMA_FROM_DEVICE, buff, bufflen, NULL,
|
return scsi_execute_cmd(sdev, cdb, opf, buff, bufflen,
|
||||||
sshdr, ALUA_FAILOVER_TIMEOUT * HZ,
|
ALUA_FAILOVER_TIMEOUT * HZ,
|
||||||
ALUA_FAILOVER_RETRIES, req_flags, 0, NULL);
|
ALUA_FAILOVER_RETRIES, &exec_args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -157,8 +160,11 @@ static int submit_stpg(struct scsi_device *sdev, int group_id,
|
|||||||
u8 cdb[MAX_COMMAND_SIZE];
|
u8 cdb[MAX_COMMAND_SIZE];
|
||||||
unsigned char stpg_data[8];
|
unsigned char stpg_data[8];
|
||||||
int stpg_len = 8;
|
int stpg_len = 8;
|
||||||
blk_opf_t req_flags = REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
|
blk_opf_t opf = REQ_OP_DRV_OUT | REQ_FAILFAST_DEV |
|
||||||
REQ_FAILFAST_DRIVER;
|
REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER;
|
||||||
|
const struct scsi_exec_args exec_args = {
|
||||||
|
.sshdr = sshdr,
|
||||||
|
};
|
||||||
|
|
||||||
/* Prepare the data buffer */
|
/* Prepare the data buffer */
|
||||||
memset(stpg_data, 0, stpg_len);
|
memset(stpg_data, 0, stpg_len);
|
||||||
@ -171,9 +177,9 @@ static int submit_stpg(struct scsi_device *sdev, int group_id,
|
|||||||
cdb[1] = MO_SET_TARGET_PGS;
|
cdb[1] = MO_SET_TARGET_PGS;
|
||||||
put_unaligned_be32(stpg_len, &cdb[6]);
|
put_unaligned_be32(stpg_len, &cdb[6]);
|
||||||
|
|
||||||
return scsi_execute(sdev, cdb, DMA_TO_DEVICE, stpg_data, stpg_len, NULL,
|
return scsi_execute_cmd(sdev, cdb, opf, stpg_data,
|
||||||
sshdr, ALUA_FAILOVER_TIMEOUT * HZ,
|
stpg_len, ALUA_FAILOVER_TIMEOUT * HZ,
|
||||||
ALUA_FAILOVER_RETRIES, req_flags, 0, NULL);
|
ALUA_FAILOVER_RETRIES, &exec_args);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct alua_port_group *alua_find_get_pg(char *id_str, size_t id_size,
|
static struct alua_port_group *alua_find_get_pg(char *id_str, size_t id_size,
|
||||||
|
@ -239,8 +239,11 @@ static int send_trespass_cmd(struct scsi_device *sdev,
|
|||||||
unsigned char cdb[MAX_COMMAND_SIZE];
|
unsigned char cdb[MAX_COMMAND_SIZE];
|
||||||
int err, res = SCSI_DH_OK, len;
|
int err, res = SCSI_DH_OK, len;
|
||||||
struct scsi_sense_hdr sshdr;
|
struct scsi_sense_hdr sshdr;
|
||||||
blk_opf_t req_flags = REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
|
blk_opf_t opf = REQ_OP_DRV_OUT | REQ_FAILFAST_DEV |
|
||||||
REQ_FAILFAST_DRIVER;
|
REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER;
|
||||||
|
const struct scsi_exec_args exec_args = {
|
||||||
|
.sshdr = &sshdr,
|
||||||
|
};
|
||||||
|
|
||||||
if (csdev->flags & CLARIION_SHORT_TRESPASS) {
|
if (csdev->flags & CLARIION_SHORT_TRESPASS) {
|
||||||
page22 = short_trespass;
|
page22 = short_trespass;
|
||||||
@ -263,9 +266,9 @@ static int send_trespass_cmd(struct scsi_device *sdev,
|
|||||||
BUG_ON((len > CLARIION_BUFFER_SIZE));
|
BUG_ON((len > CLARIION_BUFFER_SIZE));
|
||||||
memcpy(csdev->buffer, page22, len);
|
memcpy(csdev->buffer, page22, len);
|
||||||
|
|
||||||
err = scsi_execute(sdev, cdb, DMA_TO_DEVICE, csdev->buffer, len, NULL,
|
err = scsi_execute_cmd(sdev, cdb, opf, csdev->buffer, len,
|
||||||
&sshdr, CLARIION_TIMEOUT * HZ, CLARIION_RETRIES,
|
CLARIION_TIMEOUT * HZ, CLARIION_RETRIES,
|
||||||
req_flags, 0, NULL);
|
&exec_args);
|
||||||
if (err) {
|
if (err) {
|
||||||
if (scsi_sense_valid(&sshdr))
|
if (scsi_sense_valid(&sshdr))
|
||||||
res = trespass_endio(sdev, &sshdr);
|
res = trespass_endio(sdev, &sshdr);
|
||||||
|
@ -83,12 +83,15 @@ static int hp_sw_tur(struct scsi_device *sdev, struct hp_sw_dh_data *h)
|
|||||||
unsigned char cmd[6] = { TEST_UNIT_READY };
|
unsigned char cmd[6] = { TEST_UNIT_READY };
|
||||||
struct scsi_sense_hdr sshdr;
|
struct scsi_sense_hdr sshdr;
|
||||||
int ret = SCSI_DH_OK, res;
|
int ret = SCSI_DH_OK, res;
|
||||||
blk_opf_t req_flags = REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
|
blk_opf_t opf = REQ_OP_DRV_IN | REQ_FAILFAST_DEV |
|
||||||
REQ_FAILFAST_DRIVER;
|
REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER;
|
||||||
|
const struct scsi_exec_args exec_args = {
|
||||||
|
.sshdr = &sshdr,
|
||||||
|
};
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
res = scsi_execute(sdev, cmd, DMA_NONE, NULL, 0, NULL, &sshdr,
|
res = scsi_execute_cmd(sdev, cmd, opf, NULL, 0, HP_SW_TIMEOUT,
|
||||||
HP_SW_TIMEOUT, HP_SW_RETRIES, req_flags, 0, NULL);
|
HP_SW_RETRIES, &exec_args);
|
||||||
if (res) {
|
if (res) {
|
||||||
if (scsi_sense_valid(&sshdr))
|
if (scsi_sense_valid(&sshdr))
|
||||||
ret = tur_done(sdev, h, &sshdr);
|
ret = tur_done(sdev, h, &sshdr);
|
||||||
@ -121,12 +124,15 @@ static int hp_sw_start_stop(struct hp_sw_dh_data *h)
|
|||||||
struct scsi_device *sdev = h->sdev;
|
struct scsi_device *sdev = h->sdev;
|
||||||
int res, rc = SCSI_DH_OK;
|
int res, rc = SCSI_DH_OK;
|
||||||
int retry_cnt = HP_SW_RETRIES;
|
int retry_cnt = HP_SW_RETRIES;
|
||||||
blk_opf_t req_flags = REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
|
blk_opf_t opf = REQ_OP_DRV_IN | REQ_FAILFAST_DEV |
|
||||||
REQ_FAILFAST_DRIVER;
|
REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER;
|
||||||
|
const struct scsi_exec_args exec_args = {
|
||||||
|
.sshdr = &sshdr,
|
||||||
|
};
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
res = scsi_execute(sdev, cmd, DMA_NONE, NULL, 0, NULL, &sshdr,
|
res = scsi_execute_cmd(sdev, cmd, opf, NULL, 0, HP_SW_TIMEOUT,
|
||||||
HP_SW_TIMEOUT, HP_SW_RETRIES, req_flags, 0, NULL);
|
HP_SW_RETRIES, &exec_args);
|
||||||
if (res) {
|
if (res) {
|
||||||
if (!scsi_sense_valid(&sshdr)) {
|
if (!scsi_sense_valid(&sshdr)) {
|
||||||
sdev_printk(KERN_WARNING, sdev,
|
sdev_printk(KERN_WARNING, sdev,
|
||||||
|
@ -536,8 +536,11 @@ static void send_mode_select(struct work_struct *work)
|
|||||||
unsigned char cdb[MAX_COMMAND_SIZE];
|
unsigned char cdb[MAX_COMMAND_SIZE];
|
||||||
struct scsi_sense_hdr sshdr;
|
struct scsi_sense_hdr sshdr;
|
||||||
unsigned int data_size;
|
unsigned int data_size;
|
||||||
blk_opf_t req_flags = REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
|
blk_opf_t opf = REQ_OP_DRV_OUT | REQ_FAILFAST_DEV |
|
||||||
REQ_FAILFAST_DRIVER;
|
REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER;
|
||||||
|
const struct scsi_exec_args exec_args = {
|
||||||
|
.sshdr = &sshdr,
|
||||||
|
};
|
||||||
|
|
||||||
spin_lock(&ctlr->ms_lock);
|
spin_lock(&ctlr->ms_lock);
|
||||||
list_splice_init(&ctlr->ms_head, &list);
|
list_splice_init(&ctlr->ms_head, &list);
|
||||||
@ -555,9 +558,8 @@ static void send_mode_select(struct work_struct *work)
|
|||||||
(char *) h->ctlr->array_name, h->ctlr->index,
|
(char *) h->ctlr->array_name, h->ctlr->index,
|
||||||
(retry_cnt == RDAC_RETRY_COUNT) ? "queueing" : "retrying");
|
(retry_cnt == RDAC_RETRY_COUNT) ? "queueing" : "retrying");
|
||||||
|
|
||||||
if (scsi_execute(sdev, cdb, DMA_TO_DEVICE, &h->ctlr->mode_select,
|
if (scsi_execute_cmd(sdev, cdb, opf, &h->ctlr->mode_select, data_size,
|
||||||
data_size, NULL, &sshdr, RDAC_TIMEOUT * HZ,
|
RDAC_TIMEOUT * HZ, RDAC_RETRIES, &exec_args)) {
|
||||||
RDAC_RETRIES, req_flags, 0, NULL)) {
|
|
||||||
err = mode_select_handle_sense(sdev, &sshdr);
|
err = mode_select_handle_sense(sdev, &sshdr);
|
||||||
if (err == SCSI_DH_RETRY && retry_cnt--)
|
if (err == SCSI_DH_RETRY && retry_cnt--)
|
||||||
goto retry;
|
goto retry;
|
||||||
|
@ -309,8 +309,8 @@ static int scsi_vpd_inquiry(struct scsi_device *sdev, unsigned char *buffer,
|
|||||||
* I'm not convinced we need to try quite this hard to get VPD, but
|
* I'm not convinced we need to try quite this hard to get VPD, but
|
||||||
* all the existing users tried this hard.
|
* all the existing users tried this hard.
|
||||||
*/
|
*/
|
||||||
result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer,
|
result = scsi_execute_cmd(sdev, cmd, REQ_OP_DRV_IN, buffer, len,
|
||||||
len, NULL, 30 * HZ, 3, NULL);
|
30 * HZ, 3, NULL);
|
||||||
if (result)
|
if (result)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
@ -510,6 +510,9 @@ int scsi_report_opcode(struct scsi_device *sdev, unsigned char *buffer,
|
|||||||
unsigned char cmd[16];
|
unsigned char cmd[16];
|
||||||
struct scsi_sense_hdr sshdr;
|
struct scsi_sense_hdr sshdr;
|
||||||
int result, request_len;
|
int result, request_len;
|
||||||
|
const struct scsi_exec_args exec_args = {
|
||||||
|
.sshdr = &sshdr,
|
||||||
|
};
|
||||||
|
|
||||||
if (sdev->no_report_opcodes || sdev->scsi_level < SCSI_SPC_3)
|
if (sdev->no_report_opcodes || sdev->scsi_level < SCSI_SPC_3)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -531,9 +534,8 @@ int scsi_report_opcode(struct scsi_device *sdev, unsigned char *buffer,
|
|||||||
put_unaligned_be32(request_len, &cmd[6]);
|
put_unaligned_be32(request_len, &cmd[6]);
|
||||||
memset(buffer, 0, len);
|
memset(buffer, 0, len);
|
||||||
|
|
||||||
result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer,
|
result = scsi_execute_cmd(sdev, cmd, REQ_OP_DRV_IN, buffer,
|
||||||
request_len, &sshdr, 30 * HZ, 3, NULL);
|
request_len, 30 * HZ, 3, &exec_args);
|
||||||
|
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
return result;
|
return result;
|
||||||
if (result && scsi_sense_valid(&sshdr) &&
|
if (result && scsi_sense_valid(&sshdr) &&
|
||||||
|
@ -69,12 +69,15 @@ static int ioctl_internal_command(struct scsi_device *sdev, char *cmd,
|
|||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
struct scsi_sense_hdr sshdr;
|
struct scsi_sense_hdr sshdr;
|
||||||
|
const struct scsi_exec_args exec_args = {
|
||||||
|
.sshdr = &sshdr,
|
||||||
|
};
|
||||||
|
|
||||||
SCSI_LOG_IOCTL(1, sdev_printk(KERN_INFO, sdev,
|
SCSI_LOG_IOCTL(1, sdev_printk(KERN_INFO, sdev,
|
||||||
"Trying ioctl with scsi command %d\n", *cmd));
|
"Trying ioctl with scsi command %d\n", *cmd));
|
||||||
|
|
||||||
result = scsi_execute_req(sdev, cmd, DMA_NONE, NULL, 0,
|
result = scsi_execute_cmd(sdev, cmd, REQ_OP_DRV_IN, NULL, 0, timeout,
|
||||||
&sshdr, timeout, retries, NULL);
|
retries, &exec_args);
|
||||||
|
|
||||||
SCSI_LOG_IOCTL(2, sdev_printk(KERN_INFO, sdev,
|
SCSI_LOG_IOCTL(2, sdev_printk(KERN_INFO, sdev,
|
||||||
"Ioctl returned 0x%x\n", result));
|
"Ioctl returned 0x%x\n", result));
|
||||||
|
@ -185,39 +185,37 @@ void scsi_queue_insert(struct scsi_cmnd *cmd, int reason)
|
|||||||
__scsi_queue_insert(cmd, reason, true);
|
__scsi_queue_insert(cmd, reason, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* __scsi_execute - insert request and wait for the result
|
* scsi_execute_cmd - insert request and wait for the result
|
||||||
* @sdev: scsi device
|
* @sdev: scsi_device
|
||||||
* @cmd: scsi command
|
* @cmd: scsi command
|
||||||
* @data_direction: data direction
|
* @opf: block layer request cmd_flags
|
||||||
* @buffer: data buffer
|
* @buffer: data buffer
|
||||||
* @bufflen: len of buffer
|
* @bufflen: len of buffer
|
||||||
* @sense: optional sense buffer
|
|
||||||
* @sshdr: optional decoded sense header
|
|
||||||
* @timeout: request timeout in HZ
|
* @timeout: request timeout in HZ
|
||||||
* @retries: number of times to retry request
|
* @retries: number of times to retry request
|
||||||
* @flags: flags for ->cmd_flags
|
* @args: Optional args. See struct definition for field descriptions
|
||||||
* @rq_flags: flags for ->rq_flags
|
|
||||||
* @resid: optional residual length
|
|
||||||
*
|
*
|
||||||
* Returns the scsi_cmnd result field if a command was executed, or a negative
|
* Returns the scsi_cmnd result field if a command was executed, or a negative
|
||||||
* Linux error code if we didn't get that far.
|
* Linux error code if we didn't get that far.
|
||||||
*/
|
*/
|
||||||
int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
|
int scsi_execute_cmd(struct scsi_device *sdev, const unsigned char *cmd,
|
||||||
int data_direction, void *buffer, unsigned bufflen,
|
blk_opf_t opf, void *buffer, unsigned int bufflen,
|
||||||
unsigned char *sense, struct scsi_sense_hdr *sshdr,
|
int timeout, int retries,
|
||||||
int timeout, int retries, blk_opf_t flags,
|
const struct scsi_exec_args *args)
|
||||||
req_flags_t rq_flags, int *resid)
|
|
||||||
{
|
{
|
||||||
|
static const struct scsi_exec_args default_args;
|
||||||
struct request *req;
|
struct request *req;
|
||||||
struct scsi_cmnd *scmd;
|
struct scsi_cmnd *scmd;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
req = scsi_alloc_request(sdev->request_queue,
|
if (!args)
|
||||||
data_direction == DMA_TO_DEVICE ?
|
args = &default_args;
|
||||||
REQ_OP_DRV_OUT : REQ_OP_DRV_IN,
|
else if (WARN_ON_ONCE(args->sense &&
|
||||||
rq_flags & RQF_PM ? BLK_MQ_REQ_PM : 0);
|
args->sense_len != SCSI_SENSE_BUFFERSIZE))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
req = scsi_alloc_request(sdev->request_queue, opf, args->req_flags);
|
||||||
if (IS_ERR(req))
|
if (IS_ERR(req))
|
||||||
return PTR_ERR(req);
|
return PTR_ERR(req);
|
||||||
|
|
||||||
@ -232,8 +230,7 @@ int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
|
|||||||
memcpy(scmd->cmnd, cmd, scmd->cmd_len);
|
memcpy(scmd->cmnd, cmd, scmd->cmd_len);
|
||||||
scmd->allowed = retries;
|
scmd->allowed = retries;
|
||||||
req->timeout = timeout;
|
req->timeout = timeout;
|
||||||
req->cmd_flags |= flags;
|
req->rq_flags |= RQF_QUIET;
|
||||||
req->rq_flags |= rq_flags | RQF_QUIET;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* head injection *required* here otherwise quiesce won't work
|
* head injection *required* here otherwise quiesce won't work
|
||||||
@ -249,20 +246,21 @@ int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
|
|||||||
if (unlikely(scmd->resid_len > 0 && scmd->resid_len <= bufflen))
|
if (unlikely(scmd->resid_len > 0 && scmd->resid_len <= bufflen))
|
||||||
memset(buffer + bufflen - scmd->resid_len, 0, scmd->resid_len);
|
memset(buffer + bufflen - scmd->resid_len, 0, scmd->resid_len);
|
||||||
|
|
||||||
if (resid)
|
if (args->resid)
|
||||||
*resid = scmd->resid_len;
|
*args->resid = scmd->resid_len;
|
||||||
if (sense && scmd->sense_len)
|
if (args->sense)
|
||||||
memcpy(sense, scmd->sense_buffer, SCSI_SENSE_BUFFERSIZE);
|
memcpy(args->sense, scmd->sense_buffer, SCSI_SENSE_BUFFERSIZE);
|
||||||
if (sshdr)
|
if (args->sshdr)
|
||||||
scsi_normalize_sense(scmd->sense_buffer, scmd->sense_len,
|
scsi_normalize_sense(scmd->sense_buffer, scmd->sense_len,
|
||||||
sshdr);
|
args->sshdr);
|
||||||
|
|
||||||
ret = scmd->result;
|
ret = scmd->result;
|
||||||
out:
|
out:
|
||||||
blk_mq_free_request(req);
|
blk_mq_free_request(req);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(__scsi_execute);
|
EXPORT_SYMBOL(scsi_execute_cmd);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wake up the error handler if necessary. Avoid as follows that the error
|
* Wake up the error handler if necessary. Avoid as follows that the error
|
||||||
@ -2086,6 +2084,9 @@ int scsi_mode_select(struct scsi_device *sdev, int pf, int sp,
|
|||||||
{
|
{
|
||||||
unsigned char cmd[10];
|
unsigned char cmd[10];
|
||||||
unsigned char *real_buffer;
|
unsigned char *real_buffer;
|
||||||
|
const struct scsi_exec_args exec_args = {
|
||||||
|
.sshdr = sshdr,
|
||||||
|
};
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
memset(cmd, 0, sizeof(cmd));
|
memset(cmd, 0, sizeof(cmd));
|
||||||
@ -2135,8 +2136,8 @@ int scsi_mode_select(struct scsi_device *sdev, int pf, int sp,
|
|||||||
cmd[4] = len;
|
cmd[4] = len;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = scsi_execute_req(sdev, cmd, DMA_TO_DEVICE, real_buffer, len,
|
ret = scsi_execute_cmd(sdev, cmd, REQ_OP_DRV_OUT, real_buffer, len,
|
||||||
sshdr, timeout, retries, NULL);
|
timeout, retries, &exec_args);
|
||||||
kfree(real_buffer);
|
kfree(real_buffer);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -2167,6 +2168,10 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
|
|||||||
int header_length;
|
int header_length;
|
||||||
int result, retry_count = retries;
|
int result, retry_count = retries;
|
||||||
struct scsi_sense_hdr my_sshdr;
|
struct scsi_sense_hdr my_sshdr;
|
||||||
|
const struct scsi_exec_args exec_args = {
|
||||||
|
/* caller might not be interested in sense, but we need it */
|
||||||
|
.sshdr = sshdr ? : &my_sshdr,
|
||||||
|
};
|
||||||
|
|
||||||
memset(data, 0, sizeof(*data));
|
memset(data, 0, sizeof(*data));
|
||||||
memset(&cmd[0], 0, 12);
|
memset(&cmd[0], 0, 12);
|
||||||
@ -2175,9 +2180,7 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
|
|||||||
cmd[1] = dbd & 0x18; /* allows DBD and LLBA bits */
|
cmd[1] = dbd & 0x18; /* allows DBD and LLBA bits */
|
||||||
cmd[2] = modepage;
|
cmd[2] = modepage;
|
||||||
|
|
||||||
/* caller might not be interested in sense, but we need it */
|
sshdr = exec_args.sshdr;
|
||||||
if (!sshdr)
|
|
||||||
sshdr = &my_sshdr;
|
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
use_10_for_ms = sdev->use_10_for_ms || len > 255;
|
use_10_for_ms = sdev->use_10_for_ms || len > 255;
|
||||||
@ -2200,8 +2203,8 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
|
|||||||
|
|
||||||
memset(buffer, 0, len);
|
memset(buffer, 0, len);
|
||||||
|
|
||||||
result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer, len,
|
result = scsi_execute_cmd(sdev, cmd, REQ_OP_DRV_IN, buffer, len,
|
||||||
sshdr, timeout, retries, NULL);
|
timeout, retries, &exec_args);
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
@ -2281,12 +2284,15 @@ scsi_test_unit_ready(struct scsi_device *sdev, int timeout, int retries,
|
|||||||
char cmd[] = {
|
char cmd[] = {
|
||||||
TEST_UNIT_READY, 0, 0, 0, 0, 0,
|
TEST_UNIT_READY, 0, 0, 0, 0, 0,
|
||||||
};
|
};
|
||||||
|
const struct scsi_exec_args exec_args = {
|
||||||
|
.sshdr = sshdr,
|
||||||
|
};
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
/* try to eat the UNIT_ATTENTION if there are enough retries */
|
/* try to eat the UNIT_ATTENTION if there are enough retries */
|
||||||
do {
|
do {
|
||||||
result = scsi_execute_req(sdev, cmd, DMA_NONE, NULL, 0, sshdr,
|
result = scsi_execute_cmd(sdev, cmd, REQ_OP_DRV_IN, NULL, 0,
|
||||||
timeout, 1, NULL);
|
timeout, 1, &exec_args);
|
||||||
if (sdev->removable && scsi_sense_valid(sshdr) &&
|
if (sdev->removable && scsi_sense_valid(sshdr) &&
|
||||||
sshdr->sense_key == UNIT_ATTENTION)
|
sshdr->sense_key == UNIT_ATTENTION)
|
||||||
sdev->changed = 1;
|
sdev->changed = 1;
|
||||||
|
@ -210,7 +210,7 @@ static void scsi_unlock_floptical(struct scsi_device *sdev,
|
|||||||
scsi_cmd[3] = 0;
|
scsi_cmd[3] = 0;
|
||||||
scsi_cmd[4] = 0x2a; /* size */
|
scsi_cmd[4] = 0x2a; /* size */
|
||||||
scsi_cmd[5] = 0;
|
scsi_cmd[5] = 0;
|
||||||
scsi_execute_req(sdev, scsi_cmd, DMA_FROM_DEVICE, result, 0x2a, NULL,
|
scsi_execute_cmd(sdev, scsi_cmd, REQ_OP_DRV_IN, result, 0x2a,
|
||||||
SCSI_TIMEOUT, 3, NULL);
|
SCSI_TIMEOUT, 3, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -646,8 +646,12 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result,
|
|||||||
unsigned char scsi_cmd[MAX_COMMAND_SIZE];
|
unsigned char scsi_cmd[MAX_COMMAND_SIZE];
|
||||||
int first_inquiry_len, try_inquiry_len, next_inquiry_len;
|
int first_inquiry_len, try_inquiry_len, next_inquiry_len;
|
||||||
int response_len = 0;
|
int response_len = 0;
|
||||||
int pass, count, result;
|
int pass, count, result, resid;
|
||||||
struct scsi_sense_hdr sshdr;
|
struct scsi_sense_hdr sshdr;
|
||||||
|
const struct scsi_exec_args exec_args = {
|
||||||
|
.sshdr = &sshdr,
|
||||||
|
.resid = &resid,
|
||||||
|
};
|
||||||
|
|
||||||
*bflags = 0;
|
*bflags = 0;
|
||||||
|
|
||||||
@ -665,18 +669,16 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result,
|
|||||||
|
|
||||||
/* Each pass gets up to three chances to ignore Unit Attention */
|
/* Each pass gets up to three chances to ignore Unit Attention */
|
||||||
for (count = 0; count < 3; ++count) {
|
for (count = 0; count < 3; ++count) {
|
||||||
int resid;
|
|
||||||
|
|
||||||
memset(scsi_cmd, 0, 6);
|
memset(scsi_cmd, 0, 6);
|
||||||
scsi_cmd[0] = INQUIRY;
|
scsi_cmd[0] = INQUIRY;
|
||||||
scsi_cmd[4] = (unsigned char) try_inquiry_len;
|
scsi_cmd[4] = (unsigned char) try_inquiry_len;
|
||||||
|
|
||||||
memset(inq_result, 0, try_inquiry_len);
|
memset(inq_result, 0, try_inquiry_len);
|
||||||
|
|
||||||
result = scsi_execute_req(sdev, scsi_cmd, DMA_FROM_DEVICE,
|
result = scsi_execute_cmd(sdev, scsi_cmd, REQ_OP_DRV_IN,
|
||||||
inq_result, try_inquiry_len, &sshdr,
|
inq_result, try_inquiry_len,
|
||||||
HZ / 2 + HZ * scsi_inq_timeout, 3,
|
HZ / 2 + HZ * scsi_inq_timeout, 3,
|
||||||
&resid);
|
&exec_args);
|
||||||
|
|
||||||
SCSI_LOG_SCAN_BUS(3, sdev_printk(KERN_INFO, sdev,
|
SCSI_LOG_SCAN_BUS(3, sdev_printk(KERN_INFO, sdev,
|
||||||
"scsi scan: INQUIRY %s with code 0x%x\n",
|
"scsi scan: INQUIRY %s with code 0x%x\n",
|
||||||
@ -1402,6 +1404,9 @@ static int scsi_report_lun_scan(struct scsi_target *starget, blist_flags_t bflag
|
|||||||
struct scsi_sense_hdr sshdr;
|
struct scsi_sense_hdr sshdr;
|
||||||
struct scsi_device *sdev;
|
struct scsi_device *sdev;
|
||||||
struct Scsi_Host *shost = dev_to_shost(&starget->dev);
|
struct Scsi_Host *shost = dev_to_shost(&starget->dev);
|
||||||
|
const struct scsi_exec_args exec_args = {
|
||||||
|
.sshdr = &sshdr,
|
||||||
|
};
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1476,9 +1481,10 @@ retry:
|
|||||||
"scsi scan: Sending REPORT LUNS to (try %d)\n",
|
"scsi scan: Sending REPORT LUNS to (try %d)\n",
|
||||||
retries));
|
retries));
|
||||||
|
|
||||||
result = scsi_execute_req(sdev, scsi_cmd, DMA_FROM_DEVICE,
|
result = scsi_execute_cmd(sdev, scsi_cmd, REQ_OP_DRV_IN,
|
||||||
lun_data, length, &sshdr,
|
lun_data, length,
|
||||||
SCSI_REPORT_LUNS_TIMEOUT, 3, NULL);
|
SCSI_REPORT_LUNS_TIMEOUT, 3,
|
||||||
|
&exec_args);
|
||||||
|
|
||||||
SCSI_LOG_SCAN_BUS(3, sdev_printk (KERN_INFO, sdev,
|
SCSI_LOG_SCAN_BUS(3, sdev_printk (KERN_INFO, sdev,
|
||||||
"scsi scan: REPORT LUNS"
|
"scsi scan: REPORT LUNS"
|
||||||
|
@ -105,28 +105,27 @@ static int sprint_frac(char *dest, int value, int denom)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int spi_execute(struct scsi_device *sdev, const void *cmd,
|
static int spi_execute(struct scsi_device *sdev, const void *cmd,
|
||||||
enum dma_data_direction dir,
|
enum req_op op, void *buffer, unsigned int bufflen,
|
||||||
void *buffer, unsigned bufflen,
|
|
||||||
struct scsi_sense_hdr *sshdr)
|
struct scsi_sense_hdr *sshdr)
|
||||||
{
|
{
|
||||||
int i, result;
|
int i, result;
|
||||||
unsigned char sense[SCSI_SENSE_BUFFERSIZE];
|
|
||||||
struct scsi_sense_hdr sshdr_tmp;
|
struct scsi_sense_hdr sshdr_tmp;
|
||||||
|
blk_opf_t opf = op | REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
|
||||||
|
REQ_FAILFAST_DRIVER;
|
||||||
|
const struct scsi_exec_args exec_args = {
|
||||||
|
.req_flags = BLK_MQ_REQ_PM,
|
||||||
|
.sshdr = sshdr ? : &sshdr_tmp,
|
||||||
|
};
|
||||||
|
|
||||||
if (!sshdr)
|
sshdr = exec_args.sshdr;
|
||||||
sshdr = &sshdr_tmp;
|
|
||||||
|
|
||||||
for(i = 0; i < DV_RETRIES; i++) {
|
for(i = 0; i < DV_RETRIES; i++) {
|
||||||
/*
|
/*
|
||||||
* The purpose of the RQF_PM flag below is to bypass the
|
* The purpose of the RQF_PM flag below is to bypass the
|
||||||
* SDEV_QUIESCE state.
|
* SDEV_QUIESCE state.
|
||||||
*/
|
*/
|
||||||
result = scsi_execute(sdev, cmd, dir, buffer, bufflen, sense,
|
result = scsi_execute_cmd(sdev, cmd, opf, buffer, bufflen,
|
||||||
sshdr, DV_TIMEOUT, /* retries */ 1,
|
DV_TIMEOUT, 1, &exec_args);
|
||||||
REQ_FAILFAST_DEV |
|
|
||||||
REQ_FAILFAST_TRANSPORT |
|
|
||||||
REQ_FAILFAST_DRIVER,
|
|
||||||
RQF_PM, NULL);
|
|
||||||
if (result < 0 || !scsi_sense_valid(sshdr) ||
|
if (result < 0 || !scsi_sense_valid(sshdr) ||
|
||||||
sshdr->sense_key != UNIT_ATTENTION)
|
sshdr->sense_key != UNIT_ATTENTION)
|
||||||
break;
|
break;
|
||||||
@ -675,7 +674,7 @@ spi_dv_device_echo_buffer(struct scsi_device *sdev, u8 *buffer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (r = 0; r < retries; r++) {
|
for (r = 0; r < retries; r++) {
|
||||||
result = spi_execute(sdev, spi_write_buffer, DMA_TO_DEVICE,
|
result = spi_execute(sdev, spi_write_buffer, REQ_OP_DRV_OUT,
|
||||||
buffer, len, &sshdr);
|
buffer, len, &sshdr);
|
||||||
if(result || !scsi_device_online(sdev)) {
|
if(result || !scsi_device_online(sdev)) {
|
||||||
|
|
||||||
@ -697,7 +696,7 @@ spi_dv_device_echo_buffer(struct scsi_device *sdev, u8 *buffer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
memset(ptr, 0, len);
|
memset(ptr, 0, len);
|
||||||
spi_execute(sdev, spi_read_buffer, DMA_FROM_DEVICE,
|
spi_execute(sdev, spi_read_buffer, REQ_OP_DRV_IN,
|
||||||
ptr, len, NULL);
|
ptr, len, NULL);
|
||||||
scsi_device_set_state(sdev, SDEV_QUIESCE);
|
scsi_device_set_state(sdev, SDEV_QUIESCE);
|
||||||
|
|
||||||
@ -722,7 +721,7 @@ spi_dv_device_compare_inquiry(struct scsi_device *sdev, u8 *buffer,
|
|||||||
for (r = 0; r < retries; r++) {
|
for (r = 0; r < retries; r++) {
|
||||||
memset(ptr, 0, len);
|
memset(ptr, 0, len);
|
||||||
|
|
||||||
result = spi_execute(sdev, spi_inquiry, DMA_FROM_DEVICE,
|
result = spi_execute(sdev, spi_inquiry, REQ_OP_DRV_IN,
|
||||||
ptr, len, NULL);
|
ptr, len, NULL);
|
||||||
|
|
||||||
if(result || !scsi_device_online(sdev)) {
|
if(result || !scsi_device_online(sdev)) {
|
||||||
@ -828,7 +827,7 @@ spi_dv_device_get_echo_buffer(struct scsi_device *sdev, u8 *buffer)
|
|||||||
* (reservation conflict, device not ready, etc) just
|
* (reservation conflict, device not ready, etc) just
|
||||||
* skip the write tests */
|
* skip the write tests */
|
||||||
for (l = 0; ; l++) {
|
for (l = 0; ; l++) {
|
||||||
result = spi_execute(sdev, spi_test_unit_ready, DMA_NONE,
|
result = spi_execute(sdev, spi_test_unit_ready, REQ_OP_DRV_IN,
|
||||||
NULL, 0, NULL);
|
NULL, 0, NULL);
|
||||||
|
|
||||||
if(result) {
|
if(result) {
|
||||||
@ -841,7 +840,7 @@ spi_dv_device_get_echo_buffer(struct scsi_device *sdev, u8 *buffer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
result = spi_execute(sdev, spi_read_buffer_descriptor,
|
result = spi_execute(sdev, spi_read_buffer_descriptor,
|
||||||
DMA_FROM_DEVICE, buffer, 4, NULL);
|
REQ_OP_DRV_IN, buffer, 4, NULL);
|
||||||
|
|
||||||
if (result)
|
if (result)
|
||||||
/* Device has no echo buffer */
|
/* Device has no echo buffer */
|
||||||
|
@ -664,6 +664,9 @@ static int sd_sec_submit(void *data, u16 spsp, u8 secp, void *buffer,
|
|||||||
struct scsi_disk *sdkp = data;
|
struct scsi_disk *sdkp = data;
|
||||||
struct scsi_device *sdev = sdkp->device;
|
struct scsi_device *sdev = sdkp->device;
|
||||||
u8 cdb[12] = { 0, };
|
u8 cdb[12] = { 0, };
|
||||||
|
const struct scsi_exec_args exec_args = {
|
||||||
|
.req_flags = BLK_MQ_REQ_PM,
|
||||||
|
};
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
cdb[0] = send ? SECURITY_PROTOCOL_OUT : SECURITY_PROTOCOL_IN;
|
cdb[0] = send ? SECURITY_PROTOCOL_OUT : SECURITY_PROTOCOL_IN;
|
||||||
@ -671,9 +674,9 @@ static int sd_sec_submit(void *data, u16 spsp, u8 secp, void *buffer,
|
|||||||
put_unaligned_be16(spsp, &cdb[2]);
|
put_unaligned_be16(spsp, &cdb[2]);
|
||||||
put_unaligned_be32(len, &cdb[6]);
|
put_unaligned_be32(len, &cdb[6]);
|
||||||
|
|
||||||
ret = scsi_execute(sdev, cdb, send ? DMA_TO_DEVICE : DMA_FROM_DEVICE,
|
ret = scsi_execute_cmd(sdev, cdb, send ? REQ_OP_DRV_OUT : REQ_OP_DRV_IN,
|
||||||
buffer, len, NULL, NULL, SD_TIMEOUT, sdkp->max_retries, 0,
|
buffer, len, SD_TIMEOUT, sdkp->max_retries,
|
||||||
RQF_PM, NULL);
|
&exec_args);
|
||||||
return ret <= 0 ? ret : -EIO;
|
return ret <= 0 ? ret : -EIO;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_BLK_SED_OPAL */
|
#endif /* CONFIG_BLK_SED_OPAL */
|
||||||
@ -1583,13 +1586,16 @@ static int sd_sync_cache(struct scsi_disk *sdkp, struct scsi_sense_hdr *sshdr)
|
|||||||
const int timeout = sdp->request_queue->rq_timeout
|
const int timeout = sdp->request_queue->rq_timeout
|
||||||
* SD_FLUSH_TIMEOUT_MULTIPLIER;
|
* SD_FLUSH_TIMEOUT_MULTIPLIER;
|
||||||
struct scsi_sense_hdr my_sshdr;
|
struct scsi_sense_hdr my_sshdr;
|
||||||
|
const struct scsi_exec_args exec_args = {
|
||||||
|
.req_flags = BLK_MQ_REQ_PM,
|
||||||
|
/* caller might not be interested in sense, but we need it */
|
||||||
|
.sshdr = sshdr ? : &my_sshdr,
|
||||||
|
};
|
||||||
|
|
||||||
if (!scsi_device_online(sdp))
|
if (!scsi_device_online(sdp))
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
/* caller might not be interested in sense, but we need it */
|
sshdr = exec_args.sshdr;
|
||||||
if (!sshdr)
|
|
||||||
sshdr = &my_sshdr;
|
|
||||||
|
|
||||||
for (retries = 3; retries > 0; --retries) {
|
for (retries = 3; retries > 0; --retries) {
|
||||||
unsigned char cmd[16] = { 0 };
|
unsigned char cmd[16] = { 0 };
|
||||||
@ -1602,8 +1608,8 @@ static int sd_sync_cache(struct scsi_disk *sdkp, struct scsi_sense_hdr *sshdr)
|
|||||||
* Leave the rest of the command zero to indicate
|
* Leave the rest of the command zero to indicate
|
||||||
* flush everything.
|
* flush everything.
|
||||||
*/
|
*/
|
||||||
res = scsi_execute(sdp, cmd, DMA_NONE, NULL, 0, NULL, sshdr,
|
res = scsi_execute_cmd(sdp, cmd, REQ_OP_DRV_IN, NULL, 0,
|
||||||
timeout, sdkp->max_retries, 0, RQF_PM, NULL);
|
timeout, sdkp->max_retries, &exec_args);
|
||||||
if (res == 0)
|
if (res == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1745,6 +1751,9 @@ static int sd_pr_command(struct block_device *bdev, u8 sa,
|
|||||||
struct scsi_disk *sdkp = scsi_disk(bdev->bd_disk);
|
struct scsi_disk *sdkp = scsi_disk(bdev->bd_disk);
|
||||||
struct scsi_device *sdev = sdkp->device;
|
struct scsi_device *sdev = sdkp->device;
|
||||||
struct scsi_sense_hdr sshdr;
|
struct scsi_sense_hdr sshdr;
|
||||||
|
const struct scsi_exec_args exec_args = {
|
||||||
|
.sshdr = &sshdr,
|
||||||
|
};
|
||||||
int result;
|
int result;
|
||||||
u8 cmd[16] = { 0, };
|
u8 cmd[16] = { 0, };
|
||||||
u8 data[24] = { 0, };
|
u8 data[24] = { 0, };
|
||||||
@ -1758,8 +1767,9 @@ static int sd_pr_command(struct block_device *bdev, u8 sa,
|
|||||||
put_unaligned_be64(sa_key, &data[8]);
|
put_unaligned_be64(sa_key, &data[8]);
|
||||||
data[20] = flags;
|
data[20] = flags;
|
||||||
|
|
||||||
result = scsi_execute_req(sdev, cmd, DMA_TO_DEVICE, &data, sizeof(data),
|
result = scsi_execute_cmd(sdev, cmd, REQ_OP_DRV_OUT, &data,
|
||||||
&sshdr, SD_TIMEOUT, sdkp->max_retries, NULL);
|
sizeof(data), SD_TIMEOUT, sdkp->max_retries,
|
||||||
|
&exec_args);
|
||||||
|
|
||||||
if (scsi_status_is_check_condition(result) &&
|
if (scsi_status_is_check_condition(result) &&
|
||||||
scsi_sense_valid(&sshdr)) {
|
scsi_sense_valid(&sshdr)) {
|
||||||
@ -2088,6 +2098,9 @@ sd_spinup_disk(struct scsi_disk *sdkp)
|
|||||||
int retries, spintime;
|
int retries, spintime;
|
||||||
unsigned int the_result;
|
unsigned int the_result;
|
||||||
struct scsi_sense_hdr sshdr;
|
struct scsi_sense_hdr sshdr;
|
||||||
|
const struct scsi_exec_args exec_args = {
|
||||||
|
.sshdr = &sshdr,
|
||||||
|
};
|
||||||
int sense_valid = 0;
|
int sense_valid = 0;
|
||||||
|
|
||||||
spintime = 0;
|
spintime = 0;
|
||||||
@ -2103,10 +2116,11 @@ sd_spinup_disk(struct scsi_disk *sdkp)
|
|||||||
cmd[0] = TEST_UNIT_READY;
|
cmd[0] = TEST_UNIT_READY;
|
||||||
memset((void *) &cmd[1], 0, 9);
|
memset((void *) &cmd[1], 0, 9);
|
||||||
|
|
||||||
the_result = scsi_execute_req(sdkp->device, cmd,
|
the_result = scsi_execute_cmd(sdkp->device, cmd,
|
||||||
DMA_NONE, NULL, 0,
|
REQ_OP_DRV_IN, NULL, 0,
|
||||||
&sshdr, SD_TIMEOUT,
|
SD_TIMEOUT,
|
||||||
sdkp->max_retries, NULL);
|
sdkp->max_retries,
|
||||||
|
&exec_args);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the drive has indicated to us that it
|
* If the drive has indicated to us that it
|
||||||
@ -2163,10 +2177,10 @@ sd_spinup_disk(struct scsi_disk *sdkp)
|
|||||||
cmd[4] = 1; /* Start spin cycle */
|
cmd[4] = 1; /* Start spin cycle */
|
||||||
if (sdkp->device->start_stop_pwr_cond)
|
if (sdkp->device->start_stop_pwr_cond)
|
||||||
cmd[4] |= 1 << 4;
|
cmd[4] |= 1 << 4;
|
||||||
scsi_execute_req(sdkp->device, cmd, DMA_NONE,
|
scsi_execute_cmd(sdkp->device, cmd,
|
||||||
NULL, 0, &sshdr,
|
REQ_OP_DRV_IN, NULL, 0,
|
||||||
SD_TIMEOUT, sdkp->max_retries,
|
SD_TIMEOUT, sdkp->max_retries,
|
||||||
NULL);
|
&exec_args);
|
||||||
spintime_expire = jiffies + 100 * HZ;
|
spintime_expire = jiffies + 100 * HZ;
|
||||||
spintime = 1;
|
spintime = 1;
|
||||||
}
|
}
|
||||||
@ -2296,6 +2310,9 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp,
|
|||||||
{
|
{
|
||||||
unsigned char cmd[16];
|
unsigned char cmd[16];
|
||||||
struct scsi_sense_hdr sshdr;
|
struct scsi_sense_hdr sshdr;
|
||||||
|
const struct scsi_exec_args exec_args = {
|
||||||
|
.sshdr = &sshdr,
|
||||||
|
};
|
||||||
int sense_valid = 0;
|
int sense_valid = 0;
|
||||||
int the_result;
|
int the_result;
|
||||||
int retries = 3, reset_retries = READ_CAPACITY_RETRIES_ON_RESET;
|
int retries = 3, reset_retries = READ_CAPACITY_RETRIES_ON_RESET;
|
||||||
@ -2313,9 +2330,9 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp,
|
|||||||
cmd[13] = RC16_LEN;
|
cmd[13] = RC16_LEN;
|
||||||
memset(buffer, 0, RC16_LEN);
|
memset(buffer, 0, RC16_LEN);
|
||||||
|
|
||||||
the_result = scsi_execute_req(sdp, cmd, DMA_FROM_DEVICE,
|
the_result = scsi_execute_cmd(sdp, cmd, REQ_OP_DRV_IN,
|
||||||
buffer, RC16_LEN, &sshdr,
|
buffer, RC16_LEN, SD_TIMEOUT,
|
||||||
SD_TIMEOUT, sdkp->max_retries, NULL);
|
sdkp->max_retries, &exec_args);
|
||||||
|
|
||||||
if (media_not_present(sdkp, &sshdr))
|
if (media_not_present(sdkp, &sshdr))
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
@ -2387,6 +2404,9 @@ static int read_capacity_10(struct scsi_disk *sdkp, struct scsi_device *sdp,
|
|||||||
{
|
{
|
||||||
unsigned char cmd[16];
|
unsigned char cmd[16];
|
||||||
struct scsi_sense_hdr sshdr;
|
struct scsi_sense_hdr sshdr;
|
||||||
|
const struct scsi_exec_args exec_args = {
|
||||||
|
.sshdr = &sshdr,
|
||||||
|
};
|
||||||
int sense_valid = 0;
|
int sense_valid = 0;
|
||||||
int the_result;
|
int the_result;
|
||||||
int retries = 3, reset_retries = READ_CAPACITY_RETRIES_ON_RESET;
|
int retries = 3, reset_retries = READ_CAPACITY_RETRIES_ON_RESET;
|
||||||
@ -2398,9 +2418,9 @@ static int read_capacity_10(struct scsi_disk *sdkp, struct scsi_device *sdp,
|
|||||||
memset(&cmd[1], 0, 9);
|
memset(&cmd[1], 0, 9);
|
||||||
memset(buffer, 0, 8);
|
memset(buffer, 0, 8);
|
||||||
|
|
||||||
the_result = scsi_execute_req(sdp, cmd, DMA_FROM_DEVICE,
|
the_result = scsi_execute_cmd(sdp, cmd, REQ_OP_DRV_IN, buffer,
|
||||||
buffer, 8, &sshdr,
|
8, SD_TIMEOUT, sdkp->max_retries,
|
||||||
SD_TIMEOUT, sdkp->max_retries, NULL);
|
&exec_args);
|
||||||
|
|
||||||
if (media_not_present(sdkp, &sshdr))
|
if (media_not_present(sdkp, &sshdr))
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
@ -3637,6 +3657,10 @@ static int sd_start_stop_device(struct scsi_disk *sdkp, int start)
|
|||||||
{
|
{
|
||||||
unsigned char cmd[6] = { START_STOP }; /* START_VALID */
|
unsigned char cmd[6] = { START_STOP }; /* START_VALID */
|
||||||
struct scsi_sense_hdr sshdr;
|
struct scsi_sense_hdr sshdr;
|
||||||
|
const struct scsi_exec_args exec_args = {
|
||||||
|
.sshdr = &sshdr,
|
||||||
|
.req_flags = BLK_MQ_REQ_PM,
|
||||||
|
};
|
||||||
struct scsi_device *sdp = sdkp->device;
|
struct scsi_device *sdp = sdkp->device;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
@ -3649,8 +3673,8 @@ static int sd_start_stop_device(struct scsi_disk *sdkp, int start)
|
|||||||
if (!scsi_device_online(sdp))
|
if (!scsi_device_online(sdp))
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
res = scsi_execute(sdp, cmd, DMA_NONE, NULL, 0, NULL, &sshdr,
|
res = scsi_execute_cmd(sdp, cmd, REQ_OP_DRV_IN, NULL, 0, SD_TIMEOUT,
|
||||||
SD_TIMEOUT, sdkp->max_retries, 0, RQF_PM, NULL);
|
sdkp->max_retries, &exec_args);
|
||||||
if (res) {
|
if (res) {
|
||||||
sd_print_result(sdkp, "Start/Stop Unit failed", res);
|
sd_print_result(sdkp, "Start/Stop Unit failed", res);
|
||||||
if (res > 0 && scsi_sense_valid(&sshdr)) {
|
if (res > 0 && scsi_sense_valid(&sshdr)) {
|
||||||
@ -3790,10 +3814,13 @@ static int sd_resume_runtime(struct device *dev)
|
|||||||
if (sdp->ignore_media_change) {
|
if (sdp->ignore_media_change) {
|
||||||
/* clear the device's sense data */
|
/* clear the device's sense data */
|
||||||
static const u8 cmd[10] = { REQUEST_SENSE };
|
static const u8 cmd[10] = { REQUEST_SENSE };
|
||||||
|
const struct scsi_exec_args exec_args = {
|
||||||
|
.req_flags = BLK_MQ_REQ_PM,
|
||||||
|
};
|
||||||
|
|
||||||
if (scsi_execute(sdp, cmd, DMA_NONE, NULL, 0, NULL,
|
if (scsi_execute_cmd(sdp, cmd, REQ_OP_DRV_IN, NULL, 0,
|
||||||
NULL, sdp->request_queue->rq_timeout, 1, 0,
|
sdp->request_queue->rq_timeout, 1,
|
||||||
RQF_PM, NULL))
|
&exec_args))
|
||||||
sd_printk(KERN_NOTICE, sdkp,
|
sd_printk(KERN_NOTICE, sdkp,
|
||||||
"Failed to clear sense data\n");
|
"Failed to clear sense data\n");
|
||||||
}
|
}
|
||||||
|
@ -148,6 +148,9 @@ static int sd_zbc_do_report_zones(struct scsi_disk *sdkp, unsigned char *buf,
|
|||||||
struct scsi_device *sdp = sdkp->device;
|
struct scsi_device *sdp = sdkp->device;
|
||||||
const int timeout = sdp->request_queue->rq_timeout;
|
const int timeout = sdp->request_queue->rq_timeout;
|
||||||
struct scsi_sense_hdr sshdr;
|
struct scsi_sense_hdr sshdr;
|
||||||
|
const struct scsi_exec_args exec_args = {
|
||||||
|
.sshdr = &sshdr,
|
||||||
|
};
|
||||||
unsigned char cmd[16];
|
unsigned char cmd[16];
|
||||||
unsigned int rep_len;
|
unsigned int rep_len;
|
||||||
int result;
|
int result;
|
||||||
@ -160,9 +163,8 @@ static int sd_zbc_do_report_zones(struct scsi_disk *sdkp, unsigned char *buf,
|
|||||||
if (partial)
|
if (partial)
|
||||||
cmd[14] = ZBC_REPORT_ZONE_PARTIAL;
|
cmd[14] = ZBC_REPORT_ZONE_PARTIAL;
|
||||||
|
|
||||||
result = scsi_execute_req(sdp, cmd, DMA_FROM_DEVICE,
|
result = scsi_execute_cmd(sdp, cmd, REQ_OP_DRV_IN, buf, buflen,
|
||||||
buf, buflen, &sshdr,
|
timeout, SD_MAX_RETRIES, &exec_args);
|
||||||
timeout, SD_MAX_RETRIES, NULL);
|
|
||||||
if (result) {
|
if (result) {
|
||||||
sd_printk(KERN_ERR, sdkp,
|
sd_printk(KERN_ERR, sdkp,
|
||||||
"REPORT ZONES start lba %llu failed\n", lba);
|
"REPORT ZONES start lba %llu failed\n", lba);
|
||||||
|
@ -89,10 +89,13 @@ static int ses_recv_diag(struct scsi_device *sdev, int page_code,
|
|||||||
unsigned char recv_page_code;
|
unsigned char recv_page_code;
|
||||||
unsigned int retries = SES_RETRIES;
|
unsigned int retries = SES_RETRIES;
|
||||||
struct scsi_sense_hdr sshdr;
|
struct scsi_sense_hdr sshdr;
|
||||||
|
const struct scsi_exec_args exec_args = {
|
||||||
|
.sshdr = &sshdr,
|
||||||
|
};
|
||||||
|
|
||||||
do {
|
do {
|
||||||
ret = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buf, bufflen,
|
ret = scsi_execute_cmd(sdev, cmd, REQ_OP_DRV_IN, buf, bufflen,
|
||||||
&sshdr, SES_TIMEOUT, 1, NULL);
|
SES_TIMEOUT, 1, &exec_args);
|
||||||
} while (ret > 0 && --retries && scsi_sense_valid(&sshdr) &&
|
} while (ret > 0 && --retries && scsi_sense_valid(&sshdr) &&
|
||||||
(sshdr.sense_key == NOT_READY ||
|
(sshdr.sense_key == NOT_READY ||
|
||||||
(sshdr.sense_key == UNIT_ATTENTION && sshdr.asc == 0x29)));
|
(sshdr.sense_key == UNIT_ATTENTION && sshdr.asc == 0x29)));
|
||||||
@ -130,10 +133,13 @@ static int ses_send_diag(struct scsi_device *sdev, int page_code,
|
|||||||
};
|
};
|
||||||
struct scsi_sense_hdr sshdr;
|
struct scsi_sense_hdr sshdr;
|
||||||
unsigned int retries = SES_RETRIES;
|
unsigned int retries = SES_RETRIES;
|
||||||
|
const struct scsi_exec_args exec_args = {
|
||||||
|
.sshdr = &sshdr,
|
||||||
|
};
|
||||||
|
|
||||||
do {
|
do {
|
||||||
result = scsi_execute_req(sdev, cmd, DMA_TO_DEVICE, buf, bufflen,
|
result = scsi_execute_cmd(sdev, cmd, REQ_OP_DRV_OUT, buf,
|
||||||
&sshdr, SES_TIMEOUT, 1, NULL);
|
bufflen, SES_TIMEOUT, 1, &exec_args);
|
||||||
} while (result > 0 && --retries && scsi_sense_valid(&sshdr) &&
|
} while (result > 0 && --retries && scsi_sense_valid(&sshdr) &&
|
||||||
(sshdr.sense_key == NOT_READY ||
|
(sshdr.sense_key == NOT_READY ||
|
||||||
(sshdr.sense_key == UNIT_ATTENTION && sshdr.asc == 0x29)));
|
(sshdr.sense_key == UNIT_ATTENTION && sshdr.asc == 0x29)));
|
||||||
|
@ -170,10 +170,13 @@ static unsigned int sr_get_events(struct scsi_device *sdev)
|
|||||||
struct event_header *eh = (void *)buf;
|
struct event_header *eh = (void *)buf;
|
||||||
struct media_event_desc *med = (void *)(buf + 4);
|
struct media_event_desc *med = (void *)(buf + 4);
|
||||||
struct scsi_sense_hdr sshdr;
|
struct scsi_sense_hdr sshdr;
|
||||||
|
const struct scsi_exec_args exec_args = {
|
||||||
|
.sshdr = &sshdr,
|
||||||
|
};
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buf, sizeof(buf),
|
result = scsi_execute_cmd(sdev, cmd, REQ_OP_DRV_IN, buf, sizeof(buf),
|
||||||
&sshdr, SR_TIMEOUT, MAX_RETRIES, NULL);
|
SR_TIMEOUT, MAX_RETRIES, &exec_args);
|
||||||
if (scsi_sense_valid(&sshdr) && sshdr.sense_key == UNIT_ATTENTION)
|
if (scsi_sense_valid(&sshdr) && sshdr.sense_key == UNIT_ATTENTION)
|
||||||
return DISK_EVENT_MEDIA_CHANGE;
|
return DISK_EVENT_MEDIA_CHANGE;
|
||||||
|
|
||||||
@ -730,8 +733,8 @@ static void get_sectorsize(struct scsi_cd *cd)
|
|||||||
memset(buffer, 0, sizeof(buffer));
|
memset(buffer, 0, sizeof(buffer));
|
||||||
|
|
||||||
/* Do the command and wait.. */
|
/* Do the command and wait.. */
|
||||||
the_result = scsi_execute_req(cd->device, cmd, DMA_FROM_DEVICE,
|
the_result = scsi_execute_cmd(cd->device, cmd, REQ_OP_DRV_IN,
|
||||||
buffer, sizeof(buffer), NULL,
|
buffer, sizeof(buffer),
|
||||||
SR_TIMEOUT, MAX_RETRIES, NULL);
|
SR_TIMEOUT, MAX_RETRIES, NULL);
|
||||||
|
|
||||||
retries--;
|
retries--;
|
||||||
|
@ -188,13 +188,15 @@ static int sr_play_trkind(struct cdrom_device_info *cdi,
|
|||||||
int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc)
|
int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc)
|
||||||
{
|
{
|
||||||
struct scsi_device *SDev;
|
struct scsi_device *SDev;
|
||||||
struct scsi_sense_hdr local_sshdr, *sshdr = &local_sshdr;
|
struct scsi_sense_hdr local_sshdr, *sshdr;
|
||||||
int result, err = 0, retries = 0;
|
int result, err = 0, retries = 0;
|
||||||
|
const struct scsi_exec_args exec_args = {
|
||||||
|
.sshdr = cgc->sshdr ? : &local_sshdr,
|
||||||
|
};
|
||||||
|
|
||||||
SDev = cd->device;
|
SDev = cd->device;
|
||||||
|
|
||||||
if (cgc->sshdr)
|
sshdr = exec_args.sshdr;
|
||||||
sshdr = cgc->sshdr;
|
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
if (!scsi_block_when_processing_errors(SDev)) {
|
if (!scsi_block_when_processing_errors(SDev)) {
|
||||||
@ -202,10 +204,11 @@ int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = scsi_execute(SDev, cgc->cmd, cgc->data_direction,
|
result = scsi_execute_cmd(SDev, cgc->cmd,
|
||||||
cgc->buffer, cgc->buflen, NULL, sshdr,
|
cgc->data_direction == DMA_TO_DEVICE ?
|
||||||
cgc->timeout, IOCTL_RETRIES, 0, 0, NULL);
|
REQ_OP_DRV_OUT : REQ_OP_DRV_IN, cgc->buffer,
|
||||||
|
cgc->buflen, cgc->timeout, IOCTL_RETRIES,
|
||||||
|
&exec_args);
|
||||||
/* Minimal error checking. Ignore cases we know about, and report the rest. */
|
/* Minimal error checking. Ignore cases we know about, and report the rest. */
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
err = result;
|
err = result;
|
||||||
|
@ -347,8 +347,8 @@ static void virtscsi_rescan_hotunplug(struct virtio_scsi *vscsi)
|
|||||||
|
|
||||||
memset(inq_result, 0, inq_result_len);
|
memset(inq_result, 0, inq_result_len);
|
||||||
|
|
||||||
result = scsi_execute_req(sdev, scsi_cmd, DMA_FROM_DEVICE,
|
result = scsi_execute_cmd(sdev, scsi_cmd, REQ_OP_DRV_IN,
|
||||||
inq_result, inquiry_len, NULL,
|
inq_result, inquiry_len,
|
||||||
SD_TIMEOUT, SD_MAX_RETRIES, NULL);
|
SD_TIMEOUT, SD_MAX_RETRIES, NULL);
|
||||||
|
|
||||||
if (result == 0 && inq_result[0] >> 5) {
|
if (result == 0 && inq_result[0] >> 5) {
|
||||||
|
@ -144,8 +144,7 @@ static void pscsi_tape_read_blocksize(struct se_device *dev,
|
|||||||
cdb[0] = MODE_SENSE;
|
cdb[0] = MODE_SENSE;
|
||||||
cdb[4] = 0x0c; /* 12 bytes */
|
cdb[4] = 0x0c; /* 12 bytes */
|
||||||
|
|
||||||
ret = scsi_execute_req(sdev, cdb, DMA_FROM_DEVICE, buf, 12, NULL,
|
ret = scsi_execute_cmd(sdev, cdb, REQ_OP_DRV_IN, buf, 12, HZ, 1, NULL);
|
||||||
HZ, 1, NULL);
|
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out_free;
|
goto out_free;
|
||||||
|
|
||||||
@ -195,8 +194,8 @@ pscsi_get_inquiry_vpd_serial(struct scsi_device *sdev, struct t10_wwn *wwn)
|
|||||||
cdb[2] = 0x80; /* Unit Serial Number */
|
cdb[2] = 0x80; /* Unit Serial Number */
|
||||||
put_unaligned_be16(INQUIRY_VPD_SERIAL_LEN, &cdb[3]);
|
put_unaligned_be16(INQUIRY_VPD_SERIAL_LEN, &cdb[3]);
|
||||||
|
|
||||||
ret = scsi_execute_req(sdev, cdb, DMA_FROM_DEVICE, buf,
|
ret = scsi_execute_cmd(sdev, cdb, REQ_OP_DRV_IN, buf,
|
||||||
INQUIRY_VPD_SERIAL_LEN, NULL, HZ, 1, NULL);
|
INQUIRY_VPD_SERIAL_LEN, HZ, 1, NULL);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out_free;
|
goto out_free;
|
||||||
|
|
||||||
@ -230,9 +229,8 @@ pscsi_get_inquiry_vpd_device_ident(struct scsi_device *sdev,
|
|||||||
cdb[2] = 0x83; /* Device Identifier */
|
cdb[2] = 0x83; /* Device Identifier */
|
||||||
put_unaligned_be16(INQUIRY_VPD_DEVICE_IDENTIFIER_LEN, &cdb[3]);
|
put_unaligned_be16(INQUIRY_VPD_DEVICE_IDENTIFIER_LEN, &cdb[3]);
|
||||||
|
|
||||||
ret = scsi_execute_req(sdev, cdb, DMA_FROM_DEVICE, buf,
|
ret = scsi_execute_cmd(sdev, cdb, REQ_OP_DRV_IN, buf,
|
||||||
INQUIRY_VPD_DEVICE_IDENTIFIER_LEN,
|
INQUIRY_VPD_DEVICE_IDENTIFIER_LEN, HZ, 1, NULL);
|
||||||
NULL, HZ, 1, NULL);
|
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
@ -455,29 +455,21 @@ extern const char *scsi_device_state_name(enum scsi_device_state);
|
|||||||
extern int scsi_is_sdev_device(const struct device *);
|
extern int scsi_is_sdev_device(const struct device *);
|
||||||
extern int scsi_is_target_device(const struct device *);
|
extern int scsi_is_target_device(const struct device *);
|
||||||
extern void scsi_sanitize_inquiry_string(unsigned char *s, int len);
|
extern void scsi_sanitize_inquiry_string(unsigned char *s, int len);
|
||||||
extern int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
|
|
||||||
int data_direction, void *buffer, unsigned bufflen,
|
/* Optional arguments to scsi_execute_cmd */
|
||||||
unsigned char *sense, struct scsi_sense_hdr *sshdr,
|
struct scsi_exec_args {
|
||||||
int timeout, int retries, blk_opf_t flags,
|
unsigned char *sense; /* sense buffer */
|
||||||
req_flags_t rq_flags, int *resid);
|
unsigned int sense_len; /* sense buffer len */
|
||||||
/* Make sure any sense buffer is the correct size. */
|
struct scsi_sense_hdr *sshdr; /* decoded sense header */
|
||||||
#define scsi_execute(sdev, cmd, data_direction, buffer, bufflen, sense, \
|
blk_mq_req_flags_t req_flags; /* BLK_MQ_REQ flags */
|
||||||
sshdr, timeout, retries, flags, rq_flags, resid) \
|
int *resid; /* residual length */
|
||||||
({ \
|
};
|
||||||
BUILD_BUG_ON((sense) != NULL && \
|
|
||||||
sizeof(sense) != SCSI_SENSE_BUFFERSIZE); \
|
int scsi_execute_cmd(struct scsi_device *sdev, const unsigned char *cmd,
|
||||||
__scsi_execute(sdev, cmd, data_direction, buffer, bufflen, \
|
blk_opf_t opf, void *buffer, unsigned int bufflen,
|
||||||
sense, sshdr, timeout, retries, flags, rq_flags, \
|
int timeout, int retries,
|
||||||
resid); \
|
const struct scsi_exec_args *args);
|
||||||
})
|
|
||||||
static inline int scsi_execute_req(struct scsi_device *sdev,
|
|
||||||
const unsigned char *cmd, int data_direction, void *buffer,
|
|
||||||
unsigned bufflen, struct scsi_sense_hdr *sshdr, int timeout,
|
|
||||||
int retries, int *resid)
|
|
||||||
{
|
|
||||||
return scsi_execute(sdev, cmd, data_direction, buffer,
|
|
||||||
bufflen, NULL, sshdr, timeout, retries, 0, 0, resid);
|
|
||||||
}
|
|
||||||
extern void sdev_disable_disk_events(struct scsi_device *sdev);
|
extern void sdev_disable_disk_events(struct scsi_device *sdev);
|
||||||
extern void sdev_enable_disk_events(struct scsi_device *sdev);
|
extern void sdev_enable_disk_events(struct scsi_device *sdev);
|
||||||
extern int scsi_vpd_lun_id(struct scsi_device *, char *, size_t);
|
extern int scsi_vpd_lun_id(struct scsi_device *, char *, size_t);
|
||||||
|
Reference in New Issue
Block a user