aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorJiang Liu <jiang.liu@linux.intel.com>2013-12-19 07:38:13 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-01-05 10:07:14 -0500
commit1d0fcef732832432aee47cb75bf4a2cb3107be64 (patch)
tree2dbd9c1017342f1b39618ebb8b9bf74c9c846aa4 /drivers/pci
parent54e5bb46597e5eba63e460a1f96eb2021dc71fec (diff)
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: Jiang Liu <jiang.liu@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/pci-label.c121
1 files changed, 34 insertions, 87 deletions
diff --git a/drivers/pci/pci-label.c b/drivers/pci/pci-label.c
index f6e01a500d79..f12dcd1dc208 100644
--- a/drivers/pci/pci-label.c
+++ b/drivers/pci/pci-label.c
@@ -195,80 +195,58 @@ enum acpi_attr_enum {
195static void dsm_label_utf16s_to_utf8s(union acpi_object *obj, char *buf) 195static void dsm_label_utf16s_to_utf8s(union acpi_object *obj, char *buf)
196{ 196{
197 int len; 197 int len;
198 len = utf16s_to_utf8s((const wchar_t *)obj-> 198 len = utf16s_to_utf8s((const wchar_t *)obj->string.pointer,
199 package.elements[1].string.pointer, 199 obj->string.length,
200 obj->package.elements[1].string.length,
201 UTF16_LITTLE_ENDIAN, 200 UTF16_LITTLE_ENDIAN,
202 buf, PAGE_SIZE); 201 buf, PAGE_SIZE);
203 buf[len] = '\n'; 202 buf[len] = '\n';
204} 203}
205 204
206static int 205static int
207dsm_get_label(acpi_handle handle, int func, 206dsm_get_label(struct device *dev, char *buf, enum acpi_attr_enum attr)
208 struct acpi_buffer *output,
209 char *buf, enum acpi_attr_enum attribute)
210{ 207{
211 struct acpi_object_list input; 208 acpi_handle handle;
212 union acpi_object params[4]; 209 union acpi_object *obj, *tmp;
213 union acpi_object *obj; 210 int len = -1;
214 int len = 0; 211
215 212 handle = ACPI_HANDLE(dev);
216 int err; 213 if (!handle)
217
218 input.count = 4;
219 input.pointer = params;
220 params[0].type = ACPI_TYPE_BUFFER;
221 params[0].buffer.length = sizeof(device_label_dsm_uuid);
222 params[0].buffer.pointer = (char *)device_label_dsm_uuid;
223 params[1].type = ACPI_TYPE_INTEGER;
224 params[1].integer.value = 0x02;
225 params[2].type = ACPI_TYPE_INTEGER;
226 params[2].integer.value = func;
227 params[3].type = ACPI_TYPE_PACKAGE;
228 params[3].package.count = 0;
229 params[3].package.elements = NULL;
230
231 err = acpi_evaluate_object(handle, "_DSM", &input, output);
232 if (err)
233 return -1; 214 return -1;
234 215
235 obj = (union acpi_object *)output->pointer; 216 obj = acpi_evaluate_dsm(handle, device_label_dsm_uuid, 0x2,
236 if (obj->type == ACPI_TYPE_PACKAGE && obj->package.count == 2) { 217 DEVICE_LABEL_DSM, NULL);
237 len = obj->package.elements[0].integer.value; 218 if (!obj)
219 return -1;
220
221 tmp = obj->package.elements;
222 if (obj->type == ACPI_TYPE_PACKAGE && obj->package.count == 2 &&
223 tmp[0].type == ACPI_TYPE_INTEGER &&
224 tmp[1].type == ACPI_TYPE_STRING) {
225 len = tmp[0].integer.value;
238 if (buf) { 226 if (buf) {
239 if (attribute == ACPI_ATTR_INDEX_SHOW) 227 /*
228 * This second string element is optional even when
229 * this _DSM is implemented; when not implemented,
230 * this entry must return a null string.
231 */
232 if (attr == ACPI_ATTR_INDEX_SHOW)
240 scnprintf(buf, PAGE_SIZE, "%llu\n", 233 scnprintf(buf, PAGE_SIZE, "%llu\n",
241 obj->package.elements[0].integer.value); 234 tmp->integer.value);
242 else if (attribute == ACPI_ATTR_LABEL_SHOW) 235 else if (attr == ACPI_ATTR_LABEL_SHOW)
243 dsm_label_utf16s_to_utf8s(obj, buf); 236 dsm_label_utf16s_to_utf8s(tmp + 1, buf);
244 kfree(output->pointer); 237 len = strlen(buf) > 0 ? strlen(buf) : -1;
245 return strlen(buf);
246 } 238 }
247 kfree(output->pointer);
248 return len;
249 } 239 }
250 240
251 kfree(output->pointer); 241 ACPI_FREE(obj);
252 242
253 return -1; 243 return len;
254} 244}
255 245
256static bool 246static bool
257device_has_dsm(struct device *dev) 247device_has_dsm(struct device *dev)
258{ 248{
259 acpi_handle handle; 249 return dsm_get_label(dev, NULL, ACPI_ATTR_NONE) > 0;
260 struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
261
262 handle = ACPI_HANDLE(dev);
263
264 if (!handle)
265 return FALSE;
266
267 if (dsm_get_label(handle, DEVICE_LABEL_DSM, &output, NULL,
268 ACPI_ATTR_NONE) > 0)
269 return TRUE;
270
271 return FALSE;
272} 250}
273 251
274static umode_t 252static umode_t
@@ -287,44 +265,13 @@ acpi_index_string_exist(struct kobject *kobj, struct attribute *attr, int n)
287static ssize_t 265static ssize_t
288acpilabel_show(struct device *dev, struct device_attribute *attr, char *buf) 266acpilabel_show(struct device *dev, struct device_attribute *attr, char *buf)
289{ 267{
290 struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL}; 268 return dsm_get_label(dev, buf, ACPI_ATTR_LABEL_SHOW);
291 acpi_handle handle;
292 int length;
293
294 handle = ACPI_HANDLE(dev);
295
296 if (!handle)
297 return -1;
298
299 length = dsm_get_label(handle, DEVICE_LABEL_DSM,
300 &output, buf, ACPI_ATTR_LABEL_SHOW);
301
302 if (length < 1)
303 return -1;
304
305 return length;
306} 269}
307 270
308static ssize_t 271static ssize_t
309acpiindex_show(struct device *dev, struct device_attribute *attr, char *buf) 272acpiindex_show(struct device *dev, struct device_attribute *attr, char *buf)
310{ 273{
311 struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL}; 274 return dsm_get_label(dev, buf, ACPI_ATTR_INDEX_SHOW);
312 acpi_handle handle;
313 int length;
314
315 handle = ACPI_HANDLE(dev);
316
317 if (!handle)
318 return -1;
319
320 length = dsm_get_label(handle, DEVICE_LABEL_DSM,
321 &output, buf, ACPI_ATTR_INDEX_SHOW);
322
323 if (length < 0)
324 return -1;
325
326 return length;
327
328} 275}
329 276
330static struct device_attribute acpi_attr_label = { 277static struct device_attribute acpi_attr_label = {