1 /******************************************************************************
3 * Module Name: rsirq - Acpi_rs_irq_resource,
5 * Acpi_rs_extended_irq_resource
6 * Acpi_rs_extended_irq_stream
8 *****************************************************************************/
11 * Copyright (C) 2000 R. Byron Moore
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 #define _COMPONENT RESOURCE_MANAGER
32 MODULE_NAME ("rsirq");
35 /***************************************************************************
36 * FUNCTION: Acpi_rs_irq_resource
39 * Byte_stream_buffer - Pointer to the resource input byte
41 * Bytes_consumed - u32 pointer that is filled with
42 * the number of bytes consumed from
43 * the Byte_stream_buffer
44 * Output_buffer - Pointer to the user's return buffer
45 * Structure_size - u32 pointer that is filled with
46 * the number of bytes in the filled
49 * RETURN: Status AE_OK if okay, else a valid ACPI_STATUS code
51 * DESCRIPTION: Take the resource byte stream and fill out the appropriate
52 * structure pointed to by the Output_buffer. Return the
53 * number of bytes consumed from the byte stream.
55 ***************************************************************************/
58 acpi_rs_irq_resource (
59 u8
*byte_stream_buffer
,
64 u8
*buffer
= byte_stream_buffer
;
65 RESOURCE
*output_struct
= (RESOURCE
*) * output_buffer
;
70 u32 struct_size
= sizeof (IRQ_RESOURCE
) +
71 RESOURCE_LENGTH_NO_DATA
;
75 * The number of bytes consumed are contained in the descriptor
80 *bytes_consumed
= (temp8
& 0x03) + 1;
82 output_struct
->id
= irq
;
85 * Point to the 16-bits of Bytes 1 and 2
88 temp16
= *(u16
*)buffer
;
90 output_struct
->data
.irq
.number_of_interrupts
= 0;
92 /* 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
) {
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 /***************************************************************************
169 * FUNCTION: Acpi_rs_irq_stream
172 * 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
;
219 * Loop through all of the interrupts and set the mask bits
222 index
< linked_list
->data
.irq
.number_of_interrupts
;
225 temp8
= (u8
) linked_list
->data
.irq
.interrupts
[index
];
226 temp16
|= 0x1 << temp8
;
229 *(u16
*)buffer
= temp16
;
234 * Set the IRQ Info byte if needed.
236 if (IRQinfo_byte_needed
) {
239 temp8
= (u8
) ((linked_list
->data
.irq
.shared_exclusive
&
242 if (LEVEL_SENSITIVE
== linked_list
->data
.irq
.edge_level
&&
243 ACTIVE_LOW
== linked_list
->data
.irq
.active_high_low
)
258 * Return the number of bytes consumed in this operation
260 *bytes_consumed
= (u32
) ((NATIVE_UINT
) buffer
-
261 (NATIVE_UINT
) *output_buffer
);
267 /***************************************************************************
268 * FUNCTION: Acpi_rs_extended_irq_resource
271 * Byte_stream_buffer - Pointer to the resource input byte
273 * Bytes_consumed - u32 pointer that is filled with
274 * the number of bytes consumed from
275 * the Byte_stream_buffer
276 * Output_buffer - Pointer to the user's return buffer
277 * Structure_size - u32 pointer that is filled with
278 * the number of bytes in the filled
281 * RETURN: Status AE_OK if okay, else a valid ACPI_STATUS code
283 * DESCRIPTION: Take the resource byte stream and fill out the appropriate
284 * structure pointed to by the Output_buffer. Return the
285 * number of bytes consumed from the byte stream.
287 ***************************************************************************/
290 acpi_rs_extended_irq_resource (
291 u8
*byte_stream_buffer
,
296 u8
*buffer
= byte_stream_buffer
;
297 RESOURCE
*output_struct
= (RESOURCE
*) * output_buffer
;
301 u32 struct_size
= sizeof (EXTENDED_IRQ_RESOURCE
) +
302 RESOURCE_LENGTH_NO_DATA
;
306 * Point past the Descriptor to get the number of bytes consumed
309 temp16
= *(u16
*)buffer
;
311 *bytes_consumed
= temp16
+ 3;
312 output_struct
->id
= extended_irq
;
320 output_struct
->data
.extended_irq
.producer_consumer
= temp8
& 0x01;
323 * Check for HE, LL or HL
326 output_struct
->data
.extended_irq
.edge_level
= EDGE_SENSITIVE
;
327 output_struct
->data
.extended_irq
.active_high_low
= ACTIVE_HIGH
;
332 output_struct
->data
.extended_irq
.edge_level
= LEVEL_SENSITIVE
;
333 output_struct
->data
.extended_irq
.active_high_low
= ACTIVE_LOW
;
338 * Only _LL and _HE polarity/trigger interrupts
339 * are allowed (ACPI spec v1.0b ection 6.4.2.1),
340 * so an error will occur if we reach this point
342 return (AE_BAD_DATA
);
349 output_struct
->data
.extended_irq
.shared_exclusive
=
353 * Point to Byte4 (IRQ Table length)
358 output_struct
->data
.extended_irq
.number_of_interrupts
= temp8
;
361 * Add any additional structure size to properly calculate
362 * the next pointer at the end of this function
364 struct_size
+= (temp8
- 1) * 4;
367 * Point to Byte5 (First IRQ Number)
372 * Cycle through every IRQ in the table
374 for (index
= 0; index
< temp8
; index
++) {
375 output_struct
->data
.extended_irq
.interrupts
[index
] =
378 /* Point to the next IRQ */
384 * This will leave us pointing to the Resource Source Index
385 * If it is present, then save it off and calculate the
386 * pointer to where the null terminated string goes:
387 * Each Interrupt takes 32-bits + the 5 bytes of the
388 * stream that are default.
390 if (*bytes_consumed
>
391 (u32
)(output_struct
->data
.extended_irq
.number_of_interrupts
*
394 /* Dereference the Index */
397 output_struct
->data
.extended_irq
.resource_source_index
=
400 /* Point to the String */
404 /* Copy the string into the buffer */
408 while (0x00 != *buffer
) {
409 output_struct
->data
.extended_irq
.resource_source
[index
] =
417 * Add the terminating null
419 output_struct
->data
.extended_irq
.resource_source
[index
] = 0x00;
420 output_struct
->data
.extended_irq
.resource_source_string_length
=
424 * In order for the Struct_size to fall on a 32-bit boundry,
425 * calculate the length of the string and expand the
426 * Struct_size to the next 32-bit boundry.
428 temp8
= (u8
) (index
+ 1);
429 temp8
= (u8
) ROUND_UP_TO_32_bITS (temp8
);
433 output_struct
->data
.extended_irq
.resource_source_index
= 0x00;
434 output_struct
->data
.extended_irq
.resource_source_string_length
= 0;
435 output_struct
->data
.extended_irq
.resource_source
[0] = 0x00;
439 * Set the Length parameter
441 output_struct
->length
= struct_size
;
444 * Return the final size of the structure
446 *structure_size
= struct_size
;
452 /***************************************************************************
453 * FUNCTION: Acpi_rs_extended_irq_stream
456 * Linked_list - Pointer to the resource linked list
457 * Output_buffer - Pointer to the user's return buffer
458 * Bytes_consumed - u32 pointer that is filled with
459 * the number of bytes of the
462 * RETURN: Status AE_OK if okay, else a valid ACPI_STATUS code
464 * DESCRIPTION: Take the linked list resource structure and fills in the
465 * the appropriate bytes in a byte stream
467 ***************************************************************************/
470 acpi_rs_extended_irq_stream (
471 RESOURCE
*linked_list
,
475 u8
*buffer
= *output_buffer
;
479 u8
*temp_pointer
= NULL
;
483 * The descriptor field is static
489 * Set a pointer to the Length field - to be filled in later
492 length_field
= (u16
*)buffer
;
496 * Set the Interrupt vector flags
498 temp8
= (u8
)(linked_list
->data
.extended_irq
.producer_consumer
& 0x01);
500 temp8
|= ((linked_list
->data
.extended_irq
.shared_exclusive
& 0x01) << 3);
502 if (LEVEL_SENSITIVE
== linked_list
->data
.extended_irq
.edge_level
&&
503 ACTIVE_LOW
== linked_list
->data
.extended_irq
.active_high_low
)
515 * Set the Interrupt table length
517 temp8
= (u8
) linked_list
->data
.extended_irq
.number_of_interrupts
;
524 index
< linked_list
->data
.extended_irq
.number_of_interrupts
;
527 MOVE_UNALIGNED32_TO_32 (buffer
,
528 &linked_list
->data
.extended_irq
.interrupts
[index
]);
533 * Resource Source Index and Resource Source are optional
535 if (0 != linked_list
->data
.extended_irq
.resource_source_string_length
) {
536 temp8
= (u8
) linked_list
->data
.extended_irq
.resource_source_index
;
540 temp_pointer
= buffer
;
545 STRCPY (temp_pointer
, linked_list
->data
.extended_irq
.resource_source
);
548 * Buffer needs to be set to the length of the sting + one for the
551 buffer
+= (STRLEN (linked_list
->data
.extended_irq
.resource_source
) + 1);
555 * Return the number of bytes consumed in this operation
557 *bytes_consumed
= (u32
) ((NATIVE_UINT
) buffer
-
558 (NATIVE_UINT
) *output_buffer
);
561 * Set the length field to the number of bytes consumed
562 * minus the header size (3 bytes)
564 *length_field
= (u16
) (*bytes_consumed
- 3);