1 /*******************************************************************************
3 * Module Name: rsirq - Acpi_rs_irq_resource,
5 * Acpi_rs_extended_irq_resource
6 * Acpi_rs_extended_irq_stream
9 ******************************************************************************/
12 * Copyright (C) 2000, 2001 R. Byron Moore
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 #define _COMPONENT ACPI_RESOURCES
36 /*******************************************************************************
38 * FUNCTION: Acpi_rs_irq_resource
40 * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte
42 * Bytes_consumed - u32 pointer that is filled with
43 * the number of bytes consumed from
44 * the Byte_stream_buffer
45 * Output_buffer - Pointer to the user's return buffer
46 * Structure_size - u32 pointer that is filled with
47 * the number of bytes in the filled
50 * RETURN: Status AE_OK if okay, else a valid ACPI_STATUS code
52 * DESCRIPTION: Take the resource byte stream and fill out the appropriate
53 * structure pointed to by the Output_buffer. Return the
54 * number of bytes consumed from the byte stream.
56 ******************************************************************************/
59 acpi_rs_irq_resource (
60 u8
*byte_stream_buffer
,
65 u8
*buffer
= byte_stream_buffer
;
66 RESOURCE
*output_struct
= (RESOURCE
*) * output_buffer
;
71 u32 struct_size
= sizeof (IRQ_RESOURCE
) +
72 RESOURCE_LENGTH_NO_DATA
;
76 * The number of bytes consumed are contained in the descriptor
80 *bytes_consumed
= (temp8
& 0x03) + 1;
81 output_struct
->id
= irq
;
84 * Point to the 16-bits of Bytes 1 and 2
87 MOVE_UNALIGNED16_TO_16 (&temp16
, buffer
);
89 output_struct
->data
.irq
.number_of_interrupts
= 0;
91 /* Decode the IRQ bits */
93 for (i
= 0, index
= 0; index
< 16; index
++) {
94 if((temp16
>> index
) & 0x01) {
95 output_struct
->data
.irq
.interrupts
[i
] = index
;
99 output_struct
->data
.irq
.number_of_interrupts
= i
;
102 * Calculate the structure size based upon the number of interrupts
104 struct_size
+= (output_struct
->data
.irq
.number_of_interrupts
- 1) * 4;
107 * Point to Byte 3 if it is used
109 if (4 == *bytes_consumed
) {
114 * Check for HE, LL or HL
117 output_struct
->data
.irq
.edge_level
= EDGE_SENSITIVE
;
118 output_struct
->data
.irq
.active_high_low
= ACTIVE_HIGH
;
123 output_struct
->data
.irq
.edge_level
= LEVEL_SENSITIVE
;
124 output_struct
->data
.irq
.active_high_low
= ACTIVE_LOW
;
129 * Only _LL and _HE polarity/trigger interrupts
130 * are allowed (ACPI spec v1.0b ection 6.4.2.1),
131 * so an error will occur if we reach this point
133 return (AE_BAD_DATA
);
140 output_struct
->data
.irq
.shared_exclusive
= (temp8
>> 3) & 0x01;
145 * Assume Edge Sensitive, Active High, Non-Sharable
146 * per ACPI Specification
148 output_struct
->data
.irq
.edge_level
= EDGE_SENSITIVE
;
149 output_struct
->data
.irq
.active_high_low
= ACTIVE_HIGH
;
150 output_struct
->data
.irq
.shared_exclusive
= EXCLUSIVE
;
154 * Set the Length parameter
156 output_struct
->length
= struct_size
;
159 * Return the final size of the structure
161 *structure_size
= struct_size
;
167 /*******************************************************************************
169 * FUNCTION: Acpi_rs_irq_stream
171 * PARAMETERS: Linked_list - Pointer to the resource linked list
172 * Output_buffer - Pointer to the user's return buffer
173 * Bytes_consumed - u32 pointer that is filled with
174 * the number of bytes of the
177 * RETURN: Status AE_OK if okay, else a valid ACPI_STATUS code
179 * DESCRIPTION: Take the linked list resource structure and fills in the
180 * the appropriate bytes in a byte stream
182 ******************************************************************************/
186 RESOURCE
*linked_list
,
190 u8
*buffer
= *output_buffer
;
194 u8 IRQinfo_byte_needed
;
198 * The descriptor field is set based upon whether a third byte is
199 * needed to contain the IRQ Information.
201 if (EDGE_SENSITIVE
== linked_list
->data
.irq
.edge_level
&&
202 ACTIVE_HIGH
== linked_list
->data
.irq
.active_high_low
&&
203 EXCLUSIVE
== linked_list
->data
.irq
.shared_exclusive
) {
205 IRQinfo_byte_needed
= FALSE
;
209 IRQinfo_byte_needed
= TRUE
;
216 * Loop through all of the interrupts and set the mask bits
219 index
< linked_list
->data
.irq
.number_of_interrupts
;
221 temp8
= (u8
) linked_list
->data
.irq
.interrupts
[index
];
222 temp16
|= 0x1 << temp8
;
225 MOVE_UNALIGNED16_TO_16 (buffer
, &temp16
);
229 * Set the IRQ Info byte if needed.
231 if (IRQinfo_byte_needed
) {
233 temp8
= (u8
) ((linked_list
->data
.irq
.shared_exclusive
&
236 if (LEVEL_SENSITIVE
== linked_list
->data
.irq
.edge_level
&&
237 ACTIVE_LOW
== linked_list
->data
.irq
.active_high_low
) {
250 * Return the number of bytes consumed in this operation
252 *bytes_consumed
= (u32
) ((NATIVE_UINT
) buffer
-
253 (NATIVE_UINT
) *output_buffer
);
259 /*******************************************************************************
261 * FUNCTION: Acpi_rs_extended_irq_resource
263 * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte
265 * Bytes_consumed - u32 pointer that is filled with
266 * the number of bytes consumed from
267 * the Byte_stream_buffer
268 * Output_buffer - Pointer to the user's return buffer
269 * Structure_size - u32 pointer that is filled with
270 * the number of bytes in the filled
273 * RETURN: Status AE_OK if okay, else a valid ACPI_STATUS code
275 * DESCRIPTION: Take the resource byte stream and fill out the appropriate
276 * structure pointed to by the Output_buffer. Return the
277 * number of bytes consumed from the byte stream.
279 ******************************************************************************/
282 acpi_rs_extended_irq_resource (
283 u8
*byte_stream_buffer
,
288 u8
*buffer
= byte_stream_buffer
;
289 RESOURCE
*output_struct
= (RESOURCE
*) * output_buffer
;
293 u32 struct_size
= sizeof (EXTENDED_IRQ_RESOURCE
) +
294 RESOURCE_LENGTH_NO_DATA
;
298 * Point past the Descriptor to get the number of bytes consumed
301 MOVE_UNALIGNED16_TO_16 (&temp16
, buffer
);
303 *bytes_consumed
= temp16
+ 3;
304 output_struct
->id
= extended_irq
;
312 output_struct
->data
.extended_irq
.producer_consumer
= temp8
& 0x01;
315 * Check for HE, LL or HL
318 output_struct
->data
.extended_irq
.edge_level
= EDGE_SENSITIVE
;
319 output_struct
->data
.extended_irq
.active_high_low
= ACTIVE_HIGH
;
324 output_struct
->data
.extended_irq
.edge_level
= LEVEL_SENSITIVE
;
325 output_struct
->data
.extended_irq
.active_high_low
= ACTIVE_LOW
;
330 * Only _LL and _HE polarity/trigger interrupts
331 * are allowed (ACPI spec v1.0b ection 6.4.2.1),
332 * so an error will occur if we reach this point
334 return (AE_BAD_DATA
);
341 output_struct
->data
.extended_irq
.shared_exclusive
=
345 * Point to Byte4 (IRQ Table length)
350 output_struct
->data
.extended_irq
.number_of_interrupts
= temp8
;
353 * Add any additional structure size to properly calculate
354 * the next pointer at the end of this function
356 struct_size
+= (temp8
- 1) * 4;
359 * Point to Byte5 (First IRQ Number)
364 * Cycle through every IRQ in the table
366 for (index
= 0; index
< temp8
; index
++) {
367 output_struct
->data
.extended_irq
.interrupts
[index
] =
370 /* Point to the next IRQ */
376 * This will leave us pointing to the Resource Source Index
377 * If it is present, then save it off and calculate the
378 * pointer to where the null terminated string goes:
379 * Each Interrupt takes 32-bits + the 5 bytes of the
380 * stream that are default.
382 if (*bytes_consumed
>
383 (u32
)(output_struct
->data
.extended_irq
.number_of_interrupts
*
385 /* Dereference the Index */
388 output_struct
->data
.extended_irq
.resource_source_index
=
391 /* Point to the String */
395 /* Copy the string into the buffer */
399 while (0x00 != *buffer
) {
400 output_struct
->data
.extended_irq
.resource_source
[index
] =
408 * Add the terminating null
410 output_struct
->data
.extended_irq
.resource_source
[index
] = 0x00;
411 output_struct
->data
.extended_irq
.resource_source_string_length
=
415 * In order for the Struct_size to fall on a 32-bit boundry,
416 * calculate the length of the string and expand the
417 * Struct_size to the next 32-bit boundry.
419 temp8
= (u8
) (index
+ 1);
420 temp8
= (u8
) ROUND_UP_TO_32_bITS (temp8
);
424 output_struct
->data
.extended_irq
.resource_source_index
= 0x00;
425 output_struct
->data
.extended_irq
.resource_source_string_length
= 0;
426 output_struct
->data
.extended_irq
.resource_source
[0] = 0x00;
430 * Set the Length parameter
432 output_struct
->length
= struct_size
;
435 * Return the final size of the structure
437 *structure_size
= struct_size
;
443 /*******************************************************************************
445 * FUNCTION: Acpi_rs_extended_irq_stream
447 * PARAMETERS: Linked_list - Pointer to the resource linked list
448 * Output_buffer - Pointer to the user's return buffer
449 * Bytes_consumed - u32 pointer that is filled with
450 * the number of bytes of the
453 * RETURN: Status AE_OK if okay, else a valid ACPI_STATUS code
455 * DESCRIPTION: Take the linked list resource structure and fills in the
456 * the appropriate bytes in a byte stream
458 ******************************************************************************/
461 acpi_rs_extended_irq_stream (
462 RESOURCE
*linked_list
,
466 u8
*buffer
= *output_buffer
;
470 NATIVE_CHAR
*temp_pointer
= NULL
;
474 * The descriptor field is static
480 * Set a pointer to the Length field - to be filled in later
483 length_field
= (u16
*)buffer
;
487 * Set the Interrupt vector flags
489 temp8
= (u8
)(linked_list
->data
.extended_irq
.producer_consumer
& 0x01);
491 temp8
|= ((linked_list
->data
.extended_irq
.shared_exclusive
& 0x01) << 3);
493 if (LEVEL_SENSITIVE
== linked_list
->data
.extended_irq
.edge_level
&&
494 ACTIVE_LOW
== linked_list
->data
.extended_irq
.active_high_low
) {
505 * Set the Interrupt table length
507 temp8
= (u8
) linked_list
->data
.extended_irq
.number_of_interrupts
;
513 index
< linked_list
->data
.extended_irq
.number_of_interrupts
;
515 MOVE_UNALIGNED32_TO_32 (buffer
,
516 &linked_list
->data
.extended_irq
.interrupts
[index
]);
521 * Resource Source Index and Resource Source are optional
523 if (0 != linked_list
->data
.extended_irq
.resource_source_string_length
) {
524 *buffer
= (u8
) linked_list
->data
.extended_irq
.resource_source_index
;
527 temp_pointer
= (NATIVE_CHAR
*) buffer
;
532 STRCPY (temp_pointer
, linked_list
->data
.extended_irq
.resource_source
);
535 * Buffer needs to be set to the length of the sting + one for the
538 buffer
+= (STRLEN (linked_list
->data
.extended_irq
.resource_source
) + 1);
542 * Return the number of bytes consumed in this operation
544 *bytes_consumed
= (u32
) ((NATIVE_UINT
) buffer
-
545 (NATIVE_UINT
) *output_buffer
);
548 * Set the length field to the number of bytes consumed
549 * minus the header size (3 bytes)
551 *length_field
= (u16
) (*bytes_consumed
- 3);