Beispiel #1
0
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;
}
Beispiel #2
0
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));
}
Beispiel #3
0
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;
}
Beispiel #4
0
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", &params->uid);
	if (ACPI_FAILURE(status))
	    params->uid = 0;
	status = acpi_GetInteger(h, "_GLK", &params->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, &params->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);
}