From b225caf8f743b9f5f9e84d0df711ee0c17e049ae Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Wed, 11 Feb 2015 16:53:08 -0600 Subject: [PATCH 106/114] pci: probe Author: Arjan van de Ven Signed-off-by: Miguel Bernal Marin --- drivers/pci/probe.c | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 204960e70333..7399a06698da 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -182,6 +182,10 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, mask = type ? PCI_ROM_ADDRESS_MASK : ~0; + res->name = pci_name(dev); + + printk("clr: Starting probe for %s\n", res->name); + /* No printks while decoding is disabled! */ if (!dev->mmio_always_on) { pci_read_config_word(dev, PCI_COMMAND, &orig_cmd); @@ -191,8 +195,6 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, } } - res->name = pci_name(dev); - pci_read_config_dword(dev, pos, &l); pci_write_config_dword(dev, pos, l | mask); pci_read_config_dword(dev, pos, &sz); @@ -324,6 +326,8 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) if (dev->non_compliant_bars) return; + printk("clr: pci_read_bases start\n"); + for (pos = 0; pos < howmany; pos++) { struct resource *res = &dev->resource[pos]; reg = PCI_BASE_ADDRESS_0 + (pos << 2); @@ -332,11 +336,13 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) if (rom) { struct resource *res = &dev->resource[PCI_ROM_RESOURCE]; + printk("clr: rom path\n"); dev->rom_base_reg = rom; res->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH | IORESOURCE_READONLY | IORESOURCE_SIZEALIGN; __pci_read_base(dev, pci_bar_mem32, res, rom); } + printk("clr: pci_read_bases end\n"); } static void pci_read_bridge_io(struct pci_bus *child) @@ -1311,6 +1317,28 @@ static void pci_msi_setup_pci_dev(struct pci_dev *dev) pci_msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_ENABLE, 0); } +static int guess_bar_count(int class) +{ + if (class == 0x068000) + return 0; + if (class == 0x020000) + return 2; + if (class == 0x010000) + return 2; + if (class == 0x00ff00) + return 1; + return 6; +} + +static int has_rom(int class, int rom) +{ + if (class == 0x020000) + return 0; + if (class == 0x010000 || class == 0x00ff00) + return 0; + return rom; +} + /** * pci_setup_device - fill in class and map information of a device * @dev: the device structure to fill @@ -1329,6 +1357,9 @@ int pci_setup_device(struct pci_dev *dev) int pos = 0; struct pci_bus_region region; struct resource *res; + int maxbar; + + printk("clr: pci_setup_device start\n"); if (pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type)) return -EIO; @@ -1383,7 +1414,11 @@ int pci_setup_device(struct pci_dev *dev) if (class == PCI_CLASS_BRIDGE_PCI) goto bad; pci_read_irq(dev); - pci_read_bases(dev, 6, PCI_ROM_ADDRESS); + + maxbar = guess_bar_count(dev->class); + + if (class != PCI_CLASS_STORAGE_IDE) + pci_read_bases(dev, maxbar, has_rom(dev->class, PCI_ROM_ADDRESS)); pci_read_config_word(dev, PCI_SUBSYSTEM_VENDOR_ID, &dev->subsystem_vendor); pci_read_config_word(dev, PCI_SUBSYSTEM_ID, &dev->subsystem_device); @@ -1468,6 +1503,8 @@ int pci_setup_device(struct pci_dev *dev) dev->class = PCI_CLASS_NOT_DEFINED << 8; } + printk("clr: pci_setup_device end\n"); + /* We found a fine healthy device, go go go... */ return 0; } -- 2.11.1