/** * create_pnp_modalias - Create hid/cid(s) string for modalias and uevent * @acpi_dev: ACPI device object. * @modalias: Buffer to print into. * @size: Size of the buffer. * * Creates hid/cid(s) string needed for modalias and uevent * e.g. on a device with hid:IBM0001 and cid:ACPI0001 you get: * char *modalias: "acpi:IBM0001:ACPI0001" * Return: 0: no _HID and no _CID * -EINVAL: output error * -ENOMEM: output is truncated
*/ staticint create_pnp_modalias(conststruct acpi_device *acpi_dev, char *modalias, int size)
{ int len; int count; struct acpi_hardware_id *id;
/* Avoid unnecessarily loading modules for non present devices. */ if (!acpi_device_is_present(acpi_dev)) return 0;
/* * Since we skip ACPI_DT_NAMESPACE_HID from the modalias below, 0 should * be returned if ACPI_DT_NAMESPACE_HID is the only ACPI/PNP ID in the * device's list.
*/
count = 0;
list_for_each_entry(id, &acpi_dev->pnp.ids, list) if (strcmp(id->id, ACPI_DT_NAMESPACE_HID))
count++;
if (!count) return 0;
len = snprintf(modalias, size, "acpi:"); if (len >= size) return -ENOMEM;
size -= len;
list_for_each_entry(id, &acpi_dev->pnp.ids, list) { if (!strcmp(id->id, ACPI_DT_NAMESPACE_HID)) continue;
/** * create_of_modalias - Creates DT compatible string for modalias and uevent * @acpi_dev: ACPI device object. * @modalias: Buffer to print into. * @size: Size of the buffer. * * Expose DT compatible modalias as of:NnameTCcompatible. This function should * only be called for devices having ACPI_DT_NAMESPACE_HID in their list of * ACPI/PNP IDs.
*/ staticint create_of_modalias(conststruct acpi_device *acpi_dev, char *modalias, int size)
{ struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER }; constunion acpi_object *of_compatible, *obj;
acpi_status status; int len, count; int i, nval; char *c;
status = acpi_get_name(acpi_dev->handle, ACPI_SINGLE_NAME, &buf); if (ACPI_FAILURE(status)) return -ENODEV;
/* DT strings are all in lower case */ for (c = buf.pointer; *c != '\0'; c++)
*c = tolower(*c);
len = snprintf(modalias, size, "of:N%sT", (char *)buf.pointer);
ACPI_FREE(buf.pointer);
if (len >= size) return -ENOMEM;
size -= len;
of_compatible = acpi_dev->data.of_compatible; if (of_compatible->type == ACPI_TYPE_PACKAGE) {
nval = of_compatible->package.count;
obj = of_compatible->package.elements;
} else { /* Must be ACPI_TYPE_STRING. */
nval = 1;
obj = of_compatible;
} for (i = 0; i < nval; i++, obj++) {
count = snprintf(&modalias[len], size, "C%s",
obj->string.pointer);
if (count >= size) return -ENOMEM;
len += count;
size -= count;
}
return len;
}
int __acpi_device_uevent_modalias(conststruct acpi_device *adev, struct kobj_uevent_env *env)
{ int len;
if (!adev) return -ENODEV;
if (list_empty(&adev->pnp.ids)) return 0;
if (add_uevent_var(env, "MODALIAS=")) return -ENOMEM;
if (adev->data.of_compatible)
len = create_of_modalias(adev, &env->buf[env->buflen - 1], sizeof(env->buf) - env->buflen); else
len = create_pnp_modalias(adev, &env->buf[env->buflen - 1], sizeof(env->buf) - env->buflen); if (len < 0) return len;
env->buflen += len;
return 0;
}
/** * acpi_device_uevent_modalias - uevent modalias for ACPI-enumerated devices. * @dev: Struct device to get ACPI device node. * @env: Environment variables of the kobject uevent. * * Create the uevent modalias field for ACPI-enumerated devices. * * Because other buses do not support ACPI HIDs & CIDs, e.g. for a device with * hid:IBM0001 and cid:ACPI0001 you get: "acpi:IBM0001:ACPI0001".
*/ int acpi_device_uevent_modalias(conststruct device *dev, struct kobj_uevent_env *env)
{ return __acpi_device_uevent_modalias(acpi_companion_match(dev), env);
}
EXPORT_SYMBOL_GPL(acpi_device_uevent_modalias);
staticint __acpi_device_modalias(conststruct acpi_device *adev, char *buf, int size)
{ int len, count;
/** * acpi_device_modalias - modalias sysfs attribute for ACPI-enumerated devices. * @dev: Struct device to get ACPI device node. * @buf: The buffer to save pnp_modalias and of_modalias. * @size: Size of buffer. * * Create the modalias sysfs attribute for ACPI-enumerated devices. * * Because other buses do not support ACPI HIDs & CIDs, e.g. for a device with * hid:IBM0001 and cid:ACPI0001 you get: "acpi:IBM0001:ACPI0001".
*/ int acpi_device_modalias(struct device *dev, char *buf, int size)
{ return __acpi_device_modalias(acpi_companion_match(dev), buf, size);
}
EXPORT_SYMBOL_GPL(acpi_device_modalias);
/* sysfs file that shows description text from the ACPI _STR method */ static ssize_t description_show(struct device *dev, struct device_attribute *attr, char *buf)
{ struct acpi_device *acpi_dev = to_acpi_device(dev); struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; union acpi_object *str_obj;
acpi_status status; int result;
status = acpi_evaluate_object_typed(acpi_dev->handle, "_STR",
NULL, &buffer,
ACPI_TYPE_BUFFER); if (ACPI_FAILURE(status)) return -EIO;
str_obj = buffer.pointer;
/* * The _STR object contains a Unicode identifier for a device. * We need to convert to utf-8 so it can be displayed.
*/
result = utf16s_to_utf8s(
(wchar_t *)str_obj->buffer.pointer,
str_obj->buffer.length,
UTF16_LITTLE_ENDIAN, buf,
PAGE_SIZE - 1);
staticbool acpi_show_attr(struct acpi_device *dev, conststruct device_attribute *attr)
{ /* * Devices gotten from FADT don't have a "path" attribute
*/ if (attr == &dev_attr_path) return dev->handle;
if (attr == &dev_attr_hid || attr == &dev_attr_modalias) return !list_empty(&dev->pnp.ids);
if (attr == &dev_attr_description) return acpi_has_method(dev->handle, "_STR");
if (attr == &dev_attr_adr) return dev->pnp.type.bus_address;
if (attr == &dev_attr_uid) return acpi_device_uid(dev);
if (attr == &dev_attr_sun) return acpi_has_method(dev->handle, "_SUN");
if (attr == &dev_attr_hrv) return acpi_has_method(dev->handle, "_HRV");
if (attr == &dev_attr_status) return acpi_has_method(dev->handle, "_STA");
/* * If device has _EJ0, 'eject' file is created that is used to trigger * hot-removal function from userland.
*/ if (attr == &dev_attr_eject) return acpi_has_method(dev->handle, "_EJ0");
if (attr == &dev_attr_power_state) return dev->flags.power_manageable;
if (attr == &dev_attr_real_power_state) return dev->flags.power_manageable && dev->power.flags.power_resources;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.