blob: 23a4d149fac88d4b62534636e64a439ce55f3a08 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*******************************************************************************
2 *
3 * Module Name: rsio - IO and DMA resource descriptors
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 ("rsio")
50
51
52/*******************************************************************************
53 *
54 * FUNCTION: acpi_rs_io_resource
55 *
56 * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte
57 * stream
58 * bytes_consumed - Pointer to where the number of bytes
59 * consumed the byte_stream_buffer is
60 * returned
61 * output_buffer - Pointer to the return data buffer
62 * structure_size - Pointer to where the number of bytes
63 * in the return data struct is returned
64 *
65 * RETURN: Status
66 *
67 * DESCRIPTION: Take the resource byte stream and fill out the appropriate
68 * structure pointed to by the output_buffer. Return the
69 * number of bytes consumed from the byte stream.
70 *
71 ******************************************************************************/
72
73acpi_status
74acpi_rs_io_resource (
75 u8 *byte_stream_buffer,
76 acpi_size *bytes_consumed,
77 u8 **output_buffer,
78 acpi_size *structure_size)
79{
80 u8 *buffer = byte_stream_buffer;
81 struct acpi_resource *output_struct = (void *) *output_buffer;
82 u16 temp16 = 0;
83 u8 temp8 = 0;
Robert Moore44f6c012005-04-18 22:49:35 -040084 acpi_size struct_size = ACPI_SIZEOF_RESOURCE (
85 struct acpi_resource_io);
Linus Torvalds1da177e2005-04-16 15:20:36 -070086
87
88 ACPI_FUNCTION_TRACE ("rs_io_resource");
89
90
Robert Moore44f6c012005-04-18 22:49:35 -040091 /* The number of bytes consumed are Constant */
92
Linus Torvalds1da177e2005-04-16 15:20:36 -070093 *bytes_consumed = 8;
94
95 output_struct->id = ACPI_RSTYPE_IO;
96
Robert Moore44f6c012005-04-18 22:49:35 -040097 /* Check Decode */
98
Linus Torvalds1da177e2005-04-16 15:20:36 -070099 buffer += 1;
100 temp8 = *buffer;
101
102 output_struct->data.io.io_decode = temp8 & 0x01;
103
Robert Moore44f6c012005-04-18 22:49:35 -0400104 /* Check min_base Address */
105
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106 buffer += 1;
107 ACPI_MOVE_16_TO_16 (&temp16, buffer);
108
109 output_struct->data.io.min_base_address = temp16;
110
Robert Moore44f6c012005-04-18 22:49:35 -0400111 /* Check max_base Address */
112
Linus Torvalds1da177e2005-04-16 15:20:36 -0700113 buffer += 2;
114 ACPI_MOVE_16_TO_16 (&temp16, buffer);
115
116 output_struct->data.io.max_base_address = temp16;
117
Robert Moore44f6c012005-04-18 22:49:35 -0400118 /* Check Base alignment */
119
Linus Torvalds1da177e2005-04-16 15:20:36 -0700120 buffer += 2;
121 temp8 = *buffer;
122
123 output_struct->data.io.alignment = temp8;
124
Robert Moore44f6c012005-04-18 22:49:35 -0400125 /* Check range_length */
126
Linus Torvalds1da177e2005-04-16 15:20:36 -0700127 buffer += 1;
128 temp8 = *buffer;
129
130 output_struct->data.io.range_length = temp8;
131
Robert Moore44f6c012005-04-18 22:49:35 -0400132 /* Set the Length parameter */
133
Linus Torvalds1da177e2005-04-16 15:20:36 -0700134 output_struct->length = (u32) struct_size;
135
Robert Moore44f6c012005-04-18 22:49:35 -0400136 /* Return the final size of the structure */
137
Linus Torvalds1da177e2005-04-16 15:20:36 -0700138 *structure_size = struct_size;
139 return_ACPI_STATUS (AE_OK);
140}
141
142
143/*******************************************************************************
144 *
145 * FUNCTION: acpi_rs_fixed_io_resource
146 *
147 * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte
148 * stream
149 * bytes_consumed - Pointer to where the number of bytes
150 * consumed the byte_stream_buffer is
151 * returned
152 * output_buffer - Pointer to the return data buffer
153 * structure_size - Pointer to where the number of bytes
154 * in the return data struct is returned
155 *
156 * RETURN: Status
157 *
158 * DESCRIPTION: Take the resource byte stream and fill out the appropriate
159 * structure pointed to by the output_buffer. Return the
160 * number of bytes consumed from the byte stream.
161 *
162 ******************************************************************************/
163
164acpi_status
165acpi_rs_fixed_io_resource (
166 u8 *byte_stream_buffer,
167 acpi_size *bytes_consumed,
168 u8 **output_buffer,
169 acpi_size *structure_size)
170{
171 u8 *buffer = byte_stream_buffer;
172 struct acpi_resource *output_struct = (void *) *output_buffer;
173 u16 temp16 = 0;
174 u8 temp8 = 0;
Robert Moore44f6c012005-04-18 22:49:35 -0400175 acpi_size struct_size = ACPI_SIZEOF_RESOURCE (
176 struct acpi_resource_fixed_io);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700177
178
179 ACPI_FUNCTION_TRACE ("rs_fixed_io_resource");
180
181
Robert Moore44f6c012005-04-18 22:49:35 -0400182 /* The number of bytes consumed are Constant */
183
Linus Torvalds1da177e2005-04-16 15:20:36 -0700184 *bytes_consumed = 4;
185
186 output_struct->id = ACPI_RSTYPE_FIXED_IO;
187
Robert Moore44f6c012005-04-18 22:49:35 -0400188 /* Check Range Base Address */
189
Linus Torvalds1da177e2005-04-16 15:20:36 -0700190 buffer += 1;
191 ACPI_MOVE_16_TO_16 (&temp16, buffer);
192
193 output_struct->data.fixed_io.base_address = temp16;
194
Robert Moore44f6c012005-04-18 22:49:35 -0400195 /* Check range_length */
196
Linus Torvalds1da177e2005-04-16 15:20:36 -0700197 buffer += 2;
198 temp8 = *buffer;
199
200 output_struct->data.fixed_io.range_length = temp8;
201
Robert Moore44f6c012005-04-18 22:49:35 -0400202 /* Set the Length parameter */
203
Linus Torvalds1da177e2005-04-16 15:20:36 -0700204 output_struct->length = (u32) struct_size;
205
Robert Moore44f6c012005-04-18 22:49:35 -0400206 /* Return the final size of the structure */
207
Linus Torvalds1da177e2005-04-16 15:20:36 -0700208 *structure_size = struct_size;
209 return_ACPI_STATUS (AE_OK);
210}
211
212
213/*******************************************************************************
214 *
215 * FUNCTION: acpi_rs_io_stream
216 *
217 * PARAMETERS: linked_list - Pointer to the resource linked list
218 * output_buffer - Pointer to the user's return buffer
219 * bytes_consumed - Pointer to where the number of bytes
220 * used in the output_buffer is returned
221 *
222 * RETURN: Status
223 *
224 * DESCRIPTION: Take the linked list resource structure and fills in the
225 * the appropriate bytes in a byte stream
226 *
227 ******************************************************************************/
228
229acpi_status
230acpi_rs_io_stream (
231 struct acpi_resource *linked_list,
232 u8 **output_buffer,
233 acpi_size *bytes_consumed)
234{
235 u8 *buffer = *output_buffer;
236 u16 temp16 = 0;
237 u8 temp8 = 0;
238
239
240 ACPI_FUNCTION_TRACE ("rs_io_stream");
241
242
Robert Moore44f6c012005-04-18 22:49:35 -0400243 /* The descriptor field is static */
244
Linus Torvalds1da177e2005-04-16 15:20:36 -0700245 *buffer = 0x47;
246 buffer += 1;
247
Robert Moore44f6c012005-04-18 22:49:35 -0400248 /* Io Information Byte */
249
Linus Torvalds1da177e2005-04-16 15:20:36 -0700250 temp8 = (u8) (linked_list->data.io.io_decode & 0x01);
251
252 *buffer = temp8;
253 buffer += 1;
254
Robert Moore44f6c012005-04-18 22:49:35 -0400255 /* Set the Range minimum base address */
256
Linus Torvalds1da177e2005-04-16 15:20:36 -0700257 temp16 = (u16) linked_list->data.io.min_base_address;
258
259 ACPI_MOVE_16_TO_16 (buffer, &temp16);
260 buffer += 2;
261
Robert Moore44f6c012005-04-18 22:49:35 -0400262 /* Set the Range maximum base address */
263
Linus Torvalds1da177e2005-04-16 15:20:36 -0700264 temp16 = (u16) linked_list->data.io.max_base_address;
265
266 ACPI_MOVE_16_TO_16 (buffer, &temp16);
267 buffer += 2;
268
Robert Moore44f6c012005-04-18 22:49:35 -0400269 /* Set the base alignment */
270
Linus Torvalds1da177e2005-04-16 15:20:36 -0700271 temp8 = (u8) linked_list->data.io.alignment;
272
273 *buffer = temp8;
274 buffer += 1;
275
Robert Moore44f6c012005-04-18 22:49:35 -0400276 /* Set the range length */
277
Linus Torvalds1da177e2005-04-16 15:20:36 -0700278 temp8 = (u8) linked_list->data.io.range_length;
279
280 *buffer = temp8;
281 buffer += 1;
282
Robert Moore44f6c012005-04-18 22:49:35 -0400283 /* Return the number of bytes consumed in this operation */
284
Linus Torvalds1da177e2005-04-16 15:20:36 -0700285 *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
286 return_ACPI_STATUS (AE_OK);
287}
288
289
290/*******************************************************************************
291 *
292 * FUNCTION: acpi_rs_fixed_io_stream
293 *
294 * PARAMETERS: linked_list - Pointer to the resource linked list
295 * output_buffer - Pointer to the user's return buffer
296 * bytes_consumed - Pointer to where the number of bytes
297 * used in the output_buffer is returned
298 *
299 * RETURN: Status
300 *
301 * DESCRIPTION: Take the linked list resource structure and fills in the
302 * the appropriate bytes in a byte stream
303 *
304 ******************************************************************************/
305
306acpi_status
307acpi_rs_fixed_io_stream (
308 struct acpi_resource *linked_list,
309 u8 **output_buffer,
310 acpi_size *bytes_consumed)
311{
312 u8 *buffer = *output_buffer;
313 u16 temp16 = 0;
314 u8 temp8 = 0;
315
316
317 ACPI_FUNCTION_TRACE ("rs_fixed_io_stream");
318
319
Robert Moore44f6c012005-04-18 22:49:35 -0400320 /* The descriptor field is static */
321
Linus Torvalds1da177e2005-04-16 15:20:36 -0700322 *buffer = 0x4B;
323
324 buffer += 1;
325
Robert Moore44f6c012005-04-18 22:49:35 -0400326 /* Set the Range base address */
327
Linus Torvalds1da177e2005-04-16 15:20:36 -0700328 temp16 = (u16) linked_list->data.fixed_io.base_address;
329
330 ACPI_MOVE_16_TO_16 (buffer, &temp16);
331 buffer += 2;
332
Robert Moore44f6c012005-04-18 22:49:35 -0400333 /* Set the range length */
334
Linus Torvalds1da177e2005-04-16 15:20:36 -0700335 temp8 = (u8) linked_list->data.fixed_io.range_length;
336
337 *buffer = temp8;
338 buffer += 1;
339
Robert Moore44f6c012005-04-18 22:49:35 -0400340 /* Return the number of bytes consumed in this operation */
341
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342 *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
343 return_ACPI_STATUS (AE_OK);
344}
345
346
347/*******************************************************************************
348 *
349 * FUNCTION: acpi_rs_dma_resource
350 *
351 * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte
352 * stream
353 * bytes_consumed - Pointer to where the number of bytes
354 * consumed the byte_stream_buffer is
355 * returned
356 * output_buffer - Pointer to the return data buffer
357 * structure_size - Pointer to where the number of bytes
358 * in the return data struct is returned
359 *
360 * RETURN: Status
361 *
362 * DESCRIPTION: Take the resource byte stream and fill out the appropriate
363 * structure pointed to by the output_buffer. Return the
364 * number of bytes consumed from the byte stream.
365 *
366 ******************************************************************************/
367
368acpi_status
369acpi_rs_dma_resource (
370 u8 *byte_stream_buffer,
371 acpi_size *bytes_consumed,
372 u8 **output_buffer,
373 acpi_size *structure_size)
374{
375 u8 *buffer = byte_stream_buffer;
376 struct acpi_resource *output_struct = (void *) *output_buffer;
377 u8 temp8 = 0;
378 u8 index;
379 u8 i;
Robert Moore44f6c012005-04-18 22:49:35 -0400380 acpi_size struct_size = ACPI_SIZEOF_RESOURCE (
381 struct acpi_resource_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700382
383
384 ACPI_FUNCTION_TRACE ("rs_dma_resource");
385
386
Robert Moore44f6c012005-04-18 22:49:35 -0400387 /* The number of bytes consumed are Constant */
388
Linus Torvalds1da177e2005-04-16 15:20:36 -0700389 *bytes_consumed = 3;
390 output_struct->id = ACPI_RSTYPE_DMA;
391
Robert Moore44f6c012005-04-18 22:49:35 -0400392 /* Point to the 8-bits of Byte 1 */
393
Linus Torvalds1da177e2005-04-16 15:20:36 -0700394 buffer += 1;
395 temp8 = *buffer;
396
397 /* Decode the DMA channel bits */
398
399 for (i = 0, index = 0; index < 8; index++) {
400 if ((temp8 >> index) & 0x01) {
401 output_struct->data.dma.channels[i] = index;
402 i++;
403 }
404 }
405
406 /* Zero DMA channels is valid */
407
408 output_struct->data.dma.number_of_channels = i;
409 if (i > 0) {
Robert Moore44f6c012005-04-18 22:49:35 -0400410 /* Calculate the structure size based upon the number of interrupts */
411
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412 struct_size += ((acpi_size) i - 1) * 4;
413 }
414
Robert Moore44f6c012005-04-18 22:49:35 -0400415 /* Point to Byte 2 */
416
Linus Torvalds1da177e2005-04-16 15:20:36 -0700417 buffer += 1;
418 temp8 = *buffer;
419
Robert Moore44f6c012005-04-18 22:49:35 -0400420 /* Check for transfer preference (Bits[1:0]) */
421
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422 output_struct->data.dma.transfer = temp8 & 0x03;
423
424 if (0x03 == output_struct->data.dma.transfer) {
Robert Moore44f6c012005-04-18 22:49:35 -0400425 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
426 "Invalid DMA.Transfer preference (3)\n"));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700427 return_ACPI_STATUS (AE_BAD_DATA);
428 }
429
Robert Moore44f6c012005-04-18 22:49:35 -0400430 /* Get bus master preference (Bit[2]) */
431
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432 output_struct->data.dma.bus_master = (temp8 >> 2) & 0x01;
433
Robert Moore44f6c012005-04-18 22:49:35 -0400434 /* Get channel speed support (Bits[6:5]) */
435
Linus Torvalds1da177e2005-04-16 15:20:36 -0700436 output_struct->data.dma.type = (temp8 >> 5) & 0x03;
437
Robert Moore44f6c012005-04-18 22:49:35 -0400438 /* Set the Length parameter */
439
Linus Torvalds1da177e2005-04-16 15:20:36 -0700440 output_struct->length = (u32) struct_size;
441
Robert Moore44f6c012005-04-18 22:49:35 -0400442 /* Return the final size of the structure */
443
Linus Torvalds1da177e2005-04-16 15:20:36 -0700444 *structure_size = struct_size;
445 return_ACPI_STATUS (AE_OK);
446}
447
448
449/*******************************************************************************
450 *
451 * FUNCTION: acpi_rs_dma_stream
452 *
453 * PARAMETERS: linked_list - Pointer to the resource linked list
454 * output_buffer - Pointer to the user's return buffer
455 * bytes_consumed - Pointer to where the number of bytes
456 * used in the output_buffer is returned
457 *
458 * RETURN: Status
459 *
460 * DESCRIPTION: Take the linked list resource structure and fills in the
461 * the appropriate bytes in a byte stream
462 *
463 ******************************************************************************/
464
465acpi_status
466acpi_rs_dma_stream (
467 struct acpi_resource *linked_list,
468 u8 **output_buffer,
469 acpi_size *bytes_consumed)
470{
471 u8 *buffer = *output_buffer;
472 u16 temp16 = 0;
473 u8 temp8 = 0;
474 u8 index;
475
476
477 ACPI_FUNCTION_TRACE ("rs_dma_stream");
478
479
Robert Moore44f6c012005-04-18 22:49:35 -0400480 /* The descriptor field is static */
481
Linus Torvalds1da177e2005-04-16 15:20:36 -0700482 *buffer = 0x2A;
483 buffer += 1;
484 temp8 = 0;
485
Robert Moore44f6c012005-04-18 22:49:35 -0400486 /* Loop through all of the Channels and set the mask bits */
487
Linus Torvalds1da177e2005-04-16 15:20:36 -0700488 for (index = 0;
489 index < linked_list->data.dma.number_of_channels;
490 index++) {
491 temp16 = (u16) linked_list->data.dma.channels[index];
492 temp8 |= 0x1 << temp16;
493 }
494
495 *buffer = temp8;
496 buffer += 1;
497
Robert Moore44f6c012005-04-18 22:49:35 -0400498 /* Set the DMA Info */
499
Linus Torvalds1da177e2005-04-16 15:20:36 -0700500 temp8 = (u8) ((linked_list->data.dma.type & 0x03) << 5);
501 temp8 |= ((linked_list->data.dma.bus_master & 0x01) << 2);
502 temp8 |= (linked_list->data.dma.transfer & 0x03);
503
504 *buffer = temp8;
505 buffer += 1;
506
Robert Moore44f6c012005-04-18 22:49:35 -0400507 /* Return the number of bytes consumed in this operation */
508
Linus Torvalds1da177e2005-04-16 15:20:36 -0700509 *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
510 return_ACPI_STATUS (AE_OK);
511}
512