예제 #1
0
파일: core.c 프로젝트: 274914765/C
static int __init pnpacpi_add_device(struct acpi_device *device)
{
    acpi_handle temp = NULL;
    acpi_status status;
    struct pnp_dev *dev;

    status = acpi_get_handle(device->handle, "_CRS", &temp);
    if (ACPI_FAILURE(status) || !ispnpidacpi(acpi_device_hid(device)) ||
        is_exclusive_device(device))
        return 0;

    dev = pnp_alloc_dev(&pnpacpi_protocol, num, acpi_device_hid(device));
    if (!dev)
        return -ENOMEM;

    dev->data = device->handle;
    /* .enabled means the device can decode the resources */
    dev->active = device->status.enabled;
    status = acpi_get_handle(device->handle, "_SRS", &temp);
    if (ACPI_SUCCESS(status))
        dev->capabilities |= PNP_CONFIGURABLE;
    dev->capabilities |= PNP_READ;
    if (device->flags.dynamic_status && (dev->capabilities & PNP_CONFIGURABLE))
        dev->capabilities |= PNP_WRITE;
    if (device->flags.removable)
        dev->capabilities |= PNP_REMOVABLE;
    status = acpi_get_handle(device->handle, "_DIS", &temp);
    if (ACPI_SUCCESS(status))
        dev->capabilities |= PNP_DISABLE;

    if (strlen(acpi_device_name(device)))
        strncpy(dev->name, acpi_device_name(device), sizeof(dev->name));
    else
        strncpy(dev->name, acpi_device_bid(device), sizeof(dev->name));

    if (dev->active)
        pnpacpi_parse_allocated_resource(dev);

    if (dev->capabilities & PNP_CONFIGURABLE)
        pnpacpi_parse_resource_option_data(dev);

    if (device->flags.compatible_ids) {
        struct acpi_compatible_id_list *cid_list = device->pnp.cid_list;
        int i;

        for (i = 0; i < cid_list->count; i++) {
            if (!ispnpidacpi(cid_list->id[i].value))
                continue;
            pnp_add_id(dev, cid_list->id[i].value);
        }
    }

    /* clear out the damaged flags */
    if (!dev->active)
        pnp_init_resources(dev);
    pnp_add_device(dev);
    num++;

    return AE_OK;
}
예제 #2
0
static int __init pnpacpi_add_device(struct acpi_device *device)
{
	acpi_handle temp = NULL;
	acpi_status status;
	struct pnp_id *dev_id;
	struct pnp_dev *dev;

	if (!ispnpidacpi(acpi_device_hid(device)) ||
		is_exclusive_device(device))
		return 0;

	pnp_dbg("ACPI device : hid %s", acpi_device_hid(device));
	dev =  kcalloc(1, sizeof(struct pnp_dev), GFP_KERNEL);
	if (!dev) {
		pnp_err("Out of memory");
		return -ENOMEM;
	}
	dev->data = device->handle;
	/* .enabled means if the device can decode the resources */
	dev->active = device->status.enabled;
	status = acpi_get_handle(device->handle, "_SRS", &temp);
	if (ACPI_SUCCESS(status))
		dev->capabilities |= PNP_CONFIGURABLE;
	dev->capabilities |= PNP_READ;
	if (device->flags.dynamic_status)
		dev->capabilities |= PNP_WRITE;
	if (device->flags.removable)
		dev->capabilities |= PNP_REMOVABLE;
	status = acpi_get_handle(device->handle, "_DIS", &temp);
	if (ACPI_SUCCESS(status))
		dev->capabilities |= PNP_DISABLE;

	dev->protocol = &pnpacpi_protocol;

	if (strlen(acpi_device_name(device)))
		strncpy(dev->name, acpi_device_name(device), sizeof(dev->name));
	else
		strncpy(dev->name, acpi_device_bid(device), sizeof(dev->name));

	dev->number = num;
	
	/* set the initial values for the PnP device */
	dev_id = kcalloc(1, sizeof(struct pnp_id), GFP_KERNEL);
	if (!dev_id)
		goto err;
	pnpidacpi_to_pnpid(acpi_device_hid(device), dev_id->id);
	pnp_add_id(dev_id, dev);

	if(dev->active) {
		/* parse allocated resource */
		status = pnpacpi_parse_allocated_resource(device->handle, &dev->res);
		if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {
			pnp_err("PnPACPI: METHOD_NAME__CRS failure for %s", dev_id->id);
			goto err1;
		}
	}

	if(dev->capabilities & PNP_CONFIGURABLE) {
		status = pnpacpi_parse_resource_option_data(device->handle, 
			dev);
		if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {
			pnp_err("PnPACPI: METHOD_NAME__PRS failure for %s", dev_id->id);
			goto err1;
		}
	}
	
	/* parse compatible ids */
	if (device->flags.compatible_ids) {
		struct acpi_compatible_id_list *cid_list = device->pnp.cid_list;
		int i;

		for (i = 0; i < cid_list->count; i++) {
			if (!ispnpidacpi(cid_list->id[i].value))
				continue;
			dev_id = kcalloc(1, sizeof(struct pnp_id), GFP_KERNEL);
			if (!dev_id)
				continue;

			pnpidacpi_to_pnpid(cid_list->id[i].value, dev_id->id);
			pnp_add_id(dev_id, dev);
		}
	}

	/* clear out the damaged flags */
	if (!dev->active)
		pnp_init_resource_table(&dev->res);
	pnp_add_device(dev);
	num ++;

	return AE_OK;
err1:
	kfree(dev_id);
err:
	kfree(dev);
	return -EINVAL;
}