diff options
Diffstat (limited to 'drivers/acpi/resources/rsirq.c')
-rw-r--r-- | drivers/acpi/resources/rsirq.c | 568 |
1 files changed, 123 insertions, 445 deletions
diff --git a/drivers/acpi/resources/rsirq.c b/drivers/acpi/resources/rsirq.c index 56043fee96cb..1fa63bc2e36f 100644 --- a/drivers/acpi/resources/rsirq.c +++ b/drivers/acpi/resources/rsirq.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2005, R. Byron Moore | 8 | * Copyright (C) 2000 - 2006, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -49,504 +49,182 @@ ACPI_MODULE_NAME("rsirq") | |||
49 | 49 | ||
50 | /******************************************************************************* | 50 | /******************************************************************************* |
51 | * | 51 | * |
52 | * FUNCTION: acpi_rs_irq_resource | 52 | * acpi_rs_get_irq |
53 | * | ||
54 | * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte | ||
55 | * stream | ||
56 | * bytes_consumed - Pointer to where the number of bytes | ||
57 | * consumed the byte_stream_buffer is | ||
58 | * returned | ||
59 | * output_buffer - Pointer to the return data buffer | ||
60 | * structure_size - Pointer to where the number of bytes | ||
61 | * in the return data struct is returned | ||
62 | * | ||
63 | * RETURN: Status | ||
64 | * | ||
65 | * DESCRIPTION: Take the resource byte stream and fill out the appropriate | ||
66 | * structure pointed to by the output_buffer. Return the | ||
67 | * number of bytes consumed from the byte stream. | ||
68 | * | 53 | * |
69 | ******************************************************************************/ | 54 | ******************************************************************************/ |
70 | acpi_status | 55 | struct acpi_rsconvert_info acpi_rs_get_irq[7] = { |
71 | acpi_rs_irq_resource(u8 * byte_stream_buffer, | 56 | {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_IRQ, |
72 | acpi_size * bytes_consumed, | 57 | ACPI_RS_SIZE(struct acpi_resource_irq), |
73 | u8 ** output_buffer, acpi_size * structure_size) | 58 | ACPI_RSC_TABLE_SIZE(acpi_rs_get_irq)}, |
74 | { | ||
75 | u8 *buffer = byte_stream_buffer; | ||
76 | struct acpi_resource *output_struct = (void *)*output_buffer; | ||
77 | u16 temp16 = 0; | ||
78 | u8 temp8 = 0; | ||
79 | u8 index; | ||
80 | u8 i; | ||
81 | acpi_size struct_size = ACPI_SIZEOF_RESOURCE(struct acpi_resource_irq); | ||
82 | |||
83 | ACPI_FUNCTION_TRACE("rs_irq_resource"); | ||
84 | |||
85 | /* | ||
86 | * The number of bytes consumed are contained in the descriptor | ||
87 | * (Bits:0-1) | ||
88 | */ | ||
89 | temp8 = *buffer; | ||
90 | *bytes_consumed = (temp8 & 0x03) + 1; | ||
91 | output_struct->id = ACPI_RSTYPE_IRQ; | ||
92 | |||
93 | /* Point to the 16-bits of Bytes 1 and 2 */ | ||
94 | |||
95 | buffer += 1; | ||
96 | ACPI_MOVE_16_TO_16(&temp16, buffer); | ||
97 | |||
98 | output_struct->data.irq.number_of_interrupts = 0; | ||
99 | |||
100 | /* Decode the IRQ bits */ | ||
101 | |||
102 | for (i = 0, index = 0; index < 16; index++) { | ||
103 | if ((temp16 >> index) & 0x01) { | ||
104 | output_struct->data.irq.interrupts[i] = index; | ||
105 | i++; | ||
106 | } | ||
107 | } | ||
108 | 59 | ||
109 | /* Zero interrupts is valid */ | 60 | /* Get the IRQ mask (bytes 1:2) */ |
110 | 61 | ||
111 | output_struct->data.irq.number_of_interrupts = i; | 62 | {ACPI_RSC_BITMASK16, ACPI_RS_OFFSET(data.irq.interrupts[0]), |
112 | if (i > 0) { | 63 | AML_OFFSET(irq.irq_mask), |
113 | /* Calculate the structure size based upon the number of interrupts */ | 64 | ACPI_RS_OFFSET(data.irq.interrupt_count)}, |
114 | 65 | ||
115 | struct_size += ((acpi_size) i - 1) * 4; | 66 | /* Set default flags (others are zero) */ |
116 | } | ||
117 | 67 | ||
118 | /* Point to Byte 3 if it is used */ | 68 | {ACPI_RSC_SET8, ACPI_RS_OFFSET(data.irq.triggering), |
69 | ACPI_EDGE_SENSITIVE, | ||
70 | 1}, | ||
119 | 71 | ||
120 | if (4 == *bytes_consumed) { | 72 | /* All done if no flag byte present in descriptor */ |
121 | buffer += 2; | ||
122 | temp8 = *buffer; | ||
123 | 73 | ||
124 | /* Check for HE, LL interrupts */ | 74 | {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_AML_LENGTH, 0, 3}, |
125 | 75 | ||
126 | switch (temp8 & 0x09) { | 76 | /* Get flags: Triggering[0], Polarity[3], Sharing[4] */ |
127 | case 0x01: /* HE */ | ||
128 | output_struct->data.irq.edge_level = | ||
129 | ACPI_EDGE_SENSITIVE; | ||
130 | output_struct->data.irq.active_high_low = | ||
131 | ACPI_ACTIVE_HIGH; | ||
132 | break; | ||
133 | 77 | ||
134 | case 0x08: /* LL */ | 78 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.triggering), |
135 | output_struct->data.irq.edge_level = | 79 | AML_OFFSET(irq.flags), |
136 | ACPI_LEVEL_SENSITIVE; | 80 | 0}, |
137 | output_struct->data.irq.active_high_low = | ||
138 | ACPI_ACTIVE_LOW; | ||
139 | break; | ||
140 | 81 | ||
141 | default: | 82 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.polarity), |
142 | /* | 83 | AML_OFFSET(irq.flags), |
143 | * Only _LL and _HE polarity/trigger interrupts | 84 | 3}, |
144 | * are allowed (ACPI spec, section "IRQ Format") | ||
145 | * so 0x00 and 0x09 are illegal. | ||
146 | */ | ||
147 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
148 | "Invalid interrupt polarity/trigger in resource list, %X\n", | ||
149 | temp8)); | ||
150 | return_ACPI_STATUS(AE_BAD_DATA); | ||
151 | } | ||
152 | 85 | ||
153 | /* Check for sharable */ | 86 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.sharable), |
154 | 87 | AML_OFFSET(irq.flags), | |
155 | output_struct->data.irq.shared_exclusive = (temp8 >> 3) & 0x01; | 88 | 4} |
156 | } else { | 89 | }; |
157 | /* | ||
158 | * Assume Edge Sensitive, Active High, Non-Sharable | ||
159 | * per ACPI Specification | ||
160 | */ | ||
161 | output_struct->data.irq.edge_level = ACPI_EDGE_SENSITIVE; | ||
162 | output_struct->data.irq.active_high_low = ACPI_ACTIVE_HIGH; | ||
163 | output_struct->data.irq.shared_exclusive = ACPI_EXCLUSIVE; | ||
164 | } | ||
165 | |||
166 | /* Set the Length parameter */ | ||
167 | |||
168 | output_struct->length = (u32) struct_size; | ||
169 | |||
170 | /* Return the final size of the structure */ | ||
171 | |||
172 | *structure_size = struct_size; | ||
173 | return_ACPI_STATUS(AE_OK); | ||
174 | } | ||
175 | 90 | ||
176 | /******************************************************************************* | 91 | /******************************************************************************* |
177 | * | 92 | * |
178 | * FUNCTION: acpi_rs_irq_stream | 93 | * acpi_rs_set_irq |
179 | * | ||
180 | * PARAMETERS: linked_list - Pointer to the resource linked list | ||
181 | * output_buffer - Pointer to the user's return buffer | ||
182 | * bytes_consumed - Pointer to where the number of bytes | ||
183 | * used in the output_buffer is returned | ||
184 | * | ||
185 | * RETURN: Status | ||
186 | * | ||
187 | * DESCRIPTION: Take the linked list resource structure and fills in the | ||
188 | * the appropriate bytes in a byte stream | ||
189 | * | 94 | * |
190 | ******************************************************************************/ | 95 | ******************************************************************************/ |
191 | 96 | ||
192 | acpi_status | 97 | struct acpi_rsconvert_info acpi_rs_set_irq[9] = { |
193 | acpi_rs_irq_stream(struct acpi_resource *linked_list, | 98 | {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_IRQ, |
194 | u8 ** output_buffer, acpi_size * bytes_consumed) | 99 | sizeof(struct aml_resource_irq), |
195 | { | 100 | ACPI_RSC_TABLE_SIZE(acpi_rs_set_irq)}, |
196 | u8 *buffer = *output_buffer; | ||
197 | u16 temp16 = 0; | ||
198 | u8 temp8 = 0; | ||
199 | u8 index; | ||
200 | u8 IRqinfo_byte_needed; | ||
201 | |||
202 | ACPI_FUNCTION_TRACE("rs_irq_stream"); | ||
203 | |||
204 | /* | ||
205 | * The descriptor field is set based upon whether a third byte is | ||
206 | * needed to contain the IRQ Information. | ||
207 | */ | ||
208 | if (ACPI_EDGE_SENSITIVE == linked_list->data.irq.edge_level && | ||
209 | ACPI_ACTIVE_HIGH == linked_list->data.irq.active_high_low && | ||
210 | ACPI_EXCLUSIVE == linked_list->data.irq.shared_exclusive) { | ||
211 | *buffer = 0x22; | ||
212 | IRqinfo_byte_needed = FALSE; | ||
213 | } else { | ||
214 | *buffer = 0x23; | ||
215 | IRqinfo_byte_needed = TRUE; | ||
216 | } | ||
217 | |||
218 | buffer += 1; | ||
219 | temp16 = 0; | ||
220 | |||
221 | /* Loop through all of the interrupts and set the mask bits */ | ||
222 | |||
223 | for (index = 0; | ||
224 | index < linked_list->data.irq.number_of_interrupts; index++) { | ||
225 | temp8 = (u8) linked_list->data.irq.interrupts[index]; | ||
226 | temp16 |= 0x1 << temp8; | ||
227 | } | ||
228 | |||
229 | ACPI_MOVE_16_TO_16(buffer, &temp16); | ||
230 | buffer += 2; | ||
231 | |||
232 | /* Set the IRQ Info byte if needed. */ | ||
233 | |||
234 | if (IRqinfo_byte_needed) { | ||
235 | temp8 = 0; | ||
236 | temp8 = (u8) ((linked_list->data.irq.shared_exclusive & | ||
237 | 0x01) << 4); | ||
238 | |||
239 | if (ACPI_LEVEL_SENSITIVE == linked_list->data.irq.edge_level && | ||
240 | ACPI_ACTIVE_LOW == linked_list->data.irq.active_high_low) { | ||
241 | temp8 |= 0x08; | ||
242 | } else { | ||
243 | temp8 |= 0x01; | ||
244 | } | ||
245 | |||
246 | *buffer = temp8; | ||
247 | buffer += 1; | ||
248 | } | ||
249 | |||
250 | /* Return the number of bytes consumed in this operation */ | ||
251 | |||
252 | *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); | ||
253 | return_ACPI_STATUS(AE_OK); | ||
254 | } | ||
255 | |||
256 | /******************************************************************************* | ||
257 | * | ||
258 | * FUNCTION: acpi_rs_extended_irq_resource | ||
259 | * | ||
260 | * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte | ||
261 | * stream | ||
262 | * bytes_consumed - Pointer to where the number of bytes | ||
263 | * consumed the byte_stream_buffer is | ||
264 | * returned | ||
265 | * output_buffer - Pointer to the return data buffer | ||
266 | * structure_size - Pointer to where the number of bytes | ||
267 | * in the return data struct is returned | ||
268 | * | ||
269 | * RETURN: Status | ||
270 | * | ||
271 | * DESCRIPTION: Take the resource byte stream and fill out the appropriate | ||
272 | * structure pointed to by the output_buffer. Return the | ||
273 | * number of bytes consumed from the byte stream. | ||
274 | * | ||
275 | ******************************************************************************/ | ||
276 | |||
277 | acpi_status | ||
278 | acpi_rs_extended_irq_resource(u8 * byte_stream_buffer, | ||
279 | acpi_size * bytes_consumed, | ||
280 | u8 ** output_buffer, acpi_size * structure_size) | ||
281 | { | ||
282 | u8 *buffer = byte_stream_buffer; | ||
283 | struct acpi_resource *output_struct = (void *)*output_buffer; | ||
284 | u16 temp16 = 0; | ||
285 | u8 temp8 = 0; | ||
286 | u8 *temp_ptr; | ||
287 | u8 index; | ||
288 | acpi_size struct_size = | ||
289 | ACPI_SIZEOF_RESOURCE(struct acpi_resource_ext_irq); | ||
290 | |||
291 | ACPI_FUNCTION_TRACE("rs_extended_irq_resource"); | ||
292 | |||
293 | /* Get the Descriptor Length field */ | ||
294 | |||
295 | buffer += 1; | ||
296 | ACPI_MOVE_16_TO_16(&temp16, buffer); | ||
297 | |||
298 | /* Validate minimum descriptor length */ | ||
299 | |||
300 | if (temp16 < 6) { | ||
301 | return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH); | ||
302 | } | ||
303 | |||
304 | *bytes_consumed = temp16 + 3; | ||
305 | output_struct->id = ACPI_RSTYPE_EXT_IRQ; | ||
306 | |||
307 | /* Point to the Byte3 */ | ||
308 | |||
309 | buffer += 2; | ||
310 | temp8 = *buffer; | ||
311 | |||
312 | output_struct->data.extended_irq.producer_consumer = temp8 & 0x01; | ||
313 | 101 | ||
314 | /* | 102 | /* Convert interrupt list to 16-bit IRQ bitmask */ |
315 | * Check for Interrupt Mode | ||
316 | * | ||
317 | * The definition of an Extended IRQ changed between ACPI spec v1.0b | ||
318 | * and ACPI spec 2.0 (section 6.4.3.6 in both). | ||
319 | * | ||
320 | * - Edge/Level are defined opposite in the table vs the headers | ||
321 | */ | ||
322 | output_struct->data.extended_irq.edge_level = | ||
323 | (temp8 & 0x2) ? ACPI_EDGE_SENSITIVE : ACPI_LEVEL_SENSITIVE; | ||
324 | |||
325 | /* Check Interrupt Polarity */ | ||
326 | |||
327 | output_struct->data.extended_irq.active_high_low = (temp8 >> 2) & 0x1; | ||
328 | |||
329 | /* Check for sharable */ | ||
330 | |||
331 | output_struct->data.extended_irq.shared_exclusive = (temp8 >> 3) & 0x01; | ||
332 | 103 | ||
333 | /* Point to Byte4 (IRQ Table length) */ | 104 | {ACPI_RSC_BITMASK16, ACPI_RS_OFFSET(data.irq.interrupts[0]), |
105 | AML_OFFSET(irq.irq_mask), | ||
106 | ACPI_RS_OFFSET(data.irq.interrupt_count)}, | ||
334 | 107 | ||
335 | buffer += 1; | 108 | /* Set the flags byte by default */ |
336 | temp8 = *buffer; | ||
337 | 109 | ||
338 | /* Must have at least one IRQ */ | 110 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.triggering), |
111 | AML_OFFSET(irq.flags), | ||
112 | 0}, | ||
339 | 113 | ||
340 | if (temp8 < 1) { | 114 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.polarity), |
341 | return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH); | 115 | AML_OFFSET(irq.flags), |
342 | } | 116 | 3}, |
343 | |||
344 | output_struct->data.extended_irq.number_of_interrupts = temp8; | ||
345 | 117 | ||
118 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.sharable), | ||
119 | AML_OFFSET(irq.flags), | ||
120 | 4}, | ||
346 | /* | 121 | /* |
347 | * Add any additional structure size to properly calculate | 122 | * Check if the flags byte is necessary. Not needed if the flags are: |
348 | * the next pointer at the end of this function | 123 | * ACPI_EDGE_SENSITIVE, ACPI_ACTIVE_HIGH, ACPI_EXCLUSIVE |
349 | */ | 124 | */ |
350 | struct_size += (temp8 - 1) * 4; | 125 | {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_VALUE, |
351 | 126 | ACPI_RS_OFFSET(data.irq.triggering), | |
352 | /* Point to Byte5 (First IRQ Number) */ | 127 | ACPI_EDGE_SENSITIVE}, |
353 | |||
354 | buffer += 1; | ||
355 | |||
356 | /* Cycle through every IRQ in the table */ | ||
357 | |||
358 | for (index = 0; index < temp8; index++) { | ||
359 | ACPI_MOVE_32_TO_32(&output_struct->data.extended_irq. | ||
360 | interrupts[index], buffer); | ||
361 | |||
362 | /* Point to the next IRQ */ | ||
363 | |||
364 | buffer += 4; | ||
365 | } | ||
366 | |||
367 | /* | ||
368 | * This will leave us pointing to the Resource Source Index | ||
369 | * If it is present, then save it off and calculate the | ||
370 | * pointer to where the null terminated string goes: | ||
371 | * Each Interrupt takes 32-bits + the 5 bytes of the | ||
372 | * stream that are default. | ||
373 | * | ||
374 | * Note: Some resource descriptors will have an additional null, so | ||
375 | * we add 1 to the length. | ||
376 | */ | ||
377 | if (*bytes_consumed > | ||
378 | ((acpi_size) output_struct->data.extended_irq.number_of_interrupts * | ||
379 | 4) + (5 + 1)) { | ||
380 | /* Dereference the Index */ | ||
381 | |||
382 | temp8 = *buffer; | ||
383 | output_struct->data.extended_irq.resource_source.index = | ||
384 | (u32) temp8; | ||
385 | |||
386 | /* Point to the String */ | ||
387 | |||
388 | buffer += 1; | ||
389 | |||
390 | /* Point the String pointer to the end of this structure. */ | ||
391 | |||
392 | output_struct->data.extended_irq.resource_source.string_ptr = | ||
393 | (char *)((char *)output_struct + struct_size); | ||
394 | 128 | ||
395 | temp_ptr = (u8 *) | 129 | {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_VALUE, |
396 | output_struct->data.extended_irq.resource_source.string_ptr; | 130 | ACPI_RS_OFFSET(data.irq.polarity), |
131 | ACPI_ACTIVE_HIGH}, | ||
397 | 132 | ||
398 | /* Copy the string into the buffer */ | 133 | {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_VALUE, |
134 | ACPI_RS_OFFSET(data.irq.sharable), | ||
135 | ACPI_EXCLUSIVE}, | ||
399 | 136 | ||
400 | index = 0; | 137 | /* irq_no_flags() descriptor can be used */ |
401 | while (*buffer) { | ||
402 | *temp_ptr = *buffer; | ||
403 | 138 | ||
404 | temp_ptr += 1; | 139 | {ACPI_RSC_LENGTH, 0, 0, sizeof(struct aml_resource_irq_noflags)} |
405 | buffer += 1; | 140 | }; |
406 | index += 1; | ||
407 | } | ||
408 | |||
409 | /* Add the terminating null */ | ||
410 | |||
411 | *temp_ptr = 0; | ||
412 | output_struct->data.extended_irq.resource_source.string_length = | ||
413 | index + 1; | ||
414 | |||
415 | /* | ||
416 | * In order for the struct_size to fall on a 32-bit boundary, | ||
417 | * calculate the length of the string and expand the | ||
418 | * struct_size to the next 32-bit boundary. | ||
419 | */ | ||
420 | temp8 = (u8) (index + 1); | ||
421 | struct_size += ACPI_ROUND_UP_to_32_bITS(temp8); | ||
422 | } else { | ||
423 | output_struct->data.extended_irq.resource_source.index = 0; | ||
424 | output_struct->data.extended_irq.resource_source.string_length = | ||
425 | 0; | ||
426 | output_struct->data.extended_irq.resource_source.string_ptr = | ||
427 | NULL; | ||
428 | } | ||
429 | |||
430 | /* Set the Length parameter */ | ||
431 | |||
432 | output_struct->length = (u32) struct_size; | ||
433 | |||
434 | /* Return the final size of the structure */ | ||
435 | |||
436 | *structure_size = struct_size; | ||
437 | return_ACPI_STATUS(AE_OK); | ||
438 | } | ||
439 | 141 | ||
440 | /******************************************************************************* | 142 | /******************************************************************************* |
441 | * | 143 | * |
442 | * FUNCTION: acpi_rs_extended_irq_stream | 144 | * acpi_rs_convert_ext_irq |
443 | * | ||
444 | * PARAMETERS: linked_list - Pointer to the resource linked list | ||
445 | * output_buffer - Pointer to the user's return buffer | ||
446 | * bytes_consumed - Pointer to where the number of bytes | ||
447 | * used in the output_buffer is returned | ||
448 | * | ||
449 | * RETURN: Status | ||
450 | * | ||
451 | * DESCRIPTION: Take the linked list resource structure and fills in the | ||
452 | * the appropriate bytes in a byte stream | ||
453 | * | 145 | * |
454 | ******************************************************************************/ | 146 | ******************************************************************************/ |
455 | 147 | ||
456 | acpi_status | 148 | struct acpi_rsconvert_info acpi_rs_convert_ext_irq[9] = { |
457 | acpi_rs_extended_irq_stream(struct acpi_resource *linked_list, | 149 | {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_EXTENDED_IRQ, |
458 | u8 ** output_buffer, acpi_size * bytes_consumed) | 150 | ACPI_RS_SIZE(struct acpi_resource_extended_irq), |
459 | { | 151 | ACPI_RSC_TABLE_SIZE(acpi_rs_convert_ext_irq)}, |
460 | u8 *buffer = *output_buffer; | ||
461 | u16 *length_field; | ||
462 | u8 temp8 = 0; | ||
463 | u8 index; | ||
464 | 152 | ||
465 | ACPI_FUNCTION_TRACE("rs_extended_irq_stream"); | 153 | {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_EXTENDED_IRQ, |
154 | sizeof(struct aml_resource_extended_irq), | ||
155 | 0}, | ||
466 | 156 | ||
467 | /* Set the Descriptor Type field */ | 157 | /* Flag bits */ |
468 | 158 | ||
469 | *buffer = ACPI_RDESC_TYPE_EXTENDED_XRUPT; | 159 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.extended_irq.producer_consumer), |
470 | buffer += 1; | 160 | AML_OFFSET(extended_irq.flags), |
161 | 0}, | ||
471 | 162 | ||
472 | /* Save a pointer to the Length field - to be filled in later */ | 163 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.extended_irq.triggering), |
164 | AML_OFFSET(extended_irq.flags), | ||
165 | 1}, | ||
473 | 166 | ||
474 | length_field = ACPI_CAST_PTR(u16, buffer); | 167 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.extended_irq.polarity), |
475 | buffer += 2; | 168 | AML_OFFSET(extended_irq.flags), |
169 | 2}, | ||
476 | 170 | ||
477 | /* Set the Interrupt vector flags */ | 171 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.extended_irq.sharable), |
172 | AML_OFFSET(extended_irq.flags), | ||
173 | 3}, | ||
478 | 174 | ||
479 | temp8 = (u8) (linked_list->data.extended_irq.producer_consumer & 0x01); | 175 | /* IRQ Table length (Byte4) */ |
480 | temp8 |= | ||
481 | ((linked_list->data.extended_irq.shared_exclusive & 0x01) << 3); | ||
482 | 176 | ||
483 | /* | 177 | {ACPI_RSC_COUNT, ACPI_RS_OFFSET(data.extended_irq.interrupt_count), |
484 | * Set the Interrupt Mode | 178 | AML_OFFSET(extended_irq.interrupt_count), |
485 | * | 179 | sizeof(u32)} |
486 | * The definition of an Extended IRQ changed between ACPI spec v1.0b | 180 | , |
487 | * and ACPI spec 2.0 (section 6.4.3.6 in both). This code does not | ||
488 | * implement the more restrictive definition of 1.0b | ||
489 | * | ||
490 | * - Edge/Level are defined opposite in the table vs the headers | ||
491 | */ | ||
492 | if (ACPI_EDGE_SENSITIVE == linked_list->data.extended_irq.edge_level) { | ||
493 | temp8 |= 0x2; | ||
494 | } | ||
495 | |||
496 | /* Set the Interrupt Polarity */ | ||
497 | 181 | ||
498 | temp8 |= ((linked_list->data.extended_irq.active_high_low & 0x1) << 2); | 182 | /* Copy every IRQ in the table, each is 32 bits */ |
499 | 183 | ||
500 | *buffer = temp8; | 184 | {ACPI_RSC_MOVE32, ACPI_RS_OFFSET(data.extended_irq.interrupts[0]), |
501 | buffer += 1; | 185 | AML_OFFSET(extended_irq.interrupts[0]), |
186 | 0} | ||
187 | , | ||
502 | 188 | ||
503 | /* Set the Interrupt table length */ | 189 | /* Optional resource_source (Index and String) */ |
504 | 190 | ||
505 | temp8 = (u8) linked_list->data.extended_irq.number_of_interrupts; | 191 | {ACPI_RSC_SOURCEX, ACPI_RS_OFFSET(data.extended_irq.resource_source), |
192 | ACPI_RS_OFFSET(data.extended_irq.interrupts[0]), | ||
193 | sizeof(struct aml_resource_extended_irq)} | ||
194 | }; | ||
506 | 195 | ||
507 | *buffer = temp8; | 196 | /******************************************************************************* |
508 | buffer += 1; | 197 | * |
509 | 198 | * acpi_rs_convert_dma | |
510 | for (index = 0; | 199 | * |
511 | index < linked_list->data.extended_irq.number_of_interrupts; | 200 | ******************************************************************************/ |
512 | index++) { | ||
513 | ACPI_MOVE_32_TO_32(buffer, | ||
514 | &linked_list->data.extended_irq. | ||
515 | interrupts[index]); | ||
516 | buffer += 4; | ||
517 | } | ||
518 | 201 | ||
519 | /* Resource Source Index and Resource Source are optional */ | 202 | struct acpi_rsconvert_info acpi_rs_convert_dma[6] = { |
203 | {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_DMA, | ||
204 | ACPI_RS_SIZE(struct acpi_resource_dma), | ||
205 | ACPI_RSC_TABLE_SIZE(acpi_rs_convert_dma)}, | ||
520 | 206 | ||
521 | if (0 != linked_list->data.extended_irq.resource_source.string_length) { | 207 | {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_DMA, |
522 | *buffer = | 208 | sizeof(struct aml_resource_dma), |
523 | (u8) linked_list->data.extended_irq.resource_source.index; | 209 | 0}, |
524 | buffer += 1; | ||
525 | 210 | ||
526 | /* Copy the string */ | 211 | /* Flags: transfer preference, bus mastering, channel speed */ |
527 | 212 | ||
528 | ACPI_STRCPY((char *)buffer, | 213 | {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.dma.transfer), |
529 | linked_list->data.extended_irq.resource_source. | 214 | AML_OFFSET(dma.flags), |
530 | string_ptr); | 215 | 0}, |
531 | 216 | ||
532 | /* | 217 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.dma.bus_master), |
533 | * Buffer needs to be set to the length of the string + one for the | 218 | AML_OFFSET(dma.flags), |
534 | * terminating null | 219 | 2}, |
535 | */ | ||
536 | buffer += | ||
537 | (acpi_size) (ACPI_STRLEN | ||
538 | (linked_list->data.extended_irq. | ||
539 | resource_source.string_ptr) + 1); | ||
540 | } | ||
541 | 220 | ||
542 | /* Return the number of bytes consumed in this operation */ | 221 | {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.dma.type), |
222 | AML_OFFSET(dma.flags), | ||
223 | 5}, | ||
543 | 224 | ||
544 | *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); | 225 | /* DMA channel mask bits */ |
545 | 226 | ||
546 | /* | 227 | {ACPI_RSC_BITMASK, ACPI_RS_OFFSET(data.dma.channels[0]), |
547 | * Set the length field to the number of bytes consumed | 228 | AML_OFFSET(dma.dma_channel_mask), |
548 | * minus the header size (3 bytes) | 229 | ACPI_RS_OFFSET(data.dma.channel_count)} |
549 | */ | 230 | }; |
550 | *length_field = (u16) (*bytes_consumed - 3); | ||
551 | return_ACPI_STATUS(AE_OK); | ||
552 | } | ||