static void smapi_identify (driver_t *driver, device_t parent) { device_t child; u_int32_t addr; int length; int rid; if (!device_is_alive(parent)) return; addr = bios_sigsearch(SMAPI_START, SMAPI_SIG, SMAPI_LEN, SMAPI_STEP, SMAPI_OFF); if (addr != 0) { rid = 0; length = ADDR2HDR(addr)->length; child = BUS_ADD_CHILD(parent, 5, "smapi", -1); device_set_driver(child, driver); bus_set_resource(child, SYS_RES_MEMORY, rid, addr, length); device_set_desc(child, "SMAPI BIOS"); } return; }
static void acpi_pci_update_device(ACPI_HANDLE handle, device_t pci_child) { ACPI_STATUS status; device_t child; /* * Lookup and remove the unused device that acpi0 creates when it walks * the namespace creating devices. */ child = acpi_get_device(handle); if (child != NULL) { if (device_is_alive(child)) { /* * The TabletPC TC1000 has a second PCI-ISA bridge * that has a _HID for an acpi_sysresource device. * In that case, leave ACPI-CA's device data pointing * at the ACPI-enumerated device. */ device_printf(child, "Conflicts with PCI device %d:%d:%d\n", pci_get_bus(pci_child), pci_get_slot(pci_child), pci_get_function(pci_child)); return; } KASSERT(device_get_parent(child) == devclass_get_device(devclass_find("acpi"), 0), ("%s: child (%s)'s parent is not acpi0", __func__, acpi_name(handle))); device_delete_child(device_get_parent(child), child); } /* * Update ACPI-CA to use the PCI enumerated device_t for this handle. */ status = AcpiDetachData(handle, acpi_fake_objhandler); if (ACPI_FAILURE(status)) kprintf("WARNING: Unable to detach object data from %s - %s\n", acpi_name(handle), AcpiFormatException(status)); status = AcpiAttachData(handle, acpi_fake_objhandler, pci_child); if (ACPI_FAILURE(status)) kprintf("WARNING: Unable to attach object data to %s - %s\n", acpi_name(handle), AcpiFormatException(status)); }
static void vpd_identify (driver_t *driver, device_t parent) { device_t child; u_int32_t addr; int length; int rid; if (!device_is_alive(parent)) return; addr = bios_sigsearch(VPD_START, VPD_SIG, VPD_LEN, VPD_STEP, VPD_OFF); if (addr != 0) { rid = 0; length = ADDR2VPD(addr)->Length; child = BUS_ADD_CHILD(parent, 5, "vpd", -1); device_set_driver(child, driver); bus_set_resource(child, SYS_RES_MEMORY, rid, addr, length); device_set_desc(child, "Vital Product Data Area"); } return; }
static int acpi_ec_probe(device_t dev) { ACPI_BUFFER buf; ACPI_HANDLE h; ACPI_OBJECT *obj; ACPI_STATUS status; device_t peer; char desc[64]; int ecdt; int ret; struct acpi_ec_params *params; static char *ec_ids[] = { "PNP0C09", NULL }; /* Check that this is a device and that EC is not disabled. */ if (acpi_get_type(dev) != ACPI_TYPE_DEVICE || acpi_disabled("ec")) return (ENXIO); /* * If probed via ECDT, set description and continue. Otherwise, * we can access the namespace and make sure this is not a * duplicate probe. */ ret = ENXIO; ecdt = 0; buf.Pointer = NULL; buf.Length = ACPI_ALLOCATE_BUFFER; params = acpi_get_private(dev); if (params != NULL) { ecdt = 1; ret = 0; } else if (ACPI_ID_PROBE(device_get_parent(dev), dev, ec_ids)) { params = kmalloc(sizeof(struct acpi_ec_params), M_TEMP, M_WAITOK | M_ZERO); h = acpi_get_handle(dev); /* * Read the unit ID to check for duplicate attach and the * global lock value to see if we should acquire it when * accessing the EC. */ status = acpi_GetInteger(h, "_UID", ¶ms->uid); if (ACPI_FAILURE(status)) params->uid = 0; status = acpi_GetInteger(h, "_GLK", ¶ms->glk); if (ACPI_FAILURE(status)) params->glk = 0; /* * Evaluate the _GPE method to find the GPE bit used by the EC to * signal status (SCI). If it's a package, it contains a reference * and GPE bit, similar to _PRW. */ status = AcpiEvaluateObject(h, "_GPE", NULL, &buf); if (ACPI_FAILURE(status)) { device_printf(dev, "can't evaluate _GPE - %s\n", AcpiFormatException(status)); goto out; } obj = (ACPI_OBJECT *)buf.Pointer; if (obj == NULL) goto out; switch (obj->Type) { case ACPI_TYPE_INTEGER: params->gpe_handle = NULL; params->gpe_bit = obj->Integer.Value; break; case ACPI_TYPE_PACKAGE: if (!ACPI_PKG_VALID(obj, 2)) goto out; params->gpe_handle = acpi_GetReference(NULL, &obj->Package.Elements[0]); if (params->gpe_handle == NULL || acpi_PkgInt32(obj, 1, ¶ms->gpe_bit) != 0) goto out; break; default: device_printf(dev, "_GPE has invalid type %d\n", obj->Type); goto out; } /* Store the values we got from the namespace for attach. */ acpi_set_private(dev, params); /* * Check for a duplicate probe. This can happen when a probe * via ECDT succeeded already. If this is a duplicate, disable * this device. */ peer = devclass_get_device(acpi_ec_devclass, params->uid); if (peer == NULL || !device_is_alive(peer)) ret = 0; else device_disable(dev); } out: if (ret == 0) { ksnprintf(desc, sizeof(desc), "Embedded Controller: GPE %#x%s%s", params->gpe_bit, (params->glk) ? ", GLK" : "", ecdt ? ", ECDT" : ""); device_set_desc_copy(dev, desc); } if (ret > 0 && params) kfree(params, M_TEMP); if (buf.Pointer) AcpiOsFree(buf.Pointer); return (ret); }