[PATCH] libata: implement ata_tf_read_block()
[linux-2.6.git] / drivers / ata / libata-core.c
index 7d786fb..3fd7c79 100644 (file)
@@ -240,6 +240,49 @@ int ata_rwcmd_protocol(struct ata_queued_cmd *qc)
 }
 
 /**
+ *     ata_tf_read_block - Read block address from ATA taskfile
+ *     @tf: ATA taskfile of interest
+ *     @dev: ATA device @tf belongs to
+ *
+ *     LOCKING:
+ *     None.
+ *
+ *     Read block address from @tf.  This function can handle all
+ *     three address formats - LBA, LBA48 and CHS.  tf->protocol and
+ *     flags select the address format to use.
+ *
+ *     RETURNS:
+ *     Block address read from @tf.
+ */
+u64 ata_tf_read_block(struct ata_taskfile *tf, struct ata_device *dev)
+{
+       u64 block = 0;
+
+       if (tf->flags & ATA_TFLAG_LBA) {
+               if (tf->flags & ATA_TFLAG_LBA48) {
+                       block |= (u64)tf->hob_lbah << 40;
+                       block |= (u64)tf->hob_lbam << 32;
+                       block |= tf->hob_lbal << 24;
+               } else
+                       block |= (tf->device & 0xf) << 24;
+
+               block |= tf->lbah << 16;
+               block |= tf->lbam << 8;
+               block |= tf->lbal;
+       } else {
+               u32 cyl, head, sect;
+
+               cyl = tf->lbam | (tf->lbah << 8);
+               head = tf->device & 0xf;
+               sect = tf->lbal;
+
+               block = (cyl * dev->heads + head) * dev->sectors + sect;
+       }
+
+       return block;
+}
+
+/**
  *     ata_pack_xfermask - Pack pio, mwdma and udma masks into xfer_mask
  *     @pio_mask: pio_mask
  *     @mwdma_mask: mwdma_mask
@@ -386,9 +429,13 @@ static const char *ata_mode_string(unsigned int xfer_mask)
                "PIO2",
                "PIO3",
                "PIO4",
+               "PIO5",
+               "PIO6",
                "MWDMA0",
                "MWDMA1",
                "MWDMA2",
+               "MWDMA3",
+               "MWDMA4",
                "UDMA/16",
                "UDMA/25",
                "UDMA/33",
@@ -612,8 +659,11 @@ ata_dev_try_classify(struct ata_port *ap, unsigned int device, u8 *r_err)
        if (r_err)
                *r_err = err;
 
-       /* see if device passed diags */
-       if (err == 1)
+       /* see if device passed diags: if master then continue and warn later */
+       if (err == 0 && device == 0)
+               /* diagnostic fail : do nothing _YET_ */
+               ap->device[device].horkage |= ATA_HORKAGE_DIAGNOSTIC;
+       else if (err == 1)
                /* do nothing */ ;
        else if ((device == 0) && (err == 0x81))
                /* do nothing */ ;
@@ -863,7 +913,11 @@ static unsigned int ata_id_xfermask(const u16 *id)
                 * the PIO timing number for the maximum. Turn it into
                 * a mask.
                 */
-               pio_mask = (2 << (id[ATA_ID_OLD_PIO_MODES] & 0xFF)) - 1 ;
+               u8 mode = id[ATA_ID_OLD_PIO_MODES] & 0xFF;
+               if (mode < 5)   /* Valid PIO range */
+                       pio_mask = (2 << mode) - 1;
+               else
+                       pio_mask = 1;
 
                /* But wait.. there's more. Design your standards by
                 * committee and you too can get a free iordy field to
@@ -875,6 +929,23 @@ static unsigned int ata_id_xfermask(const u16 *id)
 
        mwdma_mask = id[ATA_ID_MWDMA_MODES] & 0x07;
 
+       if (ata_id_is_cfa(id)) {
+               /*
+                *      Process compact flash extended modes
+                */
+               int pio = id[163] & 0x7;
+               int dma = (id[163] >> 3) & 7;
+
+               if (pio)
+                       pio_mask |= (1 << 5);
+               if (pio > 1)
+                       pio_mask |= (1 << 6);
+               if (dma)
+                       mwdma_mask |= (1 << 3);
+               if (dma > 1)
+                       mwdma_mask |= (1 << 4);
+       }
+
        udma_mask = 0;
        if (id[ATA_ID_FIELD_VALID] & (1 << 2))
                udma_mask = id[ATA_ID_UDMA_MODES] & 0xff;
@@ -1196,7 +1267,7 @@ unsigned int ata_pio_need_iordy(const struct ata_device *adev)
  *     ata_dev_read_id - Read ID data from the specified device
  *     @dev: target device
  *     @p_class: pointer to class of the target device (may be changed)
- *     @post_reset: is this read ID post-reset?
+ *     @flags: ATA_READID_* flags
  *     @id: buffer to read IDENTIFY data into
  *
  *     Read ID data from the specified device.  ATA_CMD_ID_ATA is
@@ -1211,7 +1282,7 @@ unsigned int ata_pio_need_iordy(const struct ata_device *adev)
  *     0 on success, -errno otherwise.
  */
 int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
-                   int post_reset, u16 *id)
+                   unsigned int flags, u16 *id)
 {
        struct ata_port *ap = dev->ap;
        unsigned int class = *p_class;
@@ -1244,9 +1315,20 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
 
        tf.protocol = ATA_PROT_PIO;
 
+       /* presence detection using polling IDENTIFY? */
+       if (flags & ATA_READID_DETECT)
+               tf.flags |= ATA_TFLAG_POLLING;
+
        err_mask = ata_exec_internal(dev, &tf, NULL, DMA_FROM_DEVICE,
                                     id, sizeof(id[0]) * ATA_ID_WORDS);
        if (err_mask) {
+               if ((flags & ATA_READID_DETECT) &&
+                   (err_mask & AC_ERR_NODEV_HINT)) {
+                       DPRINTK("ata%u.%d: NODEV after polling detection\n",
+                               ap->id, dev->devno);
+                       return -ENOENT;
+               }
+
                rc = -EIO;
                reason = "I/O error";
                goto err_out;
@@ -1255,13 +1337,18 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
        swap_buf_le16(id, ATA_ID_WORDS);
 
        /* sanity check */
-       if ((class == ATA_DEV_ATA) != (ata_id_is_ata(id) | ata_id_is_cfa(id))) {
-               rc = -EINVAL;
-               reason = "device reports illegal type";
-               goto err_out;
+       rc = -EINVAL;
+       reason = "device reports illegal type";
+
+       if (class == ATA_DEV_ATA) {
+               if (!ata_id_is_ata(id) && !ata_id_is_cfa(id))
+                       goto err_out;
+       } else {
+               if (ata_id_is_ata(id))
+                       goto err_out;
        }
 
-       if (post_reset && class == ATA_DEV_ATA) {
+       if ((flags & ATA_READID_POSTRESET) && class == ATA_DEV_ATA) {
                /*
                 * The exact sequence expected by certain pre-ATA4 drives is:
                 * SRST RESET
@@ -1281,7 +1368,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
                        /* current CHS translation info (id[53-58]) might be
                         * changed. reread the identify device info.
                         */
-                       post_reset = 0;
+                       flags &= ~ATA_READID_POSTRESET;
                        goto retry;
                }
        }
@@ -1312,9 +1399,12 @@ static void ata_dev_config_ncq(struct ata_device *dev,
                desc[0] = '\0';
                return;
        }
-
+       if (ata_device_blacklisted(dev) & ATA_HORKAGE_NONCQ) {
+               snprintf(desc, desc_sz, "NCQ (not used)");
+               return;
+       }
        if (ap->flags & ATA_FLAG_NCQ) {
-               hdepth = min(ap->host->can_queue, ATA_MAX_QUEUE - 1);
+               hdepth = min(ap->scsi_host->can_queue, ATA_MAX_QUEUE - 1);
                dev->flags |= ATA_DFLAG_NCQ;
        }
 
@@ -1328,19 +1418,19 @@ static void ata_set_port_max_cmd_len(struct ata_port *ap)
 {
        int i;
 
-       if (ap->host) {
-               ap->host->max_cmd_len = 0;
+       if (ap->scsi_host) {
+               unsigned int len = 0;
+
                for (i = 0; i < ATA_MAX_DEVICES; i++)
-                       ap->host->max_cmd_len = max_t(unsigned int,
-                                                     ap->host->max_cmd_len,
-                                                     ap->device[i].cdb_len);
+                       len = max(len, ap->device[i].cdb_len);
+
+               ap->scsi_host->max_cmd_len = len;
        }
 }
 
 /**
  *     ata_dev_configure - Configure the specified ATA/ATAPI device
  *     @dev: Target device to configure
- *     @print_info: Enable device info printout
  *
  *     Configure @dev according to @dev->id.  Generic and low-level
  *     driver specific fixups are also applied.
@@ -1351,11 +1441,13 @@ static void ata_set_port_max_cmd_len(struct ata_port *ap)
  *     RETURNS:
  *     0 on success, -errno otherwise
  */
-int ata_dev_configure(struct ata_device *dev, int print_info)
+int ata_dev_configure(struct ata_device *dev)
 {
        struct ata_port *ap = dev->ap;
+       int print_info = ap->eh_context.i.flags & ATA_EHI_PRINTINFO;
        const u16 *id = dev->id;
        unsigned int xfer_mask;
+       char revbuf[7];         /* XYZ-99\0 */
        int rc;
 
        if (!ata_dev_enabled(dev) && ata_msg_info(ap)) {
@@ -1399,6 +1491,15 @@ int ata_dev_configure(struct ata_device *dev, int print_info)
 
        /* ATA-specific feature tests */
        if (dev->class == ATA_DEV_ATA) {
+               if (ata_id_is_cfa(id)) {
+                       if (id[162] & 1) /* CPRM may make this media unusable */
+                               ata_dev_printk(dev, KERN_WARNING, "ata%u: device %u  supports DRM functions and may not be fully accessable.\n",
+                                       ap->id, dev->devno);
+                       snprintf(revbuf, 7, "CFA");
+               }
+               else
+                       snprintf(revbuf, 7, "ATA-%d",  ata_id_major_version(id));
+
                dev->n_sectors = ata_id_n_sectors(id);
 
                if (ata_id_has_lba(id)) {
@@ -1410,6 +1511,10 @@ int ata_dev_configure(struct ata_device *dev, int print_info)
                        if (ata_id_has_lba48(id)) {
                                dev->flags |= ATA_DFLAG_LBA48;
                                lba_desc = "LBA48";
+
+                               if (dev->n_sectors >= (1UL << 28) &&
+                                   ata_id_has_flush_ext(id))
+                                       dev->flags |= ATA_DFLAG_FLUSH_EXT;
                        }
 
                        /* config NCQ */
@@ -1417,9 +1522,9 @@ int ata_dev_configure(struct ata_device *dev, int print_info)
 
                        /* print device info to dmesg */
                        if (ata_msg_drv(ap) && print_info)
-                               ata_dev_printk(dev, KERN_INFO, "ATA-%d, "
+                               ata_dev_printk(dev, KERN_INFO, "%s, "
                                        "max %s, %Lu sectors: %s %s\n",
-                                       ata_id_major_version(id),
+                                       revbuf,
                                        ata_mode_string(xfer_mask),
                                        (unsigned long long)dev->n_sectors,
                                        lba_desc, ncq_desc);
@@ -1440,9 +1545,9 @@ int ata_dev_configure(struct ata_device *dev, int print_info)
 
                        /* print device info to dmesg */
                        if (ata_msg_drv(ap) && print_info)
-                               ata_dev_printk(dev, KERN_INFO, "ATA-%d, "
+                               ata_dev_printk(dev, KERN_INFO, "%s, "
                                        "max %s, %Lu sectors: CHS %u/%u/%u\n",
-                                       ata_id_major_version(id),
+                                       revbuf,
                                        ata_mode_string(xfer_mask),
                                        (unsigned long long)dev->n_sectors,
                                        dev->cylinders, dev->heads,
@@ -1486,6 +1591,23 @@ int ata_dev_configure(struct ata_device *dev, int print_info)
                                       cdb_intr_string);
        }
 
+       /* determine max_sectors */
+       dev->max_sectors = ATA_MAX_SECTORS;
+       if (dev->flags & ATA_DFLAG_LBA48)
+               dev->max_sectors = ATA_MAX_SECTORS_LBA48;
+
+       if (dev->horkage & ATA_HORKAGE_DIAGNOSTIC) {
+               /* Let the user know. We don't want to disallow opens for
+                  rescue purposes, or in case the vendor is just a blithering
+                  idiot */
+                if (print_info) {
+                       ata_dev_printk(dev, KERN_WARNING,
+"Drive reports diagnostics failure. This may indicate a drive\n");
+                       ata_dev_printk(dev, KERN_WARNING,
+"fault or invalid emulation. Contact drive vendor for information.\n");
+               }
+       }
+
        ata_set_port_max_cmd_len(ap);
 
        /* limit bridge transfers to udma5, 200 sectors */
@@ -1575,11 +1697,14 @@ int ata_bus_probe(struct ata_port *ap)
                if (!ata_dev_enabled(dev))
                        continue;
 
-               rc = ata_dev_read_id(dev, &dev->class, 1, dev->id);
+               rc = ata_dev_read_id(dev, &dev->class, ATA_READID_POSTRESET,
+                                    dev->id);
                if (rc)
                        goto fail;
 
-               rc = ata_dev_configure(dev, 1);
+               ap->eh_context.i.flags |= ATA_EHI_PRINTINFO;
+               rc = ata_dev_configure(dev);
+               ap->eh_context.i.flags &= ~ATA_EHI_PRINTINFO;
                if (rc)
                        goto fail;
        }
@@ -1631,7 +1756,7 @@ int ata_bus_probe(struct ata_port *ap)
  *     Modify @ap data structure such that the system
  *     thinks that the entire port is enabled.
  *
- *     LOCKING: host_set lock, or some other form of
+ *     LOCKING: host lock, or some other form of
  *     serialization.
  */
 
@@ -1769,7 +1894,7 @@ struct ata_device *ata_dev_pair(struct ata_device *adev)
  *     never attempt to probe or communicate with devices
  *     on this port.
  *
- *     LOCKING: host_set lock, or some other form of
+ *     LOCKING: host lock, or some other form of
  *     serialization.
  */
 
@@ -1900,10 +2025,11 @@ int sata_set_spd(struct ata_port *ap)
  * drivers/ide/ide-timing.h and was originally written by Vojtech Pavlik
  */
 /*
- * PIO 0-5, MWDMA 0-2 and UDMA 0-6 timings (in nanoseconds).
+ * PIO 0-4, MWDMA 0-2 and UDMA 0-6 timings (in nanoseconds).
  * These were taken from ATA/ATAPI-6 standard, rev 0a, except
- * for PIO 5, which is a nonstandard extension and UDMA6, which
- * is currently supported only by Maxtor drives.
+ * for UDMA6, which is currently supported only by Maxtor drives.
+ *
+ * For PIO 5/6 MWDMA 3/4 see the CFA specification 3.0.
  */
 
 static const struct ata_timing ata_timing[] = {
@@ -1913,6 +2039,8 @@ static const struct ata_timing ata_timing[] = {
        { XFER_UDMA_4,     0,   0,   0,   0,   0,   0,   0,  30 },
        { XFER_UDMA_3,     0,   0,   0,   0,   0,   0,   0,  45 },
 
+       { XFER_MW_DMA_4,  25,   0,   0,   0,  55,  20,  80,   0 },
+       { XFER_MW_DMA_3,  25,   0,   0,   0,  65,  25, 100,   0 },
        { XFER_UDMA_2,     0,   0,   0,   0,   0,   0,   0,  60 },
        { XFER_UDMA_1,     0,   0,   0,   0,   0,   0,   0,  80 },
        { XFER_UDMA_0,     0,   0,   0,   0,   0,   0,   0, 120 },
@@ -1927,7 +2055,8 @@ static const struct ata_timing ata_timing[] = {
        { XFER_SW_DMA_1,  90,   0,   0,   0, 240, 240, 480,   0 },
        { XFER_SW_DMA_0, 120,   0,   0,   0, 480, 480, 960,   0 },
 
-/*     { XFER_PIO_5,     20,  50,  30, 100,  50,  30, 100,   0 }, */
+       { XFER_PIO_6,     10,  55,  20,  80,  55,  20,  80,   0 },
+       { XFER_PIO_5,     15,  65,  25, 100,  65,  25, 100,   0 },
        { XFER_PIO_4,     25,  70,  25, 120,  70,  25, 120,   0 },
        { XFER_PIO_3,     30,  80,  70, 180,  80,  70, 180,   0 },
 
@@ -2093,6 +2222,7 @@ int ata_down_xfermask_limit(struct ata_device *dev, int force_pio0)
 
 static int ata_dev_set_mode(struct ata_device *dev)
 {
+       struct ata_eh_context *ehc = &dev->ap->eh_context;
        unsigned int err_mask;
        int rc;
 
@@ -2107,7 +2237,9 @@ static int ata_dev_set_mode(struct ata_device *dev)
                return -EIO;
        }
 
+       ehc->i.flags |= ATA_EHI_POST_SETMODE;
        rc = ata_dev_revalidate(dev, 0);
+       ehc->i.flags &= ~ATA_EHI_POST_SETMODE;
        if (rc)
                return rc;
 
@@ -2223,8 +2355,8 @@ int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)
        /* Record simplex status. If we selected DMA then the other
         * host channels are not permitted to do so.
         */
-       if (used_dma && (ap->host_set->flags & ATA_HOST_SIMPLEX))
-               ap->host_set->simplex_claimed = 1;
+       if (used_dma && (ap->host->flags & ATA_HOST_SIMPLEX))
+               ap->host->simplex_claimed = 1;
 
        /* step5: chip specific finalisation */
        if (ap->ops->post_set_mode)
@@ -2246,7 +2378,7 @@ int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)
  *     other threads.
  *
  *     LOCKING:
- *     spin_lock_irqsave(host_set lock)
+ *     spin_lock_irqsave(host lock)
  */
 
 static inline void ata_tf_to_host(struct ata_port *ap,
@@ -2265,11 +2397,14 @@ static inline void ata_tf_to_host(struct ata_port *ap,
  *     Sleep until ATA Status register bit BSY clears,
  *     or a timeout occurs.
  *
- *     LOCKING: None.
+ *     LOCKING:
+ *     Kernel thread context (may sleep).
+ *
+ *     RETURNS:
+ *     0 on success, -errno otherwise.
  */
-
-unsigned int ata_busy_sleep (struct ata_port *ap,
-                            unsigned long tmout_pat, unsigned long tmout)
+int ata_busy_sleep(struct ata_port *ap,
+                  unsigned long tmout_pat, unsigned long tmout)
 {
        unsigned long timer_start, timeout;
        u8 status;
@@ -2277,25 +2412,32 @@ unsigned int ata_busy_sleep (struct ata_port *ap,
        status = ata_busy_wait(ap, ATA_BUSY, 300);
        timer_start = jiffies;
        timeout = timer_start + tmout_pat;
-       while ((status & ATA_BUSY) && (time_before(jiffies, timeout))) {
+       while (status != 0xff && (status & ATA_BUSY) &&
+              time_before(jiffies, timeout)) {
                msleep(50);
                status = ata_busy_wait(ap, ATA_BUSY, 3);
        }
 
-       if (status & ATA_BUSY)
+       if (status != 0xff && (status & ATA_BUSY))
                ata_port_printk(ap, KERN_WARNING,
-                               "port is slow to respond, please be patient\n");
+                               "port is slow to respond, please be patient "
+                               "(Status 0x%x)\n", status);
 
        timeout = timer_start + tmout;
-       while ((status & ATA_BUSY) && (time_before(jiffies, timeout))) {
+       while (status != 0xff && (status & ATA_BUSY) &&
+              time_before(jiffies, timeout)) {
                msleep(50);
                status = ata_chk_status(ap);
        }
 
+       if (status == 0xff)
+               return -ENODEV;
+
        if (status & ATA_BUSY) {
                ata_port_printk(ap, KERN_ERR, "port failed to respond "
-                               "(%lu secs)\n", tmout / HZ);
-               return 1;
+                               "(%lu secs, Status 0x%x)\n",
+                               tmout / HZ, status);
+               return -EBUSY;
        }
 
        return 0;
@@ -2386,10 +2528,8 @@ static unsigned int ata_bus_softreset(struct ata_port *ap,
         * the bus shows 0xFF because the odd clown forgets the D7
         * pulldown resistor.
         */
-       if (ata_check_status(ap) == 0xFF) {
-               ata_port_printk(ap, KERN_ERR, "SRST failed (status 0xFF)\n");
-               return AC_ERR_OTHER;
-       }
+       if (ata_check_status(ap) == 0xFF)
+               return 0;
 
        ata_bus_post_reset(ap, devmask);
 
@@ -2410,7 +2550,7 @@ static unsigned int ata_bus_softreset(struct ata_port *ap,
  *
  *     LOCKING:
  *     PCI/etc. bus probe sem.
- *     Obtains host_set lock.
+ *     Obtains host lock.
  *
  *     SIDE EFFECTS:
  *     Sets ATA_FLAG_DISABLED if bus reset fails.
@@ -2715,9 +2855,9 @@ int ata_std_softreset(struct ata_port *ap, unsigned int *classes)
 }
 
 /**
- *     sata_std_hardreset - reset host port via SATA phy reset
+ *     sata_port_hardreset - reset port via SATA phy reset
  *     @ap: port to reset
- *     @class: resulting class of attached device
+ *     @timing: timing parameters { interval, duratinon, timeout } in msec
  *
  *     SATA phy-reset host port using DET bits of SControl register.
  *
@@ -2727,10 +2867,8 @@ int ata_std_softreset(struct ata_port *ap, unsigned int *classes)
  *     RETURNS:
  *     0 on success, -errno otherwise.
  */
-int sata_std_hardreset(struct ata_port *ap, unsigned int *class)
+int sata_port_hardreset(struct ata_port *ap, const unsigned long *timing)
 {
-       struct ata_eh_context *ehc = &ap->eh_context;
-       const unsigned long *timing = sata_ehc_deb_timing(ehc);
        u32 scontrol;
        int rc;
 
@@ -2743,24 +2881,24 @@ int sata_std_hardreset(struct ata_port *ap, unsigned int *class)
                 * and Sil3124.
                 */
                if ((rc = sata_scr_read(ap, SCR_CONTROL, &scontrol)))
-                       return rc;
+                       goto out;
 
-               scontrol = (scontrol & 0x0f0) | 0x302;
+               scontrol = (scontrol & 0x0f0) | 0x304;
 
                if ((rc = sata_scr_write(ap, SCR_CONTROL, scontrol)))
-                       return rc;
+                       goto out;
 
                sata_set_spd(ap);
        }
 
        /* issue phy wake/reset */
        if ((rc = sata_scr_read(ap, SCR_CONTROL, &scontrol)))
-               return rc;
+               goto out;
 
        scontrol = (scontrol & 0x0f0) | 0x301;
 
        if ((rc = sata_scr_write_flush(ap, SCR_CONTROL, scontrol)))
-               return rc;
+               goto out;
 
        /* Couldn't find anything in SATA I/II specs, but AHCI-1.1
         * 10.4.2 says at least 1 ms.
@@ -2768,7 +2906,40 @@ int sata_std_hardreset(struct ata_port *ap, unsigned int *class)
        msleep(1);
 
        /* bring phy back */
-       sata_phy_resume(ap, timing);
+       rc = sata_phy_resume(ap, timing);
+ out:
+       DPRINTK("EXIT, rc=%d\n", rc);
+       return rc;
+}
+
+/**
+ *     sata_std_hardreset - reset host port via SATA phy reset
+ *     @ap: port to reset
+ *     @class: resulting class of attached device
+ *
+ *     SATA phy-reset host port using DET bits of SControl register,
+ *     wait for !BSY and classify the attached device.
+ *
+ *     LOCKING:
+ *     Kernel thread context (may sleep)
+ *
+ *     RETURNS:
+ *     0 on success, -errno otherwise.
+ */
+int sata_std_hardreset(struct ata_port *ap, unsigned int *class)
+{
+       const unsigned long *timing = sata_ehc_deb_timing(&ap->eh_context);
+       int rc;
+
+       DPRINTK("ENTER\n");
+
+       /* do hardreset */
+       rc = sata_port_hardreset(ap, timing);
+       if (rc) {
+               ata_port_printk(ap, KERN_ERR,
+                               "COMRESET failed (errno=%d)\n", rc);
+               return rc;
+       }
 
        /* TODO: phy layer with polling, timeouts, etc. */
        if (ata_port_offline(ap)) {
@@ -2907,7 +3078,7 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class,
 /**
  *     ata_dev_revalidate - Revalidate ATA device
  *     @dev: device to revalidate
- *     @post_reset: is this revalidation after reset?
+ *     @readid_flags: read ID flags
  *
  *     Re-read IDENTIFY page and make sure @dev is still attached to
  *     the port.
@@ -2918,7 +3089,7 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class,
  *     RETURNS:
  *     0 on success, negative errno otherwise
  */
-int ata_dev_revalidate(struct ata_device *dev, int post_reset)
+int ata_dev_revalidate(struct ata_device *dev, unsigned int readid_flags)
 {
        unsigned int class = dev->class;
        u16 *id = (void *)dev->ap->sector_buf;
@@ -2930,7 +3101,7 @@ int ata_dev_revalidate(struct ata_device *dev, int post_reset)
        }
 
        /* read ID data */
-       rc = ata_dev_read_id(dev, &class, post_reset, id);
+       rc = ata_dev_read_id(dev, &class, readid_flags, id);
        if (rc)
                goto fail;
 
@@ -2943,7 +3114,7 @@ int ata_dev_revalidate(struct ata_device *dev, int post_reset)
        memcpy(dev->id, id, sizeof(id[0]) * ATA_ID_WORDS);
 
        /* configure device according to the new ID */
-       rc = ata_dev_configure(dev, 0);
+       rc = ata_dev_configure(dev);
        if (rc == 0)
                return 0;
 
@@ -2952,37 +3123,55 @@ int ata_dev_revalidate(struct ata_device *dev, int post_reset)
        return rc;
 }
 
-static const char * const ata_dma_blacklist [] = {
-       "WDC AC11000H", NULL,
-       "WDC AC22100H", NULL,
-       "WDC AC32500H", NULL,
-       "WDC AC33100H", NULL,
-       "WDC AC31600H", NULL,
-       "WDC AC32100H", "24.09P07",
-       "WDC AC23200L", "21.10N21",
-       "Compaq CRD-8241B",  NULL,
-       "CRD-8400B", NULL,
-       "CRD-8480B", NULL,
-       "CRD-8482B", NULL,
-       "CRD-84", NULL,
-       "SanDisk SDP3B", NULL,
-       "SanDisk SDP3B-64", NULL,
-       "SANYO CD-ROM CRD", NULL,
-       "HITACHI CDR-8", NULL,
-       "HITACHI CDR-8335", NULL,
-       "HITACHI CDR-8435", NULL,
-       "Toshiba CD-ROM XM-6202B", NULL,
-       "TOSHIBA CD-ROM XM-1702BC", NULL,
-       "CD-532E-A", NULL,
-       "E-IDE CD-ROM CR-840", NULL,
-       "CD-ROM Drive/F5A", NULL,
-       "WPI CDD-820", NULL,
-       "SAMSUNG CD-ROM SC-148C", NULL,
-       "SAMSUNG CD-ROM SC", NULL,
-       "SanDisk SDP3B-64", NULL,
-       "ATAPI CD-ROM DRIVE 40X MAXIMUM",NULL,
-       "_NEC DV5800A", NULL,
-       "SAMSUNG CD-ROM SN-124", "N001"
+struct ata_blacklist_entry {
+       const char *model_num;
+       const char *model_rev;
+       unsigned long horkage;
+};
+
+static const struct ata_blacklist_entry ata_device_blacklist [] = {
+       /* Devices with DMA related problems under Linux */
+       { "WDC AC11000H",       NULL,           ATA_HORKAGE_NODMA },
+       { "WDC AC22100H",       NULL,           ATA_HORKAGE_NODMA },
+       { "WDC AC32500H",       NULL,           ATA_HORKAGE_NODMA },
+       { "WDC AC33100H",       NULL,           ATA_HORKAGE_NODMA },
+       { "WDC AC31600H",       NULL,           ATA_HORKAGE_NODMA },
+       { "WDC AC32100H",       "24.09P07",     ATA_HORKAGE_NODMA },
+       { "WDC AC23200L",       "21.10N21",     ATA_HORKAGE_NODMA },
+       { "Compaq CRD-8241B",   NULL,           ATA_HORKAGE_NODMA },
+       { "CRD-8400B",          NULL,           ATA_HORKAGE_NODMA },
+       { "CRD-8480B",          NULL,           ATA_HORKAGE_NODMA },
+       { "CRD-8482B",          NULL,           ATA_HORKAGE_NODMA },
+       { "CRD-84",             NULL,           ATA_HORKAGE_NODMA },
+       { "SanDisk SDP3B",      NULL,           ATA_HORKAGE_NODMA },
+       { "SanDisk SDP3B-64",   NULL,           ATA_HORKAGE_NODMA },
+       { "SANYO CD-ROM CRD",   NULL,           ATA_HORKAGE_NODMA },
+       { "HITACHI CDR-8",      NULL,           ATA_HORKAGE_NODMA },
+       { "HITACHI CDR-8335",   NULL,           ATA_HORKAGE_NODMA },
+       { "HITACHI CDR-8435",   NULL,           ATA_HORKAGE_NODMA },
+       { "Toshiba CD-ROM XM-6202B", NULL,      ATA_HORKAGE_NODMA },
+       { "TOSHIBA CD-ROM XM-1702BC", NULL,     ATA_HORKAGE_NODMA },
+       { "CD-532E-A",          NULL,           ATA_HORKAGE_NODMA },
+       { "E-IDE CD-ROM CR-840",NULL,           ATA_HORKAGE_NODMA },
+       { "CD-ROM Drive/F5A",   NULL,           ATA_HORKAGE_NODMA },
+       { "WPI CDD-820",        NULL,           ATA_HORKAGE_NODMA },
+       { "SAMSUNG CD-ROM SC-148C", NULL,       ATA_HORKAGE_NODMA },
+       { "SAMSUNG CD-ROM SC",  NULL,           ATA_HORKAGE_NODMA },
+       { "SanDisk SDP3B-64",   NULL,           ATA_HORKAGE_NODMA },
+       { "ATAPI CD-ROM DRIVE 40X MAXIMUM",NULL,ATA_HORKAGE_NODMA },
+       { "_NEC DV5800A",       NULL,           ATA_HORKAGE_NODMA },
+       { "SAMSUNG CD-ROM SN-124","N001",       ATA_HORKAGE_NODMA },
+
+       /* Devices we expect to fail diagnostics */
+
+       /* Devices where NCQ should be avoided */
+       /* NCQ is slow */
+        { "WDC WD740ADFD-00",   NULL,          ATA_HORKAGE_NONCQ },
+
+       /* Devices with NCQ limits */
+
+       /* End Marker */
+       { }
 };
 
 static int ata_strim(char *s, size_t len)
@@ -2997,20 +3186,12 @@ static int ata_strim(char *s, size_t len)
        return len;
 }
 
-static int ata_dma_blacklisted(const struct ata_device *dev)
+unsigned long ata_device_blacklisted(const struct ata_device *dev)
 {
        unsigned char model_num[40];
        unsigned char model_rev[16];
        unsigned int nlen, rlen;
-       int i;
-
-       /* We don't support polling DMA.
-        * DMA blacklist those ATAPI devices with CDB-intr (and use PIO)
-        * if the LLDD handles only interrupts in the HSM_ST_LAST state.
-        */
-       if ((dev->ap->flags & ATA_FLAG_PIO_POLLING) &&
-           (dev->flags & ATA_DFLAG_CDB_INTR))
-               return 1;
+       const struct ata_blacklist_entry *ad = ata_device_blacklist;
 
        ata_id_string(dev->id, model_num, ATA_ID_PROD_OFS,
                          sizeof(model_num));
@@ -3019,17 +3200,30 @@ static int ata_dma_blacklisted(const struct ata_device *dev)
        nlen = ata_strim(model_num, sizeof(model_num));
        rlen = ata_strim(model_rev, sizeof(model_rev));
 
-       for (i = 0; i < ARRAY_SIZE(ata_dma_blacklist); i += 2) {
-               if (!strncmp(ata_dma_blacklist[i], model_num, nlen)) {
-                       if (ata_dma_blacklist[i+1] == NULL)
-                               return 1;
-                       if (!strncmp(ata_dma_blacklist[i], model_rev, rlen))
-                               return 1;
+       while (ad->model_num) {
+               if (!strncmp(ad->model_num, model_num, nlen)) {
+                       if (ad->model_rev == NULL)
+                               return ad->horkage;
+                       if (!strncmp(ad->model_rev, model_rev, rlen))
+                               return ad->horkage;
                }
+               ad++;
        }
        return 0;
 }
 
+static int ata_dma_blacklisted(const struct ata_device *dev)
+{
+       /* We don't support polling DMA.
+        * DMA blacklist those ATAPI devices with CDB-intr (and use PIO)
+        * if the LLDD handles only interrupts in the HSM_ST_LAST state.
+        */
+       if ((dev->ap->flags & ATA_FLAG_PIO_POLLING) &&
+           (dev->flags & ATA_DFLAG_CDB_INTR))
+               return 1;
+       return (ata_device_blacklisted(dev) & ATA_HORKAGE_NODMA) ? 1 : 0;
+}
+
 /**
  *     ata_dev_xfermask - Compute supported xfermask of the given device
  *     @dev: Device to compute xfermask for
@@ -3045,7 +3239,7 @@ static int ata_dma_blacklisted(const struct ata_device *dev)
 static void ata_dev_xfermask(struct ata_device *dev)
 {
        struct ata_port *ap = dev->ap;
-       struct ata_host_set *hs = ap->host_set;
+       struct ata_host *host = ap->host;
        unsigned long xfer_mask;
 
        /* controller modes available */
@@ -3057,18 +3251,36 @@ static void ata_dev_xfermask(struct ata_device *dev)
         */
        if (ap->cbl == ATA_CBL_PATA40)
                xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA);
+       /* Apply drive side cable rule. Unknown or 80 pin cables reported
+        * host side are checked drive side as well. Cases where we know a
+        * 40wire cable is used safely for 80 are not checked here.
+        */
+        if (ata_drive_40wire(dev->id) && (ap->cbl == ATA_CBL_PATA_UNK || ap->cbl == ATA_CBL_PATA80))
+               xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA);
+
 
        xfer_mask &= ata_pack_xfermask(dev->pio_mask,
                                       dev->mwdma_mask, dev->udma_mask);
        xfer_mask &= ata_id_xfermask(dev->id);
 
+       /*
+        *      CFA Advanced TrueIDE timings are not allowed on a shared
+        *      cable
+        */
+       if (ata_dev_pair(dev)) {
+               /* No PIO5 or PIO6 */
+               xfer_mask &= ~(0x03 << (ATA_SHIFT_PIO + 5));
+               /* No MWDMA3 or MWDMA 4 */
+               xfer_mask &= ~(0x03 << (ATA_SHIFT_MWDMA + 3));
+       }
+
        if (ata_dma_blacklisted(dev)) {
                xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
                ata_dev_printk(dev, KERN_WARNING,
                               "device is on DMA blacklist, disabling DMA\n");
        }
 
-       if ((hs->flags & ATA_HOST_SIMPLEX) && hs->simplex_claimed) {
+       if ((host->flags & ATA_HOST_SIMPLEX) && host->simplex_claimed) {
                xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
                ata_dev_printk(dev, KERN_WARNING, "simplex DMA is claimed by "
                               "other device, disabling DMA\n");
@@ -3161,7 +3373,7 @@ static unsigned int ata_dev_init_params(struct ata_device *dev,
  *     Unmap all mapped DMA memory associated with this command.
  *
  *     LOCKING:
- *     spin_lock_irqsave(host_set lock)
+ *     spin_lock_irqsave(host lock)
  */
 
 static void ata_sg_clean(struct ata_queued_cmd *qc)
@@ -3221,7 +3433,7 @@ static void ata_sg_clean(struct ata_queued_cmd *qc)
  *     associated with the current disk command.
  *
  *     LOCKING:
- *     spin_lock_irqsave(host_set lock)
+ *     spin_lock_irqsave(host lock)
  *
  */
 static void ata_fill_sg(struct ata_queued_cmd *qc)
@@ -3273,7 +3485,7 @@ static void ata_fill_sg(struct ata_queued_cmd *qc)
  *     supplied PACKET command.
  *
  *     LOCKING:
- *     spin_lock_irqsave(host_set lock)
+ *     spin_lock_irqsave(host lock)
  *
  *     RETURNS: 0 when ATAPI DMA can be used
  *               nonzero otherwise
@@ -3295,7 +3507,7 @@ int ata_check_atapi_dma(struct ata_queued_cmd *qc)
  *     Prepare ATA taskfile for submission.
  *
  *     LOCKING:
- *     spin_lock_irqsave(host_set lock)
+ *     spin_lock_irqsave(host lock)
  */
 void ata_qc_prep(struct ata_queued_cmd *qc)
 {
@@ -3317,24 +3529,20 @@ void ata_noop_qc_prep(struct ata_queued_cmd *qc) { }
  *     to point to a single memory buffer, @buf of byte length @buflen.
  *
  *     LOCKING:
- *     spin_lock_irqsave(host_set lock)
+ *     spin_lock_irqsave(host lock)
  */
 
 void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen)
 {
-       struct scatterlist *sg;
-
        qc->flags |= ATA_QCFLAG_SINGLE;
 
-       memset(&qc->sgent, 0, sizeof(qc->sgent));
        qc->__sg = &qc->sgent;
        qc->n_elem = 1;
        qc->orig_n_elem = 1;
        qc->buf_virt = buf;
        qc->nbytes = buflen;
 
-       sg = qc->__sg;
-       sg_init_one(sg, buf, buflen);
+       sg_init_one(&qc->sgent, buf, buflen);
 }
 
 /**
@@ -3348,7 +3556,7 @@ void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen)
  *     elements.
  *
  *     LOCKING:
- *     spin_lock_irqsave(host_set lock)
+ *     spin_lock_irqsave(host lock)
  */
 
 void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
@@ -3367,7 +3575,7 @@ void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
  *     DMA-map the memory buffer associated with queued_cmd @qc.
  *
  *     LOCKING:
- *     spin_lock_irqsave(host_set lock)
+ *     spin_lock_irqsave(host lock)
  *
  *     RETURNS:
  *     Zero on success, negative on error.
@@ -3436,7 +3644,7 @@ skip_map:
  *     DMA-map the scatter-gather table associated with queued_cmd @qc.
  *
  *     LOCKING:
- *     spin_lock_irqsave(host_set lock)
+ *     spin_lock_irqsave(host lock)
  *
  *     RETURNS:
  *     Zero on success, negative on error.
@@ -3945,7 +4153,7 @@ static inline int ata_hsm_ok_in_wq(struct ata_port *ap, struct ata_queued_cmd *q
  *     Finish @qc which is running on standard HSM.
  *
  *     LOCKING:
- *     If @in_wq is zero, spin_lock_irqsave(host_set lock).
+ *     If @in_wq is zero, spin_lock_irqsave(host lock).
  *     Otherwise, none on entry and grabs host lock.
  */
 static void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq)
@@ -3957,8 +4165,8 @@ static void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq)
                if (in_wq) {
                        spin_lock_irqsave(ap->lock, flags);
 
-                       /* EH might have kicked in while host_set lock
-                        * is released.
+                       /* EH might have kicked in while host lock is
+                        * released.
                         */
                        qc = ata_qc_from_tag(ap, qc->tag);
                        if (qc) {
@@ -4127,8 +4335,12 @@ fsm_start:
                                        /* device stops HSM for abort/error */
                                        qc->err_mask |= AC_ERR_DEV;
                                else
-                                       /* HSM violation. Let EH handle this */
-                                       qc->err_mask |= AC_ERR_HSM;
+                                       /* HSM violation. Let EH handle this.
+                                        * Phantom devices also trigger this
+                                        * condition.  Mark hint.
+                                        */
+                                       qc->err_mask |= AC_ERR_HSM |
+                                                       AC_ERR_NODEV_HINT;
 
                                ap->hsm_task_state = HSM_ST_ERR;
                                goto fsm_start;
@@ -4323,7 +4535,7 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev)
  *     in case something prevents using it.
  *
  *     LOCKING:
- *     spin_lock_irqsave(host_set lock)
+ *     spin_lock_irqsave(host lock)
  */
 void ata_qc_free(struct ata_queued_cmd *qc)
 {
@@ -4367,6 +4579,14 @@ void __ata_qc_complete(struct ata_queued_cmd *qc)
        qc->complete_fn(qc);
 }
 
+static void fill_result_tf(struct ata_queued_cmd *qc)
+{
+       struct ata_port *ap = qc->ap;
+
+       ap->ops->tf_read(ap, &qc->result_tf);
+       qc->result_tf.flags = qc->tf.flags;
+}
+
 /**
  *     ata_qc_complete - Complete an active ATA command
  *     @qc: Command to complete
@@ -4376,7 +4596,7 @@ void __ata_qc_complete(struct ata_queued_cmd *qc)
  *     command has completed, with either an ok or not-ok status.
  *
  *     LOCKING:
- *     spin_lock_irqsave(host_set lock)
+ *     spin_lock_irqsave(host lock)
  */
 void ata_qc_complete(struct ata_queued_cmd *qc)
 {
@@ -4404,7 +4624,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
                if (unlikely(qc->flags & ATA_QCFLAG_FAILED)) {
                        if (!ata_tag_internal(qc->tag)) {
                                /* always fill result TF for failed qc */
-                               ap->ops->tf_read(ap, &qc->result_tf);
+                               fill_result_tf(qc);
                                ata_qc_schedule_eh(qc);
                                return;
                        }
@@ -4412,7 +4632,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
 
                /* read result TF if requested */
                if (qc->flags & ATA_QCFLAG_RESULT_TF)
-                       ap->ops->tf_read(ap, &qc->result_tf);
+                       fill_result_tf(qc);
 
                __ata_qc_complete(qc);
        } else {
@@ -4421,7 +4641,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
 
                /* read result TF if failed or requested */
                if (qc->err_mask || qc->flags & ATA_QCFLAG_RESULT_TF)
-                       ap->ops->tf_read(ap, &qc->result_tf);
+                       fill_result_tf(qc);
 
                __ata_qc_complete(qc);
        }
@@ -4439,7 +4659,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
  *     and commands are completed accordingly.
  *
  *     LOCKING:
- *     spin_lock_irqsave(host_set lock)
+ *     spin_lock_irqsave(host lock)
  *
  *     RETURNS:
  *     Number of completed commands on success, -errno otherwise.
@@ -4510,7 +4730,7 @@ static inline int ata_should_dma_map(struct ata_queued_cmd *qc)
  *     writing the taskfile to hardware, starting the command.
  *
  *     LOCKING:
- *     spin_lock_irqsave(host_set lock)
+ *     spin_lock_irqsave(host lock)
  */
 void ata_qc_issue(struct ata_queued_cmd *qc)
 {
@@ -4571,7 +4791,7 @@ err:
  *     May be used as the qc_issue() entry in ata_port_operations.
  *
  *     LOCKING:
- *     spin_lock_irqsave(host_set lock)
+ *     spin_lock_irqsave(host lock)
  *
  *     RETURNS:
  *     Zero on success, AC_ERR_* mask on failure
@@ -4700,7 +4920,7 @@ unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc)
  *     handled via polling with interrupts disabled (nIEN bit).
  *
  *     LOCKING:
- *     spin_lock_irqsave(host_set lock)
+ *     spin_lock_irqsave(host lock)
  *
  *     RETURNS:
  *     One if interrupt was handled, zero if not (shared irq).
@@ -4787,33 +5007,32 @@ idle_irq:
 /**
  *     ata_interrupt - Default ATA host interrupt handler
  *     @irq: irq line (unused)
- *     @dev_instance: pointer to our ata_host_set information structure
- *     @regs: unused
+ *     @dev_instance: pointer to our ata_host information structure
  *
  *     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.
+ *     Obtains host lock during operation.
  *
  *     RETURNS:
  *     IRQ_NONE or IRQ_HANDLED.
  */
 
-irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
+irqreturn_t ata_interrupt (int irq, void *dev_instance)
 {
-       struct ata_host_set *host_set = dev_instance;
+       struct ata_host *host = dev_instance;
        unsigned int i;
        unsigned int handled = 0;
        unsigned long flags;
 
        /* TODO: make _irqsave conditional on x86 PCI IDE legacy mode */
-       spin_lock_irqsave(&host_set->lock, flags);
+       spin_lock_irqsave(&host->lock, flags);
 
-       for (i = 0; i < host_set->n_ports; i++) {
+       for (i = 0; i < host->n_ports; i++) {
                struct ata_port *ap;
 
-               ap = host_set->ports[i];
+               ap = host->ports[i];
                if (ap &&
                    !(ap->flags & ATA_FLAG_DISABLED)) {
                        struct ata_queued_cmd *qc;
@@ -4825,7 +5044,7 @@ irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
                }
        }
 
-       spin_unlock_irqrestore(&host_set->lock, flags);
+       spin_unlock_irqrestore(&host->lock, flags);
 
        return IRQ_RETVAL(handled);
 }
@@ -4976,7 +5195,7 @@ int ata_flush_cache(struct ata_device *dev)
        if (!ata_try_flush_cache(dev))
                return 0;
 
-       if (ata_id_has_flush_ext(dev->id))
+       if (dev->flags & ATA_DFLAG_FLUSH_EXT)
                cmd = ATA_CMD_FLUSH_EXT;
        else
                cmd = ATA_CMD_FLUSH;
@@ -4990,15 +5209,15 @@ int ata_flush_cache(struct ata_device *dev)
        return 0;
 }
 
-static int ata_host_set_request_pm(struct ata_host_set *host_set,
-                                  pm_message_t mesg, unsigned int action,
-                                  unsigned int ehi_flags, int wait)
+static int ata_host_request_pm(struct ata_host *host, pm_message_t mesg,
+                              unsigned int action, unsigned int ehi_flags,
+                              int wait)
 {
        unsigned long flags;
        int i, rc;
 
-       for (i = 0; i < host_set->n_ports; i++) {
-               struct ata_port *ap = host_set->ports[i];
+       for (i = 0; i < host->n_ports; i++) {
+               struct ata_port *ap = host->ports[i];
 
                /* Previous resume operation might still be in
                 * progress.  Wait for PM_PENDING to clear.
@@ -5038,11 +5257,11 @@ static int ata_host_set_request_pm(struct ata_host_set *host_set,
 }
 
 /**
- *     ata_host_set_suspend - suspend host_set
- *     @host_set: host_set to suspend
+ *     ata_host_suspend - suspend host
+ *     @host: host to suspend
  *     @mesg: PM message
  *
- *     Suspend @host_set.  Actual operation is performed by EH.  This
+ *     Suspend @host.  Actual operation is performed by EH.  This
  *     function requests EH to perform PM operations and waits for EH
  *     to finish.
  *
@@ -5052,11 +5271,11 @@ static int ata_host_set_request_pm(struct ata_host_set *host_set,
  *     RETURNS:
  *     0 on success, -errno on failure.
  */
-int ata_host_set_suspend(struct ata_host_set *host_set, pm_message_t mesg)
+int ata_host_suspend(struct ata_host *host, pm_message_t mesg)
 {
        int i, j, rc;
 
-       rc = ata_host_set_request_pm(host_set, mesg, 0, ATA_EHI_QUIET, 1);
+       rc = ata_host_request_pm(host, mesg, 0, ATA_EHI_QUIET, 1);
        if (rc)
                goto fail;
 
@@ -5064,8 +5283,8 @@ int ata_host_set_suspend(struct ata_host_set *host_set, pm_message_t mesg)
         * This happens if hotplug occurs between completion of device
         * suspension and here.
         */
-       for (i = 0; i < host_set->n_ports; i++) {
-               struct ata_port *ap = host_set->ports[i];
+       for (i = 0; i < host->n_ports; i++) {
+               struct ata_port *ap = host->ports[i];
 
                for (j = 0; j < ATA_MAX_DEVICES; j++) {
                        struct ata_device *dev = &ap->device[j];
@@ -5080,30 +5299,30 @@ int ata_host_set_suspend(struct ata_host_set *host_set, pm_message_t mesg)
                }
        }
 
-       host_set->dev->power.power_state = mesg;
+       host->dev->power.power_state = mesg;
        return 0;
 
  fail:
-       ata_host_set_resume(host_set);
+       ata_host_resume(host);
        return rc;
 }
 
 /**
- *     ata_host_set_resume - resume host_set
- *     @host_set: host_set to resume
+ *     ata_host_resume - resume host
+ *     @host: host to resume
  *
- *     Resume @host_set.  Actual operation is performed by EH.  This
+ *     Resume @host.  Actual operation is performed by EH.  This
  *     function requests EH to perform PM operations and returns.
  *     Note that all resume operations are performed parallely.
  *
  *     LOCKING:
  *     Kernel thread context (may sleep).
  */
-void ata_host_set_resume(struct ata_host_set *host_set)
+void ata_host_resume(struct ata_host *host)
 {
-       ata_host_set_request_pm(host_set, PMSG_ON, ATA_EH_SOFTRESET,
-                               ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET, 0);
-       host_set->dev->power.power_state = PMSG_ON;
+       ata_host_request_pm(host, PMSG_ON, ATA_EH_SOFTRESET,
+                           ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET, 0);
+       host->dev->power.power_state = PMSG_ON;
 }
 
 /**
@@ -5160,10 +5379,10 @@ void ata_port_stop (struct ata_port *ap)
        ata_pad_free(ap, dev);
 }
 
-void ata_host_stop (struct ata_host_set *host_set)
+void ata_host_stop (struct ata_host *host)
 {
-       if (host_set->mmio_base)
-               iounmap(host_set->mmio_base);
+       if (host->mmio_base)
+               iounmap(host->mmio_base);
 }
 
 /**
@@ -5185,7 +5404,7 @@ void ata_dev_init(struct ata_device *dev)
 
        /* High bits of dev->flags are used to record warm plug
         * requests which occur asynchronously.  Synchronize using
-        * host_set lock.
+        * host lock.
         */
        spin_lock_irqsave(ap->lock, flags);
        dev->flags &= ~ATA_DFLAG_INIT_MASK;
@@ -5201,7 +5420,7 @@ void ata_dev_init(struct ata_device *dev)
 /**
  *     ata_port_init - Initialize an ata_port structure
  *     @ap: Structure to initialize
- *     @host_set: Collection of hosts to which @ap belongs
+ *     @host: Collection of hosts to which @ap belongs
  *     @ent: Probe information provided by low-level driver
  *     @port_no: Port number associated with this ata_port
  *
@@ -5210,23 +5429,31 @@ void ata_dev_init(struct ata_device *dev)
  *     LOCKING:
  *     Inherited from caller.
  */
-void ata_port_init(struct ata_port *ap, struct ata_host_set *host_set,
+void ata_port_init(struct ata_port *ap, struct ata_host *host,
                   const struct ata_probe_ent *ent, unsigned int port_no)
 {
        unsigned int i;
 
-       ap->lock = &host_set->lock;
+       ap->lock = &host->lock;
        ap->flags = ATA_FLAG_DISABLED;
        ap->id = ata_unique_id++;
        ap->ctl = ATA_DEVCTL_OBS;
-       ap->host_set = host_set;
+       ap->host = host;
        ap->dev = ent->dev;
        ap->port_no = port_no;
-       ap->pio_mask = ent->pio_mask;
-       ap->mwdma_mask = ent->mwdma_mask;
-       ap->udma_mask = ent->udma_mask;
-       ap->flags |= ent->host_flags;
-       ap->ops = ent->port_ops;
+       if (port_no == 1 && ent->pinfo2) {
+               ap->pio_mask = ent->pinfo2->pio_mask;
+               ap->mwdma_mask = ent->pinfo2->mwdma_mask;
+               ap->udma_mask = ent->pinfo2->udma_mask;
+               ap->flags |= ent->pinfo2->flags;
+               ap->ops = ent->pinfo2->port_ops;
+       } else {
+               ap->pio_mask = ent->pio_mask;
+               ap->mwdma_mask = ent->mwdma_mask;
+               ap->udma_mask = ent->udma_mask;
+               ap->flags |= ent->port_flags;
+               ap->ops = ent->port_ops;
+       }
        ap->hw_sata_spd_limit = UINT_MAX;
        ap->active_tag = ATA_TAG_POISON;
        ap->last_ctl = 0xFF;
@@ -5278,7 +5505,7 @@ void ata_port_init(struct ata_port *ap, struct ata_host_set *host_set,
  */
 static void ata_port_init_shost(struct ata_port *ap, struct Scsi_Host *shost)
 {
-       ap->host = shost;
+       ap->scsi_host = shost;
 
        shost->unique_id = ap->id;
        shost->max_id = 16;
@@ -5290,7 +5517,7 @@ static void ata_port_init_shost(struct ata_port *ap, struct Scsi_Host *shost)
 /**
  *     ata_port_add - Attach low-level ATA driver to system
  *     @ent: Information provided by low-level driver
- *     @host_set: Collections of ports to which we add
+ *     @host: Collections of ports to which we add
  *     @port_no: Port number associated with this host
  *
  *     Attach low-level ATA driver to system.
@@ -5302,7 +5529,7 @@ static void ata_port_init_shost(struct ata_port *ap, struct Scsi_Host *shost)
  *     New ata_port on success, for NULL on error.
  */
 static struct ata_port * ata_port_add(const struct ata_probe_ent *ent,
-                                     struct ata_host_set *host_set,
+                                     struct ata_host *host,
                                      unsigned int port_no)
 {
        struct Scsi_Host *shost;
@@ -5311,7 +5538,7 @@ static struct ata_port * ata_port_add(const struct ata_probe_ent *ent,
        DPRINTK("ENTER\n");
 
        if (!ent->port_ops->error_handler &&
-           !(ent->host_flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST))) {
+           !(ent->port_flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST))) {
                printk(KERN_ERR "ata%u: no reset mechanism available\n",
                       port_no);
                return NULL;
@@ -5325,32 +5552,31 @@ static struct ata_port * ata_port_add(const struct ata_probe_ent *ent,
 
        ap = ata_shost_to_port(shost);
 
-       ata_port_init(ap, host_set, ent, port_no);
+       ata_port_init(ap, host, ent, port_no);
        ata_port_init_shost(ap, shost);
 
        return ap;
 }
 
 /**
- *     ata_sas_host_init - Initialize a host_set struct
- *     @host_set:      host_set to initialize
- *     @dev:           device host_set is attached to
- *     @flags: host_set flags
- *     @ops:           port_ops
+ *     ata_sas_host_init - Initialize a host struct
+ *     @host:  host to initialize
+ *     @dev:   device host is attached to
+ *     @flags: host flags
+ *     @ops:   port_ops
  *
  *     LOCKING:
  *     PCI/etc. bus probe sem.
  *
  */
 
-void ata_host_set_init(struct ata_host_set *host_set,
-                      struct device *dev, unsigned long flags,
-                      const struct ata_port_operations *ops)
+void ata_host_init(struct ata_host *host, struct device *dev,
+                  unsigned long flags, const struct ata_port_operations *ops)
 {
-       spin_lock_init(&host_set->lock);
-       host_set->dev = dev;
-       host_set->flags = flags;
-       host_set->ops = ops;
+       spin_lock_init(&host->lock);
+       host->dev = dev;
+       host->flags = flags;
+       host->ops = ops;
 }
 
 /**
@@ -5375,35 +5601,39 @@ int ata_device_add(const struct ata_probe_ent *ent)
 {
        unsigned int i;
        struct device *dev = ent->dev;
-       struct ata_host_set *host_set;
+       struct ata_host *host;
        int rc;
 
        DPRINTK("ENTER\n");
+       
+       if (ent->irq == 0) {
+               dev_printk(KERN_ERR, dev, "is not available: No interrupt assigned.\n");
+               return 0;
+       }
        /* alloc a container for our list of ATA ports (buses) */
-       host_set = kzalloc(sizeof(struct ata_host_set) +
-                          (ent->n_ports * sizeof(void *)), GFP_KERNEL);
-       if (!host_set)
+       host = kzalloc(sizeof(struct ata_host) +
+                      (ent->n_ports * sizeof(void *)), GFP_KERNEL);
+       if (!host)
                return 0;
 
-       ata_host_set_init(host_set, dev, ent->host_set_flags, ent->port_ops);
-       host_set->n_ports = ent->n_ports;
-       host_set->irq = ent->irq;
-       host_set->irq2 = ent->irq2;
-       host_set->mmio_base = ent->mmio_base;
-       host_set->private_data = ent->private_data;
+       ata_host_init(host, dev, ent->_host_flags, ent->port_ops);
+       host->n_ports = ent->n_ports;
+       host->irq = ent->irq;
+       host->irq2 = ent->irq2;
+       host->mmio_base = ent->mmio_base;
+       host->private_data = ent->private_data;
 
        /* register each port bound to this device */
-       for (i = 0; i < host_set->n_ports; i++) {
+       for (i = 0; i < host->n_ports; i++) {
                struct ata_port *ap;
                unsigned long xfer_mode_mask;
                int irq_line = ent->irq;
 
-               ap = ata_port_add(ent, host_set, i);
+               ap = ata_port_add(ent, host, i);
+               host->ports[i] = ap;
                if (!ap)
                        goto err_out;
 
-               host_set->ports[i] = ap;
-
                /* dummy? */
                if (ent->dummy_port_mask & (1 << i)) {
                        ata_port_printk(ap, KERN_INFO, "DUMMY\n");
@@ -5414,8 +5644,8 @@ int ata_device_add(const struct ata_probe_ent *ent)
                /* start port */
                rc = ap->ops->port_start(ap);
                if (rc) {
-                       host_set->ports[i] = NULL;
-                       scsi_host_put(ap->host);
+                       host->ports[i] = NULL;
+                       scsi_host_put(ap->scsi_host);
                        goto err_out;
                }
 
@@ -5438,13 +5668,13 @@ int ata_device_add(const struct ata_probe_ent *ent)
                                irq_line);
 
                ata_chk_status(ap);
-               host_set->ops->irq_clear(ap);
+               host->ops->irq_clear(ap);
                ata_eh_freeze_port(ap); /* freeze port before requesting IRQ */
        }
 
        /* obtain irq, that may be shared between channels */
        rc = request_irq(ent->irq, ent->port_ops->irq_handler, ent->irq_flags,
-                        DRV_NAME, host_set);
+                        DRV_NAME, host);
        if (rc) {
                dev_printk(KERN_ERR, dev, "irq %lu request failed: %d\n",
                           ent->irq, rc);
@@ -5458,7 +5688,7 @@ int ata_device_add(const struct ata_probe_ent *ent)
                BUG_ON(ent->irq == ent->irq2);
 
                rc = request_irq(ent->irq2, ent->port_ops->irq_handler, ent->irq_flags,
-                        DRV_NAME, host_set);
+                        DRV_NAME, host);
                if (rc) {
                        dev_printk(KERN_ERR, dev, "irq %lu request failed: %d\n",
                                   ent->irq2, rc);
@@ -5468,8 +5698,8 @@ int ata_device_add(const struct ata_probe_ent *ent)
 
        /* perform each probe synchronously */
        DPRINTK("probe begin\n");
-       for (i = 0; i < host_set->n_ports; i++) {
-               struct ata_port *ap = host_set->ports[i];
+       for (i = 0; i < host->n_ports; i++) {
+               struct ata_port *ap = host->ports[i];
                u32 scontrol;
                int rc;
 
@@ -5480,7 +5710,7 @@ int ata_device_add(const struct ata_probe_ent *ent)
                }
                ap->sata_spd_limit = ap->hw_sata_spd_limit;
 
-               rc = scsi_add_host(ap->host, dev);
+               rc = scsi_add_host(ap->scsi_host, dev);
                if (rc) {
                        ata_port_printk(ap, KERN_ERR, "scsi_add_host failed\n");
                        /* FIXME: do something useful here */
@@ -5528,29 +5758,29 @@ int ata_device_add(const struct ata_probe_ent *ent)
 
        /* probes are done, now scan each port's disk(s) */
        DPRINTK("host probe begin\n");
-       for (i = 0; i < host_set->n_ports; i++) {
-               struct ata_port *ap = host_set->ports[i];
+       for (i = 0; i < host->n_ports; i++) {
+               struct ata_port *ap = host->ports[i];
 
                ata_scsi_scan_host(ap);
        }
 
-       dev_set_drvdata(dev, host_set);
+       dev_set_drvdata(dev, host);
 
        VPRINTK("EXIT, returning %u\n", ent->n_ports);
        return ent->n_ports; /* success */
 
 err_out_free_irq:
-       free_irq(ent->irq, host_set);
+       free_irq(ent->irq, host);
 err_out:
-       for (i = 0; i < host_set->n_ports; i++) {
-               struct ata_port *ap = host_set->ports[i];
+       for (i = 0; i < host->n_ports; i++) {
+               struct ata_port *ap = host->ports[i];
                if (ap) {
                        ap->ops->port_stop(ap);
-                       scsi_host_put(ap->host);
+                       scsi_host_put(ap->scsi_host);
                }
        }
 
-       kfree(host_set);
+       kfree(host);
        VPRINTK("EXIT, returning 0\n");
        return 0;
 }
@@ -5610,12 +5840,12 @@ void ata_port_detach(struct ata_port *ap)
 
  skip_eh:
        /* remove the associated SCSI host */
-       scsi_remove_host(ap->host);
+       scsi_remove_host(ap->scsi_host);
 }
 
 /**
- *     ata_host_set_remove - PCI layer callback for device removal
- *     @host_set: ATA host set that was removed
+ *     ata_host_remove - PCI layer callback for device removal
+ *     @host: ATA host set that was removed
  *
  *     Unregister all objects associated with this host set. Free those
  *     objects.
@@ -5624,21 +5854,21 @@ void ata_port_detach(struct ata_port *ap)
  *     Inherited from calling layer (may sleep).
  */
 
-void ata_host_set_remove(struct ata_host_set *host_set)
+void ata_host_remove(struct ata_host *host)
 {
        unsigned int i;
 
-       for (i = 0; i < host_set->n_ports; i++)
-               ata_port_detach(host_set->ports[i]);
+       for (i = 0; i < host->n_ports; i++)
+               ata_port_detach(host->ports[i]);
 
-       free_irq(host_set->irq, host_set);
-       if (host_set->irq2)
-               free_irq(host_set->irq2, host_set);
+       free_irq(host->irq, host);
+       if (host->irq2)
+               free_irq(host->irq2, host);
 
-       for (i = 0; i < host_set->n_ports; i++) {
-               struct ata_port *ap = host_set->ports[i];
+       for (i = 0; i < host->n_ports; i++) {
+               struct ata_port *ap = host->ports[i];
 
-               ata_scsi_release(ap->host);
+               ata_scsi_release(ap->scsi_host);
 
                if ((ap->flags & ATA_FLAG_NO_LEGACY) == 0) {
                        struct ata_ioports *ioaddr = &ap->ioaddr;
@@ -5650,18 +5880,18 @@ void ata_host_set_remove(struct ata_host_set *host_set)
                                release_region(ATA_SECONDARY_CMD, 8);
                }
 
-               scsi_host_put(ap->host);
+               scsi_host_put(ap->scsi_host);
        }
 
-       if (host_set->ops->host_stop)
-               host_set->ops->host_stop(host_set);
+       if (host->ops->host_stop)
+               host->ops->host_stop(host);
 
-       kfree(host_set);
+       kfree(host);
 }
 
 /**
  *     ata_scsi_release - SCSI layer callback hook for host unload
- *     @host: libata host to be unloaded
+ *     @shost: libata host to be unloaded
  *
  *     Performs all duties necessary to shut down a libata port...
  *     Kill port kthread, disable port, and release resources.
@@ -5673,9 +5903,9 @@ void ata_host_set_remove(struct ata_host_set *host_set)
  *     One.
  */
 
-int ata_scsi_release(struct Scsi_Host *host)
+int ata_scsi_release(struct Scsi_Host *shost)
 {
-       struct ata_port *ap = ata_shost_to_port(host);
+       struct ata_port *ap = ata_shost_to_port(shost);
 
        DPRINTK("ENTER\n");
 
@@ -5702,11 +5932,12 @@ ata_probe_ent_alloc(struct device *dev, const struct ata_port_info *port)
        probe_ent->dev = dev;
 
        probe_ent->sht = port->sht;
-       probe_ent->host_flags = port->host_flags;
+       probe_ent->port_flags = port->flags;
        probe_ent->pio_mask = port->pio_mask;
        probe_ent->mwdma_mask = port->mwdma_mask;
        probe_ent->udma_mask = port->udma_mask;
        probe_ent->port_ops = port->port_ops;
+       probe_ent->private_data = port->private_data;
 
        return probe_ent;
 }
@@ -5740,11 +5971,11 @@ void ata_std_ports(struct ata_ioports *ioaddr)
 
 #ifdef CONFIG_PCI
 
-void ata_pci_host_stop (struct ata_host_set *host_set)
+void ata_pci_host_stop (struct ata_host *host)
 {
-       struct pci_dev *pdev = to_pci_dev(host_set->dev);
+       struct pci_dev *pdev = to_pci_dev(host->dev);
 
-       pci_iounmap(pdev, host_set->mmio_base);
+       pci_iounmap(pdev, host->mmio_base);
 }
 
 /**
@@ -5764,9 +5995,9 @@ void ata_pci_host_stop (struct ata_host_set *host_set)
 void ata_pci_remove_one (struct pci_dev *pdev)
 {
        struct device *dev = pci_dev_to_dev(pdev);
-       struct ata_host_set *host_set = dev_get_drvdata(dev);
+       struct ata_host *host = dev_get_drvdata(dev);
 
-       ata_host_set_remove(host_set);
+       ata_host_remove(host);
 
        pci_release_regions(pdev);
        pci_disable_device(pdev);
@@ -5827,10 +6058,10 @@ void ata_pci_device_do_resume(struct pci_dev *pdev)
 
 int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
 {
-       struct ata_host_set *host_set = dev_get_drvdata(&pdev->dev);
+       struct ata_host *host = dev_get_drvdata(&pdev->dev);
        int rc = 0;
 
-       rc = ata_host_set_suspend(host_set, mesg);
+       rc = ata_host_suspend(host, mesg);
        if (rc)
                return rc;
 
@@ -5841,10 +6072,10 @@ int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
 
 int ata_pci_device_resume(struct pci_dev *pdev)
 {
-       struct ata_host_set *host_set = dev_get_drvdata(&pdev->dev);
+       struct ata_host *host = dev_get_drvdata(&pdev->dev);
 
        ata_pci_device_do_resume(pdev);
-       ata_host_set_resume(host_set);
+       ata_host_resume(host);
        return 0;
 }
 #endif /* CONFIG_PCI */
@@ -5873,7 +6104,7 @@ static void __exit ata_exit(void)
        destroy_workqueue(ata_aux_wq);
 }
 
-module_init(ata_init);
+subsys_initcall(ata_init);
 module_exit(ata_exit);
 
 static unsigned long ratelimit_time;
@@ -5989,10 +6220,10 @@ EXPORT_SYMBOL_GPL(sata_deb_timing_long);
 EXPORT_SYMBOL_GPL(ata_dummy_port_ops);
 EXPORT_SYMBOL_GPL(ata_std_bios_param);
 EXPORT_SYMBOL_GPL(ata_std_ports);
-EXPORT_SYMBOL_GPL(ata_host_set_init);
+EXPORT_SYMBOL_GPL(ata_host_init);
 EXPORT_SYMBOL_GPL(ata_device_add);
 EXPORT_SYMBOL_GPL(ata_port_detach);
-EXPORT_SYMBOL_GPL(ata_host_set_remove);
+EXPORT_SYMBOL_GPL(ata_host_remove);
 EXPORT_SYMBOL_GPL(ata_sg_init);
 EXPORT_SYMBOL_GPL(ata_sg_init_one);
 EXPORT_SYMBOL_GPL(ata_hsm_move);
@@ -6036,9 +6267,9 @@ EXPORT_SYMBOL_GPL(__sata_phy_reset);
 EXPORT_SYMBOL_GPL(ata_bus_reset);
 EXPORT_SYMBOL_GPL(ata_std_prereset);
 EXPORT_SYMBOL_GPL(ata_std_softreset);
+EXPORT_SYMBOL_GPL(sata_port_hardreset);
 EXPORT_SYMBOL_GPL(sata_std_hardreset);
 EXPORT_SYMBOL_GPL(ata_std_postreset);
-EXPORT_SYMBOL_GPL(ata_dev_revalidate);
 EXPORT_SYMBOL_GPL(ata_dev_classify);
 EXPORT_SYMBOL_GPL(ata_dev_pair);
 EXPORT_SYMBOL_GPL(ata_port_disable);
@@ -6059,10 +6290,11 @@ EXPORT_SYMBOL_GPL(sata_scr_write);
 EXPORT_SYMBOL_GPL(sata_scr_write_flush);
 EXPORT_SYMBOL_GPL(ata_port_online);
 EXPORT_SYMBOL_GPL(ata_port_offline);
-EXPORT_SYMBOL_GPL(ata_host_set_suspend);
-EXPORT_SYMBOL_GPL(ata_host_set_resume);
+EXPORT_SYMBOL_GPL(ata_host_suspend);
+EXPORT_SYMBOL_GPL(ata_host_resume);
 EXPORT_SYMBOL_GPL(ata_id_string);
 EXPORT_SYMBOL_GPL(ata_id_c_string);
+EXPORT_SYMBOL_GPL(ata_device_blacklisted);
 EXPORT_SYMBOL_GPL(ata_scsi_simulate);
 
 EXPORT_SYMBOL_GPL(ata_pio_need_iordy);