Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]

Diff markup

Differences between /linux/drivers/acpi/dispatcher/dsmethod.c (Version 2.6.25) and /linux/drivers/acpi/dispatcher/dsmethod.c (Version 2.6.11.8)


  1 /*********************************************      1 /******************************************************************************
  2  *                                                  2  *
  3  * Module Name: dsmethod - Parser/Interpreter       3  * Module Name: dsmethod - Parser/Interpreter interface - control method parsing
  4  *                                                  4  *
  5  *********************************************      5  *****************************************************************************/
  6                                                     6 
  7 /*                                                  7 /*
  8  * Copyright (C) 2000 - 2007, R. Byron Moore   !!   8  * Copyright (C) 2000 - 2005, R. Byron Moore
  9  * All rights reserved.                             9  * All rights reserved.
 10  *                                                 10  *
 11  * Redistribution and use in source and binary     11  * Redistribution and use in source and binary forms, with or without
 12  * modification, are permitted provided that t     12  * modification, are permitted provided that the following conditions
 13  * are met:                                        13  * are met:
 14  * 1. Redistributions of source code must reta     14  * 1. Redistributions of source code must retain the above copyright
 15  *    notice, this list of conditions, and the     15  *    notice, this list of conditions, and the following disclaimer,
 16  *    without modification.                        16  *    without modification.
 17  * 2. Redistributions in binary form must repr     17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
 18  *    substantially similar to the "NO WARRANT     18  *    substantially similar to the "NO WARRANTY" disclaimer below
 19  *    ("Disclaimer") and any redistribution mu     19  *    ("Disclaimer") and any redistribution must be conditioned upon
 20  *    including a substantially similar Discla     20  *    including a substantially similar Disclaimer requirement for further
 21  *    binary redistribution.                       21  *    binary redistribution.
 22  * 3. Neither the names of the above-listed co     22  * 3. Neither the names of the above-listed copyright holders nor the names
 23  *    of any contributors may be used to endor     23  *    of any contributors may be used to endorse or promote products derived
 24  *    from this software without specific prio     24  *    from this software without specific prior written permission.
 25  *                                                 25  *
 26  * Alternatively, this software may be distrib     26  * Alternatively, this software may be distributed under the terms of the
 27  * GNU General Public License ("GPL") version      27  * GNU General Public License ("GPL") version 2 as published by the Free
 28  * Software Foundation.                            28  * Software Foundation.
 29  *                                                 29  *
 30  * NO WARRANTY                                     30  * NO WARRANTY
 31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT      31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTI     32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCH     33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
 34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO      34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECI     35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PRO     36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS;     37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILI     38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIG     39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,     40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 41  * POSSIBILITY OF SUCH DAMAGES.                    41  * POSSIBILITY OF SUCH DAMAGES.
 42  */                                                42  */
 43                                                    43 
                                                   >>  44 
 44 #include <acpi/acpi.h>                             45 #include <acpi/acpi.h>
 45 #include <acpi/acparser.h>                         46 #include <acpi/acparser.h>
 46 #include <acpi/amlcode.h>                          47 #include <acpi/amlcode.h>
 47 #include <acpi/acdispat.h>                         48 #include <acpi/acdispat.h>
 48 #include <acpi/acinterp.h>                         49 #include <acpi/acinterp.h>
 49 #include <acpi/acnamesp.h>                         50 #include <acpi/acnamesp.h>
 50 #include <acpi/acdisasm.h>                     !!  51 
 51                                                    52 
 52 #define _COMPONENT          ACPI_DISPATCHER        53 #define _COMPONENT          ACPI_DISPATCHER
 53 ACPI_MODULE_NAME("dsmethod")                   !!  54          ACPI_MODULE_NAME    ("dsmethod")
 54                                                    55 
 55 /* Local prototypes */                         << 
 56 static acpi_status                             << 
 57 acpi_ds_create_method_mutex(union acpi_operand << 
 58                                                    56 
 59 /*********************************************     57 /*******************************************************************************
 60  *                                                 58  *
 61  * FUNCTION:    acpi_ds_method_error           !!  59  * FUNCTION:    acpi_ds_parse_method
 62  *                                                 60  *
 63  * PARAMETERS:  Status          - Execution st !!  61  * PARAMETERS:  obj_handle      - Method node
 64  *              walk_state      - Current stat << 
 65  *                                                 62  *
 66  * RETURN:      Status                             63  * RETURN:      Status
 67  *                                                 64  *
 68  * DESCRIPTION: Called on method error. Invoke !!  65  * DESCRIPTION: Call the parser and parse the AML that is associated with the
 69  *              present, dump the method data  !!  66  *              method.
 70  *                                                 67  *
 71  *              Note: Allows the exception han !!  68  * MUTEX:       Assumes parser is locked
 72  *                                                 69  *
 73  *********************************************     70  ******************************************************************************/
 74                                                    71 
 75 acpi_status                                        72 acpi_status
 76 acpi_ds_method_error(acpi_status status, struc !!  73 acpi_ds_parse_method (
                                                   >>  74         acpi_handle                     obj_handle)
 77 {                                                  75 {
 78         ACPI_FUNCTION_ENTRY();                 !!  76         acpi_status                     status;
                                                   >>  77         union acpi_operand_object       *obj_desc;
                                                   >>  78         union acpi_parse_object         *op;
                                                   >>  79         struct acpi_namespace_node      *node;
                                                   >>  80         acpi_owner_id                   owner_id;
                                                   >>  81         struct acpi_walk_state          *walk_state;
 79                                                    82 
 80         /* Ignore AE_OK and control exception  << 
 81                                                    83 
 82         if (ACPI_SUCCESS(status) || (status &  !!  84         ACPI_FUNCTION_TRACE_PTR ("ds_parse_method", obj_handle);
 83                 return (status);               << 
 84         }                                      << 
 85                                                    85 
 86         /* Invoke the global exception handler << 
 87                                                    86 
 88         if (acpi_gbl_exception_handler) {      !!  87         /* Parameter Validation */
 89                                                    88 
 90                 /* Exit the interpreter, allow !!  89         if (!obj_handle) {
                                                   >>  90                 return_ACPI_STATUS (AE_NULL_ENTRY);
                                                   >>  91         }
 91                                                    92 
 92                 acpi_ex_exit_interpreter();    !!  93         ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "**** Parsing [%4.4s] **** named_obj=%p\n",
                                                   >>  94                 acpi_ut_get_node_name (obj_handle), obj_handle));
 93                                                    95 
 94                 /*                             !!  96         /* Extract the method object from the method Node */
 95                  * Handler can map the excepti !!  97 
 96                  * AE_OK, in which case the ex !!  98         node = (struct acpi_namespace_node *) obj_handle;
 97                  */                            !!  99         obj_desc = acpi_ns_get_attached_object (node);
 98                 status = acpi_gbl_exception_ha !! 100         if (!obj_desc) {
 99                                                !! 101                 return_ACPI_STATUS (AE_NULL_OBJECT);
100                                                << 
101                                                << 
102                                                << 
103                                                << 
104                                                << 
105                 (void)acpi_ex_enter_interprete << 
106         }                                         102         }
107 #ifdef ACPI_DISASSEMBLER                       << 
108         if (ACPI_FAILURE(status)) {            << 
109                                                   103 
110                 /* Display method locals/args  !! 104         /* Create a mutex for the method if there is a concurrency limit */
111                                                   105 
112                 acpi_dm_dump_method_info(statu !! 106         if ((obj_desc->method.concurrency != ACPI_INFINITE_CONCURRENCY) &&
                                                   >> 107                 (!obj_desc->method.semaphore)) {
                                                   >> 108                 status = acpi_os_create_semaphore (obj_desc->method.concurrency,
                                                   >> 109                                    obj_desc->method.concurrency,
                                                   >> 110                                    &obj_desc->method.semaphore);
                                                   >> 111                 if (ACPI_FAILURE (status)) {
                                                   >> 112                         return_ACPI_STATUS (status);
                                                   >> 113                 }
113         }                                         114         }
114 #endif                                         << 
115                                                   115 
116         return (status);                       !! 116         /*
117 }                                              !! 117          * Allocate a new parser op to be the root of the parsed
                                                   >> 118          * method tree
                                                   >> 119          */
                                                   >> 120         op = acpi_ps_alloc_op (AML_METHOD_OP);
                                                   >> 121         if (!op) {
                                                   >> 122                 return_ACPI_STATUS (AE_NO_MEMORY);
                                                   >> 123         }
118                                                   124 
119 /********************************************* !! 125         /* Init new op with the method name and pointer back to the Node */
120  *                                             << 
121  * FUNCTION:    acpi_ds_create_method_mutex    << 
122  *                                             << 
123  * PARAMETERS:  obj_desc            - The meth << 
124  *                                             << 
125  * RETURN:      Status                         << 
126  *                                             << 
127  * DESCRIPTION: Create a mutex object for a se << 
128  *                                             << 
129  ********************************************* << 
130                                                   126 
131 static acpi_status                             !! 127         acpi_ps_set_name (op, node->name.integer);
132 acpi_ds_create_method_mutex(union acpi_operand !! 128         op->common.node = node;
133 {                                              << 
134         union acpi_operand_object *mutex_desc; << 
135         acpi_status status;                    << 
136                                                   129 
137         ACPI_FUNCTION_TRACE(ds_create_method_m !! 130         /*
                                                   >> 131          * Get a new owner_id for objects created by this method. Namespace
                                                   >> 132          * objects (such as Operation Regions) can be created during the
                                                   >> 133          * first pass parse.
                                                   >> 134          */
                                                   >> 135         owner_id = acpi_ut_allocate_owner_id (ACPI_OWNER_TYPE_METHOD);
                                                   >> 136         obj_desc->method.owning_id = owner_id;
138                                                   137 
139         /* Create the new mutex object */      !! 138         /* Create and initialize a new walk state */
140                                                   139 
141         mutex_desc = acpi_ut_create_internal_o !! 140         walk_state = acpi_ds_create_walk_state (owner_id, NULL, NULL, NULL);
142         if (!mutex_desc) {                     !! 141         if (!walk_state) {
143                 return_ACPI_STATUS(AE_NO_MEMOR !! 142                 return_ACPI_STATUS (AE_NO_MEMORY);
                                                   >> 143         }
                                                   >> 144 
                                                   >> 145         status = acpi_ds_init_aml_walk (walk_state, op, node,
                                                   >> 146                           obj_desc->method.aml_start,
                                                   >> 147                           obj_desc->method.aml_length, NULL, 1);
                                                   >> 148         if (ACPI_FAILURE (status)) {
                                                   >> 149                 acpi_ds_delete_walk_state (walk_state);
                                                   >> 150                 return_ACPI_STATUS (status);
144         }                                         151         }
145                                                   152 
146         /* Create the actual OS Mutex */       !! 153         /*
147                                                !! 154          * Parse the method, first pass
148         status = acpi_os_create_mutex(&mutex_d !! 155          *
149         if (ACPI_FAILURE(status)) {            !! 156          * The first pass load is where newly declared named objects are
150                 return_ACPI_STATUS(status);    !! 157          * added into the namespace.  Actual evaluation of
                                                   >> 158          * the named objects (what would be called a "second
                                                   >> 159          * pass") happens during the actual execution of the
                                                   >> 160          * method so that operands to the named objects can
                                                   >> 161          * take on dynamic run-time values.
                                                   >> 162          */
                                                   >> 163         status = acpi_ps_parse_aml (walk_state);
                                                   >> 164         if (ACPI_FAILURE (status)) {
                                                   >> 165                 return_ACPI_STATUS (status);
151         }                                         166         }
152                                                   167 
153         mutex_desc->mutex.sync_level = method_ !! 168         ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
154         method_desc->method.mutex = mutex_desc !! 169                 "**** [%4.4s] Parsed **** named_obj=%p Op=%p\n",
155         return_ACPI_STATUS(AE_OK);             !! 170                 acpi_ut_get_node_name (obj_handle), obj_handle, op));
                                                   >> 171 
                                                   >> 172         acpi_ps_delete_parse_tree (op);
                                                   >> 173         return_ACPI_STATUS (status);
156 }                                                 174 }
157                                                   175 
                                                   >> 176 
158 /*********************************************    177 /*******************************************************************************
159  *                                                178  *
160  * FUNCTION:    acpi_ds_begin_method_execution    179  * FUNCTION:    acpi_ds_begin_method_execution
161  *                                                180  *
162  * PARAMETERS:  method_node         - Node of     181  * PARAMETERS:  method_node         - Node of the method
163  *              obj_desc            - The meth    182  *              obj_desc            - The method object
164  *              walk_state          - current  !! 183  *              calling_method_node - Caller of this method (if non-null)
165  *                                    a method << 
166  *                                                184  *
167  * RETURN:      Status                            185  * RETURN:      Status
168  *                                                186  *
169  * DESCRIPTION: Prepare a method for execution    187  * DESCRIPTION: Prepare a method for execution.  Parses the method if necessary,
170  *              increments the thread count, a    188  *              increments the thread count, and waits at the method semaphore
171  *              for clearance to execute.         189  *              for clearance to execute.
172  *                                                190  *
173  *********************************************    191  ******************************************************************************/
174                                                   192 
175 acpi_status                                       193 acpi_status
176 acpi_ds_begin_method_execution(struct acpi_nam !! 194 acpi_ds_begin_method_execution (
177                                union acpi_oper !! 195         struct acpi_namespace_node      *method_node,
178                                struct acpi_wal !! 196         union acpi_operand_object       *obj_desc,
                                                   >> 197         struct acpi_namespace_node      *calling_method_node)
179 {                                                 198 {
180         acpi_status status = AE_OK;            !! 199         acpi_status                     status = AE_OK;
181                                                   200 
182         ACPI_FUNCTION_TRACE_PTR(ds_begin_metho << 
183                                                   201 
184         if (!method_node) {                    !! 202         ACPI_FUNCTION_TRACE_PTR ("ds_begin_method_execution", method_node);
185                 return_ACPI_STATUS(AE_NULL_ENT << 
186         }                                      << 
187                                                   203 
188         /* Prevent wraparound of thread count  << 
189                                                   204 
190         if (obj_desc->method.thread_count == A !! 205         if (!method_node) {
191                 ACPI_ERROR((AE_INFO,           !! 206                 return_ACPI_STATUS (AE_NULL_ENTRY);
192                             "Method reached ma << 
193                 return_ACPI_STATUS(AE_AML_METH << 
194         }                                         207         }
195                                                   208 
196         /*                                        209         /*
197          * If this method is serialized, we ne !! 210          * If there is a concurrency limit on this method, we need to
                                                   >> 211          * obtain a unit from the method semaphore.
198          */                                       212          */
199         if (obj_desc->method.method_flags & AM !! 213         if (obj_desc->method.semaphore) {
200                 /*                             << 
201                  * Create a mutex for the meth << 
202                  * and a mutex has not already << 
203                  * until a method is actually  << 
204                  */                            << 
205                 if (!obj_desc->method.mutex) { << 
206                         status = acpi_ds_creat << 
207                         if (ACPI_FAILURE(statu << 
208                                 return_ACPI_ST << 
209                         }                      << 
210                 }                              << 
211                                                << 
212                 /*                                214                 /*
213                  * The current_sync_level (per !! 215                  * Allow recursive method calls, up to the reentrancy/concurrency
214                  * the sync level of the metho !! 216                  * limit imposed by the SERIALIZED rule and the sync_level method
215                  * deadlock prevention         !! 217                  * parameter.
216                  *                                218                  *
217                  * Top-level method invocation !! 219                  * The point of this code is to avoid permanently blocking a
                                                   >> 220                  * thread that is making recursive method calls.
218                  */                               221                  */
219                 if (walk_state &&              !! 222                 if (method_node == calling_method_node) {
220                     (walk_state->thread->curre !! 223                         if (obj_desc->method.thread_count >= obj_desc->method.concurrency) {
221                      obj_desc->method.mutex->m !! 224                                 return_ACPI_STATUS (AE_AML_METHOD_LIMIT);
222                         ACPI_ERROR((AE_INFO,   !! 225                         }
223                                     "Cannot ac << 
224                                     acpi_ut_ge << 
225                                     walk_state << 
226                                                << 
227                         return_ACPI_STATUS(AE_ << 
228                 }                                 226                 }
229                                                   227 
230                 /*                                228                 /*
231                  * Obtain the method mutex if  !! 229                  * Get a unit from the method semaphore. This releases the
232                  * recursive call.             !! 230                  * interpreter if we block
233                  */                               231                  */
234                 if (!walk_state ||             !! 232                 status = acpi_ex_system_wait_semaphore (obj_desc->method.semaphore,
235                     !obj_desc->method.mutex->m !! 233                                  ACPI_WAIT_FOREVER);
236                     (walk_state->thread !=     << 
237                      obj_desc->method.mutex->m << 
238                         /*                     << 
239                          * Acquire the method  << 
240                          * block (and reacquir << 
241                          */                    << 
242                         status =               << 
243                             acpi_ex_system_wai << 
244                                                << 
245                                                << 
246                         if (ACPI_FAILURE(statu << 
247                                 return_ACPI_ST << 
248                         }                      << 
249                                                << 
250                         /* Update the mutex an << 
251                                                << 
252                         if (walk_state) {      << 
253                                 obj_desc->meth << 
254                                     original_s << 
255                                     walk_state << 
256                                                << 
257                                 obj_desc->meth << 
258                                     walk_state << 
259                                 walk_state->th << 
260                                     obj_desc-> << 
261                         } else {               << 
262                                 obj_desc->meth << 
263                                     original_s << 
264                                     obj_desc-> << 
265                         }                      << 
266                 }                              << 
267                                                << 
268                 /* Always increase acquisition << 
269                                                << 
270                 obj_desc->method.mutex->mutex. << 
271         }                                      << 
272                                                << 
273         /*                                     << 
274          * Allocate an Owner ID for this metho << 
275          * to begin concurrent execution. We o << 
276          * method is invoked recursively.      << 
277          */                                    << 
278         if (!obj_desc->method.owner_id) {      << 
279                 status = acpi_ut_allocate_owne << 
280                 if (ACPI_FAILURE(status)) {    << 
281                         goto cleanup;          << 
282                 }                              << 
283         }                                         234         }
284                                                   235 
285         /*                                        236         /*
286          * Increment the method parse tree thr    237          * Increment the method parse tree thread count since it has been
287          * reentered one more time (even if it    238          * reentered one more time (even if it is the same thread)
288          */                                       239          */
289         obj_desc->method.thread_count++;          240         obj_desc->method.thread_count++;
290         return_ACPI_STATUS(status);            !! 241         return_ACPI_STATUS (status);
291                                                << 
292       cleanup:                                 << 
293         /* On error, must release the method m << 
294                                                << 
295         if (obj_desc->method.mutex) {          << 
296                 acpi_os_release_mutex(obj_desc << 
297         }                                      << 
298         return_ACPI_STATUS(status);            << 
299 }                                                 242 }
300                                                   243 
                                                   >> 244 
301 /*********************************************    245 /*******************************************************************************
302  *                                                246  *
303  * FUNCTION:    acpi_ds_call_control_method       247  * FUNCTION:    acpi_ds_call_control_method
304  *                                                248  *
305  * PARAMETERS:  Thread              - Info for    249  * PARAMETERS:  Thread              - Info for this thread
306  *              this_walk_state     - Current     250  *              this_walk_state     - Current walk state
307  *              Op                  - Current     251  *              Op                  - Current Op to be walked
308  *                                                252  *
309  * RETURN:      Status                            253  * RETURN:      Status
310  *                                                254  *
311  * DESCRIPTION: Transfer execution to a called    255  * DESCRIPTION: Transfer execution to a called control method
312  *                                                256  *
313  *********************************************    257  ******************************************************************************/
314                                                   258 
315 acpi_status                                       259 acpi_status
316 acpi_ds_call_control_method(struct acpi_thread !! 260 acpi_ds_call_control_method (
317                             struct acpi_walk_s !! 261         struct acpi_thread_state        *thread,
318                             union acpi_parse_o !! 262         struct acpi_walk_state          *this_walk_state,
                                                   >> 263         union acpi_parse_object         *op)
319 {                                                 264 {
320         acpi_status status;                    !! 265         acpi_status                     status;
321         struct acpi_namespace_node *method_nod !! 266         struct acpi_namespace_node      *method_node;
322         struct acpi_walk_state *next_walk_stat !! 267         struct acpi_walk_state          *next_walk_state;
323         union acpi_operand_object *obj_desc;   !! 268         union acpi_operand_object       *obj_desc;
324         struct acpi_evaluate_info *info;       !! 269         struct acpi_parameter_info      info;
325         u32 i;                                 !! 270         u32                             i;
326                                                !! 271 
327         ACPI_FUNCTION_TRACE_PTR(ds_call_contro !! 272 
328                                                !! 273         ACPI_FUNCTION_TRACE_PTR ("ds_call_control_method", this_walk_state);
329         ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,    !! 274 
330                           "Calling method %p,  !! 275         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Execute method %p, currentstate=%p\n",
331                           this_walk_state->pre !! 276                 this_walk_state->prev_op, this_walk_state));
332                                                   277 
333         /*                                        278         /*
334          * Get the namespace entry for the con    279          * Get the namespace entry for the control method we are about to call
335          */                                       280          */
336         method_node = this_walk_state->method_    281         method_node = this_walk_state->method_call_node;
337         if (!method_node) {                       282         if (!method_node) {
338                 return_ACPI_STATUS(AE_NULL_ENT !! 283                 return_ACPI_STATUS (AE_NULL_ENTRY);
339         }                                         284         }
340                                                   285 
341         obj_desc = acpi_ns_get_attached_object !! 286         obj_desc = acpi_ns_get_attached_object (method_node);
342         if (!obj_desc) {                          287         if (!obj_desc) {
343                 return_ACPI_STATUS(AE_NULL_OBJ !! 288                 return_ACPI_STATUS (AE_NULL_OBJECT);
344         }                                         289         }
345                                                   290 
346         /* Init for new method, possibly wait  !! 291         obj_desc->method.owning_id = acpi_ut_allocate_owner_id (ACPI_OWNER_TYPE_METHOD);
                                                   >> 292 
                                                   >> 293         /* Init for new method, wait on concurrency semaphore */
347                                                   294 
348         status = acpi_ds_begin_method_executio !! 295         status = acpi_ds_begin_method_execution (method_node, obj_desc,
349                                                !! 296                           this_walk_state->method_node);
350         if (ACPI_FAILURE(status)) {            !! 297         if (ACPI_FAILURE (status)) {
351                 return_ACPI_STATUS(status);    !! 298                 return_ACPI_STATUS (status);
352         }                                         299         }
353                                                   300 
354         /* Begin method parse/execution. Creat !! 301         if (!(obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY)) {
                                                   >> 302                 /* 1) Parse: Create a new walk state for the preempting walk */
                                                   >> 303 
                                                   >> 304                 next_walk_state = acpi_ds_create_walk_state (obj_desc->method.owning_id,
                                                   >> 305                                   op, obj_desc, NULL);
                                                   >> 306                 if (!next_walk_state) {
                                                   >> 307                         return_ACPI_STATUS (AE_NO_MEMORY);
                                                   >> 308                 }
                                                   >> 309 
                                                   >> 310                 /* Create and init a Root Node */
                                                   >> 311 
                                                   >> 312                 op = acpi_ps_create_scope_op ();
                                                   >> 313                 if (!op) {
                                                   >> 314                         status = AE_NO_MEMORY;
                                                   >> 315                         goto cleanup;
                                                   >> 316                 }
355                                                   317 
356         next_walk_state = acpi_ds_create_walk_ !! 318                 status = acpi_ds_init_aml_walk (next_walk_state, op, method_node,
357                                                !! 319                                   obj_desc->method.aml_start, obj_desc->method.aml_length,
                                                   >> 320                                   NULL, 1);
                                                   >> 321                 if (ACPI_FAILURE (status)) {
                                                   >> 322                         acpi_ds_delete_walk_state (next_walk_state);
                                                   >> 323                         goto cleanup;
                                                   >> 324                 }
                                                   >> 325 
                                                   >> 326                 /* Begin AML parse */
                                                   >> 327 
                                                   >> 328                 status = acpi_ps_parse_aml (next_walk_state);
                                                   >> 329                 acpi_ps_delete_parse_tree (op);
                                                   >> 330         }
                                                   >> 331 
                                                   >> 332         /* 2) Execute: Create a new state for the preempting walk */
                                                   >> 333 
                                                   >> 334         next_walk_state = acpi_ds_create_walk_state (obj_desc->method.owning_id,
                                                   >> 335                           NULL, obj_desc, thread);
358         if (!next_walk_state) {                   336         if (!next_walk_state) {
359                 status = AE_NO_MEMORY;            337                 status = AE_NO_MEMORY;
360                 goto cleanup;                     338                 goto cleanup;
361         }                                         339         }
362                                                << 
363         /*                                        340         /*
364          * The resolved arguments were put on     341          * The resolved arguments were put on the previous walk state's operand
365          * stack. Operands on the previous wal !! 342          * stack.  Operands on the previous walk state stack always
366          * start at index 0. Also, null termin !! 343          * start at index 0.
                                                   >> 344          * Null terminate the list of arguments
367          */                                       345          */
368         this_walk_state->operands[this_walk_st !! 346         this_walk_state->operands [this_walk_state->num_operands] = NULL;
369                                                   347 
370         /*                                     !! 348         info.parameters = &this_walk_state->operands[0];
371          * Allocate and initialize the evaluat !! 349         info.parameter_type = ACPI_PARAM_ARGS;
372          * TBD: this is somewhat inefficient,  << 
373          * ds_init_aml_walk. For now, keeps th << 
374          */                                    << 
375         info = ACPI_ALLOCATE_ZEROED(sizeof(str << 
376         if (!info) {                           << 
377                 return_ACPI_STATUS(AE_NO_MEMOR << 
378         }                                      << 
379                                                << 
380         info->parameters = &this_walk_state->o << 
381         info->parameter_type = ACPI_PARAM_ARGS << 
382                                                << 
383         status = acpi_ds_init_aml_walk(next_wa << 
384                                        obj_des << 
385                                        obj_des << 
386                                        ACPI_IM << 
387                                                   350 
388         ACPI_FREE(info);                       !! 351         status = acpi_ds_init_aml_walk (next_walk_state, NULL, method_node,
389         if (ACPI_FAILURE(status)) {            !! 352                           obj_desc->method.aml_start, obj_desc->method.aml_length,
                                                   >> 353                           &info, 3);
                                                   >> 354         if (ACPI_FAILURE (status)) {
390                 goto cleanup;                     355                 goto cleanup;
391         }                                         356         }
392                                                   357 
393         /*                                        358         /*
394          * Delete the operands on the previous    359          * Delete the operands on the previous walkstate operand stack
395          * (they were copied to new objects)      360          * (they were copied to new objects)
396          */                                       361          */
397         for (i = 0; i < obj_desc->method.param    362         for (i = 0; i < obj_desc->method.param_count; i++) {
398                 acpi_ut_remove_reference(this_ !! 363                 acpi_ut_remove_reference (this_walk_state->operands [i]);
399                 this_walk_state->operands[i] = !! 364                 this_walk_state->operands [i] = NULL;
400         }                                         365         }
401                                                   366 
402         /* Clear the operand stack */             367         /* Clear the operand stack */
403                                                   368 
404         this_walk_state->num_operands = 0;        369         this_walk_state->num_operands = 0;
405                                                   370 
406         ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,    !! 371         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
407                           "**** Begin nested e !! 372                 "Starting nested execution, newstate=%p\n", next_walk_state));
408                           method_node->name.as << 
409                                                << 
410         /* Invoke an internal method if necess << 
411                                                   373 
412         if (obj_desc->method.method_flags & AM    374         if (obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY) {
413                 status = obj_desc->method.impl !! 375                 status = obj_desc->method.implementation (next_walk_state);
                                                   >> 376                 return_ACPI_STATUS (status);
414         }                                         377         }
415                                                   378 
416         return_ACPI_STATUS(status);            !! 379         return_ACPI_STATUS (AE_OK);
417                                                   380 
418       cleanup:                                 << 
419                                                   381 
420         /* On error, we must terminate the met !! 382         /* On error, we must delete the new walk state */
421                                                   383 
422         acpi_ds_terminate_control_method(obj_d !! 384 cleanup:
423         if (next_walk_state) {                 !! 385         if (next_walk_state && (next_walk_state->method_desc)) {
424                 acpi_ds_delete_walk_state(next !! 386                 /* Decrement the thread count on the method parse tree */
425         }                                      << 
426                                                   387 
427         return_ACPI_STATUS(status);            !! 388            next_walk_state->method_desc->method.thread_count--;
                                                   >> 389         }
                                                   >> 390         (void) acpi_ds_terminate_control_method (next_walk_state);
                                                   >> 391         acpi_ds_delete_walk_state (next_walk_state);
                                                   >> 392         return_ACPI_STATUS (status);
428 }                                                 393 }
429                                                   394 
                                                   >> 395 
430 /*********************************************    396 /*******************************************************************************
431  *                                                397  *
432  * FUNCTION:    acpi_ds_restart_control_method    398  * FUNCTION:    acpi_ds_restart_control_method
433  *                                                399  *
434  * PARAMETERS:  walk_state          - State fo    400  * PARAMETERS:  walk_state          - State for preempted method (caller)
435  *              return_desc         - Return v    401  *              return_desc         - Return value from the called method
436  *                                                402  *
437  * RETURN:      Status                            403  * RETURN:      Status
438  *                                                404  *
439  * DESCRIPTION: Restart a method that was pree    405  * DESCRIPTION: Restart a method that was preempted by another (nested) method
440  *              invocation.  Handle the return    406  *              invocation.  Handle the return value (if any) from the callee.
441  *                                                407  *
442  *********************************************    408  ******************************************************************************/
443                                                   409 
444 acpi_status                                       410 acpi_status
445 acpi_ds_restart_control_method(struct acpi_wal !! 411 acpi_ds_restart_control_method (
446                                union acpi_oper !! 412         struct acpi_walk_state          *walk_state,
                                                   >> 413         union acpi_operand_object       *return_desc)
447 {                                                 414 {
448         acpi_status status;                    !! 415         acpi_status                     status;
449         int same_as_implicit_return;           << 
450                                                   416 
451         ACPI_FUNCTION_TRACE_PTR(ds_restart_con << 
452                                                   417 
453         ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,    !! 418         ACPI_FUNCTION_TRACE_PTR ("ds_restart_control_method", walk_state);
454                           "****Restart [%4.4s] << 
455                           acpi_ut_get_node_nam << 
456                           walk_state->method_c << 
457                                                << 
458         ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,    << 
459                           "    ReturnFromThisM << 
460                           walk_state->return_u << 
461                           walk_state->results, << 
462                                                   419 
463         /* Did the called method return a valu << 
464                                                   420 
465         if (return_desc) {                     !! 421         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
                                                   >> 422                 "****Restart [%4.4s] Op %p return_value_from_callee %p\n",
                                                   >> 423                 (char *) &walk_state->method_node->name, walk_state->method_call_op,
                                                   >> 424                 return_desc));
466                                                   425 
467                 /* Is the implicit return obje !! 426         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
                                                   >> 427                 "    return_from_this_method_used?=%X res_stack %p Walk %p\n",
                                                   >> 428                 walk_state->return_used,
                                                   >> 429                 walk_state->results, walk_state));
468                                                   430 
469                 same_as_implicit_return =      !! 431         /* Did the called method return a value? */
470                     (walk_state->implicit_retu << 
471                                                   432 
                                                   >> 433         if (return_desc) {
472                 /* Are we actually going to us    434                 /* Are we actually going to use the return value? */
473                                                   435 
474                 if (walk_state->return_used) {    436                 if (walk_state->return_used) {
475                                                << 
476                         /* Save the return val    437                         /* Save the return value from the previous method */
477                                                   438 
478                         status = acpi_ds_resul !! 439                         status = acpi_ds_result_push (return_desc, walk_state);
479                         if (ACPI_FAILURE(statu !! 440                         if (ACPI_FAILURE (status)) {
480                                 acpi_ut_remove !! 441                                 acpi_ut_remove_reference (return_desc);
481                                 return_ACPI_ST !! 442                                 return_ACPI_STATUS (status);
482                         }                         443                         }
483                                                   444 
484                         /*                        445                         /*
485                          * Save as THIS method    446                          * Save as THIS method's return value in case it is returned
486                          * immediately to yet     447                          * immediately to yet another method
487                          */                       448                          */
488                         walk_state->return_des    449                         walk_state->return_desc = return_desc;
489                 }                                 450                 }
490                                                !! 451                 else {
491                 /*                             << 
492                  * The following code is the o << 
493                  * "implicit return". Some AML << 
494                  * method is "implicitly" retu << 
495                  * explicit return value.      << 
496                  *                             << 
497                  * Just save the last result o << 
498                  *                             << 
499                  * NOTE: this is optional beca << 
500                  * support this behavior.      << 
501                  */                            << 
502                 else if (!acpi_ds_do_implicit_ << 
503                          (return_desc, walk_st << 
504                          || same_as_implicit_r << 
505                         /*                        452                         /*
506                          * Delete the return v    453                          * Delete the return value if it will not be used by the
507                          * calling method or r !! 454                          * calling method
508                          * is the same as the  << 
509                          */                       455                          */
510                         acpi_ut_remove_referen !! 456                         acpi_ut_remove_reference (return_desc);
511                 }                                 457                 }
512         }                                         458         }
513                                                   459 
514         return_ACPI_STATUS(AE_OK);             !! 460         return_ACPI_STATUS (AE_OK);
515 }                                                 461 }
516                                                   462 
                                                   >> 463 
517 /*********************************************    464 /*******************************************************************************
518  *                                                465  *
519  * FUNCTION:    acpi_ds_terminate_control_meth    466  * FUNCTION:    acpi_ds_terminate_control_method
520  *                                                467  *
521  * PARAMETERS:  method_desc         - Method o !! 468  * PARAMETERS:  walk_state          - State of the method
522  *              walk_state          - State as << 
523  *                                                469  *
524  * RETURN:      None                           !! 470  * RETURN:      Status
525  *                                                471  *
526  * DESCRIPTION: Terminate a control method.  D    472  * DESCRIPTION: Terminate a control method.  Delete everything that the method
527  *              created, delete all locals and    473  *              created, delete all locals and arguments, and delete the parse
528  *              tree if requested.                474  *              tree if requested.
529  *                                                475  *
530  * MUTEX:       Interpreter is locked          << 
531  *                                             << 
532  *********************************************    476  ******************************************************************************/
533                                                   477 
534 void                                           !! 478 acpi_status
535 acpi_ds_terminate_control_method(union acpi_op !! 479 acpi_ds_terminate_control_method (
536                                  struct acpi_w !! 480         struct acpi_walk_state          *walk_state)
537 {                                                 481 {
538         struct acpi_namespace_node *method_nod !! 482         union acpi_operand_object       *obj_desc;
539         acpi_status status;                    !! 483         struct acpi_namespace_node      *method_node;
                                                   >> 484         acpi_status                     status;
540                                                   485 
541         ACPI_FUNCTION_TRACE_PTR(ds_terminate_c << 
542                                                   486 
543         /* method_desc is required, walk_state !! 487         ACPI_FUNCTION_TRACE_PTR ("ds_terminate_control_method", walk_state);
544                                                   488 
545         if (!method_desc) {                    << 
546                 return_VOID;                   << 
547         }                                      << 
548                                                   489 
549         if (walk_state) {                      !! 490         if (!walk_state) {
                                                   >> 491                 return (AE_BAD_PARAMETER);
                                                   >> 492         }
550                                                   493 
551                 /* Delete all arguments and lo !! 494         /* The current method object was saved in the walk state */
552                                                   495 
553                 acpi_ds_method_data_delete_all !! 496         obj_desc = walk_state->method_desc;
                                                   >> 497         if (!obj_desc) {
                                                   >> 498                 return_ACPI_STATUS (AE_OK);
554         }                                         499         }
555                                                   500 
                                                   >> 501         /* Delete all arguments and locals */
                                                   >> 502 
                                                   >> 503         acpi_ds_method_data_delete_all (walk_state);
                                                   >> 504 
556         /*                                        505         /*
557          * If method is serialized, release th !! 506          * Lock the parser while we terminate this method.
558          * current sync level for this thread  !! 507          * If this is the last thread executing the method,
                                                   >> 508          * we have additional cleanup to perform
559          */                                       509          */
560         if (method_desc->method.mutex) {       !! 510         status = acpi_ut_acquire_mutex (ACPI_MTX_PARSER);
                                                   >> 511         if (ACPI_FAILURE (status)) {
                                                   >> 512                 return_ACPI_STATUS (status);
                                                   >> 513         }
561                                                   514 
562                 /* Acquisition Depth handles r !! 515         /* Signal completion of the execution of this method if necessary */
563                                                   516 
564                 method_desc->method.mutex->mut !! 517         if (walk_state->method_desc->method.semaphore) {
565                 if (!method_desc->method.mutex !! 518                 status = acpi_os_signal_semaphore (
566                         walk_state->thread->cu !! 519                                   walk_state->method_desc->method.semaphore, 1);
567                             method_desc->metho !! 520                 if (ACPI_FAILURE (status)) {
568                             original_sync_leve !! 521                         ACPI_REPORT_ERROR (("Could not signal method semaphore\n"));
                                                   >> 522                         status = AE_OK;
569                                                   523 
570                         acpi_os_release_mutex( !! 524                         /* Ignore error and continue cleanup */
571                                                << 
572                         method_desc->method.mu << 
573                 }                                 525                 }
574         }                                         526         }
575                                                   527 
576         if (walk_state) {                      !! 528         if (walk_state->method_desc->method.thread_count) {
577                 /*                             !! 529                 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
578                  * Delete any objects created  !! 530                         "*** Not deleting method namespace, there are still %d threads\n",
579                  * The method Node is stored i !! 531                         walk_state->method_desc->method.thread_count));
580                  */                            << 
581                 method_node = walk_state->meth << 
582                                                << 
583                 /*                             << 
584                  * Delete any namespace object << 
585                  * the namespace by the execut << 
586                  */                            << 
587                 acpi_ns_delete_namespace_by_ow << 
588         }                                      << 
589                                                << 
590         /* Decrement the thread count on the m << 
591                                                << 
592         if (method_desc->method.thread_count)  << 
593                 method_desc->method.thread_cou << 
594         } else {                               << 
595                 ACPI_ERROR((AE_INFO, "Invalid  << 
596         }                                         532         }
597                                                   533 
598         /* Are there any other threads current !! 534         if (!walk_state->method_desc->method.thread_count) {
599                                                << 
600         if (method_desc->method.thread_count)  << 
601                 /*                             << 
602                  * Additional threads. Do not  << 
603                  * we immediately reuse it for << 
604                  */                            << 
605                 ACPI_DEBUG_PRINT((ACPI_DB_DISP << 
606                                   "*** Complet << 
607                                   method_desc- << 
608         } else {                               << 
609                 /* This is the only executing  << 
610                                                << 
611                 /*                                535                 /*
612                  * Support to dynamically chan    536                  * Support to dynamically change a method from not_serialized to
613                  * Serialized if it appears th !! 537                  * Serialized if it appears that the method is written foolishly and
614                  * does not support multiple t !! 538                  * does not support multiple thread execution.  The best example of this
615                  * is if such a method creates !! 539                  * is if such a method creates namespace objects and blocks.  A second
616                  * thread will fail with an AE    540                  * thread will fail with an AE_ALREADY_EXISTS exception
617                  *                                541                  *
618                  * This code is here because w    542                  * This code is here because we must wait until the last thread exits
619                  * before creating the synchro    543                  * before creating the synchronization semaphore.
620                  */                               544                  */
621                 if ((method_desc->method.metho !! 545                 if ((walk_state->method_desc->method.concurrency == 1) &&
622                     && (!method_desc->method.m !! 546                         (!walk_state->method_desc->method.semaphore)) {
623                         status = acpi_ds_creat !! 547                         status = acpi_os_create_semaphore (1,
                                                   >> 548                                          1,
                                                   >> 549                                          &walk_state->method_desc->method.semaphore);
624                 }                                 550                 }
625                                                   551 
626                 /* No more threads, we can fre !! 552                 /*
                                                   >> 553                  * There are no more threads executing this method.  Perform
                                                   >> 554                  * additional cleanup.
                                                   >> 555                  *
                                                   >> 556                  * The method Node is stored in the walk state
                                                   >> 557                  */
                                                   >> 558                 method_node = walk_state->method_node;
                                                   >> 559 
                                                   >> 560                 /*
                                                   >> 561                  * Delete any namespace entries created immediately underneath
                                                   >> 562                  * the method
                                                   >> 563                  */
                                                   >> 564                 status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
                                                   >> 565                 if (ACPI_FAILURE (status)) {
                                                   >> 566                         return_ACPI_STATUS (status);
                                                   >> 567                 }
                                                   >> 568 
                                                   >> 569                 if (method_node->child) {
                                                   >> 570                         acpi_ns_delete_namespace_subtree (method_node);
                                                   >> 571                 }
627                                                   572 
628                 acpi_ut_release_owner_id(&meth !! 573                 /*
                                                   >> 574                  * Delete any namespace entries created anywhere else within
                                                   >> 575                  * the namespace
                                                   >> 576                  */
                                                   >> 577                 acpi_ns_delete_namespace_by_owner (walk_state->method_desc->method.owning_id);
                                                   >> 578                 status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
                                                   >> 579                 if (ACPI_FAILURE (status)) {
                                                   >> 580                         return_ACPI_STATUS (status);
                                                   >> 581                 }
629         }                                         582         }
630                                                   583 
631         return_VOID;                           !! 584         status = acpi_ut_release_mutex (ACPI_MTX_PARSER);
                                                   >> 585         return_ACPI_STATUS (status);
632 }                                                 586 }
                                                   >> 587 
                                                   >> 588 
633                                                   589 
  This page was automatically generated by the LXR engine.