linux-ide.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Albert Lee" <albertcc@tw.ibm.com>
To: Jeff Garzik <jgarzik@pobox.com>
Cc: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>,
	Doug Maxey <dwm@maxeymade.com>,
	IDE Linux <linux-ide@vger.kernel.org>,
	"Mudama, Eric" <eric_mudama@Maxtor.com>,
	Mark Lord <mlord@pobox.com>
Subject: Re: [PATCH libata-dev-2.6 1/3] Add CHS support
Date: Mon, 14 Feb 2005 19:17:43 +0800	[thread overview]
Message-ID: <008e01c51286$d2f8b740$6401a8c0@tw.ibm.com> (raw)
In-Reply-To: 007f01c51285$a3612450$6401a8c0@tw.ibm.com

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


> 2) Patch #3 needs to be split up into three patches:
>   a) rename variables (s/sector/block/),
>   b) reorganize read/write translation
>   c) add CHS support
> 

Patch 3-2: 
 - reorganize read/write translation in ata_scsi_rw_xlat()

Albert

Signed-off-by: Albert Lee <albertcc@tw.ibm.com>
------------------------------------------------------------------
--- libata-dev-2.6/drivers/scsi/libata-scsi.c 2005-02-14 16:54:47.000000000 +0800
+++ libata-dev-2.6-mod/drivers/scsi/libata-scsi.c 2005-02-14 17:05:12.000000000 +0800
@@ -788,10 +788,11 @@
 {
  struct ata_taskfile *tf = &qc->tf;
  unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48;
+ u64 block = 0;
+ u32 n_block = 0;
 
  tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
  tf->protocol = qc->dev->xfer_protocol;
- tf->device |= ATA_LBA;
 
  if (scsicmd[0] == READ_10 || scsicmd[0] == READ_6 ||
      scsicmd[0] == READ_16) {
@@ -801,80 +802,79 @@
   tf->flags |= ATA_TFLAG_WRITE;
  }
 
+ /* Calculate the SCSI LBA and transfer length. */
  if (scsicmd[0] == READ_10 || scsicmd[0] == WRITE_10) {
-  if (lba48) {
-   tf->hob_nsect = scsicmd[7];
-   tf->hob_lbal = scsicmd[2];
-
-   qc->nsect = ((unsigned int)scsicmd[7] << 8) |
-     scsicmd[8];
-  } else {
-   /* if we don't support LBA48 addressing, the request
-    * -may- be too large. */
-   if ((scsicmd[2] & 0xf0) || scsicmd[7])
-    return 1;
-
-   /* stores LBA27:24 in lower 4 bits of device reg */
-   tf->device |= scsicmd[2];
+  block |= ((u64)scsicmd[2]) << 24;
+  block |= ((u64)scsicmd[3]) << 16;
+  block |= ((u64)scsicmd[4]) << 8;
+  block |= ((u64)scsicmd[5]);
 
-   qc->nsect = scsicmd[8];
-  }
-
-  tf->nsect = scsicmd[8];
-  tf->lbal = scsicmd[5];
-  tf->lbam = scsicmd[4];
-  tf->lbah = scsicmd[3];
+  n_block |= ((u32)scsicmd[7]) << 8;
+  n_block |= ((u32)scsicmd[8]);
 
   VPRINTK("ten-byte command\n");
-  return 0;
- }
-
- if (scsicmd[0] == READ_6 || scsicmd[0] == WRITE_6) {
-  qc->nsect = tf->nsect = scsicmd[4];
-  tf->lbal = scsicmd[3];
-  tf->lbam = scsicmd[2];
-  tf->lbah = scsicmd[1] & 0x1f; /* mask out reserved bits */
-
+ } else if (scsicmd[0] == READ_6 || scsicmd[0] == WRITE_6) {
+  block |= ((u64)scsicmd[2]) << 8;
+  block |= ((u64)scsicmd[3]);
+  n_block |= ((u32)scsicmd[4]);
+ 
   VPRINTK("six-byte command\n");
-  return 0;
- }
+ } else if (scsicmd[0] == READ_16 || scsicmd[0] == WRITE_16) {
+  block |= ((u64)scsicmd[2]) << 56;
+  block |= ((u64)scsicmd[3]) << 48;
+  block |= ((u64)scsicmd[4]) << 40;
+  block |= ((u64)scsicmd[5]) << 32;
+  block |= ((u64)scsicmd[6]) << 24;
+  block |= ((u64)scsicmd[7]) << 16;
+  block |= ((u64)scsicmd[8]) << 8;
+  block |= ((u64)scsicmd[9]);
+
+  n_block |= ((u32)scsicmd[10]) << 24;
+  n_block |= ((u32)scsicmd[11]) << 16;
+  n_block |= ((u32)scsicmd[12]) << 8;
+  n_block |= ((u32)scsicmd[13]);
 
- if (scsicmd[0] == READ_16 || scsicmd[0] == WRITE_16) {
-  /* rule out impossible LBAs and sector counts */
-  if (scsicmd[2] || scsicmd[3] || scsicmd[10] || scsicmd[11])
-   return 1;
+  VPRINTK("sixteen-byte command\n");
+ } else {
+  DPRINTK("no-byte command\n");
+  return 1;
+ }
 
-  if (lba48) {
-   tf->hob_nsect = scsicmd[12];
-   tf->hob_lbal = scsicmd[6];
-   tf->hob_lbam = scsicmd[5];
-   tf->hob_lbah = scsicmd[4];
+ /* Check and compose ATA command */
+ if (!n_block)
+  /* In ATA, sector count 0 are 256 or 65536 sectors, not 0 sectors. */
+  return 1;
 
-   qc->nsect = ((unsigned int)scsicmd[12] << 8) |
-     scsicmd[13];
-  } else {
-   /* once again, filter out impossible non-zero values */
-   if (scsicmd[4] || scsicmd[5] || scsicmd[12] ||
-       (scsicmd[6] & 0xf0))
-    return 1;
+ if (lba48) {
+  /* The request -may- be too large for LBA48. */
+  if ((block >> 48) || (n_block > 65536))
+   return 1;
 
-   /* stores LBA27:24 in lower 4 bits of device reg */
-   tf->device |= scsicmd[6];
+  tf->hob_nsect = (n_block >> 8) & 0xff;
 
-   qc->nsect = scsicmd[13];
-  }
+  tf->hob_lbah = (block >> 40) & 0xff;
+  tf->hob_lbam = (block >> 32) & 0xff;
+  tf->hob_lbal = (block >> 24) & 0xff;
+ } else { 
+  /* LBA28 */
 
-  tf->nsect = scsicmd[13];
-  tf->lbal = scsicmd[9];
-  tf->lbam = scsicmd[8];
-  tf->lbah = scsicmd[7];
+  /* The request -may- be too large for LBA28. */
+  if ((block >> 28) || (n_block > 256))
+   return 1;
 
-  VPRINTK("sixteen-byte command\n");
-  return 0;
+  tf->device |= (block >> 24) & 0xf;
  }
+ 
+ qc->nsect = n_block;
+ tf->nsect = n_block & 0xff;
+
+ tf->lbah = (block >> 16) & 0xff;
+ tf->lbam = (block >> 8) & 0xff;
+ tf->lbal = block & 0xff;
 
- DPRINTK("no-byte command\n");
- return 1;
+ tf->device |= ATA_LBA;
+
+ return 0;
 }
 
 static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)

[-- Attachment #2: chs3-2.diff --]
[-- Type: application/octet-stream, Size: 4460 bytes --]

--- libata-dev-2.6/drivers/scsi/libata-scsi.c	2005-02-14 16:54:47.000000000 +0800
+++ libata-dev-2.6-mod/drivers/scsi/libata-scsi.c	2005-02-14 17:05:12.000000000 +0800
@@ -788,10 +788,11 @@
 {
 	struct ata_taskfile *tf = &qc->tf;
 	unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48;
+	u64 block = 0;
+	u32 n_block = 0;
 
 	tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
 	tf->protocol = qc->dev->xfer_protocol;
-	tf->device |= ATA_LBA;
 
 	if (scsicmd[0] == READ_10 || scsicmd[0] == READ_6 ||
 	    scsicmd[0] == READ_16) {
@@ -801,80 +802,79 @@
 		tf->flags |= ATA_TFLAG_WRITE;
 	}
 
+	/* Calculate the SCSI LBA and transfer length. */
 	if (scsicmd[0] == READ_10 || scsicmd[0] == WRITE_10) {
-		if (lba48) {
-			tf->hob_nsect = scsicmd[7];
-			tf->hob_lbal = scsicmd[2];
-
-			qc->nsect = ((unsigned int)scsicmd[7] << 8) |
-					scsicmd[8];
-		} else {
-			/* if we don't support LBA48 addressing, the request
-			 * -may- be too large. */
-			if ((scsicmd[2] & 0xf0) || scsicmd[7])
-				return 1;
-
-			/* stores LBA27:24 in lower 4 bits of device reg */
-			tf->device |= scsicmd[2];
+		block |= ((u64)scsicmd[2]) << 24;
+		block |= ((u64)scsicmd[3]) << 16;
+		block |= ((u64)scsicmd[4]) << 8;
+		block |= ((u64)scsicmd[5]);
 
-			qc->nsect = scsicmd[8];
-		}
-
-		tf->nsect = scsicmd[8];
-		tf->lbal = scsicmd[5];
-		tf->lbam = scsicmd[4];
-		tf->lbah = scsicmd[3];
+		n_block |= ((u32)scsicmd[7]) << 8;
+		n_block |= ((u32)scsicmd[8]);
 
 		VPRINTK("ten-byte command\n");
-		return 0;
-	}
-
-	if (scsicmd[0] == READ_6 || scsicmd[0] == WRITE_6) {
-		qc->nsect = tf->nsect = scsicmd[4];
-		tf->lbal = scsicmd[3];
-		tf->lbam = scsicmd[2];
-		tf->lbah = scsicmd[1] & 0x1f; /* mask out reserved bits */
-
+	} else if (scsicmd[0] == READ_6 || scsicmd[0] == WRITE_6) {
+		block |= ((u64)scsicmd[2]) << 8;
+		block |= ((u64)scsicmd[3]);
+		n_block |= ((u32)scsicmd[4]);
+	
 		VPRINTK("six-byte command\n");
-		return 0;
-	}
+	} else if (scsicmd[0] == READ_16 || scsicmd[0] == WRITE_16) {
+		block |= ((u64)scsicmd[2]) << 56;
+		block |= ((u64)scsicmd[3]) << 48;
+		block |= ((u64)scsicmd[4]) << 40;
+		block |= ((u64)scsicmd[5]) << 32;
+		block |= ((u64)scsicmd[6]) << 24;
+		block |= ((u64)scsicmd[7]) << 16;
+		block |= ((u64)scsicmd[8]) << 8;
+		block |= ((u64)scsicmd[9]);
+
+		n_block |= ((u32)scsicmd[10]) << 24;
+		n_block |= ((u32)scsicmd[11]) << 16;
+		n_block |= ((u32)scsicmd[12]) << 8;
+		n_block |= ((u32)scsicmd[13]);
 
-	if (scsicmd[0] == READ_16 || scsicmd[0] == WRITE_16) {
-		/* rule out impossible LBAs and sector counts */
-		if (scsicmd[2] || scsicmd[3] || scsicmd[10] || scsicmd[11])
-			return 1;
+		VPRINTK("sixteen-byte command\n");
+	} else {
+		DPRINTK("no-byte command\n");
+		return 1;
+	}
 
-		if (lba48) {
-			tf->hob_nsect = scsicmd[12];
-			tf->hob_lbal = scsicmd[6];
-			tf->hob_lbam = scsicmd[5];
-			tf->hob_lbah = scsicmd[4];
+	/* Check and compose ATA command */
+	if (!n_block)
+		/* In ATA, sector count 0 are 256 or 65536 sectors, not 0 sectors. */
+		return 1;
 
-			qc->nsect = ((unsigned int)scsicmd[12] << 8) |
-					scsicmd[13];
-		} else {
-			/* once again, filter out impossible non-zero values */
-			if (scsicmd[4] || scsicmd[5] || scsicmd[12] ||
-			    (scsicmd[6] & 0xf0))
-				return 1;
+	if (lba48) {
+		/* The request -may- be too large for LBA48. */
+		if ((block >> 48) || (n_block > 65536))
+			return 1;
 
-			/* stores LBA27:24 in lower 4 bits of device reg */
-			tf->device |= scsicmd[6];
+		tf->hob_nsect = (n_block >> 8) & 0xff;
 
-			qc->nsect = scsicmd[13];
-		}
+		tf->hob_lbah = (block >> 40) & 0xff;
+		tf->hob_lbam = (block >> 32) & 0xff;
+		tf->hob_lbal = (block >> 24) & 0xff;
+	} else { 
+		/* LBA28 */
 
-		tf->nsect = scsicmd[13];
-		tf->lbal = scsicmd[9];
-		tf->lbam = scsicmd[8];
-		tf->lbah = scsicmd[7];
+		/* The request -may- be too large for LBA28. */
+		if ((block >> 28) || (n_block > 256))
+			return 1;
 
-		VPRINTK("sixteen-byte command\n");
-		return 0;
+		tf->device |= (block >> 24) & 0xf;
 	}
+	
+	qc->nsect = n_block;
+	tf->nsect = n_block & 0xff;
+
+	tf->lbah = (block >> 16) & 0xff;
+	tf->lbam = (block >> 8) & 0xff;
+	tf->lbal = block & 0xff;
 
-	DPRINTK("no-byte command\n");
-	return 1;
+	tf->device |= ATA_LBA;
+
+	return 0;
 }
 
 static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)

  reply	other threads:[~2005-02-14 11:18 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-02-06  6:02 [PATCH libata-dev-2.6 1/3] Add CHS support Albert Lee
2005-02-06  6:26 ` Jeff Garzik
2005-02-06 14:41   ` Mark Lord
2005-02-06 15:00     ` Jeff Garzik
2005-02-06 22:02       ` Mark Lord
2005-02-14 11:09   ` Albert Lee
2005-02-14 11:17     ` Albert Lee [this message]
2005-02-14 11:23       ` Albert Lee
2005-02-18 23:40 ` Jeff Garzik
2005-02-22  3:35   ` Albert Lee
2005-02-23 11:25   ` [PATCH libata-dev-2.6] Issue INITIALIZE DEVICE PARAMETERS for CHS only devices Albert Lee
2005-02-23 14:48     ` Mark Lord
2005-02-24  2:36       ` Albert Lee
2005-02-24  2:53         ` Jeff Garzik
2005-02-24  5:29           ` Albert Lee
2005-02-24  5:35             ` Jeff Garzik
2005-02-24  6:41               ` Albert Lee
2005-02-24  6:48                 ` Jeff Garzik
2005-02-24  7:01                   ` Albert Lee
2005-02-24  7:48                     ` Jeff Garzik
2005-02-25  5:01                       ` Albert Lee
2005-02-25  5:22                         ` Albert Lee
2005-02-25  5:40                         ` Jeff Garzik
2005-02-24  3:10         ` Mark Lord
2005-02-24  3:15           ` Jeff Garzik
2005-02-24  3:35             ` Mark Lord
2005-02-23 16:50     ` Bartlomiej Zolnierkiewicz
2005-02-24  3:05       ` Albert Lee

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='008e01c51286$d2f8b740$6401a8c0@tw.ibm.com' \
    --to=albertcc@tw.ibm.com \
    --cc=bzolnier@gmail.com \
    --cc=dwm@maxeymade.com \
    --cc=eric_mudama@Maxtor.com \
    --cc=jgarzik@pobox.com \
    --cc=linux-ide@vger.kernel.org \
    --cc=mlord@pobox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).