u8 args[4], *argbuf = NULL, *sensebuf = NULL;
int argsize = 0;
enum dma_data_direction data_dir;
+ struct scsi_sense_hdr sshdr;
int cmd_result;
if (arg == NULL)
/* Good values for timeout and retries? Values below
from scsi_ioctl_send_command() for default case... */
cmd_result = scsi_execute(scsidev, scsi_cmd, data_dir, argbuf, argsize,
- sensebuf, (10*HZ), 5, 0, NULL);
+ sensebuf, &sshdr, (10*HZ), 5, 0, 0, NULL);
if (driver_byte(cmd_result) == DRIVER_SENSE) {/* sense data available */
u8 *desc = sensebuf + 8;
/* If we set cc then ATA pass-through will cause a
* check condition even if no error. Filter that. */
if (cmd_result & SAM_STAT_CHECK_CONDITION) {
- struct scsi_sense_hdr sshdr;
- scsi_normalize_sense(sensebuf, SCSI_SENSE_BUFFERSIZE,
- &sshdr);
if (sshdr.sense_key == RECOVERED_ERROR &&
sshdr.asc == 0 && sshdr.ascq == 0x1d)
cmd_result &= ~SAM_STAT_CHECK_CONDITION;
int rc = 0;
u8 scsi_cmd[MAX_COMMAND_SIZE];
u8 args[7], *sensebuf = NULL;
+ struct scsi_sense_hdr sshdr;
int cmd_result;
if (arg == NULL)
/* Good values for timeout and retries? Values below
from scsi_ioctl_send_command() for default case... */
cmd_result = scsi_execute(scsidev, scsi_cmd, DMA_NONE, NULL, 0,
- sensebuf, (10*HZ), 5, 0, NULL);
+ sensebuf, &sshdr, (10*HZ), 5, 0, 0, NULL);
if (driver_byte(cmd_result) == DRIVER_SENSE) {/* sense data available */
u8 *desc = sensebuf + 8;
/* If we set cc then ATA pass-through will cause a
* check condition even if no error. Filter that. */
if (cmd_result & SAM_STAT_CHECK_CONDITION) {
- struct scsi_sense_hdr sshdr;
- scsi_normalize_sense(sensebuf, SCSI_SENSE_BUFFERSIZE,
- &sshdr);
if (sshdr.sense_key == RECOVERED_ERROR &&
sshdr.asc == 0 && sshdr.ascq == 0x1d)
cmd_result &= ~SAM_STAT_CHECK_CONDITION;
struct cxlflash_cfg *cfg = shost_priv(sdev->host);
struct device *dev = &cfg->dev->dev;
struct glun_info *gli = lli->parent;
+ struct scsi_sense_hdr sshdr;
u8 *cmd_buf = NULL;
u8 *scsi_cmd = NULL;
u8 *sense_buf = NULL;
/* Drop the ioctl read semahpore across lengthy call */
up_read(&cfg->ioctl_rwsem);
result = scsi_execute(sdev, scsi_cmd, DMA_FROM_DEVICE, cmd_buf,
- CMD_BUFSIZE, sense_buf, to, CMD_RETRIES, 0, NULL);
+ CMD_BUFSIZE, sense_buf, &sshdr, to, CMD_RETRIES,
+ 0, 0, NULL);
down_read(&cfg->ioctl_rwsem);
rc = check_state(cfg);
if (rc) {
if (driver_byte(result) == DRIVER_SENSE) {
result &= ~(0xFF<<24); /* DRIVER_SENSE is not an error */
if (result & SAM_STAT_CHECK_CONDITION) {
- struct scsi_sense_hdr sshdr;
-
- scsi_normalize_sense(sense_buf, SCSI_SENSE_BUFFERSIZE,
- &sshdr);
switch (sshdr.sense_key) {
case NO_SENSE:
case RECOVERED_ERROR:
/* Drop the ioctl read semahpore across lengthy call */
up_read(&cfg->ioctl_rwsem);
result = scsi_execute(sdev, scsi_cmd, DMA_TO_DEVICE, cmd_buf,
- CMD_BUFSIZE, sense_buf, to, CMD_RETRIES,
- 0, NULL);
+ CMD_BUFSIZE, sense_buf, NULL, to,
+ CMD_RETRIES, 0, 0, NULL);
down_read(&cfg->ioctl_rwsem);
rc = check_state(cfg);
if (rc) {
__scsi_queue_insert(cmd, reason, 1);
}
-static int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
+
+/**
+ * scsi_execute - insert request and wait for the result
+ * @sdev: scsi device
+ * @cmd: scsi command
+ * @data_direction: data direction
+ * @buffer: data buffer
+ * @bufflen: len of buffer
+ * @sense: optional sense buffer
+ * @sshdr: optional decoded sense header
+ * @timeout: request timeout in seconds
+ * @retries: number of times to retry request
+ * @flags: flags for ->cmd_flags
+ * @rq_flags: flags for ->rq_flags
+ * @resid: optional residual length
+ *
+ * returns the req->errors value which is the scsi_cmnd result
+ * field.
+ */
+int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
int data_direction, void *buffer, unsigned bufflen,
unsigned char *sense, struct scsi_sense_hdr *sshdr,
int timeout, int retries, u64 flags, req_flags_t rq_flags,
return ret;
}
-
-/**
- * scsi_execute - insert request and wait for the result
- * @sdev: scsi device
- * @cmd: scsi command
- * @data_direction: data direction
- * @buffer: data buffer
- * @bufflen: len of buffer
- * @sense: optional sense buffer
- * @timeout: request timeout in seconds
- * @retries: number of times to retry request
- * @flags: or into request flags;
- * @resid: optional residual length
- *
- * returns the req->errors value which is the scsi_cmnd result
- * field.
- */
-int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
- int data_direction, void *buffer, unsigned bufflen,
- unsigned char *sense, int timeout, int retries, u64 flags,
- int *resid)
-{
- return __scsi_execute(sdev, cmd, data_direction, buffer, bufflen, sense,
- NULL, timeout, retries, flags, 0, resid);
-}
EXPORT_SYMBOL(scsi_execute);
int scsi_execute_req_flags(struct scsi_device *sdev, const unsigned char *cmd,
struct scsi_sense_hdr *sshdr, int timeout, int retries,
int *resid, u64 flags, req_flags_t rq_flags)
{
- return __scsi_execute(sdev, cmd, data_direction, buffer, bufflen,
+ return scsi_execute(sdev, cmd, data_direction, buffer, bufflen,
NULL, sshdr, timeout, retries, flags, rq_flags,
resid);
}
{
int i, result;
unsigned char sense[SCSI_SENSE_BUFFERSIZE];
+ struct scsi_sense_hdr sshdr_tmp;
+
+ if (!sshdr)
+ sshdr = &sshdr_tmp;
for(i = 0; i < DV_RETRIES; i++) {
- result = scsi_execute(sdev, cmd, dir, buffer, bufflen,
- sense, DV_TIMEOUT, /* retries */ 1,
+ result = scsi_execute(sdev, cmd, dir, buffer, bufflen, sense,
+ sshdr, DV_TIMEOUT, /* retries */ 1,
REQ_FAILFAST_DEV |
REQ_FAILFAST_TRANSPORT |
REQ_FAILFAST_DRIVER,
- NULL);
- if (driver_byte(result) & DRIVER_SENSE) {
- struct scsi_sense_hdr sshdr_tmp;
- if (!sshdr)
- sshdr = &sshdr_tmp;
-
- if (scsi_normalize_sense(sense, SCSI_SENSE_BUFFERSIZE,
- sshdr)
- && sshdr->sense_key == UNIT_ATTENTION)
- continue;
- }
- break;
+ 0, NULL);
+ if (!(driver_byte(result) & DRIVER_SENSE) ||
+ sshdr->sense_key != UNIT_ATTENTION)
+ break;
}
return result;
}
struct scsi_device *SDev;
struct scsi_sense_hdr sshdr;
int result, err = 0, retries = 0;
- struct request_sense *sense = cgc->sense;
SDev = cd->device;
- if (!sense) {
- sense = kmalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL);
- if (!sense) {
- err = -ENOMEM;
- goto out;
- }
- }
-
retry:
if (!scsi_block_when_processing_errors(SDev)) {
err = -ENODEV;
goto out;
}
- memset(sense, 0, sizeof(*sense));
result = scsi_execute(SDev, cgc->cmd, cgc->data_direction,
- cgc->buffer, cgc->buflen, (char *)sense,
- cgc->timeout, IOCTL_RETRIES, 0, NULL);
-
- scsi_normalize_sense((char *)sense, sizeof(*sense), &sshdr);
+ cgc->buffer, cgc->buflen,
+ (unsigned char *)cgc->sense, &sshdr,
+ cgc->timeout, IOCTL_RETRIES, 0, 0, NULL);
/* Minimal error checking. Ignore cases we know about, and report the rest. */
if (driver_byte(result) != 0) {
/* Wake up a process waiting for device */
out:
- if (!cgc->sense)
- kfree(sense);
cgc->stat = err;
return err;
}
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,
- unsigned char *sense, int timeout, int retries,
- u64 flags, int *resid);
+ unsigned char *sense, struct scsi_sense_hdr *sshdr,
+ int timeout, int retries, u64 flags,
+ req_flags_t rq_flags, int *resid);
extern int scsi_execute_req_flags(struct scsi_device *sdev,
const unsigned char *cmd, int data_direction, void *buffer,
unsigned bufflen, struct scsi_sense_hdr *sshdr, int timeout,