libata: add comment documenting PIO latency issues on UP
[safe/jmp/linux-2.6] / drivers / ata / pata_pdc2027x.c
index 31ab9c8..ca5cad0 100644 (file)
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_cmnd.h>
 #include <linux/libata.h>
-#include <asm/io.h>
 
 #define DRV_NAME       "pata_pdc2027x"
-#define DRV_VERSION    "0.74-ac3"
+#define DRV_VERSION    "1.0"
 #undef PDC_DEBUG
 
 #ifdef PDC_DEBUG
-#define PDPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
+#define PDPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ## args)
 #else
 #define PDPRINTK(fmt, args...)
 #endif
 
 enum {
+       PDC_MMIO_BAR            = 5,
+
        PDC_UDMA_100            = 0,
        PDC_UDMA_133            = 1,
 
@@ -62,12 +63,13 @@ enum {
 };
 
 static int pdc2027x_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
-static void pdc2027x_remove_one(struct pci_dev *pdev);
-static void pdc2027x_error_handler(struct ata_port *ap);
+static int pdc2027x_prereset(struct ata_link *link, unsigned long deadline);
 static void pdc2027x_set_piomode(struct ata_port *ap, struct ata_device *adev);
 static void pdc2027x_set_dmamode(struct ata_port *ap, struct ata_device *adev);
-static void pdc2027x_post_set_mode(struct ata_port *ap);
 static int pdc2027x_check_atapi_dma(struct ata_queued_cmd *qc);
+static unsigned long pdc2027x_mode_filter(struct ata_device *adev, unsigned long mask);
+static int pdc2027x_cable_detect(struct ata_port *ap);
+static int pdc2027x_set_mode(struct ata_link *link, struct ata_device **r_failed);
 
 /*
  * ATA Timing Tables based on 133MHz controller clock.
@@ -108,13 +110,14 @@ static struct pdc2027x_udma_timing {
 };
 
 static const struct pci_device_id pdc2027x_pci_tbl[] = {
-       { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20268, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PDC_UDMA_100 },
-       { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20269, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PDC_UDMA_133 },
-       { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20270, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PDC_UDMA_100 },
-       { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20271, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PDC_UDMA_133 },
-       { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20275, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PDC_UDMA_133 },
-       { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20276, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PDC_UDMA_133 },
-       { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20277, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PDC_UDMA_133 },
+       { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20268), PDC_UDMA_100 },
+       { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20269), PDC_UDMA_133 },
+       { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20270), PDC_UDMA_100 },
+       { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20271), PDC_UDMA_133 },
+       { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20275), PDC_UDMA_133 },
+       { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20276), PDC_UDMA_133 },
+       { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20277), PDC_UDMA_133 },
+
        { }     /* terminate list */
 };
 
@@ -122,111 +125,45 @@ static struct pci_driver pdc2027x_pci_driver = {
        .name                   = DRV_NAME,
        .id_table               = pdc2027x_pci_tbl,
        .probe                  = pdc2027x_init_one,
-       .remove                 = __devexit_p(pdc2027x_remove_one),
+       .remove                 = ata_pci_remove_one,
 };
 
 static struct scsi_host_template pdc2027x_sht = {
-       .module                 = THIS_MODULE,
-       .name                   = DRV_NAME,
-       .ioctl                  = ata_scsi_ioctl,
-       .queuecommand           = ata_scsi_queuecmd,
-       .can_queue              = ATA_DEF_QUEUE,
-       .this_id                = ATA_SHT_THIS_ID,
-       .sg_tablesize           = LIBATA_MAX_PRD,
-       .max_sectors            = ATA_MAX_SECTORS,
-       .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,
-       .bios_param             = ata_std_bios_param,
+       ATA_BMDMA_SHT(DRV_NAME),
 };
 
 static struct ata_port_operations pdc2027x_pata100_ops = {
-       .port_disable           = ata_port_disable,
-
-       .tf_load                = ata_tf_load,
-       .tf_read                = ata_tf_read,
-       .check_status           = ata_check_status,
-       .exec_command           = ata_exec_command,
-       .dev_select             = ata_std_dev_select,
-
+       .inherits               = &ata_bmdma_port_ops,
        .check_atapi_dma        = pdc2027x_check_atapi_dma,
-       .bmdma_setup            = ata_bmdma_setup,
-       .bmdma_start            = ata_bmdma_start,
-       .bmdma_stop             = ata_bmdma_stop,
-       .bmdma_status           = ata_bmdma_status,
-       .qc_prep                = ata_qc_prep,
-       .qc_issue               = ata_qc_issue_prot,
-       .data_xfer              = ata_mmio_data_xfer,
-
-       .freeze                 = ata_bmdma_freeze,
-       .thaw                   = ata_bmdma_thaw,
-       .error_handler          = pdc2027x_error_handler,
-       .post_internal_cmd      = ata_bmdma_post_internal_cmd,
-
-       .irq_handler            = ata_interrupt,
-       .irq_clear              = ata_bmdma_irq_clear,
-
-       .port_start             = ata_port_start,
-       .port_stop              = ata_port_stop,
-       .host_stop              = ata_pci_host_stop,
+       .cable_detect           = pdc2027x_cable_detect,
+       .prereset               = pdc2027x_prereset,
 };
 
 static struct ata_port_operations pdc2027x_pata133_ops = {
-       .port_disable           = ata_port_disable,
+       .inherits               = &pdc2027x_pata100_ops,
+       .mode_filter            = pdc2027x_mode_filter,
        .set_piomode            = pdc2027x_set_piomode,
        .set_dmamode            = pdc2027x_set_dmamode,
-       .post_set_mode          = pdc2027x_post_set_mode,
-
-       .tf_load                = ata_tf_load,
-       .tf_read                = ata_tf_read,
-       .check_status           = ata_check_status,
-       .exec_command           = ata_exec_command,
-       .dev_select             = ata_std_dev_select,
-
-       .check_atapi_dma        = pdc2027x_check_atapi_dma,
-       .bmdma_setup            = ata_bmdma_setup,
-       .bmdma_start            = ata_bmdma_start,
-       .bmdma_stop             = ata_bmdma_stop,
-       .bmdma_status           = ata_bmdma_status,
-       .qc_prep                = ata_qc_prep,
-       .qc_issue               = ata_qc_issue_prot,
-       .data_xfer              = ata_mmio_data_xfer,
-
-       .freeze                 = ata_bmdma_freeze,
-       .thaw                   = ata_bmdma_thaw,
-       .error_handler          = pdc2027x_error_handler,
-       .post_internal_cmd      = ata_bmdma_post_internal_cmd,
-
-       .irq_handler            = ata_interrupt,
-       .irq_clear              = ata_bmdma_irq_clear,
-
-       .port_start             = ata_port_start,
-       .port_stop              = ata_port_stop,
-       .host_stop              = ata_pci_host_stop,
+       .set_mode               = pdc2027x_set_mode,
 };
 
 static struct ata_port_info pdc2027x_port_info[] = {
        /* PDC_UDMA_100 */
        {
-               .sht            = &pdc2027x_sht,
                .flags          = ATA_FLAG_NO_LEGACY | ATA_FLAG_SLAVE_POSS |
                                  ATA_FLAG_MMIO,
-               .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       = &pdc2027x_pata100_ops,
        },
        /* PDC_UDMA_133 */
        {
-               .sht            = &pdc2027x_sht,
                .flags          = ATA_FLAG_NO_LEGACY | ATA_FLAG_SLAVE_POSS |
                                  ATA_FLAG_MMIO,
-               .pio_mask       = 0x1f, /* pio0-4 */
-               .mwdma_mask     = 0x07, /* mwdma0-2 */
-               .udma_mask      = ATA_UDMA6, /* udma0-6 */
+               .pio_mask       = ATA_PIO4,
+               .mwdma_mask     = ATA_MWDMA2,
+               .udma_mask      = ATA_UDMA6,
                .port_ops       = &pdc2027x_pata133_ops,
        },
 };
@@ -244,7 +181,7 @@ MODULE_DEVICE_TABLE(pci, pdc2027x_pci_tbl);
  */
 static inline void __iomem *port_mmio(struct ata_port *ap, unsigned int offset)
 {
-       return ap->host->mmio_base + ap->port_no * 0x100 + offset;
+       return ap->host->iomap[PDC_MMIO_BAR] + ap->port_no * 0x100 + offset;
 }
 
 /**
@@ -260,7 +197,7 @@ static inline void __iomem *dev_mmio(struct ata_port *ap, struct ata_device *ade
 }
 
 /**
- *     pdc2027x_pata_cbl_detect - Probe host controller cable detect info
+ *     pdc2027x_pata_cable_detect - Probe host controller cable detect info
  *     @ap: Port for which cable detect info is desired
  *
  *     Read 80c cable indicator from Promise extended register.
@@ -269,24 +206,21 @@ static inline void __iomem *dev_mmio(struct ata_port *ap, struct ata_device *ade
  *     LOCKING:
  *     None (inherited from caller).
  */
-static void pdc2027x_cbl_detect(struct ata_port *ap)
+static int pdc2027x_cable_detect(struct ata_port *ap)
 {
        u32 cgcr;
 
        /* check cable detect results */
-       cgcr = readl(port_mmio(ap, PDC_GLOBAL_CTL));
+       cgcr = ioread32(port_mmio(ap, PDC_GLOBAL_CTL));
        if (cgcr & (1 << 26))
                goto cbl40;
 
        PDPRINTK("No cable or 80-conductor cable on port %d\n", ap->port_no);
 
-       ap->cbl = ATA_CBL_PATA80;
-       return;
-
+       return ATA_CBL_PATA80;
 cbl40:
        printk(KERN_INFO DRV_NAME ": 40-conductor cable detected on port %d\n", ap->port_no);
-       ap->cbl = ATA_CBL_PATA40;
-       ap->udma_mask &= ATA_UDMA_MASK_40C;
+       return ATA_CBL_PATA40;
 }
 
 /**
@@ -295,12 +229,13 @@ cbl40:
  */
 static inline int pdc2027x_port_enabled(struct ata_port *ap)
 {
-       return readb(port_mmio(ap, PDC_ATA_CTL)) & 0x02;
+       return ioread8(port_mmio(ap, PDC_ATA_CTL)) & 0x02;
 }
 
 /**
  *     pdc2027x_prereset - prereset for PATA host controller
- *     @ap: Target port
+ *     @link: Target link
+ *     @deadline: deadline jiffies for the operation
  *
  *     Probeinit including cable detection.
  *
@@ -308,37 +243,44 @@ static inline int pdc2027x_port_enabled(struct ata_port *ap)
  *     None (inherited from caller).
  */
 
-static int pdc2027x_prereset(struct ata_port *ap)
+static int pdc2027x_prereset(struct ata_link *link, unsigned long deadline)
 {
        /* Check whether port enabled */
-       if (!pdc2027x_port_enabled(ap)) {
-               printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id);
-               return 0;
-       }
-       pdc2027x_cbl_detect(ap);
-       return ata_std_prereset(ap);
+       if (!pdc2027x_port_enabled(link->ap))
+               return -ENOENT;
+       return ata_sff_prereset(link, deadline);
 }
 
 /**
- *     pdc2027x_error_handler - Perform reset on PATA port and classify
- *     @ap: Port to reset
- *
- *     Reset PATA phy and classify attached devices.
+ *     pdc2720x_mode_filter    -       mode selection filter
+ *     @adev: ATA device
+ *     @mask: list of modes proposed
  *
- *     LOCKING:
- *     None (inherited from caller).
+ *     Block UDMA on devices that cause trouble with this controller.
  */
 
-static void pdc2027x_error_handler(struct ata_port *ap)
+static unsigned long pdc2027x_mode_filter(struct ata_device *adev, unsigned long mask)
 {
-       ata_bmdma_drive_eh(ap, pdc2027x_prereset, ata_std_softreset, NULL, ata_std_postreset);
+       unsigned char model_num[ATA_ID_PROD_LEN + 1];
+       struct ata_device *pair = ata_dev_pair(adev);
+
+       if (adev->class != ATA_DEV_ATA || adev->devno == 0 || pair == NULL)
+               return ata_bmdma_mode_filter(adev, mask);
+
+       /* Check for slave of a Maxtor at UDMA6 */
+       ata_id_c_string(pair->id, model_num, ATA_ID_PROD,
+                         ATA_ID_PROD_LEN + 1);
+       /* If the master is a maxtor in UDMA6 then the slave should not use UDMA 6 */
+       if (strstr(model_num, "Maxtor") == NULL && pair->dma_mode == XFER_UDMA_6)
+               mask &= ~ (1 << (6 + ATA_SHIFT_UDMA));
+
+       return ata_bmdma_mode_filter(adev, mask);
 }
 
 /**
  *     pdc2027x_set_piomode - Initialize host controller PATA PIO timings
  *     @ap: Port to configure
  *     @adev: um
- *     @pio: PIO mode, 0 - 4
  *
  *     Set PIO mode for device.
  *
@@ -363,16 +305,16 @@ static void pdc2027x_set_piomode(struct ata_port *ap, struct ata_device *adev)
        /* Set the PIO timing registers using value table for 133MHz */
        PDPRINTK("Set pio regs... \n");
 
-       ctcr0 = readl(dev_mmio(ap, adev, PDC_CTCR0));
+       ctcr0 = ioread32(dev_mmio(ap, adev, PDC_CTCR0));
        ctcr0 &= 0xffff0000;
        ctcr0 |= pdc2027x_pio_timing_tbl[pio].value0 |
                (pdc2027x_pio_timing_tbl[pio].value1 << 8);
-       writel(ctcr0, dev_mmio(ap, adev, PDC_CTCR0));
+       iowrite32(ctcr0, dev_mmio(ap, adev, PDC_CTCR0));
 
-       ctcr1 = readl(dev_mmio(ap, adev, PDC_CTCR1));
+       ctcr1 = ioread32(dev_mmio(ap, adev, PDC_CTCR1));
        ctcr1 &= 0x00ffffff;
        ctcr1 |= (pdc2027x_pio_timing_tbl[pio].value2 << 24);
-       writel(ctcr1, dev_mmio(ap, adev, PDC_CTCR1));
+       iowrite32(ctcr1, dev_mmio(ap, adev, PDC_CTCR1));
 
        PDPRINTK("Set pio regs done\n");
 
@@ -383,7 +325,6 @@ static void pdc2027x_set_piomode(struct ata_port *ap, struct ata_device *adev)
  *     pdc2027x_set_dmamode - Initialize host controller PATA UDMA timings
  *     @ap: Port to configure
  *     @adev: um
- *     @udma: udma mode, XFER_UDMA_0 to XFER_UDMA_6
  *
  *     Set UDMA mode for device.
  *
@@ -406,18 +347,18 @@ static void pdc2027x_set_dmamode(struct ata_port *ap, struct ata_device *adev)
                         * If tHOLD is '1', the hardware will add half clock for data hold time.
                         * This code segment seems to be no effect. tHOLD will be overwritten below.
                         */
-                       ctcr1 = readl(dev_mmio(ap, adev, PDC_CTCR1));
-                       writel(ctcr1 & ~(1 << 7), dev_mmio(ap, adev, PDC_CTCR1));
+                       ctcr1 = ioread32(dev_mmio(ap, adev, PDC_CTCR1));
+                       iowrite32(ctcr1 & ~(1 << 7), dev_mmio(ap, adev, PDC_CTCR1));
                }
 
                PDPRINTK("Set udma regs... \n");
 
-               ctcr1 = readl(dev_mmio(ap, adev, PDC_CTCR1));
+               ctcr1 = ioread32(dev_mmio(ap, adev, PDC_CTCR1));
                ctcr1 &= 0xff000000;
                ctcr1 |= pdc2027x_udma_timing_tbl[udma_mode].value0 |
                        (pdc2027x_udma_timing_tbl[udma_mode].value1 << 8) |
                        (pdc2027x_udma_timing_tbl[udma_mode].value2 << 16);
-               writel(ctcr1, dev_mmio(ap, adev, PDC_CTCR1));
+               iowrite32(ctcr1, dev_mmio(ap, adev, PDC_CTCR1));
 
                PDPRINTK("Set udma regs done\n");
 
@@ -429,13 +370,13 @@ static void pdc2027x_set_dmamode(struct ata_port *ap, struct ata_device *adev)
                unsigned int mdma_mode = dma_mode & 0x07;
 
                PDPRINTK("Set mdma regs... \n");
-               ctcr0 = readl(dev_mmio(ap, adev, PDC_CTCR0));
+               ctcr0 = ioread32(dev_mmio(ap, adev, PDC_CTCR0));
 
                ctcr0 &= 0x0000ffff;
                ctcr0 |= (pdc2027x_mdma_timing_tbl[mdma_mode].value0 << 16) |
                        (pdc2027x_mdma_timing_tbl[mdma_mode].value1 << 24);
 
-               writel(ctcr0, dev_mmio(ap, adev, PDC_CTCR0));
+               iowrite32(ctcr0, dev_mmio(ap, adev, PDC_CTCR0));
                PDPRINTK("Set mdma regs done\n");
 
                PDPRINTK("Set to mdma mode[%u] \n", mdma_mode);
@@ -445,38 +386,41 @@ static void pdc2027x_set_dmamode(struct ata_port *ap, struct ata_device *adev)
 }
 
 /**
- *     pdc2027x_post_set_mode - Set the timing registers back to correct values.
- *     @ap: Port to configure
+ *     pdc2027x_set_mode - Set the timing registers back to correct values.
+ *     @link: link to configure
+ *     @r_failed: Returned device for failure
  *
  *     The pdc2027x hardware will look at "SET FEATURES" and change the timing registers
  *     automatically. The values set by the hardware might be incorrect, under 133Mhz PLL.
  *     This function overwrites the possibly incorrect values set by the hardware to be correct.
  */
-static void pdc2027x_post_set_mode(struct ata_port *ap)
+static int pdc2027x_set_mode(struct ata_link *link, struct ata_device **r_failed)
 {
-       int i;
+       struct ata_port *ap = link->ap;
+       struct ata_device *dev;
+       int rc;
 
-       for (i = 0; i < ATA_MAX_DEVICES; i++) {
-               struct ata_device *dev = &ap->device[i];
+       rc = ata_do_set_mode(link, r_failed);
+       if (rc < 0)
+               return rc;
 
-               if (ata_dev_enabled(dev)) {
+       ata_for_each_dev(dev, link, ENABLED) {
+               pdc2027x_set_piomode(ap, dev);
 
-                       pdc2027x_set_piomode(ap, dev);
+               /*
+                * Enable prefetch if the device support PIO only.
+                */
+               if (dev->xfer_shift == ATA_SHIFT_PIO) {
+                       u32 ctcr1 = ioread32(dev_mmio(ap, dev, PDC_CTCR1));
+                       ctcr1 |= (1 << 25);
+                       iowrite32(ctcr1, dev_mmio(ap, dev, PDC_CTCR1));
 
-                       /*
-                        * Enable prefetch if the device support PIO only.
-                        */
-                       if (dev->xfer_shift == ATA_SHIFT_PIO) {
-                               u32 ctcr1 = readl(dev_mmio(ap, dev, PDC_CTCR1));
-                               ctcr1 |= (1 << 25);
-                               writel(ctcr1, dev_mmio(ap, dev, PDC_CTCR1));
-
-                               PDPRINTK("Turn on prefetch\n");
-                       } else {
-                               pdc2027x_set_dmamode(ap, dev);
-                       }
+                       PDPRINTK("Turn on prefetch\n");
+               } else {
+                       pdc2027x_set_dmamode(ap, dev);
                }
        }
+       return 0;
 }
 
 /**
@@ -522,24 +466,23 @@ static int pdc2027x_check_atapi_dma(struct ata_queued_cmd *qc)
 
 /**
  * pdc_read_counter - Read the ctr counter
- * @probe_ent: for the port address
+ * @host: target ATA host
  */
 
-static long pdc_read_counter(struct ata_probe_ent *probe_ent)
+static long pdc_read_counter(struct ata_host *host)
 {
+       void __iomem *mmio_base = host->iomap[PDC_MMIO_BAR];
        long counter;
        int retry = 1;
        u32 bccrl, bccrh, bccrlv, bccrhv;
 
 retry:
-       bccrl = readl(probe_ent->mmio_base + PDC_BYTE_COUNT) & 0xffff;
-       bccrh = readl(probe_ent->mmio_base + PDC_BYTE_COUNT + 0x100) & 0xffff;
-       rmb();
+       bccrl = ioread32(mmio_base + PDC_BYTE_COUNT) & 0x7fff;
+       bccrh = ioread32(mmio_base + PDC_BYTE_COUNT + 0x100) & 0x7fff;
 
        /* Read the counter values again for verification */
-       bccrlv = readl(probe_ent->mmio_base + PDC_BYTE_COUNT) & 0xffff;
-       bccrhv = readl(probe_ent->mmio_base + PDC_BYTE_COUNT + 0x100) & 0xffff;
-       rmb();
+       bccrlv = ioread32(mmio_base + PDC_BYTE_COUNT) & 0x7fff;
+       bccrhv = ioread32(mmio_base + PDC_BYTE_COUNT + 0x100) & 0x7fff;
 
        counter = (bccrh << 15) | bccrl;
 
@@ -564,12 +507,12 @@ retry:
  * adjust_pll - Adjust the PLL input clock in Hz.
  *
  * @pdc_controller: controller specific information
- * @probe_ent: For the port address
+ * @host: target ATA host
  * @pll_clock: The input of PLL in HZ
  */
-static void pdc_adjust_pll(struct ata_probe_ent *probe_ent, long pll_clock, unsigned int board_idx)
+static void pdc_adjust_pll(struct ata_host *host, long pll_clock, unsigned int board_idx)
 {
-
+       void __iomem *mmio_base = host->iomap[PDC_MMIO_BAR];
        u16 pll_ctl;
        long pll_clock_khz = pll_clock / 1000;
        long pout_required = board_idx? PDC_133_MHZ:PDC_100_MHZ;
@@ -588,7 +531,7 @@ static void pdc_adjust_pll(struct ata_probe_ent *probe_ent, long pll_clock, unsi
        /* Show the current clock value of PLL control register
         * (maybe already configured by the firmware)
         */
-       pll_ctl = readw(probe_ent->mmio_base + PDC_PLL_CTL);
+       pll_ctl = ioread16(mmio_base + PDC_PLL_CTL);
 
        PDPRINTK("pll_ctl[%X]\n", pll_ctl);
 #endif
@@ -628,8 +571,8 @@ static void pdc_adjust_pll(struct ata_probe_ent *probe_ent, long pll_clock, unsi
 
        PDPRINTK("Writing pll_ctl[%X]\n", pll_ctl);
 
-       writew(pll_ctl, probe_ent->mmio_base + PDC_PLL_CTL);
-       readw(probe_ent->mmio_base + PDC_PLL_CTL); /* flush */
+       iowrite16(pll_ctl, mmio_base + PDC_PLL_CTL);
+       ioread16(mmio_base + PDC_PLL_CTL); /* flush */
 
        /* Wait the PLL circuit to be stable */
        mdelay(30);
@@ -639,7 +582,7 @@ static void pdc_adjust_pll(struct ata_probe_ent *probe_ent, long pll_clock, unsi
         *  Show the current clock value of PLL control register
         * (maybe configured by the firmware)
         */
-       pll_ctl = readw(probe_ent->mmio_base + PDC_PLL_CTL);
+       pll_ctl = ioread16(mmio_base + PDC_PLL_CTL);
 
        PDPRINTK("pll_ctl[%X]\n", pll_ctl);
 #endif
@@ -649,39 +592,47 @@ static void pdc_adjust_pll(struct ata_probe_ent *probe_ent, long pll_clock, unsi
 
 /**
  * detect_pll_input_clock - Detect the PLL input clock in Hz.
- * @probe_ent: for the port address
+ * @host: target ATA host
  * Ex. 16949000 on 33MHz PCI bus for pdc20275.
  *     Half of the PCI clock.
  */
-static long pdc_detect_pll_input_clock(struct ata_probe_ent *probe_ent)
+static long pdc_detect_pll_input_clock(struct ata_host *host)
 {
+       void __iomem *mmio_base = host->iomap[PDC_MMIO_BAR];
        u32 scr;
        long start_count, end_count;
-       long pll_clock;
-
-       /* Read current counter value */
-       start_count = pdc_read_counter(probe_ent);
+       struct timeval start_time, end_time;
+       long pll_clock, usec_elapsed;
 
        /* Start the test mode */
-       scr = readl(probe_ent->mmio_base + PDC_SYS_CTL);
+       scr = ioread32(mmio_base + PDC_SYS_CTL);
        PDPRINTK("scr[%X]\n", scr);
-       writel(scr | (0x01 << 14), probe_ent->mmio_base + PDC_SYS_CTL);
-       readl(probe_ent->mmio_base + PDC_SYS_CTL); /* flush */
+       iowrite32(scr | (0x01 << 14), mmio_base + PDC_SYS_CTL);
+       ioread32(mmio_base + PDC_SYS_CTL); /* flush */
+
+       /* Read current counter value */
+       start_count = pdc_read_counter(host);
+       do_gettimeofday(&start_time);
 
        /* Let the counter run for 100 ms. */
        mdelay(100);
 
        /* Read the counter values again */
-       end_count = pdc_read_counter(probe_ent);
+       end_count = pdc_read_counter(host);
+       do_gettimeofday(&end_time);
 
        /* Stop the test mode */
-       scr = readl(probe_ent->mmio_base + PDC_SYS_CTL);
+       scr = ioread32(mmio_base + PDC_SYS_CTL);
        PDPRINTK("scr[%X]\n", scr);
-       writel(scr & ~(0x01 << 14), probe_ent->mmio_base + PDC_SYS_CTL);
-       readl(probe_ent->mmio_base + PDC_SYS_CTL); /* flush */
+       iowrite32(scr & ~(0x01 << 14), mmio_base + PDC_SYS_CTL);
+       ioread32(mmio_base + PDC_SYS_CTL); /* flush */
 
        /* calculate the input clock in Hz */
-       pll_clock = (start_count - end_count) * 10;
+       usec_elapsed = (end_time.tv_sec - start_time.tv_sec) * 1000000 +
+               (end_time.tv_usec - start_time.tv_usec);
+
+       pll_clock = ((start_count - end_count) & 0x3fffffff) / 100 *
+               (100000000 / usec_elapsed);
 
        PDPRINTK("start[%ld] end[%ld] \n", start_count, end_count);
        PDPRINTK("PLL input clock[%ld]Hz\n", pll_clock);
@@ -691,11 +642,10 @@ static long pdc_detect_pll_input_clock(struct ata_probe_ent *probe_ent)
 
 /**
  * pdc_hardware_init - Initialize the hardware.
- * @pdev: instance of pci_dev found
- * @pdc_controller: controller specific information
- * @pe:  for the port address
+ * @host: target ATA host
+ * @board_idx: board identifier
  */
-static int pdc_hardware_init(struct pci_dev *pdev, struct ata_probe_ent *pe, unsigned int board_idx)
+static int pdc_hardware_init(struct ata_host *host, unsigned int board_idx)
 {
        long pll_clock;
 
@@ -705,15 +655,12 @@ static int pdc_hardware_init(struct pci_dev *pdev, struct ata_probe_ent *pe, uns
         * Ex. 25MHz or 40MHz, we have to adjust the cycle_time.
         * The pdc20275 controller employs PLL circuit to help correct timing registers setting.
         */
-       pll_clock = pdc_detect_pll_input_clock(pe);
-
-       if (pll_clock < 0) /* counter overflow? Try again. */
-               pll_clock = pdc_detect_pll_input_clock(pe);
+       pll_clock = pdc_detect_pll_input_clock(host);
 
-       dev_printk(KERN_INFO, &pdev->dev, "PLL input clock %ld kHz\n", pll_clock/1000);
+       dev_printk(KERN_INFO, host->dev, "PLL input clock %ld kHz\n", pll_clock/1000);
 
        /* Adjust PLL control register */
-       pdc_adjust_pll(pe, pll_clock, board_idx);
+       pdc_adjust_pll(host, pll_clock, board_idx);
 
        return 0;
 }
@@ -723,7 +670,7 @@ static int pdc_hardware_init(struct pci_dev *pdev, struct ata_probe_ent *pe, uns
  * @port: ata ioports to setup
  * @base: base address
  */
-static void pdc_ata_setup_port(struct ata_ioports *port, unsigned long base)
+static void pdc_ata_setup_port(struct ata_ioports *port, void __iomem *base)
 {
        port->cmd_addr          =
        port->data_addr         = base;
@@ -745,8 +692,7 @@ static void pdc_ata_setup_port(struct ata_ioports *port, unsigned long base)
  * Called when an instance of PCI adapter is inserted.
  * This function checks whether the hardware is supported,
  * initialize hardware and register an instance of ata_host to
- * libata by providing struct ata_probe_ent and ata_device_add().
- * (implements struct pci_driver.probe() )
+ * libata.  (implements struct pci_driver.probe() )
  *
  * @pdev: instance of pci_dev found
  * @ent:  matching entry in the id_tbl[]
@@ -754,99 +700,62 @@ static void pdc_ata_setup_port(struct ata_ioports *port, unsigned long base)
 static int __devinit pdc2027x_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int printed_version;
+       static const unsigned long cmd_offset[] = { 0x17c0, 0x15c0 };
+       static const unsigned long bmdma_offset[] = { 0x1000, 0x1008 };
        unsigned int board_idx = (unsigned int) ent->driver_data;
-
-       struct ata_probe_ent *probe_ent = NULL;
-       unsigned long base;
+       const struct ata_port_info *ppi[] =
+               { &pdc2027x_port_info[board_idx], NULL };
+       struct ata_host *host;
        void __iomem *mmio_base;
-       int rc;
+       int i, rc;
 
        if (!printed_version++)
                dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
 
-       rc = pci_enable_device(pdev);
+       /* alloc host */
+       host = ata_host_alloc_pinfo(&pdev->dev, ppi, 2);
+       if (!host)
+               return -ENOMEM;
+
+       /* acquire resources and fill host */
+       rc = pcim_enable_device(pdev);
        if (rc)
                return rc;
 
-       rc = pci_request_regions(pdev, DRV_NAME);
+       rc = pcim_iomap_regions(pdev, 1 << PDC_MMIO_BAR, DRV_NAME);
        if (rc)
-               goto err_out;
+               return rc;
+       host->iomap = pcim_iomap_table(pdev);
 
        rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
        if (rc)
-               goto err_out_regions;
+               return rc;
 
        rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
        if (rc)
-               goto err_out_regions;
-
-       /* Prepare the probe entry */
-       probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL);
-       if (probe_ent == NULL) {
-               rc = -ENOMEM;
-               goto err_out_regions;
-       }
-
-       probe_ent->dev = pci_dev_to_dev(pdev);
-       INIT_LIST_HEAD(&probe_ent->node);
-
-       mmio_base = pci_iomap(pdev, 5, 0);
-       if (!mmio_base) {
-               rc = -ENOMEM;
-               goto err_out_free_ent;
-       }
-
-       base = (unsigned long) mmio_base;
+               return rc;
 
-       probe_ent->sht          = pdc2027x_port_info[board_idx].sht;
-       probe_ent->port_flags   = pdc2027x_port_info[board_idx].flags;
-       probe_ent->pio_mask     = pdc2027x_port_info[board_idx].pio_mask;
-       probe_ent->mwdma_mask   = pdc2027x_port_info[board_idx].mwdma_mask;
-       probe_ent->udma_mask    = pdc2027x_port_info[board_idx].udma_mask;
-       probe_ent->port_ops     = pdc2027x_port_info[board_idx].port_ops;
+       mmio_base = host->iomap[PDC_MMIO_BAR];
 
-               probe_ent->irq = pdev->irq;
-               probe_ent->irq_flags = SA_SHIRQ;
-       probe_ent->mmio_base = mmio_base;
+       for (i = 0; i < 2; i++) {
+               struct ata_port *ap = host->ports[i];
 
-       pdc_ata_setup_port(&probe_ent->port[0], base + 0x17c0);
-       probe_ent->port[0].bmdma_addr = base + 0x1000;
-       pdc_ata_setup_port(&probe_ent->port[1], base + 0x15c0);
-       probe_ent->port[1].bmdma_addr = base + 0x1008;
+               pdc_ata_setup_port(&ap->ioaddr, mmio_base + cmd_offset[i]);
+               ap->ioaddr.bmdma_addr = mmio_base + bmdma_offset[i];
 
-       probe_ent->n_ports = 2;
+               ata_port_pbar_desc(ap, PDC_MMIO_BAR, -1, "mmio");
+               ata_port_pbar_desc(ap, PDC_MMIO_BAR, cmd_offset[i], "cmd");
+       }
 
-       pci_set_master(pdev);
        //pci_enable_intx(pdev);
 
        /* initialize adapter */
-       if (pdc_hardware_init(pdev, probe_ent, board_idx) != 0)
-               goto err_out_free_ent;
-
-       ata_device_add(probe_ent);
-       kfree(probe_ent);
-
-       return 0;
-
-err_out_free_ent:
-       kfree(probe_ent);
-err_out_regions:
-       pci_release_regions(pdev);
-err_out:
-       pci_disable_device(pdev);
-       return rc;
-}
+       if (pdc_hardware_init(host, board_idx) != 0)
+               return -EIO;
 
-/**
- * pdc2027x_remove_one - Called to remove a single instance of the
- * adapter.
- *
- * @dev: The PCI device to remove.
- * FIXME: module load/unload not working yet
- */
-static void __devexit pdc2027x_remove_one(struct pci_dev *pdev)
-{
-       ata_pci_remove_one(pdev);
+       pci_set_master(pdev);
+       return ata_host_activate(host, pdev->irq, ata_sff_interrupt,
+                                IRQF_SHARED, &pdc2027x_sht);
 }
 
 /**
@@ -854,7 +763,7 @@ static void __devexit pdc2027x_remove_one(struct pci_dev *pdev)
  */
 static int __init pdc2027x_init(void)
 {
-       return pci_module_init(&pdc2027x_pci_driver);
+       return pci_register_driver(&pdc2027x_pci_driver);
 }
 
 /**