]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/ata/ahci.c
[libata] AHCI: enable AHCI mode, before using AHCI reset
[linux-2.6-omap-h63xx.git] / drivers / ata / ahci.c
index 06f212ff2b4f2093e6d954c169c8c2454136dbb7..b615390b6b8a0fc7c52d4bc09060562f3f490a5c 100644 (file)
@@ -77,11 +77,10 @@ enum {
        RX_FIS_UNK              = 0x60, /* offset of Unknown FIS data */
 
        board_ahci              = 0,
-       board_ahci_pi           = 1,
-       board_ahci_vt8251       = 2,
-       board_ahci_ign_iferr    = 3,
-       board_ahci_sb600        = 4,
-       board_ahci_mv           = 5,
+       board_ahci_vt8251       = 1,
+       board_ahci_ign_iferr    = 2,
+       board_ahci_sb600        = 3,
+       board_ahci_mv           = 4,
 
        /* global controller registers */
        HOST_CAP                = 0x00, /* host capabilities */
@@ -170,16 +169,16 @@ enum {
        /* ap->flags bits */
        AHCI_FLAG_NO_NCQ                = (1 << 24),
        AHCI_FLAG_IGN_IRQ_IF_ERR        = (1 << 25), /* ignore IRQ_IF_ERR */
-       AHCI_FLAG_HONOR_PI              = (1 << 26), /* honor PORTS_IMPL */
        AHCI_FLAG_IGN_SERR_INTERNAL     = (1 << 27), /* ignore SERR_INTERNAL */
        AHCI_FLAG_32BIT_ONLY            = (1 << 28), /* force 32bit */
        AHCI_FLAG_MV_PATA               = (1 << 29), /* PATA port */
        AHCI_FLAG_NO_MSI                = (1 << 30), /* no PCI MSI */
+       AHCI_FLAG_NO_HOTPLUG            = (1 << 31), /* ignore PxSERR.DIAG.N */
 
        AHCI_FLAG_COMMON                = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
                                          ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
-                                         ATA_FLAG_SKIP_D2H_BSY |
-                                         ATA_FLAG_ACPI_SATA,
+                                         ATA_FLAG_ACPI_SATA | ATA_FLAG_AN,
+       AHCI_LFLAG_COMMON               = ATA_LFLAG_SKIP_D2H_BSY,
 };
 
 struct ahci_cmd_hdr {
@@ -215,6 +214,7 @@ struct ahci_port_priv {
        unsigned int            ncq_saw_d2h:1;
        unsigned int            ncq_saw_dmas:1;
        unsigned int            ncq_saw_sdb:1;
+       u32                     intr_mask;      /* interrupts to enable */
 };
 
 static int ahci_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val);
@@ -262,20 +262,17 @@ static struct scsi_host_template ahci_sht = {
 };
 
 static const struct ata_port_operations ahci_ops = {
-       .port_disable           = ata_port_disable,
-
        .check_status           = ahci_check_status,
        .check_altstatus        = ahci_check_status,
        .dev_select             = ata_noop_dev_select,
 
        .tf_read                = ahci_tf_read,
 
+       .qc_defer               = ata_std_qc_defer,
        .qc_prep                = ahci_qc_prep,
        .qc_issue               = ahci_qc_issue,
 
        .irq_clear              = ahci_irq_clear,
-       .irq_on                 = ata_dummy_irq_on,
-       .irq_ack                = ata_dummy_irq_ack,
 
        .scr_read               = ahci_scr_read,
        .scr_write              = ahci_scr_write,
@@ -296,20 +293,17 @@ static const struct ata_port_operations ahci_ops = {
 };
 
 static const struct ata_port_operations ahci_vt8251_ops = {
-       .port_disable           = ata_port_disable,
-
        .check_status           = ahci_check_status,
        .check_altstatus        = ahci_check_status,
        .dev_select             = ata_noop_dev_select,
 
        .tf_read                = ahci_tf_read,
 
+       .qc_defer               = ata_std_qc_defer,
        .qc_prep                = ahci_qc_prep,
        .qc_issue               = ahci_qc_issue,
 
        .irq_clear              = ahci_irq_clear,
-       .irq_on                 = ata_dummy_irq_on,
-       .irq_ack                = ata_dummy_irq_ack,
 
        .scr_read               = ahci_scr_read,
        .scr_write              = ahci_scr_write,
@@ -333,21 +327,15 @@ static const struct ata_port_info ahci_port_info[] = {
        /* board_ahci */
        {
                .flags          = AHCI_FLAG_COMMON,
-               .pio_mask       = 0x1f, /* pio0-4 */
-               .udma_mask      = ATA_UDMA6,
-               .port_ops       = &ahci_ops,
-       },
-       /* board_ahci_pi */
-       {
-               .flags          = AHCI_FLAG_COMMON | AHCI_FLAG_HONOR_PI,
+               .link_flags     = AHCI_LFLAG_COMMON,
                .pio_mask       = 0x1f, /* pio0-4 */
                .udma_mask      = ATA_UDMA6,
                .port_ops       = &ahci_ops,
        },
        /* board_ahci_vt8251 */
        {
-               .flags          = AHCI_FLAG_COMMON | ATA_FLAG_HRST_TO_RESUME |
-                                 AHCI_FLAG_NO_NCQ,
+               .flags          = AHCI_FLAG_COMMON | AHCI_FLAG_NO_NCQ,
+               .link_flags     = AHCI_LFLAG_COMMON | ATA_LFLAG_HRST_TO_RESUME,
                .pio_mask       = 0x1f, /* pio0-4 */
                .udma_mask      = ATA_UDMA6,
                .port_ops       = &ahci_vt8251_ops,
@@ -355,6 +343,7 @@ static const struct ata_port_info ahci_port_info[] = {
        /* board_ahci_ign_iferr */
        {
                .flags          = AHCI_FLAG_COMMON | AHCI_FLAG_IGN_IRQ_IF_ERR,
+               .link_flags     = AHCI_LFLAG_COMMON,
                .pio_mask       = 0x1f, /* pio0-4 */
                .udma_mask      = ATA_UDMA6,
                .port_ops       = &ahci_ops,
@@ -364,6 +353,7 @@ static const struct ata_port_info ahci_port_info[] = {
                .flags          = AHCI_FLAG_COMMON |
                                  AHCI_FLAG_IGN_SERR_INTERNAL |
                                  AHCI_FLAG_32BIT_ONLY,
+               .link_flags     = AHCI_LFLAG_COMMON,
                .pio_mask       = 0x1f, /* pio0-4 */
                .udma_mask      = ATA_UDMA6,
                .port_ops       = &ahci_ops,
@@ -373,9 +363,9 @@ static const struct ata_port_info ahci_port_info[] = {
                .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 |
                                  AHCI_FLAG_NO_NCQ | AHCI_FLAG_NO_MSI |
                                  AHCI_FLAG_MV_PATA,
+               .link_flags     = AHCI_LFLAG_COMMON,
                .pio_mask       = 0x1f, /* pio0-4 */
                .udma_mask      = ATA_UDMA6,
                .port_ops       = &ahci_ops,
@@ -394,23 +384,25 @@ static const struct pci_device_id ahci_pci_tbl[] = {
        { PCI_VDEVICE(INTEL, 0x2682), board_ahci }, /* ESB2 */
        { PCI_VDEVICE(INTEL, 0x2683), board_ahci }, /* ESB2 */
        { PCI_VDEVICE(INTEL, 0x27c6), board_ahci }, /* ICH7-M DH */
-       { PCI_VDEVICE(INTEL, 0x2821), board_ahci_pi }, /* ICH8 */
-       { PCI_VDEVICE(INTEL, 0x2822), board_ahci_pi }, /* ICH8 */
-       { PCI_VDEVICE(INTEL, 0x2824), board_ahci_pi }, /* ICH8 */
-       { PCI_VDEVICE(INTEL, 0x2829), board_ahci_pi }, /* ICH8M */
-       { PCI_VDEVICE(INTEL, 0x282a), board_ahci_pi }, /* ICH8M */
-       { PCI_VDEVICE(INTEL, 0x2922), board_ahci_pi }, /* ICH9 */
-       { PCI_VDEVICE(INTEL, 0x2923), board_ahci_pi }, /* ICH9 */
-       { PCI_VDEVICE(INTEL, 0x2924), board_ahci_pi }, /* ICH9 */
-       { PCI_VDEVICE(INTEL, 0x2925), board_ahci_pi }, /* ICH9 */
-       { PCI_VDEVICE(INTEL, 0x2927), board_ahci_pi }, /* ICH9 */
-       { PCI_VDEVICE(INTEL, 0x2929), board_ahci_pi }, /* ICH9M */
-       { PCI_VDEVICE(INTEL, 0x292a), board_ahci_pi }, /* ICH9M */
-       { PCI_VDEVICE(INTEL, 0x292b), board_ahci_pi }, /* ICH9M */
-       { PCI_VDEVICE(INTEL, 0x292c), board_ahci_pi }, /* ICH9M */
-       { PCI_VDEVICE(INTEL, 0x292f), board_ahci_pi }, /* ICH9M */
-       { PCI_VDEVICE(INTEL, 0x294d), board_ahci_pi }, /* ICH9 */
-       { PCI_VDEVICE(INTEL, 0x294e), board_ahci_pi }, /* ICH9M */
+       { PCI_VDEVICE(INTEL, 0x2821), board_ahci }, /* ICH8 */
+       { PCI_VDEVICE(INTEL, 0x2822), board_ahci }, /* ICH8 */
+       { PCI_VDEVICE(INTEL, 0x2824), board_ahci }, /* ICH8 */
+       { PCI_VDEVICE(INTEL, 0x2829), board_ahci }, /* ICH8M */
+       { PCI_VDEVICE(INTEL, 0x282a), board_ahci }, /* ICH8M */
+       { PCI_VDEVICE(INTEL, 0x2922), board_ahci }, /* ICH9 */
+       { PCI_VDEVICE(INTEL, 0x2923), board_ahci }, /* ICH9 */
+       { PCI_VDEVICE(INTEL, 0x2924), board_ahci }, /* ICH9 */
+       { PCI_VDEVICE(INTEL, 0x2925), board_ahci }, /* ICH9 */
+       { PCI_VDEVICE(INTEL, 0x2927), board_ahci }, /* ICH9 */
+       { PCI_VDEVICE(INTEL, 0x2929), board_ahci }, /* ICH9M */
+       { PCI_VDEVICE(INTEL, 0x292a), board_ahci }, /* ICH9M */
+       { PCI_VDEVICE(INTEL, 0x292b), board_ahci }, /* ICH9M */
+       { PCI_VDEVICE(INTEL, 0x292c), board_ahci }, /* ICH9M */
+       { PCI_VDEVICE(INTEL, 0x292f), board_ahci }, /* ICH9M */
+       { PCI_VDEVICE(INTEL, 0x294d), board_ahci }, /* ICH9 */
+       { PCI_VDEVICE(INTEL, 0x294e), board_ahci }, /* ICH9M */
+       { PCI_VDEVICE(INTEL, 0x502a), board_ahci }, /* Tolapai */
+       { PCI_VDEVICE(INTEL, 0x502b), board_ahci }, /* Tolapai */
 
        /* JMicron 360/1/3/5/6, match class to avoid IDE function */
        { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
@@ -418,10 +410,12 @@ static const struct pci_device_id ahci_pci_tbl[] = {
 
        /* ATI */
        { PCI_VDEVICE(ATI, 0x4380), board_ahci_sb600 }, /* ATI SB600 */
-       { PCI_VDEVICE(ATI, 0x4390), board_ahci_sb600 }, /* ATI SB700 IDE */
-       { PCI_VDEVICE(ATI, 0x4391), board_ahci_sb600 }, /* ATI SB700 AHCI */
-       { PCI_VDEVICE(ATI, 0x4392), board_ahci_sb600 }, /* ATI SB700 nraid5 */
-       { PCI_VDEVICE(ATI, 0x4393), board_ahci_sb600 }, /* ATI SB700 raid5 */
+       { PCI_VDEVICE(ATI, 0x4390), board_ahci_sb600 }, /* ATI SB700/800 */
+       { PCI_VDEVICE(ATI, 0x4391), board_ahci_sb600 }, /* ATI SB700/800 */
+       { PCI_VDEVICE(ATI, 0x4392), board_ahci_sb600 }, /* ATI SB700/800 */
+       { PCI_VDEVICE(ATI, 0x4393), board_ahci_sb600 }, /* ATI SB700/800 */
+       { PCI_VDEVICE(ATI, 0x4394), board_ahci_sb600 }, /* ATI SB700/800 */
+       { PCI_VDEVICE(ATI, 0x4395), board_ahci_sb600 }, /* ATI SB700/800 */
 
        /* VIA */
        { PCI_VDEVICE(VIA, 0x3349), board_ahci_vt8251 }, /* VIA VT8251 */
@@ -562,16 +556,6 @@ static void ahci_save_initial_config(struct pci_dev *pdev,
                cap &= ~HOST_CAP_NCQ;
        }
 
-       /* fixup zero port_map */
-       if (!port_map) {
-               port_map = (1 << ahci_nr_ports(cap)) - 1;
-               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 */
-               hpriv->saved_port_map = port_map;
-       }
-
        /*
         * Temporary Marvell 6145 hack: PATA port presence
         * is asserted through the standard AHCI port
@@ -587,7 +571,7 @@ static void ahci_save_initial_config(struct pci_dev *pdev,
        }
 
        /* cross check port_map and cap.n_ports */
-       if (pi->flags & AHCI_FLAG_HONOR_PI) {
+       if (port_map) {
                u32 tmp_port_map = port_map;
                int n_ports = ahci_nr_ports(cap);
 
@@ -598,17 +582,26 @@ static void ahci_save_initial_config(struct pci_dev *pdev,
                        }
                }
 
-               /* Whine if inconsistent.  No need to update cap.
-                * port_map is used to determine number of ports.
+               /* If n_ports and port_map are inconsistent, whine and
+                * clear port_map and let it be generated from n_ports.
                 */
-               if (n_ports || tmp_port_map)
+               if (n_ports || tmp_port_map) {
                        dev_printk(KERN_WARNING, &pdev->dev,
                                   "nr_ports (%u) and implemented port map "
-                                  "(0x%x) don't match\n",
+                                  "(0x%x) don't match, using nr_ports\n",
                                   ahci_nr_ports(cap), port_map);
-       } else {
-               /* fabricate port_map from cap.nr_ports */
+                       port_map = 0;
+               }
+       }
+
+       /* fabricate port_map from cap.nr_ports */
+       if (!port_map) {
                port_map = (1 << ahci_nr_ports(cap)) - 1;
+               dev_printk(KERN_WARNING, &pdev->dev,
+                          "forcing PORTS_IMPL to 0x%x\n", port_map);
+
+               /* write the fixed up value to the PI register */
+               hpriv->saved_port_map = port_map;
        }
 
        /* record values to use during operation */
@@ -834,8 +827,14 @@ static int ahci_reset_controller(struct ata_host *host)
        void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
        u32 tmp;
 
-       /* global controller reset */
+       /* we must be in AHCI mode, before using anything
+        * AHCI-specific, such as HOST_RESET.
+        */
        tmp = readl(mmio + HOST_CTL);
+       if (!(tmp & HOST_AHCI_EN))
+               writel(tmp | HOST_AHCI_EN, mmio + HOST_CTL);
+
+       /* global controller reset */
        if ((tmp & HOST_RESET) == 0) {
                writel(tmp | HOST_RESET, mmio + HOST_CTL);
                readl(mmio + HOST_CTL); /* flush */
@@ -1040,9 +1039,10 @@ static int ahci_exec_polled_cmd(struct ata_port *ap, int pmp,
        return 0;
 }
 
-static int ahci_do_softreset(struct ata_port *ap, unsigned int *class,
+static int ahci_do_softreset(struct ata_link *link, unsigned int *class,
                             int pmp, unsigned long deadline)
 {
+       struct ata_port *ap = link->ap;
        const char *reason = NULL;
        unsigned long now, msecs;
        struct ata_taskfile tf;
@@ -1050,7 +1050,7 @@ static int ahci_do_softreset(struct ata_port *ap, unsigned int *class,
 
        DPRINTK("ENTER\n");
 
-       if (ata_port_offline(ap)) {
+       if (ata_link_offline(link)) {
                DPRINTK("PHY reports no device\n");
                *class = ATA_DEV_NONE;
                return 0;
@@ -1059,10 +1059,10 @@ static int ahci_do_softreset(struct ata_port *ap, unsigned int *class,
        /* prepare for SRST (AHCI-1.1 10.4.1) */
        rc = ahci_kick_engine(ap, 1);
        if (rc)
-               ata_port_printk(ap, KERN_WARNING,
+               ata_link_printk(link, KERN_WARNING,
                                "failed to reset engine (errno=%d)", rc);
 
-       ata_tf_init(ap->device, &tf);
+       ata_tf_init(link->device, &tf);
 
        /* issue the first D2H Register FIS */
        msecs = 0;
@@ -1107,19 +1107,20 @@ static int ahci_do_softreset(struct ata_port *ap, unsigned int *class,
        return 0;
 
  fail:
-       ata_port_printk(ap, KERN_ERR, "softreset failed (%s)\n", reason);
+       ata_link_printk(link, KERN_ERR, "softreset failed (%s)\n", reason);
        return rc;
 }
 
-static int ahci_softreset(struct ata_port *ap, unsigned int *class,
+static int ahci_softreset(struct ata_link *link, unsigned int *class,
                          unsigned long deadline)
 {
-       return ahci_do_softreset(ap, class, 0, deadline);
+       return ahci_do_softreset(link, class, 0, deadline);
 }
 
-static int ahci_hardreset(struct ata_port *ap, unsigned int *class,
+static int ahci_hardreset(struct ata_link *link, unsigned int *class,
                          unsigned long deadline)
 {
+       struct ata_port *ap = link->ap;
        struct ahci_port_priv *pp = ap->private_data;
        u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
        struct ata_taskfile tf;
@@ -1130,15 +1131,15 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class,
        ahci_stop_engine(ap);
 
        /* clear D2H reception area to properly wait for D2H FIS */
-       ata_tf_init(ap->device, &tf);
+       ata_tf_init(link->device, &tf);
        tf.command = 0x80;
        ata_tf_to_fis(&tf, 0, 0, d2h_fis);
 
-       rc = sata_std_hardreset(ap, class, deadline);
+       rc = sata_std_hardreset(link, class, deadline);
 
        ahci_start_engine(ap);
 
-       if (rc == 0 && ata_port_online(ap))
+       if (rc == 0 && ata_link_online(link))
                *class = ahci_dev_classify(ap);
        if (*class == ATA_DEV_UNKNOWN)
                *class = ATA_DEV_NONE;
@@ -1147,9 +1148,10 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class,
        return rc;
 }
 
-static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class,
+static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class,
                                 unsigned long deadline)
 {
+       struct ata_port *ap = link->ap;
        u32 serror;
        int rc;
 
@@ -1157,7 +1159,7 @@ static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class,
 
        ahci_stop_engine(ap);
 
-       rc = sata_port_hardreset(ap, sata_ehc_deb_timing(&ap->eh_context),
+       rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context),
                                 deadline);
 
        /* vt8251 needs SError cleared for the port to operate */
@@ -1174,12 +1176,13 @@ static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class,
        return rc ?: -EAGAIN;
 }
 
-static void ahci_postreset(struct ata_port *ap, unsigned int *class)
+static void ahci_postreset(struct ata_link *link, unsigned int *class)
 {
+       struct ata_port *ap = link->ap;
        void __iomem *port_mmio = ahci_port_base(ap);
        u32 new_tmp, tmp;
 
-       ata_std_postreset(ap, class);
+       ata_std_postreset(link, class);
 
        /* Make sure port's ATAPI bit is set appropriately */
        new_tmp = tmp = readl(port_mmio + PORT_CMD);
@@ -1276,7 +1279,7 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc)
 static void ahci_error_intr(struct ata_port *ap, u32 irq_stat)
 {
        struct ahci_port_priv *pp = ap->private_data;
-       struct ata_eh_info *ehi = &ap->eh_info;
+       struct ata_eh_info *ehi = &ap->link.eh_info;
        unsigned int err_mask = 0, action = 0;
        struct ata_queued_cmd *qc;
        u32 serror;
@@ -1330,7 +1333,7 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat)
        ehi->serror |= serror;
        ehi->action |= action;
 
-       qc = ata_qc_from_tag(ap, ap->active_tag);
+       qc = ata_qc_from_tag(ap, ap->link.active_tag);
        if (qc)
                qc->err_mask |= err_mask;
        else
@@ -1345,7 +1348,7 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat)
 static void ahci_port_intr(struct ata_port *ap)
 {
        void __iomem *port_mmio = ap->ioaddr.cmd_addr;
-       struct ata_eh_info *ehi = &ap->eh_info;
+       struct ata_eh_info *ehi = &ap->link.eh_info;
        struct ahci_port_priv *pp = ap->private_data;
        u32 status, qc_active;
        int rc, known_irq = 0;
@@ -1358,7 +1361,21 @@ static void ahci_port_intr(struct ata_port *ap)
                return;
        }
 
-       if (ap->sactive)
+       if (status & PORT_IRQ_SDB_FIS) {
+               /* If the 'N' bit in word 0 of the FIS is set, we just
+                * received asynchronous notification.  Tell libata
+                * about it.  Note that as the SDB FIS itself is
+                * accessible, SNotification can be emulated by the
+                * driver but don't bother for the time being.
+                */
+               const __le32 *f = pp->rx_fis + RX_FIS_SDB;
+               u32 f0 = le32_to_cpu(f[0]);
+
+               if (f0 & (1 << 15))
+                       sata_async_notification(ap);
+       }
+
+       if (ap->link.sactive)
                qc_active = readl(port_mmio + PORT_SCR_ACT);
        else
                qc_active = readl(port_mmio + PORT_CMD_ISSUE);
@@ -1378,7 +1395,7 @@ static void ahci_port_intr(struct ata_port *ap)
        /* if !NCQ, ignore.  No modern ATA device has broken HSM
         * implementation for non-NCQ commands.
         */
-       if (!ap->sactive)
+       if (!ap->link.sactive)
                return;
 
        if (status & PORT_IRQ_D2H_REG_FIS) {
@@ -1431,7 +1448,7 @@ static void ahci_port_intr(struct ata_port *ap)
        if (!known_irq)
                ata_port_printk(ap, KERN_INFO, "spurious interrupt "
                                "(irq_stat 0x%x active_tag 0x%x sactive 0x%x)\n",
-                               status, ap->active_tag, ap->sactive);
+                               status, ap->link.active_tag, ap->link.sactive);
 }
 
 static void ahci_irq_clear(struct ata_port *ap)
@@ -1518,6 +1535,7 @@ static void ahci_thaw(struct ata_port *ap)
        void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
        void __iomem *port_mmio = ahci_port_base(ap);
        u32 tmp;
+       struct ahci_port_priv *pp = ap->private_data;
 
        /* clear IRQ */
        tmp = readl(port_mmio + PORT_IRQ_STAT);
@@ -1525,7 +1543,7 @@ static void ahci_thaw(struct ata_port *ap)
        writel(1 << ap->port_no, mmio + HOST_IRQ_STAT);
 
        /* turn IRQ back on */
-       writel(DEF_PORT_IRQ, port_mmio + PORT_IRQ_MASK);
+       writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK);
 }
 
 static void ahci_error_handler(struct ata_port *ap)
@@ -1679,6 +1697,12 @@ static int ahci_port_start(struct ata_port *ap)
        pp->cmd_tbl = mem;
        pp->cmd_tbl_dma = mem_dma;
 
+       /*
+        * Save off initial list of interrupts to be enabled.
+        * This could be changed later
+        */
+       pp->intr_mask = DEF_PORT_IRQ;
+
        ap->private_data = pp;
 
        /* engage engines, captain */
@@ -1852,6 +1876,10 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
                struct ata_port *ap = host->ports[i];
                void __iomem *port_mmio = ahci_port_base(ap);
 
+               ata_port_pbar_desc(ap, AHCI_PCI_BAR, -1, "abar");
+               ata_port_pbar_desc(ap, AHCI_PCI_BAR,
+                                  0x100 + ap->port_no * 0x80, "port");
+
                /* standard SATA port setup */
                if (hpriv->port_map & (1 << i))
                        ap->ioaddr.cmd_addr = port_mmio;