Add support for multiple CIDs since _CID can contain a package of values.

Implement this in acpi_MatchHid() and acpi_isa_get_compatid().  This
should fix mouse support for some users.

Move all users of AcpiGetObjectInfo() to use dynamic storage instead of
a devinfo on the stack.  This is necessary since ACPI-CA needs to
allocate different sized arrays for the CompatList.
This commit is contained in:
njl 2003-12-18 03:25:22 +00:00
parent e918d8f302
commit 3242fb60cc
3 changed files with 125 additions and 64 deletions

View File

@ -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)
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 (ACPI_FAILURE(error = acpi_EvaluateInteger(h, "_CID", &pnpid)))
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);
devinfo = (ACPI_DEVICE_INFO *)buf.Pointer;
if (ACPI_FAILURE(error = acpi_EvaluateInteger(h, "_CID", &cid)))
return (FALSE);
if (cid == PNP_EISAID(hid))
return (TRUE);
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);
}
/*

View File

@ -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);
}

View File

@ -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);