PERFORCE change 1190508 for review
John Baldwin
jhb at FreeBSD.org
Mon Feb 3 00:17:04 UTC 2014
http://p4web.freebsd.org/@@1190508?ac=10
Change 1190508 by jhb at jhb_jhbbsd on 2014/01/31 19:03:06
Try to make the allocation of bus ranges less hacky, and allow
for the pcib and pccbb drivers to request a minimum count.
Affected files ...
.. //depot/projects/pci/sys/dev/pccbb/pccbb_pci.c#11 edit
.. //depot/projects/pci/sys/dev/pci/pci.c#51 edit
.. //depot/projects/pci/sys/dev/pci/pci_pci.c#45 edit
.. //depot/projects/pci/sys/dev/pci/pcib_private.h#28 edit
Differences ...
==== //depot/projects/pci/sys/dev/pccbb/pccbb_pci.c#11 (text+ko) ====
@@ -326,7 +326,7 @@
sc->pribus = pcib_get_bus(parent);
#if defined(NEW_PCIB) && defined(PCI_RES_BUS)
pci_write_config(brdev, PCIR_PRIBUS_2, sc->pribus, 1);
- pcib_setup_secbus(brdev, &sc->bus);
+ pcib_setup_secbus(brdev, &sc->bus, 1);
#endif
SLIST_INIT(&sc->rl);
cbb_powerstate_d0(brdev);
==== //depot/projects/pci/sys/dev/pci/pci.c#51 (text+ko) ====
@@ -3238,17 +3238,6 @@
}
/*
- * If requested, clear secondary bus registers in bridge devices
- * to force a complete renumbering rather than reserving the
- * existing range.
- */
- if (pci_clear_buses) {
- PCI_WRITE_CONFIG(bus, dev, sec_reg, 0, 1);
- PCI_WRITE_CONFIG(bus, dev, sub_reg, 0, 1);
- return;
- }
-
- /*
* If the existing bus range is valid, attempt to reserve it
* from our parent. If this fails for any reason, clear the
* secbus and subbus registers.
@@ -3266,26 +3255,36 @@
end = sub_bus;
count = end - start + 1;
- resource_list_add(rl, PCI_RES_BUS, 0, start, end, count);
+ resource_list_add(rl, PCI_RES_BUS, 0, 0ul, ~0ul, count);
+
+ /*
+ * If requested, clear secondary bus registers in
+ * bridge devices to force a complete renumbering
+ * rather than reserving the existing range. However,
+ * preserve the existing size.
+ */
+ if (pci_clear_buses)
+ goto clear;
+
rid = 0;
res = resource_list_reserve(rl, bus, dev, PCI_RES_BUS, &rid,
start, end, count, 0);
- if (res == NULL) {
- if (bootverbose || 1)
- device_printf(bus,
- "pci%d:%d:%d:%d secbus failed to allocate\n",
- pci_get_domain(dev), pci_get_bus(dev),
- pci_get_slot(dev), pci_get_function(dev));
- resource_list_delete(rl, PCI_RES_BUS, 0);
- } else
+ if (res != NULL) {
/* XXX */
pci_printf(cfg, "allocated initial secbus range\n");
- } else
- res = NULL;
- if (res == NULL) {
- PCI_WRITE_CONFIG(bus, dev, sec_reg, 0, 1);
- PCI_WRITE_CONFIG(bus, dev, sub_reg, 0, 1);
+ return;
+ }
+
+ if (bootverbose || 1)
+ device_printf(bus,
+ "pci%d:%d:%d:%d secbus failed to allocate\n",
+ pci_get_domain(dev), pci_get_bus(dev),
+ pci_get_slot(dev), pci_get_function(dev));
}
+
+clear:
+ PCI_WRITE_CONFIG(bus, dev, sec_reg, 0, 1);
+ PCI_WRITE_CONFIG(bus, dev, sub_reg, 0, 1);
}
static struct resource *
@@ -3314,17 +3313,12 @@
return (NULL);
}
- /*
- * rid 0 is used to request an already reserved range while
- * rid 1 is used to request an arbitrary range with a specific
- * count.
- */
- if (*rid > 1)
+ if (*rid != 0)
return (NULL);
- if (*rid == 1) {
- *rid = 0;
+ if (resource_list_find(rl, PCI_RES_BUS, *rid) == NULL)
resource_list_add(rl, PCI_RES_BUS, *rid, start, end, count);
+ if (!resource_list_reserved(rl, PCI_RES_BUS, *rid)) {
res = resource_list_reserve(rl, dev, child, PCI_RES_BUS, rid,
start, end, count, flags & ~RF_ACTIVE);
if (res == NULL) {
==== //depot/projects/pci/sys/dev/pci/pci_pci.c#45 (text+ko) ====
@@ -531,10 +531,12 @@
#ifdef PCI_RES_BUS
/*
* Allocate a suitable secondary bus for this bridge if needed and
- * initialize the resource manager for the secondary bus range.
+ * initialize the resource manager for the secondary bus range. Note
+ * that the minimum count is a desired value and this may allocate a
+ * smaller range.
*/
void
-pcib_setup_secbus(device_t dev, struct pcib_secbus *bus)
+pcib_setup_secbus(device_t dev, struct pcib_secbus *bus, int min_count)
{
char buf[64];
int error, rid;
@@ -560,44 +562,37 @@
panic("Failed to initialize %s bus number rman",
device_get_nameunit(dev));
- /* Allocate any existing bus range. */
+ /*
+ * Allocate a bus range. This will return an existing bus range
+ * if one exists, or a new bus range if one does not.
+ */
rid = 0;
- bus->res = bus_alloc_resource_any(dev, PCI_RES_BUS, &rid, 0);
+ bus->res = bus_alloc_resource(dev, PCI_RES_BUS, &rid, 0ul, ~0ul,
+ min_count, 0);
+ if (bus_res == NULL) {
+ /*
+ * Fall back to just allocating a range of a single bus
+ * number.
+ */
+ bus->res = bus_alloc_resource(dev, PCI_RES_BUS, &rid, 0ul, ~0ul,
+ 1, 0);
+ } else if (rman_get_size(bus_res) < min_count)
+ /*
+ * Attempt to grow the existing range to satisfy the
+ * minimum desired count.
+ */
+ (void)bus_adjust_resource(dev, PCI_RES_BUS, bus_res,
+ rman_get_start(bus_res), rman_get_start(bus_res) +
+ min_count - 1);
/* XXX */
if (bus->res != NULL)
device_printf(dev,
- "allocated initial secbus range %lu-%lu\n",
+ "allocated secbus range %lu-%lu\n",
rman_get_start(bus->res), rman_get_end(bus->res));
-
- /*
- * If we don't have a valid resource, allocate a fresh resource
- * for just this bus.
- *
- * XXX: Should we always start with a bus higher than our primary
- * side bus number? I'm not sure it is required by the spec but
- * it seems sensible. OTOH, the existing rmans in any parent
- * PCI-PCI bridges should already enforce this.
- */
- if (bus->res == NULL) {
- /*
- * This doesn't use bus_alloc_resource_any() as the
- * count of 1 is explicit.
- */
- rid = 1;
- bus->res = bus_alloc_resource(dev, PCI_RES_BUS, &rid, 0ul, ~0ul,
- 1, 0);
- if (bus->res != NULL) {
- KASSERT(rman_get_size(bus->res) == 1,
- ("more than one bus number"));
- if (bootverbose || 1)
- device_printf(bus->dev,
- "allocated initial secbus %lu\n",
- rman_get_start(bus->res));
- } else
- device_printf(bus->dev,
+ else
+ device_printf(dev,
"failed to allocate secondary bus number\n");
- }
/*
* Add the initial resource to the rman.
@@ -1027,7 +1022,7 @@
#ifdef NEW_PCIB
#ifdef PCI_RES_BUS
- pcib_setup_secbus(dev, &sc->bus);
+ pcib_setup_secbus(dev, &sc->bus, 1);
#endif
pcib_probe_windows(sc);
#endif
==== //depot/projects/pci/sys/dev/pci/pcib_private.h#28 (text+ko) ====
@@ -140,7 +140,8 @@
struct resource *pcib_alloc_subbus(struct pcib_secbus *bus, device_t child,
int *rid, u_long start, u_long end, u_long count,
u_int flags);
-void pcib_setup_secbus(device_t dev, struct pcib_secbus *bus);
+void pcib_setup_secbus(device_t dev, struct pcib_secbus *bus,
+ int min_count);
#endif
int pcib_attach(device_t dev);
void pcib_attach_common(device_t dev);
More information about the p4-projects
mailing list