both libata-scsi and libata-eh used a cooked up
REQUEST_SENSE command to retrieve sense data. Use
of the scsi_eh_{prep,restore}_cmnd() can facilitate
and simplify the code. And insulates code from scsi
future changes.
Am I right in assuming that ata_exec_internal_sg() executes
synchronously (called from atapi_eh_request_sense()) and
once returned contain valid sense data?
Also other places in libata where converted to new scsi_eh
API and accessors.
Set shost->sense_buffsize in ata_scsi_add_hosts() for all drivers.
Signed-off-by: Boaz Harrosh <[EMAIL PROTECTED]>
---
drivers/ata/libata-eh.c | 29 +++++++++++------------------
drivers/ata/libata-scsi.c | 44 ++++++++++++++++++++++----------------------
include/linux/libata.h | 3 +++
3 files changed, 36 insertions(+), 40 deletions(-)
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 4e31071..9f02be4 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -1270,29 +1270,19 @@ static int ata_eh_read_log_10h(struct ata_device *dev,
static unsigned int atapi_eh_request_sense(struct ata_queued_cmd *qc)
{
struct ata_device *dev = qc->dev;
- unsigned char *sense_buf = qc->scsicmd->sense_buffer;
struct ata_port *ap = dev->link->ap;
struct ata_taskfile tf;
- u8 cdb[ATAPI_CDB_LEN];
+ struct scsi_eh_save ses;
+ struct scsi_cmnd *cmd = qc->scsicmd;
+ int ret;
DPRINTK("ATAPI request sense\n");
- /* FIXME: is this needed? */
- memset(sense_buf, 0, SCSI_SENSE_BUFFERSIZE);
-
- /* initialize sense_buf with the error register,
- * for the case where they are -not- overwritten
- */
- sense_buf[0] = 0x70;
- sense_buf[2] = qc->result_tf.feature >> 4;
-
+ /*?? Is there a maximum size here that ATAPI will confuse if more ??*/
+ scsi_eh_prep_cmnd(cmd, &ses, NULL, 0, ~0);
/* some devices time out if garbage left in tf */
ata_tf_init(dev, &tf);
- memset(cdb, 0, ATAPI_CDB_LEN);
- cdb[0] = REQUEST_SENSE;
- cdb[4] = SCSI_SENSE_BUFFERSIZE;
-
tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
tf.command = ATA_CMD_PACKET;
@@ -1302,12 +1292,15 @@ static unsigned int atapi_eh_request_sense(struct
ata_queued_cmd *qc)
tf.feature |= ATAPI_PKT_DMA;
} else {
tf.protocol = ATAPI_PROT_PIO;
- tf.lbam = SCSI_SENSE_BUFFERSIZE;
+ tf.lbam = scsi_bufflen(cmd);
tf.lbah = 0;
}
- return ata_exec_internal(dev, &tf, cdb, DMA_FROM_DEVICE,
- sense_buf, SCSI_SENSE_BUFFERSIZE, 0);
+ ret = ata_exec_internal_sg(dev, &tf, cmd->cmnd, DMA_FROM_DEVICE,
+ scsi_sglist(cmd), scsi_sg_count(cmd), 0);
+
+ scsi_eh_restore_cmnd(cmd, &ses);
+ return ret;
}
/**
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index c02c490..652fce4 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -705,11 +705,11 @@ static void ata_gen_passthru_sense(struct ata_queued_cmd
*qc)
{
struct scsi_cmnd *cmd = qc->scsicmd;
struct ata_taskfile *tf = &qc->result_tf;
- unsigned char *sb = cmd->sense_buffer;
+ unsigned char sb[24];
unsigned char *desc = sb + 8;
int verbose = qc->ap->ops->error_handler == NULL;
- memset(sb, 0, SCSI_SENSE_BUFFERSIZE);
+ memset(sb, 0, sizeof(sb));
cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
@@ -758,6 +758,7 @@ static void ata_gen_passthru_sense(struct ata_queued_cmd
*qc)
desc[8] = tf->hob_lbam;
desc[10] = tf->hob_lbah;
}
+ scsi_eh_cpy_sense(cmd, sb, sizeof(sb));
}
/**
@@ -775,12 +776,12 @@ static void ata_gen_ata_sense(struct ata_queued_cmd *qc)
struct ata_device *dev = qc->dev;
struct scsi_cmnd *cmd = qc->scsicmd;
struct ata_taskfile *tf = &qc->result_tf;
- unsigned char *sb = cmd->sense_buffer;
+ u8 sb[24];
unsigned char *desc = sb + 8;
int verbose = qc->ap->ops->error_handler == NULL;
u64 block;
- memset(sb, 0, SCSI_SENSE_BUFFERSIZE);
+ memset(sb, 0, sizeof(sb));
cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
@@ -811,6 +812,8 @@ static void ata_gen_ata_sense(struct ata_queued_cmd *qc)
desc[9] = block >> 16;
desc[10] = block >> 8;
desc[11] = block;
+
+ scsi_eh_cpy_sense(cmd, sb, sizeof(sb));
}
static void ata_scsi_sdev_config(struct scsi_device *sdev)
@@ -2277,13 +2280,17 @@ unsigned int ata_scsiop_report_luns(struct
ata_scsi_args *args, u8 *rbuf,
void ata_scsi_set_sense(struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq)
{
+ u8 sb[14];
+
+ memset(sb, 0, sizeof(sb));
cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
- cmd->sense_buffer[0] = 0x70; /* fixed format, current */
- cmd->sense_buffer[2] = sk;
- cmd->sense_buffer[7] = 18 - 8; /* additional sense length */
- cmd->sense_buffer[12] = asc;
- cmd->sense_buffer[13] = ascq;
+ sb[0] = 0x70; /* fixed format, current */
+ sb[2] = sk;
+ sb[7] = 18 - 8; /* additional sense length */
+ sb[12] = asc;
+ sb[13] = ascq;
+ scsi_eh_cpy_sense(cmd, sb, sizeof(sb));
}
/**
@@ -2311,6 +2318,7 @@ void ata_scsi_badcmd(struct scsi_cmnd *cmd, void
(*done)(struct scsi_cmnd *), u8
static void atapi_sense_complete(struct ata_queued_cmd *qc)
{
+ scsi_eh_restore_cmnd(qc->scsicmd, &qc->ses);
if (qc->err_mask && ((qc->err_mask & AC_ERR_DEV) == 0)) {
/* FIXME: not quite right; we don't want the
* translation of taskfile registers into
@@ -2337,25 +2345,16 @@ static void atapi_request_sense(struct ata_queued_cmd
*qc)
DPRINTK("ATAPI request sense\n");
- /* FIXME: is this needed? */
- memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
-
ap->ops->tf_read(ap, &qc->tf);
- /* fill these in, for the case where they are -not- overwritten */
- cmd->sense_buffer[0] = 0x70;
- cmd->sense_buffer[2] = qc->tf.feature >> 4;
-
ata_qc_reinit(qc);
- /* setup sg table and init transfer direction */
- sg_init_one(&qc->sgent, cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE);
- ata_sg_init(qc, &qc->sgent, 1);
- qc->dma_dir = DMA_FROM_DEVICE;
+ scsi_eh_prep_cmnd(cmd, &qc->ses, NULL, 0, SCSI_SENSE_BUFFERSIZE);
+ ata_sg_init(qc, scsi_sglist(cmd), scsi_sg_count(cmd));
+ qc->dma_dir = cmd->sc_data_direction;
memset(&qc->cdb, 0, qc->dev->cdb_len);
- qc->cdb[0] = REQUEST_SENSE;
- qc->cdb[4] = SCSI_SENSE_BUFFERSIZE;
+ memcpy(qc->cdb, cmd->cmnd, cmd->cmd_len);
qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
qc->tf.command = ATA_CMD_PACKET;
@@ -3141,6 +3140,7 @@ int ata_scsi_add_hosts(struct ata_host *host, struct
scsi_host_template *sht)
shost->max_lun = 1;
shost->max_channel = 1;
shost->max_cmd_len = 16;
+ shost->sense_buffsize = SCSI_SENSE_BUFFERSIZE;
/* Schedule policy is determined by ->qc_defer()
* callback and it needs to see every deferred qc.
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 4374c42..6f2974f 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -34,6 +34,7 @@
#include <linux/ata.h>
#include <linux/workqueue.h>
#include <scsi/scsi_host.h>
+#include <scsi/scsi_eh.h>
#include <linux/acpi.h>
#include <linux/cdrom.h>
@@ -454,6 +455,8 @@ struct ata_queued_cmd {
struct ata_taskfile tf;
u8 cdb[ATAPI_CDB_LEN];
+ struct scsi_eh_save ses;
+
unsigned long flags; /* ATA_QCFLAG_xxx */
unsigned int tag;
unsigned int n_elem;
--
1.5.3.3
-
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html