w1: fix omap 1-wire driver compilation
[safe/jmp/linux-2.6] / drivers / ata / pata_hpt366.c
index 4824821..af49bfb 100644 (file)
@@ -11,9 +11,7 @@
  *
  *
  * TODO
- *     Maybe PLL mode
- *     Look into engine reset on timeout errors. Should not be
- *             required.
+ *     Look into engine reset on timeout errors. Should not be required.
  */
 
 
 #include <linux/libata.h>
 
 #define DRV_NAME       "pata_hpt366"
-#define DRV_VERSION    "0.6.2"
+#define DRV_VERSION    "0.6.8"
 
 struct hpt_clock {
-       u8      xfer_speed;
+       u8      xfer_mode;
        u32     timing;
 };
 
 /* key for bus clock timings
  * bit
- * 0:3    data_high_time. inactive time of DIOW_/DIOR_ for PIO and MW
- *        DMA. cycles = value + 1
- * 4:8    data_low_time. active time of DIOW_/DIOR_ for PIO and MW
- *        DMA. cycles = value + 1
- * 9:12   cmd_high_time. inactive time of DIOW_/DIOR_ during task file
+ * 0:3    data_high_time. Inactive time of DIOW_/DIOR_ for PIO and MW DMA.
+ *        cycles = value + 1
+ * 4:7    data_low_time. Active time of DIOW_/DIOR_ for PIO and MW DMA.
+ *        cycles = value + 1
+ * 8:11   cmd_high_time. Inactive time of DIOW_/DIOR_ during task file
  *        register access.
- * 13:17  cmd_low_time. active time of DIOW_/DIOR_ during task file
+ * 12:15  cmd_low_time. Active time of DIOW_/DIOR_ during task file
  *        register access.
- * 18:21  udma_cycle_time. clock freq and clock cycles for UDMA xfer.
- *        during task file register access.
- * 22:24  pre_high_time. time to initialize 1st cycle for PIO and MW DMA
- *        xfer.
- * 25:27  cmd_pre_high_time. time to initialize 1st PIO cycle for task
+ * 16:18  udma_cycle_time. Clock cycles for UDMA xfer?
+ * 19:21  pre_high_time. Time to initialize 1st cycle for PIO and MW DMA xfer.
+ * 22:24  cmd_pre_high_time. Time to initialize 1st PIO cycle for task file
  *        register access.
- * 28     UDMA enable
- * 29     DMA enable
- * 30     PIO_MST enable. if set, the chip is in bus master mode during
- *        PIO.
+ * 28     UDMA enable.
+ * 29     DMA  enable.
+ * 30     PIO_MST enable. If set, the chip is in bus master mode during
+ *        PIO xfer.
  * 31     FIFO enable.
  */
 
@@ -183,30 +179,10 @@ static unsigned long hpt366_filter(struct ata_device *adev, unsigned long mask)
                        mask &= ~(0xF8 << ATA_SHIFT_UDMA);
                if (hpt_dma_blacklisted(adev, "UDMA4", bad_ata66_4))
                        mask &= ~(0xF0 << ATA_SHIFT_UDMA);
-       }
-       return ata_bmdma_mode_filter(adev, mask);
-}
-
-/**
- *     hpt36x_find_mode        -       reset the hpt36x bus
- *     @ap: ATA port
- *     @speed: transfer mode
- *
- *     Return the 32bit register programming information for this channel
- *     that matches the speed provided.
- */
-
-static u32 hpt36x_find_mode(struct ata_port *ap, int speed)
-{
-       struct hpt_clock *clocks = ap->host->private_data;
+       } else if (adev->class == ATA_DEV_ATAPI)
+               mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
 
-       while(clocks->xfer_speed) {
-               if (clocks->xfer_speed == speed)
-                       return clocks->timing;
-               clocks++;
-       }
-       BUG();
-       return 0xffffffffU;     /* silence compiler warning */
+       return ata_bmdma_mode_filter(adev, mask);
 }
 
 static int hpt36x_cable_detect(struct ata_port *ap)
@@ -224,6 +200,40 @@ static int hpt36x_cable_detect(struct ata_port *ap)
        return ATA_CBL_PATA80;
 }
 
+static void hpt366_set_mode(struct ata_port *ap, struct ata_device *adev,
+                           u8 mode)
+{
+       struct hpt_clock *clocks = ap->host->private_data;
+       struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+       u32 addr = 0x40 + 4 * adev->devno;
+       u32 mask, reg;
+
+       /* determine timing mask and find matching clock entry */
+       if (mode < XFER_MW_DMA_0)
+               mask = 0xc1f8ffff;
+       else if (mode < XFER_UDMA_0)
+               mask = 0x303800ff;
+       else
+               mask = 0x30070000;
+
+       while (clocks->xfer_mode) {
+               if (clocks->xfer_mode == mode)
+                       break;
+               clocks++;
+       }
+       if (!clocks->xfer_mode)
+               BUG();
+
+       /*
+        * Combine new mode bits with old config bits and disable
+        * on-chip PIO FIFO/buffer (and PIO MST mode as well) to avoid
+        * problems handling I/O errors later.
+        */
+       pci_read_config_dword(pdev, addr, &reg);
+       reg = ((reg & ~mask) | (clocks->timing & mask)) & ~0xc0000000;
+       pci_write_config_dword(pdev, addr, reg);
+}
+
 /**
  *     hpt366_set_piomode              -       PIO setup
  *     @ap: ATA interface
@@ -234,28 +244,7 @@ static int hpt36x_cable_detect(struct ata_port *ap)
 
 static void hpt366_set_piomode(struct ata_port *ap, struct ata_device *adev)
 {
-       struct pci_dev *pdev = to_pci_dev(ap->host->dev);
-       u32 addr1, addr2;
-       u32 reg;
-       u32 mode;
-       u8 fast;
-
-       addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
-       addr2 = 0x51 + 4 * ap->port_no;
-
-       /* Fast interrupt prediction disable, hold off interrupt disable */
-       pci_read_config_byte(pdev, addr2, &fast);
-       if (fast & 0x80) {
-               fast &= ~0x80;
-               pci_write_config_byte(pdev, addr2, fast);
-       }
-
-       pci_read_config_dword(pdev, addr1, &reg);
-       mode = hpt36x_find_mode(ap, adev->pio_mode);
-       mode &= ~0x8000000;     /* No FIFO in PIO */
-       mode &= ~0x30070000;    /* Leave config bits alone */
-       reg &= 0x30070000;      /* Strip timing bits */
-       pci_write_config_dword(pdev, addr1, reg | mode);
+       hpt366_set_mode(ap, adev, adev->pio_mode);
 }
 
 /**
@@ -269,28 +258,7 @@ static void hpt366_set_piomode(struct ata_port *ap, struct ata_device *adev)
 
 static void hpt366_set_dmamode(struct ata_port *ap, struct ata_device *adev)
 {
-       struct pci_dev *pdev = to_pci_dev(ap->host->dev);
-       u32 addr1, addr2;
-       u32 reg;
-       u32 mode;
-       u8 fast;
-
-       addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
-       addr2 = 0x51 + 4 * ap->port_no;
-
-       /* Fast interrupt prediction disable, hold off interrupt disable */
-       pci_read_config_byte(pdev, addr2, &fast);
-       if (fast & 0x80) {
-               fast &= ~0x80;
-               pci_write_config_byte(pdev, addr2, fast);
-       }
-
-       pci_read_config_dword(pdev, addr1, &reg);
-       mode = hpt36x_find_mode(ap, adev->dma_mode);
-       mode |= 0x8000000;      /* FIFO in MWDMA or UDMA */
-       mode &= ~0xC0000000;    /* Leave config bits alone */
-       reg &= 0xC0000000;      /* Strip timing bits */
-       pci_write_config_dword(pdev, addr1, reg | mode);
+       hpt366_set_mode(ap, adev, adev->dma_mode);
 }
 
 static struct scsi_host_template hpt36x_sht = {
@@ -355,15 +323,14 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
        static const struct ata_port_info info_hpt366 = {
                .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 = &hpt366_port_ops
        };
        const struct ata_port_info *ppi[] = { &info_hpt366, NULL };
 
        void *hpriv = NULL;
-       u32 class_rev;
        u32 reg1;
        int rc;
 
@@ -371,13 +338,10 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
        if (rc)
                return rc;
 
-       pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
-       class_rev &= 0xFF;
-
        /* May be a later chip in disguise. Check */
        /* Newer chips are not in the HPT36x driver. Ignore them */
-       if (class_rev > 2)
-                       return -ENODEV;
+       if (dev->revision > 2)
+               return -ENODEV;
 
        hpt36x_init_chipset(dev);
 
@@ -397,7 +361,7 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
                        break;
        }
        /* Now kick off ATA set up */
-       return ata_pci_sff_init_one(dev, ppi, &hpt36x_sht, hpriv);
+       return ata_pci_sff_init_one(dev, ppi, &hpt36x_sht, hpriv, 0);
 }
 
 #ifdef CONFIG_PM