]>
Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /******************************************************************************* |
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 | ||
73 | acpi_status | |
74 | acpi_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; | |
84 | acpi_size struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_io); | |
85 | ||
86 | ||
87 | ACPI_FUNCTION_TRACE ("rs_io_resource"); | |
88 | ||
89 | ||
90 | /* | |
91 | * The number of bytes consumed are Constant | |
92 | */ | |
93 | *bytes_consumed = 8; | |
94 | ||
95 | output_struct->id = ACPI_RSTYPE_IO; | |
96 | ||
97 | /* | |
98 | * Check Decode | |
99 | */ | |
100 | buffer += 1; | |
101 | temp8 = *buffer; | |
102 | ||
103 | output_struct->data.io.io_decode = temp8 & 0x01; | |
104 | ||
105 | /* | |
106 | * Check min_base Address | |
107 | */ | |
108 | buffer += 1; | |
109 | ACPI_MOVE_16_TO_16 (&temp16, buffer); | |
110 | ||
111 | output_struct->data.io.min_base_address = temp16; | |
112 | ||
113 | /* | |
114 | * Check max_base Address | |
115 | */ | |
116 | buffer += 2; | |
117 | ACPI_MOVE_16_TO_16 (&temp16, buffer); | |
118 | ||
119 | output_struct->data.io.max_base_address = temp16; | |
120 | ||
121 | /* | |
122 | * Check Base alignment | |
123 | */ | |
124 | buffer += 2; | |
125 | temp8 = *buffer; | |
126 | ||
127 | output_struct->data.io.alignment = temp8; | |
128 | ||
129 | /* | |
130 | * Check range_length | |
131 | */ | |
132 | buffer += 1; | |
133 | temp8 = *buffer; | |
134 | ||
135 | output_struct->data.io.range_length = temp8; | |
136 | ||
137 | /* | |
138 | * Set the Length parameter | |
139 | */ | |
140 | output_struct->length = (u32) struct_size; | |
141 | ||
142 | /* | |
143 | * Return the final size of the structure | |
144 | */ | |
145 | *structure_size = struct_size; | |
146 | return_ACPI_STATUS (AE_OK); | |
147 | } | |
148 | ||
149 | ||
150 | /******************************************************************************* | |
151 | * | |
152 | * FUNCTION: acpi_rs_fixed_io_resource | |
153 | * | |
154 | * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte | |
155 | * stream | |
156 | * bytes_consumed - Pointer to where the number of bytes | |
157 | * consumed the byte_stream_buffer is | |
158 | * returned | |
159 | * output_buffer - Pointer to the return data buffer | |
160 | * structure_size - Pointer to where the number of bytes | |
161 | * in the return data struct is returned | |
162 | * | |
163 | * RETURN: Status | |
164 | * | |
165 | * DESCRIPTION: Take the resource byte stream and fill out the appropriate | |
166 | * structure pointed to by the output_buffer. Return the | |
167 | * number of bytes consumed from the byte stream. | |
168 | * | |
169 | ******************************************************************************/ | |
170 | ||
171 | acpi_status | |
172 | acpi_rs_fixed_io_resource ( | |
173 | u8 *byte_stream_buffer, | |
174 | acpi_size *bytes_consumed, | |
175 | u8 **output_buffer, | |
176 | acpi_size *structure_size) | |
177 | { | |
178 | u8 *buffer = byte_stream_buffer; | |
179 | struct acpi_resource *output_struct = (void *) *output_buffer; | |
180 | u16 temp16 = 0; | |
181 | u8 temp8 = 0; | |
182 | acpi_size struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_fixed_io); | |
183 | ||
184 | ||
185 | ACPI_FUNCTION_TRACE ("rs_fixed_io_resource"); | |
186 | ||
187 | ||
188 | /* | |
189 | * The number of bytes consumed are Constant | |
190 | */ | |
191 | *bytes_consumed = 4; | |
192 | ||
193 | output_struct->id = ACPI_RSTYPE_FIXED_IO; | |
194 | ||
195 | /* | |
196 | * Check Range Base Address | |
197 | */ | |
198 | buffer += 1; | |
199 | ACPI_MOVE_16_TO_16 (&temp16, buffer); | |
200 | ||
201 | output_struct->data.fixed_io.base_address = temp16; | |
202 | ||
203 | /* | |
204 | * Check range_length | |
205 | */ | |
206 | buffer += 2; | |
207 | temp8 = *buffer; | |
208 | ||
209 | output_struct->data.fixed_io.range_length = temp8; | |
210 | ||
211 | /* | |
212 | * Set the Length parameter | |
213 | */ | |
214 | output_struct->length = (u32) struct_size; | |
215 | ||
216 | /* | |
217 | * Return the final size of the structure | |
218 | */ | |
219 | *structure_size = struct_size; | |
220 | return_ACPI_STATUS (AE_OK); | |
221 | } | |
222 | ||
223 | ||
224 | /******************************************************************************* | |
225 | * | |
226 | * FUNCTION: acpi_rs_io_stream | |
227 | * | |
228 | * PARAMETERS: linked_list - Pointer to the resource linked list | |
229 | * output_buffer - Pointer to the user's return buffer | |
230 | * bytes_consumed - Pointer to where the number of bytes | |
231 | * used in the output_buffer is returned | |
232 | * | |
233 | * RETURN: Status | |
234 | * | |
235 | * DESCRIPTION: Take the linked list resource structure and fills in the | |
236 | * the appropriate bytes in a byte stream | |
237 | * | |
238 | ******************************************************************************/ | |
239 | ||
240 | acpi_status | |
241 | acpi_rs_io_stream ( | |
242 | struct acpi_resource *linked_list, | |
243 | u8 **output_buffer, | |
244 | acpi_size *bytes_consumed) | |
245 | { | |
246 | u8 *buffer = *output_buffer; | |
247 | u16 temp16 = 0; | |
248 | u8 temp8 = 0; | |
249 | ||
250 | ||
251 | ACPI_FUNCTION_TRACE ("rs_io_stream"); | |
252 | ||
253 | ||
254 | /* | |
255 | * The descriptor field is static | |
256 | */ | |
257 | *buffer = 0x47; | |
258 | buffer += 1; | |
259 | ||
260 | /* | |
261 | * Io Information Byte | |
262 | */ | |
263 | temp8 = (u8) (linked_list->data.io.io_decode & 0x01); | |
264 | ||
265 | *buffer = temp8; | |
266 | buffer += 1; | |
267 | ||
268 | /* | |
269 | * Set the Range minimum base address | |
270 | */ | |
271 | temp16 = (u16) linked_list->data.io.min_base_address; | |
272 | ||
273 | ACPI_MOVE_16_TO_16 (buffer, &temp16); | |
274 | buffer += 2; | |
275 | ||
276 | /* | |
277 | * Set the Range maximum base address | |
278 | */ | |
279 | temp16 = (u16) linked_list->data.io.max_base_address; | |
280 | ||
281 | ACPI_MOVE_16_TO_16 (buffer, &temp16); | |
282 | buffer += 2; | |
283 | ||
284 | /* | |
285 | * Set the base alignment | |
286 | */ | |
287 | temp8 = (u8) linked_list->data.io.alignment; | |
288 | ||
289 | *buffer = temp8; | |
290 | buffer += 1; | |
291 | ||
292 | /* | |
293 | * Set the range length | |
294 | */ | |
295 | temp8 = (u8) linked_list->data.io.range_length; | |
296 | ||
297 | *buffer = temp8; | |
298 | buffer += 1; | |
299 | ||
300 | /* | |
301 | * Return the number of bytes consumed in this operation | |
302 | */ | |
303 | *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer); | |
304 | return_ACPI_STATUS (AE_OK); | |
305 | } | |
306 | ||
307 | ||
308 | /******************************************************************************* | |
309 | * | |
310 | * FUNCTION: acpi_rs_fixed_io_stream | |
311 | * | |
312 | * PARAMETERS: linked_list - Pointer to the resource linked list | |
313 | * output_buffer - Pointer to the user's return buffer | |
314 | * bytes_consumed - Pointer to where the number of bytes | |
315 | * used in the output_buffer is returned | |
316 | * | |
317 | * RETURN: Status | |
318 | * | |
319 | * DESCRIPTION: Take the linked list resource structure and fills in the | |
320 | * the appropriate bytes in a byte stream | |
321 | * | |
322 | ******************************************************************************/ | |
323 | ||
324 | acpi_status | |
325 | acpi_rs_fixed_io_stream ( | |
326 | struct acpi_resource *linked_list, | |
327 | u8 **output_buffer, | |
328 | acpi_size *bytes_consumed) | |
329 | { | |
330 | u8 *buffer = *output_buffer; | |
331 | u16 temp16 = 0; | |
332 | u8 temp8 = 0; | |
333 | ||
334 | ||
335 | ACPI_FUNCTION_TRACE ("rs_fixed_io_stream"); | |
336 | ||
337 | ||
338 | /* | |
339 | * The descriptor field is static | |
340 | */ | |
341 | *buffer = 0x4B; | |
342 | ||
343 | buffer += 1; | |
344 | ||
345 | /* | |
346 | * Set the Range base address | |
347 | */ | |
348 | temp16 = (u16) linked_list->data.fixed_io.base_address; | |
349 | ||
350 | ACPI_MOVE_16_TO_16 (buffer, &temp16); | |
351 | buffer += 2; | |
352 | ||
353 | /* | |
354 | * Set the range length | |
355 | */ | |
356 | temp8 = (u8) linked_list->data.fixed_io.range_length; | |
357 | ||
358 | *buffer = temp8; | |
359 | buffer += 1; | |
360 | ||
361 | /* | |
362 | * Return the number of bytes consumed in this operation | |
363 | */ | |
364 | *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer); | |
365 | return_ACPI_STATUS (AE_OK); | |
366 | } | |
367 | ||
368 | ||
369 | /******************************************************************************* | |
370 | * | |
371 | * FUNCTION: acpi_rs_dma_resource | |
372 | * | |
373 | * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte | |
374 | * stream | |
375 | * bytes_consumed - Pointer to where the number of bytes | |
376 | * consumed the byte_stream_buffer is | |
377 | * returned | |
378 | * output_buffer - Pointer to the return data buffer | |
379 | * structure_size - Pointer to where the number of bytes | |
380 | * in the return data struct is returned | |
381 | * | |
382 | * RETURN: Status | |
383 | * | |
384 | * DESCRIPTION: Take the resource byte stream and fill out the appropriate | |
385 | * structure pointed to by the output_buffer. Return the | |
386 | * number of bytes consumed from the byte stream. | |
387 | * | |
388 | ******************************************************************************/ | |
389 | ||
390 | acpi_status | |
391 | acpi_rs_dma_resource ( | |
392 | u8 *byte_stream_buffer, | |
393 | acpi_size *bytes_consumed, | |
394 | u8 **output_buffer, | |
395 | acpi_size *structure_size) | |
396 | { | |
397 | u8 *buffer = byte_stream_buffer; | |
398 | struct acpi_resource *output_struct = (void *) *output_buffer; | |
399 | u8 temp8 = 0; | |
400 | u8 index; | |
401 | u8 i; | |
402 | acpi_size struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_dma); | |
403 | ||
404 | ||
405 | ACPI_FUNCTION_TRACE ("rs_dma_resource"); | |
406 | ||
407 | ||
408 | /* | |
409 | * The number of bytes consumed are Constant | |
410 | */ | |
411 | *bytes_consumed = 3; | |
412 | output_struct->id = ACPI_RSTYPE_DMA; | |
413 | ||
414 | /* | |
415 | * Point to the 8-bits of Byte 1 | |
416 | */ | |
417 | buffer += 1; | |
418 | temp8 = *buffer; | |
419 | ||
420 | /* Decode the DMA channel bits */ | |
421 | ||
422 | for (i = 0, index = 0; index < 8; index++) { | |
423 | if ((temp8 >> index) & 0x01) { | |
424 | output_struct->data.dma.channels[i] = index; | |
425 | i++; | |
426 | } | |
427 | } | |
428 | ||
429 | /* Zero DMA channels is valid */ | |
430 | ||
431 | output_struct->data.dma.number_of_channels = i; | |
432 | if (i > 0) { | |
433 | /* | |
434 | * Calculate the structure size based upon the number of interrupts | |
435 | */ | |
436 | struct_size += ((acpi_size) i - 1) * 4; | |
437 | } | |
438 | ||
439 | /* | |
440 | * Point to Byte 2 | |
441 | */ | |
442 | buffer += 1; | |
443 | temp8 = *buffer; | |
444 | ||
445 | /* | |
446 | * Check for transfer preference (Bits[1:0]) | |
447 | */ | |
448 | output_struct->data.dma.transfer = temp8 & 0x03; | |
449 | ||
450 | if (0x03 == output_struct->data.dma.transfer) { | |
451 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid DMA.Transfer preference (3)\n")); | |
452 | return_ACPI_STATUS (AE_BAD_DATA); | |
453 | } | |
454 | ||
455 | /* | |
456 | * Get bus master preference (Bit[2]) | |
457 | */ | |
458 | output_struct->data.dma.bus_master = (temp8 >> 2) & 0x01; | |
459 | ||
460 | /* | |
461 | * Get channel speed support (Bits[6:5]) | |
462 | */ | |
463 | output_struct->data.dma.type = (temp8 >> 5) & 0x03; | |
464 | ||
465 | /* | |
466 | * Set the Length parameter | |
467 | */ | |
468 | output_struct->length = (u32) struct_size; | |
469 | ||
470 | /* | |
471 | * Return the final size of the structure | |
472 | */ | |
473 | *structure_size = struct_size; | |
474 | return_ACPI_STATUS (AE_OK); | |
475 | } | |
476 | ||
477 | ||
478 | /******************************************************************************* | |
479 | * | |
480 | * FUNCTION: acpi_rs_dma_stream | |
481 | * | |
482 | * PARAMETERS: linked_list - Pointer to the resource linked list | |
483 | * output_buffer - Pointer to the user's return buffer | |
484 | * bytes_consumed - Pointer to where the number of bytes | |
485 | * used in the output_buffer is returned | |
486 | * | |
487 | * RETURN: Status | |
488 | * | |
489 | * DESCRIPTION: Take the linked list resource structure and fills in the | |
490 | * the appropriate bytes in a byte stream | |
491 | * | |
492 | ******************************************************************************/ | |
493 | ||
494 | acpi_status | |
495 | acpi_rs_dma_stream ( | |
496 | struct acpi_resource *linked_list, | |
497 | u8 **output_buffer, | |
498 | acpi_size *bytes_consumed) | |
499 | { | |
500 | u8 *buffer = *output_buffer; | |
501 | u16 temp16 = 0; | |
502 | u8 temp8 = 0; | |
503 | u8 index; | |
504 | ||
505 | ||
506 | ACPI_FUNCTION_TRACE ("rs_dma_stream"); | |
507 | ||
508 | ||
509 | /* | |
510 | * The descriptor field is static | |
511 | */ | |
512 | *buffer = 0x2A; | |
513 | buffer += 1; | |
514 | temp8 = 0; | |
515 | ||
516 | /* | |
517 | * Loop through all of the Channels and set the mask bits | |
518 | */ | |
519 | for (index = 0; | |
520 | index < linked_list->data.dma.number_of_channels; | |
521 | index++) { | |
522 | temp16 = (u16) linked_list->data.dma.channels[index]; | |
523 | temp8 |= 0x1 << temp16; | |
524 | } | |
525 | ||
526 | *buffer = temp8; | |
527 | buffer += 1; | |
528 | ||
529 | /* | |
530 | * Set the DMA Info | |
531 | */ | |
532 | temp8 = (u8) ((linked_list->data.dma.type & 0x03) << 5); | |
533 | temp8 |= ((linked_list->data.dma.bus_master & 0x01) << 2); | |
534 | temp8 |= (linked_list->data.dma.transfer & 0x03); | |
535 | ||
536 | *buffer = temp8; | |
537 | buffer += 1; | |
538 | ||
539 | /* | |
540 | * Return the number of bytes consumed in this operation | |
541 | */ | |
542 | *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer); | |
543 | return_ACPI_STATUS (AE_OK); | |
544 | } | |
545 |