diff options
Diffstat (limited to 'drivers/acpi/resources/rsmisc.c')
-rw-r--r-- | drivers/acpi/resources/rsmisc.c | 814 |
1 files changed, 443 insertions, 371 deletions
diff --git a/drivers/acpi/resources/rsmisc.c b/drivers/acpi/resources/rsmisc.c index 337a0f01cb23..16ad3bfbee2a 100644 --- a/drivers/acpi/resources/rsmisc.c +++ b/drivers/acpi/resources/rsmisc.c | |||
@@ -47,156 +47,267 @@ | |||
47 | #define _COMPONENT ACPI_RESOURCES | 47 | #define _COMPONENT ACPI_RESOURCES |
48 | ACPI_MODULE_NAME("rsmisc") | 48 | ACPI_MODULE_NAME("rsmisc") |
49 | 49 | ||
50 | #define INIT_RESOURCE_TYPE(i) i->resource_offset | ||
51 | #define INIT_RESOURCE_LENGTH(i) i->aml_offset | ||
52 | #define INIT_TABLE_LENGTH(i) i->value | ||
53 | #define COMPARE_OPCODE(i) i->resource_offset | ||
54 | #define COMPARE_TARGET(i) i->aml_offset | ||
55 | #define COMPARE_VALUE(i) i->value | ||
50 | /******************************************************************************* | 56 | /******************************************************************************* |
51 | * | 57 | * |
52 | * FUNCTION: acpi_rs_get_generic_reg | 58 | * FUNCTION: acpi_rs_convert_aml_to_resource |
53 | * | ||
54 | * PARAMETERS: Aml - Pointer to the AML resource descriptor | ||
55 | * aml_resource_length - Length of the resource from the AML header | ||
56 | * Resource - Where the internal resource is returned | ||
57 | * | ||
58 | * RETURN: Status | ||
59 | * | ||
60 | * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding | ||
61 | * internal resource descriptor, simplifying bitflags and handling | ||
62 | * alignment and endian issues if necessary. | ||
63 | * | ||
64 | ******************************************************************************/ | ||
65 | acpi_status | ||
66 | acpi_rs_get_generic_reg(union aml_resource *aml, | ||
67 | u16 aml_resource_length, struct acpi_resource *resource) | ||
68 | { | ||
69 | ACPI_FUNCTION_TRACE("rs_get_generic_reg"); | ||
70 | |||
71 | /* | ||
72 | * Get the following fields from the AML descriptor: | ||
73 | * Address Space ID | ||
74 | * Register Bit Width | ||
75 | * Register Bit Offset | ||
76 | * Access Size | ||
77 | * Register Address | ||
78 | */ | ||
79 | resource->data.generic_reg.space_id = aml->generic_reg.address_space_id; | ||
80 | resource->data.generic_reg.bit_width = aml->generic_reg.bit_width; | ||
81 | resource->data.generic_reg.bit_offset = aml->generic_reg.bit_offset; | ||
82 | resource->data.generic_reg.access_size = aml->generic_reg.access_size; | ||
83 | ACPI_MOVE_64_TO_64(&resource->data.generic_reg.address, | ||
84 | &aml->generic_reg.address); | ||
85 | |||
86 | /* Complete the resource header */ | ||
87 | |||
88 | resource->type = ACPI_RESOURCE_TYPE_GENERIC_REGISTER; | ||
89 | resource->length = | ||
90 | ACPI_SIZEOF_RESOURCE(struct acpi_resource_generic_register); | ||
91 | return_ACPI_STATUS(AE_OK); | ||
92 | } | ||
93 | |||
94 | /******************************************************************************* | ||
95 | * | ||
96 | * FUNCTION: acpi_rs_set_generic_reg | ||
97 | * | 59 | * |
98 | * PARAMETERS: Resource - Pointer to the resource descriptor | 60 | * PARAMETERS: Resource - Pointer to the resource descriptor |
99 | * Aml - Where the AML descriptor is returned | 61 | * Aml - Where the AML descriptor is returned |
62 | * Info - Pointer to appropriate conversion table | ||
100 | * | 63 | * |
101 | * RETURN: Status | 64 | * RETURN: Status |
102 | * | 65 | * |
103 | * DESCRIPTION: Convert an internal resource descriptor to the corresponding | 66 | * DESCRIPTION: Convert an external AML resource descriptor to the corresponding |
104 | * external AML resource descriptor. | 67 | * internal resource descriptor |
105 | * | ||
106 | ******************************************************************************/ | ||
107 | |||
108 | acpi_status | ||
109 | acpi_rs_set_generic_reg(struct acpi_resource *resource, union aml_resource *aml) | ||
110 | { | ||
111 | ACPI_FUNCTION_TRACE("rs_set_generic_reg"); | ||
112 | |||
113 | /* | ||
114 | * Set the following fields in the AML descriptor: | ||
115 | * Address Space ID | ||
116 | * Register Bit Width | ||
117 | * Register Bit Offset | ||
118 | * Access Size | ||
119 | * Register Address | ||
120 | */ | ||
121 | aml->generic_reg.address_space_id = | ||
122 | (u8) resource->data.generic_reg.space_id; | ||
123 | aml->generic_reg.bit_width = (u8) resource->data.generic_reg.bit_width; | ||
124 | aml->generic_reg.bit_offset = | ||
125 | (u8) resource->data.generic_reg.bit_offset; | ||
126 | aml->generic_reg.access_size = | ||
127 | (u8) resource->data.generic_reg.access_size; | ||
128 | ACPI_MOVE_64_TO_64(&aml->generic_reg.address, | ||
129 | &resource->data.generic_reg.address); | ||
130 | |||
131 | /* Complete the AML descriptor header */ | ||
132 | |||
133 | acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_GENERIC_REGISTER, | ||
134 | sizeof(struct | ||
135 | aml_resource_generic_register), aml); | ||
136 | return_ACPI_STATUS(AE_OK); | ||
137 | } | ||
138 | |||
139 | /******************************************************************************* | ||
140 | * | ||
141 | * FUNCTION: acpi_rs_get_vendor | ||
142 | * | ||
143 | * PARAMETERS: Aml - Pointer to the AML resource descriptor | ||
144 | * aml_resource_length - Length of the resource from the AML header | ||
145 | * Resource - Where the internal resource is returned | ||
146 | * | ||
147 | * RETURN: Status | ||
148 | * | ||
149 | * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding | ||
150 | * internal resource descriptor, simplifying bitflags and handling | ||
151 | * alignment and endian issues if necessary. | ||
152 | * | 68 | * |
153 | ******************************************************************************/ | 69 | ******************************************************************************/ |
154 | |||
155 | acpi_status | 70 | acpi_status |
156 | acpi_rs_get_vendor(union aml_resource *aml, | 71 | acpi_rs_convert_aml_to_resource(struct acpi_resource *resource, |
157 | u16 aml_resource_length, struct acpi_resource *resource) | 72 | union aml_resource *aml, |
73 | struct acpi_rsconvert_info *info) | ||
158 | { | 74 | { |
159 | u8 *aml_byte_data; | 75 | acpi_rs_length aml_resource_length; |
160 | 76 | void *source; | |
161 | ACPI_FUNCTION_TRACE("rs_get_vendor"); | 77 | void *destination; |
78 | char *target; | ||
79 | u8 count; | ||
80 | u8 flags_mode = FALSE; | ||
81 | u16 item_count = 0; | ||
82 | u16 temp16 = 0; | ||
83 | |||
84 | ACPI_FUNCTION_TRACE("rs_get_resource"); | ||
85 | |||
86 | if (((acpi_native_uint) resource) & 0x3) { | ||
87 | acpi_os_printf | ||
88 | ("**** GET: Misaligned resource pointer: %p Type %2.2X Len %X\n", | ||
89 | resource, resource->type, resource->length); | ||
90 | } | ||
162 | 91 | ||
163 | /* Determine if this is a large or small vendor specific item */ | 92 | /* Extract the resource Length field (does not include header length) */ |
164 | 93 | ||
165 | if (aml->large_header.descriptor_type & ACPI_RESOURCE_NAME_LARGE) { | 94 | aml_resource_length = acpi_ut_get_resource_length(aml); |
166 | /* Large item, Point to the first vendor byte */ | ||
167 | 95 | ||
168 | aml_byte_data = | 96 | /* |
169 | ((u8 *) aml) + sizeof(struct aml_resource_large_header); | 97 | * First table entry must be ACPI_RSC_INITxxx and must contain the |
170 | } else { | 98 | * table length (# of table entries) |
171 | /* Small item, Point to the first vendor byte */ | 99 | */ |
100 | count = INIT_TABLE_LENGTH(info); | ||
101 | |||
102 | while (count) { | ||
103 | /* | ||
104 | * Source is the external AML byte stream buffer, | ||
105 | * destination is the internal resource descriptor | ||
106 | */ | ||
107 | source = ((u8 *) aml) + info->aml_offset; | ||
108 | destination = ((u8 *) resource) + info->resource_offset; | ||
109 | |||
110 | switch (info->opcode) { | ||
111 | case ACPI_RSC_INITGET: | ||
112 | /* | ||
113 | * Get the resource type and the initial (minimum) length | ||
114 | */ | ||
115 | ACPI_MEMSET(resource, 0, INIT_RESOURCE_LENGTH(info)); | ||
116 | resource->type = INIT_RESOURCE_TYPE(info); | ||
117 | resource->length = INIT_RESOURCE_LENGTH(info); | ||
118 | break; | ||
119 | |||
120 | case ACPI_RSC_INITSET: | ||
121 | break; | ||
122 | |||
123 | case ACPI_RSC_FLAGINIT: | ||
124 | |||
125 | flags_mode = TRUE; | ||
126 | break; | ||
127 | |||
128 | case ACPI_RSC_1BITFLAG: | ||
129 | /* | ||
130 | * Mask and shift the flag bit | ||
131 | */ | ||
132 | *((u8 *) destination) = (u8) | ||
133 | ((*((u8 *) source) >> info->value) & 0x01); | ||
134 | break; | ||
135 | |||
136 | case ACPI_RSC_2BITFLAG: | ||
137 | /* | ||
138 | * Mask and shift the flag bits | ||
139 | */ | ||
140 | *((u8 *) destination) = (u8) | ||
141 | ((*((u8 *) source) >> info->value) & 0x03); | ||
142 | break; | ||
143 | |||
144 | case ACPI_RSC_COUNT: | ||
145 | |||
146 | item_count = *((u8 *) source); | ||
147 | *((u8 *) destination) = (u8) item_count; | ||
148 | |||
149 | resource->length = resource->length + | ||
150 | (info->value * (item_count - 1)); | ||
151 | break; | ||
152 | |||
153 | case ACPI_RSC_COUNT16: | ||
154 | |||
155 | item_count = aml_resource_length; | ||
156 | *((u16 *) destination) = item_count; | ||
157 | |||
158 | resource->length = resource->length + | ||
159 | (info->value * (item_count - 1)); | ||
160 | break; | ||
161 | |||
162 | case ACPI_RSC_LENGTH: | ||
163 | |||
164 | resource->length = resource->length + info->value; | ||
165 | break; | ||
166 | |||
167 | case ACPI_RSC_MOVE8: | ||
168 | case ACPI_RSC_MOVE16: | ||
169 | case ACPI_RSC_MOVE32: | ||
170 | case ACPI_RSC_MOVE64: | ||
171 | /* | ||
172 | * Raw data move. Use the Info value field unless item_count has | ||
173 | * been previously initialized via a COUNT opcode | ||
174 | */ | ||
175 | if (info->value) { | ||
176 | item_count = info->value; | ||
177 | } | ||
178 | acpi_rs_move_data(destination, source, item_count, | ||
179 | info->opcode); | ||
180 | break; | ||
181 | |||
182 | case ACPI_RSC_SET8: | ||
183 | |||
184 | ACPI_MEMSET(destination, info->aml_offset, info->value); | ||
185 | break; | ||
186 | |||
187 | case ACPI_RSC_DATA8: | ||
188 | |||
189 | target = ((char *)resource) + info->value; | ||
190 | ACPI_MEMCPY(destination, source, | ||
191 | *(ACPI_CAST_PTR(u16, target))); | ||
192 | break; | ||
193 | |||
194 | case ACPI_RSC_ADDRESS: | ||
195 | /* | ||
196 | * Common handler for address descriptor flags | ||
197 | */ | ||
198 | if (!acpi_rs_get_address_common(resource, aml)) { | ||
199 | return_ACPI_STATUS | ||
200 | (AE_AML_INVALID_RESOURCE_TYPE); | ||
201 | } | ||
202 | break; | ||
203 | |||
204 | case ACPI_RSC_SOURCE: | ||
205 | /* | ||
206 | * Optional resource_source (Index and String) | ||
207 | */ | ||
208 | resource->length += | ||
209 | acpi_rs_get_resource_source(aml_resource_length, | ||
210 | info->value, | ||
211 | destination, aml, NULL); | ||
212 | break; | ||
213 | |||
214 | case ACPI_RSC_SOURCEX: | ||
215 | /* | ||
216 | * Optional resource_source (Index and String). This is the more | ||
217 | * complicated case used by the Interrupt() macro | ||
218 | */ | ||
219 | target = | ||
220 | ((char *)resource) + info->aml_offset + | ||
221 | (item_count * 4); | ||
222 | |||
223 | resource->length += | ||
224 | acpi_rs_get_resource_source(aml_resource_length, | ||
225 | (acpi_rs_length) (((item_count - 1) * sizeof(u32)) + info->value), destination, aml, target); | ||
226 | break; | ||
227 | |||
228 | case ACPI_RSC_BITMASK: | ||
229 | /* | ||
230 | * 8-bit encoded bitmask (DMA macro) | ||
231 | */ | ||
232 | item_count = | ||
233 | acpi_rs_decode_bitmask(*((u8 *) source), | ||
234 | destination); | ||
235 | if (item_count) { | ||
236 | resource->length += | ||
237 | resource->length + (item_count - 1); | ||
238 | } | ||
239 | |||
240 | target = ((char *)resource) + info->value; | ||
241 | *((u8 *) target) = (u8) item_count; | ||
242 | break; | ||
243 | |||
244 | case ACPI_RSC_BITMASK16: | ||
245 | /* | ||
246 | * 16-bit encoded bitmask (IRQ macro) | ||
247 | */ | ||
248 | ACPI_MOVE_16_TO_16(&temp16, source); | ||
249 | |||
250 | item_count = | ||
251 | acpi_rs_decode_bitmask(temp16, destination); | ||
252 | if (item_count) { | ||
253 | resource->length = | ||
254 | resource->length + (item_count - 1); | ||
255 | } | ||
256 | |||
257 | target = ((char *)resource) + info->value; | ||
258 | *((u8 *) target) = (u8) item_count; | ||
259 | break; | ||
260 | |||
261 | case ACPI_RSC_EXIT_NE: | ||
262 | /* | ||
263 | * Control - Exit conversion if not equal | ||
264 | */ | ||
265 | switch (info->resource_offset) { | ||
266 | case ACPI_RSC_COMPARE_AML_LENGTH: | ||
267 | if (aml_resource_length != info->value) { | ||
268 | goto exit; | ||
269 | } | ||
270 | break; | ||
271 | |||
272 | case ACPI_RSC_COMPARE_VALUE: | ||
273 | if (*((u8 *) source) != info->value) { | ||
274 | goto exit; | ||
275 | } | ||
276 | break; | ||
277 | |||
278 | default: | ||
279 | acpi_os_printf | ||
280 | ("*** Invalid conversion sub-opcode\n"); | ||
281 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
282 | } | ||
283 | break; | ||
284 | |||
285 | default: | ||
286 | |||
287 | acpi_os_printf("*** Invalid conversion opcode\n"); | ||
288 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
289 | } | ||
172 | 290 | ||
173 | aml_byte_data = | 291 | count--; |
174 | ((u8 *) aml) + sizeof(struct aml_resource_small_header); | 292 | info++; |
175 | } | 293 | } |
176 | 294 | ||
177 | /* Copy the vendor-specific bytes */ | 295 | exit: |
178 | 296 | if (!flags_mode) { | |
179 | ACPI_MEMCPY(resource->data.vendor.byte_data, | 297 | /* Round the resource struct length up to the next 32-bit boundary */ |
180 | aml_byte_data, aml_resource_length); | ||
181 | resource->data.vendor.byte_length = aml_resource_length; | ||
182 | 298 | ||
183 | /* | 299 | resource->length = ACPI_ROUND_UP_to_32_bITS(resource->length); |
184 | * In order for the struct_size to fall on a 32-bit boundary, | 300 | } |
185 | * calculate the length of the vendor string and expand the | ||
186 | * struct_size to the next 32-bit boundary. | ||
187 | */ | ||
188 | resource->type = ACPI_RESOURCE_TYPE_VENDOR; | ||
189 | resource->length = ACPI_SIZEOF_RESOURCE(struct acpi_resource_vendor) + | ||
190 | ACPI_ROUND_UP_to_32_bITS(aml_resource_length); | ||
191 | return_ACPI_STATUS(AE_OK); | 301 | return_ACPI_STATUS(AE_OK); |
192 | } | 302 | } |
193 | 303 | ||
194 | /******************************************************************************* | 304 | /******************************************************************************* |
195 | * | 305 | * |
196 | * FUNCTION: acpi_rs_set_vendor | 306 | * FUNCTION: acpi_rs_convert_resource_to_aml |
197 | * | 307 | * |
198 | * PARAMETERS: Resource - Pointer to the resource descriptor | 308 | * PARAMETERS: Resource - Pointer to the resource descriptor |
199 | * Aml - Where the AML descriptor is returned | 309 | * Aml - Where the AML descriptor is returned |
310 | * Info - Pointer to appropriate conversion table | ||
200 | * | 311 | * |
201 | * RETURN: Status | 312 | * RETURN: Status |
202 | * | 313 | * |
@@ -206,275 +317,236 @@ acpi_rs_get_vendor(union aml_resource *aml, | |||
206 | ******************************************************************************/ | 317 | ******************************************************************************/ |
207 | 318 | ||
208 | acpi_status | 319 | acpi_status |
209 | acpi_rs_set_vendor(struct acpi_resource *resource, union aml_resource *aml) | 320 | acpi_rs_convert_resource_to_aml(struct acpi_resource *resource, |
321 | union aml_resource *aml, | ||
322 | struct acpi_rsconvert_info *info) | ||
210 | { | 323 | { |
211 | u32 resource_length; | 324 | void *source = NULL; |
212 | u8 *source; | 325 | void *destination; |
213 | u8 *destination; | 326 | acpi_rsdesc_size aml_length = 0; |
214 | 327 | u8 count; | |
215 | ACPI_FUNCTION_TRACE("rs_set_vendor"); | 328 | u16 temp16 = 0; |
216 | 329 | u16 item_count = 0; | |
217 | resource_length = resource->data.vendor.byte_length; | ||
218 | source = ACPI_CAST_PTR(u8, resource->data.vendor.byte_data); | ||
219 | |||
220 | /* Length determines if this is a large or small resource */ | ||
221 | 330 | ||
222 | if (resource_length > 7) { | 331 | ACPI_FUNCTION_TRACE("rs_convert_resource_to_aml"); |
223 | /* Large item, get pointer to the data part of the descriptor */ | ||
224 | 332 | ||
225 | destination = | 333 | /* Validate the Resource pointer, must be 32-bit aligned */ |
226 | ((u8 *) aml) + sizeof(struct aml_resource_large_header); | ||
227 | 334 | ||
228 | /* Complete the AML descriptor header */ | 335 | if (((acpi_native_uint) resource) & 0x3) { |
229 | 336 | acpi_os_printf | |
230 | acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_VENDOR_LARGE, | 337 | ("**** SET: Misaligned resource pointer: %p Type %2.2X Len %X\n", |
231 | (u32) (resource_length + | 338 | resource, resource->type, resource->length); |
232 | sizeof(struct | ||
233 | aml_resource_large_header)), | ||
234 | aml); | ||
235 | } else { | ||
236 | /* Small item, get pointer to the data part of the descriptor */ | ||
237 | |||
238 | destination = | ||
239 | ((u8 *) aml) + sizeof(struct aml_resource_small_header); | ||
240 | |||
241 | /* Complete the AML descriptor header */ | ||
242 | |||
243 | acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_VENDOR_SMALL, | ||
244 | (u32) (resource_length + | ||
245 | sizeof(struct | ||
246 | aml_resource_small_header)), | ||
247 | aml); | ||
248 | } | 339 | } |
249 | 340 | ||
250 | /* Copy the vendor-specific bytes */ | 341 | /* |
251 | 342 | * First table entry must be ACPI_RSC_INITxxx and must contain the | |
252 | ACPI_MEMCPY(destination, source, resource_length); | 343 | * table length (# of table entries) |
253 | return_ACPI_STATUS(AE_OK); | 344 | */ |
254 | } | 345 | count = INIT_TABLE_LENGTH(info); |
255 | 346 | ||
256 | /******************************************************************************* | 347 | while (count) { |
257 | * | 348 | /* |
258 | * FUNCTION: acpi_rs_get_start_dpf | 349 | * Source is the internal resource descriptor, |
259 | * | 350 | * destination is the external AML byte stream buffer |
260 | * PARAMETERS: Aml - Pointer to the AML resource descriptor | 351 | */ |
261 | * aml_resource_length - Length of the resource from the AML header | 352 | source = ((u8 *) resource) + info->resource_offset; |
262 | * Resource - Where the internal resource is returned | 353 | destination = ((u8 *) aml) + info->aml_offset; |
263 | * | 354 | |
264 | * RETURN: Status | 355 | switch (info->opcode) { |
265 | * | 356 | case ACPI_RSC_INITSET: |
266 | * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding | 357 | |
267 | * internal resource descriptor, simplifying bitflags and handling | 358 | ACPI_MEMSET(aml, 0, INIT_RESOURCE_LENGTH(info)); |
268 | * alignment and endian issues if necessary. | 359 | aml_length = INIT_RESOURCE_LENGTH(info); |
269 | * | 360 | acpi_rs_set_resource_header(INIT_RESOURCE_TYPE(info), |
270 | ******************************************************************************/ | 361 | aml_length, aml); |
271 | 362 | break; | |
272 | acpi_status | 363 | |
273 | acpi_rs_get_start_dpf(union aml_resource *aml, | 364 | case ACPI_RSC_INITGET: |
274 | u16 aml_resource_length, struct acpi_resource *resource) | 365 | break; |
275 | { | 366 | |
276 | ACPI_FUNCTION_TRACE("rs_get_start_dpf"); | 367 | case ACPI_RSC_FLAGINIT: |
277 | 368 | /* | |
278 | /* Get the flags byte if present */ | 369 | * Clear the flag byte |
279 | 370 | */ | |
280 | if (aml_resource_length == 1) { | 371 | *((u8 *) destination) = 0; |
281 | /* Get the Compatibility priority */ | 372 | break; |
282 | 373 | ||
283 | resource->data.start_dpf.compatibility_priority = | 374 | case ACPI_RSC_1BITFLAG: |
284 | (aml->start_dpf.flags & 0x03); | 375 | /* |
285 | 376 | * Mask and shift the flag bit | |
286 | if (resource->data.start_dpf.compatibility_priority >= 3) { | 377 | */ |
287 | return_ACPI_STATUS(AE_AML_BAD_RESOURCE_VALUE); | 378 | *((u8 *) destination) |= (u8) |
288 | } | 379 | ((*((u8 *) source) & 0x01) << info->value); |
289 | 380 | break; | |
290 | /* Get the Performance/Robustness preference */ | 381 | |
291 | 382 | case ACPI_RSC_2BITFLAG: | |
292 | resource->data.start_dpf.performance_robustness = | 383 | /* |
293 | ((aml->start_dpf.flags >> 2) & 0x03); | 384 | * Mask and shift the flag bits |
294 | 385 | */ | |
295 | if (resource->data.start_dpf.performance_robustness >= 3) { | 386 | *((u8 *) destination) |= (u8) |
296 | return_ACPI_STATUS(AE_AML_BAD_RESOURCE_VALUE); | 387 | ((*((u8 *) source) & 0x03) << info->value); |
388 | break; | ||
389 | |||
390 | case ACPI_RSC_COUNT: | ||
391 | |||
392 | item_count = *((u8 *) source); | ||
393 | *((u8 *) destination) = (u8) item_count; | ||
394 | |||
395 | aml_length = (u16) (aml_length + | ||
396 | (info->value * (item_count - 1))); | ||
397 | break; | ||
398 | |||
399 | case ACPI_RSC_COUNT16: | ||
400 | |||
401 | item_count = *((u16 *) source); | ||
402 | aml_length = (u16) (aml_length + item_count); | ||
403 | acpi_rs_set_resource_length(aml_length, aml); | ||
404 | break; | ||
405 | |||
406 | case ACPI_RSC_LENGTH: | ||
407 | |||
408 | acpi_rs_set_resource_length(info->value, aml); | ||
409 | break; | ||
410 | |||
411 | case ACPI_RSC_MOVE8: | ||
412 | case ACPI_RSC_MOVE16: | ||
413 | case ACPI_RSC_MOVE32: | ||
414 | case ACPI_RSC_MOVE64: | ||
415 | |||
416 | if (info->value) { | ||
417 | item_count = info->value; | ||
418 | } | ||
419 | acpi_rs_move_data(destination, source, item_count, | ||
420 | info->opcode); | ||
421 | break; | ||
422 | |||
423 | case ACPI_RSC_ADDRESS: | ||
424 | |||
425 | /* Set the Resource Type, General Flags, and Type-Specific Flags */ | ||
426 | |||
427 | acpi_rs_set_address_common(aml, resource); | ||
428 | break; | ||
429 | |||
430 | case ACPI_RSC_SOURCEX: | ||
431 | /* | ||
432 | * Optional resource_source (Index and String) | ||
433 | */ | ||
434 | aml_length = | ||
435 | acpi_rs_set_resource_source(aml, | ||
436 | (acpi_rs_length) | ||
437 | aml_length, source); | ||
438 | acpi_rs_set_resource_length(aml_length, aml); | ||
439 | break; | ||
440 | |||
441 | case ACPI_RSC_SOURCE: | ||
442 | /* | ||
443 | * Optional resource_source (Index and String). This is the more | ||
444 | * complicated case used by the Interrupt() macro | ||
445 | */ | ||
446 | aml_length = | ||
447 | acpi_rs_set_resource_source(aml, info->value, | ||
448 | source); | ||
449 | acpi_rs_set_resource_length(aml_length, aml); | ||
450 | break; | ||
451 | |||
452 | case ACPI_RSC_BITMASK: | ||
453 | /* | ||
454 | * 8-bit encoded bitmask (DMA macro) | ||
455 | */ | ||
456 | *((u8 *) destination) = (u8) | ||
457 | acpi_rs_encode_bitmask(source, | ||
458 | *(((u8 *) resource) + | ||
459 | info->value)); | ||
460 | break; | ||
461 | |||
462 | case ACPI_RSC_BITMASK16: | ||
463 | /* | ||
464 | * 16-bit encoded bitmask (IRQ macro) | ||
465 | */ | ||
466 | temp16 = | ||
467 | acpi_rs_encode_bitmask(source, | ||
468 | *(((u8 *) resource) + | ||
469 | info->value)); | ||
470 | ACPI_MOVE_16_TO_16(destination, &temp16); | ||
471 | break; | ||
472 | |||
473 | case ACPI_RSC_EXIT_LE: | ||
474 | /* | ||
475 | * Control - Exit conversion if less than or equal | ||
476 | */ | ||
477 | if (item_count <= info->value) { | ||
478 | goto exit; | ||
479 | } | ||
480 | break; | ||
481 | |||
482 | case ACPI_RSC_EXIT_NE: | ||
483 | /* | ||
484 | * Control - Exit conversion if not equal | ||
485 | */ | ||
486 | switch (COMPARE_OPCODE(info)) { | ||
487 | case ACPI_RSC_COMPARE_VALUE: | ||
488 | if (* | ||
489 | ((u8 *) (((u8 *) resource) + | ||
490 | COMPARE_TARGET(info))) != | ||
491 | COMPARE_VALUE(info)) { | ||
492 | goto exit; | ||
493 | } | ||
494 | break; | ||
495 | |||
496 | default: | ||
497 | acpi_os_printf | ||
498 | ("*** Invalid conversion sub-opcode\n"); | ||
499 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
500 | } | ||
501 | break; | ||
502 | |||
503 | default: | ||
504 | |||
505 | acpi_os_printf("*** Invalid conversion opcode\n"); | ||
506 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
297 | } | 507 | } |
298 | } else { | ||
299 | /* start_dependent_no_pri(), no flags byte, set defaults */ | ||
300 | |||
301 | resource->data.start_dpf.compatibility_priority = | ||
302 | ACPI_ACCEPTABLE_CONFIGURATION; | ||
303 | 508 | ||
304 | resource->data.start_dpf.performance_robustness = | 509 | count--; |
305 | ACPI_ACCEPTABLE_CONFIGURATION; | 510 | info++; |
306 | } | 511 | } |
307 | 512 | ||
308 | /* Complete the resource header */ | 513 | exit: |
309 | |||
310 | resource->type = ACPI_RESOURCE_TYPE_START_DEPENDENT; | ||
311 | resource->length = | ||
312 | ACPI_SIZEOF_RESOURCE(struct acpi_resource_start_dependent); | ||
313 | return_ACPI_STATUS(AE_OK); | 514 | return_ACPI_STATUS(AE_OK); |
314 | } | 515 | } |
315 | 516 | ||
316 | /******************************************************************************* | 517 | #if 0 |
317 | * | 518 | /* Previous resource validations */ |
318 | * FUNCTION: acpi_rs_set_start_dpf | ||
319 | * | ||
320 | * PARAMETERS: Resource - Pointer to the resource descriptor | ||
321 | * Aml - Where the AML descriptor is returned | ||
322 | * | ||
323 | * RETURN: Status | ||
324 | * | ||
325 | * DESCRIPTION: Convert an internal resource descriptor to the corresponding | ||
326 | * external AML resource descriptor. | ||
327 | * | ||
328 | ******************************************************************************/ | ||
329 | |||
330 | acpi_status | ||
331 | acpi_rs_set_start_dpf(struct acpi_resource *resource, union aml_resource *aml) | ||
332 | { | ||
333 | ACPI_FUNCTION_TRACE("rs_set_start_dpf"); | ||
334 | 519 | ||
335 | /* | 520 | if (aml->ext_address64.revision_iD != AML_RESOURCE_EXTENDED_ADDRESS_REVISION) { |
336 | * The descriptor type field is set based upon whether a byte is needed | 521 | return_ACPI_STATUS(AE_SUPPORT); |
337 | * to contain Priority data. | ||
338 | */ | ||
339 | if (ACPI_ACCEPTABLE_CONFIGURATION == | ||
340 | resource->data.start_dpf.compatibility_priority && | ||
341 | ACPI_ACCEPTABLE_CONFIGURATION == | ||
342 | resource->data.start_dpf.performance_robustness) { | ||
343 | acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_START_DEPENDENT, | ||
344 | sizeof(struct | ||
345 | aml_resource_start_dependent_noprio), | ||
346 | aml); | ||
347 | } else { | ||
348 | acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_START_DEPENDENT, | ||
349 | sizeof(struct | ||
350 | aml_resource_start_dependent), | ||
351 | aml); | ||
352 | |||
353 | /* Set the Flags byte */ | ||
354 | |||
355 | aml->start_dpf.flags = (u8) | ||
356 | (((resource->data.start_dpf. | ||
357 | performance_robustness & 0x03) << 2) | (resource->data. | ||
358 | start_dpf. | ||
359 | compatibility_priority | ||
360 | & 0x03)); | ||
361 | } | ||
362 | return_ACPI_STATUS(AE_OK); | ||
363 | } | 522 | } |
364 | 523 | ||
365 | /******************************************************************************* | 524 | if (resource->data.start_dpf.performance_robustness >= 3) { |
366 | * | 525 | return_ACPI_STATUS(AE_AML_BAD_RESOURCE_VALUE); |
367 | * FUNCTION: acpi_rs_get_end_dpf | ||
368 | * | ||
369 | * PARAMETERS: Aml - Pointer to the AML resource descriptor | ||
370 | * aml_resource_length - Length of the resource from the AML header | ||
371 | * Resource - Where the internal resource is returned | ||
372 | * | ||
373 | * RETURN: Status | ||
374 | * | ||
375 | * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding | ||
376 | * internal resource descriptor, simplifying bitflags and handling | ||
377 | * alignment and endian issues if necessary. | ||
378 | * | ||
379 | ******************************************************************************/ | ||
380 | |||
381 | acpi_status | ||
382 | acpi_rs_get_end_dpf(union aml_resource *aml, | ||
383 | u16 aml_resource_length, struct acpi_resource *resource) | ||
384 | { | ||
385 | ACPI_FUNCTION_TRACE("rs_get_end_dpf"); | ||
386 | |||
387 | /* Complete the resource header */ | ||
388 | |||
389 | resource->type = ACPI_RESOURCE_TYPE_END_DEPENDENT; | ||
390 | resource->length = (u32) ACPI_RESOURCE_LENGTH; | ||
391 | return_ACPI_STATUS(AE_OK); | ||
392 | } | 526 | } |
393 | 527 | ||
394 | /******************************************************************************* | 528 | if (((aml->irq.flags & 0x09) == 0x00) || ((aml->irq.flags & 0x09) == 0x09)) { |
395 | * | 529 | /* |
396 | * FUNCTION: acpi_rs_set_end_dpf | 530 | * Only [active_high, edge_sensitive] or [active_low, level_sensitive] |
397 | * | 531 | * polarity/trigger interrupts are allowed (ACPI spec, section |
398 | * PARAMETERS: Resource - Pointer to the resource descriptor | 532 | * "IRQ Format"), so 0x00 and 0x09 are illegal. |
399 | * Aml - Where the AML descriptor is returned | 533 | */ |
400 | * | 534 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
401 | * RETURN: Status | 535 | "Invalid interrupt polarity/trigger in resource list, %X\n", |
402 | * | 536 | aml->irq.flags)); |
403 | * DESCRIPTION: Convert an internal resource descriptor to the corresponding | 537 | return_ACPI_STATUS(AE_BAD_DATA); |
404 | * external AML resource descriptor. | ||
405 | * | ||
406 | ******************************************************************************/ | ||
407 | |||
408 | acpi_status | ||
409 | acpi_rs_set_end_dpf(struct acpi_resource *resource, union aml_resource *aml) | ||
410 | { | ||
411 | ACPI_FUNCTION_TRACE("rs_set_end_dpf"); | ||
412 | |||
413 | /* Complete the AML descriptor header */ | ||
414 | |||
415 | acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_END_DEPENDENT, | ||
416 | sizeof(struct aml_resource_end_dependent), | ||
417 | aml); | ||
418 | return_ACPI_STATUS(AE_OK); | ||
419 | } | 538 | } |
420 | 539 | ||
421 | /******************************************************************************* | 540 | resource->data.extended_irq.interrupt_count = temp8; |
422 | * | 541 | if (temp8 < 1) { |
423 | * FUNCTION: acpi_rs_get_end_tag | 542 | /* Must have at least one IRQ */ |
424 | * | ||
425 | * PARAMETERS: Aml - Pointer to the AML resource descriptor | ||
426 | * aml_resource_length - Length of the resource from the AML header | ||
427 | * Resource - Where the internal resource is returned | ||
428 | * | ||
429 | * RETURN: Status | ||
430 | * | ||
431 | * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding | ||
432 | * internal resource descriptor, simplifying bitflags and handling | ||
433 | * alignment and endian issues if necessary. | ||
434 | * | ||
435 | ******************************************************************************/ | ||
436 | |||
437 | acpi_status | ||
438 | acpi_rs_get_end_tag(union aml_resource *aml, | ||
439 | u16 aml_resource_length, struct acpi_resource *resource) | ||
440 | { | ||
441 | ACPI_FUNCTION_TRACE("rs_get_end_tag"); | ||
442 | |||
443 | /* Complete the resource header */ | ||
444 | 543 | ||
445 | resource->type = ACPI_RESOURCE_TYPE_END_TAG; | 544 | return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH); |
446 | resource->length = ACPI_RESOURCE_LENGTH; | ||
447 | return_ACPI_STATUS(AE_OK); | ||
448 | } | 545 | } |
449 | 546 | ||
450 | /******************************************************************************* | 547 | if (resource->data.dma.transfer == 0x03) { |
451 | * | 548 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
452 | * FUNCTION: acpi_rs_set_end_tag | 549 | "Invalid DMA.Transfer preference (3)\n")); |
453 | * | 550 | return_ACPI_STATUS(AE_BAD_DATA); |
454 | * PARAMETERS: Resource - Pointer to the resource descriptor | ||
455 | * Aml - Where the AML descriptor is returned | ||
456 | * | ||
457 | * RETURN: Status | ||
458 | * | ||
459 | * DESCRIPTION: Convert an internal resource descriptor to the corresponding | ||
460 | * external AML resource descriptor. | ||
461 | * | ||
462 | ******************************************************************************/ | ||
463 | |||
464 | acpi_status | ||
465 | acpi_rs_set_end_tag(struct acpi_resource *resource, union aml_resource *aml) | ||
466 | { | ||
467 | ACPI_FUNCTION_TRACE("rs_set_end_tag"); | ||
468 | |||
469 | /* | ||
470 | * Set the Checksum - zero means that the resource data is treated as if | ||
471 | * the checksum operation succeeded (ACPI Spec 1.0b Section 6.4.2.8) | ||
472 | */ | ||
473 | aml->end_tag.checksum = 0; | ||
474 | |||
475 | /* Complete the AML descriptor header */ | ||
476 | |||
477 | acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_END_TAG, | ||
478 | sizeof(struct aml_resource_end_tag), aml); | ||
479 | return_ACPI_STATUS(AE_OK); | ||
480 | } | 551 | } |
552 | #endif | ||