You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
qubes-linux-kernel/patches.xen/pcifront-enforce-scan.patch

128 lines
4.2 KiB

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)