/spare/repo/libata-dev branch 'v2.6.13'
authorJeff Garzik <jgarzik@pobox.com>
Mon, 29 Aug 2005 20:12:36 +0000 (16:12 -0400)
committerJeff Garzik <jgarzik@pobox.com>
Mon, 29 Aug 2005 20:12:36 +0000 (16:12 -0400)
1  2 
drivers/scsi/libata-core.c
drivers/scsi/libata-scsi.c

index 141de479caca949e4069bb765f741c1fbf71cbc6,f4e7dcb6492bcdbfed7d9dced994caf44d24d38b..35b61d699f3456f91ca45a2ebce0470f37ef6d1d
@@@ -52,7 -52,6 +52,7 @@@
  static unsigned int ata_busy_sleep (struct ata_port *ap,
                                    unsigned long tmout_pat,
                                    unsigned long tmout);
 +static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev);
  static void ata_set_mode(struct ata_port *ap);
  static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev);
  static unsigned int ata_get_mode_mask(struct ata_port *ap, int shift);
@@@ -1118,7 -1117,7 +1118,7 @@@ static inline void ata_dump_id(struct a
  static void ata_dev_identify(struct ata_port *ap, unsigned int device)
  {
        struct ata_device *dev = &ap->device[device];
 -      unsigned int i;
 +      unsigned int major_version;
        u16 tmp;
        unsigned long xfer_modes;
        u8 status;
@@@ -1216,9 -1215,9 +1216,9 @@@ retry
         * common ATA, ATAPI feature tests
         */
  
 -      /* we require LBA and DMA support (bits 8 & 9 of word 49) */
 -      if (!ata_id_has_dma(dev->id) || !ata_id_has_lba(dev->id)) {
 -              printk(KERN_DEBUG "ata%u: no dma/lba\n", ap->id);
 +      /* we require DMA support (bits 8 of word 49) */
 +      if (!ata_id_has_dma(dev->id)) {
 +              printk(KERN_DEBUG "ata%u: no dma\n", ap->id);
                goto err_out_nosup;
        }
  
                if (!ata_id_is_ata(dev->id))    /* sanity check */
                        goto err_out_nosup;
  
 +              /* get major version */
                tmp = dev->id[ATA_ID_MAJOR_VER];
 -              for (i = 14; i >= 1; i--)
 -                      if (tmp & (1 << i))
 +              for (major_version = 14; major_version >= 1; major_version--)
 +                      if (tmp & (1 << major_version))
                                break;
  
 -              /* we require at least ATA-3 */
 -              if (i < 3) {
 -                      printk(KERN_DEBUG "ata%u: no ATA-3\n", ap->id);
 -                      goto err_out_nosup;
 -              }
 +              /*
 +               * The exact sequence expected by certain pre-ATA4 drives is:
 +               * SRST RESET
 +               * IDENTIFY
 +               * INITIALIZE DEVICE PARAMETERS
 +               * anything else..
 +               * Some drives were very specific about that exact sequence.
 +               */
 +              if (major_version < 4 || (!ata_id_has_lba(dev->id)))
 +                      ata_dev_init_params(ap, dev);
 +
 +              if (ata_id_has_lba(dev->id)) {
 +                      dev->flags |= ATA_DFLAG_LBA;
 +
 +                      if (ata_id_has_lba48(dev->id)) {
 +                              dev->flags |= ATA_DFLAG_LBA48;
 +                              dev->n_sectors = ata_id_u64(dev->id, 100);
 +                      } else {
 +                              dev->n_sectors = ata_id_u32(dev->id, 60);
 +                      }
 +
 +                      /* print device info to dmesg */
 +                      printk(KERN_INFO "ata%u: dev %u ATA-%d, max %s, %Lu sectors:%s\n",
 +                             ap->id, device,
 +                             major_version,
 +                             ata_mode_string(xfer_modes),
 +                             (unsigned long long)dev->n_sectors,
 +                             dev->flags & ATA_DFLAG_LBA48 ? " LBA48" : " LBA");
 +              } else { 
 +                      /* CHS */
 +
 +                      /* Default translation */
 +                      dev->cylinders  = dev->id[1];
 +                      dev->heads      = dev->id[3];
 +                      dev->sectors    = dev->id[6];
 +                      dev->n_sectors  = dev->cylinders * dev->heads * dev->sectors;
 +
 +                      if (ata_id_current_chs_valid(dev->id)) {
 +                              /* Current CHS translation is valid. */
 +                              dev->cylinders = dev->id[54];
 +                              dev->heads     = dev->id[55];
 +                              dev->sectors   = dev->id[56];
 +                              
 +                              dev->n_sectors = ata_id_u32(dev->id, 57);
 +                      }
 +
 +                      /* print device info to dmesg */
 +                      printk(KERN_INFO "ata%u: dev %u ATA-%d, max %s, %Lu sectors: CHS %d/%d/%d\n",
 +                             ap->id, device,
 +                             major_version,
 +                             ata_mode_string(xfer_modes),
 +                             (unsigned long long)dev->n_sectors,
 +                             (int)dev->cylinders, (int)dev->heads, (int)dev->sectors);
  
 -              if (ata_id_has_lba48(dev->id)) {
 -                      dev->flags |= ATA_DFLAG_LBA48;
 -                      dev->n_sectors = ata_id_u64(dev->id, 100);
 -              } else {
 -                      dev->n_sectors = ata_id_u32(dev->id, 60);
                }
  
                ap->host->max_cmd_len = 16;
 -
 -              /* print device info to dmesg */
 -              printk(KERN_INFO "ata%u: dev %u ATA, max %s, %Lu sectors:%s\n",
 -                     ap->id, device,
 -                     ata_mode_string(xfer_modes),
 -                     (unsigned long long)dev->n_sectors,
 -                     dev->flags & ATA_DFLAG_LBA48 ? " lba48" : "");
        }
  
        /* ATAPI-specific feature tests */
@@@ -1446,7 -1408,9 +1446,9 @@@ void __sata_phy_reset(struct ata_port *
        if (ap->flags & ATA_FLAG_SATA_RESET) {
                /* issue phy wake/reset */
                scr_write_flush(ap, SCR_CONTROL, 0x301);
-               udelay(400);                    /* FIXME: a guess */
+               /* Couldn't find anything in SATA I/II specs, but
+                * AHCI-1.1 10.4.2 says at least 1 ms. */
+               mdelay(1);
        }
        scr_write_flush(ap, SCR_CONTROL, 0x300); /* phy wake/clear reset */
  
@@@ -1958,6 -1922,7 +1960,7 @@@ static const char * ata_dma_blacklist [
        "HITACHI CDR-8335",
        "HITACHI CDR-8435",
        "Toshiba CD-ROM XM-6202B",
+       "TOSHIBA CD-ROM XM-1702BC",
        "CD-532E-A",
        "E-IDE CD-ROM CR-840",
        "CD-ROM Drive/F5A",
        "SAMSUNG CD-ROM SC-148C",
        "SAMSUNG CD-ROM SC",
        "SanDisk SDP3B-64",
-       "SAMSUNG CD-ROM SN-124",
        "ATAPI CD-ROM DRIVE 40X MAXIMUM",
        "_NEC DV5800A",
  };
@@@ -2165,54 -2129,6 +2167,54 @@@ static void ata_dev_set_xfermode(struc
        DPRINTK("EXIT\n");
  }
  
 +/**
 + *    ata_dev_init_params - Issue INIT DEV PARAMS command
 + *    @ap: Port associated with device @dev
 + *    @dev: Device to which command will be sent
 + *
 + *    LOCKING:
 + */
 +
 +static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev)
 +{
 +      DECLARE_COMPLETION(wait);
 +      struct ata_queued_cmd *qc;
 +      int rc;
 +      unsigned long flags;
 +      u16 sectors = dev->id[6];
 +      u16 heads   = dev->id[3];
 +
 +      /* Number of sectors per track 1-255. Number of heads 1-16 */
 +      if (sectors < 1 || sectors > 255 || heads < 1 || heads > 16)
 +              return;
 +
 +      /* set up init dev params taskfile */
 +      DPRINTK("init dev params \n");
 +
 +      qc = ata_qc_new_init(ap, dev);
 +      BUG_ON(qc == NULL);
 +
 +      qc->tf.command = ATA_CMD_INIT_DEV_PARAMS;
 +      qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
 +      qc->tf.protocol = ATA_PROT_NODATA;
 +      qc->tf.nsect = sectors;
 +      qc->tf.device |= (heads - 1) & 0x0f; /* max head = num. of heads - 1 */
 +
 +      qc->waiting = &wait;
 +      qc->complete_fn = ata_qc_complete_noop;
 +
 +      spin_lock_irqsave(&ap->host_set->lock, flags);
 +      rc = ata_qc_issue(qc);
 +      spin_unlock_irqrestore(&ap->host_set->lock, flags);
 +
 +      if (rc)
 +              ata_port_disable(ap);
 +      else
 +              wait_for_completion(&wait);
 +
 +      DPRINTK("EXIT\n");
 +}
 +
  /**
   *    ata_sg_clean - Unmap DMA memory associated with command
   *    @qc: Command containing DMA memory to be released
@@@ -2352,19 -2268,6 +2354,6 @@@ void ata_qc_prep(struct ata_queued_cmd 
   *    spin_lock_irqsave(host_set lock)
   */
  
- /**
-  *    ata_sg_init_one - Prepare a one-entry scatter-gather list.
-  *    @qc:  Queued command
-  *    @buf:  transfer buffer
-  *    @buflen:  length of buf
-  *
-  *    Builds a single-entry scatter-gather list to initiate a
-  *    transfer utilizing the specified buffer.
-  *
-  *    LOCKING:
-  */
  void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen)
  {
        struct scatterlist *sg;
   *    spin_lock_irqsave(host_set lock)
   */
  
- /**
-  *    ata_sg_init - Assign a scatter gather list to a queued command
-  *    @qc:  Queued command
-  *    @sg:  Scatter-gather list
-  *    @n_elem:  length of sg list
-  *
-  *    Attaches a scatter-gather list to a queued command.
-  *
-  *    LOCKING:
-  */
  void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
                 unsigned int n_elem)
  {
@@@ -2950,7 -2841,7 +2927,7 @@@ static void ata_qc_timeout(struct ata_q
        if (qc->dev->class == ATA_DEV_ATAPI && qc->scsicmd) {
                struct scsi_cmnd *cmd = qc->scsicmd;
  
-               if (!scsi_eh_eflags_chk(cmd, SCSI_EH_CANCEL_CMD)) {
+               if (!(cmd->eh_eflags & SCSI_EH_CANCEL_CMD)) {
  
                        /* finish completing original command */
                        __ata_qc_complete(qc);
@@@ -3092,12 -2983,8 +3069,12 @@@ struct ata_queued_cmd *ata_qc_new_init(
  
                ata_tf_init(ap, &qc->tf, dev->devno);
  
 -              if (dev->flags & ATA_DFLAG_LBA48)
 -                      qc->tf.flags |= ATA_TFLAG_LBA48;
 +              if (dev->flags & ATA_DFLAG_LBA) {
 +                      qc->tf.flags |= ATA_TFLAG_LBA;
 +
 +                      if (dev->flags & ATA_DFLAG_LBA48)
 +                              qc->tf.flags |= ATA_TFLAG_LBA48;
 +              }
        }
  
        return qc;
@@@ -3838,7 -3725,7 +3815,7 @@@ static void ata_host_init(struct ata_po
        host->max_channel = 1;
        host->unique_id = ata_unique_id++;
        host->max_cmd_len = 12;
-       scsi_set_device(host, ent->dev);
        scsi_assign_lock(host, &host_set->lock);
  
        ap->flags = ATA_FLAG_PORT_DISABLED;
index 5367c10e4db85db08ee0be44654daffb07928af3,6a75ec2187fde5451b1ae77443ecc8aceb96e319..954d1bca3b2a4616df8cfae13ec7882a798bb287
@@@ -385,6 -385,7 +385,7 @@@ int ata_scsi_error(struct Scsi_Host *ho
         * appropriate place
         */
        host->host_failed--;
+       INIT_LIST_HEAD(&host->eh_cmd_q);
  
        DPRINTK("EXIT\n");
        return 0;
@@@ -438,107 -439,77 +439,107 @@@ static unsigned int ata_scsi_flush_xlat
  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 sect = 0;
 -      u32 n_sect = 0;
 +      u64 block = 0;
 +      u32 n_block = 0;
  
        tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
        tf->protocol = ATA_PROT_NODATA;
 -      tf->device |= ATA_LBA;
  
        if (scsicmd[0] == VERIFY) {
 -              sect |= ((u64)scsicmd[2]) << 24;
 -              sect |= ((u64)scsicmd[3]) << 16;
 -              sect |= ((u64)scsicmd[4]) << 8;
 -              sect |= ((u64)scsicmd[5]);
 +              block |= ((u64)scsicmd[2]) << 24;
 +              block |= ((u64)scsicmd[3]) << 16;
 +              block |= ((u64)scsicmd[4]) << 8;
 +              block |= ((u64)scsicmd[5]);
  
 -              n_sect |= ((u32)scsicmd[7]) << 8;
 -              n_sect |= ((u32)scsicmd[8]);
 +              n_block |= ((u32)scsicmd[7]) << 8;
 +              n_block |= ((u32)scsicmd[8]);
        }
  
        else if (scsicmd[0] == VERIFY_16) {
 -              sect |= ((u64)scsicmd[2]) << 56;
 -              sect |= ((u64)scsicmd[3]) << 48;
 -              sect |= ((u64)scsicmd[4]) << 40;
 -              sect |= ((u64)scsicmd[5]) << 32;
 -              sect |= ((u64)scsicmd[6]) << 24;
 -              sect |= ((u64)scsicmd[7]) << 16;
 -              sect |= ((u64)scsicmd[8]) << 8;
 -              sect |= ((u64)scsicmd[9]);
 -
 -              n_sect |= ((u32)scsicmd[10]) << 24;
 -              n_sect |= ((u32)scsicmd[11]) << 16;
 -              n_sect |= ((u32)scsicmd[12]) << 8;
 -              n_sect |= ((u32)scsicmd[13]);
 +              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]);
        }
  
        else
                return 1;
  
 -      if (!n_sect)
 +      if (!n_block)
                return 1;
 -      if (sect >= dev_sectors)
 +      if (block >= dev_sectors)
                return 1;
 -      if ((sect + n_sect) > dev_sectors)
 +      if ((block + n_block) > dev_sectors)
                return 1;
        if (lba48) {
 -              if (n_sect > (64 * 1024))
 +              if (n_block > (64 * 1024))
                        return 1;
        } else {
 -              if (n_sect > 256)
 +              if (n_block > 256)
                        return 1;
        }
  
 -      if (lba48) {
 -              tf->command = ATA_CMD_VERIFY_EXT;
 +      if (lba) {
 +              if (lba48) {
 +                      tf->command = ATA_CMD_VERIFY_EXT;
  
 -              tf->hob_nsect = (n_sect >> 8) & 0xff;
 +                      tf->hob_nsect = (n_block >> 8) & 0xff;
  
 -              tf->hob_lbah = (sect >> 40) & 0xff;
 -              tf->hob_lbam = (sect >> 32) & 0xff;
 -              tf->hob_lbal = (sect >> 24) & 0xff;
 -      } else {
 -              tf->command = ATA_CMD_VERIFY;
 +                      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->device |= (sect >> 24) & 0xf;
 -      }
 +                      tf->device |= (block >> 24) & 0xf;
 +              }
 +
 +              tf->nsect = n_block & 0xff;
  
 -      tf->nsect = n_sect & 0xff;
 +              tf->lbah = (block >> 16) & 0xff;
 +              tf->lbam = (block >> 8) & 0xff;
 +              tf->lbal = block & 0xff;
  
 -      tf->lbah = (sect >> 16) & 0xff;
 -      tf->lbam = (sect >> 8) & 0xff;
 -      tf->lbal = sect & 0xff;
 +              tf->device |= ATA_LBA;
 +      } else {
 +              /* CHS */
 +              u32 sect, head, cyl, track;
 +
 +              /* 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->command = ATA_CMD_VERIFY;
 +              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;
  }
  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;
  
        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) {
                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");
 -              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]);
 +
 +              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 */
  
 -                      qc->nsect = scsicmd[13];
 +                      /* 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->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");
 -              return 0;
 +              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;
 +                      
 +              /* 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)
@@@ -1234,24 -1171,18 +1235,28 @@@ unsigned int ata_scsiop_read_cap(struc
  
        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 */
        if (args->cmd->cmnd[0] == READ_CAPACITY) {
+               if( n_sectors >= 0xffffffffULL )
+                       tmp = 0xffffffff ;  /* Return max count on overflow */
+               else
+                       tmp = n_sectors ;
                /* sector count, 32-bit */
                rbuf[0] = tmp >> (8 * 3);
                rbuf[1] = tmp >> (8 * 2);
  
        } else {
                /* sector count, 64-bit */
-               rbuf[2] = n_sectors >> (8 * 7);
-               rbuf[3] = n_sectors >> (8 * 6);
-               rbuf[4] = n_sectors >> (8 * 5);
-               rbuf[5] = n_sectors >> (8 * 4);
+               tmp = n_sectors >> (8 * 4);
+               rbuf[2] = tmp >> (8 * 3);
+               rbuf[3] = tmp >> (8 * 2);
+               rbuf[4] = tmp >> (8 * 1);
+               rbuf[5] = tmp;
+               tmp = n_sectors;
                rbuf[6] = tmp >> (8 * 3);
                rbuf[7] = tmp >> (8 * 2);
                rbuf[8] = tmp >> (8 * 1);