128 lines
4.2 KiB
Diff
128 lines
4.2 KiB
Diff
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 <konrad.wilk@oracle.com>
|
|
Tue, 8 Jun 2010 16:59:41 +0000 (12:59 -0400)
|
|
committer Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
|
|
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 <konrad.wilk@oracle.com>
|
|
--- 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)
|