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