aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/sysfs-devices-firmware_node17
-rw-r--r--drivers/acpi/scan.c54
-rw-r--r--include/acpi/acpi_bus.h1
3 files changed, 70 insertions, 2 deletions
diff --git a/Documentation/ABI/testing/sysfs-devices-firmware_node b/Documentation/ABI/testing/sysfs-devices-firmware_node
new file mode 100644
index 000000000000..46badc9ea284
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-devices-firmware_node
@@ -0,0 +1,17 @@
1What: /sys/devices/.../firmware_node/
2Date: September 2012
3Contact: <>
4Description:
5 The /sys/devices/.../firmware_node directory contains attributes
6 allowing the user space to check and modify some firmware
7 related properties of given device.
8
9What: /sys/devices/.../firmware_node/description
10Date: September 2012
11Contact: Lance Ortiz <lance.ortiz@hp.com>
12Description:
13 The /sys/devices/.../firmware/description attribute contains a string
14 that describes the device as provided by the _STR method in the ACPI
15 namespace. This attribute is read-only. If the device does not have
16 an _STR method associated with it in the ACPI namespace, this
17 attribute is not present.
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index d1ecca2b641a..04302835723d 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -10,6 +10,7 @@
10#include <linux/signal.h> 10#include <linux/signal.h>
11#include <linux/kthread.h> 11#include <linux/kthread.h>
12#include <linux/dmi.h> 12#include <linux/dmi.h>
13#include <linux/nls.h>
13 14
14#include <acpi/acpi_drivers.h> 15#include <acpi/acpi_drivers.h>
15 16
@@ -232,8 +233,35 @@ end:
232} 233}
233static DEVICE_ATTR(path, 0444, acpi_device_path_show, NULL); 234static DEVICE_ATTR(path, 0444, acpi_device_path_show, NULL);
234 235
236/* sysfs file that shows description text from the ACPI _STR method */
237static ssize_t description_show(struct device *dev,
238 struct device_attribute *attr,
239 char *buf) {
240 struct acpi_device *acpi_dev = to_acpi_device(dev);
241 int result;
242
243 if (acpi_dev->pnp.str_obj == NULL)
244 return 0;
245
246 /*
247 * The _STR object contains a Unicode identifier for a device.
248 * We need to convert to utf-8 so it can be displayed.
249 */
250 result = utf16s_to_utf8s(
251 (wchar_t *)acpi_dev->pnp.str_obj->buffer.pointer,
252 acpi_dev->pnp.str_obj->buffer.length,
253 UTF16_LITTLE_ENDIAN, buf,
254 PAGE_SIZE);
255
256 buf[result++] = '\n';
257
258 return result;
259}
260static DEVICE_ATTR(description, 0444, description_show, NULL);
261
235static int acpi_device_setup_files(struct acpi_device *dev) 262static int acpi_device_setup_files(struct acpi_device *dev)
236{ 263{
264 struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
237 acpi_status status; 265 acpi_status status;
238 acpi_handle temp; 266 acpi_handle temp;
239 int result = 0; 267 int result = 0;
@@ -257,6 +285,21 @@ static int acpi_device_setup_files(struct acpi_device *dev)
257 goto end; 285 goto end;
258 } 286 }
259 287
288 /*
289 * If device has _STR, 'description' file is created
290 */
291 status = acpi_get_handle(dev->handle, "_STR", &temp);
292 if (ACPI_SUCCESS(status)) {
293 status = acpi_evaluate_object(dev->handle, "_STR",
294 NULL, &buffer);
295 if (ACPI_FAILURE(status))
296 buffer.pointer = NULL;
297 dev->pnp.str_obj = buffer.pointer;
298 result = device_create_file(&dev->dev, &dev_attr_description);
299 if (result)
300 goto end;
301 }
302
260 /* 303 /*
261 * If device has _EJ0, 'eject' file is created that is used to trigger 304 * If device has _EJ0, 'eject' file is created that is used to trigger
262 * hot-removal function from userland. 305 * hot-removal function from userland.
@@ -274,8 +317,15 @@ static void acpi_device_remove_files(struct acpi_device *dev)
274 acpi_handle temp; 317 acpi_handle temp;
275 318
276 /* 319 /*
277 * If device has _EJ0, 'eject' file is created that is used to trigger 320 * If device has _STR, remove 'description' file
278 * hot-removal function from userland. 321 */
322 status = acpi_get_handle(dev->handle, "_STR", &temp);
323 if (ACPI_SUCCESS(status)) {
324 kfree(dev->pnp.str_obj);
325 device_remove_file(&dev->dev, &dev_attr_description);
326 }
327 /*
328 * If device has _EJ0, remove 'eject' file.
279 */ 329 */
280 status = acpi_get_handle(dev->handle, "_EJ0", &temp); 330 status = acpi_get_handle(dev->handle, "_EJ0", &temp);
281 if (ACPI_SUCCESS(status)) 331 if (ACPI_SUCCESS(status))
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index bde976ee068d..3eb9de318824 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -208,6 +208,7 @@ struct acpi_device_pnp {
208 struct list_head ids; /* _HID and _CIDs */ 208 struct list_head ids; /* _HID and _CIDs */
209 acpi_device_name device_name; /* Driver-determined */ 209 acpi_device_name device_name; /* Driver-determined */
210 acpi_device_class device_class; /* " */ 210 acpi_device_class device_class; /* " */
211 union acpi_object *str_obj; /* unicode string for _STR method */
211}; 212};
212 213
213#define acpi_device_bid(d) ((d)->pnp.bus_id) 214#define acpi_device_bid(d) ((d)->pnp.bus_id)