scan.c (77e766099efc29d8b01db4b8244ff64fa3d3d0ca) scan.c (26d46867b7d27f68a446b073dac7817721ae4c8f)
1/*
2 * scan.c - support for transforming the ACPI namespace into individual objects
3 */
4
5#include <linux/module.h>
6#include <linux/init.h>
7#include <linux/kernel.h>
8#include <linux/acpi.h>
1/*
2 * scan.c - support for transforming the ACPI namespace into individual objects
3 */
4
5#include <linux/module.h>
6#include <linux/init.h>
7#include <linux/kernel.h>
8#include <linux/acpi.h>
9#include <asm/signal.h>
9
10#include <acpi/acpi_drivers.h>
11#include <acpi/acinterp.h> /* for acpi_ex_eisa_id_to_string() */
12
13#define _COMPONENT ACPI_BUS_COMPONENT
14ACPI_MODULE_NAME("scan");
15#define STRUCT_TO_INT(s) (*((int*)&s))
16extern struct acpi_device *acpi_root;

--- 70 unchanged lines hidden (view full) ---

87 len = create_modalias(acpi_dev, buf, 1024);
88 if (len <= 0)
89 return 0;
90 buf[len++] = '\n';
91 return len;
92}
93static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL);
94
10
11#include <acpi/acpi_drivers.h>
12#include <acpi/acinterp.h> /* for acpi_ex_eisa_id_to_string() */
13
14#define _COMPONENT ACPI_BUS_COMPONENT
15ACPI_MODULE_NAME("scan");
16#define STRUCT_TO_INT(s) (*((int*)&s))
17extern struct acpi_device *acpi_root;

--- 70 unchanged lines hidden (view full) ---

88 len = create_modalias(acpi_dev, buf, 1024);
89 if (len <= 0)
90 return 0;
91 buf[len++] = '\n';
92 return len;
93}
94static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL);
95
95static int acpi_eject_operation(acpi_handle handle, int lockable)
96static int acpi_bus_hot_remove_device(void *context)
96{
97{
98 struct acpi_device *device;
99 acpi_handle handle = context;
97 struct acpi_object_list arg_list;
98 union acpi_object arg;
99 acpi_status status = AE_OK;
100
100 struct acpi_object_list arg_list;
101 union acpi_object arg;
102 acpi_status status = AE_OK;
103
101 /*
102 * TBD: evaluate _PS3?
103 */
104 if (acpi_bus_get_device(handle, &device))
105 return 0;
104
106
105 if (lockable) {
107 if (!device)
108 return 0;
109
110 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
111 "Hot-removing device %s...\n", device->dev.bus_id));
112
113
114 if (acpi_bus_trim(device, 1)) {
115 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
116 "Removing device failed\n"));
117 return -1;
118 }
119
120 /* power off device */
121 status = acpi_evaluate_object(handle, "_PS3", NULL, NULL);
122 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND)
123 ACPI_DEBUG_PRINT((ACPI_DB_WARN,
124 "Power-off device failed\n"));
125
126 if (device->flags.lockable) {
106 arg_list.count = 1;
107 arg_list.pointer = &arg;
108 arg.type = ACPI_TYPE_INTEGER;
109 arg.integer.value = 0;
110 acpi_evaluate_object(handle, "_LCK", &arg_list, NULL);
111 }
112
113 arg_list.count = 1;
114 arg_list.pointer = &arg;
115 arg.type = ACPI_TYPE_INTEGER;
116 arg.integer.value = 1;
117
118 /*
119 * TBD: _EJD support.
120 */
127 arg_list.count = 1;
128 arg_list.pointer = &arg;
129 arg.type = ACPI_TYPE_INTEGER;
130 arg.integer.value = 0;
131 acpi_evaluate_object(handle, "_LCK", &arg_list, NULL);
132 }
133
134 arg_list.count = 1;
135 arg_list.pointer = &arg;
136 arg.type = ACPI_TYPE_INTEGER;
137 arg.integer.value = 1;
138
139 /*
140 * TBD: _EJD support.
141 */
121
122 status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL);
142 status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL);
123 if (ACPI_FAILURE(status)) {
124 return (-ENODEV);
125 }
143 if (ACPI_FAILURE(status))
144 return -ENODEV;
126
145
127 return (0);
146 return 0;
128}
129
130static ssize_t
131acpi_eject_store(struct device *d, struct device_attribute *attr,
132 const char *buf, size_t count)
133{
147}
148
149static ssize_t
150acpi_eject_store(struct device *d, struct device_attribute *attr,
151 const char *buf, size_t count)
152{
134 int result;
135 int ret = count;
153 int ret = count;
136 int islockable;
137 acpi_status status;
154 acpi_status status;
138 acpi_handle handle;
139 acpi_object_type type = 0;
140 struct acpi_device *acpi_device = to_acpi_device(d);
141
142 if ((!count) || (buf[0] != '1')) {
143 return -EINVAL;
144 }
145#ifndef FORCE_EJECT
146 if (acpi_device->driver == NULL) {
147 ret = -ENODEV;
148 goto err;
149 }
150#endif
151 status = acpi_get_type(acpi_device->handle, &type);
152 if (ACPI_FAILURE(status) || (!acpi_device->flags.ejectable)) {
153 ret = -ENODEV;
154 goto err;
155 }
156
155 acpi_object_type type = 0;
156 struct acpi_device *acpi_device = to_acpi_device(d);
157
158 if ((!count) || (buf[0] != '1')) {
159 return -EINVAL;
160 }
161#ifndef FORCE_EJECT
162 if (acpi_device->driver == NULL) {
163 ret = -ENODEV;
164 goto err;
165 }
166#endif
167 status = acpi_get_type(acpi_device->handle, &type);
168 if (ACPI_FAILURE(status) || (!acpi_device->flags.ejectable)) {
169 ret = -ENODEV;
170 goto err;
171 }
172
157 islockable = acpi_device->flags.lockable;
158 handle = acpi_device->handle;
159
160 result = acpi_bus_trim(acpi_device, 1);
161
162 if (!result)
163 result = acpi_eject_operation(handle, islockable);
164
165 if (result) {
166 ret = -EBUSY;
167 }
173 /* remove the device in another thread to fix the deadlock issue */
174 ret = kernel_thread(acpi_bus_hot_remove_device,
175 acpi_device->handle, SIGCHLD);
168 err:
169 return ret;
170}
171
172static DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store);
173
174static ssize_t
175acpi_device_hid_show(struct device *dev, struct device_attribute *attr, char *buf) {

--- 510 unchanged lines hidden (view full) ---

686 return AE_OK;
687}
688
689static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
690{
691 acpi_status status = 0;
692 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
693 union acpi_object *package = NULL;
176 err:
177 return ret;
178}
179
180static DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store);
181
182static ssize_t
183acpi_device_hid_show(struct device *dev, struct device_attribute *attr, char *buf) {

--- 510 unchanged lines hidden (view full) ---

694 return AE_OK;
695}
696
697static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
698{
699 acpi_status status = 0;
700 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
701 union acpi_object *package = NULL;
694 int psw_error;
702 union acpi_object in_arg[3];
703 struct acpi_object_list arg_list = { 3, in_arg };
704 acpi_status psw_status = AE_OK;
695
696 struct acpi_device_id button_device_ids[] = {
697 {"PNP0C0D", 0},
698 {"PNP0C0C", 0},
699 {"PNP0C0E", 0},
700 {"", 0},
701 };
702

--- 15 unchanged lines hidden (view full) ---

718
719 device->wakeup.flags.valid = 1;
720 /* Call _PSW/_DSW object to disable its ability to wake the sleeping
721 * system for the ACPI device with the _PRW object.
722 * The _PSW object is depreciated in ACPI 3.0 and is replaced by _DSW.
723 * So it is necessary to call _DSW object first. Only when it is not
724 * present will the _PSW object used.
725 */
705
706 struct acpi_device_id button_device_ids[] = {
707 {"PNP0C0D", 0},
708 {"PNP0C0C", 0},
709 {"PNP0C0E", 0},
710 {"", 0},
711 };
712

--- 15 unchanged lines hidden (view full) ---

728
729 device->wakeup.flags.valid = 1;
730 /* Call _PSW/_DSW object to disable its ability to wake the sleeping
731 * system for the ACPI device with the _PRW object.
732 * The _PSW object is depreciated in ACPI 3.0 and is replaced by _DSW.
733 * So it is necessary to call _DSW object first. Only when it is not
734 * present will the _PSW object used.
735 */
726 psw_error = acpi_device_sleep_wake(device, 0, 0, 0);
727 if (psw_error)
728 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
729 "error in _DSW or _PSW evaluation\n"));
730
736 /*
737 * Three agruments are needed for the _DSW object.
738 * Argument 0: enable/disable the wake capabilities
739 * When _DSW object is called to disable the wake capabilities, maybe
740 * the first argument is filled. The value of the other two agruments
741 * is meaningless.
742 */
743 in_arg[0].type = ACPI_TYPE_INTEGER;
744 in_arg[0].integer.value = 0;
745 in_arg[1].type = ACPI_TYPE_INTEGER;
746 in_arg[1].integer.value = 0;
747 in_arg[2].type = ACPI_TYPE_INTEGER;
748 in_arg[2].integer.value = 0;
749 psw_status = acpi_evaluate_object(device->handle, "_DSW",
750 &arg_list, NULL);
751 if (ACPI_FAILURE(psw_status) && (psw_status != AE_NOT_FOUND))
752 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "error in evaluate _DSW\n"));
753 /*
754 * When the _DSW object is not present, OSPM will call _PSW object.
755 */
756 if (psw_status == AE_NOT_FOUND) {
757 /*
758 * Only one agruments is required for the _PSW object.
759 * agrument 0: enable/disable the wake capabilities
760 */
761 arg_list.count = 1;
762 in_arg[0].integer.value = 0;
763 psw_status = acpi_evaluate_object(device->handle, "_PSW",
764 &arg_list, NULL);
765 if (ACPI_FAILURE(psw_status) && (psw_status != AE_NOT_FOUND))
766 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "error in "
767 "evaluate _PSW\n"));
768 }
731 /* Power button, Lid switch always enable wakeup */
732 if (!acpi_match_device_ids(device, button_device_ids))
733 device->wakeup.flags.run_wake = 1;
734
735 end:
736 if (ACPI_FAILURE(status))
737 device->flags.wake_capable = 0;
738 return 0;

--- 845 unchanged lines hidden ---
769 /* Power button, Lid switch always enable wakeup */
770 if (!acpi_match_device_ids(device, button_device_ids))
771 device->wakeup.flags.run_wake = 1;
772
773 end:
774 if (ACPI_FAILURE(status))
775 device->flags.wake_capable = 0;
776 return 0;

--- 845 unchanged lines hidden ---