1  // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2  /*******************************************************************************
3   *
4   * Module Name: rsutils - Utilities for the resource manager
5   *
6   ******************************************************************************/
7  
8  #include <acpi/acpi.h>
9  #include "accommon.h"
10  #include "acnamesp.h"
11  #include "acresrc.h"
12  
13  #define _COMPONENT          ACPI_RESOURCES
14  ACPI_MODULE_NAME("rsutils")
15  
16  /*******************************************************************************
17   *
18   * FUNCTION:    acpi_rs_decode_bitmask
19   *
20   * PARAMETERS:  mask            - Bitmask to decode
21   *              list            - Where the converted list is returned
22   *
23   * RETURN:      Count of bits set (length of list)
24   *
25   * DESCRIPTION: Convert a bit mask into a list of values
26   *
27   ******************************************************************************/
acpi_rs_decode_bitmask(u16 mask,u8 * list)28  u8 acpi_rs_decode_bitmask(u16 mask, u8 * list)
29  {
30  	u8 i;
31  	u8 bit_count;
32  
33  	ACPI_FUNCTION_ENTRY();
34  
35  	/* Decode the mask bits */
36  
37  	for (i = 0, bit_count = 0; mask; i++) {
38  		if (mask & 0x0001) {
39  			list[bit_count] = i;
40  			bit_count++;
41  		}
42  
43  		mask >>= 1;
44  	}
45  
46  	return (bit_count);
47  }
48  
49  /*******************************************************************************
50   *
51   * FUNCTION:    acpi_rs_encode_bitmask
52   *
53   * PARAMETERS:  list            - List of values to encode
54   *              count           - Length of list
55   *
56   * RETURN:      Encoded bitmask
57   *
58   * DESCRIPTION: Convert a list of values to an encoded bitmask
59   *
60   ******************************************************************************/
61  
acpi_rs_encode_bitmask(u8 * list,u8 count)62  u16 acpi_rs_encode_bitmask(u8 * list, u8 count)
63  {
64  	u32 i;
65  	u16 mask;
66  
67  	ACPI_FUNCTION_ENTRY();
68  
69  	/* Encode the list into a single bitmask */
70  
71  	for (i = 0, mask = 0; i < count; i++) {
72  		mask |= (0x1 << list[i]);
73  	}
74  
75  	return (mask);
76  }
77  
78  /*******************************************************************************
79   *
80   * FUNCTION:    acpi_rs_move_data
81   *
82   * PARAMETERS:  destination         - Pointer to the destination descriptor
83   *              source              - Pointer to the source descriptor
84   *              item_count          - How many items to move
85   *              move_type           - Byte width
86   *
87   * RETURN:      None
88   *
89   * DESCRIPTION: Move multiple data items from one descriptor to another. Handles
90   *              alignment issues and endian issues if necessary, as configured
91   *              via the ACPI_MOVE_* macros. (This is why a memcpy is not used)
92   *
93   ******************************************************************************/
94  
95  void
acpi_rs_move_data(void * destination,void * source,u16 item_count,u8 move_type)96  acpi_rs_move_data(void *destination, void *source, u16 item_count, u8 move_type)
97  {
98  	u32 i;
99  
100  	ACPI_FUNCTION_ENTRY();
101  
102  	/* One move per item */
103  
104  	for (i = 0; i < item_count; i++) {
105  		switch (move_type) {
106  			/*
107  			 * For the 8-bit case, we can perform the move all at once
108  			 * since there are no alignment or endian issues
109  			 */
110  		case ACPI_RSC_MOVE8:
111  		case ACPI_RSC_MOVE_GPIO_RES:
112  		case ACPI_RSC_MOVE_SERIAL_VEN:
113  		case ACPI_RSC_MOVE_SERIAL_RES:
114  
115  			memcpy(destination, source, item_count);
116  			return;
117  
118  			/*
119  			 * 16-, 32-, and 64-bit cases must use the move macros that perform
120  			 * endian conversion and/or accommodate hardware that cannot perform
121  			 * misaligned memory transfers
122  			 */
123  		case ACPI_RSC_MOVE16:
124  		case ACPI_RSC_MOVE_GPIO_PIN:
125  
126  			ACPI_MOVE_16_TO_16(&ACPI_CAST_PTR(u16, destination)[i],
127  					   &ACPI_CAST_PTR(u16, source)[i]);
128  			break;
129  
130  		case ACPI_RSC_MOVE32:
131  
132  			ACPI_MOVE_32_TO_32(&ACPI_CAST_PTR(u32, destination)[i],
133  					   &ACPI_CAST_PTR(u32, source)[i]);
134  			break;
135  
136  		case ACPI_RSC_MOVE64:
137  
138  			ACPI_MOVE_64_TO_64(&ACPI_CAST_PTR(u64, destination)[i],
139  					   &ACPI_CAST_PTR(u64, source)[i]);
140  			break;
141  
142  		default:
143  
144  			return;
145  		}
146  	}
147  }
148  
149  /*******************************************************************************
150   *
151   * FUNCTION:    acpi_rs_set_resource_length
152   *
153   * PARAMETERS:  total_length        - Length of the AML descriptor, including
154   *                                    the header and length fields.
155   *              aml                 - Pointer to the raw AML descriptor
156   *
157   * RETURN:      None
158   *
159   * DESCRIPTION: Set the resource_length field of an AML
160   *              resource descriptor, both Large and Small descriptors are
161   *              supported automatically. Note: Descriptor Type field must
162   *              be valid.
163   *
164   ******************************************************************************/
165  
166  void
acpi_rs_set_resource_length(acpi_rsdesc_size total_length,union aml_resource * aml)167  acpi_rs_set_resource_length(acpi_rsdesc_size total_length,
168  			    union aml_resource *aml)
169  {
170  	acpi_rs_length resource_length;
171  
172  	ACPI_FUNCTION_ENTRY();
173  
174  	/* Length is the total descriptor length minus the header length */
175  
176  	resource_length = (acpi_rs_length)
177  	    (total_length - acpi_ut_get_resource_header_length(aml));
178  
179  	/* Length is stored differently for large and small descriptors */
180  
181  	if (aml->small_header.descriptor_type & ACPI_RESOURCE_NAME_LARGE) {
182  
183  		/* Large descriptor -- bytes 1-2 contain the 16-bit length */
184  
185  		ACPI_MOVE_16_TO_16(&aml->large_header.resource_length,
186  				   &resource_length);
187  	} else {
188  		/*
189  		 * Small descriptor -- bits 2:0 of byte 0 contain the length
190  		 * Clear any existing length, preserving descriptor type bits
191  		 */
192  		aml->small_header.descriptor_type = (u8)
193  		    ((aml->small_header.descriptor_type &
194  		      ~ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK)
195  		     | resource_length);
196  	}
197  }
198  
199  /*******************************************************************************
200   *
201   * FUNCTION:    acpi_rs_set_resource_header
202   *
203   * PARAMETERS:  descriptor_type     - Byte to be inserted as the type
204   *              total_length        - Length of the AML descriptor, including
205   *                                    the header and length fields.
206   *              aml                 - Pointer to the raw AML descriptor
207   *
208   * RETURN:      None
209   *
210   * DESCRIPTION: Set the descriptor_type and resource_length fields of an AML
211   *              resource descriptor, both Large and Small descriptors are
212   *              supported automatically
213   *
214   ******************************************************************************/
215  
216  void
acpi_rs_set_resource_header(u8 descriptor_type,acpi_rsdesc_size total_length,union aml_resource * aml)217  acpi_rs_set_resource_header(u8 descriptor_type,
218  			    acpi_rsdesc_size total_length,
219  			    union aml_resource *aml)
220  {
221  	ACPI_FUNCTION_ENTRY();
222  
223  	/* Set the Resource Type */
224  
225  	aml->small_header.descriptor_type = descriptor_type;
226  
227  	/* Set the Resource Length */
228  
229  	acpi_rs_set_resource_length(total_length, aml);
230  }
231  
232  /*******************************************************************************
233   *
234   * FUNCTION:    acpi_rs_strcpy
235   *
236   * PARAMETERS:  destination         - Pointer to the destination string
237   *              source              - Pointer to the source string
238   *
239   * RETURN:      String length, including NULL terminator
240   *
241   * DESCRIPTION: Local string copy that returns the string length, saving a
242   *              strcpy followed by a strlen.
243   *
244   ******************************************************************************/
245  
acpi_rs_strcpy(char * destination,char * source)246  static u16 acpi_rs_strcpy(char *destination, char *source)
247  {
248  	u16 i;
249  
250  	ACPI_FUNCTION_ENTRY();
251  
252  	for (i = 0; source[i]; i++) {
253  		destination[i] = source[i];
254  	}
255  
256  	destination[i] = 0;
257  
258  	/* Return string length including the NULL terminator */
259  
260  	return ((u16) (i + 1));
261  }
262  
263  /*******************************************************************************
264   *
265   * FUNCTION:    acpi_rs_get_resource_source
266   *
267   * PARAMETERS:  resource_length     - Length field of the descriptor
268   *              minimum_length      - Minimum length of the descriptor (minus
269   *                                    any optional fields)
270   *              resource_source     - Where the resource_source is returned
271   *              aml                 - Pointer to the raw AML descriptor
272   *              string_ptr          - (optional) where to store the actual
273   *                                    resource_source string
274   *
275   * RETURN:      Length of the string plus NULL terminator, rounded up to native
276   *              word boundary
277   *
278   * DESCRIPTION: Copy the optional resource_source data from a raw AML descriptor
279   *              to an internal resource descriptor
280   *
281   ******************************************************************************/
282  
283  acpi_rs_length
acpi_rs_get_resource_source(acpi_rs_length resource_length,acpi_rs_length minimum_length,struct acpi_resource_source * resource_source,union aml_resource * aml,char * string_ptr)284  acpi_rs_get_resource_source(acpi_rs_length resource_length,
285  			    acpi_rs_length minimum_length,
286  			    struct acpi_resource_source * resource_source,
287  			    union aml_resource * aml, char *string_ptr)
288  {
289  	acpi_rsdesc_size total_length;
290  	u8 *aml_resource_source;
291  
292  	ACPI_FUNCTION_ENTRY();
293  
294  	total_length =
295  	    resource_length + sizeof(struct aml_resource_large_header);
296  	aml_resource_source = ACPI_ADD_PTR(u8, aml, minimum_length);
297  
298  	/*
299  	 * resource_source is present if the length of the descriptor is longer
300  	 * than the minimum length.
301  	 *
302  	 * Note: Some resource descriptors will have an additional null, so
303  	 * we add 1 to the minimum length.
304  	 */
305  	if (total_length > (acpi_rsdesc_size)(minimum_length + 1)) {
306  
307  		/* Get the resource_source_index */
308  
309  		resource_source->index = aml_resource_source[0];
310  
311  		resource_source->string_ptr = string_ptr;
312  		if (!string_ptr) {
313  			/*
314  			 * String destination pointer is not specified; Set the String
315  			 * pointer to the end of the current resource_source structure.
316  			 */
317  			resource_source->string_ptr =
318  			    ACPI_ADD_PTR(char, resource_source,
319  					 sizeof(struct acpi_resource_source));
320  		}
321  
322  		/*
323  		 * In order for the Resource length to be a multiple of the native
324  		 * word, calculate the length of the string (+1 for NULL terminator)
325  		 * and expand to the next word multiple.
326  		 *
327  		 * Zero the entire area of the buffer.
328  		 */
329  		total_length =
330  		    (u32)strlen(ACPI_CAST_PTR(char, &aml_resource_source[1])) +
331  		    1;
332  
333  		total_length = (u32)ACPI_ROUND_UP_TO_NATIVE_WORD(total_length);
334  
335  		memset(resource_source->string_ptr, 0, total_length);
336  
337  		/* Copy the resource_source string to the destination */
338  
339  		resource_source->string_length =
340  		    acpi_rs_strcpy(resource_source->string_ptr,
341  				   ACPI_CAST_PTR(char,
342  						 &aml_resource_source[1]));
343  
344  		return ((acpi_rs_length)total_length);
345  	}
346  
347  	/* resource_source is not present */
348  
349  	resource_source->index = 0;
350  	resource_source->string_length = 0;
351  	resource_source->string_ptr = NULL;
352  	return (0);
353  }
354  
355  /*******************************************************************************
356   *
357   * FUNCTION:    acpi_rs_set_resource_source
358   *
359   * PARAMETERS:  aml                 - Pointer to the raw AML descriptor
360   *              minimum_length      - Minimum length of the descriptor (minus
361   *                                    any optional fields)
362   *              resource_source     - Internal resource_source
363  
364   *
365   * RETURN:      Total length of the AML descriptor
366   *
367   * DESCRIPTION: Convert an optional resource_source from internal format to a
368   *              raw AML resource descriptor
369   *
370   ******************************************************************************/
371  
372  acpi_rsdesc_size
acpi_rs_set_resource_source(union aml_resource * aml,acpi_rs_length minimum_length,struct acpi_resource_source * resource_source)373  acpi_rs_set_resource_source(union aml_resource *aml,
374  			    acpi_rs_length minimum_length,
375  			    struct acpi_resource_source *resource_source)
376  {
377  	u8 *aml_resource_source;
378  	acpi_rsdesc_size descriptor_length;
379  
380  	ACPI_FUNCTION_ENTRY();
381  
382  	descriptor_length = minimum_length;
383  
384  	/* Non-zero string length indicates presence of a resource_source */
385  
386  	if (resource_source->string_length) {
387  
388  		/* Point to the end of the AML descriptor */
389  
390  		aml_resource_source = ACPI_ADD_PTR(u8, aml, minimum_length);
391  
392  		/* Copy the resource_source_index */
393  
394  		aml_resource_source[0] = (u8) resource_source->index;
395  
396  		/* Copy the resource_source string */
397  
398  		strcpy(ACPI_CAST_PTR(char, &aml_resource_source[1]),
399  		       resource_source->string_ptr);
400  
401  		/*
402  		 * Add the length of the string (+ 1 for null terminator) to the
403  		 * final descriptor length
404  		 */
405  		descriptor_length += ((acpi_rsdesc_size)
406  				      resource_source->string_length + 1);
407  	}
408  
409  	/* Return the new total length of the AML descriptor */
410  
411  	return (descriptor_length);
412  }
413  
414  /*******************************************************************************
415   *
416   * FUNCTION:    acpi_rs_get_prt_method_data
417   *
418   * PARAMETERS:  node            - Device node
419   *              ret_buffer      - Pointer to a buffer structure for the
420   *                                results
421   *
422   * RETURN:      Status
423   *
424   * DESCRIPTION: This function is called to get the _PRT value of an object
425   *              contained in an object specified by the handle passed in
426   *
427   *              If the function fails an appropriate status will be returned
428   *              and the contents of the callers buffer is undefined.
429   *
430   ******************************************************************************/
431  
432  acpi_status
acpi_rs_get_prt_method_data(struct acpi_namespace_node * node,struct acpi_buffer * ret_buffer)433  acpi_rs_get_prt_method_data(struct acpi_namespace_node *node,
434  			    struct acpi_buffer *ret_buffer)
435  {
436  	union acpi_operand_object *obj_desc;
437  	acpi_status status;
438  
439  	ACPI_FUNCTION_TRACE(rs_get_prt_method_data);
440  
441  	/* Parameters guaranteed valid by caller */
442  
443  	/* Execute the method, no parameters */
444  
445  	status =
446  	    acpi_ut_evaluate_object(node, METHOD_NAME__PRT, ACPI_BTYPE_PACKAGE,
447  				    &obj_desc);
448  	if (ACPI_FAILURE(status)) {
449  		return_ACPI_STATUS(status);
450  	}
451  
452  	/*
453  	 * Create a resource linked list from the byte stream buffer that comes
454  	 * back from the _CRS method execution.
455  	 */
456  	status = acpi_rs_create_pci_routing_table(obj_desc, ret_buffer);
457  
458  	/* On exit, we must delete the object returned by evaluate_object */
459  
460  	acpi_ut_remove_reference(obj_desc);
461  	return_ACPI_STATUS(status);
462  }
463  
464  /*******************************************************************************
465   *
466   * FUNCTION:    acpi_rs_get_crs_method_data
467   *
468   * PARAMETERS:  node            - Device node
469   *              ret_buffer      - Pointer to a buffer structure for the
470   *                                results
471   *
472   * RETURN:      Status
473   *
474   * DESCRIPTION: This function is called to get the _CRS value of an object
475   *              contained in an object specified by the handle passed in
476   *
477   *              If the function fails an appropriate status will be returned
478   *              and the contents of the callers buffer is undefined.
479   *
480   ******************************************************************************/
481  
482  acpi_status
acpi_rs_get_crs_method_data(struct acpi_namespace_node * node,struct acpi_buffer * ret_buffer)483  acpi_rs_get_crs_method_data(struct acpi_namespace_node *node,
484  			    struct acpi_buffer *ret_buffer)
485  {
486  	union acpi_operand_object *obj_desc;
487  	acpi_status status;
488  
489  	ACPI_FUNCTION_TRACE(rs_get_crs_method_data);
490  
491  	/* Parameters guaranteed valid by caller */
492  
493  	/* Execute the method, no parameters */
494  
495  	status =
496  	    acpi_ut_evaluate_object(node, METHOD_NAME__CRS, ACPI_BTYPE_BUFFER,
497  				    &obj_desc);
498  	if (ACPI_FAILURE(status)) {
499  		return_ACPI_STATUS(status);
500  	}
501  
502  	/*
503  	 * Make the call to create a resource linked list from the
504  	 * byte stream buffer that comes back from the _CRS method
505  	 * execution.
506  	 */
507  	status = acpi_rs_create_resource_list(obj_desc, ret_buffer);
508  
509  	/* On exit, we must delete the object returned by evaluateObject */
510  
511  	acpi_ut_remove_reference(obj_desc);
512  	return_ACPI_STATUS(status);
513  }
514  
515  /*******************************************************************************
516   *
517   * FUNCTION:    acpi_rs_get_prs_method_data
518   *
519   * PARAMETERS:  node            - Device node
520   *              ret_buffer      - Pointer to a buffer structure for the
521   *                                results
522   *
523   * RETURN:      Status
524   *
525   * DESCRIPTION: This function is called to get the _PRS value of an object
526   *              contained in an object specified by the handle passed in
527   *
528   *              If the function fails an appropriate status will be returned
529   *              and the contents of the callers buffer is undefined.
530   *
531   ******************************************************************************/
532  
533  acpi_status
acpi_rs_get_prs_method_data(struct acpi_namespace_node * node,struct acpi_buffer * ret_buffer)534  acpi_rs_get_prs_method_data(struct acpi_namespace_node *node,
535  			    struct acpi_buffer *ret_buffer)
536  {
537  	union acpi_operand_object *obj_desc;
538  	acpi_status status;
539  
540  	ACPI_FUNCTION_TRACE(rs_get_prs_method_data);
541  
542  	/* Parameters guaranteed valid by caller */
543  
544  	/* Execute the method, no parameters */
545  
546  	status =
547  	    acpi_ut_evaluate_object(node, METHOD_NAME__PRS, ACPI_BTYPE_BUFFER,
548  				    &obj_desc);
549  	if (ACPI_FAILURE(status)) {
550  		return_ACPI_STATUS(status);
551  	}
552  
553  	/*
554  	 * Make the call to create a resource linked list from the
555  	 * byte stream buffer that comes back from the _CRS method
556  	 * execution.
557  	 */
558  	status = acpi_rs_create_resource_list(obj_desc, ret_buffer);
559  
560  	/* On exit, we must delete the object returned by evaluateObject */
561  
562  	acpi_ut_remove_reference(obj_desc);
563  	return_ACPI_STATUS(status);
564  }
565  
566  /*******************************************************************************
567   *
568   * FUNCTION:    acpi_rs_get_aei_method_data
569   *
570   * PARAMETERS:  node            - Device node
571   *              ret_buffer      - Pointer to a buffer structure for the
572   *                                results
573   *
574   * RETURN:      Status
575   *
576   * DESCRIPTION: This function is called to get the _AEI value of an object
577   *              contained in an object specified by the handle passed in
578   *
579   *              If the function fails an appropriate status will be returned
580   *              and the contents of the callers buffer is undefined.
581   *
582   ******************************************************************************/
583  
584  acpi_status
acpi_rs_get_aei_method_data(struct acpi_namespace_node * node,struct acpi_buffer * ret_buffer)585  acpi_rs_get_aei_method_data(struct acpi_namespace_node *node,
586  			    struct acpi_buffer *ret_buffer)
587  {
588  	union acpi_operand_object *obj_desc;
589  	acpi_status status;
590  
591  	ACPI_FUNCTION_TRACE(rs_get_aei_method_data);
592  
593  	/* Parameters guaranteed valid by caller */
594  
595  	/* Execute the method, no parameters */
596  
597  	status =
598  	    acpi_ut_evaluate_object(node, METHOD_NAME__AEI, ACPI_BTYPE_BUFFER,
599  				    &obj_desc);
600  	if (ACPI_FAILURE(status)) {
601  		return_ACPI_STATUS(status);
602  	}
603  
604  	/*
605  	 * Make the call to create a resource linked list from the
606  	 * byte stream buffer that comes back from the _CRS method
607  	 * execution.
608  	 */
609  	status = acpi_rs_create_resource_list(obj_desc, ret_buffer);
610  
611  	/* On exit, we must delete the object returned by evaluateObject */
612  
613  	acpi_ut_remove_reference(obj_desc);
614  	return_ACPI_STATUS(status);
615  }
616  
617  /*******************************************************************************
618   *
619   * FUNCTION:    acpi_rs_get_method_data
620   *
621   * PARAMETERS:  handle          - Handle to the containing object
622   *              path            - Path to method, relative to Handle
623   *              ret_buffer      - Pointer to a buffer structure for the
624   *                                results
625   *
626   * RETURN:      Status
627   *
628   * DESCRIPTION: This function is called to get the _CRS or _PRS value of an
629   *              object contained in an object specified by the handle passed in
630   *
631   *              If the function fails an appropriate status will be returned
632   *              and the contents of the callers buffer is undefined.
633   *
634   ******************************************************************************/
635  
636  acpi_status
acpi_rs_get_method_data(acpi_handle handle,const char * path,struct acpi_buffer * ret_buffer)637  acpi_rs_get_method_data(acpi_handle handle,
638  			const char *path, struct acpi_buffer *ret_buffer)
639  {
640  	union acpi_operand_object *obj_desc;
641  	acpi_status status;
642  
643  	ACPI_FUNCTION_TRACE(rs_get_method_data);
644  
645  	/* Parameters guaranteed valid by caller */
646  
647  	/* Execute the method, no parameters */
648  
649  	status =
650  	    acpi_ut_evaluate_object(ACPI_CAST_PTR
651  				    (struct acpi_namespace_node, handle), path,
652  				    ACPI_BTYPE_BUFFER, &obj_desc);
653  	if (ACPI_FAILURE(status)) {
654  		return_ACPI_STATUS(status);
655  	}
656  
657  	/*
658  	 * Make the call to create a resource linked list from the
659  	 * byte stream buffer that comes back from the method
660  	 * execution.
661  	 */
662  	status = acpi_rs_create_resource_list(obj_desc, ret_buffer);
663  
664  	/* On exit, we must delete the object returned by evaluate_object */
665  
666  	acpi_ut_remove_reference(obj_desc);
667  	return_ACPI_STATUS(status);
668  }
669  
670  /*******************************************************************************
671   *
672   * FUNCTION:    acpi_rs_set_srs_method_data
673   *
674   * PARAMETERS:  node            - Device node
675   *              in_buffer       - Pointer to a buffer structure of the
676   *                                parameter
677   *
678   * RETURN:      Status
679   *
680   * DESCRIPTION: This function is called to set the _SRS of an object contained
681   *              in an object specified by the handle passed in
682   *
683   *              If the function fails an appropriate status will be returned
684   *              and the contents of the callers buffer is undefined.
685   *
686   * Note: Parameters guaranteed valid by caller
687   *
688   ******************************************************************************/
689  
690  acpi_status
acpi_rs_set_srs_method_data(struct acpi_namespace_node * node,struct acpi_buffer * in_buffer)691  acpi_rs_set_srs_method_data(struct acpi_namespace_node *node,
692  			    struct acpi_buffer *in_buffer)
693  {
694  	struct acpi_evaluate_info *info;
695  	union acpi_operand_object *args[2];
696  	acpi_status status;
697  	struct acpi_buffer buffer;
698  
699  	ACPI_FUNCTION_TRACE(rs_set_srs_method_data);
700  
701  	/* Allocate and initialize the evaluation information block */
702  
703  	info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
704  	if (!info) {
705  		return_ACPI_STATUS(AE_NO_MEMORY);
706  	}
707  
708  	info->prefix_node = node;
709  	info->relative_pathname = METHOD_NAME__SRS;
710  	info->parameters = args;
711  	info->flags = ACPI_IGNORE_RETURN_VALUE;
712  
713  	/*
714  	 * The in_buffer parameter will point to a linked list of
715  	 * resource parameters. It needs to be formatted into a
716  	 * byte stream to be sent in as an input parameter to _SRS
717  	 *
718  	 * Convert the linked list into a byte stream
719  	 */
720  	buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
721  	status = acpi_rs_create_aml_resources(in_buffer, &buffer);
722  	if (ACPI_FAILURE(status)) {
723  		goto cleanup;
724  	}
725  
726  	/* Create and initialize the method parameter object */
727  
728  	args[0] = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER);
729  	if (!args[0]) {
730  		/*
731  		 * Must free the buffer allocated above (otherwise it is freed
732  		 * later)
733  		 */
734  		ACPI_FREE(buffer.pointer);
735  		status = AE_NO_MEMORY;
736  		goto cleanup;
737  	}
738  
739  	args[0]->buffer.length = (u32) buffer.length;
740  	args[0]->buffer.pointer = buffer.pointer;
741  	args[0]->common.flags = AOPOBJ_DATA_VALID;
742  	args[1] = NULL;
743  
744  	/* Execute the method, no return value is expected */
745  
746  	status = acpi_ns_evaluate(info);
747  
748  	/* Clean up and return the status from acpi_ns_evaluate */
749  
750  	acpi_ut_remove_reference(args[0]);
751  
752  cleanup:
753  	ACPI_FREE(info);
754  	return_ACPI_STATUS(status);
755  }
756