linux-ide.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* T10/04-262 ATA pass thru - patch.
@ 2004-09-28  5:16 Andy Warner
  2004-09-28  5:39 ` Andy Warner
                   ` (2 more replies)
  0 siblings, 3 replies; 22+ messages in thread
From: Andy Warner @ 2004-09-28  5:16 UTC (permalink / raw)
  To: linux-ide
  Cc: John W. Linville, Jeff Garzik, John Linville, linville,
	Pat LaVarre, Mark Lord

[-- Attachment #1: Type: text/plain, Size: 1058 bytes --]

Here is a *very* rough and ready patch that implements
the ATA pass-thru CDB. The patch should apply cleanly
to any bk://gkernel.bkbits.net/libata-2.6 clone.

The 16-byte command opcode is a totally arbitrary 0x85,
allocation of a legit opcode is still pending.

The 12-byte command is not supported yet.

Only the following protocols are currently
supported: Non-Data, PIO-In, PIO-Out, DMA.

Multiple Count is currently ignored, and
read/write multiple are handled as vanilla PIO.

UDMA (protocols 11 & 12 in T10/04-262) probably
work, since at the libata level all DMA appear to
be handled the same.

Not supported are any of the reset protocols, packet,
queued, device diagnostics or FPDMA. I have no plans
to add packet support or queued support any time soon.
This should be enough to start SMART work, though.

This is my first patch generated from a bk-based
tree, so let me know if there are any problems
due to the way I've generated the patch.

Feedback/complaints -> me.
-- 
andyw@pobox.com

Andy Warner		Voice: (612) 801-8549	Fax: (208) 575-5634

[-- Attachment #2: t10-patch-040927 --]
[-- Type: text/plain, Size: 4896 bytes --]

diff -ur -X /tmp/dontdiff libata-2.6-vanilla/drivers/scsi/libata-core.c t10-parser/drivers/scsi/libata-core.c
--- libata-2.6-vanilla/drivers/scsi/libata-core.c	2004-09-27 17:30:29.000000000 -0500
+++ t10-parser/drivers/scsi/libata-core.c	2004-09-27 21:30:23.000000000 -0500
@@ -1946,7 +1946,7 @@
 	sg->offset = (unsigned long) buf & ~PAGE_MASK;
 	sg_dma_len(sg) = buflen;
 
-	WARN_ON(buflen > PAGE_SIZE);
+//    WARN_ON(buflen > PAGE_SIZE);
 }
 
 void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
diff -ur -X /tmp/dontdiff libata-2.6-vanilla/drivers/scsi/libata-scsi.c t10-parser/drivers/scsi/libata-scsi.c
--- libata-2.6-vanilla/drivers/scsi/libata-scsi.c	2004-09-27 17:30:29.000000000 -0500
+++ t10-parser/drivers/scsi/libata-scsi.c	2004-09-27 23:42:44.733522940 -0500
@@ -623,10 +623,22 @@
 {
 	struct scsi_cmnd *cmd = qc->scsicmd;
 
-	if (unlikely(drv_stat & (ATA_ERR | ATA_BUSY | ATA_DRQ)))
-		ata_to_sense_error(qc, drv_stat);
-	else
-		cmd->result = SAM_STAT_GOOD;
+	/*
+	 * If this was a pass-thru command, and the user requested
+	 * a check condition return including register values.
+	 * Note that check condition is generated, and the ATA
+	 * register values are returned, whether the command completed
+	 * successfully or not. If there was no error, SK, ASC and
+	 * ASCQ will all be zero.
+	 */
+	if ((cmd->cmnd[0] == ATA_16) && (cmd->cmnd[2] & 0x20)) {
+/*DWD*/		printk("XX  0x%0x/0x%0x\n", qc->tf.flags, qc->tf.protocol) ;
+	} else {
+		if (unlikely(drv_stat & (ATA_ERR | ATA_BUSY | ATA_DRQ)))
+			ata_to_sense_error(qc, drv_stat);
+		else
+			cmd->result = SAM_STAT_GOOD;
+	}
 
 	qc->scsidone(cmd);
 
@@ -688,7 +700,6 @@
 
 	if (xlat_func(qc, scsicmd))
 		goto err_out;
-
 	/* select device, send command to hardware */
 	if (ata_qc_issue(qc))
 		goto err_out;
@@ -1368,6 +1379,98 @@
 	return dev;
 }
 
+/*
+ * ata_scsi_map_proto() -	Map the protocol specified
+ *				in the pass-thru CDB onto the
+ *				protocol values used by taskfiles.
+ */
+static u8
+ata_scsi_map_proto(u8 byte1)
+{
+	switch((byte1 & 0x1e) >> 1) {
+		case 3:		/* Non-data */
+			return ATA_PROT_NODATA;
+
+		case 6:		/* DMA */
+			return ATA_PROT_DMA;
+
+		case 4:		/* PIO Data-in */
+		case 5:		/* PIO Data-out */
+			if (byte1 & 0xe0) {
+				return ATA_PROT_PIO_MULT;
+			}
+			return ATA_PROT_PIO;
+
+		case 10:	/* Device Reset */
+		case 0:		/* Hard Reset */
+		case 1:		/* SRST */
+		case 2:		/* Bus Idle */
+		case 7:		/* Packet */
+		case 8:		/* DMA Queued */
+		case 9:		/* Device Diagnostic */
+		case 11:	/* UDMA Data-in */
+		case 12:	/* UDMA Data-Out */
+		case 13:	/* FPDMA */
+		default:	/* Reserved */
+			break;
+	}
+
+	return ATA_PROT_UNKNOWN;
+}
+
+static unsigned int
+ata_scsi_pass_thru_16(struct ata_queued_cmd *qc, u8 *scsicmd)
+{
+	struct ata_taskfile *tf = &(qc->tf);
+	struct scsi_cmnd *cmd = qc->scsicmd;
+
+	if ((tf->protocol = ata_scsi_map_proto(scsicmd[1])) == ATA_PROT_UNKNOWN) {
+		return 1;
+	}
+
+	/*
+	 * If the CDB claims to contain extended
+	 * ATA commands copy the upper byte register values.
+	 * 
+	 * NOTE: at present copy all register fields,
+	 * regardless of which ones are valid according
+	 * to the .En bits. TODO: research optimal
+	 * algorithm for this.
+	 */
+	if (scsicmd[1] & 0x01) {
+		tf->hob_feature = scsicmd[3];
+		tf->hob_nsect = scsicmd[5];
+		tf->hob_lbal = scsicmd[7];
+		tf->hob_lbam = scsicmd[9];
+		tf->hob_lbah = scsicmd[11];
+		tf->flags |= ATA_TFLAG_LBA48 ;
+	} else {
+		tf->flags &= ~ATA_TFLAG_LBA48 ;
+	}
+
+	tf->feature = scsicmd[4];
+	tf->nsect = scsicmd[6];
+	tf->lbal = scsicmd[8];
+	tf->lbam = scsicmd[10];
+	tf->lbah = scsicmd[12];
+
+	tf->flags |= (ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE) ;
+	tf->device = scsicmd[13];
+	tf->command = scsicmd[14];
+
+	/*
+	 * TODO: find out if we need to do more here to
+	 *       cover scatter/gather case.
+	 */
+	qc->nsect = cmd->bufflen / ATA_SECT_SIZE ;
+
+	if (cmd->sc_data_direction == SCSI_DATA_WRITE) {
+		tf->flags |= ATA_TFLAG_WRITE;
+	}
+
+	return 0;
+}
+
 /**
  *	ata_get_xlat_func - check if SCSI to ATA translation is possible
  *	@dev: ATA device
@@ -1400,6 +1503,9 @@
 	case VERIFY:
 	case VERIFY_16:
 		return ata_scsi_verify_xlat;
+
+	case ATA_16:
+		return ata_scsi_pass_thru_16 ;
 	}
 
 	return NULL;
diff -ur -X /tmp/dontdiff libata-2.6-vanilla/include/scsi/scsi.h t10-parser/include/scsi/scsi.h
--- libata-2.6-vanilla/include/scsi/scsi.h	2004-09-27 17:30:40.000000000 -0500
+++ t10-parser/include/scsi/scsi.h	2004-09-27 22:11:07.000000000 -0500
@@ -113,6 +113,9 @@
 /* values for service action in */
 #define	SAI_READ_CAPACITY_16  0x10
 
+/* Temporary values for T10/04-262 until official values are allocated */
+#define	ATA_16		      0x85	/* 16-byte pass-thru [0x85 == unused]*/
+#define	ATA_12		      0xb3	/* 12-byte pass-thru [0xb3 == obsolete set limits command] */
 
 /*
  *  SCSI Architecture Model (SAM) Status codes. Taken from SAM-3 draft

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2004-10-07  3:36 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-09-28  5:16 T10/04-262 ATA pass thru - patch Andy Warner
2004-09-28  5:39 ` Andy Warner
2004-09-29 16:49   ` John W. Linville
2004-09-29 18:19     ` Andy Warner
2004-09-29 17:12       ` John W. Linville
2004-09-29 20:44         ` Andy Warner
2004-09-29 18:29 ` Luciano A. Stertz
2004-09-29 17:20   ` John W. Linville
2004-09-29 18:32   ` Jeff Garzik
2004-09-29 19:31     ` Luciano A. Stertz
2004-09-29 19:38       ` Luciano A. Stertz
2004-09-29 18:55         ` John W. Linville
2004-10-05 18:53     ` Luciano A. Stertz
2004-10-05 19:06       ` Andy Warner
2004-10-05 22:19         ` Jeff Garzik
2004-10-05 22:37           ` Andy Warner
2004-10-05 22:41             ` Jeff Garzik
2004-10-06  6:04               ` Jens Axboe
2004-10-07  3:34                 ` Jeff Garzik
2004-10-06 12:21           ` Luciano A. Stertz
2004-09-30 18:13 ` [patch libata-2.6] libata: SMART support via ATA pass-thru John W. Linville
2004-09-30 19:52   ` Jeff Garzik

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).