From owner-p4-projects@FreeBSD.ORG Mon Feb 3 00:17:04 2014 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 55F29AF6; Mon, 3 Feb 2014 00:17:04 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 6EA6F7C5 for ; Mon, 3 Feb 2014 00:16:45 +0000 (UTC) Received: from skunkworks.freebsd.org (skunkworks.freebsd.org [IPv6:2001:1900:2254:2068::682:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 59BB01588 for ; Mon, 3 Feb 2014 00:16:45 +0000 (UTC) Received: from skunkworks.freebsd.org ([127.0.1.74]) by skunkworks.freebsd.org (8.14.7/8.14.7) with ESMTP id s12NL47i001523 for ; Sun, 2 Feb 2014 23:21:15 GMT (envelope-from jhb@freebsd.org) Received: (from perforce@localhost) by skunkworks.freebsd.org (8.14.7/8.14.7/Submit) id s0VJ3auK076244 for perforce@freebsd.org; Fri, 31 Jan 2014 19:03:36 GMT (envelope-from jhb@freebsd.org) Date: Fri, 31 Jan 2014 19:03:36 GMT Message-Id: <201401311903.s0VJ3auK076244@skunkworks.freebsd.org> X-Authentication-Warning: skunkworks.freebsd.org: perforce set sender to jhb@freebsd.org using -f From: John Baldwin Subject: PERFORCE change 1190508 for review To: Perforce Change Reviews Precedence: bulk X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.17 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 03 Feb 2014 00:17:04 -0000 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);