ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / acpi / resources / rslist.c
1 /*******************************************************************************
2  *
3  * Module Name: rslist - Linked list utilities
4  *
5  ******************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2004, R. Byron Moore
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43
44
45 #include <acpi/acpi.h>
46 #include <acpi/acresrc.h>
47
48 #define _COMPONENT          ACPI_RESOURCES
49          ACPI_MODULE_NAME    ("rslist")
50
51
52 /*******************************************************************************
53  *
54  * FUNCTION:    acpi_rs_get_resource_type
55  *
56  * PARAMETERS:  resource_start_byte     - Byte 0 of a resource descriptor
57  *
58  * RETURN:      The Resource Type (Name) with no extraneous bits
59  *
60  * DESCRIPTION: Extract the Resource Type/Name from the first byte of
61  *              a resource descriptor.
62  *
63  ******************************************************************************/
64
65 u8
66 acpi_rs_get_resource_type (
67         u8                              resource_start_byte)
68 {
69
70         ACPI_FUNCTION_ENTRY ();
71
72
73         /*
74          * Determine if this is a small or large resource
75          */
76         switch (resource_start_byte & ACPI_RDESC_TYPE_MASK) {
77         case ACPI_RDESC_TYPE_SMALL:
78
79                 /*
80                  * Small Resource Type -- Only bits 6:3 are valid
81                  */
82                 return ((u8) (resource_start_byte & ACPI_RDESC_SMALL_MASK));
83
84
85         case ACPI_RDESC_TYPE_LARGE:
86
87                 /*
88                  * Large Resource Type -- All bits are valid
89                  */
90                 return (resource_start_byte);
91
92
93         default:
94                 /* No other types of resource descriptor */
95                 break;
96         }
97
98         return (0xFF);
99 }
100
101
102 /*******************************************************************************
103  *
104  * FUNCTION:    acpi_rs_byte_stream_to_list
105  *
106  * PARAMETERS:  byte_stream_buffer      - Pointer to the resource byte stream
107  *              byte_stream_buffer_length - Length of byte_stream_buffer
108  *              output_buffer           - Pointer to the buffer that will
109  *                                        contain the output structures
110  *
111  * RETURN:      Status
112  *
113  * DESCRIPTION: Takes the resource byte stream and parses it, creating a
114  *              linked list of resources in the caller's output buffer
115  *
116  ******************************************************************************/
117
118 acpi_status
119 acpi_rs_byte_stream_to_list (
120         u8                              *byte_stream_buffer,
121         u32                             byte_stream_buffer_length,
122         u8                              *output_buffer)
123 {
124         acpi_status                     status;
125         acpi_size                       bytes_parsed = 0;
126         u8                              resource_type = 0;
127         acpi_size                       bytes_consumed = 0;
128         u8                              *buffer = output_buffer;
129         acpi_size                       structure_size = 0;
130         u8                              end_tag_processed = FALSE;
131         struct acpi_resource            *resource;
132
133         ACPI_FUNCTION_TRACE ("rs_byte_stream_to_list");
134
135
136         while (bytes_parsed < byte_stream_buffer_length &&
137                         !end_tag_processed) {
138                 /*
139                  * The next byte in the stream is the resource type
140                  */
141                 resource_type = acpi_rs_get_resource_type (*byte_stream_buffer);
142
143                 switch (resource_type) {
144                 case ACPI_RDESC_TYPE_MEMORY_24:
145                         /*
146                          * 24-Bit Memory Resource
147                          */
148                         status = acpi_rs_memory24_resource (byte_stream_buffer,
149                                          &bytes_consumed, &buffer, &structure_size);
150                         break;
151
152
153                 case ACPI_RDESC_TYPE_LARGE_VENDOR:
154                         /*
155                          * Vendor Defined Resource
156                          */
157                         status = acpi_rs_vendor_resource (byte_stream_buffer,
158                                          &bytes_consumed, &buffer, &structure_size);
159                         break;
160
161
162                 case ACPI_RDESC_TYPE_MEMORY_32:
163                         /*
164                          * 32-Bit Memory Range Resource
165                          */
166                         status = acpi_rs_memory32_range_resource (byte_stream_buffer,
167                                          &bytes_consumed, &buffer, &structure_size);
168                         break;
169
170
171                 case ACPI_RDESC_TYPE_FIXED_MEMORY_32:
172                         /*
173                          * 32-Bit Fixed Memory Resource
174                          */
175                         status = acpi_rs_fixed_memory32_resource (byte_stream_buffer,
176                                          &bytes_consumed, &buffer, &structure_size);
177                         break;
178
179
180                 case ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE:
181                         /*
182                          * 64-Bit Address Resource
183                          */
184                         status = acpi_rs_address64_resource (byte_stream_buffer,
185                                          &bytes_consumed, &buffer, &structure_size);
186                         break;
187
188
189                 case ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE:
190                         /*
191                          * 32-Bit Address Resource
192                          */
193                         status = acpi_rs_address32_resource (byte_stream_buffer,
194                                          &bytes_consumed, &buffer, &structure_size);
195                         break;
196
197
198                 case ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE:
199                         /*
200                          * 16-Bit Address Resource
201                          */
202                         status = acpi_rs_address16_resource (byte_stream_buffer,
203                                          &bytes_consumed, &buffer, &structure_size);
204                         break;
205
206
207                 case ACPI_RDESC_TYPE_EXTENDED_XRUPT:
208                         /*
209                          * Extended IRQ
210                          */
211                         status = acpi_rs_extended_irq_resource (byte_stream_buffer,
212                                          &bytes_consumed, &buffer, &structure_size);
213                         break;
214
215
216                 case ACPI_RDESC_TYPE_IRQ_FORMAT:
217                         /*
218                          * IRQ Resource
219                          */
220                         status = acpi_rs_irq_resource (byte_stream_buffer,
221                                          &bytes_consumed, &buffer, &structure_size);
222                         break;
223
224
225                 case ACPI_RDESC_TYPE_DMA_FORMAT:
226                         /*
227                          * DMA Resource
228                          */
229                         status = acpi_rs_dma_resource (byte_stream_buffer,
230                                          &bytes_consumed, &buffer, &structure_size);
231                         break;
232
233
234                 case ACPI_RDESC_TYPE_START_DEPENDENT:
235                         /*
236                          * Start Dependent Functions Resource
237                          */
238                         status = acpi_rs_start_depend_fns_resource (byte_stream_buffer,
239                                          &bytes_consumed, &buffer, &structure_size);
240                         break;
241
242
243                 case ACPI_RDESC_TYPE_END_DEPENDENT:
244                         /*
245                          * End Dependent Functions Resource
246                          */
247                         status = acpi_rs_end_depend_fns_resource (byte_stream_buffer,
248                                          &bytes_consumed, &buffer, &structure_size);
249                         break;
250
251
252                 case ACPI_RDESC_TYPE_IO_PORT:
253                         /*
254                          * IO Port Resource
255                          */
256                         status = acpi_rs_io_resource (byte_stream_buffer,
257                                          &bytes_consumed, &buffer, &structure_size);
258                         break;
259
260
261                 case ACPI_RDESC_TYPE_FIXED_IO_PORT:
262                         /*
263                          * Fixed IO Port Resource
264                          */
265                         status = acpi_rs_fixed_io_resource (byte_stream_buffer,
266                                          &bytes_consumed, &buffer, &structure_size);
267                         break;
268
269
270                 case ACPI_RDESC_TYPE_SMALL_VENDOR:
271                         /*
272                          * Vendor Specific Resource
273                          */
274                         status = acpi_rs_vendor_resource (byte_stream_buffer,
275                                          &bytes_consumed, &buffer, &structure_size);
276                         break;
277
278
279                 case ACPI_RDESC_TYPE_END_TAG:
280                         /*
281                          * End Tag
282                          */
283                         end_tag_processed = TRUE;
284                         status = acpi_rs_end_tag_resource (byte_stream_buffer,
285                                          &bytes_consumed, &buffer, &structure_size);
286                         break;
287
288
289                 default:
290                         /*
291                          * Invalid/Unknown resource type
292                          */
293                         status = AE_AML_INVALID_RESOURCE_TYPE;
294                         break;
295                 }
296
297                 if (ACPI_FAILURE (status)) {
298                         return_ACPI_STATUS (status);
299                 }
300
301                 /*
302                  * Update the return value and counter
303                  */
304                 bytes_parsed += bytes_consumed;
305
306                 /*
307                  * Set the byte stream to point to the next resource
308                  */
309                 byte_stream_buffer += bytes_consumed;
310
311                 /*
312                  * Set the Buffer to the next structure
313                  */
314                 resource = ACPI_CAST_PTR (struct acpi_resource, buffer);
315                 resource->length = (u32) ACPI_ALIGN_RESOURCE_SIZE (resource->length);
316                 buffer += ACPI_ALIGN_RESOURCE_SIZE (structure_size);
317
318         } /*  end while */
319
320         /*
321          * Check the reason for exiting the while loop
322          */
323         if (!end_tag_processed) {
324                 return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG);
325         }
326
327         return_ACPI_STATUS (AE_OK);
328 }
329
330
331 /*******************************************************************************
332  *
333  * FUNCTION:    acpi_rs_list_to_byte_stream
334  *
335  * PARAMETERS:  linked_list             - Pointer to the resource linked list
336  *              byte_steam_size_needed  - Calculated size of the byte stream
337  *                                        needed from calling
338  *                                        acpi_rs_get_byte_stream_length()
339  *                                        The size of the output_buffer is
340  *                                        guaranteed to be >=
341  *                                        byte_stream_size_needed
342  *              output_buffer           - Pointer to the buffer that will
343  *                                        contain the byte stream
344  *
345  * RETURN:      Status
346  *
347  * DESCRIPTION: Takes the resource linked list and parses it, creating a
348  *              byte stream of resources in the caller's output buffer
349  *
350  ******************************************************************************/
351
352 acpi_status
353 acpi_rs_list_to_byte_stream (
354         struct acpi_resource            *linked_list,
355         acpi_size                       byte_stream_size_needed,
356         u8                              *output_buffer)
357 {
358         acpi_status                     status;
359         u8                              *buffer = output_buffer;
360         acpi_size                       bytes_consumed = 0;
361         u8                              done = FALSE;
362
363
364         ACPI_FUNCTION_TRACE ("rs_list_to_byte_stream");
365
366
367         while (!done) {
368                 switch (linked_list->id) {
369                 case ACPI_RSTYPE_IRQ:
370                         /*
371                          * IRQ Resource
372                          */
373                         status = acpi_rs_irq_stream (linked_list, &buffer, &bytes_consumed);
374                         break;
375
376                 case ACPI_RSTYPE_DMA:
377                         /*
378                          * DMA Resource
379                          */
380                         status = acpi_rs_dma_stream (linked_list, &buffer, &bytes_consumed);
381                         break;
382
383                 case ACPI_RSTYPE_START_DPF:
384                         /*
385                          * Start Dependent Functions Resource
386                          */
387                         status = acpi_rs_start_depend_fns_stream (linked_list,
388                                           &buffer, &bytes_consumed);
389                         break;
390
391                 case ACPI_RSTYPE_END_DPF:
392                         /*
393                          * End Dependent Functions Resource
394                          */
395                         status = acpi_rs_end_depend_fns_stream (linked_list,
396                                           &buffer, &bytes_consumed);
397                         break;
398
399                 case ACPI_RSTYPE_IO:
400                         /*
401                          * IO Port Resource
402                          */
403                         status = acpi_rs_io_stream (linked_list, &buffer, &bytes_consumed);
404                         break;
405
406                 case ACPI_RSTYPE_FIXED_IO:
407                         /*
408                          * Fixed IO Port Resource
409                          */
410                         status = acpi_rs_fixed_io_stream (linked_list, &buffer, &bytes_consumed);
411                         break;
412
413                 case ACPI_RSTYPE_VENDOR:
414                         /*
415                          * Vendor Defined Resource
416                          */
417                         status = acpi_rs_vendor_stream (linked_list, &buffer, &bytes_consumed);
418                         break;
419
420                 case ACPI_RSTYPE_END_TAG:
421                         /*
422                          * End Tag
423                          */
424                         status = acpi_rs_end_tag_stream (linked_list, &buffer, &bytes_consumed);
425
426                         /*
427                          * An End Tag indicates the end of the Resource Template
428                          */
429                         done = TRUE;
430                         break;
431
432                 case ACPI_RSTYPE_MEM24:
433                         /*
434                          * 24-Bit Memory Resource
435                          */
436                         status = acpi_rs_memory24_stream (linked_list, &buffer, &bytes_consumed);
437                         break;
438
439                 case ACPI_RSTYPE_MEM32:
440                         /*
441                          * 32-Bit Memory Range Resource
442                          */
443                         status = acpi_rs_memory32_range_stream (linked_list, &buffer,
444                                          &bytes_consumed);
445                         break;
446
447                 case ACPI_RSTYPE_FIXED_MEM32:
448                         /*
449                          * 32-Bit Fixed Memory Resource
450                          */
451                         status = acpi_rs_fixed_memory32_stream (linked_list, &buffer,
452                                          &bytes_consumed);
453                         break;
454
455                 case ACPI_RSTYPE_ADDRESS16:
456                         /*
457                          * 16-Bit Address Descriptor Resource
458                          */
459                         status = acpi_rs_address16_stream (linked_list, &buffer,
460                                          &bytes_consumed);
461                         break;
462
463                 case ACPI_RSTYPE_ADDRESS32:
464                         /*
465                          * 32-Bit Address Descriptor Resource
466                          */
467                         status = acpi_rs_address32_stream (linked_list, &buffer,
468                                          &bytes_consumed);
469                         break;
470
471                 case ACPI_RSTYPE_ADDRESS64:
472                         /*
473                          * 64-Bit Address Descriptor Resource
474                          */
475                         status = acpi_rs_address64_stream (linked_list, &buffer,
476                                          &bytes_consumed);
477                         break;
478
479                 case ACPI_RSTYPE_EXT_IRQ:
480                         /*
481                          * Extended IRQ Resource
482                          */
483                         status = acpi_rs_extended_irq_stream (linked_list, &buffer,
484                                          &bytes_consumed);
485                         break;
486
487                 default:
488                         /*
489                          * If we get here, everything is out of sync,
490                          *  so exit with an error
491                          */
492                         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid descriptor type (%X) in resource list\n",
493                                 linked_list->id));
494                         status = AE_BAD_DATA;
495                         break;
496
497                 } /* switch (linked_list->Id) */
498
499                 if (ACPI_FAILURE (status)) {
500                         return_ACPI_STATUS (status);
501                 }
502
503                 /*
504                  * Set the Buffer to point to the open byte
505                  */
506                 buffer += bytes_consumed;
507
508                 /*
509                  * Point to the next object
510                  */
511                 linked_list = ACPI_PTR_ADD (struct acpi_resource,
512                                   linked_list, linked_list->length);
513         }
514
515         return_ACPI_STATUS (AE_OK);
516 }
517