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 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
33 #define _COMPONENT RESOURCE_MANAGER
37 /*******************************************************************************
39 * FUNCTION: Acpi_rs_irq_resource
41 * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte
43 * Bytes_consumed - u32 pointer that is filled with
44 * the number of bytes consumed from
45 * the Byte_stream_buffer
46 * Output_buffer - Pointer to the user's return buffer
47 * Structure_size - u32 pointer that is filled with
48 * the number of bytes in the filled
51 * RETURN: Status AE_OK if okay, else a valid ACPI_STATUS code
53 * DESCRIPTION: Take the resource byte stream and fill out the appropriate
54 * structure pointed to by the Output_buffer. Return the
55 * number of bytes consumed from the byte stream.
57 ******************************************************************************/
60 acpi_rs_irq_resource (
61 u8
*byte_stream_buffer
,
66 u8
*buffer
= byte_stream_buffer
;
67 RESOURCE
*output_struct
= (RESOURCE
*) * output_buffer
;
72 u32 struct_size
= sizeof (IRQ_RESOURCE
) +
73 RESOURCE_LENGTH_NO_DATA
;
77 * The number of bytes consumed are contained in the descriptor
81 *bytes_consumed
= (temp8
& 0x03) + 1;
82 output_struct
->id
= irq
;
85 * Point to the 16-bits of Bytes 1 and 2
88 MOVE_UNALIGNED16_TO_16 (&temp16
, buffer
);
90 output_struct
->data
.irq
.number_of_interrupts
= 0;
92 /* Decode the IRQ bits */
94 for (i
= 0, index
= 0; index
< 16; index
++) {
95 if((temp16
>> index
) & 0x01) {
96 output_struct
->data
.irq
.interrupts
[i
] = index
;
100 output_struct
->data
.irq
.number_of_interrupts
= i
;
103 * Calculate the structure size based upon the number of interrupts
105 struct_size
+= (output_struct
->data
.irq
.number_of_interrupts
- 1) * 4;
108 * Point to Byte 3 if it is used
110 if (4 == *bytes_consumed
) {
115 * Check for HE, LL or HL
118 output_struct
->data
.irq
.edge_level
= EDGE_SENSITIVE
;
119 output_struct
->data
.irq
.active_high_low
= ACTIVE_HIGH
;
124 output_struct
->data
.irq
.edge_level
= LEVEL_SENSITIVE
;
125 output_struct
->data
.irq
.active_high_low
= ACTIVE_LOW
;
130 * Only _LL and _HE polarity/trigger interrupts
131 * are allowed (ACPI spec v1.0b ection 6.4.2.1),
132 * so an error will occur if we reach this point
134 return (AE_BAD_DATA
);
141 output_struct
->data
.irq
.shared_exclusive
= (temp8
>> 3) & 0x01;
146 * Assume Edge Sensitive, Active High, Non-Sharable
147 * per ACPI Specification
149 output_struct
->data
.irq
.edge_level
= EDGE_SENSITIVE
;
150 output_struct
->data
.irq
.active_high_low
= ACTIVE_HIGH
;
151 output_struct
->data
.irq
.shared_exclusive
= EXCLUSIVE
;
155 * Set the Length parameter
157 output_struct
->length
= struct_size
;
160 * Return the final size of the structure
162 *structure_size
= struct_size
;
168 /*******************************************************************************
170 * FUNCTION: Acpi_rs_irq_stream
172 * PARAMETERS: Linked_list - Pointer to the resource linked list
173 * Output_buffer - Pointer to the user's return buffer
174 * Bytes_consumed - u32 pointer that is filled with
175 * the number of bytes of the
178 * RETURN: Status AE_OK if okay, else a valid ACPI_STATUS code
180 * DESCRIPTION: Take the linked list resource structure and fills in the
181 * the appropriate bytes in a byte stream
183 ******************************************************************************/
187 RESOURCE
*linked_list
,
191 u8
*buffer
= *output_buffer
;
195 u8 IRQinfo_byte_needed
;
199 * The descriptor field is set based upon whether a third byte is
200 * needed to contain the IRQ Information.
202 if (EDGE_SENSITIVE
== linked_list
->data
.irq
.edge_level
&&
203 ACTIVE_HIGH
== linked_list
->data
.irq
.active_high_low
&&
204 EXCLUSIVE
== linked_list
->data
.irq
.shared_exclusive
)
207 IRQinfo_byte_needed
= FALSE
;
211 IRQinfo_byte_needed
= TRUE
;
218 * Loop through all of the interrupts and set the mask bits
221 index
< linked_list
->data
.irq
.number_of_interrupts
;
224 temp8
= (u8
) linked_list
->data
.irq
.interrupts
[index
];
225 temp16
|= 0x1 << temp8
;
228 MOVE_UNALIGNED16_TO_16 (buffer
, &temp16
);
232 * Set the IRQ Info byte if needed.
234 if (IRQinfo_byte_needed
) {
236 temp8
= (u8
) ((linked_list
->data
.irq
.shared_exclusive
&
239 if (LEVEL_SENSITIVE
== linked_list
->data
.irq
.edge_level
&&
240 ACTIVE_LOW
== linked_list
->data
.irq
.active_high_low
)
254 * Return the number of bytes consumed in this operation
256 *bytes_consumed
= (u32
) ((NATIVE_UINT
) buffer
-
257 (NATIVE_UINT
) *output_buffer
);
263 /*******************************************************************************
265 * FUNCTION: Acpi_rs_extended_irq_resource
267 * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte
269 * Bytes_consumed - u32 pointer that is filled with
270 * the number of bytes consumed from
271 * the Byte_stream_buffer
272 * Output_buffer - Pointer to the user's return buffer
273 * Structure_size - u32 pointer that is filled with
274 * the number of bytes in the filled
277 * RETURN: Status AE_OK if okay, else a valid ACPI_STATUS code
279 * DESCRIPTION: Take the resource byte stream and fill out the appropriate
280 * structure pointed to by the Output_buffer. Return the
281 * number of bytes consumed from the byte stream.
283 ******************************************************************************/
286 acpi_rs_extended_irq_resource (
287 u8
*byte_stream_buffer
,
292 u8
*buffer
= byte_stream_buffer
;
293 RESOURCE
*output_struct
= (RESOURCE
*) * output_buffer
;
297 u32 struct_size
= sizeof (EXTENDED_IRQ_RESOURCE
) +
298 RESOURCE_LENGTH_NO_DATA
;
302 * Point past the Descriptor to get the number of bytes consumed
305 MOVE_UNALIGNED16_TO_16 (&temp16
, buffer
);
307 *bytes_consumed
= temp16
+ 3;
308 output_struct
->id
= extended_irq
;
316 output_struct
->data
.extended_irq
.producer_consumer
= temp8
& 0x01;
319 * Check for HE, LL or HL
322 output_struct
->data
.extended_irq
.edge_level
= EDGE_SENSITIVE
;
323 output_struct
->data
.extended_irq
.active_high_low
= ACTIVE_HIGH
;
328 output_struct
->data
.extended_irq
.edge_level
= LEVEL_SENSITIVE
;
329 output_struct
->data
.extended_irq
.active_high_low
= ACTIVE_LOW
;
334 * Only _LL and _HE polarity/trigger interrupts
335 * are allowed (ACPI spec v1.0b ection 6.4.2.1),
336 * so an error will occur if we reach this point
338 return (AE_BAD_DATA
);
345 output_struct
->data
.extended_irq
.shared_exclusive
=
349 * Point to Byte4 (IRQ Table length)
354 output_struct
->data
.extended_irq
.number_of_interrupts
= temp8
;
357 * Add any additional structure size to properly calculate
358 * the next pointer at the end of this function
360 struct_size
+= (temp8
- 1) * 4;
363 * Point to Byte5 (First IRQ Number)
368 * Cycle through every IRQ in the table
370 for (index
= 0; index
< temp8
; index
++) {
371 output_struct
->data
.extended_irq
.interrupts
[index
] =
374 /* Point to the next IRQ */
380 * This will leave us pointing to the Resource Source Index
381 * If it is present, then save it off and calculate the
382 * pointer to where the null terminated string goes:
383 * Each Interrupt takes 32-bits + the 5 bytes of the
384 * stream that are default.
386 if (*bytes_consumed
>
387 (u32
)(output_struct
->data
.extended_irq
.number_of_interrupts
*
390 /* Dereference the Index */
393 output_struct
->data
.extended_irq
.resource_source_index
=
396 /* Point to the String */
400 /* Copy the string into the buffer */
404 while (0x00 != *buffer
) {
405 output_struct
->data
.extended_irq
.resource_source
[index
] =
413 * Add the terminating null
415 output_struct
->data
.extended_irq
.resource_source
[index
] = 0x00;
416 output_struct
->data
.extended_irq
.resource_source_string_length
=
420 * In order for the Struct_size to fall on a 32-bit boundry,
421 * calculate the length of the string and expand the
422 * Struct_size to the next 32-bit boundry.
424 temp8
= (u8
) (index
+ 1);
425 temp8
= (u8
) ROUND_UP_TO_32_bITS (temp8
);
429 output_struct
->data
.extended_irq
.resource_source_index
= 0x00;
430 output_struct
->data
.extended_irq
.resource_source_string_length
= 0;
431 output_struct
->data
.extended_irq
.resource_source
[0] = 0x00;
435 * Set the Length parameter
437 output_struct
->length
= struct_size
;
440 * Return the final size of the structure
442 *structure_size
= struct_size
;
448 /*******************************************************************************
450 * FUNCTION: Acpi_rs_extended_irq_stream
452 * PARAMETERS: Linked_list - Pointer to the resource linked list
453 * Output_buffer - Pointer to the user's return buffer
454 * Bytes_consumed - u32 pointer that is filled with
455 * the number of bytes of the
458 * RETURN: Status AE_OK if okay, else a valid ACPI_STATUS code
460 * DESCRIPTION: Take the linked list resource structure and fills in the
461 * the appropriate bytes in a byte stream
463 ******************************************************************************/
466 acpi_rs_extended_irq_stream (
467 RESOURCE
*linked_list
,
471 u8
*buffer
= *output_buffer
;
475 NATIVE_CHAR
*temp_pointer
= NULL
;
479 * The descriptor field is static
485 * Set a pointer to the Length field - to be filled in later
488 length_field
= (u16
*)buffer
;
492 * Set the Interrupt vector flags
494 temp8
= (u8
)(linked_list
->data
.extended_irq
.producer_consumer
& 0x01);
496 temp8
|= ((linked_list
->data
.extended_irq
.shared_exclusive
& 0x01) << 3);
498 if (LEVEL_SENSITIVE
== linked_list
->data
.extended_irq
.edge_level
&&
499 ACTIVE_LOW
== linked_list
->data
.extended_irq
.active_high_low
)
511 * Set the Interrupt table length
513 temp8
= (u8
) linked_list
->data
.extended_irq
.number_of_interrupts
;
519 index
< linked_list
->data
.extended_irq
.number_of_interrupts
;
522 MOVE_UNALIGNED32_TO_32 (buffer
,
523 &linked_list
->data
.extended_irq
.interrupts
[index
]);
528 * Resource Source Index and Resource Source are optional
530 if (0 != linked_list
->data
.extended_irq
.resource_source_string_length
) {
531 *buffer
= (u8
) linked_list
->data
.extended_irq
.resource_source_index
;
534 temp_pointer
= (NATIVE_CHAR
*) buffer
;
539 STRCPY (temp_pointer
, linked_list
->data
.extended_irq
.resource_source
);
542 * Buffer needs to be set to the length of the sting + one for the
545 buffer
+= (STRLEN (linked_list
->data
.extended_irq
.resource_source
) + 1);
549 * Return the number of bytes consumed in this operation
551 *bytes_consumed
= (u32
) ((NATIVE_UINT
) buffer
-
552 (NATIVE_UINT
) *output_buffer
);
555 * Set the length field to the number of bytes consumed
556 * minus the header size (3 bytes)
558 *length_field
= (u16
) (*bytes_consumed
- 3);