Redux: this new version will apply with -current This patch will allow acpiec to initialize earlier if a ECDT table is found. This fixes a lockup if booting on some Thinkpads while docked. You can tell if your system supports ECDT by scanning the ACPI tables line in dmesg. There should be a line like this: acpi0: tables DSDT FACP SSDT ECDT TCPA APIC MCFG HPET SLIC BOOT ASF! SSDT SSDT SSDT SSDT ECDT will be one of the entries if the early initialization is supported. If scanning dmesg, acpiec0 will now also initialize earlier (near acpitimer and acpimadt) instead of after acpiprt.
Index: acpi.c =================================================================== RCS file: /cvs/src/sys/dev/acpi/acpi.c,v retrieving revision 1.187 diff -u -p -u -p -b -r1.187 acpi.c --- acpi.c 22 Jul 2010 14:19:47 -0000 1.187 +++ acpi.c 24 Jul 2010 05:52:03 -0000 @@ -2123,6 +2123,10 @@ acpi_foundec(struct aml_node *node, void if (strcmp(dev, ACPI_DEV_ECD)) return 0; + /* Check if we're already attached */ + if (sc->sc_ec && sc->sc_ec->sc_devnode == node->parent) + return 0; + memset(&aaa, 0, sizeof(aaa)); aaa.aaa_iot = sc->sc_iot; aaa.aaa_memt = sc->sc_memt; Index: acpiec.c =================================================================== RCS file: /cvs/src/sys/dev/acpi/acpiec.c,v retrieving revision 1.34 diff -u -p -u -p -b -r1.34 acpiec.c --- acpiec.c 23 Jul 2010 20:21:58 -0000 1.34 +++ acpiec.c 24 Jul 2010 05:52:04 -0000 @@ -245,6 +245,11 @@ acpiec_match(struct device *parent, void { struct acpi_attach_args *aa = aux; struct cfdata *cf = match; + struct acpi_ecdt *ecdt = aa->aaa_table; + + /* Check for early ECDT table attach */ + if (ecdt && !memcmp(ecdt->hdr.signature, ECDT_SIG, sizeof(ECDT_SIG) - 1)) + return (1); /* sanity */ return (acpi_matchhids(aa, acpiec_hids, cf->cf_driver->cd_name)); @@ -384,6 +389,25 @@ acpiec_getcrs(struct acpiec_softc *sc, s char *buf; int size, ret; int64_t gpe; + struct acpi_ecdt *ecdt = aa->aaa_table; + extern struct aml_node aml_root; + + /* Check if this is ECDT initialization */ + if (ecdt) { + /* Get GPE, Data and Control segments */ + sc->sc_gpe = ecdt->gpe_bit; + + ctype = ecdt->ec_control.address_space_id; + ec_sc = ecdt->ec_control.address; + + dtype = ecdt->ec_data.address_space_id; + ec_data = ecdt->ec_data.address; + + /* Get devnode from header */ + sc->sc_devnode = aml_searchname(&aml_root, ecdt->ec_id); + + goto ecdtdone; + } if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "_GPE", 0, NULL, &gpe)) { dnprintf(10, "%s: no _GPE\n", DEVNAME(sc)); @@ -439,6 +463,7 @@ acpiec_getcrs(struct acpiec_softc *sc, s aml_freevalue(&res); /* XXX: todo - validate _CRS checksum? */ +ecdtdone: dnprintf(10, "%s: Data: 0x%x, S/C: 0x%x\n", DEVNAME(sc), ec_data, ec_sc);