KVM: Correctly handle writes crossing a page boundary
[safe/jmp/linux-2.6] / drivers / ata / sata_mv.c
index d40c41c..8ec5208 100644 (file)
@@ -35,8 +35,6 @@
 
   6) Add port multiplier support (intermediate)
 
-  7) Test and verify 3.0 Gbps support
-
   8) Develop a low-power-consumption strategy, and implement it.
 
   9) [Experiment, low priority] See if ATAPI can be supported using
@@ -227,26 +225,26 @@ enum {
 
        EDMA_ERR_IRQ_CAUSE_OFS  = 0x8,
        EDMA_ERR_IRQ_MASK_OFS   = 0xc,
-       EDMA_ERR_D_PAR          = (1 << 0),
-       EDMA_ERR_PRD_PAR        = (1 << 1),
-       EDMA_ERR_DEV            = (1 << 2),
-       EDMA_ERR_DEV_DCON       = (1 << 3),
-       EDMA_ERR_DEV_CON        = (1 << 4),
-       EDMA_ERR_SERR           = (1 << 5),
+       EDMA_ERR_D_PAR          = (1 << 0),     /* UDMA data parity err */
+       EDMA_ERR_PRD_PAR        = (1 << 1),     /* UDMA PRD parity err */
+       EDMA_ERR_DEV            = (1 << 2),     /* device error */
+       EDMA_ERR_DEV_DCON       = (1 << 3),     /* device disconnect */
+       EDMA_ERR_DEV_CON        = (1 << 4),     /* device connected */
+       EDMA_ERR_SERR           = (1 << 5),     /* SError bits [WBDST] raised */
        EDMA_ERR_SELF_DIS       = (1 << 7),     /* Gen II/IIE self-disable */
        EDMA_ERR_SELF_DIS_5     = (1 << 8),     /* Gen I self-disable */
-       EDMA_ERR_BIST_ASYNC     = (1 << 8),
+       EDMA_ERR_BIST_ASYNC     = (1 << 8),     /* BIST FIS or Async Notify */
        EDMA_ERR_TRANS_IRQ_7    = (1 << 8),     /* Gen IIE transprt layer irq */
-       EDMA_ERR_CRBQ_PAR       = (1 << 9),
-       EDMA_ERR_CRPB_PAR       = (1 << 10),
-       EDMA_ERR_INTRL_PAR      = (1 << 11),
-       EDMA_ERR_IORDY          = (1 << 12),
-       EDMA_ERR_LNK_CTRL_RX    = (0xf << 13),
+       EDMA_ERR_CRQB_PAR       = (1 << 9),     /* CRQB parity error */
+       EDMA_ERR_CRPB_PAR       = (1 << 10),    /* CRPB parity error */
+       EDMA_ERR_INTRL_PAR      = (1 << 11),    /* internal parity error */
+       EDMA_ERR_IORDY          = (1 << 12),    /* IORdy timeout */
+       EDMA_ERR_LNK_CTRL_RX    = (0xf << 13),  /* link ctrl rx error */
        EDMA_ERR_LNK_CTRL_RX_2  = (1 << 15),
-       EDMA_ERR_LNK_DATA_RX    = (0xf << 17),
-       EDMA_ERR_LNK_CTRL_TX    = (0x1f << 21),
-       EDMA_ERR_LNK_DATA_TX    = (0x1f << 26),
-       EDMA_ERR_TRANS_PROTO    = (1 << 31),
+       EDMA_ERR_LNK_DATA_RX    = (0xf << 17),  /* link data rx error */
+       EDMA_ERR_LNK_CTRL_TX    = (0x1f << 21), /* link ctrl tx error */
+       EDMA_ERR_LNK_DATA_TX    = (0x1f << 26), /* link data tx error */
+       EDMA_ERR_TRANS_PROTO    = (1 << 31),    /* transport protocol error */
        EDMA_ERR_OVERRUN_5      = (1 << 5),
        EDMA_ERR_UNDERRUN_5     = (1 << 6),
        EDMA_EH_FREEZE          = EDMA_ERR_D_PAR |
@@ -255,7 +253,7 @@ enum {
                                  EDMA_ERR_DEV_CON |
                                  EDMA_ERR_SERR |
                                  EDMA_ERR_SELF_DIS |
-                                 EDMA_ERR_CRBQ_PAR |
+                                 EDMA_ERR_CRQB_PAR |
                                  EDMA_ERR_CRPB_PAR |
                                  EDMA_ERR_INTRL_PAR |
                                  EDMA_ERR_IORDY |
@@ -270,7 +268,7 @@ enum {
                                  EDMA_ERR_OVERRUN_5 |
                                  EDMA_ERR_UNDERRUN_5 |
                                  EDMA_ERR_SELF_DIS_5 |
-                                 EDMA_ERR_CRBQ_PAR |
+                                 EDMA_ERR_CRQB_PAR |
                                  EDMA_ERR_CRPB_PAR |
                                  EDMA_ERR_INTRL_PAR |
                                  EDMA_ERR_IORDY,
@@ -286,10 +284,10 @@ enum {
        EDMA_RSP_Q_OUT_PTR_OFS  = 0x24,         /* also contains BASE_LO */
        EDMA_RSP_Q_PTR_SHIFT    = 3,
 
-       EDMA_CMD_OFS            = 0x28,
-       EDMA_EN                 = (1 << 0),
-       EDMA_DS                 = (1 << 1),
-       ATA_RST                 = (1 << 2),
+       EDMA_CMD_OFS            = 0x28,         /* EDMA command register */
+       EDMA_EN                 = (1 << 0),     /* enable EDMA */
+       EDMA_DS                 = (1 << 1),     /* disable EDMA; self-negated */
+       ATA_RST                 = (1 << 2),     /* reset trans/link/phy */
 
        EDMA_IORDY_TMOUT        = 0x34,
        EDMA_ARB_CFG            = 0x38,
@@ -301,26 +299,28 @@ enum {
        MV_HP_ERRATA_60X1B2     = (1 << 3),
        MV_HP_ERRATA_60X1C0     = (1 << 4),
        MV_HP_ERRATA_XX42A0     = (1 << 5),
-       MV_HP_50XX              = (1 << 6),
-       MV_HP_GEN_IIE           = (1 << 7),
+       MV_HP_GEN_I             = (1 << 6),     /* Generation I: 50xx */
+       MV_HP_GEN_II            = (1 << 7),     /* Generation II: 60xx */
+       MV_HP_GEN_IIE           = (1 << 8),     /* Generation IIE: 6042/7042 */
 
        /* Port private flags (pp_flags) */
-       MV_PP_FLAG_EDMA_EN      = (1 << 0),
-       MV_PP_FLAG_EDMA_DS_ACT  = (1 << 1),
-       MV_PP_FLAG_HAD_A_RESET  = (1 << 2),
+       MV_PP_FLAG_EDMA_EN      = (1 << 0),     /* is EDMA engine enabled? */
+       MV_PP_FLAG_HAD_A_RESET  = (1 << 2),     /* 1st hard reset complete? */
 };
 
-#define IS_50XX(hpriv) ((hpriv)->hp_flags & MV_HP_50XX)
-#define IS_60XX(hpriv) (((hpriv)->hp_flags & MV_HP_50XX) == 0)
-#define IS_GEN_I(hpriv) IS_50XX(hpriv)
-#define IS_GEN_II(hpriv) IS_60XX(hpriv)
+#define IS_GEN_I(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_I)
+#define IS_GEN_II(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_II)
 #define IS_GEN_IIE(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_IIE)
 
 enum {
        MV_DMA_BOUNDARY         = 0xffffffffU,
 
+       /* mask of register bits containing lower 32 bits
+        * of EDMA request queue DMA address
+        */
        EDMA_REQ_Q_BASE_LO_MASK = 0xfffffc00U,
 
+       /* ditto, for response queue */
        EDMA_RSP_Q_BASE_LO_MASK = 0xffffff00U,
 };
 
@@ -404,10 +404,10 @@ struct mv_host_priv {
 };
 
 static void mv_irq_clear(struct ata_port *ap);
-static u32 mv_scr_read(struct ata_port *ap, unsigned int sc_reg_in);
-static void mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val);
-static u32 mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in);
-static void mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val);
+static int mv_scr_read(struct ata_port *ap, unsigned int sc_reg_in, u32 *val);
+static int mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val);
+static int mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in, u32 *val);
+static int mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val);
 static int mv_port_start(struct ata_port *ap);
 static void mv_port_stop(struct ata_port *ap);
 static void mv_qc_prep(struct ata_queued_cmd *qc);
@@ -824,7 +824,7 @@ static void mv_start_dma(void __iomem *base, struct mv_host_priv *hpriv,
 }
 
 /**
- *      mv_stop_dma - Disable eDMA engine
+ *      __mv_stop_dma - Disable eDMA engine
  *      @ap: ATA channel to manipulate
  *
  *      Verify the local cache of the eDMA state is accurate with a
@@ -833,7 +833,7 @@ static void mv_start_dma(void __iomem *base, struct mv_host_priv *hpriv,
  *      LOCKING:
  *      Inherited from caller.
  */
-static int mv_stop_dma(struct ata_port *ap)
+static int __mv_stop_dma(struct ata_port *ap)
 {
        void __iomem *port_mmio = mv_ap_base(ap);
        struct mv_port_priv *pp = ap->private_data;
@@ -866,6 +866,18 @@ static int mv_stop_dma(struct ata_port *ap)
        return err;
 }
 
+static int mv_stop_dma(struct ata_port *ap)
+{
+       unsigned long flags;
+       int rc;
+
+       spin_lock_irqsave(&ap->host->lock, flags);
+       rc = __mv_stop_dma(ap);
+       spin_unlock_irqrestore(&ap->host->lock, flags);
+
+       return rc;
+}
+
 #ifdef ATA_DEBUG
 static void mv_dump_mem(void __iomem *start, unsigned bytes)
 {
@@ -962,22 +974,26 @@ static unsigned int mv_scr_offset(unsigned int sc_reg_in)
        return ofs;
 }
 
-static u32 mv_scr_read(struct ata_port *ap, unsigned int sc_reg_in)
+static int mv_scr_read(struct ata_port *ap, unsigned int sc_reg_in, u32 *val)
 {
        unsigned int ofs = mv_scr_offset(sc_reg_in);
 
-       if (0xffffffffU != ofs)
-               return readl(mv_ap_base(ap) + ofs);
-       else
-               return (u32) ofs;
+       if (ofs != 0xffffffffU) {
+               *val = readl(mv_ap_base(ap) + ofs);
+               return 0;
+       } else
+               return -EINVAL;
 }
 
-static void mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val)
+static int mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val)
 {
        unsigned int ofs = mv_scr_offset(sc_reg_in);
 
-       if (0xffffffffU != ofs)
+       if (ofs != 0xffffffffU) {
                writelfl(val, mv_ap_base(ap) + ofs);
+               return 0;
+       } else
+               return -EINVAL;
 }
 
 static void mv_edma_cfg(struct ata_port *ap, struct mv_host_priv *hpriv,
@@ -1030,6 +1046,7 @@ static int mv_port_start(struct ata_port *ap)
        void __iomem *port_mmio = mv_ap_base(ap);
        void *mem;
        dma_addr_t mem_dma;
+       unsigned long flags;
        int rc;
 
        pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
@@ -1068,10 +1085,14 @@ static int mv_port_start(struct ata_port *ap)
        pp->sg_tbl = mem;
        pp->sg_tbl_dma = mem_dma;
 
+       spin_lock_irqsave(&ap->host->lock, flags);
+
        mv_edma_cfg(ap, hpriv, port_mmio);
 
        mv_set_edma_ptrs(port_mmio, hpriv, pp);
 
+       spin_unlock_irqrestore(&ap->host->lock, flags);
+
        /* Don't turn on EDMA here...do it before DMA commands only.  Else
         * we'll be unable to send non-data, PIO, etc due to restricted access
         * to shadow regs.
@@ -1091,11 +1112,7 @@ static int mv_port_start(struct ata_port *ap)
  */
 static void mv_port_stop(struct ata_port *ap)
 {
-       unsigned long flags;
-
-       spin_lock_irqsave(&ap->host->lock, flags);
        mv_stop_dma(ap);
-       spin_unlock_irqrestore(&ap->host->lock, flags);
 }
 
 /**
@@ -1326,7 +1343,7 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc)
                 * port.  Turn off EDMA so there won't be problems accessing
                 * shadow block, etc registers.
                 */
-               mv_stop_dma(ap);
+               __mv_stop_dma(ap);
                return ata_qc_issue_prot(qc);
        }
 
@@ -1394,25 +1411,25 @@ static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
        if (edma_err_cause & EDMA_ERR_DEV)
                err_mask |= AC_ERR_DEV;
        if (edma_err_cause & (EDMA_ERR_D_PAR | EDMA_ERR_PRD_PAR |
-                       EDMA_ERR_CRBQ_PAR | EDMA_ERR_CRPB_PAR |
+                       EDMA_ERR_CRQB_PAR | EDMA_ERR_CRPB_PAR |
                        EDMA_ERR_INTRL_PAR)) {
                err_mask |= AC_ERR_ATA_BUS;
                action |= ATA_EH_HARDRESET;
-               ata_ehi_push_desc(ehi, "parity error");
+               ata_ehi_push_desc(ehi, "parity error");
        }
        if (edma_err_cause & (EDMA_ERR_DEV_DCON | EDMA_ERR_DEV_CON)) {
                ata_ehi_hotplugged(ehi);
                ata_ehi_push_desc(ehi, edma_err_cause & EDMA_ERR_DEV_DCON ?
-                       ", dev disconnect" : ", dev connect");
+                       "dev disconnect" : "dev connect");
        }
 
-       if (IS_50XX(hpriv)) {
+       if (IS_GEN_I(hpriv)) {
                eh_freeze_mask = EDMA_EH_FREEZE_5;
 
                if (edma_err_cause & EDMA_ERR_SELF_DIS_5) {
                        struct mv_port_priv *pp = ap->private_data;
                        pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN;
-                       ata_ehi_push_desc(ehi, "EDMA self-disable");
+                       ata_ehi_push_desc(ehi, "EDMA self-disable");
                }
        } else {
                eh_freeze_mask = EDMA_EH_FREEZE;
@@ -1420,7 +1437,7 @@ static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
                if (edma_err_cause & EDMA_ERR_SELF_DIS) {
                        struct mv_port_priv *pp = ap->private_data;
                        pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN;
-                       ata_ehi_push_desc(ehi, "EDMA self-disable");
+                       ata_ehi_push_desc(ehi, "EDMA self-disable");
                }
 
                if (edma_err_cause & EDMA_ERR_SERR) {
@@ -1490,33 +1507,30 @@ static void mv_intr_edma(struct ata_port *ap)
 
        while (1) {
                u16 status;
+               unsigned int tag;
 
                /* get s/w response queue last-read pointer, and compare */
                out_index = pp->resp_idx & MV_MAX_Q_DEPTH_MASK;
                if (in_index == out_index)
                        break;
 
-                
                /* 50xx: get active ATA command */
-               if (IS_GEN_I(hpriv)) 
-                       qc = ata_qc_from_tag(ap, ap->active_tag);
+               if (IS_GEN_I(hpriv))
+                       tag = ap->active_tag;
 
-               /* 60xx: get active ATA command via tag, to enable support
-                * for queueing.  this works transparently for queued and
-                * non-queued modes.
+               /* Gen II/IIE: get active ATA command via tag, to enable
+                * support for queueing.  this works transparently for
+                * queued and non-queued modes.
                 */
-               else {
-                       unsigned int tag;
+               else if (IS_GEN_II(hpriv))
+                       tag = (le16_to_cpu(pp->crpb[out_index].id)
+                               >> CRPB_IOID_SHIFT_6) & 0x3f;
 
-                       if (IS_GEN_II(hpriv))
-                               tag = (le16_to_cpu(pp->crpb[out_index].id)
-                                       >> CRPB_IOID_SHIFT_6) & 0x3f;
-                       else
-                               tag = (le16_to_cpu(pp->crpb[out_index].id)
-                                       >> CRPB_IOID_SHIFT_7) & 0x3f;
+               else /* IS_GEN_IIE */
+                       tag = (le16_to_cpu(pp->crpb[out_index].id)
+                               >> CRPB_IOID_SHIFT_7) & 0x3f;
 
-                       qc = ata_qc_from_tag(ap, tag);
-               }
+               qc = ata_qc_from_tag(ap, tag);
 
                /* lower 8 bits of status are EDMA_ERR_IRQ_CAUSE_OFS
                 * bits (WARNING: might not necessarily be associated
@@ -1536,7 +1550,7 @@ static void mv_intr_edma(struct ata_port *ap)
                        ata_qc_complete(qc);
                }
 
-               /* advance software response queue pointer, to 
+               /* advance software response queue pointer, to
                 * indicate (after the loop completes) to hardware
                 * that we have consumed a response queue entry.
                 */
@@ -1742,36 +1756,37 @@ static unsigned int mv5_scr_offset(unsigned int sc_reg_in)
        return ofs;
 }
 
-static u32 mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in)
+static int mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in, u32 *val)
 {
        void __iomem *mmio = ap->host->iomap[MV_PRIMARY_BAR];
        void __iomem *addr = mv5_phy_base(mmio, ap->port_no);
        unsigned int ofs = mv5_scr_offset(sc_reg_in);
 
-       if (ofs != 0xffffffffU)
-               return readl(addr + ofs);
-       else
-               return (u32) ofs;
+       if (ofs != 0xffffffffU) {
+               *val = readl(addr + ofs);
+               return 0;
+       } else
+               return -EINVAL;
 }
 
-static void mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val)
+static int mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val)
 {
        void __iomem *mmio = ap->host->iomap[MV_PRIMARY_BAR];
        void __iomem *addr = mv5_phy_base(mmio, ap->port_no);
        unsigned int ofs = mv5_scr_offset(sc_reg_in);
 
-       if (ofs != 0xffffffffU)
+       if (ofs != 0xffffffffU) {
                writelfl(val, addr + ofs);
+               return 0;
+       } else
+               return -EINVAL;
 }
 
 static void mv5_reset_bus(struct pci_dev *pdev, void __iomem *mmio)
 {
-       u8 rev_id;
        int early_5080;
 
-       pci_read_config_byte(pdev, PCI_REVISION_ID, &rev_id);
-
-       early_5080 = (pdev->device == 0x5080) && (rev_id == 0);
+       early_5080 = (pdev->device == 0x5080) && (pdev->revision == 0);
 
        if (!early_5080) {
                u32 tmp = readl(mmio + MV_PCI_EXP_ROM_BAR_CTL);
@@ -2100,7 +2115,7 @@ static void mv_channel_reset(struct mv_host_priv *hpriv, void __iomem *mmio,
 
        writelfl(ATA_RST, port_mmio + EDMA_CMD_OFS);
 
-       if (IS_60XX(hpriv)) {
+       if (IS_GEN_II(hpriv)) {
                u32 ifctl = readl(port_mmio + SATA_INTERFACE_CTL);
                ifctl |= (1 << 7);              /* enable gen2i speed */
                ifctl = (ifctl & 0xfff) | 0x9b1000; /* from chip spec */
@@ -2116,7 +2131,7 @@ static void mv_channel_reset(struct mv_host_priv *hpriv, void __iomem *mmio,
 
        hpriv->ops->phy_errata(hpriv, mmio, port_no);
 
-       if (IS_50XX(hpriv))
+       if (IS_GEN_I(hpriv))
                mdelay(1);
 }
 
@@ -2142,9 +2157,17 @@ static void mv_phy_reset(struct ata_port *ap, unsigned int *class,
 
        VPRINTK("ENTER, port %u, mmio 0x%p\n", ap->port_no, port_mmio);
 
-       DPRINTK("S-regs after ATA_RST: SStat 0x%08x SErr 0x%08x "
-               "SCtrl 0x%08x\n", mv_scr_read(ap, SCR_STATUS),
-               mv_scr_read(ap, SCR_ERROR), mv_scr_read(ap, SCR_CONTROL));
+#ifdef DEBUG
+       {
+               u32 sstatus, serror, scontrol;
+
+               mv_scr_read(ap, SCR_STATUS, &sstatus);
+               mv_scr_read(ap, SCR_ERROR, &serror);
+               mv_scr_read(ap, SCR_CONTROL, &scontrol);
+               DPRINTK("S-regs after ATA_RST: SStat 0x%08x SErr 0x%08x "
+                       "SCtrl 0x%08x\n", status, serror, scontrol);
+       }
+#endif
 
        /* Issue COMRESET via SControl */
 comreset_retry:
@@ -2163,14 +2186,22 @@ comreset_retry:
        } while (time_before(jiffies, deadline));
 
        /* work around errata */
-       if (IS_60XX(hpriv) &&
+       if (IS_GEN_II(hpriv) &&
            (sstatus != 0x0) && (sstatus != 0x113) && (sstatus != 0x123) &&
            (retry-- > 0))
                goto comreset_retry;
 
-       DPRINTK("S-regs after PHY wake: SStat 0x%08x SErr 0x%08x "
-               "SCtrl 0x%08x\n", mv_scr_read(ap, SCR_STATUS),
-               mv_scr_read(ap, SCR_ERROR), mv_scr_read(ap, SCR_CONTROL));
+#ifdef DEBUG
+       {
+               u32 sstatus, serror, scontrol;
+
+               mv_scr_read(ap, SCR_STATUS, &sstatus);
+               mv_scr_read(ap, SCR_ERROR, &serror);
+               mv_scr_read(ap, SCR_CONTROL, &scontrol);
+               DPRINTK("S-regs after PHY wake: SStat 0x%08x SErr 0x%08x "
+                       "SCtrl 0x%08x\n", sstatus, serror, scontrol);
+       }
+#endif
 
        if (ata_port_offline(ap)) {
                *class = ATA_DEV_NONE;
@@ -2213,7 +2244,7 @@ static int mv_prereset(struct ata_port *ap, unsigned long deadline)
        struct mv_port_priv *pp = ap->private_data;
        struct ata_eh_context *ehc = &ap->eh_context;
        int rc;
-       
+
        rc = mv_stop_dma(ap);
        if (rc)
                ehc->i.action |= ATA_EH_HARDRESET;
@@ -2388,17 +2419,14 @@ 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;
 
-       pci_read_config_byte(pdev, PCI_REVISION_ID, &rev_id);
-
        switch(board_idx) {
        case chip_5080:
                hpriv->ops = &mv5xxx_ops;
-               hp_flags |= MV_HP_50XX;
+               hp_flags |= MV_HP_GEN_I;
 
-               switch (rev_id) {
+               switch (pdev->revision) {
                case 0x1:
                        hp_flags |= MV_HP_ERRATA_50XXB0;
                        break;
@@ -2416,9 +2444,9 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
        case chip_504x:
        case chip_508x:
                hpriv->ops = &mv5xxx_ops;
-               hp_flags |= MV_HP_50XX;
+               hp_flags |= MV_HP_GEN_I;
 
-               switch (rev_id) {
+               switch (pdev->revision) {
                case 0x0:
                        hp_flags |= MV_HP_ERRATA_50XXB0;
                        break;
@@ -2436,8 +2464,9 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
        case chip_604x:
        case chip_608x:
                hpriv->ops = &mv6xxx_ops;
+               hp_flags |= MV_HP_GEN_II;
 
-               switch (rev_id) {
+               switch (pdev->revision) {
                case 0x7:
                        hp_flags |= MV_HP_ERRATA_60X1B2;
                        break;
@@ -2455,10 +2484,9 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
        case chip_7042:
        case chip_6042:
                hpriv->ops = &mv6xxx_ops;
-
                hp_flags |= MV_HP_GEN_IIE;
 
-               switch (rev_id) {
+               switch (pdev->revision) {
                case 0x0:
                        hp_flags |= MV_HP_ERRATA_XX42A0;
                        break;
@@ -2522,7 +2550,7 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx)
        hpriv->ops->enable_leds(hpriv, mmio);
 
        for (port = 0; port < host->n_ports; port++) {
-               if (IS_60XX(hpriv)) {
+               if (IS_GEN_II(hpriv)) {
                        void __iomem *port_mmio = mv_port_base(mmio, port);
 
                        u32 ifctl = readl(port_mmio + SATA_INTERFACE_CTL);
@@ -2557,7 +2585,7 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx)
        /* and unmask interrupt generation for host regs */
        writelfl(PCI_UNMASK_ALL_IRQS, mmio + PCI_IRQ_MASK_OFS);
 
-       if (IS_50XX(hpriv))
+       if (IS_GEN_I(hpriv))
                writelfl(~HC_MAIN_MASKED_IRQS_5, mmio + HC_MAIN_IRQ_MASK_OFS);
        else
                writelfl(~HC_MAIN_MASKED_IRQS, mmio + HC_MAIN_IRQ_MASK_OFS);
@@ -2586,14 +2614,12 @@ static void mv_print_info(struct ata_host *host)
 {
        struct pci_dev *pdev = to_pci_dev(host->dev);
        struct mv_host_priv *hpriv = host->private_data;
-       u8 rev_id, scc;
+       u8 scc;
        const char *scc_s, *gen;
 
        /* Use this to determine the HW stepping of the chip so we know
         * what errata to workaround
         */
-       pci_read_config_byte(pdev, PCI_REVISION_ID, &rev_id);
-
        pci_read_config_byte(pdev, PCI_CLASS_DEVICE, &scc);
        if (scc == 0)
                scc_s = "SCSI";
@@ -2675,7 +2701,7 @@ static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        mv_print_info(host);
 
        pci_set_master(pdev);
-       pci_set_mwi(pdev);
+       pci_try_set_mwi(pdev);
        return ata_host_activate(host, pdev->irq, mv_interrupt, IRQF_SHARED,
                                 IS_GEN_I(hpriv) ? &mv5_sht : &mv6_sht);
 }