From owner-svn-src-head@freebsd.org Sun Sep 4 01:43:56 2016 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 5C6A7B786E1; Sun, 4 Sep 2016 01:43:56 +0000 (UTC) (envelope-from landonf@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 1B34B65E; Sun, 4 Sep 2016 01:43:56 +0000 (UTC) (envelope-from landonf@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u841htiB049150; Sun, 4 Sep 2016 01:43:55 GMT (envelope-from landonf@FreeBSD.org) Received: (from landonf@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u841htkf049147; Sun, 4 Sep 2016 01:43:55 GMT (envelope-from landonf@FreeBSD.org) Message-Id: <201609040143.u841htkf049147@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: landonf set sender to landonf@FreeBSD.org using -f From: "Landon J. Fuller" Date: Sun, 4 Sep 2016 01:43:55 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r305374 - head/sys/dev/bhnd/bhndb X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 04 Sep 2016 01:43:56 -0000 Author: landonf Date: Sun Sep 4 01:43:54 2016 New Revision: 305374 URL: https://svnweb.freebsd.org/changeset/base/305374 Log: bhndb(4): Skip disabled cores when performing bridge configuration probing. On BCM4321 chipsets, both PCI and PCIe cores are included, with one of the cores potentially left floating. Since the PCI core appears first in the device table, and the PCI profiles appear first in the resource configuration tables, this resulted in incorrectly matching and using the PCI/v1 resource configuration on PCIe devices, rather than the correct PCIe/v1 profile. Approved by: adrian (mentor, implicit) Modified: head/sys/dev/bhnd/bhndb/bhnd_bhndb.c head/sys/dev/bhnd/bhndb/bhndb.c head/sys/dev/bhnd/bhndb/bhndb_if.m Modified: head/sys/dev/bhnd/bhndb/bhnd_bhndb.c ============================================================================== --- head/sys/dev/bhnd/bhndb/bhnd_bhndb.c Sun Sep 4 01:25:46 2016 (r305373) +++ head/sys/dev/bhnd/bhndb/bhnd_bhndb.c Sun Sep 4 01:43:54 2016 (r305374) @@ -66,6 +66,17 @@ bhnd_bhndb_get_attach_type(device_t dev, return (BHND_ATTACH_ADAPTER); } + +static bool +bhnd_bhndb_is_hw_disabled(device_t dev, device_t child) +{ + struct bhnd_core_info core = bhnd_get_core_info(child); + + /* Delegate to parent bridge */ + return (BHNDB_IS_CORE_DISABLED(device_get_parent(dev), dev, &core)); +} + + static device_t bhnd_bhndb_find_hostb_device(device_t dev) { @@ -112,6 +123,7 @@ bhnd_bhndb_pwrctl_ungate_clock(device_t static device_method_t bhnd_bhndb_methods[] = { /* BHND interface */ DEVMETHOD(bhnd_bus_get_attach_type, bhnd_bhndb_get_attach_type), + DEVMETHOD(bhnd_bus_is_hw_disabled, bhnd_bhndb_is_hw_disabled), DEVMETHOD(bhnd_bus_find_hostb_device, bhnd_bhndb_find_hostb_device), DEVMETHOD(bhnd_bus_read_board_info, bhnd_bhndb_read_board_info), Modified: head/sys/dev/bhnd/bhndb/bhndb.c ============================================================================== --- head/sys/dev/bhnd/bhndb/bhndb.c Sun Sep 4 01:25:46 2016 (r305373) +++ head/sys/dev/bhnd/bhndb/bhndb.c Sun Sep 4 01:43:54 2016 (r305374) @@ -85,8 +85,9 @@ static int bhndb_init_full_config(str static struct bhnd_core_info *bhndb_get_bridge_core(struct bhndb_softc *sc); -static bool bhndb_hw_matches(struct bhnd_core_info *cores, - u_int ncores, const struct bhndb_hw *hw); +static bool bhndb_hw_matches(struct bhndb_softc *sc, + struct bhnd_core_info *cores, u_int ncores, + const struct bhndb_hw *hw); static int bhndb_init_region_cfg(struct bhndb_softc *sc, bhnd_erom_t *erom, @@ -212,14 +213,15 @@ bhndb_get_bridge_core(struct bhndb_softc /** * Return true if @p cores matches the @p hw specification. - * + * + * @param sc BHNDB device state. * @param cores A device table to match against. * @param ncores The number of cores in @p cores. * @param hw The hardware description to be matched against. */ static bool -bhndb_hw_matches(struct bhnd_core_info *cores, u_int ncores, - const struct bhndb_hw *hw) +bhndb_hw_matches(struct bhndb_softc *sc, struct bhnd_core_info *cores, + u_int ncores, const struct bhndb_hw *hw) { for (u_int i = 0; i < hw->num_hw_reqs; i++) { const struct bhnd_core_match *match; @@ -229,7 +231,12 @@ bhndb_hw_matches(struct bhnd_core_info * found = false; for (u_int d = 0; d < ncores; d++) { - if (!bhnd_core_matches(&cores[d], match)) + struct bhnd_core_info *core = &cores[d]; + + if (BHNDB_IS_CORE_DISABLED(sc->dev, sc->bus_dev, core)) + continue; + + if (!bhnd_core_matches(core, match)) continue; found = true; @@ -353,7 +360,7 @@ bhndb_init_region_cfg(struct bhndb_softc */ /* ... do not require bridge resources */ - if (BHNDB_BUS_IS_CORE_DISABLED(sc->parent_dev, sc->dev, core)) + if (BHNDB_IS_CORE_DISABLED(sc->dev, sc->bus_dev, core)) continue; /* ... do not have a priority table entry */ @@ -475,7 +482,7 @@ bhndb_find_hwspec(struct bhndb_softc *sc /* Search for the first matching hardware config. */ hw_table = BHNDB_BUS_GET_HARDWARE_TABLE(sc->parent_dev, sc->dev); for (next = hw_table; next->hw_reqs != NULL; next++) { - if (!bhndb_hw_matches(cores, ncores, next)) + if (!bhndb_hw_matches(sc, cores, ncores, next)) continue; /* Found */ @@ -1166,30 +1173,27 @@ bhndb_get_chipid(device_t dev, device_t return (&sc->chipid); } - /** - * Default implementation of BHND_BUS_IS_HW_DISABLED(). + * Default implementation of BHNDB_IS_CORE_DISABLED(). */ static bool -bhndb_is_hw_disabled(device_t dev, device_t child) +bhndb_is_core_disabled(device_t dev, device_t child, + struct bhnd_core_info *core) { struct bhndb_softc *sc; struct bhnd_core_info *bridge_core; - struct bhnd_core_info core; sc = device_get_softc(dev); - core = bhnd_get_core_info(child); - /* Try to defer to the bhndb bus parent */ - if (BHNDB_BUS_IS_CORE_DISABLED(sc->parent_dev, dev, &core)) + if (BHNDB_BUS_IS_CORE_DISABLED(sc->parent_dev, dev, core)) return (true); /* Otherwise, we treat bridge-capable cores as unpopulated if they're * not the configured host bridge */ bridge_core = bhndb_get_bridge_core(sc); - if (BHND_DEVCLASS_SUPPORTS_HOSTB(bhnd_core_class(&core))) - return (!bhnd_cores_equal(&core, bridge_core)); + if (BHND_DEVCLASS_SUPPORTS_HOSTB(bhnd_core_class(core))) + return (!bhnd_cores_equal(core, bridge_core)); /* Assume the core is populated */ return (false); @@ -2153,12 +2157,12 @@ static device_method_t bhndb_methods[] = /* BHNDB interface */ DEVMETHOD(bhndb_get_chipid, bhndb_get_chipid), + DEVMETHOD(bhndb_is_core_disabled, bhndb_is_core_disabled), DEVMETHOD(bhndb_get_hostb_core, bhndb_get_hostb_core), DEVMETHOD(bhndb_suspend_resource, bhndb_suspend_resource), DEVMETHOD(bhndb_resume_resource, bhndb_resume_resource), /* BHND interface */ - DEVMETHOD(bhnd_bus_is_hw_disabled, bhndb_is_hw_disabled), DEVMETHOD(bhnd_bus_get_chipid, bhndb_get_chipid), DEVMETHOD(bhnd_bus_activate_resource, bhndb_activate_bhnd_resource), DEVMETHOD(bhnd_bus_deactivate_resource, bhndb_deactivate_bhnd_resource), Modified: head/sys/dev/bhnd/bhndb/bhndb_if.m ============================================================================== --- head/sys/dev/bhnd/bhndb/bhndb_if.m Sun Sep 4 01:25:46 2016 (r305373) +++ head/sys/dev/bhnd/bhndb/bhndb_if.m Sun Sep 4 01:43:54 2016 (r305374) @@ -61,7 +61,14 @@ CODE { { panic("bhndb_populate_board_info unimplemented"); } - + + static int + bhndb_null_is_core_disabled(device_t dev, device_t child, + struct bhnd_core_info *core) + { + panic("bhndb_is_core_disabled unimplemented"); + } + static int bhndb_null_get_hostb_core(device_t dev, device_t child, struct bhnd_core_info *core) @@ -118,6 +125,24 @@ METHOD int populate_board_info { } DEFAULT bhndb_null_populate_board_info; /** + * Return true if the hardware required by @p core is unpopulated or + * otherwise unusable. + * + * In some cases, the core's pins may be left floating, or the hardware + * may otherwise be non-functional; this method allows the parent device + * to explicitly specify whether @p core should be disabled. + * + * @param dev The parent device of @p child. + * @param child The attached bhnd device. + * @param core A core discovered on @p child. + */ +METHOD bool is_core_disabled { + device_t dev; + device_t child; + struct bhnd_core_info *core; +} DEFAULT bhndb_null_is_core_disabled; + +/** * Get the host bridge core info for the attached bhnd bus. * * @param dev The bridge device.