[PATCH]; drivers/pci.c kernel-2.4.7

From: f.duncan.m.haldane@worldnet.att.net
Date: Sat Aug 11 2001 - 00:07:02 EST


Here is a tested patch to pci_find_parent_resource(dev,res) in
drivers/pci.c. (Patch is against 2.4.7; attached as tarball)
Problem occurs in all 2.4.x kernels.

PROBLEM: when allocating resource regions for PCI device dev at boot,
only the resources of its parent bus dev->bus are searched.

I have an nvidia AGP card on 01:00.0 which requires PCI MEM which is a
resource of the PCI bridge 00:01.0.

bus [01] = dev->bus gets searched, but nothing is found; the card is
not configured.

lspci -t shows the pci bus tree:

-[00]-+-00.0
      +-01.0-[01]---00.0
      +-07.0
      etc

SOLUTION: if bus = dev->bus has no relevant resources listed,
try bus->parent, if != NULL. Recursively search resources of parents,
grandparents, etc. of bus. In my case, the resource is found on [00],
and the card works.

QUESTION: Is it in general OK to allow "upstream" resource regions
to be allocated to a device? Maybe only dev->bus and dev->bus->parent
should be searched. (My patch will keep searching all the way to the
top)

Please CC any comments to me at f.duncan.m.haldane@worldnet.att.net.

Duncan Haldane.

------------

diff -uNr linux-2.4.7/drivers/pci/pci.c linux-2.4.7-pci_patch/drivers/pci/pci.c
--- linux-2.4.7/drivers/pci/pci.c Thu Aug 9 02:36:31 2001
+++ linux-2.4.7-pci_patch/drivers/pci/pci.c Thu Aug 9 13:13:02 2001
@@ -202,17 +202,18 @@
  * @res: child resource record for which parent is sought
  *
  * For given resource region of given device, return the resource
- * region of parent bus the given region is contained in or where
- * it should be allocated from.
+ * region of the parent bus (or recursively of its parents) in which the given
+ * region is contained in or where it should be allocated from.
  */
 struct resource *
 pci_find_parent_resource(const struct pci_dev *dev, struct resource *res)
 {
- const struct pci_bus *bus = dev->bus;
+ struct pci_bus *bus = dev->bus;
        int i;
        struct resource *best = NULL;
 
- for(i=0; i<4; i++) {
+ while (bus) {
+ for(i=0; i<4; i++) {
                struct resource *r = bus->resource[i];
                if (!r)
                        continue;
@@ -224,6 +225,10 @@
                        return r; /* Exact match */
                if ((res->flags & IORESOURCE_PREFETCH) && !(r->flags &
IORESOURCE_PREFETCH))
                        best = r; /* Approximating prefetchable by
non-prefetchable */
+ }
+ if (best)
+ return best;
+ bus = bus->parent; /* If nothing found, recursively search parent */
        }
        return best;
 }

----------------------------------
E-Mail: f.duncan.m.haldane@worldnet.att.net
Date: 11-Aug-2001
Time: 00:51:42

This message was sent by XFMail
----------------------------------



End of MIME message
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Wed Aug 15 2001 - 21:00:37 EST