diff options
Diffstat (limited to 'drivers/pci/pci-label.c')
| -rw-r--r-- | drivers/pci/pci-label.c | 193 |
1 files changed, 62 insertions, 131 deletions
diff --git a/drivers/pci/pci-label.c b/drivers/pci/pci-label.c index 6f5d343d251..a3fbe2012ea 100644 --- a/drivers/pci/pci-label.c +++ b/drivers/pci/pci-label.c @@ -29,7 +29,6 @@ #include <linux/nls.h> #include <linux/acpi.h> #include <linux/pci-acpi.h> -#include <acpi/acpi_bus.h> #include "pci.h" #define DEVICE_LABEL_DSM 0x07 @@ -41,9 +40,8 @@ enum smbios_attr_enum { SMBIOS_ATTR_INSTANCE_SHOW, }; -static size_t -find_smbios_instance_string(struct pci_dev *pdev, char *buf, - enum smbios_attr_enum attribute) +static size_t find_smbios_instance_string(struct pci_dev *pdev, char *buf, + enum smbios_attr_enum attribute) { const struct dmi_device *dmi; struct dmi_dev_onboard *donboard; @@ -75,9 +73,8 @@ find_smbios_instance_string(struct pci_dev *pdev, char *buf, return 0; } -static umode_t -smbios_instance_string_exist(struct kobject *kobj, struct attribute *attr, - int n) +static umode_t smbios_instance_string_exist(struct kobject *kobj, + struct attribute *attr, int n) { struct device *dev; struct pci_dev *pdev; @@ -89,8 +86,8 @@ smbios_instance_string_exist(struct kobject *kobj, struct attribute *attr, S_IRUGO : 0; } -static ssize_t -smbioslabel_show(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t smbioslabel_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct pci_dev *pdev; pdev = to_pci_dev(dev); @@ -99,9 +96,8 @@ smbioslabel_show(struct device *dev, struct device_attribute *attr, char *buf) SMBIOS_ATTR_LABEL_SHOW); } -static ssize_t -smbiosinstance_show(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t smbiosinstance_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct pci_dev *pdev; pdev = to_pci_dev(dev); @@ -131,26 +127,22 @@ static struct attribute_group smbios_attr_group = { .is_visible = smbios_instance_string_exist, }; -static int -pci_create_smbiosname_file(struct pci_dev *pdev) +static int pci_create_smbiosname_file(struct pci_dev *pdev) { return sysfs_create_group(&pdev->dev.kobj, &smbios_attr_group); } -static void -pci_remove_smbiosname_file(struct pci_dev *pdev) +static void pci_remove_smbiosname_file(struct pci_dev *pdev) { sysfs_remove_group(&pdev->dev.kobj, &smbios_attr_group); } #else -static inline int -pci_create_smbiosname_file(struct pci_dev *pdev) +static inline int pci_create_smbiosname_file(struct pci_dev *pdev) { return -1; } -static inline void -pci_remove_smbiosname_file(struct pci_dev *pdev) +static inline void pci_remove_smbiosname_file(struct pci_dev *pdev) { } #endif @@ -162,7 +154,6 @@ static const char device_label_dsm_uuid[] = { }; enum acpi_attr_enum { - ACPI_ATTR_NONE = 0, ACPI_ATTR_LABEL_SHOW, ACPI_ATTR_INDEX_SHOW, }; @@ -170,88 +161,64 @@ enum acpi_attr_enum { static void dsm_label_utf16s_to_utf8s(union acpi_object *obj, char *buf) { int len; - len = utf16s_to_utf8s((const wchar_t *)obj-> - package.elements[1].string.pointer, - obj->package.elements[1].string.length, + len = utf16s_to_utf8s((const wchar_t *)obj->string.pointer, + obj->string.length, UTF16_LITTLE_ENDIAN, buf, PAGE_SIZE); buf[len] = '\n'; } -static int -dsm_get_label(acpi_handle handle, int func, - struct acpi_buffer *output, - char *buf, enum acpi_attr_enum attribute) +static int dsm_get_label(struct device *dev, char *buf, + enum acpi_attr_enum attr) { - struct acpi_object_list input; - union acpi_object params[4]; - union acpi_object *obj; - int len = 0; - - int err; - - input.count = 4; - input.pointer = params; - params[0].type = ACPI_TYPE_BUFFER; - params[0].buffer.length = sizeof(device_label_dsm_uuid); - params[0].buffer.pointer = (char *)device_label_dsm_uuid; - params[1].type = ACPI_TYPE_INTEGER; - params[1].integer.value = 0x02; - params[2].type = ACPI_TYPE_INTEGER; - params[2].integer.value = func; - params[3].type = ACPI_TYPE_PACKAGE; - params[3].package.count = 0; - params[3].package.elements = NULL; - - err = acpi_evaluate_object(handle, "_DSM", &input, output); - if (err) + acpi_handle handle; + union acpi_object *obj, *tmp; + int len = -1; + + handle = ACPI_HANDLE(dev); + if (!handle) return -1; - obj = (union acpi_object *)output->pointer; - - switch (obj->type) { - case ACPI_TYPE_PACKAGE: - if (obj->package.count != 2) - break; - len = obj->package.elements[0].integer.value; - if (buf) { - if (attribute == ACPI_ATTR_INDEX_SHOW) - scnprintf(buf, PAGE_SIZE, "%llu\n", - obj->package.elements[0].integer.value); - else if (attribute == ACPI_ATTR_LABEL_SHOW) - dsm_label_utf16s_to_utf8s(obj, buf); - kfree(output->pointer); - return strlen(buf); - } - kfree(output->pointer); - return len; - break; - default: - kfree(output->pointer); + obj = acpi_evaluate_dsm(handle, device_label_dsm_uuid, 0x2, + DEVICE_LABEL_DSM, NULL); + if (!obj) + return -1; + + tmp = obj->package.elements; + if (obj->type == ACPI_TYPE_PACKAGE && obj->package.count == 2 && + tmp[0].type == ACPI_TYPE_INTEGER && + tmp[1].type == ACPI_TYPE_STRING) { + /* + * The second string element is optional even when + * this _DSM is implemented; when not implemented, + * this entry must return a null string. + */ + if (attr == ACPI_ATTR_INDEX_SHOW) + scnprintf(buf, PAGE_SIZE, "%llu\n", tmp->integer.value); + else if (attr == ACPI_ATTR_LABEL_SHOW) + dsm_label_utf16s_to_utf8s(tmp + 1, buf); + len = strlen(buf) > 0 ? strlen(buf) : -1; } - return -1; + + ACPI_FREE(obj); + + return len; } -static bool -device_has_dsm(struct device *dev) +static bool device_has_dsm(struct device *dev) { acpi_handle handle; - struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL}; handle = ACPI_HANDLE(dev); - if (!handle) - return FALSE; + return false; - if (dsm_get_label(handle, DEVICE_LABEL_DSM, &output, NULL, - ACPI_ATTR_NONE) > 0) - return TRUE; - - return FALSE; + return !!acpi_check_dsm(handle, device_label_dsm_uuid, 0x2, + 1 << DEVICE_LABEL_DSM); } -static umode_t -acpi_index_string_exist(struct kobject *kobj, struct attribute *attr, int n) +static umode_t acpi_index_string_exist(struct kobject *kobj, + struct attribute *attr, int n) { struct device *dev; @@ -263,47 +230,16 @@ acpi_index_string_exist(struct kobject *kobj, struct attribute *attr, int n) return 0; } -static ssize_t -acpilabel_show(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t acpilabel_show(struct device *dev, + struct device_attribute *attr, char *buf) { - struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL}; - acpi_handle handle; - int length; - - handle = ACPI_HANDLE(dev); - - if (!handle) - return -1; - - length = dsm_get_label(handle, DEVICE_LABEL_DSM, - &output, buf, ACPI_ATTR_LABEL_SHOW); - - if (length < 1) - return -1; - - return length; + return dsm_get_label(dev, buf, ACPI_ATTR_LABEL_SHOW); } -static ssize_t -acpiindex_show(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t acpiindex_show(struct device *dev, + struct device_attribute *attr, char *buf) { - struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL}; - acpi_handle handle; - int length; - - handle = ACPI_HANDLE(dev); - - if (!handle) - return -1; - - length = dsm_get_label(handle, DEVICE_LABEL_DSM, - &output, buf, ACPI_ATTR_INDEX_SHOW); - - if (length < 0) - return -1; - - return length; - + return dsm_get_label(dev, buf, ACPI_ATTR_INDEX_SHOW); } static struct device_attribute acpi_attr_label = { @@ -327,33 +263,28 @@ static struct attribute_group acpi_attr_group = { .is_visible = acpi_index_string_exist, }; -static int -pci_create_acpi_index_label_files(struct pci_dev *pdev) +static int pci_create_acpi_index_label_files(struct pci_dev *pdev) { return sysfs_create_group(&pdev->dev.kobj, &acpi_attr_group); } -static int -pci_remove_acpi_index_label_files(struct pci_dev *pdev) +static int pci_remove_acpi_index_label_files(struct pci_dev *pdev) { sysfs_remove_group(&pdev->dev.kobj, &acpi_attr_group); return 0; } #else -static inline int -pci_create_acpi_index_label_files(struct pci_dev *pdev) +static inline int pci_create_acpi_index_label_files(struct pci_dev *pdev) { return -1; } -static inline int -pci_remove_acpi_index_label_files(struct pci_dev *pdev) +static inline int pci_remove_acpi_index_label_files(struct pci_dev *pdev) { return -1; } -static inline bool -device_has_dsm(struct device *dev) +static inline bool device_has_dsm(struct device *dev) { return false; } |
