summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/dev/acpica/acpi.c150
-rw-r--r--sys/dev/acpica/acpi_pci_link.c17
-rw-r--r--sys/dev/acpica/acpi_pcib.c24
3 files changed, 126 insertions, 65 deletions
diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c
index 1799f7b..151587e 100644
--- a/sys/dev/acpica/acpi.c
+++ b/sys/dev/acpica/acpi.c
@@ -105,8 +105,8 @@ static struct resource *acpi_alloc_resource(device_t bus, device_t child,
u_long count, u_int flags);
static int acpi_release_resource(device_t bus, device_t child, int type,
int rid, struct resource *r);
-static u_int32_t acpi_isa_get_logicalid(device_t dev);
-static u_int32_t acpi_isa_get_compatid(device_t dev);
+static uint32_t acpi_isa_get_logicalid(device_t dev);
+static int acpi_isa_get_compatid(device_t dev, uint32_t *cids, int count);
static int acpi_isa_pnp_probe(device_t bus, device_t child,
struct isa_pnp_id *ids);
static void acpi_probe_children(device_t bus);
@@ -800,12 +800,12 @@ acpi_bus_alloc_gas(device_t dev, int *rid, ACPI_GENERIC_ADDRESS *gas)
| (PNP_HEXTONUM(s[6]) << 24) \
| (PNP_HEXTONUM(s[5]) << 28))
-static u_int32_t
+static uint32_t
acpi_isa_get_logicalid(device_t dev)
{
+ ACPI_DEVICE_INFO *devinfo;
+ ACPI_BUFFER buf;
ACPI_HANDLE h;
- ACPI_DEVICE_INFO devinfo;
- ACPI_BUFFER buf = {sizeof(devinfo), &devinfo};
ACPI_STATUS error;
u_int32_t pnpid;
ACPI_LOCK_DECL;
@@ -817,50 +817,71 @@ acpi_isa_get_logicalid(device_t dev)
/* Fetch and validate the HID. */
if ((h = acpi_get_handle(dev)) == NULL)
- goto out;
+ return (0);
+ buf.Pointer = NULL;
+ buf.Length = ACPI_ALLOCATE_BUFFER;
error = AcpiGetObjectInfo(h, &buf);
if (ACPI_FAILURE(error))
- goto out;
- if ((devinfo.Valid & ACPI_VALID_HID) == 0)
- goto out;
+ return (0);
+ devinfo = (ACPI_DEVICE_INFO *)buf.Pointer;
- pnpid = PNP_EISAID(devinfo.HardwareId.Value);
+ if ((devinfo->Valid & ACPI_VALID_HID) != 0)
+ pnpid = PNP_EISAID(devinfo->HardwareId.Value);
-out:
+ AcpiOsFree(buf.Pointer);
ACPI_UNLOCK;
return_VALUE (pnpid);
}
-static u_int32_t
-acpi_isa_get_compatid(device_t dev)
+static int
+acpi_isa_get_compatid(device_t dev, uint32_t *cids, int count)
{
+ ACPI_DEVICE_INFO *devinfo;
+ ACPI_BUFFER buf;
ACPI_HANDLE h;
ACPI_STATUS error;
- u_int32_t pnpid;
+ uint32_t *pnpid;
+ int valid, i;
ACPI_LOCK_DECL;
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
- pnpid = 0;
+ pnpid = cids;
+ valid = 0;
ACPI_LOCK;
- /* Fetch and validate the HID */
+ /* Fetch and validate the CID */
if ((h = acpi_get_handle(dev)) == NULL)
- goto out;
- if (ACPI_FAILURE(error = acpi_EvaluateInteger(h, "_CID", &pnpid)))
+ return (0);
+ buf.Pointer = NULL;
+ buf.Length = ACPI_ALLOCATE_BUFFER;
+ error = AcpiGetObjectInfo(h, &buf);
+ if (ACPI_FAILURE(error))
+ return (0);
+ devinfo = (ACPI_DEVICE_INFO *)buf.Pointer;
+ if ((devinfo->Valid & ACPI_VALID_CID) == 0)
goto out;
+ if (devinfo->CompatibilityId.Count < count)
+ count = devinfo->CompatibilityId.Count;
+ for (i = 0; i < count; i++) {
+ if (strncmp(devinfo->CompatibilityId.Id[i].Value, "PNP", 3) != 0)
+ continue;
+ *pnpid++ = PNP_EISAID(devinfo->CompatibilityId.Id[i].Value);
+ valid++;
+ }
+
out:
+ AcpiOsFree(buf.Pointer);
ACPI_UNLOCK;
- return_VALUE (pnpid);
+ return_VALUE (valid);
}
-
static int
acpi_isa_pnp_probe(device_t bus, device_t child, struct isa_pnp_id *ids)
{
- int result;
- u_int32_t lid, cid;
+ int result, cid_count, i;
+ uint32_t lid, cids[8];
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
@@ -873,17 +894,23 @@ acpi_isa_pnp_probe(device_t bus, device_t child, struct isa_pnp_id *ids)
/* Scan the supplied IDs for a match */
lid = acpi_isa_get_logicalid(child);
- cid = acpi_isa_get_compatid(child);
+ cid_count = acpi_isa_get_compatid(child, cids, 8);
while (ids && ids->ip_id) {
- if (lid == ids->ip_id || cid == ids->ip_id) {
+ if (lid == ids->ip_id) {
result = 0;
goto out;
}
+ for (i = 0; i < cid_count; i++) {
+ if (cids[i] == ids->ip_id) {
+ result = 0;
+ goto out;
+ }
+ }
ids++;
}
out:
- return_VALUE(result);
+ return_VALUE (result);
}
/*
@@ -1092,28 +1119,34 @@ acpi_enable_fixed_events(struct acpi_softc *sc)
BOOLEAN
acpi_DeviceIsPresent(device_t dev)
{
+ ACPI_DEVICE_INFO *devinfo;
ACPI_HANDLE h;
- ACPI_DEVICE_INFO devinfo;
- ACPI_BUFFER buf = {sizeof(devinfo), &devinfo};
+ ACPI_BUFFER buf;
ACPI_STATUS error;
+ int ret;
ACPI_ASSERTLOCK;
+ ret = FALSE;
if ((h = acpi_get_handle(dev)) == NULL)
return (FALSE);
+ buf.Pointer = NULL;
+ buf.Length = ACPI_ALLOCATE_BUFFER;
error = AcpiGetObjectInfo(h, &buf);
if (ACPI_FAILURE(error))
return (FALSE);
+ devinfo = (ACPI_DEVICE_INFO *)buf.Pointer;
/* If no _STA method, must be present */
- if ((devinfo.Valid & ACPI_VALID_STA) == 0)
- return (TRUE);
+ if ((devinfo->Valid & ACPI_VALID_STA) == 0)
+ ret = TRUE;
/* Return true for 'present' and 'functioning' */
- if ((devinfo.CurrentStatus & 0x9) == 0x9)
- return (TRUE);
+ if ((devinfo->CurrentStatus & 0x9) == 0x9)
+ ret = TRUE;
- return (FALSE);
+ AcpiOsFree(buf.Pointer);
+ return (ret);
}
/*
@@ -1122,28 +1155,34 @@ acpi_DeviceIsPresent(device_t dev)
BOOLEAN
acpi_BatteryIsPresent(device_t dev)
{
+ ACPI_DEVICE_INFO *devinfo;
ACPI_HANDLE h;
- ACPI_DEVICE_INFO devinfo;
- ACPI_BUFFER buf = {sizeof(devinfo), &devinfo};
+ ACPI_BUFFER buf;
ACPI_STATUS error;
+ int ret;
ACPI_ASSERTLOCK;
+ ret = FALSE;
if ((h = acpi_get_handle(dev)) == NULL)
return (FALSE);
+ buf.Pointer = NULL;
+ buf.Length = ACPI_ALLOCATE_BUFFER;
error = AcpiGetObjectInfo(h, &buf);
if (ACPI_FAILURE(error))
return (FALSE);
+ devinfo = (ACPI_DEVICE_INFO *)buf.Pointer;
/* If no _STA method, must be present */
- if ((devinfo.Valid & ACPI_VALID_STA) == 0)
- return (TRUE);
+ if ((devinfo->Valid & ACPI_VALID_STA) == 0)
+ ret = TRUE;
/* Return true for 'present' and 'functioning' */
- if ((devinfo.CurrentStatus & 0x19) == 0x19)
- return (TRUE);
+ if ((devinfo->CurrentStatus & 0x19) == 0x19)
+ ret = TRUE;
- return (FALSE);
+ AcpiOsFree(buf.Pointer);
+ return (ret);
}
/*
@@ -1152,31 +1191,40 @@ acpi_BatteryIsPresent(device_t dev)
BOOLEAN
acpi_MatchHid(device_t dev, char *hid)
{
+ ACPI_DEVICE_INFO *devinfo;
ACPI_HANDLE h;
- ACPI_DEVICE_INFO devinfo;
- ACPI_BUFFER buf = {sizeof(devinfo), &devinfo};
+ ACPI_BUFFER buf;
ACPI_STATUS error;
- int cid;
+ int ret, i;
ACPI_ASSERTLOCK;
+ ret = FALSE;
if (hid == NULL)
return (FALSE);
if ((h = acpi_get_handle(dev)) == NULL)
return (FALSE);
+ buf.Pointer = NULL;
+ buf.Length = ACPI_ALLOCATE_BUFFER;
error = AcpiGetObjectInfo(h, &buf);
if (ACPI_FAILURE(error))
return (FALSE);
- if ((devinfo.Valid & ACPI_VALID_HID) != 0 &&
- strcmp(hid, devinfo.HardwareId.Value) == 0)
- return (TRUE);
-
- if (ACPI_FAILURE(error = acpi_EvaluateInteger(h, "_CID", &cid)))
- return (FALSE);
- if (cid == PNP_EISAID(hid))
- return (TRUE);
+ devinfo = (ACPI_DEVICE_INFO *)buf.Pointer;
+
+ if ((devinfo->Valid & ACPI_VALID_HID) != 0) {
+ if (strcmp(hid, devinfo->HardwareId.Value) == 0)
+ ret = TRUE;
+ } else if ((devinfo->Valid & ACPI_VALID_CID) != 0) {
+ for (i = 0; i < devinfo->CompatibilityId.Count; i++) {
+ if (strcmp(hid, devinfo->CompatibilityId.Id[i].Value) == 0) {
+ ret = TRUE;
+ break;
+ }
+ }
+ }
- return (FALSE);
+ AcpiOsFree(buf.Pointer);
+ return (ret);
}
/*
diff --git a/sys/dev/acpica/acpi_pci_link.c b/sys/dev/acpica/acpi_pci_link.c
index 9326bc9..b259eb7 100644
--- a/sys/dev/acpica/acpi_pci_link.c
+++ b/sys/dev/acpica/acpi_pci_link.c
@@ -191,8 +191,8 @@ acpi_pci_link_entry_dump(struct acpi_prt_entry *entry)
static ACPI_STATUS
acpi_pci_link_get_object_status(ACPI_HANDLE handle, UINT32 *sta)
{
- ACPI_DEVICE_INFO devinfo;
- ACPI_BUFFER buf = {sizeof(devinfo), &devinfo};
+ ACPI_DEVICE_INFO *devinfo;
+ ACPI_BUFFER buf;
ACPI_STATUS error;
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
@@ -203,6 +203,8 @@ acpi_pci_link_get_object_status(ACPI_HANDLE handle, UINT32 *sta)
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
+ buf.Pointer = NULL;
+ buf.Length = ACPI_ALLOCATE_BUFFER;
error = AcpiGetObjectInfo(handle, &buf);
if (ACPI_FAILURE(error)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
@@ -210,22 +212,25 @@ acpi_pci_link_get_object_status(ACPI_HANDLE handle, UINT32 *sta)
acpi_name(handle), AcpiFormatException(error)));
return_ACPI_STATUS (error);
}
+ devinfo = (ACPI_DEVICE_INFO *)buf.Pointer;
- if ((devinfo.Valid & ACPI_VALID_HID) == 0 ||
- strcmp(devinfo.HardwareId.Value, "PNP0C0F") != 0) {
+ if ((devinfo->Valid & ACPI_VALID_HID) == 0 ||
+ strcmp(devinfo->HardwareId.Value, "PNP0C0F") != 0) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "invalid hardware ID - %s\n",
acpi_name(handle)));
+ AcpiOsFree(buf.Pointer);
return_ACPI_STATUS (AE_TYPE);
}
- if ((devinfo.Valid & ACPI_VALID_STA) != 0) {
- *sta = devinfo.CurrentStatus;
+ if ((devinfo->Valid & ACPI_VALID_STA) != 0) {
+ *sta = devinfo->CurrentStatus;
} else {
ACPI_DEBUG_PRINT((ACPI_DB_WARN, "invalid status - %s\n",
acpi_name(handle)));
*sta = 0;
}
+ AcpiOsFree(buf.Pointer);
return_ACPI_STATUS (AE_OK);
}
diff --git a/sys/dev/acpica/acpi_pcib.c b/sys/dev/acpica/acpi_pcib.c
index 6c3151f..b3ebbfa 100644
--- a/sys/dev/acpica/acpi_pcib.c
+++ b/sys/dev/acpica/acpi_pcib.c
@@ -113,10 +113,9 @@ acpi_pcib_route_interrupt(device_t pcib, device_t dev, int pin,
{
ACPI_PCI_ROUTING_TABLE *prt;
ACPI_HANDLE lnkdev;
- ACPI_BUFFER crsbuf, prsbuf;
+ ACPI_BUFFER crsbuf, prsbuf, buf;
ACPI_RESOURCE *crsres, *prsres, resbuf;
- ACPI_DEVICE_INFO devinfo;
- ACPI_BUFFER buf = {sizeof(devinfo), &devinfo};
+ ACPI_DEVICE_INFO *devinfo;
ACPI_STATUS status;
UINT32 NumberOfInterrupts;
UINT32 *Interrupts;
@@ -126,8 +125,6 @@ acpi_pcib_route_interrupt(device_t pcib, device_t dev, int pin,
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
- crsbuf.Pointer = NULL;
- prsbuf.Pointer = NULL;
interrupt = 255;
/* ACPI numbers pins 0-3, not 1-4 like the BIOS */
@@ -187,17 +184,24 @@ acpi_pcib_route_interrupt(device_t pcib, device_t dev, int pin,
/*
* Verify that this is a PCI link device, and that it's present.
*/
+ buf.Pointer = NULL;
+ buf.Length = ACPI_ALLOCATE_BUFFER;
if (ACPI_FAILURE(AcpiGetObjectInfo(lnkdev, &buf))) {
device_printf(pcib, "couldn't validate PCI interrupt link device %s\n",
prt->Source);
goto out;
}
- if (!(devinfo.Valid & ACPI_VALID_HID) || strcmp("PNP0C0F", devinfo.HardwareId.Value)) {
+ devinfo = (ACPI_DEVICE_INFO *)buf.Pointer;
+ if ((devinfo->Valid & ACPI_VALID_HID) == 0 ||
+ strcmp("PNP0C0F", devinfo->HardwareId.Value) != 0) {
+
device_printf(pcib, "PCI interrupt link device %s has wrong _HID (%s)\n",
- prt->Source, devinfo.HardwareId.Value);
+ prt->Source, devinfo->HardwareId.Value);
goto out;
}
- if (devinfo.Valid & ACPI_VALID_STA && (devinfo.CurrentStatus & 0x9) != 0x9) {
+ if ((devinfo->Valid & ACPI_VALID_STA) != 0 &&
+ (devinfo->CurrentStatus & 0x9) != 0x9) {
+
device_printf(pcib, "PCI interrupt link device %s not present\n",
prt->Source);
goto out;
@@ -206,12 +210,14 @@ acpi_pcib_route_interrupt(device_t pcib, device_t dev, int pin,
/*
* Get the current and possible resources for the interrupt link device.
*/
+ crsbuf.Pointer = NULL;
crsbuf.Length = ACPI_ALLOCATE_BUFFER;
if (ACPI_FAILURE(status = AcpiGetCurrentResources(lnkdev, &crsbuf))) {
device_printf(pcib, "couldn't get PCI interrupt link device _CRS data - %s\n",
AcpiFormatException(status));
goto out; /* this is fatal */
}
+ prsbuf.Pointer = NULL;
prsbuf.Length = ACPI_ALLOCATE_BUFFER;
if (ACPI_FAILURE(status = AcpiGetPossibleResources(lnkdev, &prsbuf))) {
device_printf(pcib, "couldn't get PCI interrupt link device _PRS data - %s\n",
@@ -361,6 +367,8 @@ acpi_pcib_route_interrupt(device_t pcib, device_t dev, int pin,
AcpiOsFree(crsbuf.Pointer);
if (prsbuf.Pointer != NULL)
AcpiOsFree(prsbuf.Pointer);
+ if (buf.Pointer != NULL)
+ AcpiOsFree(buf.Pointer);
/* XXX APIC_IO interrupt mapping? */
return_VALUE(interrupt);
OpenPOWER on IntegriCloud