include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit...
[safe/jmp/linux-2.6] / drivers / ata / sata_sil24.c
index b85464d..433b6b8 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/gfp.h>
 #include <linux/pci.h>
 #include <linux/blkdev.h>
 #include <linux/delay.h>
@@ -51,13 +52,6 @@ struct sil24_sge {
        __le32  flags;
 };
 
-/*
- * Port multiplier
- */
-struct sil24_port_multiplier {
-       __le32  diag;
-       __le32  sactive;
-};
 
 enum {
        SIL24_HOST_BAR          = 0,
@@ -336,22 +330,26 @@ static struct sil24_cerr_info {
 struct sil24_port_priv {
        union sil24_cmd_block *cmd_block;       /* 32 cmd blocks */
        dma_addr_t cmd_block_dma;               /* DMA base addr for them */
-       struct ata_taskfile tf;                 /* Cached taskfile registers */
        int do_port_rst;
 };
 
 static void sil24_dev_config(struct ata_device *dev);
-static u8 sil24_check_status(struct ata_port *ap);
-static int sil24_scr_read(struct ata_port *ap, unsigned sc_reg, u32 *val);
-static int sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val);
-static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
+static int sil24_scr_read(struct ata_link *link, unsigned sc_reg, u32 *val);
+static int sil24_scr_write(struct ata_link *link, unsigned sc_reg, u32 val);
 static int sil24_qc_defer(struct ata_queued_cmd *qc);
 static void sil24_qc_prep(struct ata_queued_cmd *qc);
 static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc);
+static bool sil24_qc_fill_rtf(struct ata_queued_cmd *qc);
 static void sil24_pmp_attach(struct ata_port *ap);
 static void sil24_pmp_detach(struct ata_port *ap);
 static void sil24_freeze(struct ata_port *ap);
 static void sil24_thaw(struct ata_port *ap);
+static int sil24_softreset(struct ata_link *link, unsigned int *class,
+                          unsigned long deadline);
+static int sil24_hardreset(struct ata_link *link, unsigned int *class,
+                          unsigned long deadline);
+static int sil24_pmp_hardreset(struct ata_link *link, unsigned int *class,
+                              unsigned long deadline);
 static void sil24_error_handler(struct ata_port *ap);
 static void sil24_post_internal_cmd(struct ata_queued_cmd *qc);
 static int sil24_port_start(struct ata_port *ap);
@@ -366,6 +364,7 @@ static const struct pci_device_id sil24_pci_tbl[] = {
        { PCI_VDEVICE(INTEL, 0x3124), BID_SIL3124 },
        { PCI_VDEVICE(CMD, 0x3132), BID_SIL3132 },
        { PCI_VDEVICE(CMD, 0x0242), BID_SIL3132 },
+       { PCI_VDEVICE(CMD, 0x0244), BID_SIL3132 },
        { PCI_VDEVICE(CMD, 0x3131), BID_SIL3131 },
        { PCI_VDEVICE(CMD, 0x3531), BID_SIL3131 },
 
@@ -384,57 +383,45 @@ static struct pci_driver sil24_pci_driver = {
 };
 
 static struct scsi_host_template sil24_sht = {
-       .module                 = THIS_MODULE,
-       .name                   = DRV_NAME,
-       .ioctl                  = ata_scsi_ioctl,
-       .queuecommand           = ata_scsi_queuecmd,
-       .change_queue_depth     = ata_scsi_change_queue_depth,
+       ATA_NCQ_SHT(DRV_NAME),
        .can_queue              = SIL24_MAX_CMDS,
-       .this_id                = ATA_SHT_THIS_ID,
        .sg_tablesize           = SIL24_MAX_SGE,
-       .cmd_per_lun            = ATA_SHT_CMD_PER_LUN,
-       .emulated               = ATA_SHT_EMULATED,
-       .use_clustering         = ATA_SHT_USE_CLUSTERING,
-       .proc_name              = DRV_NAME,
        .dma_boundary           = ATA_DMA_BOUNDARY,
-       .slave_configure        = ata_scsi_slave_config,
-       .slave_destroy          = ata_scsi_slave_destroy,
-       .bios_param             = ata_std_bios_param,
 };
 
-static const struct ata_port_operations sil24_ops = {
-       .dev_config             = sil24_dev_config,
-
-       .check_status           = sil24_check_status,
-       .check_altstatus        = sil24_check_status,
-       .dev_select             = ata_noop_dev_select,
-
-       .tf_read                = sil24_tf_read,
+static struct ata_port_operations sil24_ops = {
+       .inherits               = &sata_pmp_port_ops,
 
        .qc_defer               = sil24_qc_defer,
        .qc_prep                = sil24_qc_prep,
        .qc_issue               = sil24_qc_issue,
+       .qc_fill_rtf            = sil24_qc_fill_rtf,
 
-       .irq_clear              = ata_noop_irq_clear,
+       .freeze                 = sil24_freeze,
+       .thaw                   = sil24_thaw,
+       .softreset              = sil24_softreset,
+       .hardreset              = sil24_hardreset,
+       .pmp_softreset          = sil24_softreset,
+       .pmp_hardreset          = sil24_pmp_hardreset,
+       .error_handler          = sil24_error_handler,
+       .post_internal_cmd      = sil24_post_internal_cmd,
+       .dev_config             = sil24_dev_config,
 
        .scr_read               = sil24_scr_read,
        .scr_write              = sil24_scr_write,
-
        .pmp_attach             = sil24_pmp_attach,
        .pmp_detach             = sil24_pmp_detach,
 
-       .freeze                 = sil24_freeze,
-       .thaw                   = sil24_thaw,
-       .error_handler          = sil24_error_handler,
-       .post_internal_cmd      = sil24_post_internal_cmd,
-
        .port_start             = sil24_port_start,
-
 #ifdef CONFIG_PM
        .port_resume            = sil24_port_resume,
 #endif
 };
 
+static int sata_sil24_msi;    /* Disable MSI */
+module_param_named(msi, sata_sil24_msi, bool, S_IRUGO);
+MODULE_PARM_DESC(msi, "Enable MSI (Default: false)");
+
 /*
  * Use bits 30-31 of port_flags to encode available port numbers.
  * Current maxium is 4.
@@ -447,25 +434,25 @@ static const struct ata_port_info sil24_port_info[] = {
        {
                .flags          = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(4) |
                                  SIL24_FLAG_PCIX_IRQ_WOC,
-               .pio_mask       = 0x1f,                 /* pio0-4 */
-               .mwdma_mask     = 0x07,                 /* mwdma0-2 */
-               .udma_mask      = ATA_UDMA5,            /* udma0-5 */
+               .pio_mask       = ATA_PIO4,
+               .mwdma_mask     = ATA_MWDMA2,
+               .udma_mask      = ATA_UDMA5,
                .port_ops       = &sil24_ops,
        },
        /* sil_3132 */
        {
                .flags          = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(2),
-               .pio_mask       = 0x1f,                 /* pio0-4 */
-               .mwdma_mask     = 0x07,                 /* mwdma0-2 */
-               .udma_mask      = ATA_UDMA5,            /* udma0-5 */
+               .pio_mask       = ATA_PIO4,
+               .mwdma_mask     = ATA_MWDMA2,
+               .udma_mask      = ATA_UDMA5,
                .port_ops       = &sil24_ops,
        },
        /* sil_3131/sil_3531 */
        {
                .flags          = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(1),
-               .pio_mask       = 0x1f,                 /* pio0-4 */
-               .mwdma_mask     = 0x07,                 /* mwdma0-2 */
-               .udma_mask      = ATA_UDMA5,            /* udma0-5 */
+               .pio_mask       = ATA_PIO4,
+               .mwdma_mask     = ATA_MWDMA2,
+               .udma_mask      = ATA_UDMA5,
                .port_ops       = &sil24_ops,
        },
 };
@@ -477,9 +464,19 @@ static int sil24_tag(int tag)
        return tag;
 }
 
+static unsigned long sil24_port_offset(struct ata_port *ap)
+{
+       return ap->port_no * PORT_REGS_SIZE;
+}
+
+static void __iomem *sil24_port_base(struct ata_port *ap)
+{
+       return ap->host->iomap[SIL24_PORT_BAR] + sil24_port_offset(ap);
+}
+
 static void sil24_dev_config(struct ata_device *dev)
 {
-       void __iomem *port = dev->link->ap->ioaddr.cmd_addr;
+       void __iomem *port = sil24_port_base(dev->link->ap);
 
        if (dev->cdb_len == 16)
                writel(PORT_CS_CDB16, port + PORT_CTRL_STAT);
@@ -489,7 +486,7 @@ static void sil24_dev_config(struct ata_device *dev)
 
 static void sil24_read_tf(struct ata_port *ap, int tag, struct ata_taskfile *tf)
 {
-       void __iomem *port = ap->ioaddr.cmd_addr;
+       void __iomem *port = sil24_port_base(ap);
        struct sil24_prb __iomem *prb;
        u8 fis[6 * 4];
 
@@ -498,12 +495,6 @@ static void sil24_read_tf(struct ata_port *ap, int tag, struct ata_taskfile *tf)
        ata_tf_from_fis(fis, tf);
 }
 
-static u8 sil24_check_status(struct ata_port *ap)
-{
-       struct sil24_port_priv *pp = ap->private_data;
-       return pp->tf.command;
-}
-
 static int sil24_scr_map[] = {
        [SCR_CONTROL]   = 0,
        [SCR_STATUS]    = 1,
@@ -511,9 +502,9 @@ static int sil24_scr_map[] = {
        [SCR_ACTIVE]    = 3,
 };
 
-static int sil24_scr_read(struct ata_port *ap, unsigned sc_reg, u32 *val)
+static int sil24_scr_read(struct ata_link *link, unsigned sc_reg, u32 *val)
 {
-       void __iomem *scr_addr = ap->ioaddr.scr_addr;
+       void __iomem *scr_addr = sil24_port_base(link->ap) + PORT_SCONTROL;
 
        if (sc_reg < ARRAY_SIZE(sil24_scr_map)) {
                void __iomem *addr;
@@ -524,9 +515,9 @@ static int sil24_scr_read(struct ata_port *ap, unsigned sc_reg, u32 *val)
        return -EINVAL;
 }
 
-static int sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val)
+static int sil24_scr_write(struct ata_link *link, unsigned sc_reg, u32 val)
 {
-       void __iomem *scr_addr = ap->ioaddr.scr_addr;
+       void __iomem *scr_addr = sil24_port_base(link->ap) + PORT_SCONTROL;
 
        if (sc_reg < ARRAY_SIZE(sil24_scr_map)) {
                void __iomem *addr;
@@ -537,15 +528,9 @@ static int sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val)
        return -EINVAL;
 }
 
-static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
-{
-       struct sil24_port_priv *pp = ap->private_data;
-       *tf = pp->tf;
-}
-
 static void sil24_config_port(struct ata_port *ap)
 {
-       void __iomem *port = ap->ioaddr.cmd_addr;
+       void __iomem *port = sil24_port_base(ap);
 
        /* configure IRQ WoC */
        if (ap->flags & SIL24_FLAG_PCIX_IRQ_WOC)
@@ -570,7 +555,7 @@ static void sil24_config_port(struct ata_port *ap)
 
 static void sil24_config_pmp(struct ata_port *ap, int attached)
 {
-       void __iomem *port = ap->ioaddr.cmd_addr;
+       void __iomem *port = sil24_port_base(ap);
 
        if (attached)
                writel(PORT_CS_PMP_EN, port + PORT_CTRL_STAT);
@@ -580,7 +565,7 @@ static void sil24_config_pmp(struct ata_port *ap, int attached)
 
 static void sil24_clear_pmp(struct ata_port *ap)
 {
-       void __iomem *port = ap->ioaddr.cmd_addr;
+       void __iomem *port = sil24_port_base(ap);
        int i;
 
        writel(PORT_CS_PMP_RESUME, port + PORT_CTRL_CLR);
@@ -595,12 +580,12 @@ static void sil24_clear_pmp(struct ata_port *ap)
 
 static int sil24_init_port(struct ata_port *ap)
 {
-       void __iomem *port = ap->ioaddr.cmd_addr;
+       void __iomem *port = sil24_port_base(ap);
        struct sil24_port_priv *pp = ap->private_data;
        u32 tmp;
 
        /* clear PMP error status */
-       if (ap->nr_pmp_links)
+       if (sata_pmp_attached(ap))
                sil24_clear_pmp(ap);
 
        writel(PORT_CS_INIT, port + PORT_CTRL_STAT);
@@ -623,7 +608,7 @@ static int sil24_exec_polled_cmd(struct ata_port *ap, int pmp,
                                 int is_cmd, u32 ctrl,
                                 unsigned long timeout_msec)
 {
-       void __iomem *port = ap->ioaddr.cmd_addr;
+       void __iomem *port = sil24_port_base(ap);
        struct sil24_port_priv *pp = ap->private_data;
        struct sil24_prb *prb = &pp->cmd_block[0].ata.prb;
        dma_addr_t paddr = pp->cmd_block_dma;
@@ -665,10 +650,11 @@ static int sil24_exec_polled_cmd(struct ata_port *ap, int pmp,
        return rc;
 }
 
-static int sil24_do_softreset(struct ata_link *link, unsigned int *class,
-                             int pmp, unsigned long deadline)
+static int sil24_softreset(struct ata_link *link, unsigned int *class,
+                          unsigned long deadline)
 {
        struct ata_port *ap = link->ap;
+       int pmp = sata_srst_pmp(link);
        unsigned long timeout_msec = 0;
        struct ata_taskfile tf;
        const char *reason;
@@ -676,12 +662,6 @@ static int sil24_do_softreset(struct ata_link *link, unsigned int *class,
 
        DPRINTK("ENTER\n");
 
-       if (ata_link_offline(link)) {
-               DPRINTK("PHY reports no device\n");
-               *class = ATA_DEV_NONE;
-               goto out;
-       }
-
        /* put the port into known state */
        if (sil24_init_port(ap)) {
                reason = "port not ready";
@@ -706,10 +686,6 @@ static int sil24_do_softreset(struct ata_link *link, unsigned int *class,
        sil24_read_tf(ap, 0, &tf);
        *class = ata_dev_classify(&tf);
 
-       if (*class == ATA_DEV_UNKNOWN)
-               *class = ATA_DEV_NONE;
-
- out:
        DPRINTK("EXIT, class=%u\n", *class);
        return 0;
 
@@ -718,17 +694,11 @@ static int sil24_do_softreset(struct ata_link *link, unsigned int *class,
        return -EIO;
 }
 
-static int sil24_softreset(struct ata_link *link, unsigned int *class,
-                          unsigned long deadline)
-{
-       return sil24_do_softreset(link, class, SATA_PMP_CTRL_PORT, deadline);
-}
-
 static int sil24_hardreset(struct ata_link *link, unsigned int *class,
                           unsigned long deadline)
 {
        struct ata_port *ap = link->ap;
-       void __iomem *port = ap->ioaddr.cmd_addr;
+       void __iomem *port = sil24_port_base(ap);
        struct sil24_port_priv *pp = ap->private_data;
        int did_port_rst = 0;
        const char *reason;
@@ -881,6 +851,17 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc)
        if (!ata_is_atapi(qc->tf.protocol)) {
                prb = &cb->ata.prb;
                sge = cb->ata.sge;
+               if (ata_is_data(qc->tf.protocol)) {
+                       u16 prot = 0;
+                       ctrl = PRB_CTRL_PROTOCOL;
+                       if (ata_is_ncq(qc->tf.protocol))
+                               prot |= PRB_PROT_NCQ;
+                       if (qc->tf.flags & ATA_TFLAG_WRITE)
+                               prot |= PRB_PROT_WRITE;
+                       else
+                               prot |= PRB_PROT_READ;
+                       prb->prot = cpu_to_le16(prot);
+               }
        } else {
                prb = &cb->atapi.prb;
                sge = cb->atapi.sge;
@@ -906,7 +887,7 @@ static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
        struct sil24_port_priv *pp = ap->private_data;
-       void __iomem *port = ap->ioaddr.cmd_addr;
+       void __iomem *port = sil24_port_base(ap);
        unsigned int tag = sil24_tag(qc->tag);
        dma_addr_t paddr;
        void __iomem *activate;
@@ -920,22 +901,33 @@ static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc)
        return 0;
 }
 
+static bool sil24_qc_fill_rtf(struct ata_queued_cmd *qc)
+{
+       sil24_read_tf(qc->ap, qc->tag, &qc->result_tf);
+       return true;
+}
+
 static void sil24_pmp_attach(struct ata_port *ap)
 {
+       u32 *gscr = ap->link.device->gscr;
+
        sil24_config_pmp(ap, 1);
        sil24_init_port(ap);
+
+       if (sata_pmp_gscr_vendor(gscr) == 0x11ab &&
+           sata_pmp_gscr_devid(gscr) == 0x4140) {
+               ata_port_printk(ap, KERN_INFO,
+                       "disabling NCQ support due to sil24-mv4140 quirk\n");
+               ap->flags &= ~ATA_FLAG_NCQ;
+       }
 }
 
 static void sil24_pmp_detach(struct ata_port *ap)
 {
        sil24_init_port(ap);
        sil24_config_pmp(ap, 0);
-}
 
-static int sil24_pmp_softreset(struct ata_link *link, unsigned int *class,
-                              unsigned long deadline)
-{
-       return sil24_do_softreset(link, class, link->pmp, deadline);
+       ap->flags |= ATA_FLAG_NCQ;
 }
 
 static int sil24_pmp_hardreset(struct ata_link *link, unsigned int *class,
@@ -950,12 +942,12 @@ static int sil24_pmp_hardreset(struct ata_link *link, unsigned int *class,
                return rc;
        }
 
-       return sata_pmp_std_hardreset(link, class, deadline);
+       return sata_std_hardreset(link, class, deadline);
 }
 
 static void sil24_freeze(struct ata_port *ap)
 {
-       void __iomem *port = ap->ioaddr.cmd_addr;
+       void __iomem *port = sil24_port_base(ap);
 
        /* Port-wide IRQ mask in HOST_CTRL doesn't really work, clear
         * PORT_IRQ_ENABLE instead.
@@ -965,7 +957,7 @@ static void sil24_freeze(struct ata_port *ap)
 
 static void sil24_thaw(struct ata_port *ap)
 {
-       void __iomem *port = ap->ioaddr.cmd_addr;
+       void __iomem *port = sil24_port_base(ap);
        u32 tmp;
 
        /* clear IRQ */
@@ -978,7 +970,7 @@ static void sil24_thaw(struct ata_port *ap)
 
 static void sil24_error_intr(struct ata_port *ap)
 {
-       void __iomem *port = ap->ioaddr.cmd_addr;
+       void __iomem *port = sil24_port_base(ap);
        struct sil24_port_priv *pp = ap->private_data;
        struct ata_queued_cmd *qc = NULL;
        struct ata_link *link;
@@ -1040,7 +1032,7 @@ static void sil24_error_intr(struct ata_port *ap)
                }
 
                /* find out the offending link and qc */
-               if (ap->nr_pmp_links) {
+               if (sata_pmp_attached(ap)) {
                        context = readl(port + PORT_CONTEXT);
                        pmp = (context >> 5) & 0xf;
 
@@ -1080,16 +1072,15 @@ static void sil24_error_intr(struct ata_port *ap)
                }
 
                /* record error info */
-               if (qc) {
-                       sil24_read_tf(ap, qc->tag, &pp->tf);
+               if (qc)
                        qc->err_mask |= err_mask;
-               else
+               else
                        ehi->err_mask |= err_mask;
 
                ehi->action |= action;
 
                /* if PMP, resume */
-               if (ap->nr_pmp_links)
+               if (sata_pmp_attached(ap))
                        writel(PORT_CS_PMP_RESUME, port + PORT_CTRL_STAT);
        }
 
@@ -1104,18 +1095,9 @@ static void sil24_error_intr(struct ata_port *ap)
        }
 }
 
-static void sil24_finish_qc(struct ata_queued_cmd *qc)
-{
-       struct ata_port *ap = qc->ap;
-       struct sil24_port_priv *pp = ap->private_data;
-
-       if (qc->flags & ATA_QCFLAG_RESULT_TF)
-               sil24_read_tf(ap, qc->tag, &pp->tf);
-}
-
 static inline void sil24_host_intr(struct ata_port *ap)
 {
-       void __iomem *port = ap->ioaddr.cmd_addr;
+       void __iomem *port = sil24_port_base(ap);
        u32 slot_stat, qc_active;
        int rc;
 
@@ -1137,7 +1119,7 @@ static inline void sil24_host_intr(struct ata_port *ap)
        }
 
        qc_active = slot_stat & ~HOST_SSTAT_ATTN;
-       rc = ata_qc_complete_multiple(ap, qc_active, sil24_finish_qc);
+       rc = ata_qc_complete_multiple(ap, qc_active);
        if (rc > 0)
                return;
        if (rc < 0) {
@@ -1199,11 +1181,7 @@ static void sil24_error_handler(struct ata_port *ap)
        if (sil24_init_port(ap))
                ata_eh_freeze_port(ap);
 
-       /* perform recovery */
-       sata_pmp_do_eh(ap, ata_std_prereset, sil24_softreset, sil24_hardreset,
-                      ata_std_postreset, sata_pmp_std_prereset,
-                      sil24_pmp_softreset, sil24_pmp_hardreset,
-                      sata_pmp_std_postreset);
+       sata_pmp_error_handler(ap);
 
        pp->do_port_rst = 0;
 }
@@ -1229,8 +1207,6 @@ static int sil24_port_start(struct ata_port *ap)
        if (!pp)
                return -ENOMEM;
 
-       pp->tf.command = ATA_DRDY;
-
        cb = dmam_alloc_coherent(dev, cb_size, &cb_dma, GFP_KERNEL);
        if (!cb)
                return -ENOMEM;
@@ -1241,6 +1217,9 @@ static int sil24_port_start(struct ata_port *ap)
 
        ap->private_data = pp;
 
+       ata_port_pbar_desc(ap, SIL24_HOST_BAR, -1, "host");
+       ata_port_pbar_desc(ap, SIL24_PORT_BAR, sil24_port_offset(ap), "port");
+
        return 0;
 }
 
@@ -1259,7 +1238,8 @@ static void sil24_init_controller(struct ata_host *host)
        /* init ports */
        for (i = 0; i < host->n_ports; i++) {
                struct ata_port *ap = host->ports[i];
-               void __iomem *port = ap->ioaddr.cmd_addr;
+               void __iomem *port = sil24_port_base(ap);
+
 
                /* Initial PHY setting */
                writel(0x20c, port + PORT_PHY_CFG);
@@ -1292,7 +1272,7 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        const struct ata_port_info *ppi[] = { &pi, NULL };
        void __iomem * const *iomap;
        struct ata_host *host;
-       int i, rc;
+       int rc;
        u32 tmp;
 
        /* cause link error if sil24_cmd_block is sized wrongly */
@@ -1332,23 +1312,11 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
                return -ENOMEM;
        host->iomap = iomap;
 
-       for (i = 0; i < host->n_ports; i++) {
-               struct ata_port *ap = host->ports[i];
-               size_t offset = ap->port_no * PORT_REGS_SIZE;
-               void __iomem *port = iomap[SIL24_PORT_BAR] + offset;
-
-               host->ports[i]->ioaddr.cmd_addr = port;
-               host->ports[i]->ioaddr.scr_addr = port + PORT_SCONTROL;
-
-               ata_port_pbar_desc(ap, SIL24_HOST_BAR, -1, "host");
-               ata_port_pbar_desc(ap, SIL24_PORT_BAR, offset, "port");
-       }
-
        /* 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 (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
+               rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
                if (rc) {
-                       rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+                       rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
                        if (rc) {
                                dev_printk(KERN_ERR, &pdev->dev,
                                           "64-bit DMA enable failed\n");
@@ -1356,13 +1324,13 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
                        }
                }
        } else {
-               rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+               rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
                if (rc) {
                        dev_printk(KERN_ERR, &pdev->dev,
                                   "32-bit DMA enable failed\n");
                        return rc;
                }
-               rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+               rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
                if (rc) {
                        dev_printk(KERN_ERR, &pdev->dev,
                                   "32-bit consistent DMA enable failed\n");
@@ -1370,8 +1338,18 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
                }
        }
 
+       /* Set max read request size to 4096.  This slightly increases
+        * write throughput for pci-e variants.
+        */
+       pcie_set_readrq(pdev, 4096);
+
        sil24_init_controller(host);
 
+       if (sata_sil24_msi && !pci_enable_msi(pdev)) {
+               dev_printk(KERN_INFO, &pdev->dev, "Using MSI\n");
+               pci_intx(pdev, 0);
+       }
+
        pci_set_master(pdev);
        return ata_host_activate(host, pdev->irq, sil24_interrupt, IRQF_SHARED,
                                 &sil24_sht);