Linux-2.6.12-rc2
[cascardo/linux.git] / drivers / acpi / resources / rslist.c
1 /*******************************************************************************
2  *
3  * Module Name: rslist - Linked list utilities
4  *
5  ******************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2005, 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                 case ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE:
182                         /*
183                          * 64-Bit Address Resource
184                          */
185                         status = acpi_rs_address64_resource (byte_stream_buffer,
186                                          &bytes_consumed, &buffer, &structure_size);
187                         break;
188
189
190                 case ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE:
191                         /*
192                          * 32-Bit Address Resource
193                          */
194                         status = acpi_rs_address32_resource (byte_stream_buffer,
195                                          &bytes_consumed, &buffer, &structure_size);
196                         break;
197
198
199                 case ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE:
200                         /*
201                          * 16-Bit Address Resource
202                          */
203                         status = acpi_rs_address16_resource (byte_stream_buffer,
204                                          &bytes_consumed, &buffer, &structure_size);
205                         break;
206
207
208                 case ACPI_RDESC_TYPE_EXTENDED_XRUPT:
209                         /*
210                          * Extended IRQ
211                          */
212                         status = acpi_rs_extended_irq_resource (byte_stream_buffer,
213                                          &bytes_consumed, &buffer, &structure_size);
214                         break;
215
216
217                 case ACPI_RDESC_TYPE_IRQ_FORMAT:
218                         /*
219                          * IRQ Resource
220                          */
221                         status = acpi_rs_irq_resource (byte_stream_buffer,
222                                          &bytes_consumed, &buffer, &structure_size);
223                         break;
224
225
226                 case ACPI_RDESC_TYPE_DMA_FORMAT:
227                         /*
228                          * DMA Resource
229                          */
230                         status = acpi_rs_dma_resource (byte_stream_buffer,
231                                          &bytes_consumed, &buffer, &structure_size);
232                         break;
233
234
235                 case ACPI_RDESC_TYPE_START_DEPENDENT:
236                         /*
237                          * Start Dependent Functions Resource
238                          */
239                         status = acpi_rs_start_depend_fns_resource (byte_stream_buffer,
240                                          &bytes_consumed, &buffer, &structure_size);
241                         break;
242
243
244                 case ACPI_RDESC_TYPE_END_DEPENDENT:
245                         /*
246                          * End Dependent Functions Resource
247                          */
248                         status = acpi_rs_end_depend_fns_resource (byte_stream_buffer,
249                                          &bytes_consumed, &buffer, &structure_size);
250                         break;
251
252
253                 case ACPI_RDESC_TYPE_IO_PORT:
254                         /*
255                          * IO Port Resource
256                          */
257                         status = acpi_rs_io_resource (byte_stream_buffer,
258                                          &bytes_consumed, &buffer, &structure_size);
259                         break;
260
261
262                 case ACPI_RDESC_TYPE_FIXED_IO_PORT:
263                         /*
264                          * Fixed IO Port Resource
265                          */
266                         status = acpi_rs_fixed_io_resource (byte_stream_buffer,
267                                          &bytes_consumed, &buffer, &structure_size);
268                         break;
269
270
271                 case ACPI_RDESC_TYPE_SMALL_VENDOR:
272                         /*
273                          * Vendor Specific Resource
274                          */
275                         status = acpi_rs_vendor_resource (byte_stream_buffer,
276                                          &bytes_consumed, &buffer, &structure_size);
277                         break;
278
279
280                 case ACPI_RDESC_TYPE_END_TAG:
281                         /*
282                          * End Tag
283                          */
284                         end_tag_processed = TRUE;
285                         status = acpi_rs_end_tag_resource (byte_stream_buffer,
286                                          &bytes_consumed, &buffer, &structure_size);
287                         break;
288
289
290                 default:
291                         /*
292                          * Invalid/Unknown resource type
293                          */
294                         status = AE_AML_INVALID_RESOURCE_TYPE;
295                         break;
296                 }
297
298                 if (ACPI_FAILURE (status)) {
299                         return_ACPI_STATUS (status);
300                 }
301
302                 /*
303                  * Update the return value and counter
304                  */
305                 bytes_parsed += bytes_consumed;
306
307                 /*
308                  * Set the byte stream to point to the next resource
309                  */
310                 byte_stream_buffer += bytes_consumed;
311
312                 /*
313                  * Set the Buffer to the next structure
314                  */
315                 resource = ACPI_CAST_PTR (struct acpi_resource, buffer);
316                 resource->length = (u32) ACPI_ALIGN_RESOURCE_SIZE (resource->length);
317                 buffer += ACPI_ALIGN_RESOURCE_SIZE (structure_size);
318
319         } /*  end while */
320
321         /*
322          * Check the reason for exiting the while loop
323          */
324         if (!end_tag_processed) {
325                 return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG);
326         }
327
328         return_ACPI_STATUS (AE_OK);
329 }
330
331
332 /*******************************************************************************
333  *
334  * FUNCTION:    acpi_rs_list_to_byte_stream
335  *
336  * PARAMETERS:  linked_list             - Pointer to the resource linked list
337  *              byte_steam_size_needed  - Calculated size of the byte stream
338  *                                        needed from calling
339  *                                        acpi_rs_get_byte_stream_length()
340  *                                        The size of the output_buffer is
341  *                                        guaranteed to be >=
342  *                                        byte_stream_size_needed
343  *              output_buffer           - Pointer to the buffer that will
344  *                                        contain the byte stream
345  *
346  * RETURN:      Status
347  *
348  * DESCRIPTION: Takes the resource linked list and parses it, creating a
349  *              byte stream of resources in the caller's output buffer
350  *
351  ******************************************************************************/
352
353 acpi_status
354 acpi_rs_list_to_byte_stream (
355         struct acpi_resource            *linked_list,
356         acpi_size                       byte_stream_size_needed,
357         u8                              *output_buffer)
358 {
359         acpi_status                     status;
360         u8                              *buffer = output_buffer;
361         acpi_size                       bytes_consumed = 0;
362         u8                              done = FALSE;
363
364
365         ACPI_FUNCTION_TRACE ("rs_list_to_byte_stream");
366
367
368         while (!done) {
369                 switch (linked_list->id) {
370                 case ACPI_RSTYPE_IRQ:
371                         /*
372                          * IRQ Resource
373                          */
374                         status = acpi_rs_irq_stream (linked_list, &buffer, &bytes_consumed);
375                         break;
376
377                 case ACPI_RSTYPE_DMA:
378                         /*
379                          * DMA Resource
380                          */
381                         status = acpi_rs_dma_stream (linked_list, &buffer, &bytes_consumed);
382                         break;
383
384                 case ACPI_RSTYPE_START_DPF:
385                         /*
386                          * Start Dependent Functions Resource
387                          */
388                         status = acpi_rs_start_depend_fns_stream (linked_list,
389                                           &buffer, &bytes_consumed);
390                         break;
391
392                 case ACPI_RSTYPE_END_DPF:
393                         /*
394                          * End Dependent Functions Resource
395                          */
396                         status = acpi_rs_end_depend_fns_stream (linked_list,
397                                           &buffer, &bytes_consumed);
398                         break;
399
400                 case ACPI_RSTYPE_IO:
401                         /*
402                          * IO Port Resource
403                          */
404                         status = acpi_rs_io_stream (linked_list, &buffer, &bytes_consumed);
405                         break;
406
407                 case ACPI_RSTYPE_FIXED_IO:
408                         /*
409                          * Fixed IO Port Resource
410                          */
411                         status = acpi_rs_fixed_io_stream (linked_list, &buffer, &bytes_consumed);
412                         break;
413
414                 case ACPI_RSTYPE_VENDOR:
415                         /*
416                          * Vendor Defined Resource
417                          */
418                         status = acpi_rs_vendor_stream (linked_list, &buffer, &bytes_consumed);
419                         break;
420
421                 case ACPI_RSTYPE_END_TAG:
422                         /*
423                          * End Tag
424                          */
425                         status = acpi_rs_end_tag_stream (linked_list, &buffer, &bytes_consumed);
426
427                         /*
428                          * An End Tag indicates the end of the Resource Template
429                          */
430                         done = TRUE;
431                         break;
432
433                 case ACPI_RSTYPE_MEM24:
434                         /*
435                          * 24-Bit Memory Resource
436                          */
437                         status = acpi_rs_memory24_stream (linked_list, &buffer, &bytes_consumed);
438                         break;
439
440                 case ACPI_RSTYPE_MEM32:
441                         /*
442                          * 32-Bit Memory Range Resource
443                          */
444                         status = acpi_rs_memory32_range_stream (linked_list, &buffer,
445                                          &bytes_consumed);
446                         break;
447
448                 case ACPI_RSTYPE_FIXED_MEM32:
449                         /*
450                          * 32-Bit Fixed Memory Resource
451                          */
452                         status = acpi_rs_fixed_memory32_stream (linked_list, &buffer,
453                                          &bytes_consumed);
454                         break;
455
456                 case ACPI_RSTYPE_ADDRESS16:
457                         /*
458                          * 16-Bit Address Descriptor Resource
459                          */
460                         status = acpi_rs_address16_stream (linked_list, &buffer,
461                                          &bytes_consumed);
462                         break;
463
464                 case ACPI_RSTYPE_ADDRESS32:
465                         /*
466                          * 32-Bit Address Descriptor Resource
467                          */
468                         status = acpi_rs_address32_stream (linked_list, &buffer,
469                                          &bytes_consumed);
470                         break;
471
472                 case ACPI_RSTYPE_ADDRESS64:
473                         /*
474                          * 64-Bit Address Descriptor Resource
475                          */
476                         status = acpi_rs_address64_stream (linked_list, &buffer,
477                                          &bytes_consumed);
478                         break;
479
480                 case ACPI_RSTYPE_EXT_IRQ:
481                         /*
482                          * Extended IRQ Resource
483                          */
484                         status = acpi_rs_extended_irq_stream (linked_list, &buffer,
485                                          &bytes_consumed);
486                         break;
487
488                 default:
489                         /*
490                          * If we get here, everything is out of sync,
491                          *  so exit with an error
492                          */
493                         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid descriptor type (%X) in resource list\n",
494                                 linked_list->id));
495                         status = AE_BAD_DATA;
496                         break;
497
498                 } /* switch (linked_list->Id) */
499
500                 if (ACPI_FAILURE (status)) {
501                         return_ACPI_STATUS (status);
502                 }
503
504                 /*
505                  * Set the Buffer to point to the open byte
506                  */
507                 buffer += bytes_consumed;
508
509                 /*
510                  * Point to the next object
511                  */
512                 linked_list = ACPI_PTR_ADD (struct acpi_resource,
513                                   linked_list, linked_list->length);
514         }
515
516         return_ACPI_STATUS (AE_OK);
517 }
518