aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/scan.c
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2009-09-19 01:45:22 -0400
committerLen Brown <len.brown@intel.com>2009-09-19 01:45:22 -0400
commit985f38781d19101aba121df423f92c87b208c6df (patch)
tree21b10413b6e24c0eaf5c3b2432e936749a672644 /drivers/acpi/scan.c
parentd093d70a81b08673d1577ad73419998f02be9d29 (diff)
parentc9766237afa92e8d7f27bbcd4964f1b43fa0bce8 (diff)
Merge branch 'acpica' into release
Diffstat (limited to 'drivers/acpi/scan.c')
-rw-r--r--drivers/acpi/scan.c163
1 files changed, 106 insertions, 57 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 5699d979596d..297d8b94fbbc 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 }
@@ -309,6 +309,10 @@ static void acpi_device_release(struct device *dev)
309 struct acpi_device *acpi_dev = to_acpi_device(dev); 309 struct acpi_device *acpi_dev = to_acpi_device(dev);
310 310
311 kfree(acpi_dev->pnp.cid_list); 311 kfree(acpi_dev->pnp.cid_list);
312 if (acpi_dev->flags.hardware_id)
313 kfree(acpi_dev->pnp.hardware_id);
314 if (acpi_dev->flags.unique_id)
315 kfree(acpi_dev->pnp.unique_id);
312 kfree(acpi_dev); 316 kfree(acpi_dev);
313} 317}
314 318
@@ -687,7 +691,7 @@ acpi_bus_get_ejd(acpi_handle handle, acpi_handle *ejd)
687} 691}
688EXPORT_SYMBOL_GPL(acpi_bus_get_ejd); 692EXPORT_SYMBOL_GPL(acpi_bus_get_ejd);
689 693
690void acpi_bus_data_handler(acpi_handle handle, u32 function, void *context) 694void acpi_bus_data_handler(acpi_handle handle, void *context)
691{ 695{
692 696
693 /* TBD */ 697 /* TBD */
@@ -1000,33 +1004,89 @@ static int acpi_dock_match(struct acpi_device *device)
1000 return acpi_get_handle(device->handle, "_DCK", &tmp); 1004 return acpi_get_handle(device->handle, "_DCK", &tmp);
1001} 1005}
1002 1006
1007static struct acpica_device_id_list*
1008acpi_add_cid(
1009 struct acpi_device_info *info,
1010 struct acpica_device_id *new_cid)
1011{
1012 struct acpica_device_id_list *cid;
1013 char *next_id_string;
1014 acpi_size cid_length;
1015 acpi_size new_cid_length;
1016 u32 i;
1017
1018
1019 /* Allocate new CID list with room for the new CID */
1020
1021 if (!new_cid)
1022 new_cid_length = info->compatible_id_list.list_size;
1023 else if (info->compatible_id_list.list_size)
1024 new_cid_length = info->compatible_id_list.list_size +
1025 new_cid->length + sizeof(struct acpica_device_id);
1026 else
1027 new_cid_length = sizeof(struct acpica_device_id_list) + new_cid->length;
1028
1029 cid = ACPI_ALLOCATE_ZEROED(new_cid_length);
1030 if (!cid) {
1031 return NULL;
1032 }
1033
1034 cid->list_size = new_cid_length;
1035 cid->count = info->compatible_id_list.count;
1036 if (new_cid)
1037 cid->count++;
1038 next_id_string = (char *) cid->ids + (cid->count * sizeof(struct acpica_device_id));
1039
1040 /* Copy all existing CIDs */
1041
1042 for (i = 0; i < info->compatible_id_list.count; i++) {
1043 cid_length = info->compatible_id_list.ids[i].length;
1044 cid->ids[i].string = next_id_string;
1045 cid->ids[i].length = cid_length;
1046
1047 ACPI_MEMCPY(next_id_string, info->compatible_id_list.ids[i].string,
1048 cid_length);
1049
1050 next_id_string += cid_length;
1051 }
1052
1053 /* Append the new CID */
1054
1055 if (new_cid) {
1056 cid->ids[i].string = next_id_string;
1057 cid->ids[i].length = new_cid->length;
1058
1059 ACPI_MEMCPY(next_id_string, new_cid->string, new_cid->length);
1060 }
1061
1062 return cid;
1063}
1064
1003static void acpi_device_set_id(struct acpi_device *device, 1065static void acpi_device_set_id(struct acpi_device *device,
1004 struct acpi_device *parent, acpi_handle handle, 1066 struct acpi_device *parent, acpi_handle handle,
1005 int type) 1067 int type)
1006{ 1068{
1007 struct acpi_device_info *info; 1069 struct acpi_device_info *info = NULL;
1008 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
1009 char *hid = NULL; 1070 char *hid = NULL;
1010 char *uid = NULL; 1071 char *uid = NULL;
1011 struct acpi_compatible_id_list *cid_list = NULL; 1072 struct acpica_device_id_list *cid_list = NULL;
1012 const char *cid_add = NULL; 1073 char *cid_add = NULL;
1013 acpi_status status; 1074 acpi_status status;
1014 1075
1015 switch (type) { 1076 switch (type) {
1016 case ACPI_BUS_TYPE_DEVICE: 1077 case ACPI_BUS_TYPE_DEVICE:
1017 status = acpi_get_object_info(handle, &buffer); 1078 status = acpi_get_object_info(handle, &info);
1018 if (ACPI_FAILURE(status)) { 1079 if (ACPI_FAILURE(status)) {
1019 printk(KERN_ERR PREFIX "%s: Error reading device info\n", __func__); 1080 printk(KERN_ERR PREFIX "%s: Error reading device info\n", __func__);
1020 return; 1081 return;
1021 } 1082 }
1022 1083
1023 info = buffer.pointer;
1024 if (info->valid & ACPI_VALID_HID) 1084 if (info->valid & ACPI_VALID_HID)
1025 hid = info->hardware_id.value; 1085 hid = info->hardware_id.string;
1026 if (info->valid & ACPI_VALID_UID) 1086 if (info->valid & ACPI_VALID_UID)
1027 uid = info->unique_id.value; 1087 uid = info->unique_id.string;
1028 if (info->valid & ACPI_VALID_CID) 1088 if (info->valid & ACPI_VALID_CID)
1029 cid_list = &info->compatibility_id; 1089 cid_list = &info->compatible_id_list;
1030 if (info->valid & ACPI_VALID_ADR) { 1090 if (info->valid & ACPI_VALID_ADR) {
1031 device->pnp.bus_address = info->address; 1091 device->pnp.bus_address = info->address;
1032 device->flags.bus_address = 1; 1092 device->flags.bus_address = 1;
@@ -1077,55 +1137,46 @@ static void acpi_device_set_id(struct acpi_device *device,
1077 } 1137 }
1078 1138
1079 if (hid) { 1139 if (hid) {
1080 strcpy(device->pnp.hardware_id, hid); 1140 device->pnp.hardware_id = ACPI_ALLOCATE_ZEROED(strlen (hid) + 1);
1081 device->flags.hardware_id = 1; 1141 if (device->pnp.hardware_id) {
1142 strcpy(device->pnp.hardware_id, hid);
1143 device->flags.hardware_id = 1;
1144 }
1082 } 1145 }
1146 if (!device->flags.hardware_id)
1147 device->pnp.hardware_id = "";
1148
1083 if (uid) { 1149 if (uid) {
1084 strcpy(device->pnp.unique_id, uid); 1150 device->pnp.unique_id = ACPI_ALLOCATE_ZEROED(strlen (uid) + 1);
1085 device->flags.unique_id = 1; 1151 if (device->pnp.unique_id) {
1152 strcpy(device->pnp.unique_id, uid);
1153 device->flags.unique_id = 1;
1154 }
1086 } 1155 }
1156 if (!device->flags.unique_id)
1157 device->pnp.unique_id = "";
1158
1087 if (cid_list || cid_add) { 1159 if (cid_list || cid_add) {
1088 struct acpi_compatible_id_list *list; 1160 struct acpica_device_id_list *list;
1089 int size = 0; 1161
1090 int count = 0; 1162 if (cid_add) {
1091 1163 struct acpica_device_id cid;
1092 if (cid_list) { 1164 cid.length = strlen (cid_add) + 1;
1093 size = cid_list->size; 1165 cid.string = cid_add;
1094 } else if (cid_add) { 1166
1095 size = sizeof(struct acpi_compatible_id_list); 1167 list = acpi_add_cid(info, &cid);
1096 cid_list = ACPI_ALLOCATE_ZEROED((acpi_size) size); 1168 } else {
1097 if (!cid_list) { 1169 list = acpi_add_cid(info, NULL);
1098 printk(KERN_ERR "Memory allocation error\n");
1099 kfree(buffer.pointer);
1100 return;
1101 } else {
1102 cid_list->count = 0;
1103 cid_list->size = size;
1104 }
1105 } 1170 }
1106 if (cid_add)
1107 size += sizeof(struct acpi_compatible_id);
1108 list = kmalloc(size, GFP_KERNEL);
1109 1171
1110 if (list) { 1172 if (list) {
1111 if (cid_list) {
1112 memcpy(list, cid_list, cid_list->size);
1113 count = cid_list->count;
1114 }
1115 if (cid_add) {
1116 strncpy(list->id[count].value, cid_add,
1117 ACPI_MAX_CID_LENGTH);
1118 count++;
1119 device->flags.compatible_ids = 1;
1120 }
1121 list->size = size;
1122 list->count = count;
1123 device->pnp.cid_list = list; 1173 device->pnp.cid_list = list;
1124 } else 1174 if (cid_add)
1125 printk(KERN_ERR PREFIX "Memory allocation error\n"); 1175 device->flags.compatible_ids = 1;
1176 }
1126 } 1177 }
1127 1178
1128 kfree(buffer.pointer); 1179 kfree(info);
1129} 1180}
1130 1181
1131static int acpi_device_set_context(struct acpi_device *device, int type) 1182static int acpi_device_set_context(struct acpi_device *device, int type)
@@ -1310,10 +1361,8 @@ acpi_add_single_object(struct acpi_device **child,
1310end: 1361end:
1311 if (!result) 1362 if (!result)
1312 *child = device; 1363 *child = device;
1313 else { 1364 else
1314 kfree(device->pnp.cid_list); 1365 acpi_device_release(&device->dev);
1315 kfree(device);
1316 }
1317 1366
1318 return result; 1367 return result;
1319} 1368}