]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/commitdiff
Merge upstream kernel changes into 'C/H/S support' branch of libata.
authorJeff Garzik <jgarzik@pretzel.yyz.us>
Wed, 22 Jun 2005 17:07:28 +0000 (13:07 -0400)
committerJeff Garzik <jgarzik@pobox.com>
Wed, 22 Jun 2005 17:07:28 +0000 (13:07 -0400)
1  2 
drivers/scsi/libata-core.c
drivers/scsi/libata-scsi.c
include/linux/ata.h
include/linux/libata.h

index 96355b05fe5c7e980df16820e59520783cb0fcf0,36b401fee1f184d0ba6edcebd48a21e463bab89f..141de479caca949e4069bb765f741c1fbf71cbc6
@@@ -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);
@@@ -187,6 -186,28 +187,28 @@@ static void ata_tf_load_mmio(struct ata
        ata_wait_idle(ap);
  }
  
+ /**
+  *    ata_tf_load - send taskfile registers to host controller
+  *    @ap: Port to which output is sent
+  *    @tf: ATA taskfile register set
+  *
+  *    Outputs ATA taskfile to standard ATA host controller using MMIO
+  *    or PIO as indicated by the ATA_FLAG_MMIO flag.
+  *    Writes the control, feature, nsect, lbal, lbam, and lbah registers.
+  *    Optionally (ATA_TFLAG_LBA48) writes hob_feature, hob_nsect,
+  *    hob_lbal, hob_lbam, and hob_lbah.
+  *
+  *    This function waits for idle (!BUSY and !DRQ) after writing
+  *    registers.  If the control register has a new value, this
+  *    function also waits for idle after writing control and before
+  *    writing the remaining registers.
+  *
+  *    May be used as the tf_load() entry in ata_port_operations.
+  *
+  *    LOCKING:
+  *    Inherited from caller.
+  */
  void ata_tf_load(struct ata_port *ap, struct ata_taskfile *tf)
  {
        if (ap->flags & ATA_FLAG_MMIO)
  }
  
  /**
-  *    ata_exec_command - issue ATA command to host controller
+  *    ata_exec_command_pio - issue ATA command to host controller
   *    @ap: port to which command is being issued
   *    @tf: ATA taskfile register set
   *
-  *    Issues PIO/MMIO write to ATA command register, with proper
+  *    Issues PIO write to ATA command register, with proper
   *    synchronization with interrupt handler / other threads.
   *
   *    LOCKING:
@@@ -236,6 -257,18 +258,18 @@@ static void ata_exec_command_mmio(struc
        ata_pause(ap);
  }
  
+ /**
+  *    ata_exec_command - issue ATA command to host controller
+  *    @ap: port to which command is being issued
+  *    @tf: ATA taskfile register set
+  *
+  *    Issues PIO/MMIO write to ATA command register, with proper
+  *    synchronization with interrupt handler / other threads.
+  *
+  *    LOCKING:
+  *    spin_lock_irqsave(host_set lock)
+  */
  void ata_exec_command(struct ata_port *ap, struct ata_taskfile *tf)
  {
        if (ap->flags & ATA_FLAG_MMIO)
@@@ -306,7 -339,7 +340,7 @@@ void ata_tf_to_host_nolock(struct ata_p
  }
  
  /**
-  *    ata_tf_read - input device's ATA taskfile shadow registers
+  *    ata_tf_read_pio - input device's ATA taskfile shadow registers
   *    @ap: Port from which input is read
   *    @tf: ATA taskfile register set for storing input
   *
@@@ -369,6 -402,23 +403,23 @@@ static void ata_tf_read_mmio(struct ata
        }
  }
  
+ /**
+  *    ata_tf_read - input device's ATA taskfile shadow registers
+  *    @ap: Port from which input is read
+  *    @tf: ATA taskfile register set for storing input
+  *
+  *    Reads ATA taskfile registers for currently-selected device
+  *    into @tf.
+  *
+  *    Reads nsect, lbal, lbam, lbah, and device.  If ATA_TFLAG_LBA48
+  *    is set, also reads the hob registers.
+  *
+  *    May be used as the tf_read() entry in ata_port_operations.
+  *
+  *    LOCKING:
+  *    Inherited from caller.
+  */
  void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
  {
        if (ap->flags & ATA_FLAG_MMIO)
   *    @ap: port where the device is
   *
   *    Reads ATA taskfile status register for currently-selected device
-  *    and return it's value. This also clears pending interrupts
+  *    and return its value. This also clears pending interrupts
   *      from this device
   *
   *    LOCKING:
@@@ -398,7 -448,7 +449,7 @@@ static u8 ata_check_status_pio(struct a
   *    @ap: port where the device is
   *
   *    Reads ATA taskfile status register for currently-selected device
-  *    via MMIO and return it's value. This also clears pending interrupts
+  *    via MMIO and return its value. This also clears pending interrupts
   *      from this device
   *
   *    LOCKING:
@@@ -409,6 -459,20 +460,20 @@@ static u8 ata_check_status_mmio(struct 
                return readb((void __iomem *) ap->ioaddr.status_addr);
  }
  
+ /**
+  *    ata_check_status - Read device status reg & clear interrupt
+  *    @ap: port where the device is
+  *
+  *    Reads ATA taskfile status register for currently-selected device
+  *    and return its value. This also clears pending interrupts
+  *      from this device
+  *
+  *    May be used as the check_status() entry in ata_port_operations.
+  *
+  *    LOCKING:
+  *    Inherited from caller.
+  */
  u8 ata_check_status(struct ata_port *ap)
  {
        if (ap->flags & ATA_FLAG_MMIO)
        return ata_check_status_pio(ap);
  }
  
+ /**
+  *    ata_altstatus - Read device alternate status reg
+  *    @ap: port where the device is
+  *
+  *    Reads ATA taskfile alternate status register for
+  *    currently-selected device and return its value.
+  *
+  *    Note: may NOT be used as the check_altstatus() entry in
+  *    ata_port_operations.
+  *
+  *    LOCKING:
+  *    Inherited from caller.
+  */
  u8 ata_altstatus(struct ata_port *ap)
  {
        if (ap->ops->check_altstatus)
        return inb(ap->ioaddr.altstatus_addr);
  }
  
+ /**
+  *    ata_chk_err - Read device error reg
+  *    @ap: port where the device is
+  *
+  *    Reads ATA taskfile error register for
+  *    currently-selected device and return its value.
+  *
+  *    Note: may NOT be used as the check_err() entry in
+  *    ata_port_operations.
+  *
+  *    LOCKING:
+  *    Inherited from caller.
+  */
  u8 ata_chk_err(struct ata_port *ap)
  {
        if (ap->ops->check_err)
@@@ -874,10 -966,24 +967,24 @@@ void ata_dev_id_string(u16 *id, unsigne
        }
  }
  
+ /**
+  *    ata_noop_dev_select - Select device 0/1 on ATA bus
+  *    @ap: ATA channel to manipulate
+  *    @device: ATA device (numbered from zero) to select
+  *
+  *    This function performs no actual function.
+  *
+  *    May be used as the dev_select() entry in ata_port_operations.
+  *
+  *    LOCKING:
+  *    caller.
+  */
  void ata_noop_dev_select (struct ata_port *ap, unsigned int device)
  {
  }
  
  /**
   *    ata_std_dev_select - Select device 0/1 on ATA bus
   *    @ap: ATA channel to manipulate
   *
   *    Use the method defined in the ATA specification to
   *    make either device 0, or device 1, active on the
-  *    ATA channel.
+  *    ATA channel.  Works with both PIO and MMIO.
+  *
+  *    May be used as the dev_select() entry in ata_port_operations.
   *
   *    LOCKING:
   *    caller.
@@@ -1009,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;
@@@ -1107,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 */
@@@ -1224,11 -1295,47 +1333,47 @@@ err_out
        DPRINTK("EXIT, err\n");
  }
  
+ static inline u8 ata_dev_knobble(struct ata_port *ap)
+ {
+       return ((ap->cbl == ATA_CBL_SATA) && (!ata_id_is_sata(ap->device->id)));
+ }
+ /**
+  *    ata_dev_config - Run device specific handlers and check for
+  *                     SATA->PATA bridges
+  *    @ap: Bus 
+  *    @i:  Device
+  *
+  *    LOCKING:
+  */
+  
+ void ata_dev_config(struct ata_port *ap, unsigned int i)
+ {
+       /* limit bridge transfers to udma5, 200 sectors */
+       if (ata_dev_knobble(ap)) {
+               printk(KERN_INFO "ata%u(%u): applying bridge limits\n",
+                       ap->id, ap->device->devno);
+               ap->udma_mask &= ATA_UDMA5;
+               ap->host->max_sectors = ATA_MAX_SECTORS;
+               ap->host->hostt->max_sectors = ATA_MAX_SECTORS;
+               ap->device->flags |= ATA_DFLAG_LOCK_SECTORS;
+       }
+       if (ap->ops->dev_config)
+               ap->ops->dev_config(ap, &ap->device[i]);
+ }
  /**
   *    ata_bus_probe - Reset and probe ATA bus
   *    @ap: Bus to probe
   *
+  *    Master ATA bus probing function.  Initiates a hardware-dependent
+  *    bus reset, then attempts to identify any devices found on
+  *    the bus.
+  *
   *    LOCKING:
+  *    PCI/etc. bus probe sem.
   *
   *    RETURNS:
   *    Zero on success, non-zero on error.
@@@ -1246,8 -1353,7 +1391,7 @@@ static int ata_bus_probe(struct ata_por
                ata_dev_identify(ap, i);
                if (ata_dev_present(&ap->device[i])) {
                        found = 1;
-                       if (ap->ops->dev_config)
-                               ap->ops->dev_config(ap, &ap->device[i]);
+                       ata_dev_config(ap,i);
                }
        }
  
@@@ -1267,10 -1373,14 +1411,14 @@@ err_out
  }
  
  /**
-  *    ata_port_probe -
-  *    @ap:
+  *    ata_port_probe - Mark port as enabled
+  *    @ap: Port for which we indicate enablement
   *
-  *    LOCKING:
+  *    Modify @ap data structure such that the system
+  *    thinks that the entire port is enabled.
+  *
+  *    LOCKING: host_set lock, or some other form of
+  *    serialization.
   */
  
  void ata_port_probe(struct ata_port *ap)
  }
  
  /**
-  *    __sata_phy_reset -
-  *    @ap:
+  *    __sata_phy_reset - Wake/reset a low-level SATA PHY
+  *    @ap: SATA port associated with target SATA PHY.
+  *
+  *    This function issues commands to standard SATA Sxxx
+  *    PHY registers, to wake up the phy (and device), and
+  *    clear any reset condition.
   *
   *    LOCKING:
+  *    PCI/etc. bus probe sem.
   *
   */
  void __sata_phy_reset(struct ata_port *ap)
        unsigned long timeout = jiffies + (HZ * 5);
  
        if (ap->flags & ATA_FLAG_SATA_RESET) {
-               scr_write(ap, SCR_CONTROL, 0x301); /* issue phy wake/reset */
-               scr_read(ap, SCR_STATUS);       /* dummy read; flush */
+               /* issue phy wake/reset */
+               scr_write_flush(ap, SCR_CONTROL, 0x301);
                udelay(400);                    /* FIXME: a guess */
        }
-       scr_write(ap, SCR_CONTROL, 0x300);      /* issue phy wake/clear reset */
+       scr_write_flush(ap, SCR_CONTROL, 0x300); /* phy wake/clear reset */
  
        /* wait for phy to become ready, if necessary */
        do {
  }
  
  /**
-  *    __sata_phy_reset -
-  *    @ap:
+  *    sata_phy_reset - Reset SATA bus.
+  *    @ap: SATA port associated with target SATA PHY.
+  *
+  *    This function resets the SATA bus, and then probes
+  *    the bus for devices.
   *
   *    LOCKING:
+  *    PCI/etc. bus probe sem.
   *
   */
  void sata_phy_reset(struct ata_port *ap)
  }
  
  /**
-  *    ata_port_disable -
-  *    @ap:
+  *    ata_port_disable - Disable port.
+  *    @ap: Port to be disabled.
   *
-  *    LOCKING:
+  *    Modify @ap data structure such that the system
+  *    thinks that the entire port is disabled, and should
+  *    never attempt to probe or communicate with devices
+  *    on this port.
+  *
+  *    LOCKING: host_set lock, or some other form of
+  *    serialization.
   */
  
  void ata_port_disable(struct ata_port *ap)
@@@ -1454,7 -1579,10 +1617,10 @@@ static void ata_host_set_dma(struct ata
   *    ata_set_mode - Program timings and issue SET FEATURES - XFER
   *    @ap: port on which timings will be programmed
   *
+  *    Set ATA device disk transfer mode (PIO3, UDMA6, etc.).
+  *
   *    LOCKING:
+  *    PCI/etc. bus probe sem.
   *
   */
  static void ata_set_mode(struct ata_port *ap)
@@@ -1505,7 -1633,10 +1671,10 @@@ err_out
   *    @tmout_pat: impatience timeout
   *    @tmout: overall timeout
   *
-  *    LOCKING:
+  *    Sleep until ATA Status register bit BSY clears,
+  *    or a timeout occurs.
+  *
+  *    LOCKING: None.
   *
   */
  
@@@ -1591,10 -1722,14 +1760,14 @@@ static void ata_bus_post_reset(struct a
  }
  
  /**
-  *    ata_bus_edd -
-  *    @ap:
+  *    ata_bus_edd - Issue EXECUTE DEVICE DIAGNOSTIC command.
+  *    @ap: Port to reset and probe
+  *
+  *    Use the EXECUTE DEVICE DIAGNOSTIC command to reset and
+  *    probe the bus.  Not often used these days.
   *
   *    LOCKING:
+  *    PCI/etc. bus probe sem.
   *
   */
  
@@@ -1671,8 -1806,8 +1844,8 @@@ static unsigned int ata_bus_softreset(s
   *    the device is ATA or ATAPI.
   *
   *    LOCKING:
-  *    Inherited from caller.  Some functions called by this function
-  *    obtain the host_set lock.
+  *    PCI/etc. bus probe sem.
+  *    Obtains host_set lock.
   *
   *    SIDE EFFECTS:
   *    Sets ATA_FLAG_PORT_DISABLED if bus reset fails.
@@@ -1914,7 -2049,11 +2087,11 @@@ static int fgb(u32 bitmap
   *    @xfer_mode_out: (output) SET FEATURES - XFER MODE code
   *    @xfer_shift_out: (output) bit shift that selects this mode
   *
+  *    Based on host and device capabilities, determine the
+  *    maximum transfer mode that is amenable to all.
+  *
   *    LOCKING:
+  *    PCI/etc. bus probe sem.
   *
   *    RETURNS:
   *    Zero on success, negative on error.
@@@ -1947,7 -2086,11 +2124,11 @@@ static int ata_choose_xfer_mode(struct 
   *    @ap: Port associated with device @dev
   *    @dev: Device to which command will be sent
   *
+  *    Issue SET FEATURES - XFER MODE command to device @dev
+  *    on port @ap.
+  *
   *    LOCKING:
+  *    PCI/etc. bus probe sem.
   */
  
  static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev)
        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 -
-  *    @qc:
+  *    ata_sg_clean - Unmap DMA memory associated with command
+  *    @qc: Command containing DMA memory to be released
+  *
+  *    Unmap all mapped DMA memory associated with this command.
   *
   *    LOCKING:
+  *    spin_lock_irqsave(host_set lock)
   */
  
  static void ata_sg_clean(struct ata_queued_cmd *qc)
   *    ata_fill_sg - Fill PCI IDE PRD table
   *    @qc: Metadata associated with taskfile to be transferred
   *
+  *    Fill PCI IDE PRD (scatter-gather) table with segments
+  *    associated with the current disk command.
+  *
   *    LOCKING:
+  *    spin_lock_irqsave(host_set lock)
   *
   */
  static void ata_fill_sg(struct ata_queued_cmd *qc)
   *    ata_check_atapi_dma - Check whether ATAPI DMA can be supported
   *    @qc: Metadata associated with taskfile to check
   *
+  *    Allow low-level driver to filter ATA PACKET commands, returning
+  *    a status indicating whether or not it is OK to use DMA for the
+  *    supplied PACKET command.
+  *
   *    LOCKING:
+  *    spin_lock_irqsave(host_set lock)
+  *
   *    RETURNS: 0 when ATAPI DMA can be used
   *               nonzero otherwise
   */
@@@ -2132,6 -2240,8 +2326,8 @@@ int ata_check_atapi_dma(struct ata_queu
   *    ata_qc_prep - Prepare taskfile for submission
   *    @qc: Metadata associated with taskfile to be prepared
   *
+  *    Prepare ATA taskfile for submission.
+  *
   *    LOCKING:
   *    spin_lock_irqsave(host_set lock)
   */
@@@ -2143,6 -2253,32 +2339,32 @@@ void ata_qc_prep(struct ata_queued_cmd 
        ata_fill_sg(qc);
  }
  
+ /**
+  *    ata_sg_init_one - Associate command with memory buffer
+  *    @qc: Command to be associated
+  *    @buf: Memory buffer
+  *    @buflen: Length of memory buffer, in bytes.
+  *
+  *    Initialize the data-related elements of queued_cmd @qc
+  *    to point to a single memory buffer, @buf of byte length @buflen.
+  *
+  *    LOCKING:
+  *    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;
        sg = qc->sg;
        sg->page = virt_to_page(buf);
        sg->offset = (unsigned long) buf & ~PAGE_MASK;
-       sg_dma_len(sg) = buflen;
+       sg->length = buflen;
  }
  
+ /**
+  *    ata_sg_init - Associate command with scatter-gather table.
+  *    @qc: Command to be associated
+  *    @sg: Scatter-gather table.
+  *    @n_elem: Number of elements in s/g table.
+  *
+  *    Initialize the data-related elements of queued_cmd @qc
+  *    to point to a scatter-gather table @sg, containing @n_elem
+  *    elements.
+  *
+  *    LOCKING:
+  *    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)
  {
  }
  
  /**
-  *    ata_sg_setup_one -
-  *    @qc:
+  *    ata_sg_setup_one - DMA-map the memory buffer associated with a command.
+  *    @qc: Command with memory buffer to be mapped.
+  *
+  *    DMA-map the memory buffer associated with queued_cmd @qc.
   *
   *    LOCKING:
   *    spin_lock_irqsave(host_set lock)
   *
   *    RETURNS:
-  *
+  *    Zero on success, negative on error.
   */
  
  static int ata_sg_setup_one(struct ata_queued_cmd *qc)
        dma_addr_t dma_address;
  
        dma_address = dma_map_single(ap->host_set->dev, qc->buf_virt,
-                                    sg_dma_len(sg), dir);
+                                    sg->length, dir);
        if (dma_mapping_error(dma_address))
                return -1;
  
        sg_dma_address(sg) = dma_address;
+       sg_dma_len(sg) = sg->length;
  
        DPRINTK("mapped buffer of %d bytes for %s\n", sg_dma_len(sg),
                qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read");
  }
  
  /**
-  *    ata_sg_setup -
-  *    @qc:
+  *    ata_sg_setup - DMA-map the scatter-gather table associated with a command.
+  *    @qc: Command with scatter-gather table to be mapped.
+  *
+  *    DMA-map the scatter-gather table associated with queued_cmd @qc.
   *
   *    LOCKING:
   *    spin_lock_irqsave(host_set lock)
   *
   *    RETURNS:
+  *    Zero on success, negative on error.
   *
   */
  
@@@ -2236,6 -2404,7 +2490,7 @@@ static int ata_sg_setup(struct ata_queu
   *    @ap:
   *
   *    LOCKING:
+  *    None.  (executing in kernel thread context)
   *
   *    RETURNS:
   *
@@@ -2283,6 -2452,7 +2538,7 @@@ static unsigned long ata_pio_poll(struc
   *    @ap:
   *
   *    LOCKING:
+  *    None.  (executing in kernel thread context)
   */
  
  static void ata_pio_complete (struct ata_port *ap)
        ata_qc_complete(qc, drv_stat);
  }
  
+ /**
+  *    swap_buf_le16 -
+  *    @buf:  Buffer to swap
+  *    @buf_words:  Number of 16-bit words in buffer.
+  *
+  *    Swap halves of 16-bit words if needed to convert from
+  *    little-endian byte order to native cpu byte order, or
+  *    vice-versa.
+  *
+  *    LOCKING:
+  */
  void swap_buf_le16(u16 *buf, unsigned int buf_words)
  {
  #ifdef __BIG_ENDIAN
@@@ -2396,7 -2578,7 +2664,7 @@@ static void ata_pio_sector(struct ata_q
        qc->cursect++;
        qc->cursg_ofs++;
  
-       if ((qc->cursg_ofs * ATA_SECT_SIZE) == sg_dma_len(&sg[qc->cursg])) {
+       if ((qc->cursg_ofs * ATA_SECT_SIZE) == (&sg[qc->cursg])->length) {
                qc->cursg++;
                qc->cursg_ofs = 0;
        }
@@@ -2425,7 -2607,6 +2693,6 @@@ static void __atapi_pio_bytes(struct at
  next_sg:
        sg = &qc->sg[qc->cursg];
  
- next_page:
        page = sg->page;
        offset = sg->offset + qc->cursg_ofs;
  
        page = nth_page(page, (offset >> PAGE_SHIFT));
        offset %= PAGE_SIZE;
  
-       count = min(sg_dma_len(sg) - qc->cursg_ofs, bytes);
+       /* don't overrun current sg */
+       count = min(sg->length - qc->cursg_ofs, bytes);
  
        /* don't cross page boundaries */
        count = min(count, (unsigned int)PAGE_SIZE - offset);
        qc->curbytes += count;
        qc->cursg_ofs += count;
  
-       if (qc->cursg_ofs == sg_dma_len(sg)) {
+       if (qc->cursg_ofs == sg->length) {
                qc->cursg++;
                qc->cursg_ofs = 0;
        }
        kunmap(page);
  
        if (bytes) {
-               if (qc->cursg_ofs < sg_dma_len(sg))
-                       goto next_page;
                goto next_sg;
        }
  }
@@@ -2500,6 -2680,7 +2766,7 @@@ err_out
   *    @ap:
   *
   *    LOCKING:
+  *    None.  (executing in kernel thread context)
   */
  
  static void ata_pio_block(struct ata_port *ap)
@@@ -2625,7 -2806,7 +2892,7 @@@ static void atapi_request_sense(struct 
        ata_sg_init_one(qc, cmd->sense_buffer, sizeof(cmd->sense_buffer));
        qc->dma_dir = DMA_FROM_DEVICE;
  
-       memset(&qc->cdb, 0, sizeof(ap->cdb_len));
+       memset(&qc->cdb, 0, ap->cdb_len);
        qc->cdb[0] = REQUEST_SENSE;
        qc->cdb[4] = SCSI_SENSE_BUFFERSIZE;
  
   *    transaction completed successfully.
   *
   *    LOCKING:
+  *    Inherited from SCSI layer (none, can sleep)
   */
  
  static void ata_qc_timeout(struct ata_queued_cmd *qc)
@@@ -2777,6 -2959,7 +3045,7 @@@ out
   *    @dev: Device from whom we request an available command structure
   *
   *    LOCKING:
+  *    None.
   */
  
  static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
   *    @dev: Device from whom we request an available command structure
   *
   *    LOCKING:
+  *    None.
   */
  
  struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
  
                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;
@@@ -2870,6 -3050,7 +3140,7 @@@ static void __ata_qc_complete(struct at
   *    in case something prevents using it.
   *
   *    LOCKING:
+  *    spin_lock_irqsave(host_set lock)
   *
   */
  void ata_qc_free(struct ata_queued_cmd *qc)
  /**
   *    ata_qc_complete - Complete an active ATA command
   *    @qc: Command to complete
-  *    @drv_stat: ATA status register contents
+  *    @drv_stat: ATA Status register contents
+  *
+  *    Indicate to the mid and upper layers that an ATA
+  *    command has completed, with either an ok or not-ok status.
   *
   *    LOCKING:
+  *    spin_lock_irqsave(host_set lock)
   *
   */
  
@@@ -2901,6 -3086,7 +3176,7 @@@ void ata_qc_complete(struct ata_queued_
  
        /* call completion callback */
        rc = qc->complete_fn(qc, drv_stat);
+       qc->flags &= ~ATA_QCFLAG_ACTIVE;
  
        /* if callback indicates not to complete command (non-zero),
         * return immediately
@@@ -2980,6 -3166,7 +3256,7 @@@ err_out
        return -1;
  }
  
  /**
   *    ata_qc_issue_prot - issue taskfile to device in proto-dependent manner
   *    @qc: command to issue to device
   *    classes called "protocols", and issuing each type of protocol
   *    is slightly different.
   *
+  *    May be used as the qc_issue() entry in ata_port_operations.
+  *
   *    LOCKING:
   *    spin_lock_irqsave(host_set lock)
   *
@@@ -3046,7 -3235,7 +3325,7 @@@ int ata_qc_issue_prot(struct ata_queued
  }
  
  /**
-  *    ata_bmdma_setup - Set up PCI IDE BMDMA transaction
+  *    ata_bmdma_setup_mmio - Set up PCI IDE BMDMA transaction
   *    @qc: Info associated with this ATA transaction.
   *
   *    LOCKING:
@@@ -3153,6 -3342,18 +3432,18 @@@ static void ata_bmdma_start_pio (struc
             ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
  }
  
+ /**
+  *    ata_bmdma_start - Start a PCI IDE BMDMA transaction
+  *    @qc: Info associated with this ATA transaction.
+  *
+  *    Writes the ATA_DMA_START flag to the DMA command register.
+  *
+  *    May be used as the bmdma_start() entry in ata_port_operations.
+  *
+  *    LOCKING:
+  *    spin_lock_irqsave(host_set lock)
+  */
  void ata_bmdma_start(struct ata_queued_cmd *qc)
  {
        if (qc->ap->flags & ATA_FLAG_MMIO)
                ata_bmdma_start_pio(qc);
  }
  
+ /**
+  *    ata_bmdma_setup - Set up PCI IDE BMDMA transaction
+  *    @qc: Info associated with this ATA transaction.
+  *
+  *    Writes address of PRD table to device's PRD Table Address
+  *    register, sets the DMA control register, and calls
+  *    ops->exec_command() to start the transfer.
+  *
+  *    May be used as the bmdma_setup() entry in ata_port_operations.
+  *
+  *    LOCKING:
+  *    spin_lock_irqsave(host_set lock)
+  */
  void ata_bmdma_setup(struct ata_queued_cmd *qc)
  {
        if (qc->ap->flags & ATA_FLAG_MMIO)
                ata_bmdma_setup_pio(qc);
  }
  
+ /**
+  *    ata_bmdma_irq_clear - Clear PCI IDE BMDMA interrupt.
+  *    @ap: Port associated with this ATA transaction.
+  *
+  *    Clear interrupt and error flags in DMA status register.
+  *
+  *    May be used as the irq_clear() entry in ata_port_operations.
+  *
+  *    LOCKING:
+  *    spin_lock_irqsave(host_set lock)
+  */
  void ata_bmdma_irq_clear(struct ata_port *ap)
  {
      if (ap->flags & ATA_FLAG_MMIO) {
  
  }
  
+ /**
+  *    ata_bmdma_status - Read PCI IDE BMDMA status
+  *    @ap: Port associated with this ATA transaction.
+  *
+  *    Read and return BMDMA status register.
+  *
+  *    May be used as the bmdma_status() entry in ata_port_operations.
+  *
+  *    LOCKING:
+  *    spin_lock_irqsave(host_set lock)
+  */
  u8 ata_bmdma_status(struct ata_port *ap)
  {
        u8 host_stat;
        return host_stat;
  }
  
+ /**
+  *    ata_bmdma_stop - Stop PCI IDE BMDMA transfer
+  *    @ap: Port associated with this ATA transaction.
+  *
+  *    Clears the ATA_DMA_START flag in the dma control register
+  *
+  *    May be used as the bmdma_stop() entry in ata_port_operations.
+  *
+  *    LOCKING:
+  *    spin_lock_irqsave(host_set lock)
+  */
  void ata_bmdma_stop(struct ata_port *ap)
  {
        if (ap->flags & ATA_FLAG_MMIO) {
@@@ -3291,13 -3545,18 +3635,18 @@@ idle_irq
  
  /**
   *    ata_interrupt - Default ATA host interrupt handler
-  *    @irq: irq line
-  *    @dev_instance: pointer to our host information structure
+  *    @irq: irq line (unused)
+  *    @dev_instance: pointer to our ata_host_set information structure
   *    @regs: unused
   *
+  *    Default interrupt handler for PCI IDE devices.  Calls
+  *    ata_host_intr() for each port that is not disabled.
+  *
   *    LOCKING:
+  *    Obtains host_set lock during operation.
   *
   *    RETURNS:
+  *    IRQ_NONE or IRQ_HANDLED.
   *
   */
  
@@@ -3319,7 -3578,8 +3668,8 @@@ irqreturn_t ata_interrupt (int irq, voi
                        struct ata_queued_cmd *qc;
  
                        qc = ata_qc_from_tag(ap, ap->active_tag);
-                       if (qc && (!(qc->tf.ctl & ATA_NIEN)))
+                       if (qc && (!(qc->tf.ctl & ATA_NIEN)) &&
+                           (qc->flags & ATA_QCFLAG_ACTIVE))
                                handled |= ata_host_intr(ap, qc);
                }
        }
@@@ -3389,6 -3649,19 +3739,19 @@@ err_out
        ata_qc_complete(qc, ATA_ERR);
  }
  
+ /**
+  *    ata_port_start - Set port up for dma.
+  *    @ap: Port to initialize
+  *
+  *    Called just after data structures for each port are
+  *    initialized.  Allocates space for PRD table.
+  *
+  *    May be used as the port_start() entry in ata_port_operations.
+  *
+  *    LOCKING:
+  */
  int ata_port_start (struct ata_port *ap)
  {
        struct device *dev = ap->host_set->dev;
        return 0;
  }
  
+ /**
+  *    ata_port_stop - Undo ata_port_start()
+  *    @ap: Port to shut down
+  *
+  *    Frees the PRD table.
+  *
+  *    May be used as the port_stop() entry in ata_port_operations.
+  *
+  *    LOCKING:
+  */
  void ata_port_stop (struct ata_port *ap)
  {
        struct device *dev = ap->host_set->dev;
        dma_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma);
  }
  
+ void ata_host_stop (struct ata_host_set *host_set)
+ {
+       if (host_set->mmio_base)
+               iounmap(host_set->mmio_base);
+ }
  /**
   *    ata_host_remove - Unregister SCSI host structure with upper layers
   *    @ap: Port to unregister
@@@ -3437,7 -3729,11 +3819,11 @@@ static void ata_host_remove(struct ata_
   *    @ent: Probe information provided by low-level driver
   *    @port_no: Port number associated with this ata_port
   *
+  *    Initialize a new ata_port structure, and its associated
+  *    scsi_host.
+  *
   *    LOCKING:
+  *    Inherited from caller.
   *
   */
  
@@@ -3492,9 -3788,13 +3878,13 @@@ static void ata_host_init(struct ata_po
   *    @host_set: Collections of ports to which we add
   *    @port_no: Port number associated with this host
   *
+  *    Attach low-level ATA driver to system.
+  *
   *    LOCKING:
+  *    PCI/etc. bus probe sem.
   *
   *    RETURNS:
+  *    New ata_port on success, for NULL on error.
   *
   */
  
@@@ -3527,12 -3827,22 +3917,22 @@@ err_out
  }
  
  /**
-  *    ata_device_add -
-  *    @ent:
+  *    ata_device_add - Register hardware device with ATA and SCSI layers
+  *    @ent: Probe information describing hardware device to be registered
+  *
+  *    This function processes the information provided in the probe
+  *    information struct @ent, allocates the necessary ATA and SCSI
+  *    host information structures, initializes them, and registers
+  *    everything with requisite kernel subsystems.
+  *
+  *    This function requests irqs, probes the ATA bus, and probes
+  *    the SCSI bus.
   *
   *    LOCKING:
+  *    PCI/etc. bus probe sem.
   *
   *    RETURNS:
+  *    Number of ports registered.  Zero on error (no ports registered).
   *
   */
  
@@@ -3684,7 -3994,15 +4084,15 @@@ int ata_scsi_release(struct Scsi_Host *
  /**
   *    ata_std_ports - initialize ioaddr with standard port offsets.
   *    @ioaddr: IO address structure to be initialized
+  *
+  *    Utility function which initializes data_addr, error_addr,
+  *    feature_addr, nsect_addr, lbal_addr, lbam_addr, lbah_addr,
+  *    device_addr, status_addr, and command_addr to standard offsets
+  *    relative to cmd_addr.
+  *
+  *    Does not set ctl_addr, altstatus_addr, bmdma_addr, or scr_addr.
   */
  void ata_std_ports(struct ata_ioports *ioaddr)
  {
        ioaddr->data_addr = ioaddr->cmd_addr + ATA_REG_DATA;
@@@ -3726,6 -4044,20 +4134,20 @@@ ata_probe_ent_alloc(struct device *dev
        return probe_ent;
  }
  
+ /**
+  *    ata_pci_init_native_mode - Initialize native-mode driver
+  *    @pdev:  pci device to be initialized
+  *    @port:  array[2] of pointers to port info structures.
+  *
+  *    Utility function which allocates and initializes an
+  *    ata_probe_ent structure for a standard dual-port
+  *    PIO-based IDE controller.  The returned ata_probe_ent
+  *    structure can be passed to ata_device_add().  The returned
+  *    ata_probe_ent structure should then be freed with kfree().
+  */
  #ifdef CONFIG_PCI
  struct ata_probe_ent *
  ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port)
@@@ -3807,10 -4139,19 +4229,19 @@@ ata_pci_init_legacy_mode(struct pci_de
   *    @port_info: Information from low-level host driver
   *    @n_ports: Number of ports attached to host controller
   *
+  *    This is a helper function which can be called from a driver's
+  *    xxx_init_one() probe function if the hardware uses traditional
+  *    IDE taskfile registers.
+  *
+  *    This function calls pci_enable_device(), reserves its register
+  *    regions, sets the dma mask, enables bus master mode, and calls
+  *    ata_device_add()
+  *
   *    LOCKING:
   *    Inherited from PCI layer (may sleep).
   *
   *    RETURNS:
+  *    Zero on success, negative on errno-based value on error.
   *
   */
  
@@@ -3965,10 -4306,6 +4396,6 @@@ void ata_pci_remove_one (struct pci_de
        }
  
        free_irq(host_set->irq, host_set);
-       if (host_set->ops->host_stop)
-               host_set->ops->host_stop(host_set);
-       if (host_set->mmio_base)
-               iounmap(host_set->mmio_base);
  
        for (i = 0; i < host_set->n_ports; i++) {
                ap = host_set->ports[i];
                scsi_host_put(ap->host);
        }
  
+       if (host_set->ops->host_stop)
+               host_set->ops->host_stop(host_set);
        kfree(host_set);
  
        pci_release_regions(pdev);
@@@ -4030,15 -4370,6 +4460,6 @@@ int pci_test_config_bits(struct pci_de
  #endif /* CONFIG_PCI */
  
  
- /**
-  *    ata_init -
-  *
-  *    LOCKING:
-  *
-  *    RETURNS:
-  *
-  */
  static int __init ata_init(void)
  {
        ata_wq = create_workqueue("ata");
@@@ -4084,6 -4415,7 +4505,7 @@@ EXPORT_SYMBOL_GPL(ata_chk_err)
  EXPORT_SYMBOL_GPL(ata_exec_command);
  EXPORT_SYMBOL_GPL(ata_port_start);
  EXPORT_SYMBOL_GPL(ata_port_stop);
+ EXPORT_SYMBOL_GPL(ata_host_stop);
  EXPORT_SYMBOL_GPL(ata_interrupt);
  EXPORT_SYMBOL_GPL(ata_qc_prep);
  EXPORT_SYMBOL_GPL(ata_bmdma_setup);
@@@ -4104,6 -4436,7 +4526,7 @@@ EXPORT_SYMBOL_GPL(ata_scsi_release)
  EXPORT_SYMBOL_GPL(ata_host_intr);
  EXPORT_SYMBOL_GPL(ata_dev_classify);
  EXPORT_SYMBOL_GPL(ata_dev_id_string);
+ EXPORT_SYMBOL_GPL(ata_dev_config);
  EXPORT_SYMBOL_GPL(ata_scsi_simulate);
  
  #ifdef CONFIG_PCI
index 8b065ef0e39abaca243d67fc9158f9b52bfbf993,7a4adc4c8f09d6ef9cdb7460f4e6846d0def4647..5367c10e4db85db08ee0be44654daffb07928af3
@@@ -347,7 -347,10 +347,10 @@@ int ata_scsi_slave_config(struct scsi_d
                 */
                if ((dev->flags & ATA_DFLAG_LBA48) &&
                    ((dev->flags & ATA_DFLAG_LOCK_SECTORS) == 0)) {
-                       sdev->host->max_sectors = 2048;
+                       /*
+                        * do not overwrite sdev->host->max_sectors, since
+                        * other drives on this host may not support LBA48
+                        */
                        blk_queue_max_sectors(sdev->request_queue, 2048);
                }
        }
@@@ -435,107 -438,77 +438,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)
@@@ -1008,7 -947,7 +1011,7 @@@ unsigned int ata_scsiop_inq_83(struct a
  }
  
  /**
-  *    ata_scsiop_noop -
+  *    ata_scsiop_noop - Command handler that simply returns success.
   *    @args: device IDENTIFY data / SCSI command of interest.
   *    @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
   *    @buflen: Response buffer length.
@@@ -1231,20 -1170,10 +1234,20 @@@ 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 */
diff --combined include/linux/ata.h
index d8981402cd5b986bb3a094790781da768b7fd278,ca5fcadf998194cd663ff0414bc7435896749e84..6962e26fc6dfa5a6fa046c7a5dea8a6daf76815e
@@@ -125,7 -125,6 +125,7 @@@ enum 
        ATA_CMD_PACKET          = 0xA0,
        ATA_CMD_VERIFY          = 0x40,
        ATA_CMD_VERIFY_EXT      = 0x42,
 +      ATA_CMD_INIT_DEV_PARAMS = 0x91,
  
        /* SETFEATURES stuff */
        SETFEATURES_XFER        = 0x03,
        ATA_TFLAG_ISADDR        = (1 << 1), /* enable r/w to nsect/lba regs */
        ATA_TFLAG_DEVICE        = (1 << 2), /* enable r/w to device reg */
        ATA_TFLAG_WRITE         = (1 << 3), /* data dir: host->dev==1 (write) */
 +      ATA_TFLAG_LBA           = (1 << 4), /* enable LBA */
  };
  
  enum ata_tf_protocols {
@@@ -226,6 -224,7 +226,7 @@@ struct ata_taskfile 
  };
  
  #define ata_id_is_ata(id)     (((id)[0] & (1 << 15)) == 0)
+ #define ata_id_is_sata(id)    ((id)[93] == 0)
  #define ata_id_rahead_enabled(id) ((id)[85] & (1 << 6))
  #define ata_id_wcache_enabled(id) ((id)[85] & (1 << 5))
  #define ata_id_has_flush(id) ((id)[83] & (1 << 12))
          ((u64) (id)[(n) + 1] << 16) | \
          ((u64) (id)[(n) + 0]) )
  
 +static inline int ata_id_current_chs_valid(u16 *id)
 +{
 +      /* For ATA-1 devices, if the INITIALIZE DEVICE PARAMETERS command 
 +         has not been issued to the device then the values of 
 +         id[54] to id[56] are vendor specific. */
 +      return (id[53] & 0x01) && /* Current translation valid */
 +              id[54] &&  /* cylinders in current translation */
 +              id[55] &&  /* heads in current translation */
 +              id[55] <= 16 &&
 +              id[56];    /* sectors in current translation */
 +}
 +
  static inline int atapi_cdb_len(u16 *dev_id)
  {
        u16 tmp = dev_id[0] & 0x3;
diff --combined include/linux/libata.h
index bd0df84cfd877a05271597a1ac96a01d83de9ee9,6cd9ba63563b4db61b0977a88db84894d313735c..973090be7fc4e863ac27e9b5844550f25b58afd1
@@@ -95,7 -95,6 +95,7 @@@ enum 
        ATA_DFLAG_LBA48         = (1 << 0), /* device supports LBA48 */
        ATA_DFLAG_PIO           = (1 << 1), /* device currently in PIO mode */
        ATA_DFLAG_LOCK_SECTORS  = (1 << 2), /* don't adjust max_sectors */
 +      ATA_DFLAG_LBA           = (1 << 3), /* device supports LBA */
  
        ATA_DEV_UNKNOWN         = 0,    /* unknown device */
        ATA_DEV_ATA             = 1,    /* ATA device */
@@@ -279,11 -278,6 +279,11 @@@ struct ata_device 
        u8                      xfer_protocol;  /* taskfile xfer protocol */
        u8                      read_cmd;       /* opcode to use on read */
        u8                      write_cmd;      /* opcode to use on write */
 +
 +      /* for CHS addressing */
 +      u16                     cylinders;      /* Number of cylinders */
 +      u16                     heads;          /* Number of heads */
 +      u16                     sectors;        /* Number of sectors per track */
  };
  
  struct ata_port {
@@@ -416,6 -410,7 +416,7 @@@ extern u8 ata_chk_err(struct ata_port *
  extern void ata_exec_command(struct ata_port *ap, struct ata_taskfile *tf);
  extern int ata_port_start (struct ata_port *ap);
  extern void ata_port_stop (struct ata_port *ap);
+ extern void ata_host_stop (struct ata_host_set *host_set);
  extern irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
  extern void ata_qc_prep(struct ata_queued_cmd *qc);
  extern int ata_qc_issue_prot(struct ata_queued_cmd *qc);
@@@ -426,6 -421,7 +427,7 @@@ extern void ata_sg_init(struct ata_queu
  extern unsigned int ata_dev_classify(struct ata_taskfile *tf);
  extern void ata_dev_id_string(u16 *id, unsigned char *s,
                              unsigned int ofs, unsigned int len);
+ extern void ata_dev_config(struct ata_port *ap, unsigned int i);
  extern void ata_bmdma_setup (struct ata_queued_cmd *qc);
  extern void ata_bmdma_start (struct ata_queued_cmd *qc);
  extern void ata_bmdma_stop(struct ata_port *ap);
@@@ -472,12 -468,34 +474,34 @@@ static inline u8 ata_chk_status(struct 
        return ap->ops->check_status(ap);
  }
  
+ /**
+  *    ata_pause - Flush writes and pause 400 nanoseconds.
+  *    @ap: Port to wait for.
+  *
+  *    LOCKING:
+  *    Inherited from caller.
+  */
  static inline void ata_pause(struct ata_port *ap)
  {
        ata_altstatus(ap);
        ndelay(400);
  }
  
+ /**
+  *    ata_busy_wait - Wait for a port status register
+  *    @ap: Port to wait for.
+  *
+  *    Waits up to max*10 microseconds for the selected bits in the port's
+  *    status register to be cleared.
+  *    Returns final value of status register.
+  *
+  *    LOCKING:
+  *    Inherited from caller.
+  */
  static inline u8 ata_busy_wait(struct ata_port *ap, unsigned int bits,
                               unsigned int max)
  {
        return status;
  }
  
+ /**
+  *    ata_wait_idle - Wait for a port to be idle.
+  *    @ap: Port to wait for.
+  *
+  *    Waits up to 10ms for port's BUSY and DRQ signals to clear.
+  *    Returns final value of status register.
+  *
+  *    LOCKING:
+  *    Inherited from caller.
+  */
  static inline u8 ata_wait_idle(struct ata_port *ap)
  {
        u8 status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
@@@ -530,6 -560,18 +566,18 @@@ static inline void ata_tf_init(struct a
                tf->device = ATA_DEVICE_OBS | ATA_DEV1;
  }
  
+ /**
+  *    ata_irq_on - Enable interrupts on a port.
+  *    @ap: Port on which interrupts are enabled.
+  *
+  *    Enable interrupts on a legacy IDE device using MMIO or PIO,
+  *    wait for idle, clear any pending interrupts.
+  *
+  *    LOCKING:
+  *    Inherited from caller.
+  */
  static inline u8 ata_irq_on(struct ata_port *ap)
  {
        struct ata_ioports *ioaddr = &ap->ioaddr;
        return tmp;
  }
  
+ /**
+  *    ata_irq_ack - Acknowledge a device interrupt.
+  *    @ap: Port on which interrupts are enabled.
+  *
+  *    Wait up to 10 ms for legacy IDE device to become idle (BUSY
+  *    or BUSY+DRQ clear).  Obtain dma status and port status from
+  *    device.  Clear the interrupt.  Return port status.
+  *
+  *    LOCKING:
+  */
  static inline u8 ata_irq_ack(struct ata_port *ap, unsigned int chk_drq)
  {
        unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY;
@@@ -590,6 -644,13 +650,13 @@@ static inline void scr_write(struct ata
        ap->ops->scr_write(ap, reg, val);
  }
  
+ static inline void scr_write_flush(struct ata_port *ap, unsigned int reg, 
+                                  u32 val)
+ {
+       ap->ops->scr_write(ap, reg, val);
+       (void) ap->ops->scr_read(ap, reg);
+ }
  static inline unsigned int sata_dev_present(struct ata_port *ap)
  {
        return ((scr_read(ap, SCR_STATUS) & 0xf) == 0x3) ? 1 : 0;