Commit 1d0fcef7 authored by Jiang Liu's avatar Jiang Liu Committed by Rafael J. Wysocki

ACPI / PCI: replace open-coded _DSM code with helper functions

Use helper functions to simplify _DSM related code in pci-label driver.
Also enforce more strict checks on objects returned by _DSM method.
Signed-off-by: default avatarJiang Liu <jiang.liu@linux.intel.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 54e5bb46
...@@ -195,80 +195,58 @@ enum acpi_attr_enum { ...@@ -195,80 +195,58 @@ enum acpi_attr_enum {
static void dsm_label_utf16s_to_utf8s(union acpi_object *obj, char *buf) static void dsm_label_utf16s_to_utf8s(union acpi_object *obj, char *buf)
{ {
int len; int len;
len = utf16s_to_utf8s((const wchar_t *)obj-> len = utf16s_to_utf8s((const wchar_t *)obj->string.pointer,
package.elements[1].string.pointer, obj->string.length,
obj->package.elements[1].string.length,
UTF16_LITTLE_ENDIAN, UTF16_LITTLE_ENDIAN,
buf, PAGE_SIZE); buf, PAGE_SIZE);
buf[len] = '\n'; buf[len] = '\n';
} }
static int static int
dsm_get_label(acpi_handle handle, int func, dsm_get_label(struct device *dev, char *buf, enum acpi_attr_enum attr)
struct acpi_buffer *output,
char *buf, enum acpi_attr_enum attribute)
{ {
struct acpi_object_list input; acpi_handle handle;
union acpi_object params[4]; union acpi_object *obj, *tmp;
union acpi_object *obj; int len = -1;
int len = 0;
handle = ACPI_HANDLE(dev);
int err; if (!handle)
return -1;
input.count = 4;
input.pointer = params; obj = acpi_evaluate_dsm(handle, device_label_dsm_uuid, 0x2,
params[0].type = ACPI_TYPE_BUFFER; DEVICE_LABEL_DSM, NULL);
params[0].buffer.length = sizeof(device_label_dsm_uuid); if (!obj)
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)
return -1; return -1;
obj = (union acpi_object *)output->pointer; tmp = obj->package.elements;
if (obj->type == ACPI_TYPE_PACKAGE && obj->package.count == 2) { if (obj->type == ACPI_TYPE_PACKAGE && obj->package.count == 2 &&
len = obj->package.elements[0].integer.value; tmp[0].type == ACPI_TYPE_INTEGER &&
tmp[1].type == ACPI_TYPE_STRING) {
len = tmp[0].integer.value;
if (buf) { if (buf) {
if (attribute == ACPI_ATTR_INDEX_SHOW) /*
* This 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", scnprintf(buf, PAGE_SIZE, "%llu\n",
obj->package.elements[0].integer.value); tmp->integer.value);
else if (attribute == ACPI_ATTR_LABEL_SHOW) else if (attr == ACPI_ATTR_LABEL_SHOW)
dsm_label_utf16s_to_utf8s(obj, buf); dsm_label_utf16s_to_utf8s(tmp + 1, buf);
kfree(output->pointer); len = strlen(buf) > 0 ? strlen(buf) : -1;
return strlen(buf);
} }
kfree(output->pointer);
return len;
} }
kfree(output->pointer); ACPI_FREE(obj);
return -1; return len;
} }
static bool static bool
device_has_dsm(struct device *dev) device_has_dsm(struct device *dev)
{ {
acpi_handle handle; return dsm_get_label(dev, NULL, ACPI_ATTR_NONE) > 0;
struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
handle = ACPI_HANDLE(dev);
if (!handle)
return FALSE;
if (dsm_get_label(handle, DEVICE_LABEL_DSM, &output, NULL,
ACPI_ATTR_NONE) > 0)
return TRUE;
return FALSE;
} }
static umode_t static umode_t
...@@ -287,44 +265,13 @@ acpi_index_string_exist(struct kobject *kobj, struct attribute *attr, int n) ...@@ -287,44 +265,13 @@ acpi_index_string_exist(struct kobject *kobj, struct attribute *attr, int n)
static ssize_t static ssize_t
acpilabel_show(struct device *dev, struct device_attribute *attr, char *buf) acpilabel_show(struct device *dev, struct device_attribute *attr, char *buf)
{ {
struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL}; return dsm_get_label(dev, buf, ACPI_ATTR_LABEL_SHOW);
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;
} }
static ssize_t static ssize_t
acpiindex_show(struct device *dev, struct device_attribute *attr, char *buf) acpiindex_show(struct device *dev, struct device_attribute *attr, char *buf)
{ {
struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL}; return dsm_get_label(dev, buf, ACPI_ATTR_INDEX_SHOW);
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;
} }
static struct device_attribute acpi_attr_label = { static struct device_attribute acpi_attr_label = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment