[PATCH 11/24][RFC] libata: Use scsi_eh API for REQUEST_SENSE invocation

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



  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 <bharrosh@xxxxxxxxxxx>
---
 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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux