• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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