Merge libata branch 'chs-support' to latest upstream kernel.
authorJeff Garzik <jgarzik@pobox.com>
Mon, 29 Aug 2005 23:24:43 +0000 (19:24 -0400)
committerJeff Garzik <jgarzik@pobox.com>
Mon, 29 Aug 2005 23:24:43 +0000 (19:24 -0400)
1  2 
drivers/scsi/libata-core.c
drivers/scsi/libata-scsi.c
include/linux/ata.h
include/linux/libata.h

Simple merge
index 954d1bca3b2a4616df8cfae13ec7882a798bb287,346eb36b1e31e0c5665269077e65ef4f11149644..f8ddc2a29e9a744cd32b50a059da6e7430730734
@@@ -584,111 -616,90 +649,114 @@@ static unsigned int ata_scsi_rw_xlat(st
                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];
 -
 -                      qc->nsect = scsicmd[8];
 -              }
 +              block |= ((u64)scsicmd[2]) << 24;
 +              block |= ((u64)scsicmd[3]) << 16;
 +              block |= ((u64)scsicmd[4]) << 8;
 +              block |= ((u64)scsicmd[5]);
  
 -              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");
 -              if (qc->nsect == 0) /* we don't support length==0 cmds */
 -                      return 1;
 -              return 0;
 -      }
 -
 -      if (scsicmd[0] == READ_6 || scsicmd[0] == WRITE_6) {
 -              qc->nsect = tf->nsect = scsicmd[4];
 -              if (!qc->nsect) {
 -                      qc->nsect = 256;
 -                      if (lba48)
 -                              tf->hob_nsect = 1;
 -              }
 -
 -              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]);
++              if (!n_block)
++                      n_block = 256;
 +      
                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]);
 +
 +              VPRINTK("sixteen-byte command\n");
 +      } else {
 +              DPRINTK("no-byte command\n");
 +              return 1;
        }
  
 -      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;
 +      /* Check and compose ATA command */
 +      if (!n_block)
 +              /* In ATA, sector count 0 means 256 or 65536 sectors, not 0 sectors. */
 +              return 1;
  
 +      if (lba) {
                if (lba48) {
 -                      tf->hob_nsect = scsicmd[12];
 -                      tf->hob_lbal = scsicmd[6];
 -                      tf->hob_lbam = scsicmd[5];
 -                      tf->hob_lbah = scsicmd[4];
 -
 -                      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))
 +                      /* 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;
 +
 +                      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;
  
 -                      qc->nsect = scsicmd[13];
 +                      tf->device |= (block >> 24) & 0xf;
                }
 +      
 +              qc->nsect = n_block;
 +              tf->nsect = n_block & 0xff;
  
 -              tf->nsect = scsicmd[13];
 -              tf->lbal = scsicmd[9];
 -              tf->lbam = scsicmd[8];
 -              tf->lbah = scsicmd[7];
 +              tf->lbah = (block >> 16) & 0xff;
 +              tf->lbam = (block >> 8) & 0xff;
 +              tf->lbal = block & 0xff;
  
 -              VPRINTK("sixteen-byte command\n");
 -              if (qc->nsect == 0) /* we don't support length==0 cmds */
 +              tf->device |= ATA_LBA;
 +      } else { 
 +              /* CHS */
 +              u32 sect, head, cyl, track;
 +
 +              /* The request -may- be too large for CHS addressing. */
 +              if ((block >> 28) || (n_block > 256))
                        return 1;
 -              return 0;
 +                      
 +              /* 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;
        }
  
 -      DPRINTK("no-byte command\n");
 -      return 1;
 +      return 0;
  }
  
  static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
Simple merge
Simple merge