]> err.no Git - linux-2.6/blobdiff - drivers/ata/libata-core.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/shaggy...
[linux-2.6] / drivers / ata / libata-core.c
index 24b3bd63621fe20f4ec089373f42f277914f6a77..6380726f75389ff85519c0605e50d84a5fc0087f 100644 (file)
  *  Hardware documentation available from http://www.t13.org/ and
  *  http://www.sata-io.org/
  *
+ *  Standards documents from:
+ *     http://www.t13.org (ATA standards, PCI DMA IDE spec)
+ *     http://www.t10.org (SCSI MMC - for ATAPI MMC)
+ *     http://www.sata-io.org (SATA)
+ *     http://www.compactflash.org (CF)
+ *     http://www.qic.org (QIC157 - Tape and DSC)
+ *     http://www.ce-ata.org (CE-ATA: not supported)
+ *
  */
 
 #include <linux/kernel.h>
@@ -56,6 +64,7 @@
 #include <linux/libata.h>
 #include <asm/semaphore.h>
 #include <asm/byteorder.h>
+#include <linux/cdrom.h>
 
 #include "libata.h"
 
@@ -614,6 +623,7 @@ void ata_dev_disable(struct ata_device *dev)
        if (ata_dev_enabled(dev)) {
                if (ata_msg_drv(dev->link->ap))
                        ata_dev_printk(dev, KERN_WARNING, "disabled\n");
+               ata_acpi_on_disable(dev);
                ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO0 |
                                             ATA_DNXFER_QUIET);
                dev->class++;
@@ -676,10 +686,11 @@ static int ata_dev_set_dipm(struct ata_device *dev, enum link_pm policy)
                if (rc)
                        return rc;
 
-               /* disable DIPM */
-               if (ata_dev_enabled(dev) && (dev->flags & ATA_DFLAG_DIPM))
-                       err_mask = ata_dev_set_feature(dev,
-                                       SETFEATURES_SATA_DISABLE, SATA_DIPM);
+               /*
+                * we don't have to disable DIPM since IPM flags
+                * disallow transitions to SLUMBER, which effectively
+                * disable DIPM if it does not support PARTIAL
+                */
                break;
        case NOT_AVAILABLE:
        case MAX_PERFORMANCE:
@@ -689,10 +700,11 @@ static int ata_dev_set_dipm(struct ata_device *dev, enum link_pm policy)
                if (rc)
                        return rc;
 
-               /* disable DIPM */
-               if (ata_dev_enabled(dev) && (dev->flags & ATA_DFLAG_DIPM))
-                       err_mask = ata_dev_set_feature(dev,
-                                       SETFEATURES_SATA_DISABLE, SATA_DIPM);
+               /*
+                * we don't have to disable DIPM since IPM flags
+                * disallow all transitions which effectively
+                * disable DIPM anyway.
+                */
                break;
        }
 
@@ -2305,8 +2317,10 @@ int ata_dev_configure(struct ata_device *dev)
        }
 
        if ((dev->class == ATA_DEV_ATAPI) &&
-           (atapi_command_packet_set(id) == TYPE_TAPE))
+           (atapi_command_packet_set(id) == TYPE_TAPE)) {
                dev->max_sectors = ATA_MAX_SECTORS_TAPE;
+               dev->horkage |= ATA_HORKAGE_STUCK_ERR;
+       }
 
        if (dev->horkage & ATA_HORKAGE_MAX_SEC_128)
                dev->max_sectors = min_t(unsigned int, ATA_MAX_SECTORS_128,
@@ -2578,81 +2592,6 @@ void sata_print_link_status(struct ata_link *link)
        }
 }
 
-/**
- *     __sata_phy_reset - Wake/reset a low-level SATA PHY
- *     @ap: SATA port associated with target SATA PHY.
- *
- *     This function issues commands to standard SATA Sxxx
- *     PHY registers, to wake up the phy (and device), and
- *     clear any reset condition.
- *
- *     LOCKING:
- *     PCI/etc. bus probe sem.
- *
- */
-void __sata_phy_reset(struct ata_port *ap)
-{
-       struct ata_link *link = &ap->link;
-       unsigned long timeout = jiffies + (HZ * 5);
-       u32 sstatus;
-
-       if (ap->flags & ATA_FLAG_SATA_RESET) {
-               /* issue phy wake/reset */
-               sata_scr_write_flush(link, 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);
-       }
-       /* phy wake/clear reset */
-       sata_scr_write_flush(link, SCR_CONTROL, 0x300);
-
-       /* wait for phy to become ready, if necessary */
-       do {
-               msleep(200);
-               sata_scr_read(link, SCR_STATUS, &sstatus);
-               if ((sstatus & 0xf) != 1)
-                       break;
-       } while (time_before(jiffies, timeout));
-
-       /* print link status */
-       sata_print_link_status(link);
-
-       /* TODO: phy layer with polling, timeouts, etc. */
-       if (!ata_link_offline(link))
-               ata_port_probe(ap);
-       else
-               ata_port_disable(ap);
-
-       if (ap->flags & ATA_FLAG_DISABLED)
-               return;
-
-       if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) {
-               ata_port_disable(ap);
-               return;
-       }
-
-       ap->cbl = ATA_CBL_SATA;
-}
-
-/**
- *     sata_phy_reset - Reset SATA bus.
- *     @ap: SATA port associated with target SATA PHY.
- *
- *     This function resets the SATA bus, and then probes
- *     the bus for devices.
- *
- *     LOCKING:
- *     PCI/etc. bus probe sem.
- *
- */
-void sata_phy_reset(struct ata_port *ap)
-{
-       __sata_phy_reset(ap);
-       if (ap->flags & ATA_FLAG_DISABLED)
-               return;
-       ata_bus_reset(ap);
-}
-
 /**
  *     ata_dev_pair            -       return other device on cable
  *     @adev: device
@@ -2751,17 +2690,27 @@ int sata_down_spd_limit(struct ata_link *link)
 
 static int __sata_set_spd_needed(struct ata_link *link, u32 *scontrol)
 {
-       u32 spd, limit;
+       struct ata_link *host_link = &link->ap->link;
+       u32 limit, target, spd;
 
-       if (link->sata_spd_limit == UINT_MAX)
-               limit = 0;
+       limit = link->sata_spd_limit;
+
+       /* Don't configure downstream link faster than upstream link.
+        * It doesn't speed up anything and some PMPs choke on such
+        * configuration.
+        */
+       if (!ata_is_host_link(link) && host_link->sata_spd)
+               limit &= (1 << host_link->sata_spd) - 1;
+
+       if (limit == UINT_MAX)
+               target = 0;
        else
-               limit = fls(link->sata_spd_limit);
+               target = fls(limit);
 
        spd = (*scontrol >> 4) & 0xf;
-       *scontrol = (*scontrol & ~0xf0) | ((limit & 0xf) << 4);
+       *scontrol = (*scontrol & ~0xf0) | ((target & 0xf) << 4);
 
-       return spd != limit;
+       return spd != target;
 }
 
 /**
@@ -2784,7 +2733,7 @@ int sata_set_spd_needed(struct ata_link *link)
        u32 scontrol;
 
        if (sata_scr_read(link, SCR_CONTROL, &scontrol))
-               return 0;
+               return 1;
 
        return __sata_set_spd_needed(link, &scontrol);
 }
@@ -3361,14 +3310,20 @@ void ata_wait_after_reset(struct ata_port *ap, unsigned long deadline)
         * to clear 0xff after reset.  For example, HHD424020F7SV00
         * iVDR needs >= 800ms while.  Quantum GoVault needs even more
         * than that.
+        *
+        * Note that some PATA controllers (pata_ali) explode if
+        * status register is read more than once when there's no
+        * device attached.
         */
-       while (1) {
-               u8 status = ata_chk_status(ap);
+       if (ap->flags & ATA_FLAG_SATA) {
+               while (1) {
+                       u8 status = ata_chk_status(ap);
 
-               if (status != 0xff || time_after(jiffies, deadline))
-                       return;
+                       if (status != 0xff || time_after(jiffies, deadline))
+                               return;
 
-               msleep(50);
+                       msleep(50);
+               }
        }
 }
 
@@ -3970,6 +3925,7 @@ void ata_std_postreset(struct ata_link *link, unsigned int *classes)
        /* clear SError */
        if (sata_scr_read(link, SCR_ERROR, &serror) == 0)
                sata_scr_write(link, SCR_ERROR, serror);
+       link->eh_info.serror = 0;
 
        /* is double-select really necessary? */
        if (classes[0] != ATA_DEV_NONE)
@@ -4187,6 +4143,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
        /* Devices where NCQ should be avoided */
        /* NCQ is slow */
        { "WDC WD740ADFD-00",   NULL,           ATA_HORKAGE_NONCQ },
+       { "WDC WD740ADFD-00NLR1", NULL,         ATA_HORKAGE_NONCQ, },
        /* http://thread.gmane.org/gmane.linux.ide/14907 */
        { "FUJITSU MHT2060BH",  NULL,           ATA_HORKAGE_NONCQ },
        /* NCQ is broken */
@@ -4195,29 +4152,13 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
        { "HITACHI HDS7250SASUN500G*", NULL,    ATA_HORKAGE_NONCQ },
        { "HITACHI HDS7225SBSUN250G*", NULL,    ATA_HORKAGE_NONCQ },
        { "ST380817AS",         "3.42",         ATA_HORKAGE_NONCQ },
+       { "ST3160023AS",        "3.42",         ATA_HORKAGE_NONCQ },
 
        /* Blacklist entries taken from Silicon Image 3124/3132
           Windows driver .inf file - also several Linux problem reports */
        { "HTS541060G9SA00",    "MB3OC60D",     ATA_HORKAGE_NONCQ, },
        { "HTS541080G9SA00",    "MB4OC60D",     ATA_HORKAGE_NONCQ, },
        { "HTS541010G9SA00",    "MBZOC60D",     ATA_HORKAGE_NONCQ, },
-       /* Drives which do spurious command completion */
-       { "HTS541680J9SA00",    "SB2IC7EP",     ATA_HORKAGE_NONCQ, },
-       { "HTS541612J9SA00",    "SBDIC7JP",     ATA_HORKAGE_NONCQ, },
-       { "HDT722516DLA380",    "V43OA96A",     ATA_HORKAGE_NONCQ, },
-       { "Hitachi HTS541616J9SA00", "SB4OC70P", ATA_HORKAGE_NONCQ, },
-       { "Hitachi HTS542525K9SA00", "BBFOC31P", ATA_HORKAGE_NONCQ, },
-       { "WDC WD740ADFD-00NLR1", NULL,         ATA_HORKAGE_NONCQ, },
-       { "WDC WD3200AAJS-00RYA0", "12.01B01",  ATA_HORKAGE_NONCQ, },
-       { "FUJITSU MHV2080BH",  "00840028",     ATA_HORKAGE_NONCQ, },
-       { "ST9120822AS",        "3.CLF",        ATA_HORKAGE_NONCQ, },
-       { "ST9160821AS",        "3.CLF",        ATA_HORKAGE_NONCQ, },
-       { "ST9160821AS",        "3.ALD",        ATA_HORKAGE_NONCQ, },
-       { "ST9160821AS",        "3.CCD",        ATA_HORKAGE_NONCQ, },
-       { "ST3160812AS",        "3.ADJ",        ATA_HORKAGE_NONCQ, },
-       { "ST980813AS",         "3.ADB",        ATA_HORKAGE_NONCQ, },
-       { "SAMSUNG HD401LJ",    "ZZ100-15",     ATA_HORKAGE_NONCQ, },
-       { "Maxtor 7V300F0",     "VA111900",     ATA_HORKAGE_NONCQ, },
 
        /* devices which puke on READ_NATIVE_MAX */
        { "HDS724040KLSA80",    "KFAOA20N",     ATA_HORKAGE_BROKEN_HPA, },
@@ -4229,6 +4170,13 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
        { "ST340823A",          NULL,           ATA_HORKAGE_HPA_SIZE, },
        { "ST320413A",          NULL,           ATA_HORKAGE_HPA_SIZE, },
 
+       /* Devices which get the IVB wrong */
+       { "QUANTUM FIREBALLlct10 05", "A03.0900", ATA_HORKAGE_IVB, },
+       { "TSSTcorp CDDVDW SH-S202J", "SB00",     ATA_HORKAGE_IVB, },
+       { "TSSTcorp CDDVDW SH-S202J", "SB01",     ATA_HORKAGE_IVB, },
+       { "TSSTcorp CDDVDW SH-S202N", "SB00",     ATA_HORKAGE_IVB, },
+       { "TSSTcorp CDDVDW SH-S202N", "SB01",     ATA_HORKAGE_IVB, },
+
        /* End Marker */
        { }
 };
@@ -4289,6 +4237,21 @@ static int ata_dma_blacklisted(const struct ata_device *dev)
        return (dev->horkage & ATA_HORKAGE_NODMA) ? 1 : 0;
 }
 
+/**
+ *     ata_is_40wire           -       check drive side detection
+ *     @dev: device
+ *
+ *     Perform drive side detection decoding, allowing for device vendors
+ *     who can't follow the documentation.
+ */
+
+static int ata_is_40wire(struct ata_device *dev)
+{
+       if (dev->horkage & ATA_HORKAGE_IVB)
+               return ata_drive_40wire_relaxed(dev->id);
+       return ata_drive_40wire(dev->id);
+}
+
 /**
  *     ata_dev_xfermask - Compute supported xfermask of the given device
  *     @dev: Device to compute xfermask for
@@ -4358,7 +4321,7 @@ static void ata_dev_xfermask(struct ata_device *dev)
        if (xfer_mask & (0xF8 << ATA_SHIFT_UDMA))
                /* UDMA/44 or higher would be available */
                if ((ap->cbl == ATA_CBL_PATA40) ||
-                   (ata_drive_40wire(dev->id) &&
+                   (ata_is_40wire(dev) &&
                    (ap->cbl == ATA_CBL_PATA_UNK ||
                     ap->cbl == ATA_CBL_PATA80))) {
                        ata_dev_printk(dev, KERN_WARNING,
@@ -4689,6 +4652,43 @@ int ata_check_atapi_dma(struct ata_queued_cmd *qc)
        return 0;
 }
 
+/**
+ *     atapi_qc_may_overflow - Check whether data transfer may overflow
+ *     @qc: ATA command in question
+ *
+ *     ATAPI commands which transfer variable length data to host
+ *     might overflow due to application error or hardare bug.  This
+ *     function checks whether overflow should be drained and ignored
+ *     for @qc.
+ *
+ *     LOCKING:
+ *     None.
+ *
+ *     RETURNS:
+ *     1 if @qc may overflow; otherwise, 0.
+ */
+static int atapi_qc_may_overflow(struct ata_queued_cmd *qc)
+{
+       if (qc->tf.protocol != ATA_PROT_ATAPI &&
+           qc->tf.protocol != ATA_PROT_ATAPI_DMA)
+               return 0;
+
+       if (qc->tf.flags & ATA_TFLAG_WRITE)
+               return 0;
+
+       switch (qc->cdb[0]) {
+       case READ_10:
+       case READ_12:
+       case WRITE_10:
+       case WRITE_12:
+       case GPCMD_READ_CD:
+       case GPCMD_READ_CD_MSF:
+               return 0;
+       }
+
+       return 1;
+}
+
 /**
  *     ata_std_qc_defer - Check whether a qc needs to be deferred
  *     @qc: ATA command in question
@@ -5177,23 +5177,19 @@ static void atapi_send_cdb(struct ata_port *ap, struct ata_queued_cmd *qc)
  *     Inherited from caller.
  *
  */
-
-static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes)
+static int __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes)
 {
        int do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
-       struct scatterlist *sg = qc->__sg;
-       struct scatterlist *lsg = sg_last(qc->__sg, qc->n_elem);
        struct ata_port *ap = qc->ap;
+       struct ata_eh_info *ehi = &qc->dev->link->eh_info;
+       struct scatterlist *sg;
        struct page *page;
        unsigned char *buf;
        unsigned int offset, count;
-       int no_more_sg = 0;
-
-       if (qc->curbytes + bytes >= qc->nbytes)
-               ap->hsm_task_state = HSM_ST_LAST;
 
 next_sg:
-       if (unlikely(no_more_sg)) {
+       sg = qc->cursg;
+       if (unlikely(!sg)) {
                /*
                 * The end of qc->sg is reached and the device expects
                 * more data to transfer. In order not to overrun qc->sg
@@ -5202,21 +5198,28 @@ next_sg:
                 *    - for write case, padding zero data to the device
                 */
                u16 pad_buf[1] = { 0 };
-               unsigned int words = bytes >> 1;
                unsigned int i;
 
-               if (words) /* warning if bytes > 1 */
-                       ata_dev_printk(qc->dev, KERN_WARNING,
-                                      "%u bytes trailing data\n", bytes);
+               if (bytes > qc->curbytes - qc->nbytes + ATAPI_MAX_DRAIN) {
+                       ata_ehi_push_desc(ehi, "too much trailing data "
+                                         "buf=%u cur=%u bytes=%u",
+                                         qc->nbytes, qc->curbytes, bytes);
+                       return -1;
+               }
+
+                /* overflow is exptected for misc ATAPI commands */
+               if (bytes && !atapi_qc_may_overflow(qc))
+                       ata_dev_printk(qc->dev, KERN_WARNING, "ATAPI %u bytes "
+                                      "trailing data (cdb=%02x nbytes=%u)\n",
+                                      bytes, qc->cdb[0], qc->nbytes);
 
-               for (i = 0; i < words; i++)
+               for (i = 0; i < (bytes + 1) / 2; i++)
                        ap->ops->data_xfer(qc->dev, (unsigned char *)pad_buf, 2, do_write);
 
-               ap->hsm_task_state = HSM_ST_LAST;
-               return;
-       }
+               qc->curbytes += bytes;
 
-       sg = qc->cursg;
+               return 0;
+       }
 
        page = sg_page(sg);
        offset = sg->offset + qc->cursg_ofs;
@@ -5251,19 +5254,20 @@ next_sg:
        }
 
        bytes -= count;
+       if ((count & 1) && bytes)
+               bytes--;
        qc->curbytes += count;
        qc->cursg_ofs += count;
 
        if (qc->cursg_ofs == sg->length) {
-               if (qc->cursg == lsg)
-                       no_more_sg = 1;
-
                qc->cursg = sg_next(qc->cursg);
                qc->cursg_ofs = 0;
        }
 
        if (bytes)
                goto next_sg;
+
+       return 0;
 }
 
 /**
@@ -5306,7 +5310,8 @@ static void atapi_pio_bytes(struct ata_queued_cmd *qc)
 
        VPRINTK("ata%u: xfering %d bytes\n", ap->print_id, bytes);
 
-       __atapi_pio_bytes(qc, bytes);
+       if (__atapi_pio_bytes(qc, bytes))
+               goto err_out;
        ata_altstatus(ap); /* flush */
 
        return;
@@ -5453,11 +5458,19 @@ fsm_start:
                 * let the EH abort the command or reset the device.
                 */
                if (unlikely(status & (ATA_ERR | ATA_DF))) {
-                       ata_port_printk(ap, KERN_WARNING, "DRQ=1 with device "
-                                       "error, dev_stat 0x%X\n", status);
-                       qc->err_mask |= AC_ERR_HSM;
-                       ap->hsm_task_state = HSM_ST_ERR;
-                       goto fsm_start;
+                       /* Some ATAPI tape drives forget to clear the ERR bit
+                        * when doing the next command (mostly request sense).
+                        * We ignore ERR here to workaround and proceed sending
+                        * the CDB.
+                        */
+                       if (!(qc->dev->horkage & ATA_HORKAGE_STUCK_ERR)) {
+                               ata_port_printk(ap, KERN_WARNING,
+                                               "DRQ=1 with device error, "
+                                               "dev_stat 0x%X\n", status);
+                               qc->err_mask |= AC_ERR_HSM;
+                               ap->hsm_task_state = HSM_ST_ERR;
+                               goto fsm_start;
+                       }
                }
 
                /* Send the CDB (atapi) or the first data block (ata pio out).
@@ -6784,19 +6797,6 @@ static void ata_host_release(struct device *gendev, void *res)
        struct ata_host *host = dev_get_drvdata(gendev);
        int i;
 
-       for (i = 0; i < host->n_ports; i++) {
-               struct ata_port *ap = host->ports[i];
-
-               if (!ap)
-                       continue;
-
-               if ((host->flags & ATA_HOST_STARTED) && ap->ops->port_stop)
-                       ap->ops->port_stop(ap);
-       }
-
-       if ((host->flags & ATA_HOST_STARTED) && host->ops->host_stop)
-               host->ops->host_stop(host);
-
        for (i = 0; i < host->n_ports; i++) {
                struct ata_port *ap = host->ports[i];
 
@@ -6929,6 +6929,24 @@ struct ata_host *ata_host_alloc_pinfo(struct device *dev,
        return host;
 }
 
+static void ata_host_stop(struct device *gendev, void *res)
+{
+       struct ata_host *host = dev_get_drvdata(gendev);
+       int i;
+
+       WARN_ON(!(host->flags & ATA_HOST_STARTED));
+
+       for (i = 0; i < host->n_ports; i++) {
+               struct ata_port *ap = host->ports[i];
+
+               if (ap->ops->port_stop)
+                       ap->ops->port_stop(ap);
+       }
+
+       if (host->ops->host_stop)
+               host->ops->host_stop(host);
+}
+
 /**
  *     ata_host_start - start and freeze ports of an ATA host
  *     @host: ATA host to start ports for
@@ -6947,6 +6965,8 @@ struct ata_host *ata_host_alloc_pinfo(struct device *dev,
  */
 int ata_host_start(struct ata_host *host)
 {
+       int have_stop = 0;
+       void *start_dr = NULL;
        int i, rc;
 
        if (host->flags & ATA_HOST_STARTED)
@@ -6958,18 +6978,37 @@ int ata_host_start(struct ata_host *host)
                if (!host->ops && !ata_port_is_dummy(ap))
                        host->ops = ap->ops;
 
+               if (ap->ops->port_stop)
+                       have_stop = 1;
+       }
+
+       if (host->ops->host_stop)
+               have_stop = 1;
+
+       if (have_stop) {
+               start_dr = devres_alloc(ata_host_stop, 0, GFP_KERNEL);
+               if (!start_dr)
+                       return -ENOMEM;
+       }
+
+       for (i = 0; i < host->n_ports; i++) {
+               struct ata_port *ap = host->ports[i];
+
                if (ap->ops->port_start) {
                        rc = ap->ops->port_start(ap);
                        if (rc) {
-                               ata_port_printk(ap, KERN_ERR, "failed to "
-                                               "start port (errno=%d)\n", rc);
+                               if (rc != -ENODEV)
+                                       dev_printk(KERN_ERR, host->dev,
+                                               "failed to start port %d "
+                                               "(errno=%d)\n", i, rc);
                                goto err_out;
                        }
                }
-
                ata_eh_freeze_port(ap);
        }
 
+       if (start_dr)
+               devres_add(host->dev, start_dr);
        host->flags |= ATA_HOST_STARTED;
        return 0;
 
@@ -6980,6 +7019,7 @@ int ata_host_start(struct ata_host *host)
                if (ap->ops->port_stop)
                        ap->ops->port_stop(ap);
        }
+       devres_free(start_dr);
        return rc;
 }
 
@@ -7147,6 +7187,10 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
  *     request IRQ and register it.  This helper takes necessasry
  *     arguments and performs the three steps in one go.
  *
+ *     An invalid IRQ skips the IRQ registration and expects the host to
+ *     have set polling mode on the port. In this case, @irq_handler
+ *     should be NULL.
+ *
  *     LOCKING:
  *     Inherited from calling layer (may sleep).
  *
@@ -7163,6 +7207,12 @@ int ata_host_activate(struct ata_host *host, int irq,
        if (rc)
                return rc;
 
+       /* Special case for polling mode */
+       if (!irq) {
+               WARN_ON(irq_handler);
+               return ata_host_register(host, sht);
+       }
+
        rc = devm_request_irq(host->dev, irq, irq_handler, irq_flags,
                              dev_driver_string(host->dev), host);
        if (rc)
@@ -7206,18 +7256,14 @@ static void ata_port_detach(struct ata_port *ap)
 
        ata_port_wait_eh(ap);
 
-       /* EH is now guaranteed to see UNLOADING, so no new device
-        * will be attached.  Disable all existing devices.
+       /* EH is now guaranteed to see UNLOADING - EH context belongs
+        * to us.  Disable all existing devices.
         */
-       spin_lock_irqsave(ap->lock, flags);
-
        ata_port_for_each_link(link, ap) {
                ata_link_for_each_dev(dev, link)
                        ata_dev_disable(dev);
        }
 
-       spin_unlock_irqrestore(ap->lock, flags);
-
        /* Final freeze & EH.  All in-flight commands are aborted.  EH
         * will be skipped and retrials will be terminated with bad
         * target.
@@ -7249,6 +7295,9 @@ void ata_host_detach(struct ata_host *host)
 
        for (i = 0; i < host->n_ports; i++)
                ata_port_detach(host->ports[i]);
+
+       /* the host is dead now, dissociate ACPI */
+       ata_acpi_dissociate(host);
 }
 
 /**
@@ -7580,8 +7629,6 @@ EXPORT_SYMBOL_GPL(ata_dev_disable);
 EXPORT_SYMBOL_GPL(sata_set_spd);
 EXPORT_SYMBOL_GPL(sata_link_debounce);
 EXPORT_SYMBOL_GPL(sata_link_resume);
-EXPORT_SYMBOL_GPL(sata_phy_reset);
-EXPORT_SYMBOL_GPL(__sata_phy_reset);
 EXPORT_SYMBOL_GPL(ata_bus_reset);
 EXPORT_SYMBOL_GPL(ata_std_prereset);
 EXPORT_SYMBOL_GPL(ata_std_softreset);
@@ -7652,7 +7699,6 @@ EXPORT_SYMBOL_GPL(ata_port_desc);
 #ifdef CONFIG_PCI
 EXPORT_SYMBOL_GPL(ata_port_pbar_desc);
 #endif /* CONFIG_PCI */
-EXPORT_SYMBOL_GPL(ata_eng_timeout);
 EXPORT_SYMBOL_GPL(ata_port_schedule_eh);
 EXPORT_SYMBOL_GPL(ata_link_abort);
 EXPORT_SYMBOL_GPL(ata_port_abort);