0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <acpi/acpi.h>
0011 #include "accommon.h"
0012 #include "acinterp.h"
0013
0014 #define _COMPONENT ACPI_UTILITIES
0015 ACPI_MODULE_NAME("utids")
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 acpi_status
0035 acpi_ut_execute_HID(struct acpi_namespace_node *device_node,
0036 struct acpi_pnp_device_id **return_id)
0037 {
0038 union acpi_operand_object *obj_desc;
0039 struct acpi_pnp_device_id *hid;
0040 u32 length;
0041 acpi_status status;
0042
0043 ACPI_FUNCTION_TRACE(ut_execute_HID);
0044
0045 status = acpi_ut_evaluate_object(device_node, METHOD_NAME__HID,
0046 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING,
0047 &obj_desc);
0048 if (ACPI_FAILURE(status)) {
0049 return_ACPI_STATUS(status);
0050 }
0051
0052
0053
0054 if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
0055 length = ACPI_EISAID_STRING_SIZE;
0056 } else {
0057 length = obj_desc->string.length + 1;
0058 }
0059
0060
0061
0062 hid =
0063 ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_pnp_device_id) +
0064 (acpi_size)length);
0065 if (!hid) {
0066 status = AE_NO_MEMORY;
0067 goto cleanup;
0068 }
0069
0070
0071
0072 hid->string =
0073 ACPI_ADD_PTR(char, hid, sizeof(struct acpi_pnp_device_id));
0074
0075
0076
0077 if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
0078 acpi_ex_eisa_id_to_string(hid->string, obj_desc->integer.value);
0079 } else {
0080 strcpy(hid->string, obj_desc->string.pointer);
0081 }
0082
0083 hid->length = length;
0084 *return_id = hid;
0085
0086 cleanup:
0087
0088
0089
0090 acpi_ut_remove_reference(obj_desc);
0091 return_ACPI_STATUS(status);
0092 }
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112 acpi_status
0113 acpi_ut_execute_UID(struct acpi_namespace_node *device_node,
0114 struct acpi_pnp_device_id **return_id)
0115 {
0116 union acpi_operand_object *obj_desc;
0117 struct acpi_pnp_device_id *uid;
0118 u32 length;
0119 acpi_status status;
0120
0121 ACPI_FUNCTION_TRACE(ut_execute_UID);
0122
0123 status = acpi_ut_evaluate_object(device_node, METHOD_NAME__UID,
0124 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING,
0125 &obj_desc);
0126 if (ACPI_FAILURE(status)) {
0127 return_ACPI_STATUS(status);
0128 }
0129
0130
0131
0132 if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
0133 length = ACPI_MAX64_DECIMAL_DIGITS + 1;
0134 } else {
0135 length = obj_desc->string.length + 1;
0136 }
0137
0138
0139
0140 uid =
0141 ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_pnp_device_id) +
0142 (acpi_size)length);
0143 if (!uid) {
0144 status = AE_NO_MEMORY;
0145 goto cleanup;
0146 }
0147
0148
0149
0150 uid->string =
0151 ACPI_ADD_PTR(char, uid, sizeof(struct acpi_pnp_device_id));
0152
0153
0154
0155 if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
0156 acpi_ex_integer_to_string(uid->string, obj_desc->integer.value);
0157 } else {
0158 strcpy(uid->string, obj_desc->string.pointer);
0159 }
0160
0161 uid->length = length;
0162 *return_id = uid;
0163
0164 cleanup:
0165
0166
0167
0168 acpi_ut_remove_reference(obj_desc);
0169 return_ACPI_STATUS(status);
0170 }
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195 acpi_status
0196 acpi_ut_execute_CID(struct acpi_namespace_node *device_node,
0197 struct acpi_pnp_device_id_list **return_cid_list)
0198 {
0199 union acpi_operand_object **cid_objects;
0200 union acpi_operand_object *obj_desc;
0201 struct acpi_pnp_device_id_list *cid_list;
0202 char *next_id_string;
0203 u32 string_area_size;
0204 u32 length;
0205 u32 cid_list_size;
0206 acpi_status status;
0207 u32 count;
0208 u32 i;
0209
0210 ACPI_FUNCTION_TRACE(ut_execute_CID);
0211
0212
0213
0214 status = acpi_ut_evaluate_object(device_node, METHOD_NAME__CID,
0215 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING
0216 | ACPI_BTYPE_PACKAGE, &obj_desc);
0217 if (ACPI_FAILURE(status)) {
0218 return_ACPI_STATUS(status);
0219 }
0220
0221
0222
0223
0224
0225
0226
0227 if (obj_desc->common.type == ACPI_TYPE_PACKAGE) {
0228 count = obj_desc->package.count;
0229 cid_objects = obj_desc->package.elements;
0230 } else {
0231
0232 count = 1;
0233 cid_objects = &obj_desc;
0234 }
0235
0236 string_area_size = 0;
0237 for (i = 0; i < count; i++) {
0238
0239
0240
0241 switch (cid_objects[i]->common.type) {
0242 case ACPI_TYPE_INTEGER:
0243
0244 string_area_size += ACPI_EISAID_STRING_SIZE;
0245 break;
0246
0247 case ACPI_TYPE_STRING:
0248
0249 string_area_size += cid_objects[i]->string.length + 1;
0250 break;
0251
0252 default:
0253
0254 status = AE_TYPE;
0255 goto cleanup;
0256 }
0257 }
0258
0259
0260
0261
0262
0263
0264
0265 cid_list_size = sizeof(struct acpi_pnp_device_id_list) +
0266 (count * sizeof(struct acpi_pnp_device_id)) + string_area_size;
0267
0268 cid_list = ACPI_ALLOCATE_ZEROED(cid_list_size);
0269 if (!cid_list) {
0270 status = AE_NO_MEMORY;
0271 goto cleanup;
0272 }
0273
0274
0275
0276 next_id_string = ACPI_CAST_PTR(char, cid_list->ids) +
0277 ((acpi_size)count * sizeof(struct acpi_pnp_device_id));
0278
0279
0280
0281 for (i = 0; i < count; i++) {
0282 if (cid_objects[i]->common.type == ACPI_TYPE_INTEGER) {
0283
0284
0285
0286 acpi_ex_eisa_id_to_string(next_id_string,
0287 cid_objects[i]->integer.
0288 value);
0289 length = ACPI_EISAID_STRING_SIZE;
0290 } else {
0291
0292 strcpy(next_id_string, cid_objects[i]->string.pointer);
0293 length = cid_objects[i]->string.length + 1;
0294 }
0295
0296 cid_list->ids[i].string = next_id_string;
0297 cid_list->ids[i].length = length;
0298 next_id_string += length;
0299 }
0300
0301
0302
0303 cid_list->count = count;
0304 cid_list->list_size = cid_list_size;
0305 *return_cid_list = cid_list;
0306
0307 cleanup:
0308
0309
0310
0311 acpi_ut_remove_reference(obj_desc);
0312 return_ACPI_STATUS(status);
0313 }
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334 acpi_status
0335 acpi_ut_execute_CLS(struct acpi_namespace_node *device_node,
0336 struct acpi_pnp_device_id **return_id)
0337 {
0338 union acpi_operand_object *obj_desc;
0339 union acpi_operand_object **cls_objects;
0340 u32 count;
0341 struct acpi_pnp_device_id *cls;
0342 u32 length;
0343 acpi_status status;
0344 u8 class_code[3] = { 0, 0, 0 };
0345
0346 ACPI_FUNCTION_TRACE(ut_execute_CLS);
0347
0348 status = acpi_ut_evaluate_object(device_node, METHOD_NAME__CLS,
0349 ACPI_BTYPE_PACKAGE, &obj_desc);
0350 if (ACPI_FAILURE(status)) {
0351 return_ACPI_STATUS(status);
0352 }
0353
0354
0355
0356 length = ACPI_PCICLS_STRING_SIZE;
0357 cls_objects = obj_desc->package.elements;
0358 count = obj_desc->package.count;
0359
0360 if (obj_desc->common.type == ACPI_TYPE_PACKAGE) {
0361 if (count > 0
0362 && cls_objects[0]->common.type == ACPI_TYPE_INTEGER) {
0363 class_code[0] = (u8)cls_objects[0]->integer.value;
0364 }
0365 if (count > 1
0366 && cls_objects[1]->common.type == ACPI_TYPE_INTEGER) {
0367 class_code[1] = (u8)cls_objects[1]->integer.value;
0368 }
0369 if (count > 2
0370 && cls_objects[2]->common.type == ACPI_TYPE_INTEGER) {
0371 class_code[2] = (u8)cls_objects[2]->integer.value;
0372 }
0373 }
0374
0375
0376
0377 cls =
0378 ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_pnp_device_id) +
0379 (acpi_size)length);
0380 if (!cls) {
0381 status = AE_NO_MEMORY;
0382 goto cleanup;
0383 }
0384
0385
0386
0387 cls->string =
0388 ACPI_ADD_PTR(char, cls, sizeof(struct acpi_pnp_device_id));
0389
0390
0391
0392 acpi_ex_pci_cls_to_string(cls->string, class_code);
0393 cls->length = length;
0394 *return_id = cls;
0395
0396 cleanup:
0397
0398
0399
0400 acpi_ut_remove_reference(obj_desc);
0401 return_ACPI_STATUS(status);
0402 }