OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [acpi/] [resources/] [rscreate.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*******************************************************************************
2
 *
3
 * Module Name: rscreate - Create resource lists/tables
4
 *
5
 ******************************************************************************/
6
 
7
/*
8
 * Copyright (C) 2000 - 2004, 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
#include <acpi/amlcode.h>
48
#include <acpi/acnamesp.h>
49
 
50
#define _COMPONENT          ACPI_RESOURCES
51
         ACPI_MODULE_NAME    ("rscreate")
52
 
53
 
54
/*******************************************************************************
55
 *
56
 * FUNCTION:    acpi_rs_create_resource_list
57
 *
58
 * PARAMETERS:  byte_stream_buffer      - Pointer to the resource byte stream
59
 *              output_buffer           - Pointer to the user's buffer
60
 *
61
 * RETURN:      Status  - AE_OK if okay, else a valid acpi_status code
62
 *              If output_buffer is not large enough, output_buffer_length
63
 *              indicates how large output_buffer should be, else it
64
 *              indicates how may u8 elements of output_buffer are valid.
65
 *
66
 * DESCRIPTION: Takes the byte stream returned from a _CRS, _PRS control method
67
 *              execution and parses the stream to create a linked list
68
 *              of device resources.
69
 *
70
 ******************************************************************************/
71
 
72
acpi_status
73
acpi_rs_create_resource_list (
74
        union acpi_operand_object       *byte_stream_buffer,
75
        struct acpi_buffer              *output_buffer)
76
{
77
 
78
        acpi_status                     status;
79
        u8                              *byte_stream_start;
80
        acpi_size                       list_size_needed = 0;
81
        u32                             byte_stream_buffer_length;
82
 
83
 
84
        ACPI_FUNCTION_TRACE ("rs_create_resource_list");
85
 
86
 
87
        ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "byte_stream_buffer = %p\n",
88
                byte_stream_buffer));
89
 
90
        /*
91
         * Params already validated, so we don't re-validate here
92
         */
93
        byte_stream_buffer_length = byte_stream_buffer->buffer.length;
94
        byte_stream_start = byte_stream_buffer->buffer.pointer;
95
 
96
        /*
97
         * Pass the byte_stream_buffer into a module that can calculate
98
         * the buffer size needed for the linked list
99
         */
100
        status = acpi_rs_get_list_length (byte_stream_start, byte_stream_buffer_length,
101
                         &list_size_needed);
102
 
103
        ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Status=%X list_size_needed=%X\n",
104
                status, (u32) list_size_needed));
105
        if (ACPI_FAILURE (status)) {
106
                return_ACPI_STATUS (status);
107
        }
108
 
109
        /* Validate/Allocate/Clear caller buffer */
110
 
111
        status = acpi_ut_initialize_buffer (output_buffer, list_size_needed);
112
        if (ACPI_FAILURE (status)) {
113
                return_ACPI_STATUS (status);
114
        }
115
 
116
        /* Do the conversion */
117
 
118
        status = acpi_rs_byte_stream_to_list (byte_stream_start, byte_stream_buffer_length,
119
                          output_buffer->pointer);
120
        if (ACPI_FAILURE (status)) {
121
                return_ACPI_STATUS (status);
122
        }
123
 
124
        ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "output_buffer %p Length %X\n",
125
                        output_buffer->pointer, (u32) output_buffer->length));
126
        return_ACPI_STATUS (AE_OK);
127
}
128
 
129
 
130
/*******************************************************************************
131
 *
132
 * FUNCTION:    acpi_rs_create_pci_routing_table
133
 *
134
 * PARAMETERS:  package_object          - Pointer to an union acpi_operand_object
135
 *                                        package
136
 *              output_buffer           - Pointer to the user's buffer
137
 *
138
 * RETURN:      Status  AE_OK if okay, else a valid acpi_status code.
139
 *              If the output_buffer is too small, the error will be
140
 *              AE_BUFFER_OVERFLOW and output_buffer->Length will point
141
 *              to the size buffer needed.
142
 *
143
 * DESCRIPTION: Takes the union acpi_operand_object    package and creates a
144
 *              linked list of PCI interrupt descriptions
145
 *
146
 * NOTE: It is the caller's responsibility to ensure that the start of the
147
 * output buffer is aligned properly (if necessary).
148
 *
149
 ******************************************************************************/
150
 
151
acpi_status
152
acpi_rs_create_pci_routing_table (
153
        union acpi_operand_object       *package_object,
154
        struct acpi_buffer              *output_buffer)
155
{
156
        u8                              *buffer;
157
        union acpi_operand_object       **top_object_list;
158
        union acpi_operand_object       **sub_object_list;
159
        union acpi_operand_object       *obj_desc;
160
        acpi_size                       buffer_size_needed = 0;
161
        u32                             number_of_elements;
162
        u32                             index;
163
        struct acpi_pci_routing_table   *user_prt;
164
        struct acpi_namespace_node      *node;
165
        acpi_status                     status;
166
        struct acpi_buffer              path_buffer;
167
 
168
 
169
        ACPI_FUNCTION_TRACE ("rs_create_pci_routing_table");
170
 
171
 
172
        /* Params already validated, so we don't re-validate here */
173
 
174
        /*
175
         * Get the required buffer length
176
         */
177
        status = acpi_rs_get_pci_routing_table_length (package_object,
178
                         &buffer_size_needed);
179
        if (ACPI_FAILURE (status)) {
180
                return_ACPI_STATUS (status);
181
        }
182
 
183
        ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "buffer_size_needed = %X\n",
184
                (u32) buffer_size_needed));
185
 
186
        /* Validate/Allocate/Clear caller buffer */
187
 
188
        status = acpi_ut_initialize_buffer (output_buffer, buffer_size_needed);
189
        if (ACPI_FAILURE (status)) {
190
                return_ACPI_STATUS (status);
191
        }
192
 
193
        /*
194
         * Loop through the ACPI_INTERNAL_OBJECTS - Each object
195
         * should be a package that in turn contains an
196
         * acpi_integer Address, a u8 Pin, a Name and a u8 source_index.
197
         */
198
        top_object_list  = package_object->package.elements;
199
        number_of_elements = package_object->package.count;
200
        buffer           = output_buffer->pointer;
201
        user_prt         = ACPI_CAST_PTR (struct acpi_pci_routing_table, buffer);
202
 
203
        for (index = 0; index < number_of_elements; index++) {
204
                /*
205
                 * Point user_prt past this current structure
206
                 *
207
                 * NOTE: On the first iteration, user_prt->Length will
208
                 * be zero because we cleared the return buffer earlier
209
                 */
210
                buffer += user_prt->length;
211
                user_prt = ACPI_CAST_PTR (struct acpi_pci_routing_table, buffer);
212
 
213
                /*
214
                 * Fill in the Length field with the information we have at this point.
215
                 * The minus four is to subtract the size of the u8 Source[4] member
216
                 * because it is added below.
217
                 */
218
                user_prt->length = (sizeof (struct acpi_pci_routing_table) - 4);
219
 
220
                /*
221
                 * Each element of the top-level package must also be a package
222
                 */
223
                if (ACPI_GET_OBJECT_TYPE (*top_object_list) != ACPI_TYPE_PACKAGE) {
224
                        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
225
                                "(PRT[%X]) Need sub-package, found %s\n",
226
                                index, acpi_ut_get_object_type_name (*top_object_list)));
227
                        return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
228
                }
229
 
230
                /* Each sub-package must be of length 4 */
231
 
232
                if ((*top_object_list)->package.count != 4) {
233
                        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
234
                                "(PRT[%X]) Need package of length 4, found length %d\n",
235
                                index, (*top_object_list)->package.count));
236
                        return_ACPI_STATUS (AE_AML_PACKAGE_LIMIT);
237
                }
238
 
239
                /*
240
                 * Dereference the sub-package.
241
                 * The sub_object_list will now point to an array of the four IRQ
242
                 * elements: [Address, Pin, Source, source_index]
243
                 */
244
                sub_object_list = (*top_object_list)->package.elements;
245
 
246
                /*
247
                 * 1) First subobject: Dereference the PRT.Address
248
                 */
249
                obj_desc = sub_object_list[0];
250
                if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
251
                        user_prt->address = obj_desc->integer.value;
252
                }
253
                else {
254
                        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
255
                                "(PRT[%X].Address) Need Integer, found %s\n",
256
                                index, acpi_ut_get_object_type_name (obj_desc)));
257
                        return_ACPI_STATUS (AE_BAD_DATA);
258
                }
259
 
260
                /*
261
                 * 2) Second subobject: Dereference the PRT.Pin
262
                 */
263
                obj_desc = sub_object_list[1];
264
                if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
265
                        user_prt->pin = (u32) obj_desc->integer.value;
266
                }
267
                else {
268
                        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
269
                                "(PRT[%X].Pin) Need Integer, found %s\n",
270
                                index, acpi_ut_get_object_type_name (obj_desc)));
271
                        return_ACPI_STATUS (AE_BAD_DATA);
272
                }
273
 
274
                /*
275
                 * 3) Third subobject: Dereference the PRT.source_name
276
                 */
277
                obj_desc = sub_object_list[2];
278
                switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
279
                case ACPI_TYPE_LOCAL_REFERENCE:
280
 
281
                        if (obj_desc->reference.opcode != AML_INT_NAMEPATH_OP) {
282
                                ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
283
                                        "(PRT[%X].Source) Need name, found reference op %X\n",
284
                                        index, obj_desc->reference.opcode));
285
                                return_ACPI_STATUS (AE_BAD_DATA);
286
                        }
287
 
288
                        node = obj_desc->reference.node;
289
 
290
                        /* Use *remaining* length of the buffer as max for pathname */
291
 
292
                        path_buffer.length = output_buffer->length -
293
                                           (u32) ((u8 *) user_prt->source -
294
                                           (u8 *) output_buffer->pointer);
295
                        path_buffer.pointer = user_prt->source;
296
 
297
                        status = acpi_ns_handle_to_pathname ((acpi_handle) node, &path_buffer);
298
 
299
                        user_prt->length += (u32) ACPI_STRLEN (user_prt->source) + 1; /* include null terminator */
300
                        break;
301
 
302
 
303
                case ACPI_TYPE_STRING:
304
 
305
                        ACPI_STRCPY (user_prt->source, obj_desc->string.pointer);
306
 
307
                        /* Add to the Length field the length of the string (add 1 for terminator) */
308
 
309
                        user_prt->length += obj_desc->string.length + 1;
310
                        break;
311
 
312
 
313
                case ACPI_TYPE_INTEGER:
314
                        /*
315
                         * If this is a number, then the Source Name is NULL, since the
316
                         * entire buffer was zeroed out, we can leave this alone.
317
                         *
318
                         * Add to the Length field the length of the u32 NULL
319
                         */
320
                        user_prt->length += sizeof (u32);
321
                        break;
322
 
323
 
324
                default:
325
 
326
                   ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
327
                           "(PRT[%X].Source) Need Ref/String/Integer, found %s\n",
328
                                index, acpi_ut_get_object_type_name (obj_desc)));
329
                   return_ACPI_STATUS (AE_BAD_DATA);
330
                }
331
 
332
                /* Now align the current length */
333
 
334
                user_prt->length = (u32) ACPI_ROUND_UP_to_64_bITS (user_prt->length);
335
 
336
                /*
337
                 * 4) Fourth subobject: Dereference the PRT.source_index
338
                 */
339
                obj_desc = sub_object_list[3];
340
                if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
341
                        user_prt->source_index = (u32) obj_desc->integer.value;
342
                }
343
                else {
344
                        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
345
                                "(PRT[%X].source_index) Need Integer, found %s\n",
346
                                index, acpi_ut_get_object_type_name (obj_desc)));
347
                        return_ACPI_STATUS (AE_BAD_DATA);
348
                }
349
 
350
                /* Point to the next union acpi_operand_object in the top level package */
351
 
352
                top_object_list++;
353
        }
354
 
355
        ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "output_buffer %p Length %X\n",
356
                        output_buffer->pointer, (u32) output_buffer->length));
357
        return_ACPI_STATUS (AE_OK);
358
}
359
 
360
 
361
/*******************************************************************************
362
 *
363
 * FUNCTION:    acpi_rs_create_byte_stream
364
 *
365
 * PARAMETERS:  linked_list_buffer      - Pointer to the resource linked list
366
 *              output_buffer           - Pointer to the user's buffer
367
 *
368
 * RETURN:      Status  AE_OK if okay, else a valid acpi_status code.
369
 *              If the output_buffer is too small, the error will be
370
 *              AE_BUFFER_OVERFLOW and output_buffer->Length will point
371
 *              to the size buffer needed.
372
 *
373
 * DESCRIPTION: Takes the linked list of device resources and
374
 *              creates a bytestream to be used as input for the
375
 *              _SRS control method.
376
 *
377
 ******************************************************************************/
378
 
379
acpi_status
380
acpi_rs_create_byte_stream (
381
        struct acpi_resource            *linked_list_buffer,
382
        struct acpi_buffer              *output_buffer)
383
{
384
        acpi_status                     status;
385
        acpi_size                       byte_stream_size_needed = 0;
386
 
387
 
388
        ACPI_FUNCTION_TRACE ("rs_create_byte_stream");
389
 
390
 
391
        ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "linked_list_buffer = %p\n",
392
                linked_list_buffer));
393
 
394
        /*
395
         * Params already validated, so we don't re-validate here
396
         *
397
         * Pass the linked_list_buffer into a module that calculates
398
         * the buffer size needed for the byte stream.
399
         */
400
        status = acpi_rs_get_byte_stream_length (linked_list_buffer,
401
                         &byte_stream_size_needed);
402
 
403
        ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "byte_stream_size_needed=%X, %s\n",
404
                (u32) byte_stream_size_needed, acpi_format_exception (status)));
405
        if (ACPI_FAILURE (status)) {
406
                return_ACPI_STATUS (status);
407
        }
408
 
409
        /* Validate/Allocate/Clear caller buffer */
410
 
411
        status = acpi_ut_initialize_buffer (output_buffer, byte_stream_size_needed);
412
        if (ACPI_FAILURE (status)) {
413
                return_ACPI_STATUS (status);
414
        }
415
 
416
        /* Do the conversion */
417
 
418
        status = acpi_rs_list_to_byte_stream (linked_list_buffer, byte_stream_size_needed,
419
                          output_buffer->pointer);
420
        if (ACPI_FAILURE (status)) {
421
                return_ACPI_STATUS (status);
422
        }
423
 
424
        ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "output_buffer %p Length %X\n",
425
                        output_buffer->pointer, (u32) output_buffer->length));
426
        return_ACPI_STATUS (AE_OK);
427
}
428
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.