[acpi-jp 2190] Re: Outstanding ACPI issues for 5.1-RELEASE
Magnus B{ckstr|m
b at etek.chalmers.se
Thu May 8 01:29:01 PDT 2003
On Thu, 8 May 2003, User Takawata wrote:
>
> That's because the _HID format is not conform to the standard.
> Add following change and check whether Host PCI bus bridge appears or not.
> !acpi_disabled("pci") &&
> - acpi_MatchHid(dev, "PNP0A03")) {
> + acpi_MatchHid(dev, "*PNP0A03")) {
>
I'm afraid this may not be the end of it. An N800c I encountered a few
weeks ago consistently had _HIDs with asterisks. If I may contribute
an untested general workaround (untested because I don't currently have
access to the hardware):
Index: src/sys/dev/acpica/acpi.c
diff -u src/sys/dev/acpica/acpi.c:1.1.1.6.2.1 src/sys/dev/acpica/acpi.c:1.1.1.6.2.2
--- src/sys/dev/acpica/acpi.c:1.1.1.6.2.1 Wed Apr 16 16:06:20 2003
+++ src/sys/dev/acpica/acpi.c Thu May 8 10:00:28 2003
@@ -1041,8 +1041,21 @@
return(FALSE);
if (ACPI_FAILURE(error = AcpiGetObjectInfo(h, &devinfo)))
return(FALSE);
- if ((devinfo.Valid & ACPI_VALID_HID) && !strcmp(hid, devinfo.HardwareId))
- return(TRUE);
+
+ /*
+ * Some vendors erronously report HIDs with leading asterisks.
+ * The below workaround accomodates this.
+ */
+ if (devinfo.Valid & ACPI_VALID_HID) {
+ if (devinfo.HardwareId[0] == '*') {
+ if (strcmp(hid, (devinfo.HardwareId + 1)) == 0)
+ return TRUE;
+ }
+
+ if (strcmp(hid, devinfo.HardwareId) == 0)
+ return (TRUE);
+ }
+
if (ACPI_FAILURE(error = acpi_EvaluateInteger(h, "_CID", &cid)))
return(FALSE);
if (cid == PNP_EISAID(hid))
Furthermore, the laptop used idioms that were a bit too modern for
our ACPI implementation. CIDs are allowed to be not only integers,
but also buffers (think `char *') with images of ACPI_INTEGERs, and
packages with multiple integer objects in them (for multiple possible
CIDs). The below -should- fix this but is also untested.
Index: src/sys/dev/acpica/acpi.c
diff -u src/sys/dev/acpica/acpi.c:1.1.1.6.2.2 src/sys/dev/acpica/acpi.c:1.1.1.6.2.3
--- src/sys/dev/acpica/acpi.c:1.1.1.6.2.2 Thu May 8 10:00:28 2003
+++ src/sys/dev/acpica/acpi.c Thu May 8 10:06:17 2003
@@ -1160,20 +1160,57 @@
{
ACPI_OBJECT *p;
int i;
+ ACPI_INTEGER num;
p = (ACPI_OBJECT *)bufp->Pointer;
if (p->Type == ACPI_TYPE_INTEGER) {
*number = p->Integer.Value;
return(AE_OK);
}
- if (p->Type != ACPI_TYPE_BUFFER)
+ if (p->Type == ACPI_TYPE_PACKAGE) {
+ /*
+ * Shrewdly guess that the vendor is likely to put the most
+ * useful element last in the package.
+ */
+ if (p->Package.Elements[p->Package.Count-1].Type ==ACPI_TYPE_INTEGER) {
+ *number = (int) p->Package.Elements[1].Integer.Value;
+ return (AE_OK);
+ }
+
+ }
+ if (p->Type != ACPI_TYPE_BUFFER) {
+ printf("acpi_ConvertBufferToInteger: Unknown p->Type %d\n", p->Type);
return(AE_TYPE);
- if (p->Buffer.Length > sizeof(int))
- return(AE_BAD_DATA);
- *number = 0;
- for (i = 0; i < p->Buffer.Length; i++)
- *number += (*(p->Buffer.Pointer + i) << (i * 8));
- return(AE_OK);
+ }
+
+ /*
+ * In ACPI 2.0 an ACPI_INTEGER is 64 bit. In 1.0 it was 32 bit.
+ * We comply with either.
+ */
+ if (p->Buffer.Length == sizeof(ACPI_INTEGER)) {
+ num = 0;
+
+ for (i = 0; i < p->Buffer.Length; i++)
+ num += (*(p->Buffer.Pointer + i) << (i * 8));
+
+ *number = (int) num;
+ return(AE_OK);
+ }
+
+ /* ACPI 1.0 case. */
+ if (p->Buffer.Length == sizeof(int)) {
+ *number = 0;
+
+ for (i = 0; i < p->Buffer.Length; i++)
+ *number += (*(p->Buffer.Pointer + i) << (i * 8));
+
+ return (AE_OK);
+ }
+
+ printf("acpi_ConvertBufferToInteger: bad buffer length %d\n",
+ p->Buffer.Length);
+
+ return (AE_BAD_DATA);
}
/*
Best regards,
Magnus
More information about the freebsd-current
mailing list