Merge branch 'master' of /home/tglx/work/mtd/git/linux-2.6.git/
[linux-2.6] / 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 #include <acpi/acpi.h>
45 #include <acpi/acresrc.h>
46
47 #define _COMPONENT          ACPI_RESOURCES
48 ACPI_MODULE_NAME("rslist")
49
50 /*******************************************************************************
51  *
52  * FUNCTION:    acpi_rs_get_resource_type
53  *
54  * PARAMETERS:  resource_start_byte     - Byte 0 of a resource descriptor
55  *
56  * RETURN:      The Resource Type with no extraneous bits
57  *
58  * DESCRIPTION: Extract the Resource Type/Name from the first byte of
59  *              a resource descriptor.
60  *
61  ******************************************************************************/
62 u8 acpi_rs_get_resource_type(u8 resource_start_byte)
63 {
64
65         ACPI_FUNCTION_ENTRY();
66
67         /* Determine if this is a small or large resource */
68
69         switch (resource_start_byte & ACPI_RDESC_TYPE_MASK) {
70         case ACPI_RDESC_TYPE_SMALL:
71
72                 /* Small Resource Type -- Only bits 6:3 are valid */
73
74                 return ((u8) (resource_start_byte & ACPI_RDESC_SMALL_MASK));
75
76         case ACPI_RDESC_TYPE_LARGE:
77
78                 /* Large Resource Type -- All bits are valid */
79
80                 return (resource_start_byte);
81
82         default:
83                 /* Invalid type */
84                 break;
85         }
86
87         return (0xFF);
88 }
89
90 /*******************************************************************************
91  *
92  * FUNCTION:    acpi_rs_byte_stream_to_list
93  *
94  * PARAMETERS:  byte_stream_buffer      - Pointer to the resource byte stream
95  *              byte_stream_buffer_length - Length of byte_stream_buffer
96  *              output_buffer           - Pointer to the buffer that will
97  *                                        contain the output structures
98  *
99  * RETURN:      Status
100  *
101  * DESCRIPTION: Takes the resource byte stream and parses it, creating a
102  *              linked list of resources in the caller's output buffer
103  *
104  ******************************************************************************/
105
106 acpi_status
107 acpi_rs_byte_stream_to_list(u8 * byte_stream_buffer,
108                             u32 byte_stream_buffer_length, u8 * output_buffer)
109 {
110         acpi_status status;
111         acpi_size bytes_parsed = 0;
112         u8 resource_type = 0;
113         acpi_size bytes_consumed = 0;
114         u8 *buffer = output_buffer;
115         acpi_size structure_size = 0;
116         u8 end_tag_processed = FALSE;
117         struct acpi_resource *resource;
118
119         ACPI_FUNCTION_TRACE("rs_byte_stream_to_list");
120
121         while (bytes_parsed < byte_stream_buffer_length && !end_tag_processed) {
122                 /* The next byte in the stream is the resource type */
123
124                 resource_type = acpi_rs_get_resource_type(*byte_stream_buffer);
125
126                 switch (resource_type) {
127                 case ACPI_RDESC_TYPE_MEMORY_24:
128                         /*
129                          * 24-Bit Memory Resource
130                          */
131                         status = acpi_rs_memory24_resource(byte_stream_buffer,
132                                                            &bytes_consumed,
133                                                            &buffer,
134                                                            &structure_size);
135                         break;
136
137                 case ACPI_RDESC_TYPE_LARGE_VENDOR:
138                         /*
139                          * Vendor Defined Resource
140                          */
141                         status = acpi_rs_vendor_resource(byte_stream_buffer,
142                                                          &bytes_consumed,
143                                                          &buffer,
144                                                          &structure_size);
145                         break;
146
147                 case ACPI_RDESC_TYPE_MEMORY_32:
148                         /*
149                          * 32-Bit Memory Range Resource
150                          */
151                         status =
152                             acpi_rs_memory32_range_resource(byte_stream_buffer,
153                                                             &bytes_consumed,
154                                                             &buffer,
155                                                             &structure_size);
156                         break;
157
158                 case ACPI_RDESC_TYPE_FIXED_MEMORY_32:
159                         /*
160                          * 32-Bit Fixed Memory Resource
161                          */
162                         status =
163                             acpi_rs_fixed_memory32_resource(byte_stream_buffer,
164                                                             &bytes_consumed,
165                                                             &buffer,
166                                                             &structure_size);
167                         break;
168
169                 case ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE:
170                 case ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE:
171                         /*
172                          * 64-Bit Address Resource
173                          */
174                         status = acpi_rs_address64_resource(byte_stream_buffer,
175                                                             &bytes_consumed,
176                                                             &buffer,
177                                                             &structure_size);
178                         break;
179
180                 case ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE:
181                         /*
182                          * 32-Bit Address Resource
183                          */
184                         status = acpi_rs_address32_resource(byte_stream_buffer,
185                                                             &bytes_consumed,
186                                                             &buffer,
187                                                             &structure_size);
188                         break;
189
190                 case ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE:
191                         /*
192                          * 16-Bit Address Resource
193                          */
194                         status = acpi_rs_address16_resource(byte_stream_buffer,
195                                                             &bytes_consumed,
196                                                             &buffer,
197                                                             &structure_size);
198                         break;
199
200                 case ACPI_RDESC_TYPE_EXTENDED_XRUPT:
201                         /*
202                          * Extended IRQ
203                          */
204                         status =
205                             acpi_rs_extended_irq_resource(byte_stream_buffer,
206                                                           &bytes_consumed,
207                                                           &buffer,
208                                                           &structure_size);
209                         break;
210
211                 case ACPI_RDESC_TYPE_IRQ_FORMAT:
212                         /*
213                          * IRQ Resource
214                          */
215                         status = acpi_rs_irq_resource(byte_stream_buffer,
216                                                       &bytes_consumed, &buffer,
217                                                       &structure_size);
218                         break;
219
220                 case ACPI_RDESC_TYPE_DMA_FORMAT:
221                         /*
222                          * DMA Resource
223                          */
224                         status = acpi_rs_dma_resource(byte_stream_buffer,
225                                                       &bytes_consumed, &buffer,
226                                                       &structure_size);
227                         break;
228
229                 case ACPI_RDESC_TYPE_START_DEPENDENT:
230                         /*
231                          * Start Dependent Functions Resource
232                          */
233                         status =
234                             acpi_rs_start_depend_fns_resource
235                             (byte_stream_buffer, &bytes_consumed, &buffer,
236                              &structure_size);
237                         break;
238
239                 case ACPI_RDESC_TYPE_END_DEPENDENT:
240                         /*
241                          * End Dependent Functions Resource
242                          */
243                         status =
244                             acpi_rs_end_depend_fns_resource(byte_stream_buffer,
245                                                             &bytes_consumed,
246                                                             &buffer,
247                                                             &structure_size);
248                         break;
249
250                 case ACPI_RDESC_TYPE_IO_PORT:
251                         /*
252                          * IO Port Resource
253                          */
254                         status = acpi_rs_io_resource(byte_stream_buffer,
255                                                      &bytes_consumed, &buffer,
256                                                      &structure_size);
257                         break;
258
259                 case ACPI_RDESC_TYPE_FIXED_IO_PORT:
260                         /*
261                          * Fixed IO Port Resource
262                          */
263                         status = acpi_rs_fixed_io_resource(byte_stream_buffer,
264                                                            &bytes_consumed,
265                                                            &buffer,
266                                                            &structure_size);
267                         break;
268
269                 case ACPI_RDESC_TYPE_SMALL_VENDOR:
270                         /*
271                          * Vendor Specific Resource
272                          */
273                         status = acpi_rs_vendor_resource(byte_stream_buffer,
274                                                          &bytes_consumed,
275                                                          &buffer,
276                                                          &structure_size);
277                         break;
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,
286                                                           &buffer,
287                                                           &structure_size);
288                         break;
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                 /* Update the return value and counter */
303
304                 bytes_parsed += bytes_consumed;
305
306                 /* Set the byte stream to point to the next resource */
307
308                 byte_stream_buffer += bytes_consumed;
309
310                 /* Set the Buffer to the next structure */
311
312                 resource = ACPI_CAST_PTR(struct acpi_resource, buffer);
313                 resource->length =
314                     (u32) ACPI_ALIGN_RESOURCE_SIZE(resource->length);
315                 buffer += ACPI_ALIGN_RESOURCE_SIZE(structure_size);
316         }
317
318         /* Check the reason for exiting the while loop */
319
320         if (!end_tag_processed) {
321                 return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
322         }
323
324         return_ACPI_STATUS(AE_OK);
325 }
326
327 /*******************************************************************************
328  *
329  * FUNCTION:    acpi_rs_list_to_byte_stream
330  *
331  * PARAMETERS:  linked_list             - Pointer to the resource linked list
332  *              byte_steam_size_needed  - Calculated size of the byte stream
333  *                                        needed from calling
334  *                                        acpi_rs_get_byte_stream_length()
335  *                                        The size of the output_buffer is
336  *                                        guaranteed to be >=
337  *                                        byte_stream_size_needed
338  *              output_buffer           - Pointer to the buffer that will
339  *                                        contain the byte stream
340  *
341  * RETURN:      Status
342  *
343  * DESCRIPTION: Takes the resource linked list and parses it, creating a
344  *              byte stream of resources in the caller's output buffer
345  *
346  ******************************************************************************/
347
348 acpi_status
349 acpi_rs_list_to_byte_stream(struct acpi_resource *linked_list,
350                             acpi_size byte_stream_size_needed,
351                             u8 * output_buffer)
352 {
353         acpi_status status;
354         u8 *buffer = output_buffer;
355         acpi_size bytes_consumed = 0;
356         u8 done = FALSE;
357
358         ACPI_FUNCTION_TRACE("rs_list_to_byte_stream");
359
360         while (!done) {
361                 switch (linked_list->id) {
362                 case ACPI_RSTYPE_IRQ:
363                         /*
364                          * IRQ Resource
365                          */
366                         status =
367                             acpi_rs_irq_stream(linked_list, &buffer,
368                                                &bytes_consumed);
369                         break;
370
371                 case ACPI_RSTYPE_DMA:
372                         /*
373                          * DMA Resource
374                          */
375                         status =
376                             acpi_rs_dma_stream(linked_list, &buffer,
377                                                &bytes_consumed);
378                         break;
379
380                 case ACPI_RSTYPE_START_DPF:
381                         /*
382                          * Start Dependent Functions Resource
383                          */
384                         status = acpi_rs_start_depend_fns_stream(linked_list,
385                                                                  &buffer,
386                                                                  &bytes_consumed);
387                         break;
388
389                 case ACPI_RSTYPE_END_DPF:
390                         /*
391                          * End Dependent Functions Resource
392                          */
393                         status = acpi_rs_end_depend_fns_stream(linked_list,
394                                                                &buffer,
395                                                                &bytes_consumed);
396                         break;
397
398                 case ACPI_RSTYPE_IO:
399                         /*
400                          * IO Port Resource
401                          */
402                         status =
403                             acpi_rs_io_stream(linked_list, &buffer,
404                                               &bytes_consumed);
405                         break;
406
407                 case ACPI_RSTYPE_FIXED_IO:
408                         /*
409                          * Fixed IO Port Resource
410                          */
411                         status =
412                             acpi_rs_fixed_io_stream(linked_list, &buffer,
413                                                     &bytes_consumed);
414                         break;
415
416                 case ACPI_RSTYPE_VENDOR:
417                         /*
418                          * Vendor Defined Resource
419                          */
420                         status =
421                             acpi_rs_vendor_stream(linked_list, &buffer,
422                                                   &bytes_consumed);
423                         break;
424
425                 case ACPI_RSTYPE_END_TAG:
426                         /*
427                          * End Tag
428                          */
429                         status =
430                             acpi_rs_end_tag_stream(linked_list, &buffer,
431                                                    &bytes_consumed);
432
433                         /* An End Tag indicates the end of the Resource Template */
434
435                         done = TRUE;
436                         break;
437
438                 case ACPI_RSTYPE_MEM24:
439                         /*
440                          * 24-Bit Memory Resource
441                          */
442                         status =
443                             acpi_rs_memory24_stream(linked_list, &buffer,
444                                                     &bytes_consumed);
445                         break;
446
447                 case ACPI_RSTYPE_MEM32:
448                         /*
449                          * 32-Bit Memory Range Resource
450                          */
451                         status =
452                             acpi_rs_memory32_range_stream(linked_list, &buffer,
453                                                           &bytes_consumed);
454                         break;
455
456                 case ACPI_RSTYPE_FIXED_MEM32:
457                         /*
458                          * 32-Bit Fixed Memory Resource
459                          */
460                         status =
461                             acpi_rs_fixed_memory32_stream(linked_list, &buffer,
462                                                           &bytes_consumed);
463                         break;
464
465                 case ACPI_RSTYPE_ADDRESS16:
466                         /*
467                          * 16-Bit Address Descriptor Resource
468                          */
469                         status = acpi_rs_address16_stream(linked_list, &buffer,
470                                                           &bytes_consumed);
471                         break;
472
473                 case ACPI_RSTYPE_ADDRESS32:
474                         /*
475                          * 32-Bit Address Descriptor Resource
476                          */
477                         status = acpi_rs_address32_stream(linked_list, &buffer,
478                                                           &bytes_consumed);
479                         break;
480
481                 case ACPI_RSTYPE_ADDRESS64:
482                         /*
483                          * 64-Bit Address Descriptor Resource
484                          */
485                         status = acpi_rs_address64_stream(linked_list, &buffer,
486                                                           &bytes_consumed);
487                         break;
488
489                 case ACPI_RSTYPE_EXT_IRQ:
490                         /*
491                          * Extended IRQ Resource
492                          */
493                         status =
494                             acpi_rs_extended_irq_stream(linked_list, &buffer,
495                                                         &bytes_consumed);
496                         break;
497
498                 default:
499                         /*
500                          * If we get here, everything is out of sync,
501                          * so exit with an error
502                          */
503                         ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
504                                           "Invalid descriptor type (%X) in resource list\n",
505                                           linked_list->id));
506                         status = AE_BAD_DATA;
507                         break;
508                 }
509
510                 if (ACPI_FAILURE(status)) {
511                         return_ACPI_STATUS(status);
512                 }
513
514                 /* Set the Buffer to point to the open byte */
515
516                 buffer += bytes_consumed;
517
518                 /* Point to the next object */
519
520                 linked_list = ACPI_PTR_ADD(struct acpi_resource,
521                                            linked_list, linked_list->length);
522         }
523
524         return_ACPI_STATUS(AE_OK);
525 }