diff --git a/drivers/pci/pci-label.c b/drivers/pci/pci-label.c index 255e0ecffb09..5b08f50653a3 100644 --- a/drivers/pci/pci-label.c +++ b/drivers/pci/pci-label.c @@ -157,7 +157,7 @@ static int dsm_get_label(struct device *dev, char *buf, { acpi_handle handle = ACPI_HANDLE(dev); union acpi_object *obj, *tmp; - int len = 0; + int len; if (!handle) return -ENODEV; @@ -167,30 +167,43 @@ static int dsm_get_label(struct device *dev, char *buf, if (!obj) return -EIO; - 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 || - tmp[1].type == ACPI_TYPE_BUFFER)) { - /* - * 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) { - len = sysfs_emit(buf, "%llu\n", tmp->integer.value); - } else if (attr == ACPI_ATTR_LABEL_SHOW) { - if (tmp[1].type == ACPI_TYPE_STRING) - len = sysfs_emit(buf, "%s\n", - tmp[1].string.pointer); - else if (tmp[1].type == ACPI_TYPE_BUFFER) - len = dsm_label_utf16s_to_utf8s(tmp + 1, buf); - } + if (obj->type != ACPI_TYPE_PACKAGE || obj->package.count != 2) { + len = -EIO; + goto out; } + tmp = obj->package.elements; + if (tmp[0].type != ACPI_TYPE_INTEGER) { + len = -EIO; + goto out; + } + + if (attr == ACPI_ATTR_INDEX_SHOW) { + len = sysfs_emit(buf, "%llu\n", tmp[0].integer.value); + goto out; + } + + /* + * Per PCI Firmware r3.3, sec 4.6.7, the device name is optional + * even when this _DSM is implemented. When not implemented, this + * entry must return a NULL string. + */ + switch (tmp[1].type) { + case ACPI_TYPE_STRING: + len = sysfs_emit(buf, "%s\n", tmp[1].string.pointer); + break; + case ACPI_TYPE_BUFFER: + len = dsm_label_utf16s_to_utf8s(&tmp[1], buf); + break; + default: + len = -EIO; + break; + } + +out: ACPI_FREE(obj); - return len > 0 ? len : -EIO; + return len; } static ssize_t label_show(struct device *dev, struct device_attribute *attr,