From owner-svn-src-stable@FreeBSD.ORG Tue Nov 9 15:14:11 2010 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 0A2741065674; Tue, 9 Nov 2010 15:14:11 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id EBD298FC23; Tue, 9 Nov 2010 15:14:10 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id oA9FEAUh023386; Tue, 9 Nov 2010 15:14:10 GMT (envelope-from mav@svn.freebsd.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id oA9FEAa8023382; Tue, 9 Nov 2010 15:14:10 GMT (envelope-from mav@svn.freebsd.org) Message-Id: <201011091514.oA9FEAa8023382@svn.freebsd.org> From: Alexander Motin Date: Tue, 9 Nov 2010 15:14:10 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r215038 - stable/8/sys/dev/acpica X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 09 Nov 2010 15:14:11 -0000 Author: mav Date: Tue Nov 9 15:14:10 2010 New Revision: 215038 URL: http://svn.freebsd.org/changeset/base/215038 Log: MFC r208436, r208438: Make table-based HPET identification more clever. Before creating fake device, make sure we have no real HPET device entry with same ID. As side effect, it potentially allows several HPETs to be attached. Use first of them for timecounting, rest (if ever present) could later be used as event sources. Modified: stable/8/sys/dev/acpica/acpi.c stable/8/sys/dev/acpica/acpi_hpet.c stable/8/sys/dev/acpica/acpivar.h Directory Properties: stable/8/sys/ (props changed) stable/8/sys/amd64/include/xen/ (props changed) stable/8/sys/cddl/contrib/opensolaris/ (props changed) stable/8/sys/contrib/dev/acpica/ (props changed) stable/8/sys/contrib/pf/ (props changed) stable/8/sys/dev/xen/xenpci/ (props changed) Modified: stable/8/sys/dev/acpica/acpi.c ============================================================================== --- stable/8/sys/dev/acpica/acpi.c Tue Nov 9 14:53:49 2010 (r215037) +++ stable/8/sys/dev/acpica/acpi.c Tue Nov 9 15:14:10 2010 (r215038) @@ -143,7 +143,6 @@ static void acpi_probe_children(device_t static void acpi_probe_order(ACPI_HANDLE handle, int *order); static ACPI_STATUS acpi_probe_child(ACPI_HANDLE handle, UINT32 level, void *context, void **status); -static BOOLEAN acpi_MatchHid(ACPI_HANDLE h, const char *hid); static void acpi_sleep_enable(void *arg); static ACPI_STATUS acpi_sleep_disable(struct acpi_softc *sc); static ACPI_STATUS acpi_EnterSleepState(struct acpi_softc *sc, int state); @@ -1924,7 +1923,7 @@ acpi_BatteryIsPresent(device_t dev) /* * Match a HID string against a handle */ -static BOOLEAN +BOOLEAN acpi_MatchHid(ACPI_HANDLE h, const char *hid) { ACPI_DEVICE_INFO *devinfo; Modified: stable/8/sys/dev/acpica/acpi_hpet.c ============================================================================== --- stable/8/sys/dev/acpica/acpi_hpet.c Tue Nov 9 14:53:49 2010 (r215037) +++ stable/8/sys/dev/acpica/acpi_hpet.c Tue Nov 9 15:14:10 2010 (r215038) @@ -101,41 +101,60 @@ hpet_disable(struct acpi_hpet_softc *sc) bus_write_4(sc->mem_res, HPET_CONFIG, val); } +static ACPI_STATUS +acpi_hpet_find(ACPI_HANDLE handle, UINT32 level, void *context, + void **status) +{ + char **ids; + uint32_t id = (uint32_t)(uintptr_t)context; + uint32_t uid = 0; + + for (ids = hpet_ids; *ids != NULL; ids++) { + if (acpi_MatchHid(handle, *ids)) + break; + } + if (*ids == NULL) + return (AE_OK); + if (ACPI_FAILURE(acpi_GetInteger(handle, "_UID", &uid))) + uid = 0; + if (id == uid) + *((int *)status) = 1; + return (AE_OK); +} + /* Discover the HPET via the ACPI table of the same name. */ static void acpi_hpet_identify(driver_t *driver, device_t parent) { ACPI_TABLE_HPET *hpet; - ACPI_TABLE_HEADER *hdr; ACPI_STATUS status; device_t child; + int i, found; /* Only one HPET device can be added. */ if (devclass_get_device(acpi_hpet_devclass, 0)) return; - - /* Currently, ID and minimum clock tick info is unused. */ - - status = AcpiGetTable(ACPI_SIG_HPET, 1, (ACPI_TABLE_HEADER **)&hdr); - if (ACPI_FAILURE(status)) - return; - - /* - * The unit number could be derived from hdr->Sequence but we only - * support one HPET device. - */ - hpet = (ACPI_TABLE_HPET *)hdr; - if (hpet->Sequence != 0) - printf("ACPI HPET table warning: Sequence is non-zero (%d)\n", - hpet->Sequence); - child = BUS_ADD_CHILD(parent, ACPI_DEV_BASE_ORDER, "acpi_hpet", 0); - if (child == NULL) { - printf("%s: can't add child\n", __func__); - return; + for (i = 1; ; i++) { + /* Search for HPET table. */ + status = AcpiGetTable(ACPI_SIG_HPET, i, (ACPI_TABLE_HEADER **)&hpet); + if (ACPI_FAILURE(status)) + return; + /* Search for HPET device with same ID. */ + found = 0; + AcpiWalkNamespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, + 100, acpi_hpet_find, NULL, (void *)(uintptr_t)hpet->Sequence, (void *)&found); + /* If found - let it be probed in normal way. */ + if (found) + continue; + /* If not - create it from table info. */ + child = BUS_ADD_CHILD(parent, ACPI_DEV_BASE_ORDER, "acpi_hpet", 0); + if (child == NULL) { + printf("%s: can't add child\n", __func__); + continue; + } + bus_set_resource(child, SYS_RES_MEMORY, 0, hpet->Address.Address, + HPET_MEM_WIDTH); } - - bus_set_resource(child, SYS_RES_MEMORY, 0, hpet->Address.Address, - HPET_MEM_WIDTH); } static int @@ -146,8 +165,7 @@ acpi_hpet_probe(device_t dev) if (acpi_disabled("hpet")) return (ENXIO); if (acpi_get_handle(dev) != NULL && - (ACPI_ID_PROBE(device_get_parent(dev), dev, hpet_ids) == NULL || - device_get_unit(dev) != 0)) + ACPI_ID_PROBE(device_get_parent(dev), dev, hpet_ids) == NULL) return (ENXIO); device_set_desc(dev, "High Precision Event Timer"); @@ -233,11 +251,12 @@ acpi_hpet_attach(device_t dev) bus_free_resource(dev, SYS_RES_MEMORY, sc->mem_res); return (ENXIO); } - - hpet_timecounter.tc_frequency = freq; - hpet_timecounter.tc_priv = sc; - tc_init(&hpet_timecounter); - + /* Announce first HPET as timecounter. */ + if (device_get_unit(dev) == 0) { + hpet_timecounter.tc_frequency = freq; + hpet_timecounter.tc_priv = sc; + tc_init(&hpet_timecounter); + } return (0); } Modified: stable/8/sys/dev/acpica/acpivar.h ============================================================================== --- stable/8/sys/dev/acpica/acpivar.h Tue Nov 9 14:53:49 2010 (r215037) +++ stable/8/sys/dev/acpica/acpivar.h Tue Nov 9 15:14:10 2010 (r215038) @@ -344,6 +344,7 @@ int acpi_bus_alloc_gas(device_t dev, in u_int flags); void acpi_walk_subtables(void *first, void *end, acpi_subtable_handler *handler, void *arg); +BOOLEAN acpi_MatchHid(ACPI_HANDLE h, const char *hid); struct acpi_parse_resource_set { void (*set_init)(device_t dev, void *arg, void **context);