Merge branch 'for-2.6.35' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie...
[safe/jmp/linux-2.6] / drivers / ata / sata_promise.c
index 750d8cd..f03ad48 100644 (file)
@@ -33,6 +33,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/gfp.h>
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/blkdev.h>
@@ -56,6 +57,7 @@ enum {
        /* host register offsets (from host->iomap[PDC_MMIO_BAR]) */
        PDC_INT_SEQMASK         = 0x40, /* Mask of asserted SEQ INTs */
        PDC_FLASH_CTL           = 0x44, /* Flash control register */
+       PDC_PCI_CTL             = 0x48, /* PCI control/status reg */
        PDC_SATA_PLUG_CSR       = 0x6C, /* SATA Plug control/status reg */
        PDC2_SATA_PLUG_CSR      = 0x60, /* SATAII Plug control/status reg */
        PDC_TBG_MODE            = 0x41C, /* TBG mode (not SATAII) */
@@ -75,7 +77,17 @@ enum {
        PDC_CTLSTAT             = 0x60, /* IDE control and status (per port) */
 
        /* per-port SATA register offsets (from ap->ioaddr.scr_addr) */
+       PDC_SATA_ERROR          = 0x04,
        PDC_PHYMODE4            = 0x14,
+       PDC_LINK_LAYER_ERRORS   = 0x6C,
+       PDC_FPDMA_CTLSTAT       = 0xD8,
+       PDC_INTERNAL_DEBUG_1    = 0xF8, /* also used for PATA */
+       PDC_INTERNAL_DEBUG_2    = 0xFC, /* also used for PATA */
+
+       /* PDC_FPDMA_CTLSTAT bit definitions */
+       PDC_FPDMA_CTLSTAT_RESET                 = 1 << 3,
+       PDC_FPDMA_CTLSTAT_DMASETUP_INT_FLAG     = 1 << 10,
+       PDC_FPDMA_CTLSTAT_SETDB_INT_FLAG        = 1 << 11,
 
        /* PDC_GLOBAL_CTL bit definitions */
        PDC_PH_ERR              = (1 <<  8), /* PCI error while loading packet */
@@ -153,6 +165,10 @@ static void pdc_freeze(struct ata_port *ap);
 static void pdc_sata_freeze(struct ata_port *ap);
 static void pdc_thaw(struct ata_port *ap);
 static void pdc_sata_thaw(struct ata_port *ap);
+static int pdc_pata_softreset(struct ata_link *link, unsigned int *class,
+                             unsigned long deadline);
+static int pdc_sata_hardreset(struct ata_link *link, unsigned int *class,
+                             unsigned long deadline);
 static void pdc_error_handler(struct ata_port *ap);
 static void pdc_post_internal_cmd(struct ata_queued_cmd *qc);
 static int pdc_pata_cable_detect(struct ata_port *ap);
@@ -172,7 +188,9 @@ static const struct ata_port_operations pdc_common_ops = {
        .check_atapi_dma        = pdc_check_atapi_dma,
        .qc_prep                = pdc_qc_prep,
        .qc_issue               = pdc_qc_issue,
+
        .sff_irq_clear          = pdc_irq_clear,
+       .lost_interrupt         = ATA_OP_NULL,
 
        .post_internal_cmd      = pdc_post_internal_cmd,
        .error_handler          = pdc_error_handler,
@@ -186,11 +204,15 @@ static struct ata_port_operations pdc_sata_ops = {
        .scr_read               = pdc_sata_scr_read,
        .scr_write              = pdc_sata_scr_write,
        .port_start             = pdc_sata_port_start,
+       .hardreset              = pdc_sata_hardreset,
 };
 
-/* First-generation chips need a more restrictive ->check_atapi_dma op */
+/* First-generation chips need a more restrictive ->check_atapi_dma op,
+   and ->freeze/thaw that ignore the hotplug controls. */
 static struct ata_port_operations pdc_old_sata_ops = {
        .inherits               = &pdc_sata_ops,
+       .freeze                 = pdc_freeze,
+       .thaw                   = pdc_thaw,
        .check_atapi_dma        = pdc_old_sata_check_atapi_dma,
 };
 
@@ -200,6 +222,7 @@ static struct ata_port_operations pdc_pata_ops = {
        .freeze                 = pdc_freeze,
        .thaw                   = pdc_thaw,
        .port_start             = pdc_common_port_start,
+       .softreset              = pdc_pata_softreset,
 };
 
 static const struct ata_port_info pdc_port_info[] = {
@@ -207,8 +230,8 @@ static const struct ata_port_info pdc_port_info[] = {
        {
                .flags          = PDC_COMMON_FLAGS | ATA_FLAG_SATA |
                                  PDC_FLAG_SATA_PATA,
-               .pio_mask       = 0x1f, /* pio0-4 */
-               .mwdma_mask     = 0x07, /* mwdma0-2 */
+               .pio_mask       = ATA_PIO4,
+               .mwdma_mask     = ATA_MWDMA2,
                .udma_mask      = ATA_UDMA6,
                .port_ops       = &pdc_old_sata_ops,
        },
@@ -216,8 +239,8 @@ static const struct ata_port_info pdc_port_info[] = {
        [board_2037x_pata] =
        {
                .flags          = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS,
-               .pio_mask       = 0x1f, /* pio0-4 */
-               .mwdma_mask     = 0x07, /* mwdma0-2 */
+               .pio_mask       = ATA_PIO4,
+               .mwdma_mask     = ATA_MWDMA2,
                .udma_mask      = ATA_UDMA6,
                .port_ops       = &pdc_pata_ops,
        },
@@ -226,8 +249,8 @@ static const struct ata_port_info pdc_port_info[] = {
        {
                .flags          = PDC_COMMON_FLAGS | ATA_FLAG_SATA |
                                  PDC_FLAG_4_PORTS,
-               .pio_mask       = 0x1f, /* pio0-4 */
-               .mwdma_mask     = 0x07, /* mwdma0-2 */
+               .pio_mask       = ATA_PIO4,
+               .mwdma_mask     = ATA_MWDMA2,
                .udma_mask      = ATA_UDMA6,
                .port_ops       = &pdc_old_sata_ops,
        },
@@ -236,8 +259,8 @@ static const struct ata_port_info pdc_port_info[] = {
        {
                .flags          = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS |
                                  PDC_FLAG_4_PORTS,
-               .pio_mask       = 0x1f, /* pio0-4 */
-               .mwdma_mask     = 0x07, /* mwdma0-2 */
+               .pio_mask       = ATA_PIO4,
+               .mwdma_mask     = ATA_MWDMA2,
                .udma_mask      = ATA_UDMA6,
                .port_ops       = &pdc_pata_ops,
        },
@@ -246,8 +269,8 @@ static const struct ata_port_info pdc_port_info[] = {
        {
                .flags          = PDC_COMMON_FLAGS | ATA_FLAG_SATA |
                                  PDC_FLAG_GEN_II | PDC_FLAG_SATA_PATA,
-               .pio_mask       = 0x1f, /* pio0-4 */
-               .mwdma_mask     = 0x07, /* mwdma0-2 */
+               .pio_mask       = ATA_PIO4,
+               .mwdma_mask     = ATA_MWDMA2,
                .udma_mask      = ATA_UDMA6,
                .port_ops       = &pdc_sata_ops,
        },
@@ -256,8 +279,8 @@ static const struct ata_port_info pdc_port_info[] = {
        {
                .flags          = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS |
                                  PDC_FLAG_GEN_II,
-               .pio_mask       = 0x1f, /* pio0-4 */
-               .mwdma_mask     = 0x07, /* mwdma0-2 */
+               .pio_mask       = ATA_PIO4,
+               .mwdma_mask     = ATA_MWDMA2,
                .udma_mask      = ATA_UDMA6,
                .port_ops       = &pdc_pata_ops,
        },
@@ -266,8 +289,8 @@ static const struct ata_port_info pdc_port_info[] = {
        {
                .flags          = PDC_COMMON_FLAGS | ATA_FLAG_SATA |
                                  PDC_FLAG_GEN_II | PDC_FLAG_4_PORTS,
-               .pio_mask       = 0x1f, /* pio0-4 */
-               .mwdma_mask     = 0x07, /* mwdma0-2 */
+               .pio_mask       = ATA_PIO4,
+               .mwdma_mask     = ATA_MWDMA2,
                .udma_mask      = ATA_UDMA6,
                .port_ops       = &pdc_sata_ops,
        },
@@ -310,7 +333,8 @@ static int pdc_common_port_start(struct ata_port *ap)
        struct pdc_port_priv *pp;
        int rc;
 
-       rc = ata_port_start(ap);
+       /* we use the same prd table as bmdma, allocate it */
+       rc = ata_bmdma_port_start(ap);
        if (rc)
                return rc;
 
@@ -348,12 +372,76 @@ static int pdc_sata_port_start(struct ata_port *ap)
        return 0;
 }
 
+static void pdc_fpdma_clear_interrupt_flag(struct ata_port *ap)
+{
+       void __iomem *sata_mmio = ap->ioaddr.scr_addr;
+       u32 tmp;
+
+       tmp = readl(sata_mmio + PDC_FPDMA_CTLSTAT);
+       tmp |= PDC_FPDMA_CTLSTAT_DMASETUP_INT_FLAG;
+       tmp |= PDC_FPDMA_CTLSTAT_SETDB_INT_FLAG;
+
+       /* It's not allowed to write to the entire FPDMA_CTLSTAT register
+          when NCQ is running. So do a byte-sized write to bits 10 and 11. */
+       writeb(tmp >> 8, sata_mmio + PDC_FPDMA_CTLSTAT + 1);
+       readb(sata_mmio + PDC_FPDMA_CTLSTAT + 1); /* flush */
+}
+
+static void pdc_fpdma_reset(struct ata_port *ap)
+{
+       void __iomem *sata_mmio = ap->ioaddr.scr_addr;
+       u8 tmp;
+
+       tmp = (u8)readl(sata_mmio + PDC_FPDMA_CTLSTAT);
+       tmp &= 0x7F;
+       tmp |= PDC_FPDMA_CTLSTAT_RESET;
+       writeb(tmp, sata_mmio + PDC_FPDMA_CTLSTAT);
+       readl(sata_mmio + PDC_FPDMA_CTLSTAT); /* flush */
+       udelay(100);
+       tmp &= ~PDC_FPDMA_CTLSTAT_RESET;
+       writeb(tmp, sata_mmio + PDC_FPDMA_CTLSTAT);
+       readl(sata_mmio + PDC_FPDMA_CTLSTAT); /* flush */
+
+       pdc_fpdma_clear_interrupt_flag(ap);
+}
+
+static void pdc_not_at_command_packet_phase(struct ata_port *ap)
+{
+       void __iomem *sata_mmio = ap->ioaddr.scr_addr;
+       unsigned int i;
+       u32 tmp;
+
+       /* check not at ASIC packet command phase */
+       for (i = 0; i < 100; ++i) {
+               writel(0, sata_mmio + PDC_INTERNAL_DEBUG_1);
+               tmp = readl(sata_mmio + PDC_INTERNAL_DEBUG_2);
+               if ((tmp & 0xF) != 1)
+                       break;
+               udelay(100);
+       }
+}
+
+static void pdc_clear_internal_debug_record_error_register(struct ata_port *ap)
+{
+       void __iomem *sata_mmio = ap->ioaddr.scr_addr;
+
+       writel(0xffffffff, sata_mmio + PDC_SATA_ERROR);
+       writel(0xffff0000, sata_mmio + PDC_LINK_LAYER_ERRORS);
+}
+
 static void pdc_reset_port(struct ata_port *ap)
 {
        void __iomem *ata_ctlstat_mmio = ap->ioaddr.cmd_addr + PDC_CTLSTAT;
        unsigned int i;
        u32 tmp;
 
+       if (ap->flags & PDC_FLAG_GEN_II)
+               pdc_not_at_command_packet_phase(ap);
+
+       tmp = readl(ata_ctlstat_mmio);
+       tmp |= PDC_RESET;
+       writel(tmp, ata_ctlstat_mmio);
+
        for (i = 11; i > 0; i--) {
                tmp = readl(ata_ctlstat_mmio);
                if (tmp & PDC_RESET)
@@ -368,6 +456,11 @@ static void pdc_reset_port(struct ata_port *ap)
        tmp &= ~PDC_RESET;
        writel(tmp, ata_ctlstat_mmio);
        readl(ata_ctlstat_mmio);        /* flush */
+
+       if (sata_scr_valid(&ap->link) && (ap->flags & PDC_FLAG_GEN_II)) {
+               pdc_fpdma_reset(ap);
+               pdc_clear_internal_debug_record_error_register(ap);
+       }
 }
 
 static int pdc_pata_cable_detect(struct ata_port *ap)
@@ -407,7 +500,7 @@ static int pdc_sata_scr_write(struct ata_link *link,
 static void pdc_atapi_pkt(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
-       dma_addr_t sg_table = ap->prd_dma;
+       dma_addr_t sg_table = ap->bmdma_prd_dma;
        unsigned int cdb_len = qc->dev->cdb_len;
        u8 *cdb = qc->cdb;
        struct pdc_port_priv *pp = ap->private_data;
@@ -495,6 +588,7 @@ static void pdc_atapi_pkt(struct ata_queued_cmd *qc)
 static void pdc_fill_sg(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
+       struct ata_bmdma_prd *prd = ap->bmdma_prd;
        struct scatterlist *sg;
        const u32 SG_COUNT_ASIC_BUG = 41*4;
        unsigned int si, idx;
@@ -521,8 +615,8 @@ static void pdc_fill_sg(struct ata_queued_cmd *qc)
                        if ((offset + sg_len) > 0x10000)
                                len = 0x10000 - offset;
 
-                       ap->prd[idx].addr = cpu_to_le32(addr);
-                       ap->prd[idx].flags_len = cpu_to_le32(len & 0xffff);
+                       prd[idx].addr = cpu_to_le32(addr);
+                       prd[idx].flags_len = cpu_to_le32(len & 0xffff);
                        VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", idx, addr, len);
 
                        idx++;
@@ -531,27 +625,27 @@ static void pdc_fill_sg(struct ata_queued_cmd *qc)
                }
        }
 
-       len = le32_to_cpu(ap->prd[idx - 1].flags_len);
+       len = le32_to_cpu(prd[idx - 1].flags_len);
 
        if (len > SG_COUNT_ASIC_BUG) {
                u32 addr;
 
                VPRINTK("Splitting last PRD.\n");
 
-               addr = le32_to_cpu(ap->prd[idx - 1].addr);
-               ap->prd[idx - 1].flags_len = cpu_to_le32(len - SG_COUNT_ASIC_BUG);
+               addr = le32_to_cpu(prd[idx - 1].addr);
+               prd[idx - 1].flags_len = cpu_to_le32(len - SG_COUNT_ASIC_BUG);
                VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", idx - 1, addr, SG_COUNT_ASIC_BUG);
 
                addr = addr + len - SG_COUNT_ASIC_BUG;
                len = SG_COUNT_ASIC_BUG;
-               ap->prd[idx].addr = cpu_to_le32(addr);
-               ap->prd[idx].flags_len = cpu_to_le32(len);
+               prd[idx].addr = cpu_to_le32(addr);
+               prd[idx].flags_len = cpu_to_le32(len);
                VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", idx, addr, len);
 
                idx++;
        }
 
-       ap->prd[idx - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT);
+       prd[idx - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT);
 }
 
 static void pdc_qc_prep(struct ata_queued_cmd *qc)
@@ -566,7 +660,7 @@ static void pdc_qc_prep(struct ata_queued_cmd *qc)
                pdc_fill_sg(qc);
                /*FALLTHROUGH*/
        case ATA_PROT_NODATA:
-               i = pdc_pkt_header(&qc->tf, qc->ap->prd_dma,
+               i = pdc_pkt_header(&qc->tf, qc->ap->bmdma_prd_dma,
                                   qc->dev->devno, pp->pkt);
                if (qc->tf.flags & ATA_TFLAG_LBA48)
                        i = pdc_prep_lba48(&qc->tf, pp->pkt, i);
@@ -618,11 +712,6 @@ static unsigned int pdc_sata_ata_port_to_ata_no(const struct ata_port *ap)
        return pdc_port_no_to_ata_no(i, pdc_is_sataii_tx4(ap->flags));
 }
 
-static unsigned int pdc_sata_hotplug_offset(const struct ata_port *ap)
-{
-       return (ap->flags & PDC_FLAG_GEN_II) ? PDC2_SATA_PLUG_CSR : PDC_SATA_PLUG_CSR;
-}
-
 static void pdc_freeze(struct ata_port *ap)
 {
        void __iomem *ata_mmio = ap->ioaddr.cmd_addr;
@@ -639,7 +728,7 @@ static void pdc_sata_freeze(struct ata_port *ap)
 {
        struct ata_host *host = ap->host;
        void __iomem *host_mmio = host->iomap[PDC_MMIO_BAR];
-       unsigned int hotplug_offset = pdc_sata_hotplug_offset(ap);
+       unsigned int hotplug_offset = PDC2_SATA_PLUG_CSR;
        unsigned int ata_no = pdc_sata_ata_port_to_ata_no(ap);
        u32 hotplug_status;
 
@@ -677,7 +766,7 @@ static void pdc_sata_thaw(struct ata_port *ap)
 {
        struct ata_host *host = ap->host;
        void __iomem *host_mmio = host->iomap[PDC_MMIO_BAR];
-       unsigned int hotplug_offset = pdc_sata_hotplug_offset(ap);
+       unsigned int hotplug_offset = PDC2_SATA_PLUG_CSR;
        unsigned int ata_no = pdc_sata_ata_port_to_ata_no(ap);
        u32 hotplug_status;
 
@@ -693,12 +782,65 @@ static void pdc_sata_thaw(struct ata_port *ap)
        readl(host_mmio + hotplug_offset); /* flush */
 }
 
+static int pdc_pata_softreset(struct ata_link *link, unsigned int *class,
+                             unsigned long deadline)
+{
+       pdc_reset_port(link->ap);
+       return ata_sff_softreset(link, class, deadline);
+}
+
+static unsigned int pdc_ata_port_to_ata_no(const struct ata_port *ap)
+{
+       void __iomem *ata_mmio = ap->ioaddr.cmd_addr;
+       void __iomem *host_mmio = ap->host->iomap[PDC_MMIO_BAR];
+
+       /* ata_mmio == host_mmio + 0x200 + ata_no * 0x80 */
+       return (ata_mmio - host_mmio - 0x200) / 0x80;
+}
+
+static void pdc_hard_reset_port(struct ata_port *ap)
+{
+       void __iomem *host_mmio = ap->host->iomap[PDC_MMIO_BAR];
+       void __iomem *pcictl_b1_mmio = host_mmio + PDC_PCI_CTL + 1;
+       unsigned int ata_no = pdc_ata_port_to_ata_no(ap);
+       u8 tmp;
+
+       spin_lock(&ap->host->lock);
+
+       tmp = readb(pcictl_b1_mmio);
+       tmp &= ~(0x10 << ata_no);
+       writeb(tmp, pcictl_b1_mmio);
+       readb(pcictl_b1_mmio); /* flush */
+       udelay(100);
+       tmp |= (0x10 << ata_no);
+       writeb(tmp, pcictl_b1_mmio);
+       readb(pcictl_b1_mmio); /* flush */
+
+       spin_unlock(&ap->host->lock);
+}
+
+static int pdc_sata_hardreset(struct ata_link *link, unsigned int *class,
+                             unsigned long deadline)
+{
+       if (link->ap->flags & PDC_FLAG_GEN_II)
+               pdc_not_at_command_packet_phase(link->ap);
+       /* hotplug IRQs should have been masked by pdc_sata_freeze() */
+       pdc_hard_reset_port(link->ap);
+       pdc_reset_port(link->ap);
+
+       /* sata_promise can't reliably acquire the first D2H Reg FIS
+        * after hardreset.  Do non-waiting hardreset and request
+        * follow-up SRST.
+        */
+       return sata_std_hardreset(link, class, deadline);
+}
+
 static void pdc_error_handler(struct ata_port *ap)
 {
        if (!(ap->pflags & ATA_PFLAG_FROZEN))
                pdc_reset_port(ap);
 
-       ata_std_error_handler(ap);
+       ata_sff_error_handler(ap);
 }
 
 static void pdc_post_internal_cmd(struct ata_queued_cmd *qc)
@@ -723,7 +865,7 @@ static void pdc_error_intr(struct ata_port *ap, struct ata_queued_cmd *qc,
        if (port_status & PDC_DRIVE_ERR)
                ac_err_mask |= AC_ERR_DEV;
        if (port_status & (PDC_OVERRUN_ERR | PDC_UNDERRUN_ERR))
-               ac_err_mask |= AC_ERR_HSM;
+               ac_err_mask |= AC_ERR_OTHER;
        if (port_status & (PDC2_ATA_HBA_ERR | PDC2_ATA_DMA_CNT_ERR))
                ac_err_mask |= AC_ERR_ATA_BUS;
        if (port_status & (PDC_PH_ERR | PDC_SH_ERR | PDC_DH_ERR | PDC2_HTO_ERR
@@ -810,14 +952,14 @@ static irqreturn_t pdc_interrupt(int irq, void *dev_instance)
        spin_lock(&host->lock);
 
        /* read and clear hotplug flags for all ports */
-       if (host->ports[0]->flags & PDC_FLAG_GEN_II)
+       if (host->ports[0]->flags & PDC_FLAG_GEN_II) {
                hotplug_offset = PDC2_SATA_PLUG_CSR;
-       else
-               hotplug_offset = PDC_SATA_PLUG_CSR;
-       hotplug_status = readl(host_mmio + hotplug_offset);
-       if (hotplug_status & 0xff)
-               writel(hotplug_status | 0xff, host_mmio + hotplug_offset);
-       hotplug_status &= 0xff; /* clear uninteresting bits */
+               hotplug_status = readl(host_mmio + hotplug_offset);
+               if (hotplug_status & 0xff)
+                       writel(hotplug_status | 0xff, host_mmio + hotplug_offset);
+               hotplug_status &= 0xff; /* clear uninteresting bits */
+       } else
+               hotplug_status = 0;
 
        /* reading should also clear interrupts */
        mask = readl(host_mmio + PDC_INT_SEQMASK);
@@ -844,8 +986,7 @@ static irqreturn_t pdc_interrupt(int irq, void *dev_instance)
                /* check for a plug or unplug event */
                ata_no = pdc_port_no_to_ata_no(i, is_sataii_tx4);
                tmp = hotplug_status & (0x11 << ata_no);
-               if (tmp && ap &&
-                   !(ap->flags & ATA_FLAG_DISABLED)) {
+               if (tmp) {
                        struct ata_eh_info *ehi = &ap->link.eh_info;
                        ata_ehi_clear_desc(ehi);
                        ata_ehi_hotplugged(ehi);
@@ -857,8 +998,7 @@ static irqreturn_t pdc_interrupt(int irq, void *dev_instance)
 
                /* check for a packet interrupt */
                tmp = mask & (1 << (i + 1));
-               if (tmp && ap &&
-                   !(ap->flags & ATA_FLAG_DISABLED)) {
+               if (tmp) {
                        struct ata_queued_cmd *qc;
 
                        qc = ata_qc_from_tag(ap, ap->link.active_tag);
@@ -1012,9 +1152,11 @@ static void pdc_host_init(struct ata_host *host)
        tmp = readl(host_mmio + hotplug_offset);
        writel(tmp | 0xff, host_mmio + hotplug_offset);
 
-       /* unmask plug/unplug ints */
        tmp = readl(host_mmio + hotplug_offset);
-       writel(tmp & ~0xff0000, host_mmio + hotplug_offset);
+       if (is_gen2)    /* unmask plug/unplug ints */
+               writel(tmp & ~0xff0000, host_mmio + hotplug_offset);
+       else            /* mask plug/unplug ints */
+               writel(tmp | 0xff0000, host_mmio + hotplug_offset);
 
        /* don't initialise TBG or SLEW on 2nd generation chips */
        if (is_gen2)