scroll mode for very long start menus
[reactos.git] / reactos / drivers / bus / acpi / resource / rslist.c
1 /*******************************************************************************
2 *
3 * Module Name: rslist - Acpi_rs_byte_stream_to_list
4 * Acpi_list_to_byte_stream
5 * $Revision: 1.1 $
6 *
7 ******************************************************************************/
8
9 /*
10 * Copyright (C) 2000, 2001 R. Byron Moore
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 */
26
27
28 #include "acpi.h"
29 #include "acresrc.h"
30
31 #define _COMPONENT ACPI_RESOURCES
32 MODULE_NAME ("rslist")
33
34
35 /*******************************************************************************
36 *
37 * FUNCTION: Acpi_rs_byte_stream_to_list
38 *
39 * PARAMETERS: Byte_stream_buffer - Pointer to the resource byte stream
40 * Byte_stream_buffer_length - Length of Byte_stream_buffer
41 * Output_buffer - Pointer to the buffer that will
42 * contain the output structures
43 *
44 * RETURN: Status AE_OK if okay, else a valid ACPI_STATUS code
45 *
46 * DESCRIPTION: Takes the resource byte stream and parses it, creating a
47 * linked list of resources in the caller's output buffer
48 *
49 ******************************************************************************/
50
51 ACPI_STATUS
52 acpi_rs_byte_stream_to_list (
53 u8 *byte_stream_buffer,
54 u32 byte_stream_buffer_length,
55 u8 **output_buffer)
56 {
57 ACPI_STATUS status;
58 u32 bytes_parsed = 0;
59 u8 resource_type = 0;
60 u32 bytes_consumed = 0;
61 u8 **buffer = output_buffer;
62 u32 structure_size = 0;
63 u8 end_tag_processed = FALSE;
64
65
66 while (bytes_parsed < byte_stream_buffer_length &&
67 FALSE == end_tag_processed) {
68 /*
69 * Look at the next byte in the stream
70 */
71 resource_type = *byte_stream_buffer;
72
73 /*
74 * See if this is a small or large resource
75 */
76 if(resource_type & 0x80) {
77 /*
78 * Large Resource Type
79 */
80 switch (resource_type) {
81 case MEMORY_RANGE_24:
82 /*
83 * 24-Bit Memory Resource
84 */
85 status = acpi_rs_memory24_resource(byte_stream_buffer,
86 &bytes_consumed,
87 buffer,
88 &structure_size);
89
90 break;
91
92 case LARGE_VENDOR_DEFINED:
93 /*
94 * Vendor Defined Resource
95 */
96 status = acpi_rs_vendor_resource(byte_stream_buffer,
97 &bytes_consumed,
98 buffer,
99 &structure_size);
100
101 break;
102
103 case MEMORY_RANGE_32:
104 /*
105 * 32-Bit Memory Range Resource
106 */
107 status = acpi_rs_memory32_range_resource(byte_stream_buffer,
108 &bytes_consumed,
109 buffer,
110 &structure_size);
111
112 break;
113
114 case FIXED_MEMORY_RANGE_32:
115 /*
116 * 32-Bit Fixed Memory Resource
117 */
118 status = acpi_rs_fixed_memory32_resource(byte_stream_buffer,
119 &bytes_consumed,
120 buffer,
121 &structure_size);
122
123 break;
124
125 case DWORD_ADDRESS_SPACE:
126 /*
127 * 32-Bit Address Resource
128 */
129 status = acpi_rs_address32_resource(byte_stream_buffer,
130 &bytes_consumed,
131 buffer,
132 &structure_size);
133
134 break;
135
136 case WORD_ADDRESS_SPACE:
137 /*
138 * 16-Bit Address Resource
139 */
140 status = acpi_rs_address16_resource(byte_stream_buffer,
141 &bytes_consumed,
142 buffer,
143 &structure_size);
144
145 break;
146
147 case EXTENDED_IRQ:
148 /*
149 * Extended IRQ
150 */
151 status = acpi_rs_extended_irq_resource(byte_stream_buffer,
152 &bytes_consumed,
153 buffer,
154 &structure_size);
155
156 break;
157
158 /* TBD: [Future] 64-bit not currently supported */
159 /*
160 case 0x8A:
161 break;
162 */
163
164 default:
165 /*
166 * If we get here, everything is out of sync,
167 * so exit with an error
168 */
169 return (AE_AML_ERROR);
170 break;
171 }
172 }
173
174 else {
175 /*
176 * Small Resource Type
177 * Only bits 7:3 are valid
178 */
179 resource_type >>= 3;
180
181 switch(resource_type) {
182 case IRQ_FORMAT:
183 /*
184 * IRQ Resource
185 */
186 status = acpi_rs_irq_resource(byte_stream_buffer,
187 &bytes_consumed,
188 buffer,
189 &structure_size);
190
191 break;
192
193 case DMA_FORMAT:
194 /*
195 * DMA Resource
196 */
197 status = acpi_rs_dma_resource(byte_stream_buffer,
198 &bytes_consumed,
199 buffer,
200 &structure_size);
201
202 break;
203
204 case START_DEPENDENT_TAG:
205 /*
206 * Start Dependent Functions Resource
207 */
208 status = acpi_rs_start_dependent_functions_resource(byte_stream_buffer,
209 &bytes_consumed,
210 buffer,
211 &structure_size);
212
213 break;
214
215 case END_DEPENDENT_TAG:
216 /*
217 * End Dependent Functions Resource
218 */
219 status = acpi_rs_end_dependent_functions_resource(byte_stream_buffer,
220 &bytes_consumed,
221 buffer,
222 &structure_size);
223
224 break;
225
226 case IO_PORT_DESCRIPTOR:
227 /*
228 * IO Port Resource
229 */
230 status = acpi_rs_io_resource(byte_stream_buffer,
231 &bytes_consumed,
232 buffer,
233 &structure_size);
234
235 break;
236
237 case FIXED_LOCATION_IO_DESCRIPTOR:
238 /*
239 * Fixed IO Port Resource
240 */
241 status = acpi_rs_fixed_io_resource(byte_stream_buffer,
242 &bytes_consumed,
243 buffer,
244 &structure_size);
245
246 break;
247
248 case SMALL_VENDOR_DEFINED:
249 /*
250 * Vendor Specific Resource
251 */
252 status = acpi_rs_vendor_resource(byte_stream_buffer,
253 &bytes_consumed,
254 buffer,
255 &structure_size);
256
257 break;
258
259 case END_TAG:
260 /*
261 * End Tag
262 */
263 status = acpi_rs_end_tag_resource(byte_stream_buffer,
264 &bytes_consumed,
265 buffer,
266 &structure_size);
267 end_tag_processed = TRUE;
268
269 break;
270
271 default:
272 /*
273 * If we get here, everything is out of sync,
274 * so exit with an error
275 */
276 return (AE_AML_ERROR);
277 break;
278
279 } /* switch */
280 } /* end else */
281
282 /*
283 * Update the return value and counter
284 */
285 bytes_parsed += bytes_consumed;
286
287 /*
288 * Set the byte stream to point to the next resource
289 */
290 byte_stream_buffer += bytes_consumed;
291
292 /*
293 * Set the Buffer to the next structure
294 */
295 *buffer += structure_size;
296
297 } /* end while */
298
299 /*
300 * Check the reason for exiting the while loop
301 */
302 if (TRUE != end_tag_processed) {
303 return (AE_AML_ERROR);
304 }
305
306 return (AE_OK);
307 }
308
309
310 /*******************************************************************************
311 *
312 * FUNCTION: Acpi_rs_list_to_byte_stream
313 *
314 * PARAMETERS: Linked_list - Pointer to the resource linked list
315 * Byte_steam_size_needed - Calculated size of the byte stream
316 * needed from calling
317 * Acpi_rs_calculate_byte_stream_length()
318 * The size of the Output_buffer is
319 * guaranteed to be >=
320 * Byte_stream_size_needed
321 * Output_buffer - Pointer to the buffer that will
322 * contain the byte stream
323 *
324 * RETURN: Status AE_OK if okay, else a valid ACPI_STATUS code
325 *
326 * DESCRIPTION: Takes the resource linked list and parses it, creating a
327 * byte stream of resources in the caller's output buffer
328 *
329 ******************************************************************************/
330
331 ACPI_STATUS
332 acpi_rs_list_to_byte_stream (
333 RESOURCE *linked_list,
334 u32 byte_stream_size_needed,
335 u8 **output_buffer)
336 {
337 ACPI_STATUS status;
338 u8 *buffer = *output_buffer;
339 u32 bytes_consumed = 0;
340 u8 done = FALSE;
341
342
343 while (!done) {
344 switch (linked_list->id) {
345 case irq:
346 /*
347 * IRQ Resource
348 */
349 status = acpi_rs_irq_stream (linked_list,
350 &buffer,
351 &bytes_consumed);
352 break;
353
354 case dma:
355 /*
356 * DMA Resource
357 */
358 status = acpi_rs_dma_stream (linked_list,
359 &buffer,
360 &bytes_consumed);
361 break;
362
363 case start_dependent_functions:
364 /*
365 * Start Dependent Functions Resource
366 */
367 status = acpi_rs_start_dependent_functions_stream (linked_list,
368 &buffer,
369 &bytes_consumed);
370 break;
371
372 case end_dependent_functions:
373 /*
374 * End Dependent Functions Resource
375 */
376 status = acpi_rs_end_dependent_functions_stream (linked_list,
377 &buffer,
378 &bytes_consumed);
379 break;
380
381 case io:
382 /*
383 * IO Port Resource
384 */
385 status = acpi_rs_io_stream (linked_list,
386 &buffer,
387 &bytes_consumed);
388 break;
389
390 case fixed_io:
391 /*
392 * Fixed IO Port Resource
393 */
394 status = acpi_rs_fixed_io_stream (linked_list,
395 &buffer,
396 &bytes_consumed);
397 break;
398
399 case vendor_specific:
400 /*
401 * Vendor Defined Resource
402 */
403 status = acpi_rs_vendor_stream (linked_list,
404 &buffer,
405 &bytes_consumed);
406 break;
407
408 case end_tag:
409 /*
410 * End Tag
411 */
412 status = acpi_rs_end_tag_stream (linked_list,
413 &buffer,
414 &bytes_consumed);
415
416 /*
417 * An End Tag indicates the end of the Resource Template
418 */
419 done = TRUE;
420 break;
421
422 case memory24:
423 /*
424 * 24-Bit Memory Resource
425 */
426 status = acpi_rs_memory24_stream (linked_list,
427 &buffer,
428 &bytes_consumed);
429 break;
430
431 case memory32:
432 /*
433 * 32-Bit Memory Range Resource
434 */
435 status = acpi_rs_memory32_range_stream (linked_list,
436 &buffer,
437 &bytes_consumed);
438 break;
439
440 case fixed_memory32:
441 /*
442 * 32-Bit Fixed Memory Resource
443 */
444 status = acpi_rs_fixed_memory32_stream (linked_list,
445 &buffer,
446 &bytes_consumed);
447 break;
448
449 case address16:
450 /*
451 * 16-Bit Address Descriptor Resource
452 */
453 status = acpi_rs_address16_stream (linked_list,
454 &buffer,
455 &bytes_consumed);
456 break;
457
458 case address32:
459 /*
460 * 32-Bit Address Descriptor Resource
461 */
462 status = acpi_rs_address32_stream (linked_list,
463 &buffer,
464 &bytes_consumed);
465 break;
466
467 case extended_irq:
468 /*
469 * Extended IRQ Resource
470 */
471 status = acpi_rs_extended_irq_stream (linked_list,
472 &buffer,
473 &bytes_consumed);
474 break;
475
476 default:
477 /*
478 * If we get here, everything is out of sync,
479 * so exit with an error
480 */
481 return (AE_BAD_DATA);
482 break;
483
484 } /* switch (Linked_list->Id) */
485
486 /*
487 * Set the Buffer to point to the open byte
488 */
489 buffer += bytes_consumed;
490
491 /*
492 * Point to the next object
493 */
494 linked_list = (RESOURCE *) ((NATIVE_UINT) linked_list +
495 (NATIVE_UINT) linked_list->length);
496 }
497
498 return (AE_OK);
499 }
500