Print this page
update to acpica-unix2-20130927
acpica-unix2-20130823
PANKOVs restructure
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/intel/io/acpica/hardware/hwxface.c
+++ new/usr/src/common/acpica/components/hardware/hwxface.c
1 -
2 1 /******************************************************************************
3 2 *
4 3 * Module Name: hwxface - Public ACPICA hardware interfaces
5 4 *
6 5 *****************************************************************************/
7 6
8 7 /*
9 - * Copyright (C) 2000 - 2011, Intel Corp.
8 + * Copyright (C) 2000 - 2013, Intel Corp.
10 9 * All rights reserved.
11 10 *
12 11 * Redistribution and use in source and binary forms, with or without
13 12 * modification, are permitted provided that the following conditions
14 13 * are met:
15 14 * 1. Redistributions of source code must retain the above copyright
16 15 * notice, this list of conditions, and the following disclaimer,
17 16 * without modification.
18 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 18 * substantially similar to the "NO WARRANTY" disclaimer below
20 19 * ("Disclaimer") and any redistribution must be conditioned upon
21 20 * including a substantially similar Disclaimer requirement for further
22 21 * binary redistribution.
23 22 * 3. Neither the names of the above-listed copyright holders nor the names
24 23 * of any contributors may be used to endorse or promote products derived
25 24 * from this software without specific prior written permission.
26 25 *
27 26 * Alternatively, this software may be distributed under the terms of the
28 27 * GNU General Public License ("GPL") version 2 as published by the Free
29 28 * Software Foundation.
30 29 *
31 30 * NO WARRANTY
32 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
↓ open down ↓ |
15 lines elided |
↑ open up ↑ |
35 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 41 * POSSIBILITY OF SUCH DAMAGES.
43 42 */
44 43
44 +#define EXPORT_ACPI_INTERFACES
45 +
45 46 #include "acpi.h"
46 47 #include "accommon.h"
47 48 #include "acnamesp.h"
48 49
49 50 #define _COMPONENT ACPI_HARDWARE
50 51 ACPI_MODULE_NAME ("hwxface")
51 52
52 53
53 54 /******************************************************************************
54 55 *
55 56 * FUNCTION: AcpiReset
56 57 *
57 58 * PARAMETERS: None
58 59 *
59 60 * RETURN: Status
60 61 *
61 62 * DESCRIPTION: Set reset register in memory or IO space. Note: Does not
62 63 * support reset register in PCI config space, this must be
63 64 * handled separately.
64 65 *
65 66 ******************************************************************************/
66 67
67 68 ACPI_STATUS
68 69 AcpiReset (
69 70 void)
70 71 {
71 72 ACPI_GENERIC_ADDRESS *ResetReg;
72 73 ACPI_STATUS Status;
73 74
74 75
75 76 ACPI_FUNCTION_TRACE (AcpiReset);
76 77
77 78
78 79 ResetReg = &AcpiGbl_FADT.ResetRegister;
79 80
80 81 /* Check if the reset register is supported */
81 82
82 83 if (!(AcpiGbl_FADT.Flags & ACPI_FADT_RESET_REGISTER) ||
83 84 !ResetReg->Address)
↓ open down ↓ |
29 lines elided |
↑ open up ↑ |
84 85 {
85 86 return_ACPI_STATUS (AE_NOT_EXIST);
86 87 }
87 88
88 89 if (ResetReg->SpaceId == ACPI_ADR_SPACE_SYSTEM_IO)
89 90 {
90 91 /*
91 92 * For I/O space, write directly to the OSL. This bypasses the port
92 93 * validation mechanism, which may block a valid write to the reset
93 94 * register.
95 + *
96 + * NOTE:
97 + * The ACPI spec requires the reset register width to be 8, so we
98 + * hardcode it here and ignore the FADT value. This maintains
99 + * compatibility with other ACPI implementations that have allowed
100 + * BIOS code with bad register width values to go unnoticed.
94 101 */
95 102 Status = AcpiOsWritePort ((ACPI_IO_ADDRESS) ResetReg->Address,
96 - AcpiGbl_FADT.ResetValue, ResetReg->BitWidth);
103 + AcpiGbl_FADT.ResetValue, ACPI_RESET_REGISTER_WIDTH);
97 104 }
98 105 else
99 106 {
100 107 /* Write the reset value to the reset register */
101 108
102 109 Status = AcpiHwWrite (AcpiGbl_FADT.ResetValue, ResetReg);
103 110 }
104 111
105 112 return_ACPI_STATUS (Status);
106 113 }
107 114
108 115 ACPI_EXPORT_SYMBOL (AcpiReset)
109 116
110 117
111 118 /******************************************************************************
112 119 *
113 120 * FUNCTION: AcpiRead
114 121 *
115 122 * PARAMETERS: Value - Where the value is returned
116 123 * Reg - GAS register structure
117 124 *
118 125 * RETURN: Status
119 126 *
120 127 * DESCRIPTION: Read from either memory or IO space.
121 128 *
122 129 * LIMITATIONS: <These limitations also apply to AcpiWrite>
123 130 * BitWidth must be exactly 8, 16, 32, or 64.
124 131 * SpaceID must be SystemMemory or SystemIO.
↓ open down ↓ |
18 lines elided |
↑ open up ↑ |
125 132 * BitOffset and AccessWidth are currently ignored, as there has
126 133 * not been a need to implement these.
127 134 *
128 135 ******************************************************************************/
129 136
130 137 ACPI_STATUS
131 138 AcpiRead (
132 139 UINT64 *ReturnValue,
133 140 ACPI_GENERIC_ADDRESS *Reg)
134 141 {
135 - UINT32 Value;
142 + UINT32 ValueLo;
143 + UINT32 ValueHi;
136 144 UINT32 Width;
137 145 UINT64 Address;
138 146 ACPI_STATUS Status;
139 147
140 148
141 149 ACPI_FUNCTION_NAME (AcpiRead);
142 150
143 151
144 152 if (!ReturnValue)
145 153 {
146 154 return (AE_BAD_PARAMETER);
↓ open down ↓ |
1 lines elided |
↑ open up ↑ |
147 155 }
148 156
149 157 /* Validate contents of the GAS register. Allow 64-bit transfers */
150 158
151 159 Status = AcpiHwValidateRegister (Reg, 64, &Address);
152 160 if (ACPI_FAILURE (Status))
153 161 {
154 162 return (Status);
155 163 }
156 164
157 - Width = Reg->BitWidth;
158 - if (Width == 64)
159 - {
160 - Width = 32; /* Break into two 32-bit transfers */
161 - }
162 -
163 - /* Initialize entire 64-bit return value to zero */
164 -
165 - *ReturnValue = 0;
166 - Value = 0;
167 -
168 165 /*
169 - * Two address spaces supported: Memory or IO. PCI_Config is
166 + * Two address spaces supported: Memory or I/O. PCI_Config is
170 167 * not supported here because the GAS structure is insufficient
171 168 */
172 169 if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY)
173 170 {
174 171 Status = AcpiOsReadMemory ((ACPI_PHYSICAL_ADDRESS)
175 - Address, &Value, Width);
172 + Address, ReturnValue, Reg->BitWidth);
176 173 if (ACPI_FAILURE (Status))
177 174 {
178 175 return (Status);
179 176 }
180 - *ReturnValue = Value;
181 -
182 - if (Reg->BitWidth == 64)
183 - {
184 - /* Read the top 32 bits */
185 -
186 - Status = AcpiOsReadMemory ((ACPI_PHYSICAL_ADDRESS)
187 - (Address + 4), &Value, 32);
188 - if (ACPI_FAILURE (Status))
189 - {
190 - return (Status);
191 - }
192 - *ReturnValue |= ((UINT64) Value << 32);
193 - }
194 177 }
195 178 else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
196 179 {
180 + ValueLo = 0;
181 + ValueHi = 0;
182 +
183 + Width = Reg->BitWidth;
184 + if (Width == 64)
185 + {
186 + Width = 32; /* Break into two 32-bit transfers */
187 + }
188 +
197 189 Status = AcpiHwReadPort ((ACPI_IO_ADDRESS)
198 - Address, &Value, Width);
190 + Address, &ValueLo, Width);
199 191 if (ACPI_FAILURE (Status))
200 192 {
201 193 return (Status);
202 194 }
203 - *ReturnValue = Value;
204 195
205 196 if (Reg->BitWidth == 64)
206 197 {
207 198 /* Read the top 32 bits */
208 199
209 200 Status = AcpiHwReadPort ((ACPI_IO_ADDRESS)
210 - (Address + 4), &Value, 32);
201 + (Address + 4), &ValueHi, 32);
211 202 if (ACPI_FAILURE (Status))
212 203 {
213 204 return (Status);
214 205 }
215 - *ReturnValue |= ((UINT64) Value << 32);
216 206 }
207 +
208 + /* Set the return value only if status is AE_OK */
209 +
210 + *ReturnValue = (ValueLo | ((UINT64) ValueHi << 32));
217 211 }
218 212
219 213 ACPI_DEBUG_PRINT ((ACPI_DB_IO,
220 214 "Read: %8.8X%8.8X width %2d from %8.8X%8.8X (%s)\n",
221 215 ACPI_FORMAT_UINT64 (*ReturnValue), Reg->BitWidth,
222 216 ACPI_FORMAT_UINT64 (Address),
223 217 AcpiUtGetRegionName (Reg->SpaceId)));
224 218
225 - return (Status);
219 + return (AE_OK);
226 220 }
227 221
228 222 ACPI_EXPORT_SYMBOL (AcpiRead)
229 223
230 224
231 225 /******************************************************************************
232 226 *
233 227 * FUNCTION: AcpiWrite
234 228 *
235 229 * PARAMETERS: Value - Value to be written
236 230 * Reg - GAS register structure
237 231 *
238 232 * RETURN: Status
239 233 *
240 234 * DESCRIPTION: Write to either memory or IO space.
241 235 *
242 236 ******************************************************************************/
243 237
244 238 ACPI_STATUS
245 239 AcpiWrite (
246 240 UINT64 Value,
247 241 ACPI_GENERIC_ADDRESS *Reg)
248 242 {
249 243 UINT32 Width;
250 244 UINT64 Address;
251 245 ACPI_STATUS Status;
252 246
253 247
254 248 ACPI_FUNCTION_NAME (AcpiWrite);
↓ open down ↓ |
19 lines elided |
↑ open up ↑ |
255 249
256 250
257 251 /* Validate contents of the GAS register. Allow 64-bit transfers */
258 252
259 253 Status = AcpiHwValidateRegister (Reg, 64, &Address);
260 254 if (ACPI_FAILURE (Status))
261 255 {
262 256 return (Status);
263 257 }
264 258
265 - Width = Reg->BitWidth;
266 - if (Width == 64)
267 - {
268 - Width = 32; /* Break into two 32-bit transfers */
269 - }
270 -
271 259 /*
272 260 * Two address spaces supported: Memory or IO. PCI_Config is
273 261 * not supported here because the GAS structure is insufficient
274 262 */
275 263 if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY)
276 264 {
277 265 Status = AcpiOsWriteMemory ((ACPI_PHYSICAL_ADDRESS)
278 - Address, ACPI_LODWORD (Value), Width);
266 + Address, Value, Reg->BitWidth);
279 267 if (ACPI_FAILURE (Status))
280 268 {
281 269 return (Status);
282 270 }
283 -
284 - if (Reg->BitWidth == 64)
285 - {
286 - Status = AcpiOsWriteMemory ((ACPI_PHYSICAL_ADDRESS)
287 - (Address + 4), ACPI_HIDWORD (Value), 32);
288 - if (ACPI_FAILURE (Status))
289 - {
290 - return (Status);
291 - }
292 - }
293 271 }
294 272 else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
295 273 {
274 + Width = Reg->BitWidth;
275 + if (Width == 64)
276 + {
277 + Width = 32; /* Break into two 32-bit transfers */
278 + }
279 +
296 280 Status = AcpiHwWritePort ((ACPI_IO_ADDRESS)
297 281 Address, ACPI_LODWORD (Value), Width);
298 282 if (ACPI_FAILURE (Status))
299 283 {
300 284 return (Status);
301 285 }
302 286
303 287 if (Reg->BitWidth == 64)
304 288 {
305 289 Status = AcpiHwWritePort ((ACPI_IO_ADDRESS)
306 290 (Address + 4), ACPI_HIDWORD (Value), 32);
307 291 if (ACPI_FAILURE (Status))
308 292 {
309 293 return (Status);
310 294 }
311 295 }
312 296 }
313 297
314 298 ACPI_DEBUG_PRINT ((ACPI_DB_IO,
315 299 "Wrote: %8.8X%8.8X width %2d to %8.8X%8.8X (%s)\n",
↓ open down ↓ |
10 lines elided |
↑ open up ↑ |
316 300 ACPI_FORMAT_UINT64 (Value), Reg->BitWidth,
317 301 ACPI_FORMAT_UINT64 (Address),
318 302 AcpiUtGetRegionName (Reg->SpaceId)));
319 303
320 304 return (Status);
321 305 }
322 306
323 307 ACPI_EXPORT_SYMBOL (AcpiWrite)
324 308
325 309
310 +#if (!ACPI_REDUCED_HARDWARE)
326 311 /*******************************************************************************
327 312 *
328 313 * FUNCTION: AcpiReadBitRegister
329 314 *
330 315 * PARAMETERS: RegisterId - ID of ACPI Bit Register to access
331 316 * ReturnValue - Value that was read from the register,
332 317 * normalized to bit position zero.
333 318 *
334 319 * RETURN: Status and the value read from the specified Register. Value
335 320 * returned is normalized to bit0 (is shifted all the way right)
336 321 *
337 322 * DESCRIPTION: ACPI BitRegister read function. Does not acquire the HW lock.
338 323 *
339 324 * SUPPORTS: Bit fields in PM1 Status, PM1 Enable, PM1 Control, and
340 325 * PM2 Control.
341 326 *
342 327 * Note: The hardware lock is not required when reading the ACPI bit registers
343 328 * since almost all of them are single bit and it does not matter that
344 329 * the parent hardware register can be split across two physical
345 330 * registers. The only multi-bit field is SLP_TYP in the PM1 control
346 331 * register, but this field does not cross an 8-bit boundary (nor does
347 332 * it make much sense to actually read this field.)
348 333 *
349 334 ******************************************************************************/
350 335
351 336 ACPI_STATUS
352 337 AcpiReadBitRegister (
353 338 UINT32 RegisterId,
354 339 UINT32 *ReturnValue)
355 340 {
356 341 ACPI_BIT_REGISTER_INFO *BitRegInfo;
357 342 UINT32 RegisterValue;
358 343 UINT32 Value;
359 344 ACPI_STATUS Status;
360 345
361 346
362 347 ACPI_FUNCTION_TRACE_U32 (AcpiReadBitRegister, RegisterId);
363 348
364 349
365 350 /* Get the info structure corresponding to the requested ACPI Register */
366 351
367 352 BitRegInfo = AcpiHwGetBitRegisterInfo (RegisterId);
368 353 if (!BitRegInfo)
369 354 {
370 355 return_ACPI_STATUS (AE_BAD_PARAMETER);
371 356 }
372 357
373 358 /* Read the entire parent register */
374 359
375 360 Status = AcpiHwRegisterRead (BitRegInfo->ParentRegister,
376 361 &RegisterValue);
377 362 if (ACPI_FAILURE (Status))
378 363 {
379 364 return_ACPI_STATUS (Status);
380 365 }
381 366
382 367 /* Normalize the value that was read, mask off other bits */
383 368
384 369 Value = ((RegisterValue & BitRegInfo->AccessBitMask)
385 370 >> BitRegInfo->BitPosition);
386 371
387 372 ACPI_DEBUG_PRINT ((ACPI_DB_IO,
388 373 "BitReg %X, ParentReg %X, Actual %8.8X, ReturnValue %8.8X\n",
389 374 RegisterId, BitRegInfo->ParentRegister, RegisterValue, Value));
390 375
391 376 *ReturnValue = Value;
392 377 return_ACPI_STATUS (AE_OK);
393 378 }
↓ open down ↓ |
58 lines elided |
↑ open up ↑ |
394 379
395 380 ACPI_EXPORT_SYMBOL (AcpiReadBitRegister)
396 381
397 382
398 383 /*******************************************************************************
399 384 *
400 385 * FUNCTION: AcpiWriteBitRegister
401 386 *
402 387 * PARAMETERS: RegisterId - ID of ACPI Bit Register to access
403 388 * Value - Value to write to the register, in bit
404 - * position zero. The bit is automaticallly
389 + * position zero. The bit is automatically
405 390 * shifted to the correct position.
406 391 *
407 392 * RETURN: Status
408 393 *
409 394 * DESCRIPTION: ACPI Bit Register write function. Acquires the hardware lock
410 395 * since most operations require a read/modify/write sequence.
411 396 *
412 397 * SUPPORTS: Bit fields in PM1 Status, PM1 Enable, PM1 Control, and
413 398 * PM2 Control.
414 399 *
415 400 * Note that at this level, the fact that there may be actually two
416 401 * hardware registers (A and B - and B may not exist) is abstracted.
417 402 *
418 403 ******************************************************************************/
419 404
420 405 ACPI_STATUS
421 406 AcpiWriteBitRegister (
422 407 UINT32 RegisterId,
423 408 UINT32 Value)
424 409 {
425 410 ACPI_BIT_REGISTER_INFO *BitRegInfo;
426 411 ACPI_CPU_FLAGS LockFlags;
427 412 UINT32 RegisterValue;
428 413 ACPI_STATUS Status = AE_OK;
429 414
430 415
431 416 ACPI_FUNCTION_TRACE_U32 (AcpiWriteBitRegister, RegisterId);
432 417
433 418
434 419 /* Get the info structure corresponding to the requested ACPI Register */
435 420
436 421 BitRegInfo = AcpiHwGetBitRegisterInfo (RegisterId);
437 422 if (!BitRegInfo)
438 423 {
439 424 return_ACPI_STATUS (AE_BAD_PARAMETER);
440 425 }
441 426
442 427 LockFlags = AcpiOsAcquireLock (AcpiGbl_HardwareLock);
443 428
444 429 /*
445 430 * At this point, we know that the parent register is one of the
446 431 * following: PM1 Status, PM1 Enable, PM1 Control, or PM2 Control
447 432 */
448 433 if (BitRegInfo->ParentRegister != ACPI_REGISTER_PM1_STATUS)
449 434 {
450 435 /*
451 436 * 1) Case for PM1 Enable, PM1 Control, and PM2 Control
452 437 *
453 438 * Perform a register read to preserve the bits that we are not
454 439 * interested in
455 440 */
456 441 Status = AcpiHwRegisterRead (BitRegInfo->ParentRegister,
457 442 &RegisterValue);
458 443 if (ACPI_FAILURE (Status))
459 444 {
460 445 goto UnlockAndExit;
461 446 }
462 447
463 448 /*
464 449 * Insert the input bit into the value that was just read
465 450 * and write the register
466 451 */
467 452 ACPI_REGISTER_INSERT_VALUE (RegisterValue, BitRegInfo->BitPosition,
468 453 BitRegInfo->AccessBitMask, Value);
469 454
470 455 Status = AcpiHwRegisterWrite (BitRegInfo->ParentRegister,
471 456 RegisterValue);
472 457 }
473 458 else
474 459 {
475 460 /*
476 461 * 2) Case for PM1 Status
477 462 *
478 463 * The Status register is different from the rest. Clear an event
479 464 * by writing 1, writing 0 has no effect. So, the only relevant
480 465 * information is the single bit we're interested in, all others
481 466 * should be written as 0 so they will be left unchanged.
482 467 */
483 468 RegisterValue = ACPI_REGISTER_PREPARE_BITS (Value,
484 469 BitRegInfo->BitPosition, BitRegInfo->AccessBitMask);
485 470
486 471 /* No need to write the register if value is all zeros */
487 472
488 473 if (RegisterValue)
489 474 {
490 475 Status = AcpiHwRegisterWrite (ACPI_REGISTER_PM1_STATUS,
491 476 RegisterValue);
492 477 }
493 478 }
494 479
495 480 ACPI_DEBUG_PRINT ((ACPI_DB_IO,
496 481 "BitReg %X, ParentReg %X, Value %8.8X, Actual %8.8X\n",
497 482 RegisterId, BitRegInfo->ParentRegister, Value, RegisterValue));
↓ open down ↓ |
83 lines elided |
↑ open up ↑ |
498 483
499 484
500 485 UnlockAndExit:
501 486
502 487 AcpiOsReleaseLock (AcpiGbl_HardwareLock, LockFlags);
503 488 return_ACPI_STATUS (Status);
504 489 }
505 490
506 491 ACPI_EXPORT_SYMBOL (AcpiWriteBitRegister)
507 492
493 +#endif /* !ACPI_REDUCED_HARDWARE */
508 494
495 +
509 496 /*******************************************************************************
510 497 *
511 498 * FUNCTION: AcpiGetSleepTypeData
512 499 *
513 500 * PARAMETERS: SleepState - Numeric sleep state
514 501 * *SleepTypeA - Where SLP_TYPa is returned
515 502 * *SleepTypeB - Where SLP_TYPb is returned
516 503 *
517 - * RETURN: Status - ACPI status
504 + * RETURN: Status
518 505 *
519 - * DESCRIPTION: Obtain the SLP_TYPa and SLP_TYPb values for the requested sleep
520 - * state.
506 + * DESCRIPTION: Obtain the SLP_TYPa and SLP_TYPb values for the requested
507 + * sleep state via the appropriate \_Sx object.
521 508 *
509 + * The sleep state package returned from the corresponding \_Sx_ object
510 + * must contain at least one integer.
511 + *
512 + * March 2005:
513 + * Added support for a package that contains two integers. This
514 + * goes against the ACPI specification which defines this object as a
515 + * package with one encoded DWORD integer. However, existing practice
516 + * by many BIOS vendors is to return a package with 2 or more integer
517 + * elements, at least one per sleep type (A/B).
518 + *
519 + * January 2013:
520 + * Therefore, we must be prepared to accept a package with either a
521 + * single integer or multiple integers.
522 + *
523 + * The single integer DWORD format is as follows:
524 + * BYTE 0 - Value for the PM1A SLP_TYP register
525 + * BYTE 1 - Value for the PM1B SLP_TYP register
526 + * BYTE 2-3 - Reserved
527 + *
528 + * The dual integer format is as follows:
529 + * Integer 0 - Value for the PM1A SLP_TYP register
530 + * Integer 1 - Value for the PM1A SLP_TYP register
531 + *
522 532 ******************************************************************************/
523 533
524 534 ACPI_STATUS
525 535 AcpiGetSleepTypeData (
526 536 UINT8 SleepState,
527 537 UINT8 *SleepTypeA,
528 538 UINT8 *SleepTypeB)
529 539 {
530 - ACPI_STATUS Status = AE_OK;
540 + ACPI_STATUS Status;
531 541 ACPI_EVALUATE_INFO *Info;
542 + ACPI_OPERAND_OBJECT **Elements;
532 543
533 544
534 545 ACPI_FUNCTION_TRACE (AcpiGetSleepTypeData);
535 546
536 547
537 548 /* Validate parameters */
538 549
539 550 if ((SleepState > ACPI_S_STATES_MAX) ||
540 - !SleepTypeA ||
541 - !SleepTypeB)
551 + !SleepTypeA || !SleepTypeB)
542 552 {
543 553 return_ACPI_STATUS (AE_BAD_PARAMETER);
544 554 }
545 555
546 556 /* Allocate the evaluation information block */
547 557
548 558 Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
549 559 if (!Info)
550 560 {
551 561 return_ACPI_STATUS (AE_NO_MEMORY);
552 562 }
553 563
554 - Info->Pathname = ACPI_CAST_PTR (char, AcpiGbl_SleepStateNames[SleepState]);
555 -
556 - /* Evaluate the namespace object containing the values for this state */
557 -
564 + /*
565 + * Evaluate the \_Sx namespace object containing the register values
566 + * for this state
567 + */
568 + Info->RelativePathname = ACPI_CAST_PTR (
569 + char, AcpiGbl_SleepStateNames[SleepState]);
558 570 Status = AcpiNsEvaluate (Info);
559 571 if (ACPI_FAILURE (Status))
560 572 {
561 - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
562 - "%s while evaluating SleepState [%s]\n",
563 - AcpiFormatException (Status), Info->Pathname));
564 -
565 573 goto Cleanup;
566 574 }
567 575
568 576 /* Must have a return object */
569 577
570 578 if (!Info->ReturnObject)
571 579 {
572 580 ACPI_ERROR ((AE_INFO, "No Sleep State object returned from [%s]",
573 - Info->Pathname));
574 - Status = AE_NOT_EXIST;
581 + Info->RelativePathname));
582 + Status = AE_AML_NO_RETURN_VALUE;
583 + goto Cleanup;
575 584 }
576 585
577 - /* It must be of type Package */
586 + /* Return object must be of type Package */
578 587
579 - else if (Info->ReturnObject->Common.Type != ACPI_TYPE_PACKAGE)
588 + if (Info->ReturnObject->Common.Type != ACPI_TYPE_PACKAGE)
580 589 {
581 590 ACPI_ERROR ((AE_INFO, "Sleep State return object is not a Package"));
582 591 Status = AE_AML_OPERAND_TYPE;
592 + goto Cleanup1;
583 593 }
584 594
585 595 /*
586 - * The package must have at least two elements. NOTE (March 2005): This
587 - * goes against the current ACPI spec which defines this object as a
588 - * package with one encoded DWORD element. However, existing practice
589 - * by BIOS vendors seems to be to have 2 or more elements, at least
590 - * one per sleep type (A/B).
596 + * Any warnings about the package length or the object types have
597 + * already been issued by the predefined name module -- there is no
598 + * need to repeat them here.
591 599 */
592 - else if (Info->ReturnObject->Package.Count < 2)
600 + Elements = Info->ReturnObject->Package.Elements;
601 + switch (Info->ReturnObject->Package.Count)
593 602 {
594 - ACPI_ERROR ((AE_INFO,
595 - "Sleep State return package does not have at least two elements"));
596 - Status = AE_AML_NO_OPERAND;
597 - }
603 + case 0:
598 604
599 - /* The first two elements must both be of type Integer */
605 + Status = AE_AML_PACKAGE_LIMIT;
606 + break;
600 607
601 - else if (((Info->ReturnObject->Package.Elements[0])->Common.Type
602 - != ACPI_TYPE_INTEGER) ||
603 - ((Info->ReturnObject->Package.Elements[1])->Common.Type
604 - != ACPI_TYPE_INTEGER))
605 - {
606 - ACPI_ERROR ((AE_INFO,
607 - "Sleep State return package elements are not both Integers "
608 - "(%s, %s)",
609 - AcpiUtGetObjectTypeName (Info->ReturnObject->Package.Elements[0]),
610 - AcpiUtGetObjectTypeName (Info->ReturnObject->Package.Elements[1])));
611 - Status = AE_AML_OPERAND_TYPE;
612 - }
613 - else
614 - {
615 - /* Valid _Sx_ package size, type, and value */
608 + case 1:
616 609
617 - *SleepTypeA = (UINT8)
618 - (Info->ReturnObject->Package.Elements[0])->Integer.Value;
619 - *SleepTypeB = (UINT8)
620 - (Info->ReturnObject->Package.Elements[1])->Integer.Value;
610 + if (Elements[0]->Common.Type != ACPI_TYPE_INTEGER)
611 + {
612 + Status = AE_AML_OPERAND_TYPE;
613 + break;
614 + }
615 +
616 + /* A valid _Sx_ package with one integer */
617 +
618 + *SleepTypeA = (UINT8) Elements[0]->Integer.Value;
619 + *SleepTypeB = (UINT8) (Elements[0]->Integer.Value >> 8);
620 + break;
621 +
622 + case 2:
623 + default:
624 +
625 + if ((Elements[0]->Common.Type != ACPI_TYPE_INTEGER) ||
626 + (Elements[1]->Common.Type != ACPI_TYPE_INTEGER))
627 + {
628 + Status = AE_AML_OPERAND_TYPE;
629 + break;
630 + }
631 +
632 + /* A valid _Sx_ package with two integers */
633 +
634 + *SleepTypeA = (UINT8) Elements[0]->Integer.Value;
635 + *SleepTypeB = (UINT8) Elements[1]->Integer.Value;
636 + break;
621 637 }
622 638
639 +Cleanup1:
640 + AcpiUtRemoveReference (Info->ReturnObject);
641 +
642 +Cleanup:
623 643 if (ACPI_FAILURE (Status))
624 644 {
625 645 ACPI_EXCEPTION ((AE_INFO, Status,
626 - "While evaluating SleepState [%s], bad Sleep object %p type %s",
627 - Info->Pathname, Info->ReturnObject,
628 - AcpiUtGetObjectTypeName (Info->ReturnObject)));
646 + "While evaluating Sleep State [%s]", Info->RelativePathname));
629 647 }
630 648
631 - AcpiUtRemoveReference (Info->ReturnObject);
632 -
633 -Cleanup:
634 649 ACPI_FREE (Info);
635 650 return_ACPI_STATUS (Status);
636 651 }
637 652
638 653 ACPI_EXPORT_SYMBOL (AcpiGetSleepTypeData)
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX