File: /usr/src/linux/drivers/acpi/resources/rsutils.c

1     /*******************************************************************************
2      *
3      * Module Name: rsutils - Utilities for the resource manager
4      *              $Revision: 22 $
5      *
6      ******************************************************************************/
7     
8     /*
9      *  Copyright (C) 2000, 2001 R. Byron Moore
10      *
11      *  This program is free software; you can redistribute it and/or modify
12      *  it under the terms of the GNU General Public License as published by
13      *  the Free Software Foundation; either version 2 of the License, or
14      *  (at your option) any later version.
15      *
16      *  This program is distributed in the hope that it will be useful,
17      *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18      *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19      *  GNU General Public License for more details.
20      *
21      *  You should have received a copy of the GNU General Public License
22      *  along with this program; if not, write to the Free Software
23      *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24      */
25     
26     
27     #include "acpi.h"
28     #include "acnamesp.h"
29     #include "acresrc.h"
30     
31     
32     #define _COMPONENT          ACPI_RESOURCES
33     	 MODULE_NAME         ("rsutils")
34     
35     
36     /*******************************************************************************
37      *
38      * FUNCTION:    Acpi_rs_get_prt_method_data
39      *
40      * PARAMETERS:  Handle          - a handle to the containing object
41      *              Ret_buffer      - a pointer to a buffer structure for the
42      *                                  results
43      *
44      * RETURN:      Status
45      *
46      * DESCRIPTION: This function is called to get the _PRT value of an object
47      *              contained in an object specified by the handle passed in
48      *
49      *              If the function fails an appropriate status will be returned
50      *              and the contents of the callers buffer is undefined.
51      *
52      ******************************************************************************/
53     
54     acpi_status
55     acpi_rs_get_prt_method_data (
56     	acpi_handle             handle,
57     	acpi_buffer             *ret_buffer)
58     {
59     	acpi_operand_object     *ret_obj;
60     	acpi_status             status;
61     	u32                     buffer_space_needed;
62     
63     
64     	FUNCTION_TRACE ("Rs_get_prt_method_data");
65     
66     
67     	/* already validated params, so we won't repeat here */
68     
69     	buffer_space_needed = ret_buffer->length;
70     
71     	/*
72     	 *  Execute the method, no parameters
73     	 */
74     	status = acpi_ns_evaluate_relative (handle, "_PRT", NULL, &ret_obj);
75     	if (ACPI_FAILURE (status)) {
76     		return_ACPI_STATUS (status);
77     	}
78     
79     	if (!ret_obj) {
80     		/* Return object is required */
81     
82     		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No object was returned from _PRT\n"));
83     		return_ACPI_STATUS (AE_TYPE);
84     	}
85     
86     
87     	/*
88     	 * The return object will be a package, so check the
89     	 *  parameters.  If the return object is not a package,
90     	 *  then the underlying AML code is corrupt or improperly
91     	 *  written.
92     	 */
93     	if (ACPI_TYPE_PACKAGE != ret_obj->common.type) {
94     		status = AE_AML_OPERAND_TYPE;
95     		goto cleanup;
96     	}
97     
98     	/*
99     	 * Make the call to create a resource linked list from the
100     	 *  byte stream buffer that comes back from the _CRS method
101     	 *  execution.
102     	 */
103     	status = acpi_rs_create_pci_routing_table (ret_obj, ret_buffer->pointer,
104     			  &buffer_space_needed);
105     
106     	/*
107     	 * Tell the user how much of the buffer we have used or is needed
108     	 *  and return the final status.
109     	 */
110     	ret_buffer->length = buffer_space_needed;
111     
112     
113     	/* On exit, we must delete the object returned by evaluate_object */
114     
115     cleanup:
116     
117     	acpi_ut_remove_reference (ret_obj);
118     	return_ACPI_STATUS (status);
119     }
120     
121     
122     /*******************************************************************************
123      *
124      * FUNCTION:    Acpi_rs_get_crs_method_data
125      *
126      * PARAMETERS:  Handle          - a handle to the containing object
127      *              Ret_buffer      - a pointer to a buffer structure for the
128      *                                  results
129      *
130      * RETURN:      Status
131      *
132      * DESCRIPTION: This function is called to get the _CRS value of an object
133      *              contained in an object specified by the handle passed in
134      *
135      *              If the function fails an appropriate status will be returned
136      *              and the contents of the callers buffer is undefined.
137      *
138      ******************************************************************************/
139     
140     acpi_status
141     acpi_rs_get_crs_method_data (
142     	acpi_handle             handle,
143     	acpi_buffer             *ret_buffer)
144     {
145     	acpi_operand_object     *ret_obj;
146     	acpi_status             status;
147     	u32                     buffer_space_needed = ret_buffer->length;
148     
149     
150     	FUNCTION_TRACE ("Rs_get_crs_method_data");
151     
152     
153     	/* already validated params, so we won't repeat here */
154     
155     	/*
156     	 *  Execute the method, no parameters
157     	 */
158     	status = acpi_ns_evaluate_relative (handle, "_CRS", NULL, &ret_obj);
159     	if (ACPI_FAILURE (status)) {
160     		return_ACPI_STATUS (status);
161     	}
162     
163     	if (!ret_obj) {
164     		/* Return object is required */
165     
166     		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No object was returned from _CRS\n"));
167     		return_ACPI_STATUS (AE_TYPE);
168     	}
169     
170     	/*
171     	 * The return object will be a buffer, but check the
172     	 *  parameters.  If the return object is not a buffer,
173     	 *  then the underlying AML code is corrupt or improperly
174     	 *  written.
175     	 */
176     	if (ACPI_TYPE_BUFFER != ret_obj->common.type) {
177     		status = AE_AML_OPERAND_TYPE;
178     		goto cleanup;
179     	}
180     
181     	/*
182     	 * Make the call to create a resource linked list from the
183     	 *  byte stream buffer that comes back from the _CRS method
184     	 *  execution.
185     	 */
186     	status = acpi_rs_create_resource_list (ret_obj, ret_buffer->pointer,
187     			 &buffer_space_needed);
188     
189     
190     	/*
191     	 * Tell the user how much of the buffer we have used or is needed
192     	 *  and return the final status.
193     	 */
194     	ret_buffer->length = buffer_space_needed;
195     
196     
197     	/* On exit, we must delete the object returned by evaluate_object */
198     
199     cleanup:
200     
201     	acpi_ut_remove_reference (ret_obj);
202     	return_ACPI_STATUS (status);
203     }
204     
205     
206     /*******************************************************************************
207      *
208      * FUNCTION:    Acpi_rs_get_prs_method_data
209      *
210      * PARAMETERS:  Handle          - a handle to the containing object
211      *              Ret_buffer      - a pointer to a buffer structure for the
212      *                                  results
213      *
214      * RETURN:      Status
215      *
216      * DESCRIPTION: This function is called to get the _PRS value of an object
217      *              contained in an object specified by the handle passed in
218      *
219      *              If the function fails an appropriate status will be returned
220      *              and the contents of the callers buffer is undefined.
221      *
222      ******************************************************************************/
223     
224     acpi_status
225     acpi_rs_get_prs_method_data (
226     	acpi_handle             handle,
227     	acpi_buffer             *ret_buffer)
228     {
229     	acpi_operand_object     *ret_obj;
230     	acpi_status             status;
231     	u32                     buffer_space_needed = ret_buffer->length;
232     
233     
234     	FUNCTION_TRACE ("Rs_get_prs_method_data");
235     
236     
237     	/* already validated params, so we won't repeat here */
238     
239     	/*
240     	 *  Execute the method, no parameters
241     	 */
242     	status = acpi_ns_evaluate_relative (handle, "_PRS", NULL, &ret_obj);
243     	if (ACPI_FAILURE (status)) {
244     		return_ACPI_STATUS (status);
245     	}
246     
247     	if (!ret_obj) {
248     		/* Return object is required */
249     
250     		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No object was returned from _PRS\n"));
251     		return_ACPI_STATUS (AE_TYPE);
252     	}
253     
254     	/*
255     	 * The return object will be a buffer, but check the
256     	 *  parameters.  If the return object is not a buffer,
257     	 *  then the underlying AML code is corrupt or improperly
258     	 *  written..
259     	 */
260     	if (ACPI_TYPE_BUFFER != ret_obj->common.type) {
261     		status = AE_AML_OPERAND_TYPE;
262     		goto cleanup;
263     	}
264     
265     	/*
266     	 * Make the call to create a resource linked list from the
267     	 *  byte stream buffer that comes back from the _CRS method
268     	 *  execution.
269     	 */
270     	status = acpi_rs_create_resource_list (ret_obj, ret_buffer->pointer,
271     			 &buffer_space_needed);
272     
273     	/*
274     	 * Tell the user how much of the buffer we have used or is needed
275     	 *  and return the final status.
276     	 */
277     	ret_buffer->length = buffer_space_needed;
278     
279     
280     	/* On exit, we must delete the object returned by evaluate_object */
281     
282     cleanup:
283     
284     	acpi_ut_remove_reference (ret_obj);
285     	return_ACPI_STATUS (status);
286     }
287     
288     
289     /*******************************************************************************
290      *
291      * FUNCTION:    Acpi_rs_set_srs_method_data
292      *
293      * PARAMETERS:  Handle          - a handle to the containing object
294      *              In_buffer       - a pointer to a buffer structure of the
295      *                                  parameter
296      *
297      * RETURN:      Status
298      *
299      * DESCRIPTION: This function is called to set the _SRS of an object contained
300      *              in an object specified by the handle passed in
301      *
302      *              If the function fails an appropriate status will be returned
303      *              and the contents of the callers buffer is undefined.
304      *
305      ******************************************************************************/
306     
307     acpi_status
308     acpi_rs_set_srs_method_data (
309     	acpi_handle             handle,
310     	acpi_buffer             *in_buffer)
311     {
312     	acpi_operand_object     *params[2];
313     	acpi_status             status;
314     	u8                      *byte_stream = NULL;
315     	u32                     buffer_size_needed = 0;
316     
317     
318     	FUNCTION_TRACE ("Rs_set_srs_method_data");
319     
320     
321     	/* already validated params, so we won't repeat here */
322     
323     	/*
324     	 * The In_buffer parameter will point to a linked list of
325     	 * resource parameters.  It needs to be formatted into a
326     	 * byte stream to be sent in as an input parameter.
327     	 */
328     	buffer_size_needed = 0;
329     
330     	/*
331     	 * First call is to get the buffer size needed
332     	 */
333     	status = acpi_rs_create_byte_stream (in_buffer->pointer, byte_stream,
334     			 &buffer_size_needed);
335     	/*
336     	 * We expect a return of AE_BUFFER_OVERFLOW
337     	 * if not, exit with the error
338     	 */
339     	if (AE_BUFFER_OVERFLOW != status) {
340     		return_ACPI_STATUS (status);
341     	}
342     
343     	/*
344     	 * Allocate the buffer needed
345     	 */
346     	byte_stream = ACPI_MEM_CALLOCATE (buffer_size_needed);
347     	if (NULL == byte_stream) {
348     		return_ACPI_STATUS (AE_NO_MEMORY);
349     	}
350     
351     	/*
352     	 * Now call to convert the linked list into a byte stream
353     	 */
354     	status = acpi_rs_create_byte_stream (in_buffer->pointer, byte_stream,
355     			 &buffer_size_needed);
356     	if (ACPI_FAILURE (status)) {
357     		goto cleanup;
358     	}
359     
360     	/*
361     	 * Init the param object
362     	 */
363     	params[0] = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER);
364     	if (!params[0]) {
365     		status = AE_NO_MEMORY;
366     		goto cleanup;
367     	}
368     	params [1] = NULL;
369     
370     	/*
371     	 *  Set up the parameter object
372     	 */
373     	params[0]->buffer.length  = buffer_size_needed;
374     	params[0]->buffer.pointer = byte_stream;
375     
376     	/*
377     	 * Execute the method, no return value
378     	 */
379     	status = acpi_ns_evaluate_relative (handle, "_SRS", params, NULL);
380     	acpi_ut_remove_reference (params[0]);
381     
382     	/*
383     	 * Clean up and return the status from Acpi_ns_evaluate_relative
384     	 */
385     cleanup:
386     
387     	ACPI_MEM_FREE (byte_stream);
388     	return_ACPI_STATUS (status);
389     }
390     
391