aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/resources/rsirq.c
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2005-09-30 19:03:00 -0400
committerLen Brown <len.brown@intel.com>2005-12-10 00:20:25 -0500
commit50eca3eb89d73d9f0aa070b126c7ee6a616016ab (patch)
treeb2d06d21b34b9bd17eea4c53cff1f3866fa1b21d /drivers/acpi/resources/rsirq.c
parent3d5271f9883cba7b54762bc4fe027d4172f06db7 (diff)
[ACPI] ACPICA 20050930
Completed a major overhaul of the Resource Manager code - specifically, optimizations in the area of the AML/internal resource conversion code. The code has been optimized to simplify and eliminate duplicated code, CPU stack use has been decreased by optimizing function parameters and local variables, and naming conventions across the manager have been standardized for clarity and ease of maintenance (this includes function, parameter, variable, and struct/typedef names.) All Resource Manager dispatch and information tables have been moved to a single location for clarity and ease of maintenance. One new file was created, named "rsinfo.c". The ACPI return macros (return_ACPI_STATUS, etc.) have been modified to guarantee that the argument is not evaluated twice, making them less prone to macro side-effects. However, since there exists the possibility of additional stack use if a particular compiler cannot optimize them (such as in the debug generation case), the original macros are optionally available. Note that some invocations of the return_VALUE macro may now cause size mismatch warnings; the return_UINT8 and return_UINT32 macros are provided to eliminate these. (From Randy Dunlap) Implemented a new mechanism to enable debug tracing for individual control methods. A new external interface, acpi_debug_trace(), is provided to enable this mechanism. The intent is to allow the host OS to easily enable and disable tracing for problematic control methods. This interface can be easily exposed to a user or debugger interface if desired. See the file psxface.c for details. acpi_ut_callocate() will now return a valid pointer if a length of zero is specified - a length of one is used and a warning is issued. This matches the behavior of acpi_ut_allocate(). Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/resources/rsirq.c')
-rw-r--r--drivers/acpi/resources/rsirq.c494
1 files changed, 158 insertions, 336 deletions
diff --git a/drivers/acpi/resources/rsirq.c b/drivers/acpi/resources/rsirq.c
index 75df962115cc..4e854ba70811 100644
--- a/drivers/acpi/resources/rsirq.c
+++ b/drivers/acpi/resources/rsirq.c
@@ -49,93 +49,67 @@ ACPI_MODULE_NAME("rsirq")
49 49
50/******************************************************************************* 50/*******************************************************************************
51 * 51 *
52 * FUNCTION: acpi_rs_irq_resource 52 * FUNCTION: acpi_rs_get_irq
53 * 53 *
54 * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte 54 * PARAMETERS: Aml - Pointer to the AML resource descriptor
55 * stream 55 * aml_resource_length - Length of the resource from the AML header
56 * bytes_consumed - Pointer to where the number of bytes 56 * Resource - Where the internal resource is returned
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 * 57 *
63 * RETURN: Status 58 * RETURN: Status
64 * 59 *
65 * DESCRIPTION: Take the resource byte stream and fill out the appropriate 60 * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding
66 * structure pointed to by the output_buffer. Return the 61 * internal resource descriptor, simplifying bitflags and handling
67 * number of bytes consumed from the byte stream. 62 * alignment and endian issues if necessary.
68 * 63 *
69 ******************************************************************************/ 64 ******************************************************************************/
70acpi_status 65acpi_status
71acpi_rs_irq_resource(u8 * byte_stream_buffer, 66acpi_rs_get_irq(union aml_resource *aml,
72 acpi_size * bytes_consumed, 67 u16 aml_resource_length, struct acpi_resource *resource)
73 u8 ** output_buffer, acpi_size * structure_size)
74{ 68{
75 u8 *buffer = byte_stream_buffer;
76 struct acpi_resource *output_struct = (void *)*output_buffer;
77 u16 temp16 = 0; 69 u16 temp16 = 0;
78 u8 temp8 = 0; 70 u32 interrupt_count = 0;
79 u8 index; 71 u32 i;
80 u8 i; 72 u32 resource_length;
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->type = ACPI_RSTYPE_IRQ;
92 73
93 /* Point to the 16-bits of Bytes 1 and 2 */ 74 ACPI_FUNCTION_TRACE("rs_get_irq");
94 75
95 buffer += 1; 76 /* Get the IRQ mask (bytes 1:2) */
96 ACPI_MOVE_16_TO_16(&temp16, buffer);
97 77
98 output_struct->data.irq.number_of_interrupts = 0; 78 ACPI_MOVE_16_TO_16(&temp16, &aml->irq.irq_mask);
99 79
100 /* Decode the IRQ bits */ 80 /* Decode the IRQ bits (up to 16 possible) */
101 81
102 for (i = 0, index = 0; index < 16; index++) { 82 for (i = 0; i < 16; i++) {
103 if ((temp16 >> index) & 0x01) { 83 if ((temp16 >> i) & 0x01) {
104 output_struct->data.irq.interrupts[i] = index; 84 resource->data.irq.interrupts[interrupt_count] = i;
105 i++; 85 interrupt_count++;
106 } 86 }
107 } 87 }
108 88
109 /* Zero interrupts is valid */ 89 /* Zero interrupts is valid */
110 90
111 output_struct->data.irq.number_of_interrupts = i; 91 resource_length = 0;
112 if (i > 0) { 92 resource->data.irq.interrupt_count = interrupt_count;
93 if (interrupt_count > 0) {
113 /* Calculate the structure size based upon the number of interrupts */ 94 /* Calculate the structure size based upon the number of interrupts */
114 95
115 struct_size += ((acpi_size) i - 1) * 4; 96 resource_length = (u32) (interrupt_count - 1) * 4;
116 } 97 }
117 98
118 /* Point to Byte 3 if it is used */ 99 /* Get Flags (Byte 3) if it is used */
119
120 if (4 == *bytes_consumed) {
121 buffer += 2;
122 temp8 = *buffer;
123 100
101 if (aml_resource_length == 3) {
124 /* Check for HE, LL interrupts */ 102 /* Check for HE, LL interrupts */
125 103
126 switch (temp8 & 0x09) { 104 switch (aml->irq.flags & 0x09) {
127 case 0x01: /* HE */ 105 case 0x01: /* HE */
128 output_struct->data.irq.edge_level = 106 resource->data.irq.triggering = ACPI_EDGE_SENSITIVE;
129 ACPI_EDGE_SENSITIVE; 107 resource->data.irq.polarity = ACPI_ACTIVE_HIGH;
130 output_struct->data.irq.active_high_low =
131 ACPI_ACTIVE_HIGH;
132 break; 108 break;
133 109
134 case 0x08: /* LL */ 110 case 0x08: /* LL */
135 output_struct->data.irq.edge_level = 111 resource->data.irq.triggering = ACPI_LEVEL_SENSITIVE;
136 ACPI_LEVEL_SENSITIVE; 112 resource->data.irq.polarity = ACPI_ACTIVE_LOW;
137 output_struct->data.irq.active_high_low =
138 ACPI_ACTIVE_LOW;
139 break; 113 break;
140 114
141 default: 115 default:
@@ -146,170 +120,131 @@ acpi_rs_irq_resource(u8 * byte_stream_buffer,
146 */ 120 */
147 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 121 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
148 "Invalid interrupt polarity/trigger in resource list, %X\n", 122 "Invalid interrupt polarity/trigger in resource list, %X\n",
149 temp8)); 123 aml->irq.flags));
150 return_ACPI_STATUS(AE_BAD_DATA); 124 return_ACPI_STATUS(AE_BAD_DATA);
151 } 125 }
152 126
153 /* Check for sharable */ 127 /* Get Sharing flag */
154 128
155 output_struct->data.irq.shared_exclusive = (temp8 >> 3) & 0x01; 129 resource->data.irq.sharable = (aml->irq.flags >> 3) & 0x01;
156 } else { 130 } else {
157 /* 131 /*
158 * Assume Edge Sensitive, Active High, Non-Sharable 132 * Default configuration: assume Edge Sensitive, Active High,
159 * per ACPI Specification 133 * Non-Sharable as per the ACPI Specification
160 */ 134 */
161 output_struct->data.irq.edge_level = ACPI_EDGE_SENSITIVE; 135 resource->data.irq.triggering = ACPI_EDGE_SENSITIVE;
162 output_struct->data.irq.active_high_low = ACPI_ACTIVE_HIGH; 136 resource->data.irq.polarity = ACPI_ACTIVE_HIGH;
163 output_struct->data.irq.shared_exclusive = ACPI_EXCLUSIVE; 137 resource->data.irq.sharable = ACPI_EXCLUSIVE;
164 } 138 }
165 139
166 /* Set the Length parameter */ 140 /* Complete the resource header */
167 141
168 output_struct->length = (u32) struct_size; 142 resource->type = ACPI_RESOURCE_TYPE_IRQ;
169 143 resource->length =
170 /* Return the final size of the structure */ 144 resource_length + ACPI_SIZEOF_RESOURCE(struct acpi_resource_irq);
171
172 *structure_size = struct_size;
173 return_ACPI_STATUS(AE_OK); 145 return_ACPI_STATUS(AE_OK);
174} 146}
175 147
176/******************************************************************************* 148/*******************************************************************************
177 * 149 *
178 * FUNCTION: acpi_rs_irq_stream 150 * FUNCTION: acpi_rs_set_irq
179 * 151 *
180 * PARAMETERS: Resource - Pointer to the resource linked list 152 * PARAMETERS: Resource - Pointer to the resource descriptor
181 * output_buffer - Pointer to the user's return buffer 153 * Aml - Where the AML descriptor is returned
182 * bytes_consumed - Pointer to where the number of bytes
183 * used in the output_buffer is returned
184 * 154 *
185 * RETURN: Status 155 * RETURN: Status
186 * 156 *
187 * DESCRIPTION: Take the linked list resource structure and fills in the 157 * DESCRIPTION: Convert an internal resource descriptor to the corresponding
188 * the appropriate bytes in a byte stream 158 * external AML resource descriptor.
189 * 159 *
190 ******************************************************************************/ 160 ******************************************************************************/
191 161
192acpi_status 162acpi_status
193acpi_rs_irq_stream(struct acpi_resource *resource, 163acpi_rs_set_irq(struct acpi_resource *resource, union aml_resource *aml)
194 u8 ** output_buffer, acpi_size * bytes_consumed)
195{ 164{
196 u8 *buffer = *output_buffer; 165 acpi_size descriptor_length;
197 u16 temp16 = 0; 166 u16 irq_mask;
198 u8 temp8 = 0; 167 u8 i;
199 u8 index; 168
200 u8 IRqinfo_byte_needed; 169 ACPI_FUNCTION_TRACE("rs_set_irq");
201 170
202 ACPI_FUNCTION_TRACE("rs_irq_stream"); 171 /* Convert interrupt list to 16-bit IRQ bitmask */
172
173 irq_mask = 0;
174 for (i = 0; i < resource->data.irq.interrupt_count; i++) {
175 irq_mask |= (1 << resource->data.irq.interrupts[i]);
176 }
177
178 /* Set the interrupt mask */
179
180 ACPI_MOVE_16_TO_16(&aml->irq.irq_mask, &irq_mask);
203 181
204 /* 182 /*
205 * The descriptor field is set based upon whether a third byte is 183 * The descriptor field is set based upon whether a third byte is
206 * needed to contain the IRQ Information. 184 * needed to contain the IRQ Information.
207 */ 185 */
208 if (ACPI_EDGE_SENSITIVE == resource->data.irq.edge_level && 186 if ((resource->data.irq.triggering == ACPI_EDGE_SENSITIVE) &&
209 ACPI_ACTIVE_HIGH == resource->data.irq.active_high_low && 187 (resource->data.irq.polarity == ACPI_ACTIVE_HIGH) &&
210 ACPI_EXCLUSIVE == resource->data.irq.shared_exclusive) { 188 (resource->data.irq.sharable == ACPI_EXCLUSIVE)) {
211 *buffer = ACPI_RDESC_TYPE_IRQ_FORMAT | 0x02; 189 /* irq_no_flags() descriptor can be used */
212 IRqinfo_byte_needed = FALSE;
213 } else {
214 *buffer = ACPI_RDESC_TYPE_IRQ_FORMAT | 0x03;
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 190
223 for (index = 0; 191 descriptor_length = sizeof(struct aml_resource_irq_noflags);
224 index < resource->data.irq.number_of_interrupts; index++) { 192 } else {
225 temp8 = (u8) resource->data.irq.interrupts[index]; 193 /* Irq() descriptor must be used */
226 temp16 |= 0x1 << temp8;
227 }
228 194
229 ACPI_MOVE_16_TO_16(buffer, &temp16); 195 descriptor_length = sizeof(struct aml_resource_irq);
230 buffer += 2;
231 196
232 /* Set the IRQ Info byte if needed. */ 197 /* Set the IRQ Info byte */
233 198
234 if (IRqinfo_byte_needed) { 199 aml->irq.flags = (u8)
235 temp8 = 0; 200 ((resource->data.irq.sharable & 0x01) << 4);
236 temp8 = (u8) ((resource->data.irq.shared_exclusive &
237 0x01) << 4);
238 201
239 if (ACPI_LEVEL_SENSITIVE == resource->data.irq.edge_level && 202 if (ACPI_LEVEL_SENSITIVE == resource->data.irq.triggering &&
240 ACPI_ACTIVE_LOW == resource->data.irq.active_high_low) { 203 ACPI_ACTIVE_LOW == resource->data.irq.polarity) {
241 temp8 |= 0x08; 204 aml->irq.flags |= 0x08;
242 } else { 205 } else {
243 temp8 |= 0x01; 206 aml->irq.flags |= 0x01;
244 } 207 }
245
246 *buffer = temp8;
247 buffer += 1;
248 } 208 }
249 209
250 /* Return the number of bytes consumed in this operation */ 210 /* Complete the AML descriptor header */
251 211
252 *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); 212 acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_IRQ, descriptor_length,
213 aml);
253 return_ACPI_STATUS(AE_OK); 214 return_ACPI_STATUS(AE_OK);
254} 215}
255 216
256/******************************************************************************* 217/*******************************************************************************
257 * 218 *
258 * FUNCTION: acpi_rs_extended_irq_resource 219 * FUNCTION: acpi_rs_get_ext_irq
259 * 220 *
260 * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte 221 * PARAMETERS: Aml - Pointer to the AML resource descriptor
261 * stream 222 * aml_resource_length - Length of the resource from the AML header
262 * bytes_consumed - Pointer to where the number of bytes 223 * Resource - Where the internal resource is returned
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 * 224 *
269 * RETURN: Status 225 * RETURN: Status
270 * 226 *
271 * DESCRIPTION: Take the resource byte stream and fill out the appropriate 227 * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding
272 * structure pointed to by the output_buffer. Return the 228 * internal resource descriptor, simplifying bitflags and handling
273 * number of bytes consumed from the byte stream. 229 * alignment and endian issues if necessary.
274 * 230 *
275 ******************************************************************************/ 231 ******************************************************************************/
276 232
277acpi_status 233acpi_status
278acpi_rs_extended_irq_resource(u8 * byte_stream_buffer, 234acpi_rs_get_ext_irq(union aml_resource *aml,
279 acpi_size * bytes_consumed, 235 u16 aml_resource_length, struct acpi_resource *resource)
280 u8 ** output_buffer, acpi_size * structure_size)
281{ 236{
282 u8 *buffer = byte_stream_buffer; 237 char *out_resource_string;
283 struct acpi_resource *output_struct = (void *)*output_buffer; 238 u8 temp8;
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 239
293 /* Get the Descriptor Length field */ 240 ACPI_FUNCTION_TRACE("rs_get_ext_irq");
294 241
295 buffer += 1; 242 /* Get the flag bits */
296 ACPI_MOVE_16_TO_16(&temp16, buffer);
297 243
298 /* Validate minimum descriptor length */ 244 temp8 = aml->extended_irq.flags;
299 245 resource->data.extended_irq.producer_consumer = temp8 & 0x01;
300 if (temp16 < 6) { 246 resource->data.extended_irq.polarity = (temp8 >> 2) & 0x01;
301 return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH); 247 resource->data.extended_irq.sharable = (temp8 >> 3) & 0x01;
302 }
303
304 *bytes_consumed = temp16 + 3;
305 output_struct->type = 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 248
314 /* 249 /*
315 * Check for Interrupt Mode 250 * Check for Interrupt Mode
@@ -319,165 +254,80 @@ acpi_rs_extended_irq_resource(u8 * byte_stream_buffer,
319 * 254 *
320 * - Edge/Level are defined opposite in the table vs the headers 255 * - Edge/Level are defined opposite in the table vs the headers
321 */ 256 */
322 output_struct->data.extended_irq.edge_level = 257 resource->data.extended_irq.triggering =
323 (temp8 & 0x2) ? ACPI_EDGE_SENSITIVE : ACPI_LEVEL_SENSITIVE; 258 (temp8 & 0x2) ? ACPI_EDGE_SENSITIVE : ACPI_LEVEL_SENSITIVE;
324 259
325 /* Check Interrupt Polarity */ 260 /* Get the IRQ Table length (Byte4) */
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
333 /* Point to Byte4 (IRQ Table length) */
334
335 buffer += 1;
336 temp8 = *buffer;
337
338 /* Must have at least one IRQ */
339 261
262 temp8 = aml->extended_irq.table_length;
263 resource->data.extended_irq.interrupt_count = temp8;
340 if (temp8 < 1) { 264 if (temp8 < 1) {
265 /* Must have at least one IRQ */
266
341 return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH); 267 return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH);
342 } 268 }
343 269
344 output_struct->data.extended_irq.number_of_interrupts = temp8;
345
346 /* 270 /*
347 * Add any additional structure size to properly calculate 271 * Add any additional structure size to properly calculate
348 * the next pointer at the end of this function 272 * the next pointer at the end of this function
349 */ 273 */
350 struct_size += (temp8 - 1) * 4; 274 resource->length = (temp8 - 1) * 4;
275 out_resource_string = ACPI_CAST_PTR(char,
276 (&resource->data.extended_irq.
277 interrupts[0] + temp8));
351 278
352 /* Point to Byte5 (First IRQ Number) */ 279 /* Get every IRQ in the table, each is 32 bits */
353 280
354 buffer += 1; 281 acpi_rs_move_data(resource->data.extended_irq.interrupts,
282 aml->extended_irq.interrupt_number,
283 (u16) temp8, ACPI_MOVE_TYPE_32_TO_32);
355 284
356 /* Cycle through every IRQ in the table */ 285 /* Get the optional resource_source (index and string) */
357 286
358 for (index = 0; index < temp8; index++) { 287 resource->length +=
359 ACPI_MOVE_32_TO_32(&output_struct->data.extended_irq. 288 acpi_rs_get_resource_source(aml_resource_length,
360 interrupts[index], buffer); 289 (acpi_size) resource->length +
290 sizeof(struct
291 aml_resource_extended_irq),
292 &resource->data.extended_irq.
293 resource_source, aml,
294 out_resource_string);
361 295
362 /* Point to the next IRQ */ 296 /* Complete the resource header */
363 297
364 buffer += 4; 298 resource->type = ACPI_RESOURCE_TYPE_EXTENDED_IRQ;
365 } 299 resource->length +=
366 300 ACPI_SIZEOF_RESOURCE(struct acpi_resource_extended_irq);
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
395 temp_ptr = (u8 *)
396 output_struct->data.extended_irq.resource_source.string_ptr;
397
398 /* Copy the string into the buffer */
399
400 index = 0;
401 while (*buffer) {
402 *temp_ptr = *buffer;
403
404 temp_ptr += 1;
405 buffer += 1;
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); 301 return_ACPI_STATUS(AE_OK);
438} 302}
439 303
440/******************************************************************************* 304/*******************************************************************************
441 * 305 *
442 * FUNCTION: acpi_rs_extended_irq_stream 306 * FUNCTION: acpi_rs_set_ext_irq
443 * 307 *
444 * PARAMETERS: Resource - Pointer to the resource linked list 308 * PARAMETERS: Resource - Pointer to the resource descriptor
445 * output_buffer - Pointer to the user's return buffer 309 * Aml - Where the AML descriptor is returned
446 * bytes_consumed - Pointer to where the number of bytes
447 * used in the output_buffer is returned
448 * 310 *
449 * RETURN: Status 311 * RETURN: Status
450 * 312 *
451 * DESCRIPTION: Take the linked list resource structure and fills in the 313 * DESCRIPTION: Convert an internal resource descriptor to the corresponding
452 * the appropriate bytes in a byte stream 314 * external AML resource descriptor.
453 * 315 *
454 ******************************************************************************/ 316 ******************************************************************************/
455 317
456acpi_status 318acpi_status
457acpi_rs_extended_irq_stream(struct acpi_resource *resource, 319acpi_rs_set_ext_irq(struct acpi_resource *resource, union aml_resource *aml)
458 u8 ** output_buffer, acpi_size * bytes_consumed)
459{ 320{
460 u8 *buffer = *output_buffer; 321 acpi_size descriptor_length;
461 u16 *length_field;
462 u8 temp8 = 0;
463 u8 index;
464
465 ACPI_FUNCTION_TRACE("rs_extended_irq_stream");
466
467 /* Set the Descriptor Type field */
468
469 *buffer = ACPI_RDESC_TYPE_EXTENDED_XRUPT;
470 buffer += 1;
471 322
472 /* Save a pointer to the Length field - to be filled in later */ 323 ACPI_FUNCTION_TRACE("rs_set_ext_irq");
473
474 length_field = ACPI_CAST_PTR(u16, buffer);
475 buffer += 2;
476 324
477 /* Set the Interrupt vector flags */ 325 /* Set the Interrupt vector flags */
478 326
479 temp8 = (u8) (resource->data.extended_irq.producer_consumer & 0x01); 327 aml->extended_irq.flags = (u8)
480 temp8 |= ((resource->data.extended_irq.shared_exclusive & 0x01) << 3); 328 ((resource->data.extended_irq.producer_consumer & 0x01) |
329 ((resource->data.extended_irq.sharable & 0x01) << 3) |
330 ((resource->data.extended_irq.polarity & 0x1) << 2));
481 331
482 /* 332 /*
483 * Set the Interrupt Mode 333 * Set the Interrupt Mode
@@ -488,64 +338,36 @@ acpi_rs_extended_irq_stream(struct acpi_resource *resource,
488 * 338 *
489 * - Edge/Level are defined opposite in the table vs the headers 339 * - Edge/Level are defined opposite in the table vs the headers
490 */ 340 */
491 if (ACPI_EDGE_SENSITIVE == resource->data.extended_irq.edge_level) { 341 if (resource->data.extended_irq.triggering == ACPI_EDGE_SENSITIVE) {
492 temp8 |= 0x2; 342 aml->extended_irq.flags |= 0x02;
493 } 343 }
494 344
495 /* Set the Interrupt Polarity */
496
497 temp8 |= ((resource->data.extended_irq.active_high_low & 0x1) << 2);
498
499 *buffer = temp8;
500 buffer += 1;
501
502 /* Set the Interrupt table length */ 345 /* Set the Interrupt table length */
503 346
504 temp8 = (u8) resource->data.extended_irq.number_of_interrupts; 347 aml->extended_irq.table_length = (u8)
505 348 resource->data.extended_irq.interrupt_count;
506 *buffer = temp8;
507 buffer += 1;
508 349
509 for (index = 0; 350 descriptor_length = (sizeof(struct aml_resource_extended_irq) - 4) +
510 index < resource->data.extended_irq.number_of_interrupts; 351 ((acpi_size) resource->data.extended_irq.interrupt_count *
511 index++) { 352 sizeof(u32));
512 ACPI_MOVE_32_TO_32(buffer,
513 &resource->data.extended_irq.
514 interrupts[index]);
515 buffer += 4;
516 }
517
518 /* Resource Source Index and Resource Source are optional */
519 353
520 if (0 != resource->data.extended_irq.resource_source.string_length) { 354 /* Set each interrupt value */
521 *buffer =
522 (u8) resource->data.extended_irq.resource_source.index;
523 buffer += 1;
524 355
525 /* Copy the string */ 356 acpi_rs_move_data(aml->extended_irq.interrupt_number,
357 resource->data.extended_irq.interrupts,
358 (u16) resource->data.extended_irq.interrupt_count,
359 ACPI_MOVE_TYPE_32_TO_32);
526 360
527 ACPI_STRCPY((char *)buffer, 361 /* Resource Source Index and Resource Source are optional */
528 resource->data.extended_irq.resource_source.
529 string_ptr);
530
531 /*
532 * Buffer needs to be set to the length of the string + one for the
533 * terminating null
534 */
535 buffer +=
536 (acpi_size) (ACPI_STRLEN
537 (resource->data.extended_irq.resource_source.
538 string_ptr) + 1);
539 }
540 362
541 /* Return the number of bytes consumed in this operation */ 363 descriptor_length = acpi_rs_set_resource_source(aml, descriptor_length,
364 &resource->data.
365 extended_irq.
366 resource_source);
542 367
543 *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); 368 /* Complete the AML descriptor header */
544 369
545 /* 370 acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_EXTENDED_IRQ,
546 * Set the length field to the number of bytes consumed 371 descriptor_length, aml);
547 * minus the header size (3 bytes)
548 */
549 *length_field = (u16) (*bytes_consumed - 3);
550 return_ACPI_STATUS(AE_OK); 372 return_ACPI_STATUS(AE_OK);
551} 373}