Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
rsxface.c
Go to the documentation of this file.
1 /*******************************************************************************
2  *
3  * Module Name: rsxface - Public interfaces to the resource manager
4  *
5  ******************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2012, Intel Corp.
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 #include <linux/export.h>
45 #include <acpi/acpi.h>
46 #include "accommon.h"
47 #include "acresrc.h"
48 #include "acnamesp.h"
49 
50 #define _COMPONENT ACPI_RESOURCES
51 ACPI_MODULE_NAME("rsxface")
52 
53 /* Local macros for 16,32-bit to 64-bit conversion */
54 #define ACPI_COPY_FIELD(out, in, field) ((out)->field = (in)->field)
55 #define ACPI_COPY_ADDRESS(out, in) \
56  ACPI_COPY_FIELD(out, in, resource_type); \
57  ACPI_COPY_FIELD(out, in, producer_consumer); \
58  ACPI_COPY_FIELD(out, in, decode); \
59  ACPI_COPY_FIELD(out, in, min_address_fixed); \
60  ACPI_COPY_FIELD(out, in, max_address_fixed); \
61  ACPI_COPY_FIELD(out, in, info); \
62  ACPI_COPY_FIELD(out, in, granularity); \
63  ACPI_COPY_FIELD(out, in, minimum); \
64  ACPI_COPY_FIELD(out, in, maximum); \
65  ACPI_COPY_FIELD(out, in, translation_offset); \
66  ACPI_COPY_FIELD(out, in, address_length); \
67  ACPI_COPY_FIELD(out, in, resource_source);
68 /* Local prototypes */
69 static acpi_status
70 acpi_rs_match_vendor_resource(struct acpi_resource *resource, void *context);
71 
72 static acpi_status
73 acpi_rs_validate_parameters(acpi_handle device_handle,
74  struct acpi_buffer *buffer,
75  struct acpi_namespace_node **return_node);
76 
77 /*******************************************************************************
78  *
79  * FUNCTION: acpi_rs_validate_parameters
80  *
81  * PARAMETERS: device_handle - Handle to a device
82  * buffer - Pointer to a data buffer
83  * return_node - Pointer to where the device node is returned
84  *
85  * RETURN: Status
86  *
87  * DESCRIPTION: Common parameter validation for resource interfaces
88  *
89  ******************************************************************************/
90 
91 static acpi_status
92 acpi_rs_validate_parameters(acpi_handle device_handle,
93  struct acpi_buffer *buffer,
94  struct acpi_namespace_node **return_node)
95 {
97  struct acpi_namespace_node *node;
98 
99  ACPI_FUNCTION_TRACE(rs_validate_parameters);
100 
101  /*
102  * Must have a valid handle to an ACPI device
103  */
104  if (!device_handle) {
106  }
107 
108  node = acpi_ns_validate_handle(device_handle);
109  if (!node) {
111  }
112 
113  if (node->type != ACPI_TYPE_DEVICE) {
115  }
116 
117  /*
118  * Validate the user buffer object
119  *
120  * if there is a non-zero buffer length we also need a valid pointer in
121  * the buffer. If it's a zero buffer length, we'll be returning the
122  * needed buffer size (later), so keep going.
123  */
124  status = acpi_ut_validate_buffer(buffer);
125  if (ACPI_FAILURE(status)) {
126  return_ACPI_STATUS(status);
127  }
128 
129  *return_node = node;
131 }
132 
133 /*******************************************************************************
134  *
135  * FUNCTION: acpi_get_irq_routing_table
136  *
137  * PARAMETERS: device_handle - Handle to the Bus device we are querying
138  * ret_buffer - Pointer to a buffer to receive the
139  * current resources for the device
140  *
141  * RETURN: Status
142  *
143  * DESCRIPTION: This function is called to get the IRQ routing table for a
144  * specific bus. The caller must first acquire a handle for the
145  * desired bus. The routine table is placed in the buffer pointed
146  * to by the ret_buffer variable parameter.
147  *
148  * If the function fails an appropriate status will be returned
149  * and the value of ret_buffer is undefined.
150  *
151  * This function attempts to execute the _PRT method contained in
152  * the object indicated by the passed device_handle.
153  *
154  ******************************************************************************/
155 
158  struct acpi_buffer *ret_buffer)
159 {
161  struct acpi_namespace_node *node;
162 
164 
165  /* Validate parameters then dispatch to internal routine */
166 
167  status = acpi_rs_validate_parameters(device_handle, ret_buffer, &node);
168  if (ACPI_FAILURE(status)) {
169  return_ACPI_STATUS(status);
170  }
171 
172  status = acpi_rs_get_prt_method_data(node, ret_buffer);
173  return_ACPI_STATUS(status);
174 }
175 
177 
178 /*******************************************************************************
179  *
180  * FUNCTION: acpi_get_current_resources
181  *
182  * PARAMETERS: device_handle - Handle to the device object for the
183  * device we are querying
184  * ret_buffer - Pointer to a buffer to receive the
185  * current resources for the device
186  *
187  * RETURN: Status
188  *
189  * DESCRIPTION: This function is called to get the current resources for a
190  * specific device. The caller must first acquire a handle for
191  * the desired device. The resource data is placed in the buffer
192  * pointed to by the ret_buffer variable parameter.
193  *
194  * If the function fails an appropriate status will be returned
195  * and the value of ret_buffer is undefined.
196  *
197  * This function attempts to execute the _CRS method contained in
198  * the object indicated by the passed device_handle.
199  *
200  ******************************************************************************/
203  struct acpi_buffer *ret_buffer)
204 {
206  struct acpi_namespace_node *node;
207 
209 
210  /* Validate parameters then dispatch to internal routine */
211 
212  status = acpi_rs_validate_parameters(device_handle, ret_buffer, &node);
213  if (ACPI_FAILURE(status)) {
214  return_ACPI_STATUS(status);
215  }
216 
217  status = acpi_rs_get_crs_method_data(node, ret_buffer);
218  return_ACPI_STATUS(status);
219 }
220 
222 #ifdef ACPI_FUTURE_USAGE
223 /*******************************************************************************
224  *
225  * FUNCTION: acpi_get_possible_resources
226  *
227  * PARAMETERS: device_handle - Handle to the device object for the
228  * device we are querying
229  * ret_buffer - Pointer to a buffer to receive the
230  * resources for the device
231  *
232  * RETURN: Status
233  *
234  * DESCRIPTION: This function is called to get a list of the possible resources
235  * for a specific device. The caller must first acquire a handle
236  * for the desired device. The resource data is placed in the
237  * buffer pointed to by the ret_buffer variable.
238  *
239  * If the function fails an appropriate status will be returned
240  * and the value of ret_buffer is undefined.
241  *
242  ******************************************************************************/
244 acpi_get_possible_resources(acpi_handle device_handle,
245  struct acpi_buffer *ret_buffer)
246 {
248  struct acpi_namespace_node *node;
249 
250  ACPI_FUNCTION_TRACE(acpi_get_possible_resources);
251 
252  /* Validate parameters then dispatch to internal routine */
253 
254  status = acpi_rs_validate_parameters(device_handle, ret_buffer, &node);
255  if (ACPI_FAILURE(status)) {
256  return_ACPI_STATUS(status);
257  }
258 
259  status = acpi_rs_get_prs_method_data(node, ret_buffer);
260  return_ACPI_STATUS(status);
261 }
262 
263 ACPI_EXPORT_SYMBOL(acpi_get_possible_resources)
264 #endif /* ACPI_FUTURE_USAGE */
265 /*******************************************************************************
266  *
267  * FUNCTION: acpi_set_current_resources
268  *
269  * PARAMETERS: device_handle - Handle to the device object for the
270  * device we are setting resources
271  * in_buffer - Pointer to a buffer containing the
272  * resources to be set for the device
273  *
274  * RETURN: Status
275  *
276  * DESCRIPTION: This function is called to set the current resources for a
277  * specific device. The caller must first acquire a handle for
278  * the desired device. The resource data is passed to the routine
279  * the buffer pointed to by the in_buffer variable.
280  *
281  ******************************************************************************/
284  struct acpi_buffer *in_buffer)
285 {
287  struct acpi_namespace_node *node;
288 
290 
291  /* Validate the buffer, don't allow zero length */
292 
293  if ((!in_buffer) || (!in_buffer->pointer) || (!in_buffer->length)) {
295  }
296 
297  /* Validate parameters then dispatch to internal routine */
298 
299  status = acpi_rs_validate_parameters(device_handle, in_buffer, &node);
300  if (ACPI_FAILURE(status)) {
301  return_ACPI_STATUS(status);
302  }
303 
304  status = acpi_rs_set_srs_method_data(node, in_buffer);
305  return_ACPI_STATUS(status);
306 }
307 
309 
310 /*******************************************************************************
311  *
312  * FUNCTION: acpi_get_event_resources
313  *
314  * PARAMETERS: device_handle - Handle to the device object for the
315  * device we are getting resources
316  * in_buffer - Pointer to a buffer containing the
317  * resources to be set for the device
318  *
319  * RETURN: Status
320  *
321  * DESCRIPTION: This function is called to get the event resources for a
322  * specific device. The caller must first acquire a handle for
323  * the desired device. The resource data is passed to the routine
324  * the buffer pointed to by the in_buffer variable. Uses the
325  * _AEI method.
326  *
327  ******************************************************************************/
330  struct acpi_buffer *ret_buffer)
331 {
333  struct acpi_namespace_node *node;
334 
336 
337  /* Validate parameters then dispatch to internal routine */
338 
339  status = acpi_rs_validate_parameters(device_handle, ret_buffer, &node);
340  if (ACPI_FAILURE(status)) {
341  return_ACPI_STATUS(status);
342  }
343 
344  status = acpi_rs_get_aei_method_data(node, ret_buffer);
345  return_ACPI_STATUS(status);
346 }
347 
349 
350 /******************************************************************************
351  *
352  * FUNCTION: acpi_resource_to_address64
353  *
354  * PARAMETERS: resource - Pointer to a resource
355  * out - Pointer to the users's return buffer
356  * (a struct acpi_resource_address64)
357  *
358  * RETURN: Status
359  *
360  * DESCRIPTION: If the resource is an address16, address32, or address64,
361  * copy it to the address64 return buffer. This saves the
362  * caller from having to duplicate code for different-sized
363  * addresses.
364  *
365  ******************************************************************************/
369 {
370  struct acpi_resource_address16 *address16;
371  struct acpi_resource_address32 *address32;
372 
373  if (!resource || !out) {
374  return (AE_BAD_PARAMETER);
375  }
376 
377  /* Convert 16 or 32 address descriptor to 64 */
378 
379  switch (resource->type) {
381 
382  address16 =
384  &resource->data);
385  ACPI_COPY_ADDRESS(out, address16);
386  break;
387 
389 
390  address32 =
392  &resource->data);
393  ACPI_COPY_ADDRESS(out, address32);
394  break;
395 
397 
398  /* Simple copy for 64 bit source */
399 
400  ACPI_MEMCPY(out, &resource->data,
401  sizeof(struct acpi_resource_address64));
402  break;
403 
404  default:
405  return (AE_BAD_PARAMETER);
406  }
407 
408  return (AE_OK);
409 }
410 
412 
413 /*******************************************************************************
414  *
415  * FUNCTION: acpi_get_vendor_resource
416  *
417  * PARAMETERS: device_handle - Handle for the parent device object
418  * name - Method name for the parent resource
419  * (METHOD_NAME__CRS or METHOD_NAME__PRS)
420  * uuid - Pointer to the UUID to be matched.
421  * includes both subtype and 16-byte UUID
422  * ret_buffer - Where the vendor resource is returned
423  *
424  * RETURN: Status
425  *
426  * DESCRIPTION: Walk a resource template for the specified evice to find a
427  * vendor-defined resource that matches the supplied UUID and
428  * UUID subtype. Returns a struct acpi_resource of type Vendor.
429  *
430  ******************************************************************************/
433  char *name,
435  struct acpi_buffer * ret_buffer)
436 {
437  struct acpi_vendor_walk_info info;
439 
440  /* Other parameters are validated by acpi_walk_resources */
441 
442  if (!uuid || !ret_buffer) {
443  return (AE_BAD_PARAMETER);
444  }
445 
446  info.uuid = uuid;
447  info.buffer = ret_buffer;
448  info.status = AE_NOT_EXIST;
449 
450  /* Walk the _CRS or _PRS resource list for this device */
451 
452  status =
453  acpi_walk_resources(device_handle, name,
454  acpi_rs_match_vendor_resource, &info);
455  if (ACPI_FAILURE(status)) {
456  return (status);
457  }
458 
459  return (info.status);
460 }
461 
463 
464 /*******************************************************************************
465  *
466  * FUNCTION: acpi_rs_match_vendor_resource
467  *
468  * PARAMETERS: acpi_walk_resource_callback
469  *
470  * RETURN: Status
471  *
472  * DESCRIPTION: Match a vendor resource via the ACPI 3.0 UUID
473  *
474  ******************************************************************************/
475 static acpi_status
476 acpi_rs_match_vendor_resource(struct acpi_resource *resource, void *context)
477 {
480  struct acpi_buffer *buffer;
482 
483  /* Ignore all descriptors except Vendor */
484 
485  if (resource->type != ACPI_RESOURCE_TYPE_VENDOR) {
486  return (AE_OK);
487  }
488 
489  vendor = &resource->data.vendor_typed;
490 
491  /*
492  * For a valid match, these conditions must hold:
493  *
494  * 1) Length of descriptor data must be at least as long as a UUID struct
495  * 2) The UUID subtypes must match
496  * 3) The UUID data must match
497  */
498  if ((vendor->byte_length < (ACPI_UUID_LENGTH + 1)) ||
499  (vendor->uuid_subtype != info->uuid->subtype) ||
500  (ACPI_MEMCMP(vendor->uuid, info->uuid->data, ACPI_UUID_LENGTH))) {
501  return (AE_OK);
502  }
503 
504  /* Validate/Allocate/Clear caller buffer */
505 
506  buffer = info->buffer;
507  status = acpi_ut_initialize_buffer(buffer, resource->length);
508  if (ACPI_FAILURE(status)) {
509  return (status);
510  }
511 
512  /* Found the correct resource, copy and return it */
513 
514  ACPI_MEMCPY(buffer->pointer, resource, resource->length);
515  buffer->length = resource->length;
516 
517  /* Found the desired descriptor, terminate resource walk */
518 
519  info->status = AE_OK;
520  return (AE_CTRL_TERMINATE);
521 }
522 
523 /*******************************************************************************
524  *
525  * FUNCTION: acpi_walk_resources
526  *
527  * PARAMETERS: device_handle - Handle to the device object for the
528  * device we are querying
529  * name - Method name of the resources we want.
530  * (METHOD_NAME__CRS, METHOD_NAME__PRS, or
531  * METHOD_NAME__AEI)
532  * user_function - Called for each resource
533  * context - Passed to user_function
534  *
535  * RETURN: Status
536  *
537  * DESCRIPTION: Retrieves the current or possible resource list for the
538  * specified device. The user_function is called once for
539  * each resource in the list.
540  *
541  ******************************************************************************/
544  char *name,
545  acpi_walk_resource_callback user_function, void *context)
546 {
548  struct acpi_buffer buffer;
549  struct acpi_resource *resource;
550  struct acpi_resource *resource_end;
551 
553 
554  /* Parameter validation */
555 
556  if (!device_handle || !user_function || !name ||
561  }
562 
563  /* Get the _CRS/_PRS/_AEI resource list */
564 
566  status = acpi_rs_get_method_data(device_handle, name, &buffer);
567  if (ACPI_FAILURE(status)) {
568  return_ACPI_STATUS(status);
569  }
570 
571  /* Buffer now contains the resource list */
572 
573  resource = ACPI_CAST_PTR(struct acpi_resource, buffer.pointer);
574  resource_end =
575  ACPI_ADD_PTR(struct acpi_resource, buffer.pointer, buffer.length);
576 
577  /* Walk the resource list until the end_tag is found (or buffer end) */
578 
579  while (resource < resource_end) {
580 
581  /* Sanity check the resource */
582 
583  if (resource->type > ACPI_RESOURCE_TYPE_MAX) {
585  break;
586  }
587 
588  /* Invoke the user function, abort on any error returned */
589 
590  status = user_function(resource, context);
591  if (ACPI_FAILURE(status)) {
592  if (status == AE_CTRL_TERMINATE) {
593 
594  /* This is an OK termination by the user function */
595 
596  status = AE_OK;
597  }
598  break;
599  }
600 
601  /* end_tag indicates end-of-list */
602 
603  if (resource->type == ACPI_RESOURCE_TYPE_END_TAG) {
604  break;
605  }
606 
607  /* Get the next resource descriptor */
608 
609  resource =
610  ACPI_ADD_PTR(struct acpi_resource, resource,
611  resource->length);
612  }
613 
614  ACPI_FREE(buffer.pointer);
615  return_ACPI_STATUS(status);
616 }
617