As we cannot reverse iomap results portably as we tried before the libata
layer needs to keep bus addresses around for reporting. This first big
patch adds a structure for it and teaches the drivers to keep the
information. Thankfully most drivers go via libata-sff and it can do the
work for them.
For the others we replace ata_std_ports with ata_std_io_ports /
std_mmio_ports and pass both the mapped and some bus address info.
We don't keep all the mappings in both forms. We only need cmd, ctrl and
status (for wait_status() reporting). We also keep a base for devices
where the taskfile (cmd/ctl) mapping makes no sense.
This patch stores all the data but doesn't yet change the display side.
I've got a couple of variants I'm playing with on the display side and
want to get that right. In the mean time this should store all the data
and have no side effects for anyone, so is a good first chunk for testing
alone.
Signed-off-by: Alan Cox [EMAIL PROTECTED]
diff -u --new-file --recursive --exclude-from /usr/src/exclude
linux.vanilla-2.6.23rc1-mm1/include/linux/libata.h
linux-2.6.23rc1-mm1/include/linux/libata.h
--- linux.vanilla-2.6.23rc1-mm1/include/linux/libata.h 2007-07-26
15:02:58.0 +0100
+++ linux-2.6.23rc1-mm1/include/linux/libata.h 2007-07-26 15:37:59.0
+0100
@@ -370,6 +376,30 @@
void __iomem*scr_addr;
};
+typedef enum {
+ ATA_ADDR_UNSET = 0,
+ ATA_ADDR_PIO = 1,
+ ATA_ADDR_MMIO = 2
+} ata_addr_type;
+
+struct ata_busports {
+ /* If this is set it is used to indicate the resource block for
+ a device (eg AHCI) which may not fit the usual arrangement */
+ unsigned long base_addr;
+ ata_addr_type base_type;
+ /* Optionally we can provide the SFF type task file and BMDMA
+ locations. Status must be provided if the ata_status functions
+ are being used */
+ unsigned long cmd_addr;
+ ata_addr_type cmd_type;
+ unsigned long ctl_addr;
+ ata_addr_type ctl_type;
+ unsigned long bmdma_addr;
+ ata_addr_type bmdma_type;
+ unsigned long status_addr;
+ ata_addr_type status_type;
+};
+
struct ata_host {
spinlock_t lock;
struct device *dev;
@@ -536,6 +566,7 @@
dma_addr_t pad_dma;
struct ata_ioports ioaddr; /* ATA cmd/ctl/dma register blocks */
+ struct ata_busports busaddr; /* Bus addresses for reporting */
u8 ctl;/* cache of ATA control register */
u8 last_ctl; /* Cache last written value */
@@ -720,7 +751,8 @@
unsigned long deadline);
extern void ata_std_postreset(struct ata_port *ap, unsigned int *classes);
extern void ata_port_disable(struct ata_port *);
-extern void ata_std_ports(struct ata_ioports *ioaddr);
+extern void ata_std_io_ports(struct ata_ioports *ioaddr, struct ata_busports
*busaddr);
+extern void ata_std_mmio_ports(struct ata_ioports *ioaddr, struct ata_busports
*busaddr);
#ifdef CONFIG_PCI
extern int ata_pci_init_one (struct pci_dev *pdev,
const struct ata_port_info * const * ppi);
diff -u --new-file --recursive --exclude-from /usr/src/exclude
linux.vanilla-2.6.23rc1-mm1/drivers/ata/libata-core.c
linux-2.6.23rc1-mm1/drivers/ata/libata-core.c
--- linux.vanilla-2.6.23rc1-mm1/drivers/ata/libata-core.c 2007-07-26
15:02:57.656910384 +0100
+++ linux-2.6.23rc1-mm1/drivers/ata/libata-core.c 2007-07-26
15:54:41.130110744 +0100
@@ -6738,7 +6877,7 @@
* Does not set ctl_addr, altstatus_addr, bmdma_addr, or scr_addr.
*/
-void ata_std_ports(struct ata_ioports *ioaddr)
+static void ata_std_ports(struct ata_ioports *ioaddr)
{
ioaddr-data_addr = ioaddr-cmd_addr + ATA_REG_DATA;
ioaddr-error_addr = ioaddr-cmd_addr + ATA_REG_ERR;
@@ -6752,6 +6891,61 @@
ioaddr-command_addr = ioaddr-cmd_addr + ATA_REG_CMD;
}
+/**
+ * ata_std_io_ports - initialize ioaddr with standard port offsets.
+ * @ioaddr: IO address structure to be initialized
+ * @busaddr: Bus addresses to report
+ *
+ * Utility function which initializes data_addr, error_addr,
+ * feature_addr, nsect_addr, lbal_addr, lbam_addr, lbah_addr,
+ * device_addr, status_addr, and command_addr to standard offsets
+ * relative to cmd_addr.
+ *
+ * Does not set ctl_addr, altstatus_addr, bmdma_addr, or scr_addr.
+ *
+ * Sets up the types of the prepared physical bus registers as I/O
+ */
+
+void ata_std_io_ports(struct ata_ioports *ioaddr, struct ata_busports *busaddr)
+{
+ ata_std_ports(ioaddr);
+ busaddr-cmd_type = ATA_ADDR_PIO;
+ if (busaddr-status_addr == 0)
+ busaddr-status_addr = busaddr-cmd_addr + ATA_REG_STATUS;
+ busaddr-status_type = ATA_ADDR_PIO;
+ if (busaddr-bmdma_addr)
+ busaddr-bmdma_type = ATA_ADDR_PIO;
+ if (busaddr-ctl_addr)
+