> 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 <[EMAIL PROTECTED]>
------------------------------------------------------------------
--- 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: chs3-2.diff
Description: Binary data

Reply via email to