> 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-3: 
 - add CHS support to ata_scsi_verify_xlat(), ata_scsi_rw_xlat() and 
ata_scsiop_read_cap().

Albert

Signed-off-by: Albert Lee <[EMAIL PROTECTED]>
------------------------------------------------------------------
--- libata-dev-2.6/drivers/scsi/libata-scsi.c 2005-02-14 17:18:22.000000000 
+0800
+++ libata-dev-2.6-mod/drivers/scsi/libata-scsi.c 2005-02-14 17:25:43.000000000 
+0800
@@ -689,6 +689,8 @@
 static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 
*scsicmd)
 {
  struct ata_taskfile *tf = &qc->tf;
+ struct ata_device *dev = qc->dev;
+ unsigned int lba   = tf->flags & ATA_TFLAG_LBA;
  unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48;
  u64 dev_sectors = qc->dev->n_sectors;
  u64 block = 0;
@@ -696,7 +698,6 @@
 
  tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
  tf->protocol = ATA_PROT_NODATA;
- tf->device |= ATA_LBA;
 
  if (scsicmd[0] == VERIFY) {
   block |= ((u64)scsicmd[2]) << 24;
@@ -741,25 +742,53 @@
    return 1;
  }
 
- if (lba48) {
-  tf->command = ATA_CMD_VERIFY_EXT;
+ if (lba) {
+  if (lba48) {
+   tf->command = ATA_CMD_VERIFY_EXT;
+
+   tf->hob_nsect = (n_block >> 8) & 0xff;
+
+   tf->hob_lbah = (block >> 40) & 0xff;
+   tf->hob_lbam = (block >> 32) & 0xff;
+   tf->hob_lbal = (block >> 24) & 0xff;
+  } else {
+   tf->command = ATA_CMD_VERIFY;
 
-  tf->hob_nsect = (n_block >> 8) & 0xff;
+   tf->device |= (block >> 24) & 0xf;
+  }
 
-  tf->hob_lbah = (block >> 40) & 0xff;
-  tf->hob_lbam = (block >> 32) & 0xff;
-  tf->hob_lbal = (block >> 24) & 0xff;
- } else {
-  tf->command = ATA_CMD_VERIFY;
+  tf->nsect = n_block & 0xff;
 
-  tf->device |= (block >> 24) & 0xf;
- }
+  tf->lbah = (block >> 16) & 0xff;
+  tf->lbam = (block >> 8) & 0xff;
+  tf->lbal = block & 0xff;
 
- tf->nsect = n_block & 0xff;
+  tf->device |= ATA_LBA;
+ } else {
+  /* CHS */
+  u32 sect, head, cyl, track;
 
- tf->lbah = (block >> 16) & 0xff;
- tf->lbam = (block >> 8) & 0xff;
- tf->lbal = block & 0xff;
+  /* Convert LBA to CHS */
+  track = (u32)block / dev->sectors;
+  cyl   = track / dev->heads;
+  head  = track % dev->heads;
+  sect  = (u32)block % dev->sectors + 1;
+
+  DPRINTK("block[%u] track[%u] cyl[%u] head[%u] sect[%u] \n", (u32)block, 
track, cyl, head, sect);
+  
+  /* Check whether the converted CHS can fit. 
+     Cylinder: 0-65535 
+     Head: 0-15
+     Sector: 1-255*/
+  if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect)) 
+   return 1;
+  
+  tf->nsect = n_block & 0xff; /* Sector count 0 means 256 sectors */
+  tf->lbal = sect;
+  tf->lbam = cyl;
+  tf->lbah = cyl >> 8;
+  tf->device |= head;
+ }
 
  return 0;
 }
@@ -787,6 +816,8 @@
 static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
 {
  struct ata_taskfile *tf = &qc->tf;
+ struct ata_device *dev = qc->dev;
+ unsigned int lba   = tf->flags & ATA_TFLAG_LBA;
  unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48;
  u64 block = 0;
  u32 n_block = 0;
@@ -845,34 +876,66 @@
   /* In ATA, sector count 0 are 256 or 65536 sectors, not 0 sectors. */
   return 1;
 
- if (lba48) {
-  /* The request -may- be too large for LBA48. */
-  if ((block >> 48) || (n_block > 65536))
-   return 1;
+ if (lba) {
+  if (lba48) {
+   /* The request -may- be too large for LBA48. */
+   if ((block >> 48) || (n_block > 65536))
+    return 1;
+
+   tf->hob_nsect = (n_block >> 8) & 0xff;
+
+   tf->hob_lbah = (block >> 40) & 0xff;
+   tf->hob_lbam = (block >> 32) & 0xff;
+   tf->hob_lbal = (block >> 24) & 0xff;
+  } else { 
+   /* LBA28 */
+
+   /* The request -may- be too large for LBA28. */
+   if ((block >> 28) || (n_block > 256))
+    return 1;
+
+   tf->device |= (block >> 24) & 0xf;
+  }
+ 
+  qc->nsect = n_block;
+  tf->nsect = n_block & 0xff;
 
-  tf->hob_nsect = (n_block >> 8) & 0xff;
+  tf->lbah = (block >> 16) & 0xff;
+  tf->lbam = (block >> 8) & 0xff;
+  tf->lbal = block & 0xff;
 
-  tf->hob_lbah = (block >> 40) & 0xff;
-  tf->hob_lbam = (block >> 32) & 0xff;
-  tf->hob_lbal = (block >> 24) & 0xff;
+  tf->device |= ATA_LBA;
  } else { 
-  /* LBA28 */
+  /* CHS */
+  u32 sect, head, cyl, track;
 
-  /* The request -may- be too large for LBA28. */
+  /* The request -may- be too large for CHS addressing. */
   if ((block >> 28) || (n_block > 256))
    return 1;
-
-  tf->device |= (block >> 24) & 0xf;
+   
+  /* Convert LBA to CHS */
+  track = (u32)block / dev->sectors;
+  cyl   = track / dev->heads;
+  head  = track % dev->heads;
+  sect  = (u32)block % dev->sectors + 1;
+
+  DPRINTK("block[%u] track[%u] cyl[%u] head[%u] sect[%u] \n", 
+   (u32)block, track, cyl, head, sect);
+  
+  /* Check whether the converted CHS can fit. 
+     Cylinder: 0-65535 
+     Head: 0-15
+     Sector: 1-255*/
+  if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect)) 
+   return 1;
+  
+  qc->nsect = n_block;
+  tf->nsect = n_block & 0xff; /* Sector count 0 means 256 sectors */
+  tf->lbal = sect;
+  tf->lbam = cyl;
+  tf->lbah = cyl >> 8;
+  tf->device |= head;
  }
- 
- qc->nsect = n_block;
- tf->nsect = n_block & 0xff;
-
- tf->lbah = (block >> 16) & 0xff;
- tf->lbam = (block >> 8) & 0xff;
- tf->lbal = block & 0xff;
-
- tf->device |= ATA_LBA;
 
  return 0;
 }
@@ -1427,10 +1490,20 @@
 
  VPRINTK("ENTER\n");
 
- if (ata_id_has_lba48(args->id))
-  n_sectors = ata_id_u64(args->id, 100);
- else
-  n_sectors = ata_id_u32(args->id, 60);
+ if (ata_id_has_lba(args->id)) {
+  if (ata_id_has_lba48(args->id))
+   n_sectors = ata_id_u64(args->id, 100);
+  else
+   n_sectors = ata_id_u32(args->id, 60);
+ } else {
+  /* CHS default translation */
+  n_sectors = args->id[1] * args->id[3] * args->id[6];
+
+  if (ata_id_current_chs_valid(args->id))
+   /* CHS current translation */
+   n_sectors = ata_id_u32(args->id, 57);
+ }
+
  n_sectors--;  /* ATA TotalUserSectors - 1 */
 
  tmp = n_sectors; /* note: truncates, if lba48 */

Attachment: chs3-3.diff
Description: Binary data

Reply via email to