http://git.kernel.org/?p=linux/kernel/git/konrad/xen.git;a=commitdiff;h=978b7df39be386f9a875bb14fcd84145e8ad0ee2#patch1 git/pub/scm / linux/kernel/git/konrad/xen.git / commitdiff ? search: re summary | shortlog | log | commit | commitdiff | tree raw | patch (parent: 28a4d3a) xen-pcifront: Enforce scanning of device functions on initial execution. author Konrad Rzeszutek Wilk Tue, 8 Jun 2010 16:59:41 +0000 (12:59 -0400) committer Konrad Rzeszutek Wilk Fri, 18 Jun 2010 19:40:27 +0000 (15:40 -0400) 'pci_scan_slot' abondons scanning of functions above 0 if a device with function has not been detected. We need to be able to scan functions above 0 in case the user has passed in devices without the function 0 for the slot/bus. To that end we are reusing the code that existed in the rescan code path and make usage of it in the initial execution path. Signed-off-by: Konrad Rzeszutek Wilk --- linux-2.6.34.1/drivers/xen/pcifront/pci_op.c.orig 2010-09-29 16:31:32.330675478 +0200 +++ linux-2.6.34.1/drivers/xen/pcifront/pci_op.c 2010-09-29 16:39:23.197674096 +0200 @@ -435,6 +435,43 @@ static int pcifront_claim_resource(struc return 0; } +int __devinit pcifront_scan_bus(struct pcifront_device *pdev, + unsigned int domain, unsigned int bus, + struct pci_bus *b) +{ + struct pci_dev *d; + unsigned int devfn; + int err; + + /* Scan the bus for functions and add. + * We omit handling of PCI bridge attachment because pciback prevents + * bridges from being exported. + */ + for (devfn = 0; devfn < 0x100; devfn++) { + d = pci_get_slot(b, devfn); + if (d) { + /* Device is already known. */ + pci_dev_put(d); + continue; + } + + d = pci_scan_single_device(b, devfn); + if (d) { + dev_info(&pdev->xdev->dev, "New device on " + "%04x:%02x:%02x.%02x found.\n", domain, bus, + PCI_SLOT(devfn), PCI_FUNC(devfn)); + err = pci_bus_add_device(d); + if (err) { + dev_err(&pdev->xdev->dev, "Failed to add " + " device to bus.\n"); + return err; + } + } + } + + return 0; +} + int __devinit pcifront_scan_root(struct pcifront_device *pdev, unsigned int domain, unsigned int bus) { @@ -484,7 +521,11 @@ int __devinit pcifront_scan_root(struct pci_bus_add_devices(b); - return 0; + /* pci_scan_bus_parented skips devices which do not have a have + * devfn==0. The pcifront_scan_bus enumerates all devfn. */ + err = pcifront_scan_bus(pdev, domain, bus, b); + + return err; err_out: kfree(bus_entry); @@ -496,10 +537,9 @@ int __devinit pcifront_scan_root(struct int __devinit pcifront_rescan_root(struct pcifront_device *pdev, unsigned int domain, unsigned int bus) { + int err; struct pci_bus *b; - struct pci_dev *d; - unsigned int devfn; - + #ifndef CONFIG_PCI_DOMAINS if (domain != 0) { dev_err(&pdev->xdev->dev, @@ -518,34 +558,9 @@ int __devinit pcifront_rescan_root(struc /* If the bus is unknown, create it. */ return pcifront_scan_root(pdev, domain, bus); - /* Rescan the bus for newly attached functions and add. - * We omit handling of PCI bridge attachment because pciback prevents - * bridges from being exported. - */ - for (devfn = 0; devfn < 0x100; devfn++) { - d = pci_get_slot(b, devfn); - if(d) { - /* Device is already known. */ - pci_dev_put(d); - continue; - } - - d = pci_scan_single_device(b, devfn); - if (d) { - int err; - - dev_info(&pdev->xdev->dev, "New device on " - "%04x:%02x:%02x.%02x found.\n", domain, bus, - PCI_SLOT(devfn), PCI_FUNC(devfn)); - err = pci_bus_add_device(d); - if (err) - dev_err(&pdev->xdev->dev, - "error %d adding device, continuing.\n", - err); - } - } + err = pcifront_scan_bus(pdev, domain, bus, b); - return 0; + return err; } static void free_root_bus_devs(struct pci_bus *bus)