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:
parent
e918d8f302
commit
3242fb60cc
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user