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