:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / drivers / bus / acpi / resource / rsio.c
1 /*******************************************************************************
2  *
3  * Module Name: rsio - Acpi_rs_io_resource
4  *                     Acpi_rs_fixed_io_resource
5  *                     Acpi_rs_io_stream
6  *                     Acpi_rs_fixed_io_stream
7  *                     Acpi_rs_dma_resource
8  *                     Acpi_rs_dma_stream
9  *              $Revision$
10  *
11  ******************************************************************************/
12
13 /*
14  *  Copyright (C) 2000, 2001 R. Byron Moore
15  *
16  *  This program is free software; you can redistribute it and/or modify
17  *  it under the terms of the GNU General Public License as published by
18  *  the Free Software Foundation; either version 2 of the License, or
19  *  (at your option) any later version.
20  *
21  *  This program is distributed in the hope that it will be useful,
22  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
23  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  *  GNU General Public License for more details.
25  *
26  *  You should have received a copy of the GNU General Public License
27  *  along with this program; if not, write to the Free Software
28  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
29  */
30
31
32 #include "acpi.h"
33 #include "acresrc.h"
34
35 #define _COMPONENT          ACPI_RESOURCES
36          MODULE_NAME         ("rsio")
37
38
39 /*******************************************************************************
40  *
41  * FUNCTION:    Acpi_rs_io_resource
42  *
43  * PARAMETERS:  Byte_stream_buffer      - Pointer to the resource input byte
44  *                                          stream
45  *              Bytes_consumed          - u32 pointer that is filled with
46  *                                          the number of bytes consumed from
47  *                                          the Byte_stream_buffer
48  *              Output_buffer           - Pointer to the user's return buffer
49  *              Structure_size          - u32 pointer that is filled with
50  *                                          the number of bytes in the filled
51  *                                          in structure
52  *
53  * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
54  *
55  * DESCRIPTION: Take the resource byte stream and fill out the appropriate
56  *                  structure pointed to by the Output_buffer. Return the
57  *                  number of bytes consumed from the byte stream.
58  *
59  ******************************************************************************/
60
61 ACPI_STATUS
62 acpi_rs_io_resource (
63         u8                      *byte_stream_buffer,
64         u32                     *bytes_consumed,
65         u8                      **output_buffer,
66         u32                     *structure_size)
67 {
68         u8                      *buffer = byte_stream_buffer;
69         RESOURCE                *output_struct = (RESOURCE *) * output_buffer;
70         u16                     temp16 = 0;
71         u8                      temp8 = 0;
72         u32                     struct_size = sizeof (IO_RESOURCE) +
73                           RESOURCE_LENGTH_NO_DATA;
74
75
76         /*
77          * The number of bytes consumed are Constant
78          */
79         *bytes_consumed = 8;
80
81         output_struct->id = io;
82
83         /*
84          * Check Decode
85          */
86         buffer += 1;
87         temp8 = *buffer;
88
89         output_struct->data.io.io_decode = temp8 & 0x01;
90
91         /*
92          * Check Min_base Address
93          */
94         buffer += 1;
95         MOVE_UNALIGNED16_TO_16 (&temp16, buffer);
96
97         output_struct->data.io.min_base_address = temp16;
98
99         /*
100          * Check Max_base Address
101          */
102         buffer += 2;
103         MOVE_UNALIGNED16_TO_16 (&temp16, buffer);
104
105         output_struct->data.io.max_base_address = temp16;
106
107         /*
108          * Check Base alignment
109          */
110         buffer += 2;
111         temp8 = *buffer;
112
113         output_struct->data.io.alignment = temp8;
114
115         /*
116          * Check Range_length
117          */
118         buffer += 1;
119         temp8 = *buffer;
120
121         output_struct->data.io.range_length = temp8;
122
123         /*
124          * Set the Length parameter
125          */
126         output_struct->length = struct_size;
127
128         /*
129          * Return the final size of the structure
130          */
131         *structure_size = struct_size;
132
133         return (AE_OK);
134 }
135
136
137 /*******************************************************************************
138  *
139  * FUNCTION:    Acpi_rs_fixed_io_resource
140  *
141  * PARAMETERS:  Byte_stream_buffer      - Pointer to the resource input byte
142  *                                          stream
143  *              Bytes_consumed          - u32 pointer that is filled with
144  *                                          the number of bytes consumed from
145  *                                          the Byte_stream_buffer
146  *              Output_buffer           - Pointer to the user's return buffer
147  *              Structure_size          - u32 pointer that is filled with
148  *                                          the number of bytes in the filled
149  *                                          in structure
150  *
151  * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
152  *
153  * DESCRIPTION: Take the resource byte stream and fill out the appropriate
154  *                  structure pointed to by the Output_buffer. Return the
155  *                  number of bytes consumed from the byte stream.
156  *
157  ******************************************************************************/
158
159 ACPI_STATUS
160 acpi_rs_fixed_io_resource (
161         u8                      *byte_stream_buffer,
162         u32                     *bytes_consumed,
163         u8                      **output_buffer,
164         u32                     *structure_size)
165 {
166         u8                      *buffer = byte_stream_buffer;
167         RESOURCE                *output_struct = (RESOURCE *) * output_buffer;
168         u16                     temp16 = 0;
169         u8                      temp8 = 0;
170         u32                     struct_size = sizeof (FIXED_IO_RESOURCE) +
171                           RESOURCE_LENGTH_NO_DATA;
172
173
174         /*
175          * The number of bytes consumed are Constant
176          */
177         *bytes_consumed = 4;
178
179         output_struct->id = fixed_io;
180
181         /*
182          * Check Range Base Address
183          */
184         buffer += 1;
185         MOVE_UNALIGNED16_TO_16 (&temp16, buffer);
186
187         output_struct->data.fixed_io.base_address = temp16;
188
189         /*
190          * Check Range_length
191          */
192         buffer += 2;
193         temp8 = *buffer;
194
195         output_struct->data.fixed_io.range_length = temp8;
196
197         /*
198          * Set the Length parameter
199          */
200         output_struct->length = struct_size;
201
202         /*
203          * Return the final size of the structure
204          */
205         *structure_size = struct_size;
206
207         return (AE_OK);
208 }
209
210
211 /*******************************************************************************
212  *
213  * FUNCTION:    Acpi_rs_io_stream
214  *
215  * PARAMETERS:  Linked_list             - Pointer to the resource linked list
216  *              Output_buffer           - Pointer to the user's return buffer
217  *              Bytes_consumed          - u32 pointer that is filled with
218  *                                          the number of bytes of the
219  *                                          Output_buffer used
220  *
221  * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
222  *
223  * DESCRIPTION: Take the linked list resource structure and fills in the
224  *                  the appropriate bytes in a byte stream
225  *
226  ******************************************************************************/
227
228 ACPI_STATUS
229 acpi_rs_io_stream (
230         RESOURCE                *linked_list,
231         u8                      **output_buffer,
232         u32                     *bytes_consumed)
233 {
234         u8                      *buffer = *output_buffer;
235         u16                     temp16 = 0;
236         u8                      temp8 = 0;
237
238
239         /*
240          * The descriptor field is static
241          */
242         *buffer = 0x47;
243         buffer += 1;
244
245         /*
246          * Io Information Byte
247          */
248         temp8 = (u8) (linked_list->data.io.io_decode & 0x01);
249
250         *buffer = temp8;
251         buffer += 1;
252
253         /*
254          * Set the Range minimum base address
255          */
256         temp16 = (u16) linked_list->data.io.min_base_address;
257
258         MOVE_UNALIGNED16_TO_16 (buffer, &temp16);
259         buffer += 2;
260
261         /*
262          * Set the Range maximum base address
263          */
264         temp16 = (u16) linked_list->data.io.max_base_address;
265
266         MOVE_UNALIGNED16_TO_16 (buffer, &temp16);
267         buffer += 2;
268
269         /*
270          * Set the base alignment
271          */
272         temp8 = (u8) linked_list->data.io.alignment;
273
274         *buffer = temp8;
275         buffer += 1;
276
277         /*
278          * Set the range length
279          */
280         temp8 = (u8) linked_list->data.io.range_length;
281
282         *buffer = temp8;
283         buffer += 1;
284
285         /*
286          * Return the number of bytes consumed in this operation
287          */
288         *bytes_consumed = (u32) ((NATIVE_UINT) buffer -
289                            (NATIVE_UINT) *output_buffer);
290
291         return (AE_OK);
292 }
293
294
295 /*******************************************************************************
296  *
297  * FUNCTION:    Acpi_rs_fixed_io_stream
298  *
299  * PARAMETERS:  Linked_list             - Pointer to the resource linked list
300  *              Output_buffer           - Pointer to the user's return buffer
301  *              Bytes_consumed          - u32 pointer that is filled with
302  *                                          the number of bytes of the
303  *                                          Output_buffer used
304  *
305  * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
306  *
307  * DESCRIPTION: Take the linked list resource structure and fills in the
308  *                  the appropriate bytes in a byte stream
309  *
310  ******************************************************************************/
311
312 ACPI_STATUS
313 acpi_rs_fixed_io_stream (
314         RESOURCE                *linked_list,
315         u8                      **output_buffer,
316         u32                     *bytes_consumed)
317 {
318         u8                      *buffer = *output_buffer;
319         u16                     temp16 = 0;
320         u8                      temp8 = 0;
321
322
323         /*
324          * The descriptor field is static
325          */
326         *buffer = 0x4B;
327
328         buffer += 1;
329
330         /*
331          * Set the Range base address
332          */
333         temp16 = (u16) linked_list->data.fixed_io.base_address;
334
335         MOVE_UNALIGNED16_TO_16 (buffer, &temp16);
336         buffer += 2;
337
338         /*
339          * Set the range length
340          */
341         temp8 = (u8) linked_list->data.fixed_io.range_length;
342
343         *buffer = temp8;
344         buffer += 1;
345
346         /*
347          * Return the number of bytes consumed in this operation
348          */
349         *bytes_consumed = (u32) ((NATIVE_UINT) buffer -
350                            (NATIVE_UINT) *output_buffer);
351
352         return (AE_OK);
353 }
354
355
356 /*******************************************************************************
357  *
358  * FUNCTION:    Acpi_rs_dma_resource
359  *
360  * PARAMETERS:  Byte_stream_buffer      - Pointer to the resource input byte
361  *                                          stream
362  *              Bytes_consumed          - u32 pointer that is filled with
363  *                                          the number of bytes consumed from
364  *                                          the Byte_stream_buffer
365  *              Output_buffer           - Pointer to the user's return buffer
366  *              Structure_size          - u32 pointer that is filled with
367  *                                          the number of bytes in the filled
368  *                                          in structure
369  *
370  * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
371  *
372  * DESCRIPTION: Take the resource byte stream and fill out the appropriate
373  *                  structure pointed to by the Output_buffer. Return the
374  *                  number of bytes consumed from the byte stream.
375  *
376  ******************************************************************************/
377
378 ACPI_STATUS
379 acpi_rs_dma_resource (
380         u8                      *byte_stream_buffer,
381         u32                     *bytes_consumed,
382         u8                      **output_buffer,
383         u32                     *structure_size)
384 {
385         u8                      *buffer = byte_stream_buffer;
386         RESOURCE                *output_struct = (RESOURCE *) * output_buffer;
387         u8                      temp8 = 0;
388         u8                      index;
389         u8                      i;
390         u32                     struct_size = sizeof(DMA_RESOURCE) +
391                           RESOURCE_LENGTH_NO_DATA;
392
393
394         /*
395          * The number of bytes consumed are Constant
396          */
397         *bytes_consumed = 3;
398         output_struct->id = dma;
399
400         /*
401          * Point to the 8-bits of Byte 1
402          */
403         buffer += 1;
404         temp8 = *buffer;
405
406         /* Decode the IRQ bits */
407
408         for (i = 0, index = 0; index < 8; index++) {
409                 if ((temp8 >> index) & 0x01) {
410                         output_struct->data.dma.channels[i] = index;
411                         i++;
412                 }
413         }
414         output_struct->data.dma.number_of_channels = i;
415
416
417         /*
418          * Calculate the structure size based upon the number of interrupts
419          */
420         struct_size += (output_struct->data.dma.number_of_channels - 1) * 4;
421
422         /*
423          * Point to Byte 2
424          */
425         buffer += 1;
426         temp8 = *buffer;
427
428         /*
429          * Check for transfer preference (Bits[1:0])
430          */
431         output_struct->data.dma.transfer = temp8 & 0x03;
432
433         if (0x03 == output_struct->data.dma.transfer) {
434                 return (AE_BAD_DATA);
435         }
436
437         /*
438          * Get bus master preference (Bit[2])
439          */
440         output_struct->data.dma.bus_master = (temp8 >> 2) & 0x01;
441
442         /*
443          * Get channel speed support (Bits[6:5])
444          */
445         output_struct->data.dma.type = (temp8 >> 5) & 0x03;
446
447         /*
448          * Set the Length parameter
449          */
450         output_struct->length = struct_size;
451
452         /*
453          * Return the final size of the structure
454          */
455         *structure_size = struct_size;
456
457         return (AE_OK);
458 }
459
460
461 /*******************************************************************************
462  *
463  * FUNCTION:    Acpi_rs_dma_stream
464  *
465  * PARAMETERS:  Linked_list             - Pointer to the resource linked list
466  *              Output_buffer           - Pointer to the user's return buffer
467  *              Bytes_consumed          - u32 pointer that is filled with
468  *                                          the number of bytes of the
469  *                                          Output_buffer used
470  *
471  * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
472  *
473  * DESCRIPTION: Take the linked list resource structure and fills in the
474  *                  the appropriate bytes in a byte stream
475  *
476  ******************************************************************************/
477
478 ACPI_STATUS
479 acpi_rs_dma_stream (
480         RESOURCE                *linked_list,
481         u8                      **output_buffer,
482         u32                     *bytes_consumed)
483 {
484         u8                      *buffer = *output_buffer;
485         u16                     temp16 = 0;
486         u8                      temp8 = 0;
487         u8                      index;
488
489
490         /*
491          * The descriptor field is static
492          */
493         *buffer = 0x2A;
494         buffer += 1;
495         temp8 = 0;
496
497         /*
498          * Loop through all of the Channels and set the mask bits
499          */
500         for (index = 0;
501                  index < linked_list->data.dma.number_of_channels;
502                  index++) {
503                 temp16 = (u16) linked_list->data.dma.channels[index];
504                 temp8 |= 0x1 << temp16;
505         }
506
507         *buffer = temp8;
508         buffer += 1;
509
510         /*
511          * Set the DMA Info
512          */
513         temp8 = (u8) ((linked_list->data.dma.type & 0x03) << 5);
514         temp8 |= ((linked_list->data.dma.bus_master & 0x01) << 2);
515         temp8 |= (linked_list->data.dma.transfer & 0x03);
516
517         *buffer = temp8;
518         buffer += 1;
519
520         /*
521          * Return the number of bytes consumed in this operation
522          */
523         *bytes_consumed = (u32) ((NATIVE_UINT) buffer -
524                            (NATIVE_UINT) *output_buffer);
525
526         return (AE_OK);
527 }
528