:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / 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$
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