Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 31 Jan 2014 19:03:36 GMT
From:      John Baldwin <jhb@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 1190508 for review
Message-ID:  <201401311903.s0VJ3auK076244@skunkworks.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@1190508?ac=10

Change 1190508 by jhb@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);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201401311903.s0VJ3auK076244>