aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJessica Clarke <jrtc27@FreeBSD.org>2021-10-03 18:35:26 +0000
committerJessica Clarke <jrtc27@FreeBSD.org>2021-10-10 13:36:54 +0000
commit398c8572b8be32658c0d4f76481e01637d88d602 (patch)
treeca073b22d931672ff2b124ab3f48e77bffcf9481
parent2580d19585458341c8dac0fcbb51e18131ccde93 (diff)
downloadsrc-398c8572b8be32658c0d4f76481e01637d88d602.tar.gz
src-398c8572b8be32658c0d4f76481e01637d88d602.zip
pci_pci: Support growing bus ranges in bus_adjust_resource for NEW_PCIB
This is the same underlying problem as 262459806433, just for bus ranges rather than windows. SiFive's HiFive Unmatched has the following topology: Root Port <---> Bridge <---> Bridge <-+-> Bridge <---> (Unused) (pcib0) (pcib1) (pcib2) | (pcib3) +-> Bridge <---> xHCI | (pcib4) +-> Bridge <---> M.2 E-key | (pcib5) +-> Bridge <---> M.2 M-key | (pcib6) +-> Bridge <---> x16 slot (pcib7) If a device is plugged into the x16 slot that itself has a bridge, such as many graphics cards, we currently fail to allocate a bus number for its child bus (and so pcib_attach_child skips adding a child bus for further enumeration) as, when the new child bridge attaches, it attempts to allocate a bus number from its parent (pcib7) which in turn attempts to grow its own bus range by calling bus_adjust_resource on its own parent (pcib2) whose bus rman cannot accommodate the request and needs to itself be extended by calling its own parent (pcib1). Note that pcib3-7 do not face the same issue when they attach since pcib1 ends up managing bus numbers 1-255 from the beginning and so never needs to grow its own range. Reviewed by: jhb, mav MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D32011 (cherry picked from commit 31776afdc79d5fb1ea211cc2a69c17c62b3dc8ff)
-rw-r--r--sys/dev/pci/pci_pci.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/sys/dev/pci/pci_pci.c b/sys/dev/pci/pci_pci.c
index 2b86f2f50e11..cecf75024d3f 100644
--- a/sys/dev/pci/pci_pci.c
+++ b/sys/dev/pci/pci_pci.c
@@ -2364,7 +2364,20 @@ pcib_adjust_resource(device_t bus, device_t child, int type, struct resource *r,
start, end));
#ifdef PCI_RES_BUS
- if (type != PCI_RES_BUS)
+ if (type == PCI_RES_BUS) {
+ /*
+ * If our bus range isn't big enough to grow the sub-allocation
+ * then we need to grow our bus range. Any request that would
+ * require us to decrease the start of our own bus range is
+ * invalid, we can only extend the end; ignore such requests
+ * and let rman_adjust_resource fail below.
+ */
+ if (start >= sc->bus.sec && end > sc->bus.sub) {
+ error = pcib_grow_subbus(&sc->bus, end);
+ if (error != 0)
+ return (error);
+ }
+ } else
#endif
{
/*