diff options
author | Ian Abbott <abbotti@mev.co.uk> | 2012-11-20 11:08:56 +0000 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-11-21 14:13:44 -0800 |
commit | 971b5e56537bf59d56086bd2472bffa8414555d3 (patch) | |
tree | 3ed8fa3096d97901e98ae7dc3d4bb9287aae1bb6 | |
parent | a4a557e3d44f509a807e80334f012b36ba6894c6 (diff) | |
download | linux-971b5e56537bf59d56086bd2472bffa8414555d3.tar.bz2 |
staging: comedi: me_daq: remove broken workaround for PLX bug
The PLX PCI 9050 interface chip has a bug where its local configuration
registers accessible through PCI BAR 0 and/or PCI BAR 1 (depending on
settings loaded from a serial EEPROM or local bus processor) are
unreadable (always read 0 instead of the true register values) if the
base address starts on an odd multiple of 0x80 (i.e. has bit 7 set to
1).
The "me_daq" driver attempts to work around this by writing to the PCI
config space to swap the addresses assigned to PCI BAR 0 and PCI BAR 5
(which has been initially configured by serial EEPROM load as a spare
region of the same length as the PCI BAR 0 region). (If the PCI BAR 5
region is absent, it attempts to reduce the PCI BAR 0 address by 0x80,
which is likely to cause havoc for some other device, but that case
shouldn't be reachable in practice.)
The workaround in the driver is ineffective because it has already
ioremapped the memory from `pci_resource_start(pcidev, 0)` *before* it
does the workaround, so after swapping PCI BAR 0 and PCI BAR 5, this
memory will end up accessing whatever onboard registers PCI BAR 5 was
linked to instead of the local configuration registers. It also leaves
the addresses in the physical PCI BAR registers set differently to the
resource start addresses recorded in the `struct pci_dev`.
The workaround could be fixed by ioremapping `pci_resource_start(pcidev,
5)` if the PCI BAR addresses were physically swapped (and the fallback
workaround of subtracting 0x80 from the base address should really be
removed altogether). However, it's not really worth it. This sort of
thing should be worked around in "drivers/pci/quirks.c" by ensuring that
PCI BAR 0 and/or PCI BAR 1 do not end up on an odd multiple of 0x80
bytes.
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/staging/comedi/drivers/me_daq.c | 46 |
1 files changed, 0 insertions, 46 deletions
diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index b1fd74c3a61f..22cf0f1e5471 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -486,48 +486,6 @@ static int me_reset(struct comedi_device *dev) return 0; } -static int me_plx_bug_check(struct comedi_device *dev, - struct pci_dev *pcidev) -{ - resource_size_t plx_regbase_tmp = pci_resource_start(pcidev, 0); - resource_size_t swap_regbase_tmp = pci_resource_start(pcidev, 5); - resource_size_t regbase_tmp; - int ret; - - if (!swap_regbase_tmp) - dev_err(dev->class_dev, "Swap not present\n"); - - if (plx_regbase_tmp & 0x0080) { - dev_err(dev->class_dev, "PLX-Bug detected\n"); - - if (swap_regbase_tmp) { - regbase_tmp = plx_regbase_tmp; - plx_regbase_tmp = swap_regbase_tmp; - swap_regbase_tmp = regbase_tmp; - - ret = pci_write_config_dword(pcidev, - PCI_BASE_ADDRESS_0, - plx_regbase_tmp); - if (ret != PCIBIOS_SUCCESSFUL) - return -EIO; - - ret = pci_write_config_dword(pcidev, - PCI_BASE_ADDRESS_5, - swap_regbase_tmp); - if (ret != PCIBIOS_SUCCESSFUL) - return -EIO; - } else { - plx_regbase_tmp -= 0x80; - ret = pci_write_config_dword(pcidev, - PCI_BASE_ADDRESS_0, - plx_regbase_tmp); - if (ret != PCIBIOS_SUCCESSFUL) - return -EIO; - } - } - return 0; -} - static const void *me_find_boardinfo(struct comedi_device *dev, struct pci_dev *pcidev) { @@ -572,10 +530,6 @@ static int __devinit me_auto_attach(struct comedi_device *dev, if (!dev_private->plx_regbase) return -ENOMEM; - ret = me_plx_bug_check(dev, pcidev); - if (ret) - return ret; - dev_private->me_regbase = ioremap(pci_resource_start(pcidev, 2), pci_resource_len(pcidev, 2)); if (!dev_private->me_regbase) |