[PATCH] pata_hpt3x3: support this chip properly includingalternative BAR layout

From: Alan Cox
Date: Fri Jun 29 2007 - 14:12:01 EST


In some cases we cannot use BAR0-BAR3 on this chip due to errata. The
relevant interfaces are available via BAR4 and we set the chip up to use
those instead.

This plus testing means it can move from experimental to production spec

Signed-off-by: Alan Cox <alan@xxxxxxxxxx>

diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.22-rc6/drivers/ata/Kconfig linux-2.6.22-rc6/drivers/ata/Kconfig
--- linux.vanilla-2.6.22-rc6/drivers/ata/Kconfig 2007-06-25 00:21:48.000000000 +0100
+++ linux-2.6.22-rc6/drivers/ata/Kconfig 2007-06-29 15:20:26.000000000 +0100
@@ -304,7 +304,7 @@
If unsure, say N.

config PATA_HPT3X3
- tristate "HPT 343/363 PATA support (Experimental)"
+ tristate "HPT 343/363 PATA support"
depends on PCI
help
This option enables support for the HPT 343/363
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.22-rc6/drivers/ata/pata_hpt3x3.c linux-2.6.22-rc6/drivers/ata/pata_hpt3x3.c
--- linux.vanilla-2.6.22-rc6/drivers/ata/pata_hpt3x3.c 2007-06-25 00:21:48.000000000 +0100
+++ linux-2.6.22-rc6/drivers/ata/pata_hpt3x3.c 2007-06-29 16:41:14.000000000 +0100
@@ -158,19 +158,18 @@
pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20);
}

-
/**
* hpt3x3_init_one - Initialise an HPT343/363
* @dev: PCI device
* @id: Entry in match table
*
- * Perform basic initialisation. The chip has a quirk that it won't
- * function unless it is at XX00. The old ATA driver touched this up
- * but we leave it for pci quirks to do properly.
+ * Perform basic initialisation. We set the device up so we access all
+ * ports via BAR4. This is neccessary to work around errata.
*/

-static int hpt3x3_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+static int hpt3x3_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
+ static int printed_version;
static const struct ata_port_info info = {
.sht = &hpt3x3_sht,
.flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
@@ -179,11 +178,57 @@
.udma_mask = 0x07,
.port_ops = &hpt3x3_port_ops
};
+ /* Register offsets of taskfiles in BAR4 area */
+ static const u8 offset_cmd[2] = { 0x20, 0x28 };
+ static const u8 offset_ctl[2] = { 0x34, 0x3C };
const struct ata_port_info *ppi[] = { &info, NULL };
-
- hpt3x3_init_chipset(dev);
- /* Now kick off ATA set up */
- return ata_pci_init_one(dev, ppi);
+ struct ata_host *host;
+ int i, rc;
+ void __iomem *base;
+
+ hpt3x3_init_chipset(pdev);
+
+ if (!printed_version++)
+ dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
+
+ 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;
+
+ /* Everything is relative to BAR4 if we set up this way */
+ rc = pcim_iomap_regions(pdev, 1 << 4, DRV_NAME);
+ if (rc == -EBUSY)
+ pcim_pin_device(pdev);
+ if (rc)
+ return rc;
+ host->iomap = pcim_iomap_table(pdev);
+ rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
+ if (rc)
+ return rc;
+ rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
+ if (rc)
+ return rc;
+
+ base = host->iomap[4]; /* Bus mastering base */
+
+ for (i = 0; i < host->n_ports; i++) {
+ struct ata_ioports *ioaddr = &host->ports[i]->ioaddr;
+
+ ioaddr->cmd_addr = base + offset_cmd[i];
+ ioaddr->altstatus_addr =
+ ioaddr->ctl_addr = base + offset_ctl[i];
+ ioaddr->bmdma_addr = base;
+ ioaddr->scr_addr = NULL;
+ ata_std_ports(ioaddr);
+ }
+ pci_set_master(pdev);
+ return ata_host_activate(host, pdev->irq, ata_interrupt, IRQF_SHARED,
+ &hpt3x3_sht);
}

#ifdef CONFIG_PM
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/