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