diff options
author | Bob Moore <robert.moore@intel.com> | 2009-06-29 01:39:29 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2009-08-27 10:17:15 -0400 |
commit | 15b8dd53f5ffaf8e2d9095c423f713423f576c0f (patch) | |
tree | 773f09435b14a810372642502352d46c29b6f148 /drivers/acpi/scan.c | |
parent | 9c61b34cf7078da72cce276ff8cfae5d6e9955bc (diff) |
ACPICA: Major update for acpi_get_object_info external interface
Completed a major update for the acpi_get_object_info external interface.
Changes include:
- Support for variable, unlimited length HID, UID, and CID strings
- Support Processor objects the same as Devices (HID,UID,CID,ADR,STA, etc.)
- Call the _SxW power methods on behalf of a device object
- Determine if a device is a PCI root bridge
- Change the ACPI_BUFFER parameter to ACPI_DEVICE_INFO.
These changes will require an update to all callers of this interface.
See the ACPICA Programmer Reference for details.
Also, update all invocations of acpi_get_object_info interface
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/scan.c')
-rw-r--r-- | drivers/acpi/scan.c | 153 |
1 files changed, 99 insertions, 54 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 781435d7e369..0ab526de7c55 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -60,13 +60,13 @@ static int create_modalias(struct acpi_device *acpi_dev, char *modalias, | |||
60 | } | 60 | } |
61 | 61 | ||
62 | if (acpi_dev->flags.compatible_ids) { | 62 | if (acpi_dev->flags.compatible_ids) { |
63 | struct acpi_compatible_id_list *cid_list; | 63 | struct acpica_device_id_list *cid_list; |
64 | int i; | 64 | int i; |
65 | 65 | ||
66 | cid_list = acpi_dev->pnp.cid_list; | 66 | cid_list = acpi_dev->pnp.cid_list; |
67 | for (i = 0; i < cid_list->count; i++) { | 67 | for (i = 0; i < cid_list->count; i++) { |
68 | count = snprintf(&modalias[len], size, "%s:", | 68 | count = snprintf(&modalias[len], size, "%s:", |
69 | cid_list->id[i].value); | 69 | cid_list->ids[i].string); |
70 | if (count < 0 || count >= size) { | 70 | if (count < 0 || count >= size) { |
71 | printk(KERN_ERR PREFIX "%s cid[%i] exceeds event buffer size", | 71 | printk(KERN_ERR PREFIX "%s cid[%i] exceeds event buffer size", |
72 | acpi_dev->pnp.device_name, i); | 72 | acpi_dev->pnp.device_name, i); |
@@ -287,14 +287,14 @@ int acpi_match_device_ids(struct acpi_device *device, | |||
287 | } | 287 | } |
288 | 288 | ||
289 | if (device->flags.compatible_ids) { | 289 | if (device->flags.compatible_ids) { |
290 | struct acpi_compatible_id_list *cid_list = device->pnp.cid_list; | 290 | struct acpica_device_id_list *cid_list = device->pnp.cid_list; |
291 | int i; | 291 | int i; |
292 | 292 | ||
293 | for (id = ids; id->id[0]; id++) { | 293 | for (id = ids; id->id[0]; id++) { |
294 | /* compare multiple _CID entries against driver ids */ | 294 | /* compare multiple _CID entries against driver ids */ |
295 | for (i = 0; i < cid_list->count; i++) { | 295 | for (i = 0; i < cid_list->count; i++) { |
296 | if (!strcmp((char*)id->id, | 296 | if (!strcmp((char*)id->id, |
297 | cid_list->id[i].value)) | 297 | cid_list->ids[i].string)) |
298 | return 0; | 298 | return 0; |
299 | } | 299 | } |
300 | } | 300 | } |
@@ -999,33 +999,89 @@ static int acpi_dock_match(struct acpi_device *device) | |||
999 | return acpi_get_handle(device->handle, "_DCK", &tmp); | 999 | return acpi_get_handle(device->handle, "_DCK", &tmp); |
1000 | } | 1000 | } |
1001 | 1001 | ||
1002 | static struct acpica_device_id_list* | ||
1003 | acpi_add_cid( | ||
1004 | struct acpi_device_info *info, | ||
1005 | struct acpica_device_id *new_cid) | ||
1006 | { | ||
1007 | struct acpica_device_id_list *cid; | ||
1008 | char *next_id_string; | ||
1009 | acpi_size cid_length; | ||
1010 | acpi_size new_cid_length; | ||
1011 | u32 i; | ||
1012 | |||
1013 | |||
1014 | /* Allocate new CID list with room for the new CID */ | ||
1015 | |||
1016 | if (!new_cid) | ||
1017 | new_cid_length = info->compatible_id_list.list_size; | ||
1018 | else if (info->compatible_id_list.list_size) | ||
1019 | new_cid_length = info->compatible_id_list.list_size + | ||
1020 | new_cid->length + sizeof(struct acpica_device_id); | ||
1021 | else | ||
1022 | new_cid_length = sizeof(struct acpica_device_id_list) + new_cid->length; | ||
1023 | |||
1024 | cid = ACPI_ALLOCATE_ZEROED(new_cid_length); | ||
1025 | if (!cid) { | ||
1026 | return NULL; | ||
1027 | } | ||
1028 | |||
1029 | cid->list_size = new_cid_length; | ||
1030 | cid->count = info->compatible_id_list.count; | ||
1031 | if (new_cid) | ||
1032 | cid->count++; | ||
1033 | next_id_string = (char *) cid->ids + (cid->count * sizeof(struct acpica_device_id)); | ||
1034 | |||
1035 | /* Copy all existing CIDs */ | ||
1036 | |||
1037 | for (i = 0; i < info->compatible_id_list.count; i++) { | ||
1038 | cid_length = info->compatible_id_list.ids[i].length; | ||
1039 | cid->ids[i].string = next_id_string; | ||
1040 | cid->ids[i].length = cid_length; | ||
1041 | |||
1042 | ACPI_MEMCPY(next_id_string, info->compatible_id_list.ids[i].string, | ||
1043 | cid_length); | ||
1044 | |||
1045 | next_id_string += cid_length; | ||
1046 | } | ||
1047 | |||
1048 | /* Append the new CID */ | ||
1049 | |||
1050 | if (new_cid) { | ||
1051 | cid->ids[i].string = next_id_string; | ||
1052 | cid->ids[i].length = new_cid->length; | ||
1053 | |||
1054 | ACPI_MEMCPY(next_id_string, new_cid->string, new_cid->length); | ||
1055 | } | ||
1056 | |||
1057 | return cid; | ||
1058 | } | ||
1059 | |||
1002 | static void acpi_device_set_id(struct acpi_device *device, | 1060 | static void acpi_device_set_id(struct acpi_device *device, |
1003 | struct acpi_device *parent, acpi_handle handle, | 1061 | struct acpi_device *parent, acpi_handle handle, |
1004 | int type) | 1062 | int type) |
1005 | { | 1063 | { |
1006 | struct acpi_device_info *info; | 1064 | struct acpi_device_info *info = NULL; |
1007 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
1008 | char *hid = NULL; | 1065 | char *hid = NULL; |
1009 | char *uid = NULL; | 1066 | char *uid = NULL; |
1010 | struct acpi_compatible_id_list *cid_list = NULL; | 1067 | struct acpica_device_id_list *cid_list = NULL; |
1011 | const char *cid_add = NULL; | 1068 | char *cid_add = NULL; |
1012 | acpi_status status; | 1069 | acpi_status status; |
1013 | 1070 | ||
1014 | switch (type) { | 1071 | switch (type) { |
1015 | case ACPI_BUS_TYPE_DEVICE: | 1072 | case ACPI_BUS_TYPE_DEVICE: |
1016 | status = acpi_get_object_info(handle, &buffer); | 1073 | status = acpi_get_object_info(handle, &info); |
1017 | if (ACPI_FAILURE(status)) { | 1074 | if (ACPI_FAILURE(status)) { |
1018 | printk(KERN_ERR PREFIX "%s: Error reading device info\n", __func__); | 1075 | printk(KERN_ERR PREFIX "%s: Error reading device info\n", __func__); |
1019 | return; | 1076 | return; |
1020 | } | 1077 | } |
1021 | 1078 | ||
1022 | info = buffer.pointer; | ||
1023 | if (info->valid & ACPI_VALID_HID) | 1079 | if (info->valid & ACPI_VALID_HID) |
1024 | hid = info->hardware_id.value; | 1080 | hid = info->hardware_id.string; |
1025 | if (info->valid & ACPI_VALID_UID) | 1081 | if (info->valid & ACPI_VALID_UID) |
1026 | uid = info->unique_id.value; | 1082 | uid = info->unique_id.string; |
1027 | if (info->valid & ACPI_VALID_CID) | 1083 | if (info->valid & ACPI_VALID_CID) |
1028 | cid_list = &info->compatibility_id; | 1084 | cid_list = &info->compatible_id_list; |
1029 | if (info->valid & ACPI_VALID_ADR) { | 1085 | if (info->valid & ACPI_VALID_ADR) { |
1030 | device->pnp.bus_address = info->address; | 1086 | device->pnp.bus_address = info->address; |
1031 | device->flags.bus_address = 1; | 1087 | device->flags.bus_address = 1; |
@@ -1076,55 +1132,44 @@ static void acpi_device_set_id(struct acpi_device *device, | |||
1076 | } | 1132 | } |
1077 | 1133 | ||
1078 | if (hid) { | 1134 | if (hid) { |
1079 | strcpy(device->pnp.hardware_id, hid); | 1135 | device->pnp.hardware_id = ACPI_ALLOCATE_ZEROED(strlen (hid) + 1); |
1080 | device->flags.hardware_id = 1; | 1136 | if (device->pnp.hardware_id) { |
1081 | } | 1137 | strcpy(device->pnp.hardware_id, hid); |
1138 | device->flags.hardware_id = 1; | ||
1139 | } | ||
1140 | } else | ||
1141 | device->pnp.hardware_id = NULL; | ||
1142 | |||
1082 | if (uid) { | 1143 | if (uid) { |
1083 | strcpy(device->pnp.unique_id, uid); | 1144 | device->pnp.unique_id = ACPI_ALLOCATE_ZEROED(strlen (uid) + 1); |
1084 | device->flags.unique_id = 1; | 1145 | if (device->pnp.unique_id) { |
1085 | } | 1146 | strcpy(device->pnp.unique_id, uid); |
1147 | device->flags.unique_id = 1; | ||
1148 | } | ||
1149 | } else | ||
1150 | device->pnp.unique_id = NULL; | ||
1151 | |||
1086 | if (cid_list || cid_add) { | 1152 | if (cid_list || cid_add) { |
1087 | struct acpi_compatible_id_list *list; | 1153 | struct acpica_device_id_list *list; |
1088 | int size = 0; | 1154 | |
1089 | int count = 0; | 1155 | if (cid_add) { |
1090 | 1156 | struct acpica_device_id cid; | |
1091 | if (cid_list) { | 1157 | cid.length = strlen (cid_add) + 1; |
1092 | size = cid_list->size; | 1158 | cid.string = cid_add; |
1093 | } else if (cid_add) { | 1159 | |
1094 | size = sizeof(struct acpi_compatible_id_list); | 1160 | list = acpi_add_cid(info, &cid); |
1095 | cid_list = ACPI_ALLOCATE_ZEROED((acpi_size) size); | 1161 | } else { |
1096 | if (!cid_list) { | 1162 | list = acpi_add_cid(info, NULL); |
1097 | printk(KERN_ERR "Memory allocation error\n"); | ||
1098 | kfree(buffer.pointer); | ||
1099 | return; | ||
1100 | } else { | ||
1101 | cid_list->count = 0; | ||
1102 | cid_list->size = size; | ||
1103 | } | ||
1104 | } | 1163 | } |
1105 | if (cid_add) | ||
1106 | size += sizeof(struct acpi_compatible_id); | ||
1107 | list = kmalloc(size, GFP_KERNEL); | ||
1108 | 1164 | ||
1109 | if (list) { | 1165 | if (list) { |
1110 | if (cid_list) { | ||
1111 | memcpy(list, cid_list, cid_list->size); | ||
1112 | count = cid_list->count; | ||
1113 | } | ||
1114 | if (cid_add) { | ||
1115 | strncpy(list->id[count].value, cid_add, | ||
1116 | ACPI_MAX_CID_LENGTH); | ||
1117 | count++; | ||
1118 | device->flags.compatible_ids = 1; | ||
1119 | } | ||
1120 | list->size = size; | ||
1121 | list->count = count; | ||
1122 | device->pnp.cid_list = list; | 1166 | device->pnp.cid_list = list; |
1123 | } else | 1167 | if (cid_add) |
1124 | printk(KERN_ERR PREFIX "Memory allocation error\n"); | 1168 | device->flags.compatible_ids = 1; |
1169 | } | ||
1125 | } | 1170 | } |
1126 | 1171 | ||
1127 | kfree(buffer.pointer); | 1172 | kfree(info); |
1128 | } | 1173 | } |
1129 | 1174 | ||
1130 | static int acpi_device_set_context(struct acpi_device *device, int type) | 1175 | static int acpi_device_set_context(struct acpi_device *device, int type) |