]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blobdiff - drivers/scsi/libata-core.c
[PATCH] libata-eh-fw: update ata_exec_internal() for new EH
[mirror_ubuntu-zesty-kernel.git] / drivers / scsi / libata-core.c
index 9194e4a6a55a74fea63ae6f93cd368b74abfd5fd..4def48ed6f46c8ff4d7f7472bfc156d20e73f4d9 100644 (file)
 
 #include "libata.h"
 
-static unsigned int ata_dev_init_params(struct ata_port *ap,
-                                       struct ata_device *dev,
-                                       u16 heads,
-                                       u16 sectors);
-static unsigned int ata_dev_set_xfermode(struct ata_port *ap,
-                                        struct ata_device *dev);
-static void ata_dev_xfermask(struct ata_port *ap, struct ata_device *dev);
+static unsigned int ata_dev_init_params(struct ata_device *dev,
+                                       u16 heads, u16 sectors);
+static unsigned int ata_dev_set_xfermode(struct ata_device *dev);
+static void ata_dev_xfermask(struct ata_device *dev);
 
 static unsigned int ata_unique_id = 1;
 static struct workqueue_struct *ata_wq;
@@ -412,11 +409,10 @@ static const char *sata_spd_string(unsigned int spd)
        return spd_str[spd - 1];
 }
 
-void ata_dev_disable(struct ata_port *ap, struct ata_device *dev)
+void ata_dev_disable(struct ata_device *dev)
 {
        if (ata_dev_enabled(dev)) {
-               printk(KERN_WARNING "ata%u: dev %u disabled\n",
-                      ap->id, dev->devno);
+               ata_dev_printk(dev, KERN_WARNING, "disabled\n");
                dev->class++;
        }
 }
@@ -955,13 +951,11 @@ void ata_qc_complete_internal(struct ata_queued_cmd *qc)
 {
        struct completion *waiting = qc->private_data;
 
-       qc->ap->ops->tf_read(qc->ap, &qc->tf);
        complete(waiting);
 }
 
 /**
  *     ata_exec_internal - execute libata internal command
- *     @ap: Port to which the command is sent
  *     @dev: Device to which the command is sent
  *     @tf: Taskfile registers for the command and the result
  *     @cdb: CDB for packet command
@@ -979,24 +973,57 @@ void ata_qc_complete_internal(struct ata_queued_cmd *qc)
  *     None.  Should be called with kernel context, might sleep.
  */
 
-unsigned ata_exec_internal(struct ata_port *ap, struct ata_device *dev,
+unsigned ata_exec_internal(struct ata_device *dev,
                           struct ata_taskfile *tf, const u8 *cdb,
                           int dma_dir, void *buf, unsigned int buflen)
 {
+       struct ata_port *ap = dev->ap;
        u8 command = tf->command;
        struct ata_queued_cmd *qc;
+       unsigned int tag, preempted_tag;
        DECLARE_COMPLETION(wait);
        unsigned long flags;
        unsigned int err_mask;
+       int rc;
 
        spin_lock_irqsave(&ap->host_set->lock, flags);
 
-       qc = ata_qc_new_init(ap, dev);
-       BUG_ON(qc == NULL);
+       /* no internal command while frozen */
+       if (ap->flags & ATA_FLAG_FROZEN) {
+               spin_unlock_irqrestore(&ap->host_set->lock, flags);
+               return AC_ERR_SYSTEM;
+       }
+
+       /* initialize internal qc */
+
+       /* XXX: Tag 0 is used for drivers with legacy EH as some
+        * drivers choke if any other tag is given.  This breaks
+        * ata_tag_internal() test for those drivers.  Don't use new
+        * EH stuff without converting to it.
+        */
+       if (ap->ops->error_handler)
+               tag = ATA_TAG_INTERNAL;
+       else
+               tag = 0;
 
+       if (test_and_set_bit(tag, &ap->qactive))
+               BUG();
+       qc = __ata_qc_from_tag(ap, tag);
+
+       qc->tag = tag;
+       qc->scsicmd = NULL;
+       qc->ap = ap;
+       qc->dev = dev;
+       ata_qc_reinit(qc);
+
+       preempted_tag = ap->active_tag;
+       ap->active_tag = ATA_TAG_POISON;
+
+       /* prepare & issue qc */
        qc->tf = *tf;
        if (cdb)
                memcpy(qc->cdb, cdb, ATAPI_CDB_LEN);
+       qc->flags |= ATA_QCFLAG_RESULT_TF;
        qc->dma_dir = dma_dir;
        if (dma_dir != DMA_NONE) {
                ata_sg_init_one(qc, buf, buflen);
@@ -1010,31 +1037,51 @@ unsigned ata_exec_internal(struct ata_port *ap, struct ata_device *dev,
 
        spin_unlock_irqrestore(&ap->host_set->lock, flags);
 
-       if (!wait_for_completion_timeout(&wait, ATA_TMOUT_INTERNAL)) {
-               ata_port_flush_task(ap);
+       rc = wait_for_completion_timeout(&wait, ATA_TMOUT_INTERNAL);
+
+       ata_port_flush_task(ap);
 
+       if (!rc) {
                spin_lock_irqsave(&ap->host_set->lock, flags);
 
                /* We're racing with irq here.  If we lose, the
                 * following test prevents us from completing the qc
-                * again.  If completion irq occurs after here but
-                * before the caller cleans up, it will result in a
-                * spurious interrupt.  We can live with that.
+                * twice.  If we win, the port is frozen and will be
+                * cleaned up by ->post_internal_cmd().
                 */
                if (qc->flags & ATA_QCFLAG_ACTIVE) {
-                       qc->err_mask = AC_ERR_TIMEOUT;
-                       ata_qc_complete(qc);
-                       printk(KERN_WARNING "ata%u: qc timeout (cmd 0x%x)\n",
-                              ap->id, command);
+                       qc->err_mask |= AC_ERR_TIMEOUT;
+
+                       if (ap->ops->error_handler)
+                               ata_port_freeze(ap);
+                       else
+                               ata_qc_complete(qc);
+
+                       ata_dev_printk(dev, KERN_WARNING,
+                                      "qc timeout (cmd 0x%x)\n", command);
                }
 
                spin_unlock_irqrestore(&ap->host_set->lock, flags);
        }
 
-       *tf = qc->tf;
+       /* do post_internal_cmd */
+       if (ap->ops->post_internal_cmd)
+               ap->ops->post_internal_cmd(qc);
+
+       if (qc->flags & ATA_QCFLAG_FAILED && !qc->err_mask) {
+               ata_dev_printk(dev, KERN_WARNING, "zero err_mask for failed "
+                              "internal command, assuming AC_ERR_OTHER\n");
+               qc->err_mask |= AC_ERR_OTHER;
+       }
+
+       /* finish up */
+       spin_lock_irqsave(&ap->host_set->lock, flags);
+
+       *tf = qc->result_tf;
        err_mask = qc->err_mask;
 
        ata_qc_free(qc);
+       ap->active_tag = preempted_tag;
 
        /* XXX - Some LLDDs (sata_mv) disable port on command failure.
         * Until those drivers are fixed, we detect the condition
@@ -1052,6 +1099,8 @@ unsigned ata_exec_internal(struct ata_port *ap, struct ata_device *dev,
                ata_port_probe(ap);
        }
 
+       spin_unlock_irqrestore(&ap->host_set->lock, flags);
+
        return err_mask;
 }
 
@@ -1090,11 +1139,10 @@ unsigned int ata_pio_need_iordy(const struct ata_device *adev)
 
 /**
  *     ata_dev_read_id - Read ID data from the specified device
- *     @ap: port on which target device resides
  *     @dev: target device
  *     @p_class: pointer to class of the target device (may be changed)
  *     @post_reset: is this read ID post-reset?
- *     @p_id: read IDENTIFY page (newly allocated)
+ *     @id: buffer to read IDENTIFY data into
  *
  *     Read ID data from the specified device.  ATA_CMD_ID_ATA is
  *     performed on ATA devices and ATA_CMD_ID_ATAPI on ATAPI
@@ -1107,13 +1155,13 @@ unsigned int ata_pio_need_iordy(const struct ata_device *adev)
  *     RETURNS:
  *     0 on success, -errno otherwise.
  */
-static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev,
-                          unsigned int *p_class, int post_reset, u16 **p_id)
+static int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
+                          int post_reset, u16 *id)
 {
+       struct ata_port *ap = dev->ap;
        unsigned int class = *p_class;
        struct ata_taskfile tf;
        unsigned int err_mask = 0;
-       u16 *id;
        const char *reason;
        int rc;
 
@@ -1121,15 +1169,8 @@ static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev,
 
        ata_dev_select(ap, dev->devno, 1, 1); /* select device 0/1 */
 
-       id = kmalloc(sizeof(id[0]) * ATA_ID_WORDS, GFP_KERNEL);
-       if (id == NULL) {
-               rc = -ENOMEM;
-               reason = "out of memory";
-               goto err_out;
-       }
-
  retry:
-       ata_tf_init(ap, &tf, dev->devno);
+       ata_tf_init(dev, &tf);
 
        switch (class) {
        case ATA_DEV_ATA:
@@ -1146,7 +1187,7 @@ static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev,
 
        tf.protocol = ATA_PROT_PIO;
 
-       err_mask = ata_exec_internal(ap, dev, &tf, NULL, DMA_FROM_DEVICE,
+       err_mask = ata_exec_internal(dev, &tf, NULL, DMA_FROM_DEVICE,
                                     id, sizeof(id[0]) * ATA_ID_WORDS);
        if (err_mask) {
                rc = -EIO;
@@ -1173,7 +1214,7 @@ static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev,
                 * Some drives were very specific about that exact sequence.
                 */
                if (ata_id_major_version(id) < 4 || !ata_id_has_lba(id)) {
-                       err_mask = ata_dev_init_params(ap, dev, id[3], id[6]);
+                       err_mask = ata_dev_init_params(dev, id[3], id[6]);
                        if (err_mask) {
                                rc = -EIO;
                                reason = "INIT_DEV_PARAMS failed";
@@ -1189,25 +1230,22 @@ static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev,
        }
 
        *p_class = class;
-       *p_id = id;
+
        return 0;
 
  err_out:
-       printk(KERN_WARNING "ata%u: dev %u failed to IDENTIFY (%s)\n",
-              ap->id, dev->devno, reason);
-       kfree(id);
+       ata_dev_printk(dev, KERN_WARNING, "failed to IDENTIFY "
+                      "(%s, err_mask=0x%x)\n", reason, err_mask);
        return rc;
 }
 
-static inline u8 ata_dev_knobble(const struct ata_port *ap,
-                                struct ata_device *dev)
+static inline u8 ata_dev_knobble(struct ata_device *dev)
 {
-       return ((ap->cbl == ATA_CBL_SATA) && (!ata_id_is_sata(dev->id)));
+       return ((dev->ap->cbl == ATA_CBL_SATA) && (!ata_id_is_sata(dev->id)));
 }
 
 /**
  *     ata_dev_configure - Configure the specified ATA/ATAPI device
- *     @ap: Port on which target device resides
  *     @dev: Target device to configure
  *     @print_info: Enable device info printout
  *
@@ -1220,9 +1258,9 @@ static inline u8 ata_dev_knobble(const struct ata_port *ap,
  *     RETURNS:
  *     0 on success, -errno otherwise
  */
-static int ata_dev_configure(struct ata_port *ap, struct ata_device *dev,
-                            int print_info)
+static int ata_dev_configure(struct ata_device *dev, int print_info)
 {
+       struct ata_port *ap = dev->ap;
        const u16 *id = dev->id;
        unsigned int xfer_mask;
        int i, rc;
@@ -1237,10 +1275,10 @@ static int ata_dev_configure(struct ata_port *ap, struct ata_device *dev,
 
        /* print device capabilities */
        if (print_info)
-               printk(KERN_DEBUG "ata%u: dev %u cfg 49:%04x 82:%04x 83:%04x "
-                      "84:%04x 85:%04x 86:%04x 87:%04x 88:%04x\n",
-                      ap->id, dev->devno, id[49], id[82], id[83],
-                      id[84], id[85], id[86], id[87], id[88]);
+               ata_dev_printk(dev, KERN_DEBUG, "cfg 49:%04x 82:%04x 83:%04x "
+                              "84:%04x 85:%04x 86:%04x 87:%04x 88:%04x\n",
+                              id[49], id[82], id[83], id[84],
+                              id[85], id[86], id[87], id[88]);
 
        /* initialize to-be-configured parameters */
        dev->flags &= ~ATA_DFLAG_CFG_MASK;
@@ -1276,13 +1314,12 @@ static int ata_dev_configure(struct ata_port *ap, struct ata_device *dev,
 
                        /* print device info to dmesg */
                        if (print_info)
-                               printk(KERN_INFO "ata%u: dev %u ATA-%d, "
-                                      "max %s, %Lu sectors: %s\n",
-                                      ap->id, dev->devno,
-                                      ata_id_major_version(id),
-                                      ata_mode_string(xfer_mask),
-                                      (unsigned long long)dev->n_sectors,
-                                      lba_desc);
+                               ata_dev_printk(dev, KERN_INFO, "ATA-%d, "
+                                       "max %s, %Lu sectors: %s\n",
+                                       ata_id_major_version(id),
+                                       ata_mode_string(xfer_mask),
+                                       (unsigned long long)dev->n_sectors,
+                                       lba_desc);
                } else {
                        /* CHS */
 
@@ -1300,13 +1337,12 @@ static int ata_dev_configure(struct ata_port *ap, struct ata_device *dev,
 
                        /* print device info to dmesg */
                        if (print_info)
-                               printk(KERN_INFO "ata%u: dev %u ATA-%d, "
-                                      "max %s, %Lu sectors: CHS %u/%u/%u\n",
-                                      ap->id, dev->devno,
-                                      ata_id_major_version(id),
-                                      ata_mode_string(xfer_mask),
-                                      (unsigned long long)dev->n_sectors,
-                                      dev->cylinders, dev->heads, dev->sectors);
+                               ata_dev_printk(dev, KERN_INFO, "ATA-%d, "
+                                       "max %s, %Lu sectors: CHS %u/%u/%u\n",
+                                       ata_id_major_version(id),
+                                       ata_mode_string(xfer_mask),
+                                       (unsigned long long)dev->n_sectors,
+                                       dev->cylinders, dev->heads, dev->sectors);
                }
 
                dev->cdb_len = 16;
@@ -1316,7 +1352,8 @@ static int ata_dev_configure(struct ata_port *ap, struct ata_device *dev,
        else if (dev->class == ATA_DEV_ATAPI) {
                rc = atapi_cdb_len(id);
                if ((rc < 12) || (rc > ATAPI_CDB_LEN)) {
-                       printk(KERN_WARNING "ata%u: unsupported CDB len\n", ap->id);
+                       ata_dev_printk(dev, KERN_WARNING,
+                                      "unsupported CDB len\n");
                        rc = -EINVAL;
                        goto err_out_nosup;
                }
@@ -1324,8 +1361,8 @@ static int ata_dev_configure(struct ata_port *ap, struct ata_device *dev,
 
                /* print device info to dmesg */
                if (print_info)
-                       printk(KERN_INFO "ata%u: dev %u ATAPI, max %s\n",
-                              ap->id, dev->devno, ata_mode_string(xfer_mask));
+                       ata_dev_printk(dev, KERN_INFO, "ATAPI, max %s\n",
+                                      ata_mode_string(xfer_mask));
        }
 
        ap->host->max_cmd_len = 0;
@@ -1335,10 +1372,10 @@ static int ata_dev_configure(struct ata_port *ap, struct ata_device *dev,
                                              ap->device[i].cdb_len);
 
        /* limit bridge transfers to udma5, 200 sectors */
-       if (ata_dev_knobble(ap, dev)) {
+       if (ata_dev_knobble(dev)) {
                if (print_info)
-                       printk(KERN_INFO "ata%u(%u): applying bridge limits\n",
-                              ap->id, dev->devno);
+                       ata_dev_printk(dev, KERN_INFO,
+                                      "applying bridge limits\n");
                dev->udma_mask &= ATA_UDMA5;
                dev->max_sectors = ATA_MAX_SECTORS;
        }
@@ -1391,15 +1428,18 @@ static int ata_bus_probe(struct ata_port *ap)
        if (ap->ops->probe_reset) {
                rc = ap->ops->probe_reset(ap, classes);
                if (rc) {
-                       printk("ata%u: reset failed (errno=%d)\n", ap->id, rc);
+                       ata_port_printk(ap, KERN_ERR,
+                                       "reset failed (errno=%d)\n", rc);
                        return rc;
                }
        } else {
                ap->ops->phy_reset(ap);
 
-               if (!(ap->flags & ATA_FLAG_DISABLED))
-                       for (i = 0; i < ATA_MAX_DEVICES; i++)
+               for (i = 0; i < ATA_MAX_DEVICES; i++) {
+                       if (!(ap->flags & ATA_FLAG_DISABLED))
                                classes[i] = ap->device[i].class;
+                       ap->device[i].class = ATA_DEV_UNKNOWN;
+               }
 
                ata_port_probe(ap);
        }
@@ -1418,35 +1458,20 @@ static int ata_bus_probe(struct ata_port *ap)
                if (!ata_dev_enabled(dev))
                        continue;
 
-               kfree(dev->id);
-               dev->id = NULL;
-               rc = ata_dev_read_id(ap, dev, &dev->class, 1, &dev->id);
+               rc = ata_dev_read_id(dev, &dev->class, 1, dev->id);
                if (rc)
                        goto fail;
 
-               rc = ata_dev_configure(ap, dev, 1);
+               rc = ata_dev_configure(dev, 1);
                if (rc)
                        goto fail;
        }
 
        /* configure transfer mode */
-       if (ap->ops->set_mode) {
-               /* FIXME: make ->set_mode handle no device case and
-                * return error code and failing device on failure as
-                * ata_set_mode() does.
-                */
-               for (i = 0; i < ATA_MAX_DEVICES; i++)
-                       if (ata_dev_enabled(&ap->device[i])) {
-                               ap->ops->set_mode(ap);
-                               break;
-                       }
-               rc = 0;
-       } else {
-               rc = ata_set_mode(ap, &dev);
-               if (rc) {
-                       down_xfermask = 1;
-                       goto fail;
-               }
+       rc = ata_set_mode(ap, &dev);
+       if (rc) {
+               down_xfermask = 1;
+               goto fail;
        }
 
        for (i = 0; i < ATA_MAX_DEVICES; i++)
@@ -1465,18 +1490,18 @@ static int ata_bus_probe(struct ata_port *ap)
                tries[dev->devno] = 0;
                break;
        case -EIO:
-               ata_down_sata_spd_limit(ap);
+               sata_down_spd_limit(ap);
                /* fall through */
        default:
                tries[dev->devno]--;
                if (down_xfermask &&
-                   ata_down_xfermask_limit(ap, dev, tries[dev->devno] == 1))
+                   ata_down_xfermask_limit(dev, tries[dev->devno] == 1))
                        tries[dev->devno] = 0;
        }
 
        if (!tries[dev->devno]) {
-               ata_down_xfermask_limit(ap, dev, 1);
-               ata_dev_disable(ap, dev);
+               ata_down_xfermask_limit(dev, 1);
+               ata_dev_disable(dev);
        }
 
        goto retry;
@@ -1511,21 +1536,19 @@ static void sata_print_link_status(struct ata_port *ap)
 {
        u32 sstatus, scontrol, tmp;
 
-       if (!ap->ops->scr_read)
+       if (sata_scr_read(ap, SCR_STATUS, &sstatus))
                return;
+       sata_scr_read(ap, SCR_CONTROL, &scontrol);
 
-       sstatus = scr_read(ap, SCR_STATUS);
-       scontrol = scr_read(ap, SCR_CONTROL);
-
-       if (sata_dev_present(ap)) {
+       if (ata_port_online(ap)) {
                tmp = (sstatus >> 4) & 0xf;
-               printk(KERN_INFO
-                      "ata%u: SATA link up %s (SStatus %X SControl %X)\n",
-                      ap->id, sata_spd_string(tmp), sstatus, scontrol);
+               ata_port_printk(ap, KERN_INFO,
+                               "SATA link up %s (SStatus %X SControl %X)\n",
+                               sata_spd_string(tmp), sstatus, scontrol);
        } else {
-               printk(KERN_INFO
-                      "ata%u: SATA link down (SStatus %X SControl %X)\n",
-                      ap->id, sstatus, scontrol);
+               ata_port_printk(ap, KERN_INFO,
+                               "SATA link down (SStatus %X SControl %X)\n",
+                               sstatus, scontrol);
        }
 }
 
@@ -1548,17 +1571,18 @@ void __sata_phy_reset(struct ata_port *ap)
 
        if (ap->flags & ATA_FLAG_SATA_RESET) {
                /* issue phy wake/reset */
-               scr_write_flush(ap, SCR_CONTROL, 0x301);
+               sata_scr_write_flush(ap, SCR_CONTROL, 0x301);
                /* Couldn't find anything in SATA I/II specs, but
                 * AHCI-1.1 10.4.2 says at least 1 ms. */
                mdelay(1);
        }
-       scr_write_flush(ap, SCR_CONTROL, 0x300); /* phy wake/clear reset */
+       /* phy wake/clear reset */
+       sata_scr_write_flush(ap, SCR_CONTROL, 0x300);
 
        /* wait for phy to become ready, if necessary */
        do {
                msleep(200);
-               sstatus = scr_read(ap, SCR_STATUS);
+               sata_scr_read(ap, SCR_STATUS, &sstatus);
                if ((sstatus & 0xf) != 1)
                        break;
        } while (time_before(jiffies, timeout));
@@ -1567,7 +1591,7 @@ void __sata_phy_reset(struct ata_port *ap)
        sata_print_link_status(ap);
 
        /* TODO: phy layer with polling, timeouts, etc. */
-       if (sata_dev_present(ap))
+       if (!ata_port_offline(ap))
                ata_port_probe(ap);
        else
                ata_port_disable(ap);
@@ -1604,15 +1628,15 @@ void sata_phy_reset(struct ata_port *ap)
 
 /**
  *     ata_dev_pair            -       return other device on cable
- *     @ap: port
  *     @adev: device
  *
  *     Obtain the other device on the same cable, or if none is
  *     present NULL is returned
  */
 
-struct ata_device *ata_dev_pair(struct ata_port *ap, struct ata_device *adev)
+struct ata_device *ata_dev_pair(struct ata_device *adev)
 {
+       struct ata_port *ap = adev->ap;
        struct ata_device *pair = &ap->device[1 - adev->devno];
        if (!ata_dev_enabled(pair))
                return NULL;
@@ -1640,12 +1664,12 @@ void ata_port_disable(struct ata_port *ap)
 }
 
 /**
- *     ata_down_sata_spd_limit - adjust SATA spd limit downward
+ *     sata_down_spd_limit - adjust SATA spd limit downward
  *     @ap: Port to adjust SATA spd limit for
  *
  *     Adjust SATA spd limit of @ap downward.  Note that this
  *     function only adjusts the limit.  The change must be applied
- *     using ata_set_sata_spd().
+ *     using sata_set_spd().
  *
  *     LOCKING:
  *     Inherited from caller.
@@ -1653,13 +1677,14 @@ void ata_port_disable(struct ata_port *ap)
  *     RETURNS:
  *     0 on success, negative errno on failure
  */
-int ata_down_sata_spd_limit(struct ata_port *ap)
+int sata_down_spd_limit(struct ata_port *ap)
 {
-       u32 spd, mask;
-       int highbit;
+       u32 sstatus, spd, mask;
+       int rc, highbit;
 
-       if (ap->cbl != ATA_CBL_SATA || !ap->ops->scr_read)
-               return -EOPNOTSUPP;
+       rc = sata_scr_read(ap, SCR_STATUS, &sstatus);
+       if (rc)
+               return rc;
 
        mask = ap->sata_spd_limit;
        if (mask <= 1)
@@ -1667,7 +1692,7 @@ int ata_down_sata_spd_limit(struct ata_port *ap)
        highbit = fls(mask) - 1;
        mask &= ~(1 << highbit);
 
-       spd = (scr_read(ap, SCR_STATUS) >> 4) & 0xf;
+       spd = (sstatus >> 4) & 0xf;
        if (spd <= 1)
                return -EINVAL;
        spd--;
@@ -1677,13 +1702,13 @@ int ata_down_sata_spd_limit(struct ata_port *ap)
 
        ap->sata_spd_limit = mask;
 
-       printk(KERN_WARNING "ata%u: limiting SATA link speed to %s\n",
-              ap->id, sata_spd_string(fls(mask)));
+       ata_port_printk(ap, KERN_WARNING, "limiting SATA link speed to %s\n",
+                       sata_spd_string(fls(mask)));
 
        return 0;
 }
 
-static int __ata_set_sata_spd_needed(struct ata_port *ap, u32 *scontrol)
+static int __sata_set_spd_needed(struct ata_port *ap, u32 *scontrol)
 {
        u32 spd, limit;
 
@@ -1699,7 +1724,7 @@ static int __ata_set_sata_spd_needed(struct ata_port *ap, u32 *scontrol)
 }
 
 /**
- *     ata_set_sata_spd_needed - is SATA spd configuration needed
+ *     sata_set_spd_needed - is SATA spd configuration needed
  *     @ap: Port in question
  *
  *     Test whether the spd limit in SControl matches
@@ -1713,20 +1738,18 @@ static int __ata_set_sata_spd_needed(struct ata_port *ap, u32 *scontrol)
  *     RETURNS:
  *     1 if SATA spd configuration is needed, 0 otherwise.
  */
-int ata_set_sata_spd_needed(struct ata_port *ap)
+int sata_set_spd_needed(struct ata_port *ap)
 {
        u32 scontrol;
 
-       if (ap->cbl != ATA_CBL_SATA || !ap->ops->scr_read)
+       if (sata_scr_read(ap, SCR_CONTROL, &scontrol))
                return 0;
 
-       scontrol = scr_read(ap, SCR_CONTROL);
-
-       return __ata_set_sata_spd_needed(ap, &scontrol);
+       return __sata_set_spd_needed(ap, &scontrol);
 }
 
 /**
- *     ata_set_sata_spd - set SATA spd according to spd limit
+ *     sata_set_spd - set SATA spd according to spd limit
  *     @ap: Port to set SATA spd for
  *
  *     Set SATA spd of @ap according to sata_spd_limit.
@@ -1736,20 +1759,22 @@ int ata_set_sata_spd_needed(struct ata_port *ap)
  *
  *     RETURNS:
  *     0 if spd doesn't need to be changed, 1 if spd has been
- *     changed.  -EOPNOTSUPP if SCR registers are inaccessible.
+ *     changed.  Negative errno if SCR registers are inaccessible.
  */
-static int ata_set_sata_spd(struct ata_port *ap)
+int sata_set_spd(struct ata_port *ap)
 {
        u32 scontrol;
+       int rc;
 
-       if (ap->cbl != ATA_CBL_SATA || !ap->ops->scr_read)
-               return -EOPNOTSUPP;
+       if ((rc = sata_scr_read(ap, SCR_CONTROL, &scontrol)))
+               return rc;
 
-       scontrol = scr_read(ap, SCR_CONTROL);
-       if (!__ata_set_sata_spd_needed(ap, &scontrol))
+       if (!__sata_set_spd_needed(ap, &scontrol))
                return 0;
 
-       scr_write(ap, SCR_CONTROL, scontrol);
+       if ((rc = sata_scr_write(ap, SCR_CONTROL, scontrol)))
+               return rc;
+
        return 1;
 }
 
@@ -1903,7 +1928,6 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed,
 
 /**
  *     ata_down_xfermask_limit - adjust dev xfer masks downward
- *     @ap: Port associated with device @dev
  *     @dev: Device to adjust xfer masks
  *     @force_pio0: Force PIO0
  *
@@ -1917,8 +1941,7 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed,
  *     RETURNS:
  *     0 on success, negative errno on failure
  */
-int ata_down_xfermask_limit(struct ata_port *ap, struct ata_device *dev,
-                           int force_pio0)
+int ata_down_xfermask_limit(struct ata_device *dev, int force_pio0)
 {
        unsigned long xfer_mask;
        int highbit;
@@ -1942,8 +1965,8 @@ int ata_down_xfermask_limit(struct ata_port *ap, struct ata_device *dev,
        ata_unpack_xfermask(xfer_mask, &dev->pio_mask, &dev->mwdma_mask,
                            &dev->udma_mask);
 
-       printk(KERN_WARNING "ata%u: dev %u limiting speed to %s\n",
-              ap->id, dev->devno, ata_mode_string(xfer_mask));
+       ata_dev_printk(dev, KERN_WARNING, "limiting speed to %s\n",
+                      ata_mode_string(xfer_mask));
 
        return 0;
 
@@ -1951,7 +1974,7 @@ int ata_down_xfermask_limit(struct ata_port *ap, struct ata_device *dev,
        return -EINVAL;
 }
 
-static int ata_dev_set_mode(struct ata_port *ap, struct ata_device *dev)
+static int ata_dev_set_mode(struct ata_device *dev)
 {
        unsigned int err_mask;
        int rc;
@@ -1960,24 +1983,22 @@ static int ata_dev_set_mode(struct ata_port *ap, struct ata_device *dev)
        if (dev->xfer_shift == ATA_SHIFT_PIO)
                dev->flags |= ATA_DFLAG_PIO;
 
-       err_mask = ata_dev_set_xfermode(ap, dev);
+       err_mask = ata_dev_set_xfermode(dev);
        if (err_mask) {
-               printk(KERN_ERR
-                      "ata%u: failed to set xfermode (err_mask=0x%x)\n",
-                      ap->id, err_mask);
+               ata_dev_printk(dev, KERN_ERR, "failed to set xfermode "
+                              "(err_mask=0x%x)\n", err_mask);
                return -EIO;
        }
 
-       rc = ata_dev_revalidate(ap, dev, 0);
+       rc = ata_dev_revalidate(dev, 0);
        if (rc)
                return rc;
 
        DPRINTK("xfer_shift=%u, xfer_mode=0x%x\n",
                dev->xfer_shift, (int)dev->xfer_mode);
 
-       printk(KERN_INFO "ata%u: dev %u configured for %s\n",
-              ap->id, dev->devno,
-              ata_mode_string(ata_xfer_mode2mask(dev->xfer_mode)));
+       ata_dev_printk(dev, KERN_INFO, "configured for %s\n",
+                      ata_mode_string(ata_xfer_mode2mask(dev->xfer_mode)));
        return 0;
 }
 
@@ -2001,6 +2022,20 @@ int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)
        struct ata_device *dev;
        int i, rc = 0, used_dma = 0, found = 0;
 
+       /* has private set_mode? */
+       if (ap->ops->set_mode) {
+               /* FIXME: make ->set_mode handle no device case and
+                * return error code and failing device on failure.
+                */
+               for (i = 0; i < ATA_MAX_DEVICES; i++) {
+                       if (ata_dev_enabled(&ap->device[i])) {
+                               ap->ops->set_mode(ap);
+                               break;
+                       }
+               }
+               return 0;
+       }
+
        /* step 1: calculate xfer_mask */
        for (i = 0; i < ATA_MAX_DEVICES; i++) {
                unsigned int pio_mask, dma_mask;
@@ -2010,7 +2045,7 @@ int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)
                if (!ata_dev_enabled(dev))
                        continue;
 
-               ata_dev_xfermask(ap, dev);
+               ata_dev_xfermask(dev);
 
                pio_mask = ata_pack_xfermask(dev->pio_mask, 0, 0);
                dma_mask = ata_pack_xfermask(0, dev->mwdma_mask, dev->udma_mask);
@@ -2031,8 +2066,7 @@ int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)
                        continue;
 
                if (!dev->pio_mode) {
-                       printk(KERN_WARNING "ata%u: dev %u no PIO support\n",
-                              ap->id, dev->devno);
+                       ata_dev_printk(dev, KERN_WARNING, "no PIO support\n");
                        rc = -EINVAL;
                        goto out;
                }
@@ -2063,7 +2097,7 @@ int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)
                if (!ata_dev_enabled(dev))
                        continue;
 
-               rc = ata_dev_set_mode(ap, dev);
+               rc = ata_dev_set_mode(dev);
                if (rc)
                        goto out;
        }
@@ -2131,8 +2165,8 @@ unsigned int ata_busy_sleep (struct ata_port *ap,
        }
 
        if (status & ATA_BUSY)
-               printk(KERN_WARNING "ata%u is slow to respond, "
-                      "please be patient\n", ap->id);
+               ata_port_printk(ap, KERN_WARNING,
+                               "port is slow to respond, please be patient\n");
 
        timeout = timer_start + tmout;
        while ((status & ATA_BUSY) && (time_before(jiffies, timeout))) {
@@ -2141,8 +2175,8 @@ unsigned int ata_busy_sleep (struct ata_port *ap,
        }
 
        if (status & ATA_BUSY) {
-               printk(KERN_ERR "ata%u failed to respond (%lu secs)\n",
-                      ap->id, tmout / HZ);
+               ata_port_printk(ap, KERN_ERR, "port failed to respond "
+                               "(%lu secs)\n", tmout / HZ);
                return 1;
        }
 
@@ -2235,7 +2269,7 @@ static unsigned int ata_bus_softreset(struct ata_port *ap,
         * pulldown resistor.
         */
        if (ata_check_status(ap) == 0xFF) {
-               printk(KERN_ERR "ata%u: SRST failed (status 0xFF)\n", ap->id);
+               ata_port_printk(ap, KERN_ERR, "SRST failed (status 0xFF)\n");
                return AC_ERR_OTHER;
        }
 
@@ -2329,7 +2363,7 @@ void ata_bus_reset(struct ata_port *ap)
        return;
 
 err_out:
-       printk(KERN_ERR "ata%u: disabling port\n", ap->id);
+       ata_port_printk(ap, KERN_ERR, "disabling port\n");
        ap->ops->port_disable(ap);
 
        DPRINTK("EXIT\n");
@@ -2339,20 +2373,26 @@ static int sata_phy_resume(struct ata_port *ap)
 {
        unsigned long timeout = jiffies + (HZ * 5);
        u32 scontrol, sstatus;
+       int rc;
+
+       if ((rc = sata_scr_read(ap, SCR_CONTROL, &scontrol)))
+               return rc;
 
-       scontrol = scr_read(ap, SCR_CONTROL);
        scontrol = (scontrol & 0x0f0) | 0x300;
-       scr_write_flush(ap, SCR_CONTROL, scontrol);
+
+       if ((rc = sata_scr_write(ap, SCR_CONTROL, scontrol)))
+               return rc;
 
        /* Wait for phy to become ready, if necessary. */
        do {
                msleep(200);
-               sstatus = scr_read(ap, SCR_STATUS);
+               if ((rc = sata_scr_read(ap, SCR_STATUS, &sstatus)))
+                       return rc;
                if ((sstatus & 0xf) != 1)
                        return 0;
        } while (time_before(jiffies, timeout));
 
-       return -1;
+       return -EBUSY;
 }
 
 /**
@@ -2370,22 +2410,20 @@ static int sata_phy_resume(struct ata_port *ap)
  */
 void ata_std_probeinit(struct ata_port *ap)
 {
-       if ((ap->flags & ATA_FLAG_SATA) && ap->ops->scr_read) {
-               u32 spd;
-
-               /* set cable type and resume link */
-               ap->cbl = ATA_CBL_SATA;
-               sata_phy_resume(ap);
+       u32 scontrol;
 
-               /* init sata_spd_limit to the current value */
-               spd = (scr_read(ap, SCR_CONTROL) & 0xf0) >> 4;
-               if (spd)
-                       ap->sata_spd_limit &= (1 << spd) - 1;
+       /* resume link */
+       sata_phy_resume(ap);
 
-               /* wait for device */
-               if (sata_dev_present(ap))
-                       ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
+       /* init sata_spd_limit to the current value */
+       if (sata_scr_read(ap, SCR_CONTROL, &scontrol) == 0) {
+               int spd = (scontrol >> 4) & 0xf;
+               ap->sata_spd_limit &= (1 << spd) - 1;
        }
+
+       /* wait for device */
+       if (ata_port_online(ap))
+               ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
 }
 
 /**
@@ -2410,7 +2448,7 @@ int ata_std_softreset(struct ata_port *ap, unsigned int *classes)
 
        DPRINTK("ENTER\n");
 
-       if (ap->ops->scr_read && !sata_dev_present(ap)) {
+       if (ata_port_offline(ap)) {
                classes[0] = ATA_DEV_NONE;
                goto out;
        }
@@ -2428,8 +2466,8 @@ int ata_std_softreset(struct ata_port *ap, unsigned int *classes)
        DPRINTK("about to softreset, devmask=%x\n", devmask);
        err_mask = ata_bus_softreset(ap, devmask);
        if (err_mask) {
-               printk(KERN_ERR "ata%u: SRST failed (err_mask=0x%x)\n",
-                      ap->id, err_mask);
+               ata_port_printk(ap, KERN_ERR, "SRST failed (err_mask=0x%x)\n",
+                               err_mask);
                return -EIO;
        }
 
@@ -2461,26 +2499,35 @@ int ata_std_softreset(struct ata_port *ap, unsigned int *classes)
 int sata_std_hardreset(struct ata_port *ap, unsigned int *class)
 {
        u32 scontrol;
+       int rc;
 
        DPRINTK("ENTER\n");
 
-       if (ata_set_sata_spd_needed(ap)) {
+       if (sata_set_spd_needed(ap)) {
                /* SATA spec says nothing about how to reconfigure
                 * spd.  To be on the safe side, turn off phy during
                 * reconfiguration.  This works for at least ICH7 AHCI
                 * and Sil3124.
                 */
-               scontrol = scr_read(ap, SCR_CONTROL);
+               if ((rc = sata_scr_read(ap, SCR_CONTROL, &scontrol)))
+                       return rc;
+
                scontrol = (scontrol & 0x0f0) | 0x302;
-               scr_write_flush(ap, SCR_CONTROL, scontrol);
 
-               ata_set_sata_spd(ap);
+               if ((rc = sata_scr_write(ap, SCR_CONTROL, scontrol)))
+                       return rc;
+
+               sata_set_spd(ap);
        }
 
        /* issue phy wake/reset */
-       scontrol = scr_read(ap, SCR_CONTROL);
+       if ((rc = sata_scr_read(ap, SCR_CONTROL, &scontrol)))
+               return rc;
+
        scontrol = (scontrol & 0x0f0) | 0x301;
-       scr_write_flush(ap, SCR_CONTROL, scontrol);
+
+       if ((rc = sata_scr_write_flush(ap, SCR_CONTROL, scontrol)))
+               return rc;
 
        /* Couldn't find anything in SATA I/II specs, but AHCI-1.1
         * 10.4.2 says at least 1 ms.
@@ -2491,15 +2538,15 @@ int sata_std_hardreset(struct ata_port *ap, unsigned int *class)
        sata_phy_resume(ap);
 
        /* TODO: phy layer with polling, timeouts, etc. */
-       if (!sata_dev_present(ap)) {
+       if (ata_port_offline(ap)) {
                *class = ATA_DEV_NONE;
                DPRINTK("EXIT, link offline\n");
                return 0;
        }
 
        if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) {
-               printk(KERN_ERR
-                      "ata%u: COMRESET failed (device not ready)\n", ap->id);
+               ata_port_printk(ap, KERN_ERR,
+                               "COMRESET failed (device not ready)\n");
                return -EIO;
        }
 
@@ -2528,15 +2575,23 @@ int sata_std_hardreset(struct ata_port *ap, unsigned int *class)
  */
 void ata_std_postreset(struct ata_port *ap, unsigned int *classes)
 {
+       u32 serror;
+
        DPRINTK("ENTER\n");
 
        /* print link status */
-       if (ap->cbl == ATA_CBL_SATA)
-               sata_print_link_status(ap);
+       sata_print_link_status(ap);
+
+       /* clear SError */
+       if (sata_scr_read(ap, SCR_ERROR, &serror) == 0)
+               sata_scr_write(ap, SCR_ERROR, serror);
 
        /* re-enable interrupts */
-       if (ap->ioaddr.ctl_addr)        /* FIXME: hack. create a hook instead */
-               ata_irq_on(ap);
+       if (!ap->ops->error_handler) {
+               /* FIXME: hack. create a hook instead */
+               if (ap->ioaddr.ctl_addr)
+                       ata_irq_on(ap);
+       }
 
        /* is double-select really necessary? */
        if (classes[0] != ATA_DEV_NONE)
@@ -2579,7 +2634,7 @@ int ata_std_probe_reset(struct ata_port *ap, unsigned int *classes)
        ata_reset_fn_t hardreset;
 
        hardreset = NULL;
-       if (ap->cbl == ATA_CBL_SATA && ap->ops->scr_read)
+       if (sata_scr_valid(ap))
                hardreset = sata_std_hardreset;
 
        return ata_drive_probe_reset(ap, ata_std_probeinit,
@@ -2588,7 +2643,7 @@ int ata_std_probe_reset(struct ata_port *ap, unsigned int *classes)
 }
 
 int ata_do_reset(struct ata_port *ap, ata_reset_fn_t reset,
-                ata_postreset_fn_t postreset, unsigned int *classes)
+                unsigned int *classes)
 {
        int i, rc;
 
@@ -2612,9 +2667,6 @@ int ata_do_reset(struct ata_port *ap, ata_reset_fn_t reset,
                        if (classes[i] == ATA_DEV_UNKNOWN)
                                classes[i] = ATA_DEV_NONE;
 
-       if (postreset)
-               postreset(ap, classes);
-
        return 0;
 }
 
@@ -2654,15 +2706,17 @@ int ata_drive_probe_reset(struct ata_port *ap, ata_probeinit_fn_t probeinit,
 {
        int rc = -EINVAL;
 
+       ata_eh_freeze_port(ap);
+
        if (probeinit)
                probeinit(ap);
 
-       if (softreset && !ata_set_sata_spd_needed(ap)) {
-               rc = ata_do_reset(ap, softreset, postreset, classes);
+       if (softreset && !sata_set_spd_needed(ap)) {
+               rc = ata_do_reset(ap, softreset, classes);
                if (rc == 0 && classes[0] != ATA_DEV_UNKNOWN)
                        goto done;
-               printk(KERN_INFO "ata%u: softreset failed, will try "
-                      "hardreset in 5 secs\n", ap->id);
+               ata_port_printk(ap, KERN_INFO, "softreset failed, "
+                               "will try hardreset in 5 secs\n");
                ssleep(5);
        }
 
@@ -2670,39 +2724,45 @@ int ata_drive_probe_reset(struct ata_port *ap, ata_probeinit_fn_t probeinit,
                goto done;
 
        while (1) {
-               rc = ata_do_reset(ap, hardreset, postreset, classes);
+               rc = ata_do_reset(ap, hardreset, classes);
                if (rc == 0) {
                        if (classes[0] != ATA_DEV_UNKNOWN)
                                goto done;
                        break;
                }
 
-               if (ata_down_sata_spd_limit(ap))
+               if (sata_down_spd_limit(ap))
                        goto done;
 
-               printk(KERN_INFO "ata%u: hardreset failed, will retry "
-                      "in 5 secs\n", ap->id);
+               ata_port_printk(ap, KERN_INFO, "hardreset failed, "
+                               "will retry in 5 secs\n");
                ssleep(5);
        }
 
        if (softreset) {
-               printk(KERN_INFO "ata%u: hardreset succeeded without "
-                      "classification, will retry softreset in 5 secs\n",
-                      ap->id);
+               ata_port_printk(ap, KERN_INFO,
+                               "hardreset succeeded without classification, "
+                               "will retry softreset in 5 secs\n");
                ssleep(5);
 
-               rc = ata_do_reset(ap, softreset, postreset, classes);
+               rc = ata_do_reset(ap, softreset, classes);
        }
 
  done:
-       if (rc == 0 && classes[0] == ATA_DEV_UNKNOWN)
-               rc = -ENODEV;
+       if (rc == 0) {
+               if (postreset)
+                       postreset(ap, classes);
+
+               ata_eh_thaw_port(ap);
+
+               if (classes[0] == ATA_DEV_UNKNOWN)
+                       rc = -ENODEV;
+       }
        return rc;
 }
 
 /**
  *     ata_dev_same_device - Determine whether new ID matches configured device
- *     @ap: port on which the device to compare against resides
  *     @dev: device to compare against
  *     @new_class: class of the new device
  *     @new_id: IDENTIFY page of the new device
@@ -2717,17 +2777,16 @@ int ata_drive_probe_reset(struct ata_port *ap, ata_probeinit_fn_t probeinit,
  *     RETURNS:
  *     1 if @dev matches @new_class and @new_id, 0 otherwise.
  */
-static int ata_dev_same_device(struct ata_port *ap, struct ata_device *dev,
-                              unsigned int new_class, const u16 *new_id)
+static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class,
+                              const u16 *new_id)
 {
        const u16 *old_id = dev->id;
        unsigned char model[2][41], serial[2][21];
        u64 new_n_sectors;
 
        if (dev->class != new_class) {
-               printk(KERN_INFO
-                      "ata%u: dev %u class mismatch %d != %d\n",
-                      ap->id, dev->devno, dev->class, new_class);
+               ata_dev_printk(dev, KERN_INFO, "class mismatch %d != %d\n",
+                              dev->class, new_class);
                return 0;
        }
 
@@ -2738,24 +2797,22 @@ static int ata_dev_same_device(struct ata_port *ap, struct ata_device *dev,
        new_n_sectors = ata_id_n_sectors(new_id);
 
        if (strcmp(model[0], model[1])) {
-               printk(KERN_INFO
-                      "ata%u: dev %u model number mismatch '%s' != '%s'\n",
-                      ap->id, dev->devno, model[0], model[1]);
+               ata_dev_printk(dev, KERN_INFO, "model number mismatch "
+                              "'%s' != '%s'\n", model[0], model[1]);
                return 0;
        }
 
        if (strcmp(serial[0], serial[1])) {
-               printk(KERN_INFO
-                      "ata%u: dev %u serial number mismatch '%s' != '%s'\n",
-                      ap->id, dev->devno, serial[0], serial[1]);
+               ata_dev_printk(dev, KERN_INFO, "serial number mismatch "
+                              "'%s' != '%s'\n", serial[0], serial[1]);
                return 0;
        }
 
        if (dev->class == ATA_DEV_ATA && dev->n_sectors != new_n_sectors) {
-               printk(KERN_INFO
-                      "ata%u: dev %u n_sectors mismatch %llu != %llu\n",
-                      ap->id, dev->devno, (unsigned long long)dev->n_sectors,
-                      (unsigned long long)new_n_sectors);
+               ata_dev_printk(dev, KERN_INFO, "n_sectors mismatch "
+                              "%llu != %llu\n",
+                              (unsigned long long)dev->n_sectors,
+                              (unsigned long long)new_n_sectors);
                return 0;
        }
 
@@ -2764,7 +2821,6 @@ static int ata_dev_same_device(struct ata_port *ap, struct ata_device *dev,
 
 /**
  *     ata_dev_revalidate - Revalidate ATA device
- *     @ap: port on which the device to revalidate resides
  *     @dev: device to revalidate
  *     @post_reset: is this revalidation after reset?
  *
@@ -2777,11 +2833,10 @@ static int ata_dev_same_device(struct ata_port *ap, struct ata_device *dev,
  *     RETURNS:
  *     0 on success, negative errno otherwise
  */
-int ata_dev_revalidate(struct ata_port *ap, struct ata_device *dev,
-                      int post_reset)
+int ata_dev_revalidate(struct ata_device *dev, int post_reset)
 {
        unsigned int class = dev->class;
-       u16 *id = NULL;
+       u16 *id = (void *)dev->ap->sector_buf;
        int rc;
 
        if (!ata_dev_enabled(dev)) {
@@ -2789,29 +2844,26 @@ int ata_dev_revalidate(struct ata_port *ap, struct ata_device *dev,
                goto fail;
        }
 
-       /* allocate & read ID data */
-       rc = ata_dev_read_id(ap, dev, &class, post_reset, &id);
+       /* read ID data */
+       rc = ata_dev_read_id(dev, &class, post_reset, id);
        if (rc)
                goto fail;
 
        /* is the device still there? */
-       if (!ata_dev_same_device(ap, dev, class, id)) {
+       if (!ata_dev_same_device(dev, class, id)) {
                rc = -ENODEV;
                goto fail;
        }
 
-       kfree(dev->id);
-       dev->id = id;
+       memcpy(dev->id, id, sizeof(id[0]) * ATA_ID_WORDS);
 
        /* configure device according to the new ID */
-       rc = ata_dev_configure(ap, dev, 0);
+       rc = ata_dev_configure(dev, 0);
        if (rc == 0)
                return 0;
 
  fail:
-       printk(KERN_ERR "ata%u: dev %u revalidation failed (errno=%d)\n",
-              ap->id, dev->devno, rc);
-       kfree(id);
+       ata_dev_printk(dev, KERN_ERR, "revalidation failed (errno=%d)\n", rc);
        return rc;
 }
 
@@ -2887,7 +2939,6 @@ static int ata_dma_blacklisted(const struct ata_device *dev)
 
 /**
  *     ata_dev_xfermask - Compute supported xfermask of the given device
- *     @ap: Port on which the device to compute xfermask for resides
  *     @dev: Device to compute xfermask for
  *
  *     Compute supported xfermask of @dev and store it in
@@ -2902,8 +2953,9 @@ static int ata_dma_blacklisted(const struct ata_device *dev)
  *     LOCKING:
  *     None.
  */
-static void ata_dev_xfermask(struct ata_port *ap, 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;
        unsigned long xfer_mask;
        int i;
@@ -2939,8 +2991,8 @@ static void ata_dev_xfermask(struct ata_port *ap, struct ata_device *dev)
        }
 
        if (ata_dma_blacklisted(dev))
-               printk(KERN_WARNING "ata%u: dev %u is on DMA blacklist, "
-                      "disabling DMA\n", ap->id, dev->devno);
+               ata_dev_printk(dev, KERN_WARNING,
+                              "device is on DMA blacklist, disabling DMA\n");
 
        if (hs->flags & ATA_HOST_SIMPLEX) {
                if (hs->simplex_claimed)
@@ -2956,7 +3008,6 @@ static void ata_dev_xfermask(struct ata_port *ap, struct ata_device *dev)
 
 /**
  *     ata_dev_set_xfermode - Issue SET FEATURES - XFER MODE command
- *     @ap: Port associated with device @dev
  *     @dev: Device to which command will be sent
  *
  *     Issue SET FEATURES - XFER MODE command to device @dev
@@ -2969,8 +3020,7 @@ static void ata_dev_xfermask(struct ata_port *ap, struct ata_device *dev)
  *     0 on success, AC_ERR_* mask otherwise.
  */
 
-static unsigned int ata_dev_set_xfermode(struct ata_port *ap,
-                                        struct ata_device *dev)
+static unsigned int ata_dev_set_xfermode(struct ata_device *dev)
 {
        struct ata_taskfile tf;
        unsigned int err_mask;
@@ -2978,14 +3028,14 @@ static unsigned int ata_dev_set_xfermode(struct ata_port *ap,
        /* set up set-features taskfile */
        DPRINTK("set features - xfer mode\n");
 
-       ata_tf_init(ap, &tf, dev->devno);
+       ata_tf_init(dev, &tf);
        tf.command = ATA_CMD_SET_FEATURES;
        tf.feature = SETFEATURES_XFER;
        tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
        tf.protocol = ATA_PROT_NODATA;
        tf.nsect = dev->xfer_mode;
 
-       err_mask = ata_exec_internal(ap, dev, &tf, NULL, DMA_NONE, NULL, 0);
+       err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
 
        DPRINTK("EXIT, err_mask=%x\n", err_mask);
        return err_mask;
@@ -2993,8 +3043,9 @@ static unsigned int ata_dev_set_xfermode(struct ata_port *ap,
 
 /**
  *     ata_dev_init_params - Issue INIT DEV PARAMS command
- *     @ap: Port associated with device @dev
  *     @dev: Device to which command will be sent
+ *     @heads: Number of heads
+ *     @sectors: Number of sectors
  *
  *     LOCKING:
  *     Kernel thread context (may sleep)
@@ -3002,11 +3053,8 @@ static unsigned int ata_dev_set_xfermode(struct ata_port *ap,
  *     RETURNS:
  *     0 on success, AC_ERR_* mask otherwise.
  */
-
-static unsigned int ata_dev_init_params(struct ata_port *ap,
-                                       struct ata_device *dev,
-                                       u16 heads,
-                                       u16 sectors)
+static unsigned int ata_dev_init_params(struct ata_device *dev,
+                                       u16 heads, u16 sectors)
 {
        struct ata_taskfile tf;
        unsigned int err_mask;
@@ -3018,14 +3066,14 @@ static unsigned int ata_dev_init_params(struct ata_port *ap,
        /* set up init dev params taskfile */
        DPRINTK("init dev params \n");
 
-       ata_tf_init(ap, &tf, dev->devno);
+       ata_tf_init(dev, &tf);
        tf.command = ATA_CMD_INIT_DEV_PARAMS;
        tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
        tf.protocol = ATA_PROT_NODATA;
        tf.nsect = sectors;
        tf.device |= (heads - 1) & 0x0f; /* max head = num. of heads - 1 */
 
-       err_mask = ata_exec_internal(ap, dev, &tf, NULL, DMA_NONE, NULL, 0);
+       err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
 
        DPRINTK("EXIT, err_mask=%x\n", err_mask);
        return err_mask;
@@ -3398,16 +3446,31 @@ skip_map:
  *     LOCKING:
  *     None.  (grabs host lock)
  */
-
 void ata_poll_qc_complete(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
        unsigned long flags;
 
        spin_lock_irqsave(&ap->host_set->lock, flags);
-       ap->flags &= ~ATA_FLAG_NOINTR;
-       ata_irq_on(ap);
-       ata_qc_complete(qc);
+
+       if (ap->ops->error_handler) {
+               /* EH might have kicked in while host_set lock is released */
+               qc = ata_qc_from_tag(ap, qc->tag);
+               if (qc) {
+                       if (!(qc->err_mask & AC_ERR_HSM)) {
+                               ap->flags &= ~ATA_FLAG_NOINTR;
+                               ata_irq_on(ap);
+                               ata_qc_complete(qc);
+                       } else
+                               ata_port_freeze(ap);
+               }
+       } else {
+               /* old EH */
+               ap->flags &= ~ATA_FLAG_NOINTR;
+               ata_irq_on(ap);
+               ata_qc_complete(qc);
+       }
+
        spin_unlock_irqrestore(&ap->host_set->lock, flags);
 }
 
@@ -3735,8 +3798,8 @@ next_sg:
                unsigned int i;
 
                if (words) /* warning if bytes > 1 */
-                       printk(KERN_WARNING "ata%u: %u bytes trailing data\n",
-                              ap->id, bytes);
+                       ata_dev_printk(qc->dev, KERN_WARNING,
+                                      "%u bytes trailing data\n", bytes);
 
                for (i = 0; i < words; i++)
                        ata_data_xfer(ap, (unsigned char*)pad_buf, 2, do_write);
@@ -3819,8 +3882,7 @@ static void atapi_pio_bytes(struct ata_queued_cmd *qc)
        return;
 
 err_out:
-       printk(KERN_INFO "ata%u: dev %u: ATAPI check failed\n",
-             ap->id, dev->devno);
+       ata_dev_printk(dev, KERN_INFO, "ATAPI check failed\n");
        qc->err_mask |= AC_ERR_HSM;
        ap->hsm_task_state = HSM_ST_ERR;
 }
@@ -3889,8 +3951,7 @@ static void ata_pio_error(struct ata_queued_cmd *qc)
        struct ata_port *ap = qc->ap;
 
        if (qc->tf.command != ATA_CMD_PACKET)
-               printk(KERN_WARNING "ata%u: dev %u PIO error\n",
-                      ap->id, qc->dev->devno);
+               ata_dev_printk(qc->dev, KERN_WARNING, "PIO error\n");
 
        /* make sure qc->err_mask is available to
         * know what's wrong and recover
@@ -4023,9 +4084,14 @@ static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
        struct ata_queued_cmd *qc = NULL;
        unsigned int i;
 
-       for (i = 0; i < ATA_MAX_QUEUE; i++)
+       /* no command while frozen */
+       if (unlikely(ap->flags & ATA_FLAG_FROZEN))
+               return NULL;
+
+       /* the last tag is reserved for internal command. */
+       for (i = 0; i < ATA_MAX_QUEUE - 1; i++)
                if (!test_and_set_bit(i, &ap->qactive)) {
-                       qc = ata_qc_from_tag(ap, i);
+                       qc = __ata_qc_from_tag(ap, i);
                        break;
                }
 
@@ -4037,16 +4103,15 @@ static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
 
 /**
  *     ata_qc_new_init - Request an available ATA command, and initialize it
- *     @ap: Port associated with device @dev
  *     @dev: Device from whom we request an available command structure
  *
  *     LOCKING:
  *     None.
  */
 
-struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
-                                     struct ata_device *dev)
+struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev)
 {
+       struct ata_port *ap = dev->ap;
        struct ata_queued_cmd *qc;
 
        qc = ata_qc_new(ap);
@@ -4081,8 +4146,6 @@ void ata_qc_free(struct ata_queued_cmd *qc)
        qc->flags = 0;
        tag = qc->tag;
        if (likely(ata_tag_valid(tag))) {
-               if (tag == ap->active_tag)
-                       ap->active_tag = ATA_TAG_POISON;
                qc->tag = ATA_TAG_POISON;
                clear_bit(tag, &ap->qactive);
        }
@@ -4096,6 +4159,9 @@ void __ata_qc_complete(struct ata_queued_cmd *qc)
        if (likely(qc->flags & ATA_QCFLAG_DMAMAP))
                ata_sg_clean(qc);
 
+       /* command should be marked inactive atomically with qc completion */
+       qc->ap->active_tag = ATA_TAG_POISON;
+
        /* atapi: mark qc as inactive to prevent the interrupt handler
         * from completing the command twice later, before the error handler
         * is called. (when rc != 0 and atapi request sense is needed)
@@ -4106,6 +4172,66 @@ void __ata_qc_complete(struct ata_queued_cmd *qc)
        qc->complete_fn(qc);
 }
 
+/**
+ *     ata_qc_complete - Complete an active ATA command
+ *     @qc: Command to complete
+ *     @err_mask: 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)
+ */
+void ata_qc_complete(struct ata_queued_cmd *qc)
+{
+       struct ata_port *ap = qc->ap;
+
+       /* XXX: New EH and old EH use different mechanisms to
+        * synchronize EH with regular execution path.
+        *
+        * In new EH, a failed qc is marked with ATA_QCFLAG_FAILED.
+        * Normal execution path is responsible for not accessing a
+        * failed qc.  libata core enforces the rule by returning NULL
+        * from ata_qc_from_tag() for failed qcs.
+        *
+        * Old EH depends on ata_qc_complete() nullifying completion
+        * requests if ATA_QCFLAG_EH_SCHEDULED is set.  Old EH does
+        * not synchronize with interrupt handler.  Only PIO task is
+        * taken care of.
+        */
+       if (ap->ops->error_handler) {
+               WARN_ON(ap->flags & ATA_FLAG_FROZEN);
+
+               if (unlikely(qc->err_mask))
+                       qc->flags |= ATA_QCFLAG_FAILED;
+
+               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);
+                               ata_qc_schedule_eh(qc);
+                               return;
+                       }
+               }
+
+               /* read result TF if requested */
+               if (qc->flags & ATA_QCFLAG_RESULT_TF)
+                       ap->ops->tf_read(ap, &qc->result_tf);
+
+               __ata_qc_complete(qc);
+       } else {
+               if (qc->flags & ATA_QCFLAG_EH_SCHEDULED)
+                       return;
+
+               /* 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);
+
+               __ata_qc_complete(qc);
+       }
+}
+
 static inline int ata_should_dma_map(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
@@ -4316,7 +4442,7 @@ idle_irq:
 #ifdef ATA_IRQ_TRAP
        if ((ap->stats.idle_irq % 1000) == 0) {
                ata_irq_ack(ap, 0); /* debug trap */
-               printk(KERN_WARNING "ata%d: irq trap\n", ap->id);
+               ata_port_printk(ap, KERN_WARNING, "irq trap\n");
                return 1;
        }
 #endif
@@ -4369,32 +4495,168 @@ irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
        return IRQ_RETVAL(handled);
 }
 
+/**
+ *     sata_scr_valid - test whether SCRs are accessible
+ *     @ap: ATA port to test SCR accessibility for
+ *
+ *     Test whether SCRs are accessible for @ap.
+ *
+ *     LOCKING:
+ *     None.
+ *
+ *     RETURNS:
+ *     1 if SCRs are accessible, 0 otherwise.
+ */
+int sata_scr_valid(struct ata_port *ap)
+{
+       return ap->cbl == ATA_CBL_SATA && ap->ops->scr_read;
+}
+
+/**
+ *     sata_scr_read - read SCR register of the specified port
+ *     @ap: ATA port to read SCR for
+ *     @reg: SCR to read
+ *     @val: Place to store read value
+ *
+ *     Read SCR register @reg of @ap into *@val.  This function is
+ *     guaranteed to succeed if the cable type of the port is SATA
+ *     and the port implements ->scr_read.
+ *
+ *     LOCKING:
+ *     None.
+ *
+ *     RETURNS:
+ *     0 on success, negative errno on failure.
+ */
+int sata_scr_read(struct ata_port *ap, int reg, u32 *val)
+{
+       if (sata_scr_valid(ap)) {
+               *val = ap->ops->scr_read(ap, reg);
+               return 0;
+       }
+       return -EOPNOTSUPP;
+}
+
+/**
+ *     sata_scr_write - write SCR register of the specified port
+ *     @ap: ATA port to write SCR for
+ *     @reg: SCR to write
+ *     @val: value to write
+ *
+ *     Write @val to SCR register @reg of @ap.  This function is
+ *     guaranteed to succeed if the cable type of the port is SATA
+ *     and the port implements ->scr_read.
+ *
+ *     LOCKING:
+ *     None.
+ *
+ *     RETURNS:
+ *     0 on success, negative errno on failure.
+ */
+int sata_scr_write(struct ata_port *ap, int reg, u32 val)
+{
+       if (sata_scr_valid(ap)) {
+               ap->ops->scr_write(ap, reg, val);
+               return 0;
+       }
+       return -EOPNOTSUPP;
+}
+
+/**
+ *     sata_scr_write_flush - write SCR register of the specified port and flush
+ *     @ap: ATA port to write SCR for
+ *     @reg: SCR to write
+ *     @val: value to write
+ *
+ *     This function is identical to sata_scr_write() except that this
+ *     function performs flush after writing to the register.
+ *
+ *     LOCKING:
+ *     None.
+ *
+ *     RETURNS:
+ *     0 on success, negative errno on failure.
+ */
+int sata_scr_write_flush(struct ata_port *ap, int reg, u32 val)
+{
+       if (sata_scr_valid(ap)) {
+               ap->ops->scr_write(ap, reg, val);
+               ap->ops->scr_read(ap, reg);
+               return 0;
+       }
+       return -EOPNOTSUPP;
+}
+
+/**
+ *     ata_port_online - test whether the given port is online
+ *     @ap: ATA port to test
+ *
+ *     Test whether @ap is online.  Note that this function returns 0
+ *     if online status of @ap cannot be obtained, so
+ *     ata_port_online(ap) != !ata_port_offline(ap).
+ *
+ *     LOCKING:
+ *     None.
+ *
+ *     RETURNS:
+ *     1 if the port online status is available and online.
+ */
+int ata_port_online(struct ata_port *ap)
+{
+       u32 sstatus;
+
+       if (!sata_scr_read(ap, SCR_STATUS, &sstatus) && (sstatus & 0xf) == 0x3)
+               return 1;
+       return 0;
+}
+
+/**
+ *     ata_port_offline - test whether the given port is offline
+ *     @ap: ATA port to test
+ *
+ *     Test whether @ap is offline.  Note that this function returns
+ *     0 if offline status of @ap cannot be obtained, so
+ *     ata_port_online(ap) != !ata_port_offline(ap).
+ *
+ *     LOCKING:
+ *     None.
+ *
+ *     RETURNS:
+ *     1 if the port offline status is available and offline.
+ */
+int ata_port_offline(struct ata_port *ap)
+{
+       u32 sstatus;
+
+       if (!sata_scr_read(ap, SCR_STATUS, &sstatus) && (sstatus & 0xf) != 0x3)
+               return 1;
+       return 0;
+}
 
 /*
  * Execute a 'simple' command, that only consists of the opcode 'cmd' itself,
  * without filling any other registers
  */
-static int ata_do_simple_cmd(struct ata_port *ap, struct ata_device *dev,
-                            u8 cmd)
+static int ata_do_simple_cmd(struct ata_device *dev, u8 cmd)
 {
        struct ata_taskfile tf;
        int err;
 
-       ata_tf_init(ap, &tf, dev->devno);
+       ata_tf_init(dev, &tf);
 
        tf.command = cmd;
        tf.flags |= ATA_TFLAG_DEVICE;
        tf.protocol = ATA_PROT_NODATA;
 
-       err = ata_exec_internal(ap, dev, &tf, NULL, DMA_NONE, NULL, 0);
+       err = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
        if (err)
-               printk(KERN_ERR "%s: ata command failed: %d\n",
-                               __FUNCTION__, err);
+               ata_dev_printk(dev, KERN_ERR, "%s: ata command failed: %d\n",
+                              __FUNCTION__, err);
 
        return err;
 }
 
-static int ata_flush_cache(struct ata_port *ap, struct ata_device *dev)
+static int ata_flush_cache(struct ata_device *dev)
 {
        u8 cmd;
 
@@ -4406,22 +4668,21 @@ static int ata_flush_cache(struct ata_port *ap, struct ata_device *dev)
        else
                cmd = ATA_CMD_FLUSH;
 
-       return ata_do_simple_cmd(ap, dev, cmd);
+       return ata_do_simple_cmd(dev, cmd);
 }
 
-static int ata_standby_drive(struct ata_port *ap, struct ata_device *dev)
+static int ata_standby_drive(struct ata_device *dev)
 {
-       return ata_do_simple_cmd(ap, dev, ATA_CMD_STANDBYNOW1);
+       return ata_do_simple_cmd(dev, ATA_CMD_STANDBYNOW1);
 }
 
-static int ata_start_drive(struct ata_port *ap, struct ata_device *dev)
+static int ata_start_drive(struct ata_device *dev)
 {
-       return ata_do_simple_cmd(ap, dev, ATA_CMD_IDLEIMMEDIATE);
+       return ata_do_simple_cmd(dev, ATA_CMD_IDLEIMMEDIATE);
 }
 
 /**
  *     ata_device_resume - wakeup a previously suspended devices
- *     @ap: port the device is connected to
  *     @dev: the device to resume
  *
  *     Kick the drive back into action, by sending it an idle immediate
@@ -4429,39 +4690,42 @@ static int ata_start_drive(struct ata_port *ap, struct ata_device *dev)
  *     and host.
  *
  */
-int ata_device_resume(struct ata_port *ap, struct ata_device *dev)
+int ata_device_resume(struct ata_device *dev)
 {
+       struct ata_port *ap = dev->ap;
+
        if (ap->flags & ATA_FLAG_SUSPENDED) {
                struct ata_device *failed_dev;
                ap->flags &= ~ATA_FLAG_SUSPENDED;
                while (ata_set_mode(ap, &failed_dev))
-                       ata_dev_disable(ap, failed_dev);
+                       ata_dev_disable(failed_dev);
        }
        if (!ata_dev_enabled(dev))
                return 0;
        if (dev->class == ATA_DEV_ATA)
-               ata_start_drive(ap, dev);
+               ata_start_drive(dev);
 
        return 0;
 }
 
 /**
  *     ata_device_suspend - prepare a device for suspend
- *     @ap: port the device is connected to
  *     @dev: the device to suspend
  *
  *     Flush the cache on the drive, if appropriate, then issue a
  *     standbynow command.
  */
-int ata_device_suspend(struct ata_port *ap, struct ata_device *dev, pm_message_t state)
+int ata_device_suspend(struct ata_device *dev, pm_message_t state)
 {
+       struct ata_port *ap = dev->ap;
+
        if (!ata_dev_enabled(dev))
                return 0;
        if (dev->class == ATA_DEV_ATA)
-               ata_flush_cache(ap, dev);
+               ata_flush_cache(dev);
 
        if (state.event != PM_EVENT_FREEZE)
-               ata_standby_drive(ap, dev);
+               ata_standby_drive(dev);
        ap->flags |= ATA_FLAG_SUSPENDED;
        return 0;
 }
@@ -4589,7 +4853,6 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host,
        ap->udma_mask = ent->udma_mask;
        ap->flags |= ent->host_flags;
        ap->ops = ent->port_ops;
-       ap->cbl = ATA_CBL_NONE;
        ap->sata_spd_limit = UINT_MAX;
        ap->active_tag = ATA_TAG_POISON;
        ap->last_ctl = 0xFF;
@@ -4597,8 +4860,14 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host,
        INIT_WORK(&ap->port_task, NULL, NULL);
        INIT_LIST_HEAD(&ap->eh_done_q);
 
+       /* set cable type */
+       ap->cbl = ATA_CBL_NONE;
+       if (ap->flags & ATA_FLAG_SATA)
+               ap->cbl = ATA_CBL_SATA;
+
        for (i = 0; i < ATA_MAX_DEVICES; i++) {
                struct ata_device *dev = &ap->device[i];
+               dev->ap = ap;
                dev->devno = i;
                dev->pio_mask = UINT_MAX;
                dev->mwdma_mask = UINT_MAX;
@@ -4722,18 +4991,18 @@ int ata_device_add(const struct ata_probe_ent *ent)
                                (ap->pio_mask << ATA_SHIFT_PIO);
 
                /* print per-port info to dmesg */
-               printk(KERN_INFO "ata%u: %cATA max %s cmd 0x%lX ctl 0x%lX "
-                                "bmdma 0x%lX irq %lu\n",
-                       ap->id,
-                       ap->flags & ATA_FLAG_SATA ? 'S' : 'P',
-                       ata_mode_string(xfer_mode_mask),
-                       ap->ioaddr.cmd_addr,
-                       ap->ioaddr.ctl_addr,
-                       ap->ioaddr.bmdma_addr,
-                       ent->irq);
+               ata_port_printk(ap, KERN_INFO, "%cATA max %s cmd 0x%lX "
+                               "ctl 0x%lX bmdma 0x%lX irq %lu\n",
+                               ap->flags & ATA_FLAG_SATA ? 'S' : 'P',
+                               ata_mode_string(xfer_mode_mask),
+                               ap->ioaddr.cmd_addr,
+                               ap->ioaddr.ctl_addr,
+                               ap->ioaddr.bmdma_addr,
+                               ent->irq);
 
                ata_chk_status(ap);
                host_set->ops->irq_clear(ap);
+               ata_eh_freeze_port(ap); /* freeze port before requesting IRQ */
                count++;
        }
 
@@ -4768,8 +5037,7 @@ int ata_device_add(const struct ata_probe_ent *ent)
 
                rc = scsi_add_host(ap->host, dev);
                if (rc) {
-                       printk(KERN_ERR "ata%u: scsi_add_host failed\n",
-                              ap->id);
+                       ata_port_printk(ap, KERN_ERR, "scsi_add_host failed\n");
                        /* FIXME: do something useful here */
                        /* FIXME: handle unconditional calls to
                         * scsi_scan_host and ata_host_remove, below,
@@ -4865,14 +5133,11 @@ void ata_host_set_remove(struct ata_host_set *host_set)
 int ata_scsi_release(struct Scsi_Host *host)
 {
        struct ata_port *ap = ata_shost_to_port(host);
-       int i;
 
        DPRINTK("ENTER\n");
 
        ap->ops->port_disable(ap);
        ata_host_remove(ap, 0);
-       for (i = 0; i < ATA_MAX_DEVICES; i++)
-               kfree(ap->device[i].id);
 
        DPRINTK("EXIT\n");
        return 1;
@@ -5090,7 +5355,7 @@ EXPORT_SYMBOL_GPL(ata_device_add);
 EXPORT_SYMBOL_GPL(ata_host_set_remove);
 EXPORT_SYMBOL_GPL(ata_sg_init);
 EXPORT_SYMBOL_GPL(ata_sg_init_one);
-EXPORT_SYMBOL_GPL(__ata_qc_complete);
+EXPORT_SYMBOL_GPL(ata_qc_complete);
 EXPORT_SYMBOL_GPL(ata_qc_issue_prot);
 EXPORT_SYMBOL_GPL(ata_tf_load);
 EXPORT_SYMBOL_GPL(ata_tf_read);
@@ -5113,6 +5378,7 @@ EXPORT_SYMBOL_GPL(ata_bmdma_irq_clear);
 EXPORT_SYMBOL_GPL(ata_bmdma_status);
 EXPORT_SYMBOL_GPL(ata_bmdma_stop);
 EXPORT_SYMBOL_GPL(ata_port_probe);
+EXPORT_SYMBOL_GPL(sata_set_spd);
 EXPORT_SYMBOL_GPL(sata_phy_reset);
 EXPORT_SYMBOL_GPL(__sata_phy_reset);
 EXPORT_SYMBOL_GPL(ata_bus_reset);
@@ -5135,6 +5401,12 @@ EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
 EXPORT_SYMBOL_GPL(ata_scsi_slave_config);
 EXPORT_SYMBOL_GPL(ata_scsi_release);
 EXPORT_SYMBOL_GPL(ata_host_intr);
+EXPORT_SYMBOL_GPL(sata_scr_valid);
+EXPORT_SYMBOL_GPL(sata_scr_read);
+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_id_string);
 EXPORT_SYMBOL_GPL(ata_id_c_string);
 EXPORT_SYMBOL_GPL(ata_scsi_simulate);
@@ -5160,7 +5432,11 @@ EXPORT_SYMBOL_GPL(ata_device_resume);
 EXPORT_SYMBOL_GPL(ata_scsi_device_suspend);
 EXPORT_SYMBOL_GPL(ata_scsi_device_resume);
 
-EXPORT_SYMBOL_GPL(ata_scsi_error);
 EXPORT_SYMBOL_GPL(ata_eng_timeout);
+EXPORT_SYMBOL_GPL(ata_port_schedule_eh);
+EXPORT_SYMBOL_GPL(ata_port_abort);
+EXPORT_SYMBOL_GPL(ata_port_freeze);
+EXPORT_SYMBOL_GPL(ata_eh_freeze_port);
+EXPORT_SYMBOL_GPL(ata_eh_thaw_port);
 EXPORT_SYMBOL_GPL(ata_eh_qc_complete);
 EXPORT_SYMBOL_GPL(ata_eh_qc_retry);