[PATCH] OSS: replace kmalloc()+memset() combos with kzalloc()
[safe/jmp/linux-2.6] / drivers / ata / libata-core.c
index a927c4c..25d8d3f 100644 (file)
@@ -59,6 +59,9 @@
 
 #include "libata.h"
 
+#define DRV_VERSION    "2.10"  /* must be exactly four chars */
+
+
 /* debounce timing parameters in msecs { interval, duration, timeout } */
 const unsigned long sata_deb_timing_normal[]           = {   5,  100, 2000 };
 const unsigned long sata_deb_timing_hotplug[]          = {  25,  500, 2000 };
@@ -598,51 +601,7 @@ void ata_dev_disable(struct ata_device *dev)
 }
 
 /**
- *     ata_pio_devchk - PATA device presence detection
- *     @ap: ATA channel to examine
- *     @device: Device to examine (starting at zero)
- *
- *     This technique was originally described in
- *     Hale Landis's ATADRVR (www.ata-atapi.com), and
- *     later found its way into the ATA/ATAPI spec.
- *
- *     Write a pattern to the ATA shadow registers,
- *     and if a device is present, it will respond by
- *     correctly storing and echoing back the
- *     ATA shadow register contents.
- *
- *     LOCKING:
- *     caller.
- */
-
-static unsigned int ata_pio_devchk(struct ata_port *ap,
-                                  unsigned int device)
-{
-       struct ata_ioports *ioaddr = &ap->ioaddr;
-       u8 nsect, lbal;
-
-       ap->ops->dev_select(ap, device);
-
-       outb(0x55, ioaddr->nsect_addr);
-       outb(0xaa, ioaddr->lbal_addr);
-
-       outb(0xaa, ioaddr->nsect_addr);
-       outb(0x55, ioaddr->lbal_addr);
-
-       outb(0x55, ioaddr->nsect_addr);
-       outb(0xaa, ioaddr->lbal_addr);
-
-       nsect = inb(ioaddr->nsect_addr);
-       lbal = inb(ioaddr->lbal_addr);
-
-       if ((nsect == 0x55) && (lbal == 0xaa))
-               return 1;       /* we found a device */
-
-       return 0;               /* nothing found */
-}
-
-/**
- *     ata_mmio_devchk - PATA device presence detection
+ *     ata_devchk - PATA device presence detection
  *     @ap: ATA channel to examine
  *     @device: Device to examine (starting at zero)
  *
@@ -659,25 +618,24 @@ static unsigned int ata_pio_devchk(struct ata_port *ap,
  *     caller.
  */
 
-static unsigned int ata_mmio_devchk(struct ata_port *ap,
-                                   unsigned int device)
+static unsigned int ata_devchk(struct ata_port *ap, unsigned int device)
 {
        struct ata_ioports *ioaddr = &ap->ioaddr;
        u8 nsect, lbal;
 
        ap->ops->dev_select(ap, device);
 
-       writeb(0x55, (void __iomem *) ioaddr->nsect_addr);
-       writeb(0xaa, (void __iomem *) ioaddr->lbal_addr);
+       iowrite8(0x55, ioaddr->nsect_addr);
+       iowrite8(0xaa, ioaddr->lbal_addr);
 
-       writeb(0xaa, (void __iomem *) ioaddr->nsect_addr);
-       writeb(0x55, (void __iomem *) ioaddr->lbal_addr);
+       iowrite8(0xaa, ioaddr->nsect_addr);
+       iowrite8(0x55, ioaddr->lbal_addr);
 
-       writeb(0x55, (void __iomem *) ioaddr->nsect_addr);
-       writeb(0xaa, (void __iomem *) ioaddr->lbal_addr);
+       iowrite8(0x55, ioaddr->nsect_addr);
+       iowrite8(0xaa, ioaddr->lbal_addr);
 
-       nsect = readb((void __iomem *) ioaddr->nsect_addr);
-       lbal = readb((void __iomem *) ioaddr->lbal_addr);
+       nsect = ioread8(ioaddr->nsect_addr);
+       lbal = ioread8(ioaddr->lbal_addr);
 
        if ((nsect == 0x55) && (lbal == 0xaa))
                return 1;       /* we found a device */
@@ -686,27 +644,6 @@ static unsigned int ata_mmio_devchk(struct ata_port *ap,
 }
 
 /**
- *     ata_devchk - PATA device presence detection
- *     @ap: ATA channel to examine
- *     @device: Device to examine (starting at zero)
- *
- *     Dispatch ATA device presence detection, depending
- *     on whether we are using PIO or MMIO to talk to the
- *     ATA shadow registers.
- *
- *     LOCKING:
- *     caller.
- */
-
-static unsigned int ata_devchk(struct ata_port *ap,
-                                   unsigned int device)
-{
-       if (ap->flags & ATA_FLAG_MMIO)
-               return ata_mmio_devchk(ap, device);
-       return ata_pio_devchk(ap, device);
-}
-
-/**
  *     ata_dev_classify - determine device type based on ATA-spec signature
  *     @tf: ATA taskfile register set for device to be identified
  *
@@ -923,11 +860,7 @@ void ata_std_dev_select (struct ata_port *ap, unsigned int device)
        else
                tmp = ATA_DEVICE_OBS | ATA_DEV1;
 
-       if (ap->flags & ATA_FLAG_MMIO) {
-               writeb(tmp, (void __iomem *) ap->ioaddr.device_addr);
-       } else {
-               outb(tmp, ap->ioaddr.device_addr);
-       }
+       iowrite8(tmp, ap->ioaddr.device_addr);
        ata_pause(ap);          /* needed; also flushes, for mmio */
 }
 
@@ -1607,6 +1540,8 @@ int ata_dev_configure(struct ata_device *dev)
        const u16 *id = dev->id;
        unsigned int xfer_mask;
        char revbuf[7];         /* XYZ-99\0 */
+       char fwrevbuf[ATA_ID_FW_REV_LEN+1];
+       char modelbuf[ATA_ID_PROD_LEN+1];
        int rc;
 
        if (!ata_dev_enabled(dev) && ata_msg_info(ap)) {
@@ -1661,6 +1596,16 @@ int ata_dev_configure(struct ata_device *dev)
 
                dev->n_sectors = ata_id_n_sectors(id);
 
+               /* SCSI only uses 4-char revisions, dump full 8 chars from ATA */
+               ata_id_c_string(dev->id, fwrevbuf, ATA_ID_FW_REV,
+                               sizeof(fwrevbuf));
+
+               ata_id_c_string(dev->id, modelbuf, ATA_ID_PROD,
+                               sizeof(modelbuf));
+
+               if (dev->id[59] & 0x100)
+                       dev->multi_count = dev->id[59] & 0xff;
+
                if (ata_id_has_lba(id)) {
                        const char *lba_desc;
                        char ncq_desc[20];
@@ -1680,13 +1625,16 @@ int ata_dev_configure(struct ata_device *dev)
                        ata_dev_config_ncq(dev, ncq_desc, sizeof(ncq_desc));
 
                        /* print device info to dmesg */
-                       if (ata_msg_drv(ap) && print_info)
-                               ata_dev_printk(dev, KERN_INFO, "%s, "
-                                       "max %s, %Lu sectors: %s %s\n",
-                                       revbuf,
-                                       ata_mode_string(xfer_mask),
+                       if (ata_msg_drv(ap) && print_info) {
+                               ata_dev_printk(dev, KERN_INFO,
+                                       "%s: %s, %s, max %s\n",
+                                       revbuf, modelbuf, fwrevbuf,
+                                       ata_mode_string(xfer_mask));
+                               ata_dev_printk(dev, KERN_INFO,
+                                       "%Lu sectors, multi %u: %s %s\n",
                                        (unsigned long long)dev->n_sectors,
-                                       lba_desc, ncq_desc);
+                                       dev->multi_count, lba_desc, ncq_desc);
+                       }
                } else {
                        /* CHS */
 
@@ -1703,22 +1651,17 @@ int ata_dev_configure(struct ata_device *dev)
                        }
 
                        /* print device info to dmesg */
-                       if (ata_msg_drv(ap) && print_info)
-                               ata_dev_printk(dev, KERN_INFO, "%s, "
-                                       "max %s, %Lu sectors: CHS %u/%u/%u\n",
-                                       revbuf,
-                                       ata_mode_string(xfer_mask),
-                                       (unsigned long long)dev->n_sectors,
-                                       dev->cylinders, dev->heads,
-                                       dev->sectors);
-               }
-
-               if (dev->id[59] & 0x100) {
-                       dev->multi_count = dev->id[59] & 0xff;
-                       if (ata_msg_drv(ap) && print_info)
+                       if (ata_msg_drv(ap) && print_info) {
                                ata_dev_printk(dev, KERN_INFO,
-                                       "ata%u: dev %u multi count %u\n",
-                                       ap->id, dev->devno, dev->multi_count);
+                                       "%s: %s, %s, max %s\n",
+                                       revbuf, modelbuf, fwrevbuf,
+                                       ata_mode_string(xfer_mask));
+                               ata_dev_printk(dev, KERN_INFO, 
+                                       "%Lu sectors, multi %u, CHS %u/%u/%u\n",
+                                       (unsigned long long)dev->n_sectors,
+                                       dev->multi_count, dev->cylinders,
+                                       dev->heads, dev->sectors);
+                       }
                }
 
                dev->cdb_len = 16;
@@ -2390,6 +2333,10 @@ static int ata_dev_set_mode(struct ata_device *dev)
                dev->flags |= ATA_DFLAG_PIO;
 
        err_mask = ata_dev_set_xfermode(dev);
+       /* Old CFA may refuse this command, which is just fine */
+       if (dev->xfer_shift == ATA_SHIFT_PIO && ata_id_is_cfa(dev->id))
+               err_mask &= ~AC_ERR_DEV;
+
        if (err_mask) {
                ata_dev_printk(dev, KERN_ERR, "failed to set xfermode "
                               "(err_mask=0x%x)\n", err_mask);
@@ -2613,13 +2560,8 @@ static void ata_bus_post_reset(struct ata_port *ap, unsigned int devmask)
                u8 nsect, lbal;
 
                ap->ops->dev_select(ap, 1);
-               if (ap->flags & ATA_FLAG_MMIO) {
-                       nsect = readb((void __iomem *) ioaddr->nsect_addr);
-                       lbal = readb((void __iomem *) ioaddr->lbal_addr);
-               } else {
-                       nsect = inb(ioaddr->nsect_addr);
-                       lbal = inb(ioaddr->lbal_addr);
-               }
+               nsect = ioread8(ioaddr->nsect_addr);
+               lbal = ioread8(ioaddr->lbal_addr);
                if ((nsect == 1) && (lbal == 1))
                        break;
                if (time_after(jiffies, timeout)) {
@@ -2647,19 +2589,11 @@ static unsigned int ata_bus_softreset(struct ata_port *ap,
        DPRINTK("ata%u: bus reset via SRST\n", ap->id);
 
        /* software reset.  causes dev0 to be selected */
-       if (ap->flags & ATA_FLAG_MMIO) {
-               writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr);
-               udelay(20);     /* FIXME: flush */
-               writeb(ap->ctl | ATA_SRST, (void __iomem *) ioaddr->ctl_addr);
-               udelay(20);     /* FIXME: flush */
-               writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr);
-       } else {
-               outb(ap->ctl, ioaddr->ctl_addr);
-               udelay(10);
-               outb(ap->ctl | ATA_SRST, ioaddr->ctl_addr);
-               udelay(10);
-               outb(ap->ctl, ioaddr->ctl_addr);
-       }
+       iowrite8(ap->ctl, ioaddr->ctl_addr);
+       udelay(20);     /* FIXME: flush */
+       iowrite8(ap->ctl | ATA_SRST, ioaddr->ctl_addr);
+       udelay(20);     /* FIXME: flush */
+       iowrite8(ap->ctl, ioaddr->ctl_addr);
 
        /* spec mandates ">= 2ms" before checking status.
         * We wait 150ms, because that was the magic delay used for
@@ -2744,8 +2678,7 @@ void ata_bus_reset(struct ata_port *ap)
                ap->device[1].class = ata_dev_try_classify(ap, 1, &err);
 
        /* re-enable interrupts */
-       if (ap->ioaddr.ctl_addr)        /* FIXME: hack. create a hook instead */
-               ata_irq_on(ap);
+       ap->ops->irq_on(ap);
 
        /* is double-select really necessary? */
        if (ap->device[1].class != ATA_DEV_NONE)
@@ -2760,10 +2693,7 @@ void ata_bus_reset(struct ata_port *ap)
 
        if (ap->flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST)) {
                /* set up device control for ATA_FLAG_SATA_RESET */
-               if (ap->flags & ATA_FLAG_MMIO)
-                       writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr);
-               else
-                       outb(ap->ctl, ioaddr->ctl_addr);
+               iowrite8(ap->ctl, ioaddr->ctl_addr);
        }
 
        DPRINTK("EXIT\n");
@@ -3097,6 +3027,9 @@ int sata_std_hardreset(struct ata_port *ap, unsigned int *class)
                return 0;
        }
 
+       /* wait a while before checking status, see SRST for more info */
+       msleep(150);
+
        if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) {
                ata_port_printk(ap, KERN_ERR,
                                "COMRESET failed (device not ready)\n");
@@ -3137,11 +3070,8 @@ void ata_std_postreset(struct ata_port *ap, unsigned int *classes)
                sata_scr_write(ap, SCR_ERROR, serror);
 
        /* re-enable interrupts */
-       if (!ap->ops->error_handler) {
-               /* FIXME: hack. create a hook instead */
-               if (ap->ioaddr.ctl_addr)
-                       ata_irq_on(ap);
-       }
+       if (!ap->ops->error_handler)
+               ap->ops->irq_on(ap);
 
        /* is double-select really necessary? */
        if (classes[0] != ATA_DEV_NONE)
@@ -3156,12 +3086,8 @@ void ata_std_postreset(struct ata_port *ap, unsigned int *classes)
        }
 
        /* set up device control */
-       if (ap->ioaddr.ctl_addr) {
-               if (ap->flags & ATA_FLAG_MMIO)
-                       writeb(ap->ctl, (void __iomem *) ap->ioaddr.ctl_addr);
-               else
-                       outb(ap->ctl, ap->ioaddr.ctl_addr);
-       }
+       if (ap->ioaddr.ctl_addr)
+               iowrite8(ap->ctl, ap->ioaddr.ctl_addr);
 
        DPRINTK("EXIT\n");
 }
@@ -3877,53 +3803,7 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words)
 }
 
 /**
- *     ata_mmio_data_xfer - Transfer data by MMIO
- *     @adev: device for this I/O
- *     @buf: data buffer
- *     @buflen: buffer length
- *     @write_data: read/write
- *
- *     Transfer data from/to the device data register by MMIO.
- *
- *     LOCKING:
- *     Inherited from caller.
- */
-
-void ata_mmio_data_xfer(struct ata_device *adev, unsigned char *buf,
-                       unsigned int buflen, int write_data)
-{
-       struct ata_port *ap = adev->ap;
-       unsigned int i;
-       unsigned int words = buflen >> 1;
-       u16 *buf16 = (u16 *) buf;
-       void __iomem *mmio = (void __iomem *)ap->ioaddr.data_addr;
-
-       /* Transfer multiple of 2 bytes */
-       if (write_data) {
-               for (i = 0; i < words; i++)
-                       writew(le16_to_cpu(buf16[i]), mmio);
-       } else {
-               for (i = 0; i < words; i++)
-                       buf16[i] = cpu_to_le16(readw(mmio));
-       }
-
-       /* Transfer trailing 1 byte, if any. */
-       if (unlikely(buflen & 0x01)) {
-               u16 align_buf[1] = { 0 };
-               unsigned char *trailing_buf = buf + buflen - 1;
-
-               if (write_data) {
-                       memcpy(align_buf, trailing_buf, 1);
-                       writew(le16_to_cpu(align_buf[0]), mmio);
-               } else {
-                       align_buf[0] = cpu_to_le16(readw(mmio));
-                       memcpy(trailing_buf, align_buf, 1);
-               }
-       }
-}
-
-/**
- *     ata_pio_data_xfer - Transfer data by PIO
+ *     ata_data_xfer - Transfer data by PIO
  *     @adev: device to target
  *     @buf: data buffer
  *     @buflen: buffer length
@@ -3934,18 +3814,17 @@ void ata_mmio_data_xfer(struct ata_device *adev, unsigned char *buf,
  *     LOCKING:
  *     Inherited from caller.
  */
-
-void ata_pio_data_xfer(struct ata_device *adev, unsigned char *buf,
-                      unsigned int buflen, int write_data)
+void ata_data_xfer(struct ata_device *adev, unsigned char *buf,
+                  unsigned int buflen, int write_data)
 {
        struct ata_port *ap = adev->ap;
        unsigned int words = buflen >> 1;
 
        /* Transfer multiple of 2 bytes */
        if (write_data)
-               outsw(ap->ioaddr.data_addr, buf, words);
+               iowrite16_rep(ap->ioaddr.data_addr, buf, words);
        else
-               insw(ap->ioaddr.data_addr, buf, words);
+               ioread16_rep(ap->ioaddr.data_addr, buf, words);
 
        /* Transfer trailing 1 byte, if any. */
        if (unlikely(buflen & 0x01)) {
@@ -3954,16 +3833,16 @@ void ata_pio_data_xfer(struct ata_device *adev, unsigned char *buf,
 
                if (write_data) {
                        memcpy(align_buf, trailing_buf, 1);
-                       outw(le16_to_cpu(align_buf[0]), ap->ioaddr.data_addr);
+                       iowrite16(le16_to_cpu(align_buf[0]), ap->ioaddr.data_addr);
                } else {
-                       align_buf[0] = cpu_to_le16(inw(ap->ioaddr.data_addr));
+                       align_buf[0] = cpu_to_le16(ioread16(ap->ioaddr.data_addr));
                        memcpy(trailing_buf, align_buf, 1);
                }
        }
 }
 
 /**
- *     ata_pio_data_xfer_noirq - Transfer data by PIO
+ *     ata_data_xfer_noirq - Transfer data by PIO
  *     @adev: device to target
  *     @buf: data buffer
  *     @buflen: buffer length
@@ -3975,13 +3854,12 @@ void ata_pio_data_xfer(struct ata_device *adev, unsigned char *buf,
  *     LOCKING:
  *     Inherited from caller.
  */
-
-void ata_pio_data_xfer_noirq(struct ata_device *adev, unsigned char *buf,
-                                   unsigned int buflen, int write_data)
+void ata_data_xfer_noirq(struct ata_device *adev, unsigned char *buf,
+                        unsigned int buflen, int write_data)
 {
        unsigned long flags;
        local_irq_save(flags);
-       ata_pio_data_xfer(adev, buf, buflen, write_data);
+       ata_data_xfer(adev, buf, buflen, write_data);
        local_irq_restore(flags);
 }
 
@@ -4304,7 +4182,7 @@ static void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq)
                        qc = ata_qc_from_tag(ap, qc->tag);
                        if (qc) {
                                if (likely(!(qc->err_mask & AC_ERR_HSM))) {
-                                       ata_irq_on(ap);
+                                       ap->ops->irq_on(ap);
                                        ata_qc_complete(qc);
                                } else
                                        ata_port_freeze(ap);
@@ -4320,7 +4198,7 @@ static void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq)
        } else {
                if (in_wq) {
                        spin_lock_irqsave(ap->lock, flags);
-                       ata_irq_on(ap);
+                       ap->ops->irq_on(ap);
                        ata_qc_complete(qc);
                        spin_unlock_irqrestore(ap->lock, flags);
                } else
@@ -5145,7 +5023,7 @@ idle_irq:
 
 #ifdef ATA_IRQ_TRAP
        if ((ap->stats.idle_irq % 1000) == 0) {
-               ata_irq_ack(ap, 0); /* debug trap */
+               ap->ops->irq_ack(ap, 0); /* debug trap */
                ata_port_printk(ap, KERN_WARNING, "irq trap\n");
                return 1;
        }
@@ -5486,54 +5364,25 @@ void ata_host_resume(struct ata_host *host)
  *     LOCKING:
  *     Inherited from caller.
  */
-
-int ata_port_start (struct ata_port *ap)
+int ata_port_start(struct ata_port *ap)
 {
        struct device *dev = ap->dev;
        int rc;
 
-       ap->prd = dma_alloc_coherent(dev, ATA_PRD_TBL_SZ, &ap->prd_dma, GFP_KERNEL);
+       ap->prd = dmam_alloc_coherent(dev, ATA_PRD_TBL_SZ, &ap->prd_dma,
+                                     GFP_KERNEL);
        if (!ap->prd)
                return -ENOMEM;
 
        rc = ata_pad_alloc(ap, dev);
-       if (rc) {
-               dma_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma);
+       if (rc)
                return rc;
-       }
-
-       DPRINTK("prd alloc, virt %p, dma %llx\n", ap->prd, (unsigned long long) ap->prd_dma);
 
+       DPRINTK("prd alloc, virt %p, dma %llx\n", ap->prd,
+               (unsigned long long)ap->prd_dma);
        return 0;
 }
 
-
-/**
- *     ata_port_stop - Undo ata_port_start()
- *     @ap: Port to shut down
- *
- *     Frees the PRD table.
- *
- *     May be used as the port_stop() entry in ata_port_operations.
- *
- *     LOCKING:
- *     Inherited from caller.
- */
-
-void ata_port_stop (struct ata_port *ap)
-{
-       struct device *dev = ap->dev;
-
-       dma_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma);
-       ata_pad_free(ap, dev);
-}
-
-void ata_host_stop (struct ata_host *host)
-{
-       if (host->mmio_base)
-               iounmap(host->mmio_base);
-}
-
 /**
  *     ata_dev_init - Initialize an ata_device structure
  *     @dev: Device structure to initialize
@@ -5707,6 +5556,27 @@ static struct ata_port * ata_port_add(const struct ata_probe_ent *ent,
        return ap;
 }
 
+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 (ap->ops->port_stop)
+                       ap->ops->port_stop(ap);
+
+               scsi_host_put(ap->scsi_host);
+       }
+
+       if (host->ops->host_stop)
+               host->ops->host_stop(host);
+}
+
 /**
  *     ata_sas_host_init - Initialize a host struct
  *     @host:  host to initialize
@@ -5759,17 +5629,23 @@ int ata_device_add(const struct ata_probe_ent *ent)
                dev_printk(KERN_ERR, dev, "is not available: No interrupt assigned.\n");
                return 0;
        }
+
+       if (!devres_open_group(dev, ata_device_add, GFP_KERNEL))
+               return 0;
+
        /* alloc a container for our list of ATA ports (buses) */
-       host = kzalloc(sizeof(struct ata_host) +
-                      (ent->n_ports * sizeof(void *)), GFP_KERNEL);
+       host = devres_alloc(ata_host_release, sizeof(struct ata_host) +
+                           (ent->n_ports * sizeof(void *)), GFP_KERNEL);
        if (!host)
-               return 0;
+               goto err_out;
+       devres_add(dev, host);
+       dev_set_drvdata(dev, host);
 
        ata_host_init(host, dev, ent->_host_flags, ent->port_ops);
        host->n_ports = ent->n_ports;
        host->irq = ent->irq;
        host->irq2 = ent->irq2;
-       host->mmio_base = ent->mmio_base;
+       host->iomap = ent->iomap;
        host->private_data = ent->private_data;
 
        /* register each port bound to this device */
@@ -5807,8 +5683,8 @@ int ata_device_add(const struct ata_probe_ent *ent)
                                (ap->pio_mask << ATA_SHIFT_PIO);
 
                /* print per-port info to dmesg */
-               ata_port_printk(ap, KERN_INFO, "%cATA max %s cmd 0x%lX "
-                               "ctl 0x%lX bmdma 0x%lX irq %d\n",
+               ata_port_printk(ap, KERN_INFO, "%cATA max %s cmd 0x%p "
+                               "ctl 0x%p bmdma 0x%p irq %d\n",
                                ap->flags & ATA_FLAG_SATA ? 'S' : 'P',
                                ata_mode_string(xfer_mode_mask),
                                ap->ioaddr.cmd_addr,
@@ -5821,8 +5697,8 @@ int ata_device_add(const struct ata_probe_ent *ent)
        }
 
        /* obtain irq, that may be shared between channels */
-       rc = request_irq(ent->irq, ent->port_ops->irq_handler, ent->irq_flags,
-                        DRV_NAME, host);
+       rc = devm_request_irq(dev, ent->irq, ent->port_ops->irq_handler,
+                             ent->irq_flags, DRV_NAME, host);
        if (rc) {
                dev_printk(KERN_ERR, dev, "irq %lu request failed: %d\n",
                           ent->irq, rc);
@@ -5835,15 +5711,19 @@ int ata_device_add(const struct ata_probe_ent *ent)
                   so trap it now */
                BUG_ON(ent->irq == ent->irq2);
 
-               rc = request_irq(ent->irq2, ent->port_ops->irq_handler, ent->irq_flags,
-                        DRV_NAME, host);
+               rc = devm_request_irq(dev, ent->irq2,
+                               ent->port_ops->irq_handler, ent->irq_flags,
+                               DRV_NAME, host);
                if (rc) {
                        dev_printk(KERN_ERR, dev, "irq %lu request failed: %d\n",
                                   ent->irq2, rc);
-                       goto err_out_free_irq;
+                       goto err_out;
                }
        }
 
+       /* resource acquisition complete */
+       devres_remove_group(dev, ata_device_add);
+
        /* perform each probe synchronously */
        DPRINTK("probe begin\n");
        for (i = 0; i < host->n_ports; i++) {
@@ -5912,24 +5792,13 @@ int ata_device_add(const struct ata_probe_ent *ent)
                ata_scsi_scan_host(ap);
        }
 
-       dev_set_drvdata(dev, host);
-
        VPRINTK("EXIT, returning %u\n", ent->n_ports);
        return ent->n_ports; /* success */
 
-err_out_free_irq:
-       free_irq(ent->irq, host);
-err_out:
-       for (i = 0; i < host->n_ports; i++) {
-               struct ata_port *ap = host->ports[i];
-               if (ap) {
-                       ap->ops->port_stop(ap);
-                       scsi_host_put(ap->scsi_host);
-               }
-       }
-
-       kfree(host);
-       VPRINTK("EXIT, returning 0\n");
+ err_out:
+       devres_release_group(dev, ata_device_add);
+       dev_set_drvdata(dev, NULL);
+       VPRINTK("EXIT, returning %d\n", rc);
        return 0;
 }
 
@@ -6008,84 +5877,16 @@ void ata_host_detach(struct ata_host *host)
                ata_port_detach(host->ports[i]);
 }
 
-/**
- *     ata_host_remove - PCI layer callback for device removal
- *     @host: ATA host set that was removed
- *
- *     Unregister all objects associated with this host set. Free those
- *     objects.
- *
- *     LOCKING:
- *     Inherited from calling layer (may sleep).
- */
-
-void ata_host_remove(struct ata_host *host)
-{
-       unsigned int i;
-
-       ata_host_detach(host);
-
-       free_irq(host->irq, host);
-       if (host->irq2)
-               free_irq(host->irq2, host);
-
-       for (i = 0; i < host->n_ports; i++) {
-               struct ata_port *ap = host->ports[i];
-
-               ata_scsi_release(ap->scsi_host);
-
-               if ((ap->flags & ATA_FLAG_NO_LEGACY) == 0) {
-                       struct ata_ioports *ioaddr = &ap->ioaddr;
-
-                       /* FIXME: Add -ac IDE pci mods to remove these special cases */
-                       if (ioaddr->cmd_addr == ATA_PRIMARY_CMD)
-                               release_region(ATA_PRIMARY_CMD, 8);
-                       else if (ioaddr->cmd_addr == ATA_SECONDARY_CMD)
-                               release_region(ATA_SECONDARY_CMD, 8);
-               }
-
-               scsi_host_put(ap->scsi_host);
-       }
-
-       if (host->ops->host_stop)
-               host->ops->host_stop(host);
-
-       kfree(host);
-}
-
-/**
- *     ata_scsi_release - SCSI layer callback hook for host unload
- *     @shost: libata host to be unloaded
- *
- *     Performs all duties necessary to shut down a libata port...
- *     Kill port kthread, disable port, and release resources.
- *
- *     LOCKING:
- *     Inherited from SCSI layer.
- *
- *     RETURNS:
- *     One.
- */
-
-int ata_scsi_release(struct Scsi_Host *shost)
-{
-       struct ata_port *ap = ata_shost_to_port(shost);
-
-       DPRINTK("ENTER\n");
-
-       ap->ops->port_disable(ap);
-       ap->ops->port_stop(ap);
-
-       DPRINTK("EXIT\n");
-       return 1;
-}
-
 struct ata_probe_ent *
 ata_probe_ent_alloc(struct device *dev, const struct ata_port_info *port)
 {
        struct ata_probe_ent *probe_ent;
 
-       probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL);
+       /* XXX - the following if can go away once all LLDs are managed */
+       if (!list_empty(&dev->devres_head))
+               probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL);
+       else
+               probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL);
        if (!probe_ent) {
                printk(KERN_ERR DRV_NAME "(%s): out of memory\n",
                       kobject_name(&(dev->kobj)));
@@ -6135,37 +5936,23 @@ void ata_std_ports(struct ata_ioports *ioaddr)
 
 #ifdef CONFIG_PCI
 
-void ata_pci_host_stop (struct ata_host *host)
-{
-       struct pci_dev *pdev = to_pci_dev(host->dev);
-
-       pci_iounmap(pdev, host->mmio_base);
-}
-
 /**
  *     ata_pci_remove_one - PCI layer callback for device removal
  *     @pdev: PCI device that was removed
  *
- *     PCI layer indicates to libata via this hook that
- *     hot-unplug or module unload event has occurred.
- *     Handle this by unregistering all objects associated
- *     with this PCI device.  Free those objects.  Then finally
- *     release PCI resources and disable device.
+ *     PCI layer indicates to libata via this hook that hot-unplug or
+ *     module unload event has occurred.  Detach all ports.  Resource
+ *     release is handled via devres.
  *
  *     LOCKING:
  *     Inherited from PCI layer (may sleep).
  */
-
-void ata_pci_remove_one (struct pci_dev *pdev)
+void ata_pci_remove_one(struct pci_dev *pdev)
 {
        struct device *dev = pci_dev_to_dev(pdev);
        struct ata_host *host = dev_get_drvdata(dev);
 
-       ata_host_remove(host);
-
-       pci_release_regions(pdev);
-       pci_disable_device(pdev);
-       dev_set_drvdata(dev, NULL);
+       ata_host_detach(host);
 }
 
 /* move to PCI subsystem */
@@ -6219,7 +6006,7 @@ int ata_pci_device_do_resume(struct pci_dev *pdev)
        pci_set_power_state(pdev, PCI_D0);
        pci_restore_state(pdev);
 
-       rc = pci_enable_device(pdev);
+       rc = pcim_enable_device(pdev);
        if (rc) {
                dev_printk(KERN_ERR, &pdev->dev,
                           "failed to enable device after resume (%d)\n", rc);
@@ -6399,7 +6186,6 @@ EXPORT_SYMBOL_GPL(ata_std_ports);
 EXPORT_SYMBOL_GPL(ata_host_init);
 EXPORT_SYMBOL_GPL(ata_device_add);
 EXPORT_SYMBOL_GPL(ata_host_detach);
-EXPORT_SYMBOL_GPL(ata_host_remove);
 EXPORT_SYMBOL_GPL(ata_sg_init);
 EXPORT_SYMBOL_GPL(ata_sg_init_one);
 EXPORT_SYMBOL_GPL(ata_hsm_move);
@@ -6416,12 +6202,9 @@ EXPORT_SYMBOL_GPL(ata_check_status);
 EXPORT_SYMBOL_GPL(ata_altstatus);
 EXPORT_SYMBOL_GPL(ata_exec_command);
 EXPORT_SYMBOL_GPL(ata_port_start);
-EXPORT_SYMBOL_GPL(ata_port_stop);
-EXPORT_SYMBOL_GPL(ata_host_stop);
 EXPORT_SYMBOL_GPL(ata_interrupt);
-EXPORT_SYMBOL_GPL(ata_mmio_data_xfer);
-EXPORT_SYMBOL_GPL(ata_pio_data_xfer);
-EXPORT_SYMBOL_GPL(ata_pio_data_xfer_noirq);
+EXPORT_SYMBOL_GPL(ata_data_xfer);
+EXPORT_SYMBOL_GPL(ata_data_xfer_noirq);
 EXPORT_SYMBOL_GPL(ata_qc_prep);
 EXPORT_SYMBOL_GPL(ata_noop_qc_prep);
 EXPORT_SYMBOL_GPL(ata_bmdma_setup);
@@ -6458,7 +6241,6 @@ EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
 EXPORT_SYMBOL_GPL(ata_scsi_slave_config);
 EXPORT_SYMBOL_GPL(ata_scsi_slave_destroy);
 EXPORT_SYMBOL_GPL(ata_scsi_change_queue_depth);
-EXPORT_SYMBOL_GPL(ata_scsi_release);
 EXPORT_SYMBOL_GPL(ata_host_intr);
 EXPORT_SYMBOL_GPL(sata_scr_valid);
 EXPORT_SYMBOL_GPL(sata_scr_read);
@@ -6479,7 +6261,6 @@ EXPORT_SYMBOL_GPL(ata_timing_merge);
 
 #ifdef CONFIG_PCI
 EXPORT_SYMBOL_GPL(pci_test_config_bits);
-EXPORT_SYMBOL_GPL(ata_pci_host_stop);
 EXPORT_SYMBOL_GPL(ata_pci_init_native_mode);
 EXPORT_SYMBOL_GPL(ata_pci_init_one);
 EXPORT_SYMBOL_GPL(ata_pci_remove_one);
@@ -6503,3 +6284,7 @@ EXPORT_SYMBOL_GPL(ata_eh_thaw_port);
 EXPORT_SYMBOL_GPL(ata_eh_qc_complete);
 EXPORT_SYMBOL_GPL(ata_eh_qc_retry);
 EXPORT_SYMBOL_GPL(ata_do_eh);
+EXPORT_SYMBOL_GPL(ata_irq_on);
+EXPORT_SYMBOL_GPL(ata_dummy_irq_on);
+EXPORT_SYMBOL_GPL(ata_irq_ack);
+EXPORT_SYMBOL_GPL(ata_dummy_irq_ack);