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 --- |