static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
 static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
 static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc);
-static irqreturn_t ahci_interrupt (int irq, void *dev_instance);
 static void ahci_irq_clear(struct ata_port *ap);
 static int ahci_port_start(struct ata_port *ap);
 static void ahci_port_stop(struct ata_port *ap);
        .qc_prep                = ahci_qc_prep,
        .qc_issue               = ahci_qc_issue,
 
-       .irq_handler            = ahci_interrupt,
        .irq_clear              = ahci_irq_clear,
        .irq_on                 = ata_dummy_irq_on,
        .irq_ack                = ata_dummy_irq_ack,
        .qc_prep                = ahci_qc_prep,
        .qc_issue               = ahci_qc_issue,
 
-       .irq_handler            = ahci_interrupt,
        .irq_clear              = ahci_irq_clear,
        .irq_on                 = ata_dummy_irq_on,
        .irq_ack                = ata_dummy_irq_ack,
 static const struct ata_port_info ahci_port_info[] = {
        /* board_ahci */
        {
-               .sht            = &ahci_sht,
                .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
                                  ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
                                  ATA_FLAG_SKIP_D2H_BSY,
        },
        /* board_ahci_pi */
        {
-               .sht            = &ahci_sht,
                .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
                                  ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
                                  ATA_FLAG_SKIP_D2H_BSY | AHCI_FLAG_HONOR_PI,
        },
        /* board_ahci_vt8251 */
        {
-               .sht            = &ahci_sht,
                .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
                                  ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
                                  ATA_FLAG_SKIP_D2H_BSY |
        },
        /* board_ahci_ign_iferr */
        {
-               .sht            = &ahci_sht,
                .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
                                  ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
                                  ATA_FLAG_SKIP_D2H_BSY |
        return (cap & 0x1f) + 1;
 }
 
-static inline void __iomem *ahci_port_base(void __iomem *base,
-                                          unsigned int port)
+static inline void __iomem *ahci_port_base(struct ata_port *ap)
 {
-       return base + 0x100 + (port * 0x80);
+       void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
+
+       return mmio + 0x100 + (ap->port_no * 0x80);
 }
 
 /**
  *     ahci_save_initial_config - Save and fixup initial config values
- *     @probe_ent: probe_ent of target device
+ *     @pdev: target PCI device
+ *     @pi: associated ATA port info
+ *     @hpriv: host private area to store config values
  *
  *     Some registers containing configuration info might be setup by
  *     BIOS and might be cleared on reset.  This function saves the
  *     LOCKING:
  *     None.
  */
-static void ahci_save_initial_config(struct ata_probe_ent *probe_ent)
+static void ahci_save_initial_config(struct pci_dev *pdev,
+                                    const struct ata_port_info *pi,
+                                    struct ahci_host_priv *hpriv)
 {
-       struct ahci_host_priv *hpriv = probe_ent->private_data;
-       void __iomem *mmio = probe_ent->iomap[AHCI_PCI_BAR];
+       void __iomem *mmio = pcim_iomap_table(pdev)[AHCI_PCI_BAR];
        u32 cap, port_map;
        int i;
 
        /* fixup zero port_map */
        if (!port_map) {
                port_map = (1 << ahci_nr_ports(hpriv->cap)) - 1;
-               dev_printk(KERN_WARNING, probe_ent->dev,
+               dev_printk(KERN_WARNING, &pdev->dev,
                           "PORTS_IMPL is zero, forcing 0x%x\n", port_map);
 
                /* write the fixed up value to the PI register */
        }
 
        /* cross check port_map and cap.n_ports */
-       if (probe_ent->port_flags & AHCI_FLAG_HONOR_PI) {
+       if (pi->flags & AHCI_FLAG_HONOR_PI) {
                u32 tmp_port_map = port_map;
                int n_ports = ahci_nr_ports(cap);
 
                 * port_map is used to determine number of ports.
                 */
                if (n_ports || tmp_port_map)
-                       dev_printk(KERN_WARNING, probe_ent->dev,
+                       dev_printk(KERN_WARNING, &pdev->dev,
                                   "nr_ports (%u) and implemented port map "
                                   "(0x%x) don't match\n",
                                   ahci_nr_ports(cap), port_map);
 
 /**
  *     ahci_restore_initial_config - Restore initial config
- *     @mmio: MMIO base for the host
- *     @hpriv: host private data
+ *     @host: target ATA host
  *
  *     Restore initial config stored by ahci_save_initial_config().
  *
  *     LOCKING:
  *     None.
  */
-static void ahci_restore_initial_config(void __iomem *mmio,
-                                       struct ahci_host_priv *hpriv)
+static void ahci_restore_initial_config(struct ata_host *host)
 {
+       struct ahci_host_priv *hpriv = host->private_data;
+       void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
+
        writel(hpriv->saved_cap, mmio + HOST_CAP);
        writel(hpriv->saved_port_map, mmio + HOST_PORTS_IMPL);
        (void) readl(mmio + HOST_PORTS_IMPL);   /* flush */
        writel(val, ap->ioaddr.scr_addr + (sc_reg * 4));
 }
 
-static void ahci_start_engine(void __iomem *port_mmio)
+static void ahci_start_engine(struct ata_port *ap)
 {
+       void __iomem *port_mmio = ahci_port_base(ap);
        u32 tmp;
 
        /* start DMA */
        readl(port_mmio + PORT_CMD); /* flush */
 }
 
-static int ahci_stop_engine(void __iomem *port_mmio)
+static int ahci_stop_engine(struct ata_port *ap)
 {
+       void __iomem *port_mmio = ahci_port_base(ap);
        u32 tmp;
 
        tmp = readl(port_mmio + PORT_CMD);
        return 0;
 }
 
-static void ahci_start_fis_rx(void __iomem *port_mmio, u32 cap,
-                             dma_addr_t cmd_slot_dma, dma_addr_t rx_fis_dma)
+static void ahci_start_fis_rx(struct ata_port *ap)
 {
+       void __iomem *port_mmio = ahci_port_base(ap);
+       struct ahci_host_priv *hpriv = ap->host->private_data;
+       struct ahci_port_priv *pp = ap->private_data;
        u32 tmp;
 
        /* set FIS registers */
-       if (cap & HOST_CAP_64)
-               writel((cmd_slot_dma >> 16) >> 16, port_mmio + PORT_LST_ADDR_HI);
-       writel(cmd_slot_dma & 0xffffffff, port_mmio + PORT_LST_ADDR);
+       if (hpriv->cap & HOST_CAP_64)
+               writel((pp->cmd_slot_dma >> 16) >> 16,
+                      port_mmio + PORT_LST_ADDR_HI);
+       writel(pp->cmd_slot_dma & 0xffffffff, port_mmio + PORT_LST_ADDR);
 
-       if (cap & HOST_CAP_64)
-               writel((rx_fis_dma >> 16) >> 16, port_mmio + PORT_FIS_ADDR_HI);
-       writel(rx_fis_dma & 0xffffffff, port_mmio + PORT_FIS_ADDR);
+       if (hpriv->cap & HOST_CAP_64)
+               writel((pp->rx_fis_dma >> 16) >> 16,
+                      port_mmio + PORT_FIS_ADDR_HI);
+       writel(pp->rx_fis_dma & 0xffffffff, port_mmio + PORT_FIS_ADDR);
 
        /* enable FIS reception */
        tmp = readl(port_mmio + PORT_CMD);
        readl(port_mmio + PORT_CMD);
 }
 
-static int ahci_stop_fis_rx(void __iomem *port_mmio)
+static int ahci_stop_fis_rx(struct ata_port *ap)
 {
+       void __iomem *port_mmio = ahci_port_base(ap);
        u32 tmp;
 
        /* disable FIS reception */
        return 0;
 }
 
-static void ahci_power_up(void __iomem *port_mmio, u32 cap)
+static void ahci_power_up(struct ata_port *ap)
 {
+       struct ahci_host_priv *hpriv = ap->host->private_data;
+       void __iomem *port_mmio = ahci_port_base(ap);
        u32 cmd;
 
        cmd = readl(port_mmio + PORT_CMD) & ~PORT_CMD_ICC_MASK;
 
        /* spin up device */
-       if (cap & HOST_CAP_SSS) {
+       if (hpriv->cap & HOST_CAP_SSS) {
                cmd |= PORT_CMD_SPIN_UP;
                writel(cmd, port_mmio + PORT_CMD);
        }
 }
 
 #ifdef CONFIG_PM
-static void ahci_power_down(void __iomem *port_mmio, u32 cap)
+static void ahci_power_down(struct ata_port *ap)
 {
+       struct ahci_host_priv *hpriv = ap->host->private_data;
+       void __iomem *port_mmio = ahci_port_base(ap);
        u32 cmd, scontrol;
 
-       if (!(cap & HOST_CAP_SSS))
+       if (!(hpriv->cap & HOST_CAP_SSS))
                return;
 
        /* put device into listen mode, first set PxSCTL.DET to 0 */
 }
 #endif
 
-static void ahci_init_port(void __iomem *port_mmio, u32 cap,
-                          dma_addr_t cmd_slot_dma, dma_addr_t rx_fis_dma)
+static void ahci_init_port(struct ata_port *ap)
 {
        /* enable FIS reception */
-       ahci_start_fis_rx(port_mmio, cap, cmd_slot_dma, rx_fis_dma);
+       ahci_start_fis_rx(ap);
 
        /* enable DMA */
-       ahci_start_engine(port_mmio);
+       ahci_start_engine(ap);
 }
 
-static int ahci_deinit_port(void __iomem *port_mmio, u32 cap, const char **emsg)
+static int ahci_deinit_port(struct ata_port *ap, const char **emsg)
 {
        int rc;
 
        /* disable DMA */
-       rc = ahci_stop_engine(port_mmio);
+       rc = ahci_stop_engine(ap);
        if (rc) {
                *emsg = "failed to stop engine";
                return rc;
        }
 
        /* disable FIS reception */
-       rc = ahci_stop_fis_rx(port_mmio);
+       rc = ahci_stop_fis_rx(ap);
        if (rc) {
                *emsg = "failed stop FIS RX";
                return rc;
        return 0;
 }
 
-static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev,
-                                struct ahci_host_priv *hpriv)
+static int ahci_reset_controller(struct ata_host *host)
 {
+       struct pci_dev *pdev = to_pci_dev(host->dev);
+       void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
        u32 tmp;
 
        /* global controller reset */
 
        tmp = readl(mmio + HOST_CTL);
        if (tmp & HOST_RESET) {
-               dev_printk(KERN_ERR, &pdev->dev,
+               dev_printk(KERN_ERR, host->dev,
                           "controller reset failed (0x%x)\n", tmp);
                return -EIO;
        }
        (void) readl(mmio + HOST_CTL);  /* flush */
 
        /* some registers might be cleared on reset.  restore initial values */
-       ahci_restore_initial_config(mmio, hpriv);
+       ahci_restore_initial_config(host);
 
        if (pdev->vendor == PCI_VENDOR_ID_INTEL) {
                u16 tmp16;
        return 0;
 }
 
-static void ahci_init_controller(void __iomem *mmio, struct pci_dev *pdev,
-                                int n_ports, unsigned int port_flags,
-                                struct ahci_host_priv *hpriv)
+static void ahci_init_controller(struct ata_host *host)
 {
+       struct pci_dev *pdev = to_pci_dev(host->dev);
+       void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
        int i, rc;
        u32 tmp;
 
-       for (i = 0; i < n_ports; i++) {
-               void __iomem *port_mmio = ahci_port_base(mmio, i);
+       for (i = 0; i < host->n_ports; i++) {
+               struct ata_port *ap = host->ports[i];
+               void __iomem *port_mmio = ahci_port_base(ap);
                const char *emsg = NULL;
 
-               if ((port_flags & AHCI_FLAG_HONOR_PI) &&
-                   !(hpriv->port_map & (1 << i)))
+               if (ata_port_is_dummy(ap))
                        continue;
 
                /* make sure port is not active */
-               rc = ahci_deinit_port(port_mmio, hpriv->cap, &emsg);
+               rc = ahci_deinit_port(ap, &emsg);
                if (rc)
                        dev_printk(KERN_WARNING, &pdev->dev,
                                   "%s (%d)\n", emsg, rc);
 
 static unsigned int ahci_dev_classify(struct ata_port *ap)
 {
-       void __iomem *port_mmio = ap->ioaddr.cmd_addr;
+       void __iomem *port_mmio = ahci_port_base(ap);
        struct ata_taskfile tf;
        u32 tmp;
 
 static int ahci_softreset(struct ata_port *ap, unsigned int *class)
 {
        struct ahci_port_priv *pp = ap->private_data;
-       void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
-       void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
+       void __iomem *port_mmio = ahci_port_base(ap);
        const u32 cmd_fis_len = 5; /* five dwords */
        const char *reason = NULL;
        struct ata_taskfile tf;
        }
 
        /* prepare for SRST (AHCI-1.1 10.4.1) */
-       rc = ahci_stop_engine(port_mmio);
+       rc = ahci_stop_engine(ap);
        if (rc) {
                reason = "failed to stop engine";
                goto fail_restart;
        }
 
        /* restart engine */
-       ahci_start_engine(port_mmio);
+       ahci_start_engine(ap);
 
        ata_tf_init(ap->device, &tf);
        fis = pp->cmd_tbl;
        return 0;
 
  fail_restart:
-       ahci_start_engine(port_mmio);
+       ahci_start_engine(ap);
  fail:
        ata_port_printk(ap, KERN_ERR, "softreset failed (%s)\n", reason);
        return rc;
        struct ahci_port_priv *pp = ap->private_data;
        u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
        struct ata_taskfile tf;
-       void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
-       void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
        int rc;
 
        DPRINTK("ENTER\n");
 
-       ahci_stop_engine(port_mmio);
+       ahci_stop_engine(ap);
 
        /* clear D2H reception area to properly wait for D2H FIS */
        ata_tf_init(ap->device, &tf);
 
        rc = sata_std_hardreset(ap, class);
 
-       ahci_start_engine(port_mmio);
+       ahci_start_engine(ap);
 
        if (rc == 0 && ata_port_online(ap))
                *class = ahci_dev_classify(ap);
 
 static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class)
 {
-       void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
-       void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
        int rc;
 
        DPRINTK("ENTER\n");
 
-       ahci_stop_engine(port_mmio);
+       ahci_stop_engine(ap);
 
        rc = sata_port_hardreset(ap, sata_ehc_deb_timing(&ap->eh_context));
 
        /* vt8251 needs SError cleared for the port to operate */
        ahci_scr_write(ap, SCR_ERROR, ahci_scr_read(ap, SCR_ERROR));
 
-       ahci_start_engine(port_mmio);
+       ahci_start_engine(ap);
 
        DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class);
 
 
 static void ahci_postreset(struct ata_port *ap, unsigned int *class)
 {
-       void __iomem *port_mmio = ap->ioaddr.cmd_addr;
+       void __iomem *port_mmio = ahci_port_base(ap);
        u32 new_tmp, tmp;
 
        ata_std_postreset(ap, class);
 
 static void ahci_host_intr(struct ata_port *ap)
 {
-       void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
-       void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
+       void __iomem *port_mmio = ap->ioaddr.cmd_addr;
        struct ata_eh_info *ehi = &ap->eh_info;
        struct ahci_port_priv *pp = ap->private_data;
        u32 status, qc_active;
 static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
-       void __iomem *port_mmio = ap->ioaddr.cmd_addr;
+       void __iomem *port_mmio = ahci_port_base(ap);
 
        if (qc->tf.protocol == ATA_PROT_NCQ)
                writel(1 << qc->tag, port_mmio + PORT_SCR_ACT);
 
 static void ahci_freeze(struct ata_port *ap)
 {
-       void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
-       void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
+       void __iomem *port_mmio = ahci_port_base(ap);
 
        /* turn IRQ off */
        writel(0, port_mmio + PORT_IRQ_MASK);
 static void ahci_thaw(struct ata_port *ap)
 {
        void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
-       void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
+       void __iomem *port_mmio = ahci_port_base(ap);
        u32 tmp;
 
        /* clear IRQ */
 
 static void ahci_error_handler(struct ata_port *ap)
 {
-       void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
-       void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
-
        if (!(ap->pflags & ATA_PFLAG_FROZEN)) {
                /* restart engine */
-               ahci_stop_engine(port_mmio);
-               ahci_start_engine(port_mmio);
+               ahci_stop_engine(ap);
+               ahci_start_engine(ap);
        }
 
        /* perform recovery */
 
 static void ahci_vt8251_error_handler(struct ata_port *ap)
 {
-       void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
-       void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
-
        if (!(ap->pflags & ATA_PFLAG_FROZEN)) {
                /* restart engine */
-               ahci_stop_engine(port_mmio);
-               ahci_start_engine(port_mmio);
+               ahci_stop_engine(ap);
+               ahci_start_engine(ap);
        }
 
        /* perform recovery */
 static void ahci_post_internal_cmd(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
-       void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
-       void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
 
        if (qc->flags & ATA_QCFLAG_FAILED) {
                /* make DMA engine forget about the failed command */
-               ahci_stop_engine(port_mmio);
-               ahci_start_engine(port_mmio);
+               ahci_stop_engine(ap);
+               ahci_start_engine(ap);
        }
 }
 
 #ifdef CONFIG_PM
 static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg)
 {
-       struct ahci_host_priv *hpriv = ap->host->private_data;
-       struct ahci_port_priv *pp = ap->private_data;
-       void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
-       void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
        const char *emsg = NULL;
        int rc;
 
-       rc = ahci_deinit_port(port_mmio, hpriv->cap, &emsg);
+       rc = ahci_deinit_port(ap, &emsg);
        if (rc == 0)
-               ahci_power_down(port_mmio, hpriv->cap);
+               ahci_power_down(ap);
        else {
                ata_port_printk(ap, KERN_ERR, "%s (%d)\n", emsg, rc);
-               ahci_init_port(port_mmio, hpriv->cap,
-                              pp->cmd_slot_dma, pp->rx_fis_dma);
+               ahci_init_port(ap);
        }
 
        return rc;
 
 static int ahci_port_resume(struct ata_port *ap)
 {
-       struct ahci_port_priv *pp = ap->private_data;
-       struct ahci_host_priv *hpriv = ap->host->private_data;
-       void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
-       void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
-
-       ahci_power_up(port_mmio, hpriv->cap);
-       ahci_init_port(port_mmio, hpriv->cap, pp->cmd_slot_dma, pp->rx_fis_dma);
+       ahci_power_up(ap);
+       ahci_init_port(ap);
 
        return 0;
 }
 static int ahci_pci_device_resume(struct pci_dev *pdev)
 {
        struct ata_host *host = dev_get_drvdata(&pdev->dev);
-       struct ahci_host_priv *hpriv = host->private_data;
-       void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
        int rc;
 
        rc = ata_pci_device_do_resume(pdev);
                return rc;
 
        if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) {
-               rc = ahci_reset_controller(mmio, pdev, hpriv);
+               rc = ahci_reset_controller(host);
                if (rc)
                        return rc;
 
-               ahci_init_controller(mmio, pdev, host->n_ports,
-                                    host->ports[0]->flags, hpriv);
+               ahci_init_controller(host);
        }
 
        ata_host_resume(host);
 static int ahci_port_start(struct ata_port *ap)
 {
        struct device *dev = ap->host->dev;
-       struct ahci_host_priv *hpriv = ap->host->private_data;
        struct ahci_port_priv *pp;
-       void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
-       void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
        void *mem;
        dma_addr_t mem_dma;
        int rc;
        ap->private_data = pp;
 
        /* power up port */
-       ahci_power_up(port_mmio, hpriv->cap);
+       ahci_power_up(ap);
 
        /* initialize port */
-       ahci_init_port(port_mmio, hpriv->cap, pp->cmd_slot_dma, pp->rx_fis_dma);
+       ahci_init_port(ap);
 
        return 0;
 }
 
 static void ahci_port_stop(struct ata_port *ap)
 {
-       struct ahci_host_priv *hpriv = ap->host->private_data;
-       void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
-       void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
        const char *emsg = NULL;
        int rc;
 
        /* de-initialize port */
-       rc = ahci_deinit_port(port_mmio, hpriv->cap, &emsg);
+       rc = ahci_deinit_port(ap, &emsg);
        if (rc)
                ata_port_printk(ap, KERN_WARNING, "%s (%d)\n", emsg, rc);
 }
 
-static void ahci_setup_port(struct ata_ioports *port, void __iomem *base,
-                           unsigned int port_idx)
+static int ahci_configure_dma_masks(struct pci_dev *pdev, int using_dac)
 {
-       VPRINTK("ENTER, base==0x%lx, port_idx %u\n", base, port_idx);
-       base = ahci_port_base(base, port_idx);
-       VPRINTK("base now==0x%lx\n", base);
-
-       port->cmd_addr          = base;
-       port->scr_addr          = base + PORT_SCR;
-
-       VPRINTK("EXIT\n");
-}
-
-static int ahci_host_init(struct ata_probe_ent *probe_ent)
-{
-       struct ahci_host_priv *hpriv = probe_ent->private_data;
-       struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
-       void __iomem *mmio = probe_ent->iomap[AHCI_PCI_BAR];
-       unsigned int i, using_dac;
        int rc;
 
-       rc = ahci_reset_controller(mmio, pdev, hpriv);
-       if (rc)
-               return rc;
-
-       probe_ent->n_ports = fls(hpriv->port_map);
-       probe_ent->dummy_port_mask = ~hpriv->port_map;
-
-       VPRINTK("cap 0x%x  port_map 0x%x  n_ports %d\n",
-               hpriv->cap, hpriv->port_map, probe_ent->n_ports);
-
-       using_dac = hpriv->cap & HOST_CAP_64;
        if (using_dac &&
            !pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
                rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
                        return rc;
                }
        }
-
-       for (i = 0; i < probe_ent->n_ports; i++)
-               ahci_setup_port(&probe_ent->port[i], mmio, i);
-
-       ahci_init_controller(mmio, pdev, probe_ent->n_ports,
-                            probe_ent->port_flags, hpriv);
-
-       pci_set_master(pdev);
-
        return 0;
 }
 
-static void ahci_print_info(struct ata_probe_ent *probe_ent)
+static void ahci_print_info(struct ata_host *host)
 {
-       struct ahci_host_priv *hpriv = probe_ent->private_data;
-       struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
-       void __iomem *mmio = probe_ent->iomap[AHCI_PCI_BAR];
+       struct ahci_host_priv *hpriv = host->private_data;
+       struct pci_dev *pdev = to_pci_dev(host->dev);
+       void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
        u32 vers, cap, impl, speed;
        const char *speed_s;
        u16 cc;
 static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int printed_version;
-       unsigned int board_idx = (unsigned int) ent->driver_data;
+       struct ata_port_info pi = ahci_port_info[ent->driver_data];
+       const struct ata_port_info *ppi[] = { &pi, NULL };
        struct device *dev = &pdev->dev;
-       struct ata_probe_ent *probe_ent;
        struct ahci_host_priv *hpriv;
-       int rc;
+       struct ata_host *host;
+       int i, rc;
 
        VPRINTK("ENTER\n");
 
        if (!printed_version++)
                dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
 
+       /* acquire resources */
        rc = pcim_enable_device(pdev);
        if (rc)
                return rc;
        if (pci_enable_msi(pdev))
                pci_intx(pdev, 1);
 
-       probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL);
-       if (probe_ent == NULL)
-               return -ENOMEM;
-
-       probe_ent->dev = pci_dev_to_dev(pdev);
-       INIT_LIST_HEAD(&probe_ent->node);
-
        hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
        if (!hpriv)
                return -ENOMEM;
 
-       probe_ent->sht          = ahci_port_info[board_idx].sht;
-       probe_ent->port_flags   = ahci_port_info[board_idx].flags;
-       probe_ent->pio_mask     = ahci_port_info[board_idx].pio_mask;
-       probe_ent->udma_mask    = ahci_port_info[board_idx].udma_mask;
-       probe_ent->port_ops     = ahci_port_info[board_idx].port_ops;
+       /* save initial config */
+       ahci_save_initial_config(pdev, &pi, hpriv);
 
-               probe_ent->irq = pdev->irq;
-               probe_ent->irq_flags = IRQF_SHARED;
-       probe_ent->iomap = pcim_iomap_table(pdev);
-       probe_ent->private_data = hpriv;
+       /* prepare host */
+       if (!(pi.flags & AHCI_FLAG_NO_NCQ) && (hpriv->cap & HOST_CAP_NCQ))
+               pi.flags |= ATA_FLAG_NCQ;
 
-       /* initialize adapter */
-       ahci_save_initial_config(probe_ent);
+       host = ata_host_alloc_pinfo(&pdev->dev, ppi, fls(hpriv->port_map));
+       if (!host)
+               return -ENOMEM;
+       host->iomap = pcim_iomap_table(pdev);
+       host->private_data = hpriv;
+
+       for (i = 0; i < host->n_ports; i++) {
+               if (hpriv->port_map & (1 << i)) {
+                       struct ata_port *ap = host->ports[i];
+                       void __iomem *port_mmio = ahci_port_base(ap);
+
+                       ap->ioaddr.cmd_addr = port_mmio;
+                       ap->ioaddr.scr_addr = port_mmio + PORT_SCR;
+               } else
+                       host->ports[i]->ops = &ata_dummy_port_ops;
+       }
 
-       rc = ahci_host_init(probe_ent);
+       /* initialize adapter */
+       rc = ahci_configure_dma_masks(pdev, hpriv->cap & HOST_CAP_64);
        if (rc)
                return rc;
 
-       if (!(probe_ent->port_flags & AHCI_FLAG_NO_NCQ) &&
-           (hpriv->cap & HOST_CAP_NCQ))
-               probe_ent->port_flags |= ATA_FLAG_NCQ;
-
-       ahci_print_info(probe_ent);
+       rc = ahci_reset_controller(host);
+       if (rc)
+               return rc;
 
-       if (!ata_device_add(probe_ent))
-               return -ENODEV;
+       ahci_init_controller(host);
+       ahci_print_info(host);
 
-       devm_kfree(dev, probe_ent);
-       return 0;
+       pci_set_master(pdev);
+       return ata_host_activate(host, pdev->irq, ahci_interrupt, IRQF_SHARED,
+                                &ahci_sht);
 }
 
 static int __init ahci_init(void)
 
        .bmdma_stop             = inic_bmdma_stop,
        .bmdma_status           = inic_bmdma_status,
 
-       .irq_handler            = inic_interrupt,
        .irq_clear              = inic_irq_clear,
        .irq_on                 = ata_irq_on,
        .irq_ack                = ata_irq_ack,
 };
 
 static struct ata_port_info inic_port_info = {
-       .sht                    = &inic_sht,
        /* For some reason, ATA_PROT_ATAPI is broken on this
         * controller, and no, PIO_POLLING does't fix it.  It somehow
         * manages to report the wrong ireason and ignoring ireason
 static int inic_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int printed_version;
-       struct ata_port_info *pinfo = &inic_port_info;
-       struct ata_probe_ent *probe_ent;
+       const struct ata_port_info *ppi[] = { &inic_port_info, NULL };
+       struct ata_host *host;
        struct inic_host_priv *hpriv;
        void __iomem * const *iomap;
        int i, rc;
        if (!printed_version++)
                dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
 
+       /* alloc host */
+       host = ata_host_alloc_pinfo(&pdev->dev, ppi, NR_PORTS);
+       hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL);
+       if (!host || !hpriv)
+               return -ENOMEM;
+
+       host->private_data = hpriv;
+
+       /* acquire resources and fill host */
        rc = pcim_enable_device(pdev);
        if (rc)
                return rc;
        rc = pcim_iomap_regions(pdev, 0x3f, DRV_NAME);
        if (rc)
                return rc;
-       iomap = pcim_iomap_table(pdev);
+       host->iomap = iomap = pcim_iomap_table(pdev);
+
+       for (i = 0; i < NR_PORTS; i++) {
+               struct ata_ioports *port = &host->ports[i]->ioaddr;
+               void __iomem *port_base = iomap[MMIO_BAR] + i * PORT_SIZE;
+
+               port->cmd_addr = iomap[2 * i];
+               port->altstatus_addr =
+               port->ctl_addr = (void __iomem *)
+                       ((unsigned long)iomap[2 * i + 1] | ATA_PCI_CTL_OFS);
+               port->scr_addr = port_base + PORT_SCR;
+
+               ata_std_ports(port);
+       }
+
+       hpriv->cached_hctl = readw(iomap[MMIO_BAR] + HOST_CTL);
 
        /* Set dma_mask.  This devices doesn't support 64bit addressing. */
        rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
                return rc;
        }
 
-       probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL);
-       hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL);
-       if (!probe_ent || !hpriv)
-               return -ENOMEM;
-
-       probe_ent->dev = &pdev->dev;
-       INIT_LIST_HEAD(&probe_ent->node);
-
-       probe_ent->sht                  = pinfo->sht;
-       probe_ent->port_flags           = pinfo->flags;
-       probe_ent->pio_mask             = pinfo->pio_mask;
-       probe_ent->mwdma_mask           = pinfo->mwdma_mask;
-       probe_ent->udma_mask            = pinfo->udma_mask;
-       probe_ent->port_ops             = pinfo->port_ops;
-       probe_ent->n_ports              = NR_PORTS;
-
-       probe_ent->irq = pdev->irq;
-       probe_ent->irq_flags = IRQF_SHARED;
-
-       probe_ent->iomap = iomap;
-
-       for (i = 0; i < NR_PORTS; i++) {
-               struct ata_ioports *port = &probe_ent->port[i];
-               void __iomem *port_base = iomap[MMIO_BAR] + i * PORT_SIZE;
-
-               port->cmd_addr = iomap[2 * i];
-               port->altstatus_addr =
-               port->ctl_addr = (void __iomem *)
-                       ((unsigned long)iomap[2 * i + 1] | ATA_PCI_CTL_OFS);
-               port->scr_addr = port_base + PORT_SCR;
-
-               ata_std_ports(port);
-       }
-
-       probe_ent->private_data = hpriv;
-       hpriv->cached_hctl = readw(iomap[MMIO_BAR] + HOST_CTL);
-
        rc = init_controller(iomap[MMIO_BAR], hpriv->cached_hctl);
        if (rc) {
                dev_printk(KERN_ERR, &pdev->dev,
        }
 
        pci_set_master(pdev);
-
-       if (!ata_device_add(probe_ent))
-               return -ENODEV;
-
-       devm_kfree(&pdev->dev, probe_ent);
-
-       return 0;
+       return ata_host_activate(host, pdev->irq, inic_interrupt, IRQF_SHARED,
+                                &inic_sht);
 }
 
 static const struct pci_device_id inic_pci_tbl[] = {
 
 static void mv_qc_prep(struct ata_queued_cmd *qc);
 static void mv_qc_prep_iie(struct ata_queued_cmd *qc);
 static unsigned int mv_qc_issue(struct ata_queued_cmd *qc);
-static irqreturn_t mv_interrupt(int irq, void *dev_instance);
 static void mv_eng_timeout(struct ata_port *ap);
 static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
 
 
        .eng_timeout            = mv_eng_timeout,
 
-       .irq_handler            = mv_interrupt,
        .irq_clear              = mv_irq_clear,
        .irq_on                 = ata_irq_on,
        .irq_ack                = ata_irq_ack,
 
        .eng_timeout            = mv_eng_timeout,
 
-       .irq_handler            = mv_interrupt,
        .irq_clear              = mv_irq_clear,
        .irq_on                 = ata_irq_on,
        .irq_ack                = ata_irq_ack,
 
        .eng_timeout            = mv_eng_timeout,
 
-       .irq_handler            = mv_interrupt,
        .irq_clear              = mv_irq_clear,
        .irq_on                 = ata_irq_on,
        .irq_ack                = ata_irq_ack,
 
 static const struct ata_port_info mv_port_info[] = {
        {  /* chip_504x */
-               .sht            = &mv_sht,
                .flags          = MV_COMMON_FLAGS,
                .pio_mask       = 0x1f, /* pio0-4 */
                .udma_mask      = 0x7f, /* udma0-6 */
                .port_ops       = &mv5_ops,
        },
        {  /* chip_508x */
-               .sht            = &mv_sht,
                .flags          = (MV_COMMON_FLAGS | MV_FLAG_DUAL_HC),
                .pio_mask       = 0x1f, /* pio0-4 */
                .udma_mask      = 0x7f, /* udma0-6 */
                .port_ops       = &mv5_ops,
        },
        {  /* chip_5080 */
-               .sht            = &mv_sht,
                .flags          = (MV_COMMON_FLAGS | MV_FLAG_DUAL_HC),
                .pio_mask       = 0x1f, /* pio0-4 */
                .udma_mask      = 0x7f, /* udma0-6 */
                .port_ops       = &mv5_ops,
        },
        {  /* chip_604x */
-               .sht            = &mv_sht,
                .flags          = (MV_COMMON_FLAGS | MV_6XXX_FLAGS),
                .pio_mask       = 0x1f, /* pio0-4 */
                .udma_mask      = 0x7f, /* udma0-6 */
                .port_ops       = &mv6_ops,
        },
        {  /* chip_608x */
-               .sht            = &mv_sht,
                .flags          = (MV_COMMON_FLAGS | MV_6XXX_FLAGS |
                                   MV_FLAG_DUAL_HC),
                .pio_mask       = 0x1f, /* pio0-4 */
                .port_ops       = &mv6_ops,
        },
        {  /* chip_6042 */
-               .sht            = &mv_sht,
                .flags          = (MV_COMMON_FLAGS | MV_6XXX_FLAGS),
                .pio_mask       = 0x1f, /* pio0-4 */
                .udma_mask      = 0x7f, /* udma0-6 */
                .port_ops       = &mv_iie_ops,
        },
        {  /* chip_7042 */
-               .sht            = &mv_sht,
                .flags          = (MV_COMMON_FLAGS | MV_6XXX_FLAGS),
                .pio_mask       = 0x1f, /* pio0-4 */
                .udma_mask      = 0x7f, /* udma0-6 */
                readl(port_mmio + EDMA_ERR_IRQ_MASK_OFS));
 }
 
-static int mv_chip_id(struct pci_dev *pdev, struct mv_host_priv *hpriv,
-                     unsigned int board_idx)
+static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
 {
+       struct pci_dev *pdev = to_pci_dev(host->dev);
+       struct mv_host_priv *hpriv = host->private_data;
        u8 rev_id;
        u32 hp_flags = hpriv->hp_flags;
 
 
 /**
  *      mv_init_host - Perform some early initialization of the host.
- *     @pdev: host PCI device
- *      @probe_ent: early data struct representing the host
+ *     @host: ATA host to initialize
+ *      @board_idx: controller index
  *
  *      If possible, do an early global reset of the host.  Then do
  *      our port init and clear/unmask all/relevant host interrupts.
  *      LOCKING:
  *      Inherited from caller.
  */
-static int mv_init_host(struct pci_dev *pdev, struct ata_probe_ent *probe_ent,
-                       unsigned int board_idx)
+static int mv_init_host(struct ata_host *host, unsigned int board_idx)
 {
        int rc = 0, n_hc, port, hc;
-       void __iomem *mmio = probe_ent->iomap[MV_PRIMARY_BAR];
-       struct mv_host_priv *hpriv = probe_ent->private_data;
+       struct pci_dev *pdev = to_pci_dev(host->dev);
+       void __iomem *mmio = host->iomap[MV_PRIMARY_BAR];
+       struct mv_host_priv *hpriv = host->private_data;
 
        /* global interrupt mask */
        writel(0, mmio + HC_MAIN_IRQ_MASK_OFS);
 
-       rc = mv_chip_id(pdev, hpriv, board_idx);
+       rc = mv_chip_id(host, board_idx);
        if (rc)
                goto done;
 
-       n_hc = mv_get_hc_count(probe_ent->port_flags);
-       probe_ent->n_ports = MV_PORTS_PER_HC * n_hc;
+       n_hc = mv_get_hc_count(host->ports[0]->flags);
 
-       for (port = 0; port < probe_ent->n_ports; port++)
+       for (port = 0; port < host->n_ports; port++)
                hpriv->ops->read_preamp(hpriv, port, mmio);
 
        rc = hpriv->ops->reset_hc(hpriv, mmio, n_hc);
        hpriv->ops->reset_bus(pdev, mmio);
        hpriv->ops->enable_leds(hpriv, mmio);
 
-       for (port = 0; port < probe_ent->n_ports; port++) {
+       for (port = 0; port < host->n_ports; port++) {
                if (IS_60XX(hpriv)) {
                        void __iomem *port_mmio = mv_port_base(mmio, port);
 
                hpriv->ops->phy_errata(hpriv, mmio, port);
        }
 
-       for (port = 0; port < probe_ent->n_ports; port++) {
+       for (port = 0; port < host->n_ports; port++) {
                void __iomem *port_mmio = mv_port_base(mmio, port);
-               mv_port_init(&probe_ent->port[port], port_mmio);
+               mv_port_init(&host->ports[port]->ioaddr, port_mmio);
        }
 
        for (hc = 0; hc < n_hc; hc++) {
 
 /**
  *      mv_print_info - Dump key info to kernel log for perusal.
- *      @probe_ent: early data struct representing the host
+ *      @host: ATA host to print info about
  *
  *      FIXME: complete this.
  *
  *      LOCKING:
  *      Inherited from caller.
  */
-static void mv_print_info(struct ata_probe_ent *probe_ent)
+static void mv_print_info(struct ata_host *host)
 {
-       struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
-       struct mv_host_priv *hpriv = probe_ent->private_data;
+       struct pci_dev *pdev = to_pci_dev(host->dev);
+       struct mv_host_priv *hpriv = host->private_data;
        u8 rev_id, scc;
        const char *scc_s;
 
 
        dev_printk(KERN_INFO, &pdev->dev,
               "%u slots %u ports %s mode IRQ via %s\n",
-              (unsigned)MV_MAX_Q_DEPTH, probe_ent->n_ports,
+              (unsigned)MV_MAX_Q_DEPTH, host->n_ports,
               scc_s, (MV_HP_FLAG_MSI & hpriv->hp_flags) ? "MSI" : "INTx");
 }
 
 static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int printed_version = 0;
-       struct device *dev = &pdev->dev;
-       struct ata_probe_ent *probe_ent;
-       struct mv_host_priv *hpriv;
        unsigned int board_idx = (unsigned int)ent->driver_data;
-       int rc;
+       const struct ata_port_info *ppi[] = { &mv_port_info[board_idx], NULL };
+       struct ata_host *host;
+       struct mv_host_priv *hpriv;
+       int n_ports, rc;
 
        if (!printed_version++)
                dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
 
+       /* allocate host */
+       n_ports = mv_get_hc_count(ppi[0]->flags) * MV_PORTS_PER_HC;
+
+       host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports);
+       hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL);
+       if (!host || !hpriv)
+               return -ENOMEM;
+       host->private_data = hpriv;
+
+       /* acquire resources */
        rc = pcim_enable_device(pdev);
        if (rc)
                return rc;
-       pci_set_master(pdev);
 
        rc = pcim_iomap_regions(pdev, 1 << MV_PRIMARY_BAR, DRV_NAME);
        if (rc == -EBUSY)
                pcim_pin_device(pdev);
        if (rc)
                return rc;
+       host->iomap = pcim_iomap_table(pdev);
 
        rc = pci_go_64(pdev);
        if (rc)
                return rc;
 
-       probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL);
-       if (probe_ent == NULL)
-               return -ENOMEM;
-
-       probe_ent->dev = pci_dev_to_dev(pdev);
-       INIT_LIST_HEAD(&probe_ent->node);
-
-       hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
-       if (!hpriv)
-               return -ENOMEM;
-
-       probe_ent->sht = mv_port_info[board_idx].sht;
-       probe_ent->port_flags = mv_port_info[board_idx].flags;
-       probe_ent->pio_mask = mv_port_info[board_idx].pio_mask;
-       probe_ent->udma_mask = mv_port_info[board_idx].udma_mask;
-       probe_ent->port_ops = mv_port_info[board_idx].port_ops;
-
-       probe_ent->irq = pdev->irq;
-       probe_ent->irq_flags = IRQF_SHARED;
-       probe_ent->iomap = pcim_iomap_table(pdev);
-       probe_ent->private_data = hpriv;
-
        /* initialize adapter */
-       rc = mv_init_host(pdev, probe_ent, board_idx);
+       rc = mv_init_host(host, board_idx);
        if (rc)
                return rc;
 
                pci_intx(pdev, 1);
 
        mv_dump_pci_cfg(pdev, 0x68);
-       mv_print_info(probe_ent);
-
-       if (ata_device_add(probe_ent) == 0)
-               return -ENODEV;
+       mv_print_info(host);
 
-       devm_kfree(dev, probe_ent);
-       return 0;
+       pci_set_master(pdev);
+       return ata_host_activate(host, pdev->irq, mv_interrupt, IRQF_SHARED,
+                                &mv_sht);
 }
 
 static int __init mv_init(void)
 
 static u32 qs_scr_read (struct ata_port *ap, unsigned int sc_reg);
 static void qs_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
 static int qs_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
-static irqreturn_t qs_intr (int irq, void *dev_instance);
 static int qs_port_start(struct ata_port *ap);
 static void qs_host_stop(struct ata_host *host);
 static void qs_phy_reset(struct ata_port *ap);
        .qc_issue               = qs_qc_issue,
        .data_xfer              = ata_data_xfer,
        .eng_timeout            = qs_eng_timeout,
-       .irq_handler            = qs_intr,
        .irq_clear              = qs_irq_clear,
        .irq_on                 = ata_irq_on,
        .irq_ack                = ata_irq_ack,
 static const struct ata_port_info qs_port_info[] = {
        /* board_2068_idx */
        {
-               .sht            = &qs_ata_sht,
                .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
                                  ATA_FLAG_SATA_RESET |
                                  //FIXME ATA_FLAG_SRST |
        writeb(QS_CNFG3_GSRST, mmio_base + QS_HCF_CNFG3); /* global reset */
 }
 
-static void qs_host_init(unsigned int chip_id, struct ata_probe_ent *pe)
+static void qs_host_init(struct ata_host *host, unsigned int chip_id)
 {
-       void __iomem *mmio_base = pe->iomap[QS_MMIO_BAR];
+       void __iomem *mmio_base = host->iomap[QS_MMIO_BAR];
        unsigned int port_no;
 
        writeb(0, mmio_base + QS_HCT_CTRL); /* disable host interrupts */
        writeb(QS_CNFG3_GSRST, mmio_base + QS_HCF_CNFG3); /* global reset */
 
        /* reset each channel in turn */
-       for (port_no = 0; port_no < pe->n_ports; ++port_no) {
+       for (port_no = 0; port_no < host->n_ports; ++port_no) {
                u8 __iomem *chan = mmio_base + (port_no * 0x4000);
                writeb(QS_CTR1_RDEV|QS_CTR1_RCHN, chan + QS_CCT_CTR1);
                writeb(QS_CTR0_REG, chan + QS_CCT_CTR0);
        }
        writeb(QS_SERD3_PHY_ENA, mmio_base + QS_HVS_SERD3); /* enable phy */
 
-       for (port_no = 0; port_no < pe->n_ports; ++port_no) {
+       for (port_no = 0; port_no < host->n_ports; ++port_no) {
                u8 __iomem *chan = mmio_base + (port_no * 0x4000);
                /* set FIFO depths to same settings as Windows driver */
                writew(32, chan + QS_CFC_HUFT);
                                const struct pci_device_id *ent)
 {
        static int printed_version;
-       struct ata_probe_ent *probe_ent;
-       void __iomem * const *iomap;
        unsigned int board_idx = (unsigned int) ent->driver_data;
+       const struct ata_port_info *ppi[] = { &qs_port_info[board_idx], NULL };
+       struct ata_host *host;
        int rc, port_no;
 
        if (!printed_version++)
                dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
 
+       /* alloc host */
+       host = ata_host_alloc_pinfo(&pdev->dev, ppi, QS_PORTS);
+       if (!host)
+               return -ENOMEM;
+
+       /* acquire resources and fill host */
        rc = pcim_enable_device(pdev);
        if (rc)
                return rc;
        rc = pcim_iomap_regions(pdev, 1 << QS_MMIO_BAR, DRV_NAME);
        if (rc)
                return rc;
-       iomap = pcim_iomap_table(pdev);
+       host->iomap = pcim_iomap_table(pdev);
 
-       rc = qs_set_dma_masks(pdev, iomap[QS_MMIO_BAR]);
+       rc = qs_set_dma_masks(pdev, host->iomap[QS_MMIO_BAR]);
        if (rc)
                return rc;
 
-       probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL);
-       if (probe_ent == NULL)
-               return -ENOMEM;
-
-       probe_ent->dev = pci_dev_to_dev(pdev);
-       INIT_LIST_HEAD(&probe_ent->node);
-
-       probe_ent->sht          = qs_port_info[board_idx].sht;
-       probe_ent->port_flags   = qs_port_info[board_idx].flags;
-       probe_ent->pio_mask     = qs_port_info[board_idx].pio_mask;
-       probe_ent->mwdma_mask   = qs_port_info[board_idx].mwdma_mask;
-       probe_ent->udma_mask    = qs_port_info[board_idx].udma_mask;
-       probe_ent->port_ops     = qs_port_info[board_idx].port_ops;
-
-       probe_ent->irq          = pdev->irq;
-       probe_ent->irq_flags    = IRQF_SHARED;
-       probe_ent->iomap        = iomap;
-       probe_ent->n_ports      = QS_PORTS;
-
-       for (port_no = 0; port_no < probe_ent->n_ports; ++port_no) {
+       for (port_no = 0; port_no < host->n_ports; ++port_no) {
                void __iomem *chan =
-                       probe_ent->iomap[QS_MMIO_BAR] + (port_no * 0x4000);
-               qs_ata_setup_port(&probe_ent->port[port_no], chan);
+                       host->iomap[QS_MMIO_BAR] + (port_no * 0x4000);
+               qs_ata_setup_port(&host->ports[port_no]->ioaddr, chan);
        }
 
-       pci_set_master(pdev);
-
        /* initialize adapter */
-       qs_host_init(board_idx, probe_ent);
+       qs_host_init(host, board_idx);
 
-       if (ata_device_add(probe_ent) != QS_PORTS)
-               return -EIO;
-
-       devm_kfree(&pdev->dev, probe_ent);
-       return 0;
+       pci_set_master(pdev);
+       return ata_host_activate(host, pdev->irq, qs_intr, IRQF_SHARED,
+                                &qs_ata_sht);
 }
 
 static int __init qs_ata_init(void)
 
 static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg);
 static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
 static int sil_set_mode (struct ata_port *ap, struct ata_device **r_failed);
-static irqreturn_t sil_interrupt(int irq, void *dev_instance);
 static void sil_freeze(struct ata_port *ap);
 static void sil_thaw(struct ata_port *ap);
 
        .thaw                   = sil_thaw,
        .error_handler          = ata_bmdma_error_handler,
        .post_internal_cmd      = ata_bmdma_post_internal_cmd,
-       .irq_handler            = sil_interrupt,
        .irq_clear              = ata_bmdma_irq_clear,
        .irq_on                 = ata_irq_on,
        .irq_ack                = ata_irq_ack,
 static const struct ata_port_info sil_port_info[] = {
        /* sil_3112 */
        {
-               .sht            = &sil_sht,
                .flags          = SIL_DFL_PORT_FLAGS | SIL_FLAG_MOD15WRITE,
                .pio_mask       = 0x1f,                 /* pio0-4 */
                .mwdma_mask     = 0x07,                 /* mwdma0-2 */
        },
        /* sil_3112_no_sata_irq */
        {
-               .sht            = &sil_sht,
                .flags          = SIL_DFL_PORT_FLAGS | SIL_FLAG_MOD15WRITE |
                                  SIL_FLAG_NO_SATA_IRQ,
                .pio_mask       = 0x1f,                 /* pio0-4 */
        },
        /* sil_3512 */
        {
-               .sht            = &sil_sht,
                .flags          = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT,
                .pio_mask       = 0x1f,                 /* pio0-4 */
                .mwdma_mask     = 0x07,                 /* mwdma0-2 */
        },
        /* sil_3114 */
        {
-               .sht            = &sil_sht,
                .flags          = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT,
                .pio_mask       = 0x1f,                 /* pio0-4 */
                .mwdma_mask     = 0x07,                 /* mwdma0-2 */
        }
 }
 
-static void sil_init_controller(struct pci_dev *pdev,
-                               int n_ports, unsigned long port_flags,
-                               void __iomem *mmio_base)
+static void sil_init_controller(struct ata_host *host)
 {
+       struct pci_dev *pdev = to_pci_dev(host->dev);
+       void __iomem *mmio_base = host->iomap[SIL_MMIO_BAR];
        u8 cls;
        u32 tmp;
        int i;
        if (cls) {
                cls >>= 3;
                cls++;  /* cls = (line_size/8)+1 */
-               for (i = 0; i < n_ports; i++)
+               for (i = 0; i < host->n_ports; i++)
                        writew(cls << 8 | cls,
                               mmio_base + sil_port[i].fifo_cfg);
        } else
                           "cache line size not set.  Driver may not function\n");
 
        /* Apply R_ERR on DMA activate FIS errata workaround */
-       if (port_flags & SIL_FLAG_RERR_ON_DMA_ACT) {
+       if (host->ports[0]->flags & SIL_FLAG_RERR_ON_DMA_ACT) {
                int cnt;
 
-               for (i = 0, cnt = 0; i < n_ports; i++) {
+               for (i = 0, cnt = 0; i < host->n_ports; i++) {
                        tmp = readl(mmio_base + sil_port[i].sfis_cfg);
                        if ((tmp & 0x3) != 0x01)
                                continue;
                }
        }
 
-       if (n_ports == 4) {
+       if (host->n_ports == 4) {
                /* flip the magic "make 4 ports work" bit */
                tmp = readl(mmio_base + sil_port[2].bmdma);
                if ((tmp & SIL_INTR_STEERING) == 0)
 static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int printed_version;
-       struct device *dev = &pdev->dev;
-       struct ata_probe_ent *probe_ent;
+       int board_id = ent->driver_data;
+       const struct ata_port_info *ppi[] = { &sil_port_info[board_id], NULL };
+       struct ata_host *host;
        void __iomem *mmio_base;
-       int rc;
+       int n_ports, rc;
        unsigned int i;
 
        if (!printed_version++)
                dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
 
+       /* allocate host */
+       n_ports = 2;
+       if (board_id == sil_3114)
+               n_ports = 4;
+
+       host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports);
+       if (!host)
+               return -ENOMEM;
+
+       /* acquire resources and fill host */
        rc = pcim_enable_device(pdev);
        if (rc)
                return rc;
                pcim_pin_device(pdev);
        if (rc)
                return rc;
+       host->iomap = pcim_iomap_table(pdev);
 
        rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
        if (rc)
        if (rc)
                return rc;
 
-       probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL);
-       if (probe_ent == NULL)
-               return -ENOMEM;
+       mmio_base = host->iomap[SIL_MMIO_BAR];
 
-       INIT_LIST_HEAD(&probe_ent->node);
-       probe_ent->dev = pci_dev_to_dev(pdev);
-       probe_ent->port_ops = sil_port_info[ent->driver_data].port_ops;
-       probe_ent->sht = sil_port_info[ent->driver_data].sht;
-       probe_ent->n_ports = (ent->driver_data == sil_3114) ? 4 : 2;
-       probe_ent->pio_mask = sil_port_info[ent->driver_data].pio_mask;
-       probe_ent->mwdma_mask = sil_port_info[ent->driver_data].mwdma_mask;
-       probe_ent->udma_mask = sil_port_info[ent->driver_data].udma_mask;
-               probe_ent->irq = pdev->irq;
-               probe_ent->irq_flags = IRQF_SHARED;
-       probe_ent->port_flags = sil_port_info[ent->driver_data].flags;
-
-       probe_ent->iomap = pcim_iomap_table(pdev);
-
-       mmio_base = probe_ent->iomap[SIL_MMIO_BAR];
-
-       for (i = 0; i < probe_ent->n_ports; i++) {
-               probe_ent->port[i].cmd_addr = mmio_base + sil_port[i].tf;
-               probe_ent->port[i].altstatus_addr =
-               probe_ent->port[i].ctl_addr = mmio_base + sil_port[i].ctl;
-               probe_ent->port[i].bmdma_addr = mmio_base + sil_port[i].bmdma;
-               probe_ent->port[i].scr_addr = mmio_base + sil_port[i].scr;
-               ata_std_ports(&probe_ent->port[i]);
+       for (i = 0; i < host->n_ports; i++) {
+               struct ata_ioports *ioaddr = &host->ports[i]->ioaddr;
+
+               ioaddr->cmd_addr = mmio_base + sil_port[i].tf;
+               ioaddr->altstatus_addr =
+               ioaddr->ctl_addr = mmio_base + sil_port[i].ctl;
+               ioaddr->bmdma_addr = mmio_base + sil_port[i].bmdma;
+               ioaddr->scr_addr = mmio_base + sil_port[i].scr;
+               ata_std_ports(ioaddr);
        }
 
-       sil_init_controller(pdev, probe_ent->n_ports, probe_ent->port_flags,
-                           mmio_base);
+       /* initialize and activate */
+       sil_init_controller(host);
 
        pci_set_master(pdev);
-
-       if (!ata_device_add(probe_ent))
-               return -ENODEV;
-
-       devm_kfree(dev, probe_ent);
-       return 0;
+       return ata_host_activate(host, pdev->irq, sil_interrupt, IRQF_SHARED,
+                                &sil_sht);
 }
 
 #ifdef CONFIG_PM
        if (rc)
                return rc;
 
-       sil_init_controller(pdev, host->n_ports, host->ports[0]->flags,
-                           host->iomap[SIL_MMIO_BAR]);
+       sil_init_controller(host);
        ata_host_resume(host);
 
        return 0;
 
 static void sil24_qc_prep(struct ata_queued_cmd *qc);
 static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc);
 static void sil24_irq_clear(struct ata_port *ap);
-static irqreturn_t sil24_interrupt(int irq, void *dev_instance);
 static void sil24_freeze(struct ata_port *ap);
 static void sil24_thaw(struct ata_port *ap);
 static void sil24_error_handler(struct ata_port *ap);
        .qc_prep                = sil24_qc_prep,
        .qc_issue               = sil24_qc_issue,
 
-       .irq_handler            = sil24_interrupt,
        .irq_clear              = sil24_irq_clear,
        .irq_on                 = ata_dummy_irq_on,
        .irq_ack                = ata_dummy_irq_ack,
 #define SIL24_NPORTS2FLAG(nports)      ((((unsigned)(nports) - 1) & 0x3) << 30)
 #define SIL24_FLAG2NPORTS(flag)                ((((flag) >> 30) & 0x3) + 1)
 
-static struct ata_port_info sil24_port_info[] = {
+static const struct ata_port_info sil24_port_info[] = {
        /* sil_3124 */
        {
-               .sht            = &sil24_sht,
                .flags          = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(4) |
                                  SIL24_FLAG_PCIX_IRQ_WOC,
                .pio_mask       = 0x1f,                 /* pio0-4 */
        },
        /* sil_3132 */
        {
-               .sht            = &sil24_sht,
                .flags          = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(2),
                .pio_mask       = 0x1f,                 /* pio0-4 */
                .mwdma_mask     = 0x07,                 /* mwdma0-2 */
        },
        /* sil_3131/sil_3531 */
        {
-               .sht            = &sil24_sht,
                .flags          = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(1),
                .pio_mask       = 0x1f,                 /* pio0-4 */
                .mwdma_mask     = 0x07,                 /* mwdma0-2 */
        return 0;
 }
 
-static void sil24_init_controller(struct pci_dev *pdev, int n_ports,
-                                 unsigned long port_flags,
-                                 void __iomem *host_base,
-                                 void __iomem *port_base)
+static void sil24_init_controller(struct ata_host *host)
 {
+       void __iomem *host_base = host->iomap[SIL24_HOST_BAR];
+       void __iomem *port_base = host->iomap[SIL24_PORT_BAR];
        u32 tmp;
        int i;
 
        writel(0, host_base + HOST_CTRL);
 
        /* init ports */
-       for (i = 0; i < n_ports; i++) {
+       for (i = 0; i < host->n_ports; i++) {
                void __iomem *port = port_base + i * PORT_REGS_SIZE;
 
                /* Initial PHY setting */
                                                PORT_CS_PORT_RST,
                                                PORT_CS_PORT_RST, 10, 100);
                        if (tmp & PORT_CS_PORT_RST)
-                               dev_printk(KERN_ERR, &pdev->dev,
+                               dev_printk(KERN_ERR, host->dev,
                                           "failed to clear port RST\n");
                }
 
                /* Configure IRQ WoC */
-               if (port_flags & SIL24_FLAG_PCIX_IRQ_WOC)
+               if (host->ports[0]->flags & SIL24_FLAG_PCIX_IRQ_WOC)
                        writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_STAT);
                else
                        writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_CLR);
 static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int printed_version = 0;
-       struct device *dev = &pdev->dev;
-       unsigned int board_id = (unsigned int)ent->driver_data;
-       struct ata_port_info *pinfo = &sil24_port_info[board_id];
-       struct ata_probe_ent *probe_ent;
-       void __iomem *host_base;
-       void __iomem *port_base;
+       struct ata_port_info pi = sil24_port_info[ent->driver_data];
+       const struct ata_port_info *ppi[] = { &pi, NULL };
+       void __iomem * const *iomap;
+       struct ata_host *host;
        int i, rc;
        u32 tmp;
 
        if (!printed_version++)
                dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
 
+       /* acquire resources */
        rc = pcim_enable_device(pdev);
        if (rc)
                return rc;
                                DRV_NAME);
        if (rc)
                return rc;
+       iomap = pcim_iomap_table(pdev);
 
-       /* allocate & init probe_ent */
-       probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL);
-       if (!probe_ent)
-               return -ENOMEM;
+       /* apply workaround for completion IRQ loss on PCI-X errata */
+       if (pi.flags & SIL24_FLAG_PCIX_IRQ_WOC) {
+               tmp = readl(iomap[SIL24_HOST_BAR] + HOST_CTRL);
+               if (tmp & (HOST_CTRL_TRDY | HOST_CTRL_STOP | HOST_CTRL_DEVSEL))
+                       dev_printk(KERN_INFO, &pdev->dev,
+                                  "Applying completion IRQ loss on PCI-X "
+                                  "errata fix\n");
+               else
+                       pi.flags &= ~SIL24_FLAG_PCIX_IRQ_WOC;
+       }
 
-       probe_ent->dev = pci_dev_to_dev(pdev);
-       INIT_LIST_HEAD(&probe_ent->node);
+       /* allocate and fill host */
+       host = ata_host_alloc_pinfo(&pdev->dev, ppi,
+                                   SIL24_FLAG2NPORTS(ppi[0]->flags));
+       if (!host)
+               return -ENOMEM;
+       host->iomap = iomap;
 
-       probe_ent->sht          = pinfo->sht;
-       probe_ent->port_flags   = pinfo->flags;
-       probe_ent->pio_mask     = pinfo->pio_mask;
-       probe_ent->mwdma_mask   = pinfo->mwdma_mask;
-       probe_ent->udma_mask    = pinfo->udma_mask;
-       probe_ent->port_ops     = pinfo->port_ops;
-       probe_ent->n_ports      = SIL24_FLAG2NPORTS(pinfo->flags);
+       for (i = 0; i < host->n_ports; i++) {
+               void __iomem *port = iomap[SIL24_PORT_BAR] + i * PORT_REGS_SIZE;
 
-       probe_ent->irq = pdev->irq;
-       probe_ent->irq_flags = IRQF_SHARED;
-       probe_ent->iomap = pcim_iomap_table(pdev);
+               host->ports[i]->ioaddr.cmd_addr = port;
+               host->ports[i]->ioaddr.scr_addr = port + PORT_SCONTROL;
 
-       host_base = probe_ent->iomap[SIL24_HOST_BAR];
-       port_base = probe_ent->iomap[SIL24_PORT_BAR];
+               ata_std_ports(&host->ports[i]->ioaddr);
+       }
 
-       /*
-        * Configure the device
-        */
+       /* configure and activate the device */
        if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
                rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
                if (rc) {
                }
        }
 
-       /* Apply workaround for completion IRQ loss on PCI-X errata */
-       if (probe_ent->port_flags & SIL24_FLAG_PCIX_IRQ_WOC) {
-               tmp = readl(host_base + HOST_CTRL);
-               if (tmp & (HOST_CTRL_TRDY | HOST_CTRL_STOP | HOST_CTRL_DEVSEL))
-                       dev_printk(KERN_INFO, &pdev->dev,
-                                  "Applying completion IRQ loss on PCI-X "
-                                  "errata fix\n");
-               else
-                       probe_ent->port_flags &= ~SIL24_FLAG_PCIX_IRQ_WOC;
-       }
-
-       for (i = 0; i < probe_ent->n_ports; i++) {
-               void __iomem *port = port_base + i * PORT_REGS_SIZE;
-
-               probe_ent->port[i].cmd_addr = port;
-               probe_ent->port[i].scr_addr = port + PORT_SCONTROL;
-
-               ata_std_ports(&probe_ent->port[i]);
-       }
-
-       sil24_init_controller(pdev, probe_ent->n_ports, probe_ent->port_flags,
-                             host_base, port_base);
+       sil24_init_controller(host);
 
        pci_set_master(pdev);
-
-       if (!ata_device_add(probe_ent))
-               return -ENODEV;
-
-       devm_kfree(dev, probe_ent);
-       return 0;
+       return ata_host_activate(host, pdev->irq, sil24_interrupt, IRQF_SHARED,
+                                &sil24_sht);
 }
 
 #ifdef CONFIG_PM
 {
        struct ata_host *host = dev_get_drvdata(&pdev->dev);
        void __iomem *host_base = host->iomap[SIL24_HOST_BAR];
-       void __iomem *port_base = host->iomap[SIL24_PORT_BAR];
        int rc;
 
        rc = ata_pci_device_do_resume(pdev);
        if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND)
                writel(HOST_CTRL_GLOBAL_RST, host_base + HOST_CTRL);
 
-       sil24_init_controller(pdev, host->n_ports, host->ports[0]->flags,
-                             host_base, port_base);
+       sil24_init_controller(host);
 
        ata_host_resume(host);
 
 
 #define DRV_VERSION    "2.1"
 
 enum {
-       K2_FLAG_NO_ATAPI_DMA            = (1 << 29),
+       /* ap->flags bits */
+       K2_FLAG_SATA_8_PORTS            = (1 << 24),
+       K2_FLAG_NO_ATAPI_DMA            = (1 << 25),
 
        /* Taskfile registers offsets */
        K2_SATA_TF_CMD_OFFSET           = 0x00,
        board_svw8                      = 1,
 };
 
-static const struct k2_board_info {
-       unsigned int            n_ports;
-       unsigned long           port_flags;
-} k2_board_info[] = {
-       /* board_svw4 */
-       { 4, K2_FLAG_NO_ATAPI_DMA },
-
-       /* board_svw8 */
-       { 8, K2_FLAG_NO_ATAPI_DMA },
-};
-
 static u8 k2_stat_check_status(struct ata_port *ap);
 
 
        .thaw                   = ata_bmdma_thaw,
        .error_handler          = ata_bmdma_error_handler,
        .post_internal_cmd      = ata_bmdma_post_internal_cmd,
-       .irq_handler            = ata_interrupt,
        .irq_clear              = ata_bmdma_irq_clear,
        .irq_on                 = ata_irq_on,
        .irq_ack                = ata_irq_ack,
        .port_start             = ata_port_start,
 };
 
+static const struct ata_port_info k2_port_info[] = {
+       /* board_svw4 */
+       {
+               .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+                                 ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA,
+               .pio_mask       = 0x1f,
+               .mwdma_mask     = 0x07,
+               .udma_mask      = 0x7f,
+               .port_ops       = &k2_sata_ops,
+       },
+       /* board_svw8 */
+       {
+               .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+                                 ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA |
+                                 K2_FLAG_SATA_8_PORTS,
+               .pio_mask       = 0x1f,
+               .mwdma_mask     = 0x07,
+               .udma_mask      = 0x7f,
+               .port_ops       = &k2_sata_ops,
+       },
+};
+
 static void k2_sata_setup_port(struct ata_ioports *port, void __iomem *base)
 {
        port->cmd_addr          = base + K2_SATA_TF_CMD_OFFSET;
 static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int printed_version;
-       struct device *dev = &pdev->dev;
-       struct ata_probe_ent *probe_ent;
+       const struct ata_port_info *ppi[] =
+               { &k2_port_info[ent->driver_data], NULL };
+       struct ata_host *host;
        void __iomem *mmio_base;
-       const struct k2_board_info *board_info =
-                       &k2_board_info[ent->driver_data];
-       int rc;
-       int i;
+       int n_ports, i, rc;
 
        if (!printed_version++)
                dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
 
+       /* allocate host */
+       n_ports = 4;
+       if (ppi[0]->flags & K2_FLAG_SATA_8_PORTS)
+               n_ports = 8;
+
+       host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports);
+       if (!host)
+               return -ENOMEM;
+
        /*
         * If this driver happens to only be useful on Apple's K2, then
         * we should check that here as it has a normal Serverworks ID
        rc = pcim_enable_device(pdev);
        if (rc)
                return rc;
+
        /*
         * Check if we have resources mapped at all (second function may
         * have been disabled by firmware)
                pcim_pin_device(pdev);
        if (rc)
                return rc;
+       host->iomap = pcim_iomap_table(pdev);
+       mmio_base = host->iomap[5];
+
+       /* different controllers have different number of ports - currently 4 or 8 */
+       /* All ports are on the same function. Multi-function device is no
+        * longer available. This should not be seen in any system. */
+       for (i = 0; i < host->n_ports; i++)
+               k2_sata_setup_port(&host->ports[i]->ioaddr,
+                                  mmio_base + i * K2_SATA_PORT_OFFSET);
 
        rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
        if (rc)
        if (rc)
                return rc;
 
-       probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL);
-       if (probe_ent == NULL)
-               return -ENOMEM;
-
-       probe_ent->dev = pci_dev_to_dev(pdev);
-       INIT_LIST_HEAD(&probe_ent->node);
-
-       probe_ent->sht = &k2_sata_sht;
-       probe_ent->port_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
-                               ATA_FLAG_MMIO | board_info->port_flags;
-       probe_ent->port_ops = &k2_sata_ops;
-       probe_ent->n_ports = 4;
-       probe_ent->irq = pdev->irq;
-       probe_ent->irq_flags = IRQF_SHARED;
-       probe_ent->iomap = pcim_iomap_table(pdev);
-
-       /* We don't care much about the PIO/UDMA masks, but the core won't like us
-        * if we don't fill these
-        */
-       probe_ent->pio_mask = 0x1f;
-       probe_ent->mwdma_mask = 0x7;
-       probe_ent->udma_mask = 0x7f;
-
-       mmio_base = probe_ent->iomap[5];
-
-       /* different controllers have different number of ports - currently 4 or 8 */
-       /* All ports are on the same function. Multi-function device is no
-        * longer available. This should not be seen in any system. */
-       for (i = 0; i < board_info->n_ports; i++)
-               k2_sata_setup_port(&probe_ent->port[i],
-                                  mmio_base + i * K2_SATA_PORT_OFFSET);
-
        /* Clear a magic bit in SCR1 according to Darwin, those help
         * some funky seagate drives (though so far, those were already
         * set by the firmware on the machines I had access to)
        writel(0x0, mmio_base + K2_SATA_SIM_OFFSET);
 
        pci_set_master(pdev);
-
-       if (!ata_device_add(probe_ent))
-               return -ENODEV;
-
-       devm_kfree(dev, probe_ent);
-       return 0;
+       return ata_host_activate(host, pdev->irq, ata_interrupt, IRQF_SHARED,
+                                &k2_sata_sht);
 }
 
 /* 0x240 is device ID for Apple K2 device
 
 
 
 static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
-static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance);
 static void pdc_eng_timeout(struct ata_port *ap);
 static void pdc_20621_phy_reset (struct ata_port *ap);
 static int pdc_port_start(struct ata_port *ap);
 static void pdc20621_qc_prep(struct ata_queued_cmd *qc);
 static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf);
 static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf);
-static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe);
-static int pdc20621_detect_dimm(struct ata_probe_ent *pe);
-static unsigned int pdc20621_i2c_read(struct ata_probe_ent *pe,
+static unsigned int pdc20621_dimm_init(struct ata_host *host);
+static int pdc20621_detect_dimm(struct ata_host *host);
+static unsigned int pdc20621_i2c_read(struct ata_host *host,
                                      u32 device, u32 subaddr, u32 *pdata);
-static int pdc20621_prog_dimm0(struct ata_probe_ent *pe);
-static unsigned int pdc20621_prog_dimm_global(struct ata_probe_ent *pe);
+static int pdc20621_prog_dimm0(struct ata_host *host);
+static unsigned int pdc20621_prog_dimm_global(struct ata_host *host);
 #ifdef ATA_VERBOSE_DEBUG
-static void pdc20621_get_from_dimm(struct ata_probe_ent *pe,
+static void pdc20621_get_from_dimm(struct ata_host *host,
                                   void *psource, u32 offset, u32 size);
 #endif
-static void pdc20621_put_to_dimm(struct ata_probe_ent *pe,
+static void pdc20621_put_to_dimm(struct ata_host *host,
                                 void *psource, u32 offset, u32 size);
 static void pdc20621_irq_clear(struct ata_port *ap);
 static unsigned int pdc20621_qc_issue_prot(struct ata_queued_cmd *qc);
        .qc_issue               = pdc20621_qc_issue_prot,
        .data_xfer              = ata_data_xfer,
        .eng_timeout            = pdc_eng_timeout,
-       .irq_handler            = pdc20621_interrupt,
        .irq_clear              = pdc20621_irq_clear,
        .irq_on                 = ata_irq_on,
        .irq_ack                = ata_irq_ack,
 static const struct ata_port_info pdc_port_info[] = {
        /* board_20621 */
        {
-               .sht            = &pdc_sata_sht,
                .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
                                  ATA_FLAG_SRST | ATA_FLAG_MMIO |
                                  ATA_FLAG_NO_ATAPI | ATA_FLAG_PIO_POLLING,
 
 
 #ifdef ATA_VERBOSE_DEBUG
-static void pdc20621_get_from_dimm(struct ata_probe_ent *pe, void *psource,
+static void pdc20621_get_from_dimm(struct ata_host *host, void *psource,
                                   u32 offset, u32 size)
 {
        u32 window_size;
        u16 idx;
        u8 page_mask;
        long dist;
-       void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
-       void __iomem *dimm_mmio = pe->iomap[PDC_DIMM_BAR];
+       void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
+       void __iomem *dimm_mmio = host->iomap[PDC_DIMM_BAR];
 
        /* hard-code chip #0 */
        mmio += PDC_CHIP0_OFS;
 #endif
 
 
-static void pdc20621_put_to_dimm(struct ata_probe_ent *pe, void *psource,
+static void pdc20621_put_to_dimm(struct ata_host *host, void *psource,
                                 u32 offset, u32 size)
 {
        u32 window_size;
        u16 idx;
        u8 page_mask;
        long dist;
-       void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
-       void __iomem *dimm_mmio = pe->iomap[PDC_DIMM_BAR];
+       void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
+       void __iomem *dimm_mmio = host->iomap[PDC_DIMM_BAR];
 
        /* hard-code chip #0 */
        mmio += PDC_CHIP0_OFS;
 }
 
 
-static unsigned int pdc20621_i2c_read(struct ata_probe_ent *pe, u32 device,
+static unsigned int pdc20621_i2c_read(struct ata_host *host, u32 device,
                                      u32 subaddr, u32 *pdata)
 {
-       void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
+       void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
        u32 i2creg  = 0;
        u32 status;
        u32 count =0;
 }
 
 
-static int pdc20621_detect_dimm(struct ata_probe_ent *pe)
+static int pdc20621_detect_dimm(struct ata_host *host)
 {
        u32 data=0 ;
-       if (pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS,
+       if (pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS,
                             PDC_DIMM_SPD_SYSTEM_FREQ, &data)) {
                if (data == 100)
                        return 100;
        } else
                return 0;
 
-       if (pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS, 9, &data)) {
+       if (pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS, 9, &data)) {
                if(data <= 0x75)
                        return 133;
        } else
 }
 
 
-static int pdc20621_prog_dimm0(struct ata_probe_ent *pe)
+static int pdc20621_prog_dimm0(struct ata_host *host)
 {
        u32 spd0[50];
        u32 data = 0;
        int size, i;
        u8 bdimmsize;
-       void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
+       void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
        static const struct {
                unsigned int reg;
                unsigned int ofs;
        mmio += PDC_CHIP0_OFS;
 
        for(i=0; i<ARRAY_SIZE(pdc_i2c_read_data); i++)
-               pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS,
+               pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS,
                                  pdc_i2c_read_data[i].reg,
                                  &spd0[pdc_i2c_read_data[i].ofs]);
 
 }
 
 
-static unsigned int pdc20621_prog_dimm_global(struct ata_probe_ent *pe)
+static unsigned int pdc20621_prog_dimm_global(struct ata_host *host)
 {
        u32 data, spd0;
        int error, i;
-       void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
+       void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
 
        /* hard-code chip #0 */
        mmio += PDC_CHIP0_OFS;
        readl(mmio + PDC_SDRAM_CONTROL_OFFSET);
 
        /* Turn on for ECC */
-       pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS,
+       pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS,
                          PDC_DIMM_SPD_TYPE, &spd0);
        if (spd0 == 0x02) {
                data |= (0x01 << 16);
 }
 
 
-static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe)
+static unsigned int pdc20621_dimm_init(struct ata_host *host)
 {
        int speed, size, length;
        u32 addr,spd0,pci_status;
        u32 ticks=0;
        u32 clock=0;
        u32 fparam=0;
-       void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
+       void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
 
        /* hard-code chip #0 */
        mmio += PDC_CHIP0_OFS;
           Read SPD of DIMM by I2C interface,
           and program the DIMM Module Controller.
        */
-       if (!(speed = pdc20621_detect_dimm(pe))) {
+       if (!(speed = pdc20621_detect_dimm(host))) {
                printk(KERN_ERR "Detect Local DIMM Fail\n");
                return 1;       /* DIMM error */
        }
        VPRINTK("Local DIMM Speed = %d\n", speed);
 
        /* Programming DIMM0 Module Control Register (index_CID0:80h) */
-       size = pdc20621_prog_dimm0(pe);
+       size = pdc20621_prog_dimm0(host);
        VPRINTK("Local DIMM Size = %dMB\n",size);
 
        /* Programming DIMM Module Global Control Register (index_CID0:88h) */
-       if (pdc20621_prog_dimm_global(pe)) {
+       if (pdc20621_prog_dimm_global(host)) {
                printk(KERN_ERR "Programming DIMM Module Global Control Register Fail\n");
                return 1;
        }
                                '9','8','0','3','1','6','1','2',0,0};
                u8 test_parttern2[40] = {0};
 
-               pdc20621_put_to_dimm(pe, (void *) test_parttern2, 0x10040, 40);
-               pdc20621_put_to_dimm(pe, (void *) test_parttern2, 0x40, 40);
+               pdc20621_put_to_dimm(host, (void *) test_parttern2, 0x10040, 40);
+               pdc20621_put_to_dimm(host, (void *) test_parttern2, 0x40, 40);
 
-               pdc20621_put_to_dimm(pe, (void *) test_parttern1, 0x10040, 40);
-               pdc20621_get_from_dimm(pe, (void *) test_parttern2, 0x40, 40);
+               pdc20621_put_to_dimm(host, (void *) test_parttern1, 0x10040, 40);
+               pdc20621_get_from_dimm(host, (void *) test_parttern2, 0x40, 40);
                printk(KERN_ERR "%x, %x, %s\n", test_parttern2[0],
                       test_parttern2[1], &(test_parttern2[2]));
-               pdc20621_get_from_dimm(pe, (void *) test_parttern2, 0x10040,
+               pdc20621_get_from_dimm(host, (void *) test_parttern2, 0x10040,
                                       40);
                printk(KERN_ERR "%x, %x, %s\n", test_parttern2[0],
                       test_parttern2[1], &(test_parttern2[2]));
 
-               pdc20621_put_to_dimm(pe, (void *) test_parttern1, 0x40, 40);
-               pdc20621_get_from_dimm(pe, (void *) test_parttern2, 0x40, 40);
+               pdc20621_put_to_dimm(host, (void *) test_parttern1, 0x40, 40);
+               pdc20621_get_from_dimm(host, (void *) test_parttern2, 0x40, 40);
                printk(KERN_ERR "%x, %x, %s\n", test_parttern2[0],
                       test_parttern2[1], &(test_parttern2[2]));
        }
 
        /* ECC initiliazation. */
 
-       pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS,
+       pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS,
                          PDC_DIMM_SPD_TYPE, &spd0);
        if (spd0 == 0x02) {
                VPRINTK("Start ECC initialization\n");
                addr = 0;
                length = size * 1024 * 1024;
                while (addr < length) {
-                       pdc20621_put_to_dimm(pe, (void *) &tmp, addr,
+                       pdc20621_put_to_dimm(host, (void *) &tmp, addr,
                                             sizeof(u32));
                        addr += sizeof(u32);
                }
 }
 
 
-static void pdc_20621_init(struct ata_probe_ent *pe)
+static void pdc_20621_init(struct ata_host *host)
 {
        u32 tmp;
-       void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
+       void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
 
        /* hard-code chip #0 */
        mmio += PDC_CHIP0_OFS;
 static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int printed_version;
-       struct ata_probe_ent *probe_ent;
+       const struct ata_port_info *ppi[] =
+               { &pdc_port_info[ent->driver_data], NULL };
+       struct ata_host *host;
        void __iomem *base;
        struct pdc_host_priv *hpriv;
-       unsigned int board_idx = (unsigned int) ent->driver_data;
        int rc;
 
        if (!printed_version++)
                dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
 
+       /* allocate host */
+       host = ata_host_alloc_pinfo(&pdev->dev, ppi, 4);
+       hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL);
+       if (!host || !hpriv)
+               return -ENOMEM;
+
+       host->private_data = hpriv;
+
+       /* acquire resources and fill host */
        rc = pcim_enable_device(pdev);
        if (rc)
                return rc;
                pcim_pin_device(pdev);
        if (rc)
                return rc;
+       host->iomap = pcim_iomap_table(pdev);
+
+       base = host->iomap[PDC_MMIO_BAR] + PDC_CHIP0_OFS;
+       pdc_sata_setup_port(&host->ports[0]->ioaddr, base + 0x200);
+       pdc_sata_setup_port(&host->ports[1]->ioaddr, base + 0x280);
+       pdc_sata_setup_port(&host->ports[2]->ioaddr, base + 0x300);
+       pdc_sata_setup_port(&host->ports[3]->ioaddr, base + 0x380);
 
+       /* configure and activate */
        rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
        if (rc)
                return rc;
        if (rc)
                return rc;
 
-       probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL);
-       if (probe_ent == NULL)
+       if (pdc20621_dimm_init(host))
                return -ENOMEM;
-
-       probe_ent->dev = pci_dev_to_dev(pdev);
-       INIT_LIST_HEAD(&probe_ent->node);
-
-       hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL);
-       if (!hpriv)
-               return -ENOMEM;
-
-       probe_ent->sht          = pdc_port_info[board_idx].sht;
-       probe_ent->port_flags   = pdc_port_info[board_idx].flags;
-       probe_ent->pio_mask     = pdc_port_info[board_idx].pio_mask;
-       probe_ent->mwdma_mask   = pdc_port_info[board_idx].mwdma_mask;
-       probe_ent->udma_mask    = pdc_port_info[board_idx].udma_mask;
-       probe_ent->port_ops     = pdc_port_info[board_idx].port_ops;
-
-               probe_ent->irq = pdev->irq;
-               probe_ent->irq_flags = IRQF_SHARED;
-       probe_ent->iomap = pcim_iomap_table(pdev);
-
-       probe_ent->private_data = hpriv;
-       base = probe_ent->iomap[PDC_MMIO_BAR] + PDC_CHIP0_OFS;
-
-       probe_ent->n_ports = 4;
-       pdc_sata_setup_port(&probe_ent->port[0], base + 0x200);
-       pdc_sata_setup_port(&probe_ent->port[1], base + 0x280);
-       pdc_sata_setup_port(&probe_ent->port[2], base + 0x300);
-       pdc_sata_setup_port(&probe_ent->port[3], base + 0x380);
+       pdc_20621_init(host);
 
        pci_set_master(pdev);
-
-       /* initialize adapter */
-       /* initialize local dimm */
-       if (pdc20621_dimm_init(probe_ent))
-               return -ENOMEM;
-       pdc_20621_init(probe_ent);
-
-       if (!ata_device_add(probe_ent))
-               return -ENODEV;
-
-       devm_kfree(&pdev->dev, probe_ent);
-       return 0;
+       return ata_host_activate(host, pdev->irq, pdc20621_interrupt,
+                                IRQF_SHARED, &pdc_sata_sht);
 }
 
 
 
        .thaw                   = vsc_thaw,
        .error_handler          = ata_bmdma_error_handler,
        .post_internal_cmd      = ata_bmdma_post_internal_cmd,
-       .irq_handler            = vsc_sata_interrupt,
        .irq_clear              = ata_bmdma_irq_clear,
        .irq_on                 = ata_irq_on,
        .irq_ack                = ata_irq_ack,
 
 static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 {
+       static const struct ata_port_info pi = {
+               .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+                                 ATA_FLAG_MMIO,
+               .pio_mask       = 0x1f,
+               .mwdma_mask     = 0x07,
+               .udma_mask      = 0x7f,
+               .port_ops       = &vsc_sata_ops,
+       };
+       const struct ata_port_info *ppi[] = { &pi, NULL };
        static int printed_version;
-       struct ata_probe_ent *probe_ent;
+       struct ata_host *host;
        void __iomem *mmio_base;
-       int rc;
+       int i, rc;
        u8 cls;
 
        if (!printed_version++)
                dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
 
+       /* allocate host */
+       host = ata_host_alloc_pinfo(&pdev->dev, ppi, 4);
+       if (!host)
+               return -ENOMEM;
+
        rc = pcim_enable_device(pdev);
        if (rc)
                return rc;
 
-       /*
-        * Check if we have needed resource mapped.
-        */
+       /* check if we have needed resource mapped */
        if (pci_resource_len(pdev, 0) == 0)
                return -ENODEV;
 
+       /* map IO regions and intialize host accordingly */
        rc = pcim_iomap_regions(pdev, 1 << VSC_MMIO_BAR, DRV_NAME);
        if (rc == -EBUSY)
                pcim_pin_device(pdev);
        if (rc)
                return rc;
+       host->iomap = pcim_iomap_table(pdev);
+
+       mmio_base = host->iomap[VSC_MMIO_BAR];
+
+       for (i = 0; i < host->n_ports; i++)
+               vsc_sata_setup_port(&host->ports[i]->ioaddr,
+                                   mmio_base + (i + 1) * VSC_SATA_PORT_OFFSET);
 
        /*
         * Use 32 bit DMA mask, because 64 bit address support is poor.
        if (rc)
                return rc;
 
-       probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL);
-       if (probe_ent == NULL)
-               return -ENOMEM;
-       probe_ent->dev = pci_dev_to_dev(pdev);
-       INIT_LIST_HEAD(&probe_ent->node);
-
        /*
         * Due to a bug in the chip, the default cache line size can't be
         * used (unless the default is non-zero).
 
        if (pci_enable_msi(pdev) == 0)
                pci_intx(pdev, 0);
-       else
-               probe_ent->irq_flags = IRQF_SHARED;
-
-       probe_ent->sht = &vsc_sata_sht;
-       probe_ent->port_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
-                               ATA_FLAG_MMIO;
-       probe_ent->port_ops = &vsc_sata_ops;
-       probe_ent->n_ports = 4;
-       probe_ent->irq = pdev->irq;
-       probe_ent->iomap = pcim_iomap_table(pdev);
-
-       /* We don't care much about the PIO/UDMA masks, but the core won't like us
-        * if we don't fill these
-        */
-       probe_ent->pio_mask = 0x1f;
-       probe_ent->mwdma_mask = 0x07;
-       probe_ent->udma_mask = 0x7f;
-
-       mmio_base = probe_ent->iomap[VSC_MMIO_BAR];
-
-       /* We have 4 ports per PCI function */
-       vsc_sata_setup_port(&probe_ent->port[0], mmio_base + 1 * VSC_SATA_PORT_OFFSET);
-       vsc_sata_setup_port(&probe_ent->port[1], mmio_base + 2 * VSC_SATA_PORT_OFFSET);
-       vsc_sata_setup_port(&probe_ent->port[2], mmio_base + 3 * VSC_SATA_PORT_OFFSET);
-       vsc_sata_setup_port(&probe_ent->port[3], mmio_base + 4 * VSC_SATA_PORT_OFFSET);
-
-       pci_set_master(pdev);
 
        /*
         * Config offset 0x98 is "Extended Control and Status Register 0"
         */
        pci_write_config_dword(pdev, 0x98, 0);
 
-       if (!ata_device_add(probe_ent))
-               return -ENODEV;
-
-       devm_kfree(&pdev->dev, probe_ent);
-       return 0;
+       pci_set_master(pdev);
+       return ata_host_activate(host, pdev->irq, vsc_sata_interrupt,
+                                IRQF_SHARED, &vsc_sata_sht);
 }
 
 static const struct pci_device_id vsc_sata_pci_tbl[] = {