Merge branch 'nfs-for-2.6.35' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6
[safe/jmp/linux-2.6] / drivers / ata / pata_cmd64x.c
index f0e5666..4c81a71 100644 (file)
@@ -1,7 +1,8 @@
 /*
  * pata_cmd64x.c       - CMD64x PATA for new ATA layer
  *                       (C) 2005 Red Hat Inc
- *                       Alan Cox <alan@redhat.com>
+ *                       Alan Cox <alan@lxorguk.ukuu.org.uk>
+ *                       (C) 2009-2010 Bartlomiej Zolnierkiewicz
  *
  * Based upon
  * linux/drivers/ide/pci/cmd64x.c              Version 1.30    Sept 10, 2002
 
 enum {
        CFR             = 0x50,
-               CFR_INTR_CH0  = 0x02,
-       CNTRL           = 0x51,
-               CNTRL_DIS_RA0 = 0x40,
-               CNTRL_DIS_RA1 = 0x80,
-               CNTRL_ENA_2ND = 0x08,
+               CFR_INTR_CH0  = 0x04,
        CMDTIM          = 0x52,
        ARTTIM0         = 0x53,
        DRWTIM0         = 0x54,
@@ -53,9 +50,6 @@ enum {
                ARTTIM23_DIS_RA2  = 0x04,
                ARTTIM23_DIS_RA3  = 0x08,
                ARTTIM23_INTR_CH1 = 0x10,
-       ARTTIM2         = 0x57,
-       ARTTIM3         = 0x57,
-       DRWTIM23        = 0x58,
        DRWTIM2         = 0x58,
        BRST            = 0x59,
        DRWTIM3         = 0x5b,
@@ -63,14 +57,11 @@ enum {
        MRDMODE         = 0x71,
                MRDMODE_INTR_CH0 = 0x04,
                MRDMODE_INTR_CH1 = 0x08,
-               MRDMODE_BLK_CH0  = 0x10,
-               MRDMODE_BLK_CH1  = 0x20,
        BMIDESR0        = 0x72,
        UDIDETCR0       = 0x73,
        DTPR0           = 0x74,
        BMIDECR1        = 0x78,
        BMIDECSR        = 0x79,
-       BMIDESR1        = 0x7A,
        UDIDETCR1       = 0x7B,
        DTPR1           = 0x7C
 };
@@ -130,8 +121,14 @@ static void cmd64x_set_timing(struct ata_port *ap, struct ata_device *adev, u8 m
 
                if (pair) {
                        struct ata_timing tp;
+
                        ata_timing_compute(pair, pair->pio_mode, &tp, T, 0);
                        ata_timing_merge(&t, &tp, &t, ATA_TIMING_SETUP);
+                       if (pair->dma_mode) {
+                               ata_timing_compute(pair, pair->dma_mode,
+                                               &tp, T, 0);
+                               ata_timing_merge(&tp, &t, &t, ATA_TIMING_SETUP);
+                       }
                }
        }
 
@@ -147,7 +144,9 @@ static void cmd64x_set_timing(struct ata_port *ap, struct ata_device *adev, u8 m
        /* Now convert the clocks into values we can actually stuff into
           the chip */
 
-       if (t.recover > 1)
+       if (t.recover == 16)
+               t.recover = 0;
+       else if (t.recover > 1)
                t.recover--;
        else
                t.recover = 15;
@@ -219,7 +218,7 @@ static void cmd64x_set_dmamode(struct ata_port *ap, struct ata_device *adev)
                regU |= udma_data[adev->dma_mode - XFER_UDMA_0] << shift;
                /* Merge the control bits */
                regU |= 1 << adev->devno; /* UDMA on */
-               if (adev->dma_mode > 2) /* 15nS timing */
+               if (adev->dma_mode > XFER_UDMA_2) /* 15nS timing */
                        regU |= 4 << adev->devno;
        } else {
                regU &= ~ (1 << adev->devno);   /* UDMA off */
@@ -245,7 +244,7 @@ static void cmd648_bmdma_stop(struct ata_queued_cmd *qc)
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
        u8 dma_intr;
        int dma_mask = ap->port_no ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0;
-       int dma_reg = ap->port_no ? ARTTIM2 : CFR;
+       int dma_reg = ap->port_no ? ARTTIM23 : CFR;
 
        ata_bmdma_stop(qc);
 
@@ -294,45 +293,43 @@ static struct ata_port_operations cmd648_port_ops = {
 
 static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
 {
-       u32 class_rev;
-
        static const struct ata_port_info cmd_info[6] = {
                {       /* CMD 643 - no UDMA */
                        .flags = ATA_FLAG_SLAVE_POSS,
-                       .pio_mask = 0x1f,
-                       .mwdma_mask = 0x07,
+                       .pio_mask = ATA_PIO4,
+                       .mwdma_mask = ATA_MWDMA2,
                        .port_ops = &cmd64x_port_ops
                },
                {       /* CMD 646 with broken UDMA */
                        .flags = ATA_FLAG_SLAVE_POSS,
-                       .pio_mask = 0x1f,
-                       .mwdma_mask = 0x07,
+                       .pio_mask = ATA_PIO4,
+                       .mwdma_mask = ATA_MWDMA2,
                        .port_ops = &cmd64x_port_ops
                },
                {       /* CMD 646 with working UDMA */
                        .flags = ATA_FLAG_SLAVE_POSS,
-                       .pio_mask = 0x1f,
-                       .mwdma_mask = 0x07,
+                       .pio_mask = ATA_PIO4,
+                       .mwdma_mask = ATA_MWDMA2,
                        .udma_mask = ATA_UDMA2,
                        .port_ops = &cmd64x_port_ops
                },
                {       /* CMD 646 rev 1  */
                        .flags = ATA_FLAG_SLAVE_POSS,
-                       .pio_mask = 0x1f,
-                       .mwdma_mask = 0x07,
+                       .pio_mask = ATA_PIO4,
+                       .mwdma_mask = ATA_MWDMA2,
                        .port_ops = &cmd646r1_port_ops
                },
                {       /* CMD 648 */
                        .flags = ATA_FLAG_SLAVE_POSS,
-                       .pio_mask = 0x1f,
-                       .mwdma_mask = 0x07,
+                       .pio_mask = ATA_PIO4,
+                       .mwdma_mask = ATA_MWDMA2,
                        .udma_mask = ATA_UDMA4,
                        .port_ops = &cmd648_port_ops
                },
                {       /* CMD 649 */
                        .flags = ATA_FLAG_SLAVE_POSS,
-                       .pio_mask = 0x1f,
-                       .mwdma_mask = 0x07,
+                       .pio_mask = ATA_PIO4,
+                       .mwdma_mask = ATA_MWDMA2,
                        .udma_mask = ATA_UDMA5,
                        .port_ops = &cmd648_port_ops
                }
@@ -345,18 +342,15 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
        if (rc)
                return rc;
 
-       pci_read_config_dword(pdev, PCI_CLASS_REVISION, &class_rev);
-       class_rev &= 0xFF;
-
        if (id->driver_data == 0)       /* 643 */
-               ata_pci_clear_simplex(pdev);
+               ata_pci_bmdma_clear_simplex(pdev);
 
        if (pdev->device == PCI_DEVICE_ID_CMD_646) {
                /* Does UDMA work ? */
-               if (class_rev > 4)
+               if (pdev->revision > 4)
                        ppi[0] = &cmd_info[2];
                /* Early rev with other problems ? */
-               else if (class_rev == 1)
+               else if (pdev->revision == 1)
                        ppi[0] = &cmd_info[3];
        }
 
@@ -373,7 +367,7 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
        pci_write_config_byte(pdev, UDIDETCR0, 0xF0);
 #endif
 
-       return ata_pci_init_one(pdev, ppi, &cmd64x_sht, NULL);
+       return ata_pci_sff_init_one(pdev, ppi, &cmd64x_sht, NULL, 0);
 }
 
 #ifdef CONFIG_PM