Print this page
update to acpica-unix2-20140114
acpica-unix2-20130823
PANKOVs restructure
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/intel/io/acpica/executer/exconfig.c
+++ new/usr/src/common/acpica/components/executer/exconfig.c
1 1 /******************************************************************************
2 2 *
3 3 * Module Name: exconfig - Namespace reconfiguration (Load/Unload opcodes)
4 4 *
5 5 *****************************************************************************/
6 6
7 7 /*
8 - * Copyright (C) 2000 - 2011, Intel Corp.
8 + * Copyright (C) 2000 - 2014, Intel Corp.
9 9 * All rights reserved.
10 10 *
11 11 * Redistribution and use in source and binary forms, with or without
12 12 * modification, are permitted provided that the following conditions
13 13 * are met:
14 14 * 1. Redistributions of source code must retain the above copyright
15 15 * notice, this list of conditions, and the following disclaimer,
16 16 * without modification.
17 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 18 * substantially similar to the "NO WARRANTY" disclaimer below
19 19 * ("Disclaimer") and any redistribution must be conditioned upon
20 20 * including a substantially similar Disclaimer requirement for further
21 21 * binary redistribution.
22 22 * 3. Neither the names of the above-listed copyright holders nor the names
23 23 * of any contributors may be used to endorse or promote products derived
24 24 * from this software without specific prior written permission.
25 25 *
26 26 * Alternatively, this software may be distributed under the terms of the
27 27 * GNU General Public License ("GPL") version 2 as published by the Free
28 28 * Software Foundation.
29 29 *
30 30 * NO WARRANTY
31 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 41 * POSSIBILITY OF SUCH DAMAGES.
42 42 */
↓ open down ↓ |
24 lines elided |
↑ open up ↑ |
43 43
44 44 #define __EXCONFIG_C__
45 45
46 46 #include "acpi.h"
47 47 #include "accommon.h"
48 48 #include "acinterp.h"
49 49 #include "acnamesp.h"
50 50 #include "actables.h"
51 51 #include "acdispat.h"
52 52 #include "acevents.h"
53 +#include "amlcode.h"
53 54
54 55
55 56 #define _COMPONENT ACPI_EXECUTER
56 57 ACPI_MODULE_NAME ("exconfig")
57 58
58 59 /* Local prototypes */
59 60
60 61 static ACPI_STATUS
61 62 AcpiExAddTable (
62 63 UINT32 TableIndex,
63 64 ACPI_NAMESPACE_NODE *ParentNode,
64 65 ACPI_OPERAND_OBJECT **DdbHandle);
65 66
66 67 static ACPI_STATUS
67 68 AcpiExRegionRead (
68 69 ACPI_OPERAND_OBJECT *ObjDesc,
69 70 UINT32 Length,
70 71 UINT8 *Buffer);
71 72
72 73
73 74 /*******************************************************************************
74 75 *
75 76 * FUNCTION: AcpiExAddTable
76 77 *
77 78 * PARAMETERS: Table - Pointer to raw table
78 79 * ParentNode - Where to load the table (scope)
79 80 * DdbHandle - Where to return the table handle.
80 81 *
81 82 * RETURN: Status
82 83 *
83 84 * DESCRIPTION: Common function to Install and Load an ACPI table with a
84 85 * returned table handle.
85 86 *
86 87 ******************************************************************************/
87 88
88 89 static ACPI_STATUS
89 90 AcpiExAddTable (
90 91 UINT32 TableIndex,
91 92 ACPI_NAMESPACE_NODE *ParentNode,
92 93 ACPI_OPERAND_OBJECT **DdbHandle)
93 94 {
94 95 ACPI_OPERAND_OBJECT *ObjDesc;
95 96 ACPI_STATUS Status;
96 97 ACPI_OWNER_ID OwnerId;
97 98
98 99
99 100 ACPI_FUNCTION_TRACE (ExAddTable);
100 101
101 102
102 103 /* Create an object to be the table handle */
103 104
104 105 ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_REFERENCE);
105 106 if (!ObjDesc)
106 107 {
107 108 return_ACPI_STATUS (AE_NO_MEMORY);
108 109 }
109 110
110 111 /* Init the table handle */
111 112
112 113 ObjDesc->Common.Flags |= AOPOBJ_DATA_VALID;
113 114 ObjDesc->Reference.Class = ACPI_REFCLASS_TABLE;
114 115 *DdbHandle = ObjDesc;
115 116
116 117 /* Install the new table into the local data structures */
117 118
118 119 ObjDesc->Reference.Value = TableIndex;
119 120
120 121 /* Add the table to the namespace */
121 122
122 123 Status = AcpiNsLoadTable (TableIndex, ParentNode);
123 124 if (ACPI_FAILURE (Status))
124 125 {
125 126 AcpiUtRemoveReference (ObjDesc);
126 127 *DdbHandle = NULL;
127 128 return_ACPI_STATUS (Status);
128 129 }
129 130
130 131 /* Execute any module-level code that was found in the table */
131 132
132 133 AcpiExExitInterpreter ();
133 134 AcpiNsExecModuleCodeList ();
134 135 AcpiExEnterInterpreter ();
135 136
136 137 /*
137 138 * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is
138 139 * responsible for discovering any new wake GPEs by running _PRW methods
139 140 * that may have been loaded by this table.
140 141 */
141 142 Status = AcpiTbGetOwnerId (TableIndex, &OwnerId);
142 143 if (ACPI_SUCCESS (Status))
143 144 {
144 145 AcpiEvUpdateGpes (OwnerId);
145 146 }
146 147
147 148 return_ACPI_STATUS (AE_OK);
148 149 }
149 150
150 151
151 152 /*******************************************************************************
152 153 *
153 154 * FUNCTION: AcpiExLoadTableOp
154 155 *
155 156 * PARAMETERS: WalkState - Current state with operands
156 157 * ReturnDesc - Where to store the return object
157 158 *
158 159 * RETURN: Status
159 160 *
160 161 * DESCRIPTION: Load an ACPI table from the RSDT/XSDT
161 162 *
162 163 ******************************************************************************/
163 164
164 165 ACPI_STATUS
165 166 AcpiExLoadTableOp (
166 167 ACPI_WALK_STATE *WalkState,
167 168 ACPI_OPERAND_OBJECT **ReturnDesc)
168 169 {
169 170 ACPI_STATUS Status;
170 171 ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0];
171 172 ACPI_NAMESPACE_NODE *ParentNode;
↓ open down ↓ |
109 lines elided |
↑ open up ↑ |
172 173 ACPI_NAMESPACE_NODE *StartNode;
173 174 ACPI_NAMESPACE_NODE *ParameterNode = NULL;
174 175 ACPI_OPERAND_OBJECT *DdbHandle;
175 176 ACPI_TABLE_HEADER *Table;
176 177 UINT32 TableIndex;
177 178
178 179
179 180 ACPI_FUNCTION_TRACE (ExLoadTableOp);
180 181
181 182
182 - /* Validate lengths for the SignatureString, OEMIDString, OEMTableID */
183 + /* Validate lengths for the Signature, OemId, and OemTableId strings */
183 184
184 185 if ((Operand[0]->String.Length > ACPI_NAME_SIZE) ||
185 186 (Operand[1]->String.Length > ACPI_OEM_ID_SIZE) ||
186 187 (Operand[2]->String.Length > ACPI_OEM_TABLE_ID_SIZE))
187 188 {
188 - return_ACPI_STATUS (AE_BAD_PARAMETER);
189 + return_ACPI_STATUS (AE_AML_STRING_LIMIT);
189 190 }
190 191
191 192 /* Find the ACPI table in the RSDT/XSDT */
192 193
193 - Status = AcpiTbFindTable (Operand[0]->String.Pointer,
194 - Operand[1]->String.Pointer,
195 - Operand[2]->String.Pointer, &TableIndex);
194 + Status = AcpiTbFindTable (
195 + Operand[0]->String.Pointer,
196 + Operand[1]->String.Pointer,
197 + Operand[2]->String.Pointer, &TableIndex);
196 198 if (ACPI_FAILURE (Status))
197 199 {
198 200 if (Status != AE_NOT_FOUND)
199 201 {
200 202 return_ACPI_STATUS (Status);
201 203 }
202 204
203 205 /* Table not found, return an Integer=0 and AE_OK */
204 206
205 207 DdbHandle = AcpiUtCreateIntegerObject ((UINT64) 0);
206 208 if (!DdbHandle)
207 209 {
208 210 return_ACPI_STATUS (AE_NO_MEMORY);
209 211 }
210 212
211 213 *ReturnDesc = DdbHandle;
212 214 return_ACPI_STATUS (AE_OK);
213 215 }
214 216
↓ open down ↓ |
9 lines elided |
↑ open up ↑ |
215 217 /* Default nodes */
216 218
217 219 StartNode = WalkState->ScopeInfo->Scope.Node;
218 220 ParentNode = AcpiGbl_RootNode;
219 221
220 222 /* RootPath (optional parameter) */
221 223
222 224 if (Operand[3]->String.Length > 0)
223 225 {
224 226 /*
225 - * Find the node referenced by the RootPathString. This is the
227 + * Find the node referenced by the RootPathString. This is the
226 228 * location within the namespace where the table will be loaded.
227 229 */
228 230 Status = AcpiNsGetNode (StartNode, Operand[3]->String.Pointer,
229 231 ACPI_NS_SEARCH_PARENT, &ParentNode);
230 232 if (ACPI_FAILURE (Status))
231 233 {
232 234 return_ACPI_STATUS (Status);
233 235 }
234 236 }
235 237
236 238 /* ParameterPath (optional parameter) */
237 239
238 240 if (Operand[4]->String.Length > 0)
239 241 {
240 - if ((Operand[4]->String.Pointer[0] != '\\') &&
241 - (Operand[4]->String.Pointer[0] != '^'))
242 + if ((Operand[4]->String.Pointer[0] != AML_ROOT_PREFIX) &&
243 + (Operand[4]->String.Pointer[0] != AML_PARENT_PREFIX))
242 244 {
243 245 /*
244 246 * Path is not absolute, so it will be relative to the node
245 247 * referenced by the RootPathString (or the NS root if omitted)
246 248 */
247 249 StartNode = ParentNode;
248 250 }
249 251
250 252 /* Find the node referenced by the ParameterPathString */
251 253
252 254 Status = AcpiNsGetNode (StartNode, Operand[4]->String.Pointer,
253 255 ACPI_NS_SEARCH_PARENT, &ParameterNode);
254 256 if (ACPI_FAILURE (Status))
255 257 {
256 258 return_ACPI_STATUS (Status);
257 259 }
258 260 }
259 261
260 262 /* Load the table into the namespace */
261 263
262 264 Status = AcpiExAddTable (TableIndex, ParentNode, &DdbHandle);
263 265 if (ACPI_FAILURE (Status))
264 266 {
265 267 return_ACPI_STATUS (Status);
266 268 }
267 269
268 270 /* Parameter Data (optional) */
269 271
270 272 if (ParameterNode)
271 273 {
272 274 /* Store the parameter data into the optional parameter object */
273 275
274 276 Status = AcpiExStore (Operand[5],
275 277 ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, ParameterNode),
276 278 WalkState);
277 279 if (ACPI_FAILURE (Status))
278 280 {
279 281 (void) AcpiExUnloadTable (DdbHandle);
280 282
281 283 AcpiUtRemoveReference (DdbHandle);
282 284 return_ACPI_STATUS (Status);
283 285 }
284 286 }
285 287
286 288 Status = AcpiGetTableByIndex (TableIndex, &Table);
287 289 if (ACPI_SUCCESS (Status))
288 290 {
289 291 ACPI_INFO ((AE_INFO, "Dynamic OEM Table Load:"));
290 292 AcpiTbPrintTableHeader (0, Table);
291 293 }
↓ open down ↓ |
40 lines elided |
↑ open up ↑ |
292 294
293 295 /* Invoke table handler if present */
294 296
295 297 if (AcpiGbl_TableHandler)
296 298 {
297 299 (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_LOAD, Table,
298 300 AcpiGbl_TableHandlerContext);
299 301 }
300 302
301 303 *ReturnDesc = DdbHandle;
302 - return_ACPI_STATUS (Status);
304 + return_ACPI_STATUS (Status);
303 305 }
304 306
305 307
306 308 /*******************************************************************************
307 309 *
308 310 * FUNCTION: AcpiExRegionRead
309 311 *
310 312 * PARAMETERS: ObjDesc - Region descriptor
311 313 * Length - Number of bytes to read
312 314 * Buffer - Pointer to where to put the data
313 315 *
314 316 * RETURN: Status
315 317 *
316 318 * DESCRIPTION: Read data from an operation region. The read starts from the
317 319 * beginning of the region.
318 320 *
319 321 ******************************************************************************/
320 322
321 323 static ACPI_STATUS
322 324 AcpiExRegionRead (
323 325 ACPI_OPERAND_OBJECT *ObjDesc,
324 326 UINT32 Length,
325 327 UINT8 *Buffer)
326 328 {
↓ open down ↓ |
14 lines elided |
↑ open up ↑ |
327 329 ACPI_STATUS Status;
328 330 UINT64 Value;
329 331 UINT32 RegionOffset = 0;
330 332 UINT32 i;
331 333
332 334
333 335 /* Bytewise reads */
334 336
335 337 for (i = 0; i < Length; i++)
336 338 {
337 - Status = AcpiEvAddressSpaceDispatch (ObjDesc, ACPI_READ,
339 + Status = AcpiEvAddressSpaceDispatch (ObjDesc, NULL, ACPI_READ,
338 340 RegionOffset, 8, &Value);
339 341 if (ACPI_FAILURE (Status))
340 342 {
341 343 return (Status);
342 344 }
343 345
344 346 *Buffer = (UINT8) Value;
345 347 Buffer++;
346 348 RegionOffset++;
347 349 }
348 350
349 351 return (AE_OK);
350 352 }
351 353
352 354
353 355 /*******************************************************************************
354 356 *
355 357 * FUNCTION: AcpiExLoadOp
356 358 *
357 359 * PARAMETERS: ObjDesc - Region or Buffer/Field where the table will be
358 360 * obtained
359 361 * Target - Where a handle to the table will be stored
360 362 * WalkState - Current state
361 363 *
362 364 * RETURN: Status
363 365 *
364 366 * DESCRIPTION: Load an ACPI table from a field or operation region
365 367 *
366 368 * NOTE: Region Fields (Field, BankField, IndexFields) are resolved to buffer
367 369 * objects before this code is reached.
368 370 *
369 371 * If source is an operation region, it must refer to SystemMemory, as
370 372 * per the ACPI specification.
371 373 *
372 374 ******************************************************************************/
373 375
374 376 ACPI_STATUS
375 377 AcpiExLoadOp (
376 378 ACPI_OPERAND_OBJECT *ObjDesc,
377 379 ACPI_OPERAND_OBJECT *Target,
378 380 ACPI_WALK_STATE *WalkState)
379 381 {
380 382 ACPI_OPERAND_OBJECT *DdbHandle;
381 383 ACPI_TABLE_HEADER *Table;
382 384 ACPI_TABLE_DESC TableDesc;
383 385 UINT32 TableIndex;
384 386 ACPI_STATUS Status;
385 387 UINT32 Length;
386 388
387 389
388 390 ACPI_FUNCTION_TRACE (ExLoadOp);
389 391
390 392
391 393 ACPI_MEMSET (&TableDesc, 0, sizeof (ACPI_TABLE_DESC));
392 394
393 395 /* Source Object can be either an OpRegion or a Buffer/Field */
394 396
395 397 switch (ObjDesc->Common.Type)
396 398 {
397 399 case ACPI_TYPE_REGION:
398 400
399 401 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
400 402 "Load table from Region %p\n", ObjDesc));
401 403
402 404 /* Region must be SystemMemory (from ACPI spec) */
403 405
404 406 if (ObjDesc->Region.SpaceId != ACPI_ADR_SPACE_SYSTEM_MEMORY)
405 407 {
406 408 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
407 409 }
408 410
409 411 /*
410 412 * If the Region Address and Length have not been previously evaluated,
411 413 * evaluate them now and save the results.
412 414 */
413 415 if (!(ObjDesc->Common.Flags & AOPOBJ_DATA_VALID))
414 416 {
415 417 Status = AcpiDsGetRegionArguments (ObjDesc);
416 418 if (ACPI_FAILURE (Status))
417 419 {
418 420 return_ACPI_STATUS (Status);
419 421 }
420 422 }
421 423
422 424 /* Get the table header first so we can get the table length */
423 425
424 426 Table = ACPI_ALLOCATE (sizeof (ACPI_TABLE_HEADER));
425 427 if (!Table)
426 428 {
427 429 return_ACPI_STATUS (AE_NO_MEMORY);
428 430 }
429 431
430 432 Status = AcpiExRegionRead (ObjDesc, sizeof (ACPI_TABLE_HEADER),
431 433 ACPI_CAST_PTR (UINT8, Table));
432 434 Length = Table->Length;
433 435 ACPI_FREE (Table);
434 436
435 437 if (ACPI_FAILURE (Status))
436 438 {
437 439 return_ACPI_STATUS (Status);
438 440 }
439 441
440 442 /* Must have at least an ACPI table header */
441 443
442 444 if (Length < sizeof (ACPI_TABLE_HEADER))
443 445 {
444 446 return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
445 447 }
446 448
447 449 /*
448 450 * The original implementation simply mapped the table, with no copy.
449 451 * However, the memory region is not guaranteed to remain stable and
450 452 * we must copy the table to a local buffer. For example, the memory
451 453 * region is corrupted after suspend on some machines. Dynamically
452 454 * loaded tables are usually small, so this overhead is minimal.
453 455 *
454 456 * The latest implementation (5/2009) does not use a mapping at all.
455 457 * We use the low-level operation region interface to read the table
456 458 * instead of the obvious optimization of using a direct mapping.
457 459 * This maintains a consistent use of operation regions across the
458 460 * entire subsystem. This is important if additional processing must
459 461 * be performed in the (possibly user-installed) operation region
460 462 * handler. For example, AcpiExec and ASLTS depend on this.
461 463 */
462 464
463 465 /* Allocate a buffer for the table */
464 466
465 467 TableDesc.Pointer = ACPI_ALLOCATE (Length);
466 468 if (!TableDesc.Pointer)
467 469 {
468 470 return_ACPI_STATUS (AE_NO_MEMORY);
469 471 }
470 472
471 473 /* Read the entire table */
472 474
473 475 Status = AcpiExRegionRead (ObjDesc, Length,
↓ open down ↓ |
126 lines elided |
↑ open up ↑ |
474 476 ACPI_CAST_PTR (UINT8, TableDesc.Pointer));
475 477 if (ACPI_FAILURE (Status))
476 478 {
477 479 ACPI_FREE (TableDesc.Pointer);
478 480 return_ACPI_STATUS (Status);
479 481 }
480 482
481 483 TableDesc.Address = ObjDesc->Region.Address;
482 484 break;
483 485
484 -
485 486 case ACPI_TYPE_BUFFER: /* Buffer or resolved RegionField */
486 487
487 488 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
488 489 "Load table from Buffer or Field %p\n", ObjDesc));
489 490
490 491 /* Must have at least an ACPI table header */
491 492
492 493 if (ObjDesc->Buffer.Length < sizeof (ACPI_TABLE_HEADER))
493 494 {
494 495 return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
495 496 }
496 497
497 498 /* Get the actual table length from the table header */
498 499
499 500 Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ObjDesc->Buffer.Pointer);
500 501 Length = Table->Length;
501 502
502 503 /* Table cannot extend beyond the buffer */
503 504
504 505 if (Length > ObjDesc->Buffer.Length)
505 506 {
506 507 return_ACPI_STATUS (AE_AML_BUFFER_LIMIT);
507 508 }
508 509 if (Length < sizeof (ACPI_TABLE_HEADER))
509 510 {
510 511 return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
511 512 }
512 513
513 514 /*
514 515 * Copy the table from the buffer because the buffer could be modified
515 516 * or even deleted in the future
516 517 */
↓ open down ↓ |
22 lines elided |
↑ open up ↑ |
517 518 TableDesc.Pointer = ACPI_ALLOCATE (Length);
518 519 if (!TableDesc.Pointer)
519 520 {
520 521 return_ACPI_STATUS (AE_NO_MEMORY);
521 522 }
522 523
523 524 ACPI_MEMCPY (TableDesc.Pointer, Table, Length);
524 525 TableDesc.Address = ACPI_TO_INTEGER (TableDesc.Pointer);
525 526 break;
526 527
527 -
528 528 default:
529 +
529 530 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
530 531 }
531 532
532 533 /* Validate table checksum (will not get validated in TbAddTable) */
533 534
534 535 Status = AcpiTbVerifyChecksum (TableDesc.Pointer, Length);
535 536 if (ACPI_FAILURE (Status))
536 537 {
537 538 ACPI_FREE (TableDesc.Pointer);
538 539 return_ACPI_STATUS (Status);
539 540 }
540 541
541 542 /* Complete the table descriptor */
542 543
543 544 TableDesc.Length = Length;
544 545 TableDesc.Flags = ACPI_TABLE_ORIGIN_ALLOCATED;
545 546
546 547 /* Install the new table into the local data structures */
547 548
548 549 Status = AcpiTbAddTable (&TableDesc, &TableIndex);
549 550 if (ACPI_FAILURE (Status))
550 551 {
551 552 /* Delete allocated table buffer */
552 553
553 554 AcpiTbDeleteTable (&TableDesc);
554 555 return_ACPI_STATUS (Status);
555 556 }
556 557
557 558 /*
558 559 * Add the table to the namespace.
559 560 *
560 561 * Note: Load the table objects relative to the root of the namespace.
561 562 * This appears to go against the ACPI specification, but we do it for
562 563 * compatibility with other ACPI implementations.
563 564 */
564 565 Status = AcpiExAddTable (TableIndex, AcpiGbl_RootNode, &DdbHandle);
565 566 if (ACPI_FAILURE (Status))
566 567 {
567 568 /* On error, TablePtr was deallocated above */
568 569
569 570 return_ACPI_STATUS (Status);
570 571 }
571 572
572 573 /* Store the DdbHandle into the Target operand */
573 574
574 575 Status = AcpiExStore (DdbHandle, Target, WalkState);
575 576 if (ACPI_FAILURE (Status))
576 577 {
577 578 (void) AcpiExUnloadTable (DdbHandle);
578 579
579 580 /* TablePtr was deallocated above */
580 581
581 582 AcpiUtRemoveReference (DdbHandle);
582 583 return_ACPI_STATUS (Status);
583 584 }
584 585
585 586 ACPI_INFO ((AE_INFO, "Dynamic OEM Table Load:"));
586 587 AcpiTbPrintTableHeader (0, TableDesc.Pointer);
587 588
588 589 /* Remove the reference by added by AcpiExStore above */
589 590
590 591 AcpiUtRemoveReference (DdbHandle);
591 592
592 593 /* Invoke table handler if present */
593 594
594 595 if (AcpiGbl_TableHandler)
595 596 {
596 597 (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_LOAD, TableDesc.Pointer,
597 598 AcpiGbl_TableHandlerContext);
598 599 }
599 600
600 601 return_ACPI_STATUS (Status);
601 602 }
602 603
603 604
604 605 /*******************************************************************************
605 606 *
606 607 * FUNCTION: AcpiExUnloadTable
607 608 *
608 609 * PARAMETERS: DdbHandle - Handle to a previously loaded table
609 610 *
610 611 * RETURN: Status
611 612 *
612 613 * DESCRIPTION: Unload an ACPI table
613 614 *
614 615 ******************************************************************************/
615 616
616 617 ACPI_STATUS
617 618 AcpiExUnloadTable (
618 619 ACPI_OPERAND_OBJECT *DdbHandle)
619 620 {
620 621 ACPI_STATUS Status = AE_OK;
621 622 ACPI_OPERAND_OBJECT *TableDesc = DdbHandle;
622 623 UINT32 TableIndex;
623 624 ACPI_TABLE_HEADER *Table;
624 625
625 626
626 627 ACPI_FUNCTION_TRACE (ExUnloadTable);
627 628
628 629
629 630 /*
630 631 * Validate the handle
631 632 * Although the handle is partially validated in AcpiExReconfiguration()
632 633 * when it calls AcpiExResolveOperands(), the handle is more completely
633 634 * validated here.
↓ open down ↓ |
95 lines elided |
↑ open up ↑ |
634 635 *
635 636 * Handle must be a valid operand object of type reference. Also, the
636 637 * DdbHandle must still be marked valid (table has not been previously
637 638 * unloaded)
638 639 */
639 640 if ((!DdbHandle) ||
640 641 (ACPI_GET_DESCRIPTOR_TYPE (DdbHandle) != ACPI_DESC_TYPE_OPERAND) ||
641 642 (DdbHandle->Common.Type != ACPI_TYPE_LOCAL_REFERENCE) ||
642 643 (!(DdbHandle->Common.Flags & AOPOBJ_DATA_VALID)))
643 644 {
644 - return_ACPI_STATUS (AE_BAD_PARAMETER);
645 + return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
645 646 }
646 647
647 648 /* Get the table index from the DdbHandle */
648 649
649 650 TableIndex = TableDesc->Reference.Value;
650 651
651 652 /* Ensure the table is still loaded */
652 653
653 654 if (!AcpiTbIsTableLoaded (TableIndex))
654 655 {
655 656 return_ACPI_STATUS (AE_NOT_EXIST);
656 657 }
657 658
658 659 /* Invoke table handler if present */
659 660
660 661 if (AcpiGbl_TableHandler)
661 662 {
662 663 Status = AcpiGetTableByIndex (TableIndex, &Table);
663 664 if (ACPI_SUCCESS (Status))
664 665 {
665 666 (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_UNLOAD, Table,
666 667 AcpiGbl_TableHandlerContext);
667 668 }
668 669 }
669 670
670 671 /* Delete the portion of the namespace owned by this table */
671 672
672 673 Status = AcpiTbDeleteNamespaceByOwner (TableIndex);
673 674 if (ACPI_FAILURE (Status))
674 675 {
675 676 return_ACPI_STATUS (Status);
676 677 }
677 678
↓ open down ↓ |
23 lines elided |
↑ open up ↑ |
678 679 (void) AcpiTbReleaseOwnerId (TableIndex);
679 680 AcpiTbSetTableLoadedFlag (TableIndex, FALSE);
680 681
681 682 /*
682 683 * Invalidate the handle. We do this because the handle may be stored
683 684 * in a named object and may not be actually deleted until much later.
684 685 */
685 686 DdbHandle->Common.Flags &= ~AOPOBJ_DATA_VALID;
686 687 return_ACPI_STATUS (AE_OK);
687 688 }
688 -
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX