Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
acpi
acpica
utids.c
Go to the documentation of this file.
1
/******************************************************************************
2
*
3
* Module Name: utids - support for device Ids - HID, UID, CID
4
*
5
*****************************************************************************/
6
7
/*
8
* Copyright (C) 2000 - 2012, Intel Corp.
9
* All rights reserved.
10
*
11
* Redistribution and use in source and binary forms, with or without
12
* modification, are permitted provided that the following conditions
13
* are met:
14
* 1. Redistributions of source code must retain the above copyright
15
* notice, this list of conditions, and the following disclaimer,
16
* without modification.
17
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
18
* substantially similar to the "NO WARRANTY" disclaimer below
19
* ("Disclaimer") and any redistribution must be conditioned upon
20
* including a substantially similar Disclaimer requirement for further
21
* binary redistribution.
22
* 3. Neither the names of the above-listed copyright holders nor the names
23
* of any contributors may be used to endorse or promote products derived
24
* from this software without specific prior written permission.
25
*
26
* Alternatively, this software may be distributed under the terms of the
27
* GNU General Public License ("GPL") version 2 as published by the Free
28
* Software Foundation.
29
*
30
* NO WARRANTY
31
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41
* POSSIBILITY OF SUCH DAMAGES.
42
*/
43
44
#include <
acpi/acpi.h
>
45
#include "
accommon.h
"
46
#include "
acinterp.h
"
47
48
#define _COMPONENT ACPI_UTILITIES
49
ACPI_MODULE_NAME
(
"utids"
)
50
51
/*******************************************************************************
52
*
53
* FUNCTION: acpi_ut_execute_HID
54
*
55
* PARAMETERS: device_node - Node for the device
56
* return_id - Where the string HID is returned
57
*
58
* RETURN: Status
59
*
60
* DESCRIPTION: Executes the _HID control method that returns the hardware
61
* ID of the device. The HID is either an 32-bit encoded EISAID
62
* Integer or a String. A string is always returned. An EISAID
63
* is converted to a string.
64
*
65
* NOTE: Internal function, no parameter validation
66
*
67
******************************************************************************/
68
acpi_status
69
acpi_ut_execute_HID
(
struct
acpi_namespace_node
*
device_node
,
70
struct
acpica_device_id
**return_id)
71
{
72
union
acpi_operand_object
*obj_desc;
73
struct
acpica_device_id
*hid;
74
u32
length
;
75
acpi_status
status
;
76
77
ACPI_FUNCTION_TRACE
(ut_execute_HID);
78
79
status =
acpi_ut_evaluate_object
(device_node,
METHOD_NAME__HID
,
80
ACPI_BTYPE_INTEGER
|
ACPI_BTYPE_STRING
,
81
&obj_desc);
82
if
(
ACPI_FAILURE
(status)) {
83
return_ACPI_STATUS
(status);
84
}
85
86
/* Get the size of the String to be returned, includes null terminator */
87
88
if
(obj_desc->
common
.type ==
ACPI_TYPE_INTEGER
) {
89
length =
ACPI_EISAID_STRING_SIZE
;
90
}
else
{
91
length = obj_desc->
string
.length + 1;
92
}
93
94
/* Allocate a buffer for the HID */
95
96
hid =
97
ACPI_ALLOCATE_ZEROED
(
sizeof
(
struct
acpica_device_id
) +
98
(acpi_size) length);
99
if
(!hid) {
100
status =
AE_NO_MEMORY
;
101
goto
cleanup;
102
}
103
104
/* Area for the string starts after DEVICE_ID struct */
105
106
hid->
string
=
ACPI_ADD_PTR
(
char
, hid,
sizeof
(
struct
acpica_device_id
));
107
108
/* Convert EISAID to a string or simply copy existing string */
109
110
if
(obj_desc->
common
.type ==
ACPI_TYPE_INTEGER
) {
111
acpi_ex_eisa_id_to_string
(hid->
string
, obj_desc->
integer
.value);
112
}
else
{
113
ACPI_STRCPY
(hid->
string
, obj_desc->
string
.pointer);
114
}
115
116
hid->
length
=
length
;
117
*return_id = hid;
118
119
cleanup:
120
121
/* On exit, we must delete the return object */
122
123
acpi_ut_remove_reference
(obj_desc);
124
return_ACPI_STATUS
(status);
125
}
126
127
/*******************************************************************************
128
*
129
* FUNCTION: acpi_ut_execute_UID
130
*
131
* PARAMETERS: device_node - Node for the device
132
* return_id - Where the string UID is returned
133
*
134
* RETURN: Status
135
*
136
* DESCRIPTION: Executes the _UID control method that returns the unique
137
* ID of the device. The UID is either a 64-bit Integer (NOT an
138
* EISAID) or a string. Always returns a string. A 64-bit integer
139
* is converted to a decimal string.
140
*
141
* NOTE: Internal function, no parameter validation
142
*
143
******************************************************************************/
144
145
acpi_status
146
acpi_ut_execute_UID
(
struct
acpi_namespace_node
*
device_node
,
147
struct
acpica_device_id
**return_id)
148
{
149
union
acpi_operand_object
*obj_desc;
150
struct
acpica_device_id
*
uid
;
151
u32
length
;
152
acpi_status
status
;
153
154
ACPI_FUNCTION_TRACE
(ut_execute_UID);
155
156
status =
acpi_ut_evaluate_object
(device_node,
METHOD_NAME__UID
,
157
ACPI_BTYPE_INTEGER
|
ACPI_BTYPE_STRING
,
158
&obj_desc);
159
if
(
ACPI_FAILURE
(status)) {
160
return_ACPI_STATUS
(status);
161
}
162
163
/* Get the size of the String to be returned, includes null terminator */
164
165
if
(obj_desc->
common
.type ==
ACPI_TYPE_INTEGER
) {
166
length =
ACPI_MAX64_DECIMAL_DIGITS
+ 1;
167
}
else
{
168
length = obj_desc->
string
.length + 1;
169
}
170
171
/* Allocate a buffer for the UID */
172
173
uid =
174
ACPI_ALLOCATE_ZEROED
(
sizeof
(
struct
acpica_device_id
) +
175
(acpi_size) length);
176
if
(!uid) {
177
status =
AE_NO_MEMORY
;
178
goto
cleanup;
179
}
180
181
/* Area for the string starts after DEVICE_ID struct */
182
183
uid->
string
=
ACPI_ADD_PTR
(
char
, uid,
sizeof
(
struct
acpica_device_id
));
184
185
/* Convert an Integer to string, or just copy an existing string */
186
187
if
(obj_desc->
common
.type ==
ACPI_TYPE_INTEGER
) {
188
acpi_ex_integer_to_string
(uid->
string
, obj_desc->
integer
.value);
189
}
else
{
190
ACPI_STRCPY
(uid->
string
, obj_desc->
string
.pointer);
191
}
192
193
uid->
length
=
length
;
194
*return_id =
uid
;
195
196
cleanup:
197
198
/* On exit, we must delete the return object */
199
200
acpi_ut_remove_reference
(obj_desc);
201
return_ACPI_STATUS
(status);
202
}
203
204
/*******************************************************************************
205
*
206
* FUNCTION: acpi_ut_execute_CID
207
*
208
* PARAMETERS: device_node - Node for the device
209
* return_cid_list - Where the CID list is returned
210
*
211
* RETURN: Status, list of CID strings
212
*
213
* DESCRIPTION: Executes the _CID control method that returns one or more
214
* compatible hardware IDs for the device.
215
*
216
* NOTE: Internal function, no parameter validation
217
*
218
* A _CID method can return either a single compatible ID or a package of
219
* compatible IDs. Each compatible ID can be one of the following:
220
* 1) Integer (32 bit compressed EISA ID) or
221
* 2) String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss")
222
*
223
* The Integer CIDs are converted to string format by this function.
224
*
225
******************************************************************************/
226
227
acpi_status
228
acpi_ut_execute_CID
(
struct
acpi_namespace_node
*
device_node
,
229
struct
acpica_device_id_list
**return_cid_list)
230
{
231
union
acpi_operand_object
**cid_objects;
232
union
acpi_operand_object
*obj_desc;
233
struct
acpica_device_id_list
*cid_list;
234
char
*next_id_string;
235
u32
string_area_size;
236
u32
length
;
237
u32
cid_list_size;
238
acpi_status
status
;
239
u32
count
;
240
u32
i
;
241
242
ACPI_FUNCTION_TRACE
(ut_execute_CID);
243
244
/* Evaluate the _CID method for this device */
245
246
status =
acpi_ut_evaluate_object
(device_node,
METHOD_NAME__CID
,
247
ACPI_BTYPE_INTEGER
|
ACPI_BTYPE_STRING
248
|
ACPI_BTYPE_PACKAGE
, &obj_desc);
249
if
(
ACPI_FAILURE
(status)) {
250
return_ACPI_STATUS
(status);
251
}
252
253
/*
254
* Get the count and size of the returned _CIDs. _CID can return either
255
* a Package of Integers/Strings or a single Integer or String.
256
* Note: This section also validates that all CID elements are of the
257
* correct type (Integer or String).
258
*/
259
if
(obj_desc->
common
.type ==
ACPI_TYPE_PACKAGE
) {
260
count = obj_desc->
package
.count;
261
cid_objects = obj_desc->
package
.elements;
262
}
else
{
/* Single Integer or String CID */
263
264
count = 1;
265
cid_objects = &obj_desc;
266
}
267
268
string_area_size = 0;
269
for
(i = 0; i <
count
; i++) {
270
271
/* String lengths include null terminator */
272
273
switch
(cid_objects[i]->
common
.type) {
274
case
ACPI_TYPE_INTEGER
:
275
string_area_size +=
ACPI_EISAID_STRING_SIZE
;
276
break
;
277
278
case
ACPI_TYPE_STRING
:
279
string_area_size += cid_objects[
i
]->
string
.length + 1;
280
break
;
281
282
default
:
283
status =
AE_TYPE
;
284
goto
cleanup;
285
}
286
}
287
288
/*
289
* Now that we know the length of the CIDs, allocate return buffer:
290
* 1) Size of the base structure +
291
* 2) Size of the CID DEVICE_ID array +
292
* 3) Size of the actual CID strings
293
*/
294
cid_list_size =
sizeof
(
struct
acpica_device_id_list
) +
295
((count - 1) *
sizeof
(
struct
acpica_device_id
)) + string_area_size;
296
297
cid_list =
ACPI_ALLOCATE_ZEROED
(cid_list_size);
298
if
(!cid_list) {
299
status =
AE_NO_MEMORY
;
300
goto
cleanup;
301
}
302
303
/* Area for CID strings starts after the CID DEVICE_ID array */
304
305
next_id_string =
ACPI_CAST_PTR
(
char
, cid_list->ids) +
306
((acpi_size) count *
sizeof
(
struct
acpica_device_id
));
307
308
/* Copy/convert the CIDs to the return buffer */
309
310
for
(i = 0; i <
count
; i++) {
311
if
(cid_objects[i]->
common
.type ==
ACPI_TYPE_INTEGER
) {
312
313
/* Convert the Integer (EISAID) CID to a string */
314
315
acpi_ex_eisa_id_to_string
(next_id_string,
316
cid_objects[i]->
integer
.
317
value
);
318
length =
ACPI_EISAID_STRING_SIZE
;
319
}
else
{
/* ACPI_TYPE_STRING */
320
321
/* Copy the String CID from the returned object */
322
323
ACPI_STRCPY
(next_id_string,
324
cid_objects[i]->
string
.
pointer
);
325
length = cid_objects[
i
]->
string
.length + 1;
326
}
327
328
cid_list->ids[
i
].string = next_id_string;
329
cid_list->ids[
i
].length =
length
;
330
next_id_string +=
length
;
331
}
332
333
/* Finish the CID list */
334
335
cid_list->count =
count
;
336
cid_list->list_size = cid_list_size;
337
*return_cid_list = cid_list;
338
339
cleanup:
340
341
/* On exit, we must delete the _CID return object */
342
343
acpi_ut_remove_reference
(obj_desc);
344
return_ACPI_STATUS
(status);
345
}
Generated on Thu Jan 10 2013 13:23:36 for Linux Kernel by
1.8.2