Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /******************************************************************************* |
2 | * | |
3 | * Module Name: rsirq - IRQ resource descriptors | |
4 | * | |
5 | ******************************************************************************/ | |
6 | ||
7 | /* | |
8 | * Copyright (C) 2000 - 2005, R. Byron Moore | |
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 | ||
1da177e4 LT |
44 | #include <acpi/acpi.h> |
45 | #include <acpi/acresrc.h> | |
46 | ||
47 | #define _COMPONENT ACPI_RESOURCES | |
4be44fcd | 48 | ACPI_MODULE_NAME("rsirq") |
1da177e4 LT |
49 | |
50 | /******************************************************************************* | |
51 | * | |
52 | * FUNCTION: acpi_rs_irq_resource | |
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 | * | |
69 | ******************************************************************************/ | |
1da177e4 | 70 | acpi_status |
4be44fcd LB |
71 | acpi_rs_irq_resource(u8 * byte_stream_buffer, |
72 | acpi_size * bytes_consumed, | |
73 | u8 ** output_buffer, acpi_size * structure_size) | |
1da177e4 | 74 | { |
4be44fcd LB |
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); | |
1da177e4 | 82 | |
4be44fcd | 83 | ACPI_FUNCTION_TRACE("rs_irq_resource"); |
1da177e4 LT |
84 | |
85 | /* | |
86 | * The number of bytes consumed are contained in the descriptor | |
44f6c012 | 87 | * (Bits:0-1) |
1da177e4 LT |
88 | */ |
89 | temp8 = *buffer; | |
90 | *bytes_consumed = (temp8 & 0x03) + 1; | |
91 | output_struct->id = ACPI_RSTYPE_IRQ; | |
92 | ||
44f6c012 RM |
93 | /* Point to the 16-bits of Bytes 1 and 2 */ |
94 | ||
1da177e4 | 95 | buffer += 1; |
4be44fcd | 96 | ACPI_MOVE_16_TO_16(&temp16, buffer); |
1da177e4 LT |
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 | ||
109 | /* Zero interrupts is valid */ | |
110 | ||
111 | output_struct->data.irq.number_of_interrupts = i; | |
112 | if (i > 0) { | |
44f6c012 RM |
113 | /* Calculate the structure size based upon the number of interrupts */ |
114 | ||
1da177e4 LT |
115 | struct_size += ((acpi_size) i - 1) * 4; |
116 | } | |
117 | ||
44f6c012 RM |
118 | /* Point to Byte 3 if it is used */ |
119 | ||
1da177e4 LT |
120 | if (4 == *bytes_consumed) { |
121 | buffer += 2; | |
122 | temp8 = *buffer; | |
123 | ||
44f6c012 RM |
124 | /* Check for HE, LL interrupts */ |
125 | ||
1da177e4 | 126 | switch (temp8 & 0x09) { |
4be44fcd LB |
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; | |
1da177e4 LT |
132 | break; |
133 | ||
4be44fcd LB |
134 | case 0x08: /* LL */ |
135 | output_struct->data.irq.edge_level = | |
136 | ACPI_LEVEL_SENSITIVE; | |
137 | output_struct->data.irq.active_high_low = | |
138 | ACPI_ACTIVE_LOW; | |
1da177e4 LT |
139 | break; |
140 | ||
141 | default: | |
142 | /* | |
143 | * Only _LL and _HE polarity/trigger interrupts | |
144 | * are allowed (ACPI spec, section "IRQ Format") | |
145 | * so 0x00 and 0x09 are illegal. | |
146 | */ | |
4be44fcd LB |
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); | |
1da177e4 LT |
151 | } |
152 | ||
44f6c012 RM |
153 | /* Check for sharable */ |
154 | ||
1da177e4 | 155 | output_struct->data.irq.shared_exclusive = (temp8 >> 3) & 0x01; |
4be44fcd | 156 | } else { |
1da177e4 LT |
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 | ||
44f6c012 RM |
166 | /* Set the Length parameter */ |
167 | ||
1da177e4 LT |
168 | output_struct->length = (u32) struct_size; |
169 | ||
44f6c012 RM |
170 | /* Return the final size of the structure */ |
171 | ||
1da177e4 | 172 | *structure_size = struct_size; |
4be44fcd | 173 | return_ACPI_STATUS(AE_OK); |
1da177e4 LT |
174 | } |
175 | ||
1da177e4 LT |
176 | /******************************************************************************* |
177 | * | |
178 | * FUNCTION: acpi_rs_irq_stream | |
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 | * | |
190 | ******************************************************************************/ | |
191 | ||
192 | acpi_status | |
4be44fcd LB |
193 | acpi_rs_irq_stream(struct acpi_resource *linked_list, |
194 | u8 ** output_buffer, acpi_size * bytes_consumed) | |
1da177e4 | 195 | { |
4be44fcd LB |
196 | u8 *buffer = *output_buffer; |
197 | u16 temp16 = 0; | |
198 | u8 temp8 = 0; | |
199 | u8 index; | |
200 | u8 IRqinfo_byte_needed; | |
1da177e4 | 201 | |
4be44fcd | 202 | ACPI_FUNCTION_TRACE("rs_irq_stream"); |
1da177e4 LT |
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 && | |
4be44fcd LB |
209 | ACPI_ACTIVE_HIGH == linked_list->data.irq.active_high_low && |
210 | ACPI_EXCLUSIVE == linked_list->data.irq.shared_exclusive) { | |
1da177e4 LT |
211 | *buffer = 0x22; |
212 | IRqinfo_byte_needed = FALSE; | |
4be44fcd | 213 | } else { |
1da177e4 LT |
214 | *buffer = 0x23; |
215 | IRqinfo_byte_needed = TRUE; | |
216 | } | |
217 | ||
218 | buffer += 1; | |
219 | temp16 = 0; | |
220 | ||
44f6c012 RM |
221 | /* Loop through all of the interrupts and set the mask bits */ |
222 | ||
4be44fcd LB |
223 | for (index = 0; |
224 | index < linked_list->data.irq.number_of_interrupts; index++) { | |
1da177e4 LT |
225 | temp8 = (u8) linked_list->data.irq.interrupts[index]; |
226 | temp16 |= 0x1 << temp8; | |
227 | } | |
228 | ||
4be44fcd | 229 | ACPI_MOVE_16_TO_16(buffer, &temp16); |
1da177e4 LT |
230 | buffer += 2; |
231 | ||
44f6c012 RM |
232 | /* Set the IRQ Info byte if needed. */ |
233 | ||
1da177e4 LT |
234 | if (IRqinfo_byte_needed) { |
235 | temp8 = 0; | |
236 | temp8 = (u8) ((linked_list->data.irq.shared_exclusive & | |
4be44fcd | 237 | 0x01) << 4); |
1da177e4 LT |
238 | |
239 | if (ACPI_LEVEL_SENSITIVE == linked_list->data.irq.edge_level && | |
4be44fcd | 240 | ACPI_ACTIVE_LOW == linked_list->data.irq.active_high_low) { |
1da177e4 | 241 | temp8 |= 0x08; |
4be44fcd | 242 | } else { |
1da177e4 LT |
243 | temp8 |= 0x01; |
244 | } | |
245 | ||
246 | *buffer = temp8; | |
247 | buffer += 1; | |
248 | } | |
249 | ||
44f6c012 RM |
250 | /* Return the number of bytes consumed in this operation */ |
251 | ||
4be44fcd LB |
252 | *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); |
253 | return_ACPI_STATUS(AE_OK); | |
1da177e4 LT |
254 | } |
255 | ||
1da177e4 LT |
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 | |
4be44fcd LB |
278 | acpi_rs_extended_irq_resource(u8 * byte_stream_buffer, |
279 | acpi_size * bytes_consumed, | |
280 | u8 ** output_buffer, acpi_size * structure_size) | |
1da177e4 | 281 | { |
4be44fcd LB |
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); | |
1da177e4 | 290 | |
4be44fcd | 291 | ACPI_FUNCTION_TRACE("rs_extended_irq_resource"); |
1da177e4 | 292 | |
aff8c277 | 293 | /* Get the Descriptor Length field */ |
44f6c012 | 294 | |
1da177e4 | 295 | buffer += 1; |
4be44fcd | 296 | ACPI_MOVE_16_TO_16(&temp16, buffer); |
1da177e4 LT |
297 | |
298 | /* Validate minimum descriptor length */ | |
299 | ||
300 | if (temp16 < 6) { | |
4be44fcd | 301 | return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH); |
1da177e4 LT |
302 | } |
303 | ||
304 | *bytes_consumed = temp16 + 3; | |
305 | output_struct->id = ACPI_RSTYPE_EXT_IRQ; | |
306 | ||
44f6c012 RM |
307 | /* Point to the Byte3 */ |
308 | ||
1da177e4 LT |
309 | buffer += 2; |
310 | temp8 = *buffer; | |
311 | ||
312 | output_struct->data.extended_irq.producer_consumer = temp8 & 0x01; | |
313 | ||
314 | /* | |
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 = | |
4be44fcd | 323 | (temp8 & 0x2) ? ACPI_EDGE_SENSITIVE : ACPI_LEVEL_SENSITIVE; |
44f6c012 RM |
324 | |
325 | /* Check Interrupt Polarity */ | |
1da177e4 | 326 | |
1da177e4 LT |
327 | output_struct->data.extended_irq.active_high_low = (temp8 >> 2) & 0x1; |
328 | ||
44f6c012 RM |
329 | /* Check for sharable */ |
330 | ||
1da177e4 LT |
331 | output_struct->data.extended_irq.shared_exclusive = (temp8 >> 3) & 0x01; |
332 | ||
44f6c012 RM |
333 | /* Point to Byte4 (IRQ Table length) */ |
334 | ||
1da177e4 LT |
335 | buffer += 1; |
336 | temp8 = *buffer; | |
337 | ||
338 | /* Must have at least one IRQ */ | |
339 | ||
340 | if (temp8 < 1) { | |
4be44fcd | 341 | return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH); |
1da177e4 LT |
342 | } |
343 | ||
344 | output_struct->data.extended_irq.number_of_interrupts = temp8; | |
345 | ||
346 | /* | |
347 | * Add any additional structure size to properly calculate | |
348 | * the next pointer at the end of this function | |
349 | */ | |
350 | struct_size += (temp8 - 1) * 4; | |
351 | ||
44f6c012 RM |
352 | /* Point to Byte5 (First IRQ Number) */ |
353 | ||
1da177e4 LT |
354 | buffer += 1; |
355 | ||
44f6c012 RM |
356 | /* Cycle through every IRQ in the table */ |
357 | ||
1da177e4 | 358 | for (index = 0; index < temp8; index++) { |
4be44fcd LB |
359 | ACPI_MOVE_32_TO_32(&output_struct->data.extended_irq. |
360 | interrupts[index], buffer); | |
1da177e4 LT |
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 > | |
4be44fcd LB |
378 | ((acpi_size) output_struct->data.extended_irq.number_of_interrupts * |
379 | 4) + (5 + 1)) { | |
1da177e4 LT |
380 | /* Dereference the Index */ |
381 | ||
382 | temp8 = *buffer; | |
4be44fcd LB |
383 | output_struct->data.extended_irq.resource_source.index = |
384 | (u32) temp8; | |
1da177e4 LT |
385 | |
386 | /* Point to the String */ | |
387 | ||
388 | buffer += 1; | |
389 | ||
44f6c012 RM |
390 | /* Point the String pointer to the end of this structure. */ |
391 | ||
1da177e4 | 392 | output_struct->data.extended_irq.resource_source.string_ptr = |
4be44fcd | 393 | (char *)((char *)output_struct + struct_size); |
1da177e4 | 394 | |
44f6c012 | 395 | temp_ptr = (u8 *) |
4be44fcd | 396 | output_struct->data.extended_irq.resource_source.string_ptr; |
1da177e4 LT |
397 | |
398 | /* Copy the string into the buffer */ | |
399 | ||
400 | index = 0; | |
aff8c277 | 401 | while (*buffer) { |
1da177e4 LT |
402 | *temp_ptr = *buffer; |
403 | ||
404 | temp_ptr += 1; | |
405 | buffer += 1; | |
406 | index += 1; | |
407 | } | |
408 | ||
44f6c012 RM |
409 | /* Add the terminating null */ |
410 | ||
aff8c277 | 411 | *temp_ptr = 0; |
4be44fcd LB |
412 | output_struct->data.extended_irq.resource_source.string_length = |
413 | index + 1; | |
1da177e4 LT |
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); | |
4be44fcd LB |
421 | struct_size += ACPI_ROUND_UP_to_32_bITS(temp8); |
422 | } else { | |
aff8c277 | 423 | output_struct->data.extended_irq.resource_source.index = 0; |
4be44fcd LB |
424 | output_struct->data.extended_irq.resource_source.string_length = |
425 | 0; | |
426 | output_struct->data.extended_irq.resource_source.string_ptr = | |
427 | NULL; | |
1da177e4 LT |
428 | } |
429 | ||
44f6c012 RM |
430 | /* Set the Length parameter */ |
431 | ||
1da177e4 LT |
432 | output_struct->length = (u32) struct_size; |
433 | ||
44f6c012 RM |
434 | /* Return the final size of the structure */ |
435 | ||
1da177e4 | 436 | *structure_size = struct_size; |
4be44fcd | 437 | return_ACPI_STATUS(AE_OK); |
1da177e4 LT |
438 | } |
439 | ||
1da177e4 LT |
440 | /******************************************************************************* |
441 | * | |
442 | * FUNCTION: acpi_rs_extended_irq_stream | |
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 | * | |
454 | ******************************************************************************/ | |
455 | ||
456 | acpi_status | |
4be44fcd LB |
457 | acpi_rs_extended_irq_stream(struct acpi_resource *linked_list, |
458 | u8 ** output_buffer, acpi_size * bytes_consumed) | |
1da177e4 | 459 | { |
4be44fcd LB |
460 | u8 *buffer = *output_buffer; |
461 | u16 *length_field; | |
462 | u8 temp8 = 0; | |
463 | u8 index; | |
1da177e4 | 464 | |
4be44fcd | 465 | ACPI_FUNCTION_TRACE("rs_extended_irq_stream"); |
1da177e4 | 466 | |
aff8c277 | 467 | /* Set the Descriptor Type field */ |
44f6c012 | 468 | |
aff8c277 | 469 | *buffer = ACPI_RDESC_TYPE_EXTENDED_XRUPT; |
1da177e4 LT |
470 | buffer += 1; |
471 | ||
aff8c277 | 472 | /* Save a pointer to the Length field - to be filled in later */ |
44f6c012 | 473 | |
4be44fcd | 474 | length_field = ACPI_CAST_PTR(u16, buffer); |
1da177e4 LT |
475 | buffer += 2; |
476 | ||
44f6c012 RM |
477 | /* Set the Interrupt vector flags */ |
478 | ||
4be44fcd LB |
479 | temp8 = (u8) (linked_list->data.extended_irq.producer_consumer & 0x01); |
480 | temp8 |= | |
481 | ((linked_list->data.extended_irq.shared_exclusive & 0x01) << 3); | |
1da177e4 LT |
482 | |
483 | /* | |
484 | * Set the Interrupt Mode | |
485 | * | |
486 | * The definition of an Extended IRQ changed between ACPI spec v1.0b | |
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 | ||
44f6c012 RM |
496 | /* Set the Interrupt Polarity */ |
497 | ||
1da177e4 LT |
498 | temp8 |= ((linked_list->data.extended_irq.active_high_low & 0x1) << 2); |
499 | ||
500 | *buffer = temp8; | |
501 | buffer += 1; | |
502 | ||
44f6c012 RM |
503 | /* Set the Interrupt table length */ |
504 | ||
1da177e4 LT |
505 | temp8 = (u8) linked_list->data.extended_irq.number_of_interrupts; |
506 | ||
507 | *buffer = temp8; | |
508 | buffer += 1; | |
509 | ||
4be44fcd LB |
510 | for (index = 0; |
511 | index < linked_list->data.extended_irq.number_of_interrupts; | |
512 | index++) { | |
513 | ACPI_MOVE_32_TO_32(buffer, | |
514 | &linked_list->data.extended_irq. | |
515 | interrupts[index]); | |
1da177e4 LT |
516 | buffer += 4; |
517 | } | |
518 | ||
44f6c012 RM |
519 | /* Resource Source Index and Resource Source are optional */ |
520 | ||
1da177e4 | 521 | if (0 != linked_list->data.extended_irq.resource_source.string_length) { |
4be44fcd LB |
522 | *buffer = |
523 | (u8) linked_list->data.extended_irq.resource_source.index; | |
1da177e4 LT |
524 | buffer += 1; |
525 | ||
44f6c012 RM |
526 | /* Copy the string */ |
527 | ||
aff8c277 | 528 | ACPI_STRCPY((char *)buffer, |
4be44fcd LB |
529 | linked_list->data.extended_irq.resource_source. |
530 | string_ptr); | |
1da177e4 LT |
531 | |
532 | /* | |
aff8c277 | 533 | * Buffer needs to be set to the length of the string + one for the |
1da177e4 LT |
534 | * terminating null |
535 | */ | |
4be44fcd LB |
536 | buffer += |
537 | (acpi_size) (ACPI_STRLEN | |
538 | (linked_list->data.extended_irq. | |
539 | resource_source.string_ptr) + 1); | |
1da177e4 LT |
540 | } |
541 | ||
44f6c012 RM |
542 | /* Return the number of bytes consumed in this operation */ |
543 | ||
4be44fcd | 544 | *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); |
1da177e4 LT |
545 | |
546 | /* | |
547 | * Set the length field to the number of bytes consumed | |
548 | * minus the header size (3 bytes) | |
549 | */ | |
550 | *length_field = (u16) (*bytes_consumed - 3); | |
4be44fcd | 551 | return_ACPI_STATUS(AE_OK); |
1da177e4 | 552 | } |