Print this page
update to acpica-unix2-20140114
acpica-unix2-20130823
PANKOVs restructure
   1 /******************************************************************************
   2  *
   3  * Module Name: exfield - ACPI AML (p-code) execution - field manipulation
   4  *
   5  *****************************************************************************/
   6 
   7 /*
   8  * Copyright (C) 2000 - 2011, Intel Corp.
   9  * All rights reserved.
  10  *
  11  * Redistribution and use in source and binary forms, with or without
  12  * modification, are permitted provided that the following conditions
  13  * are met:
  14  * 1. Redistributions of source code must retain the above copyright
  15  *    notice, this list of conditions, and the following disclaimer,
  16  *    without modification.
  17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  18  *    substantially similar to the "NO WARRANTY" disclaimer below
  19  *    ("Disclaimer") and any redistribution must be conditioned upon
  20  *    including a substantially similar Disclaimer requirement for further
  21  *    binary redistribution.
  22  * 3. Neither the names of the above-listed copyright holders nor the names
  23  *    of any contributors may be used to endorse or promote products derived
  24  *    from this software without specific prior written permission.
  25  *
  26  * Alternatively, this software may be distributed under the terms of the
  27  * GNU General Public License ("GPL") version 2 as published by the Free
  28  * Software Foundation.


  96         return_ACPI_STATUS (AE_BAD_PARAMETER);
  97     }
  98 
  99     if (ObjDesc->Common.Type == ACPI_TYPE_BUFFER_FIELD)
 100     {
 101         /*
 102          * If the BufferField arguments have not been previously evaluated,
 103          * evaluate them now and save the results.
 104          */
 105         if (!(ObjDesc->Common.Flags & AOPOBJ_DATA_VALID))
 106         {
 107             Status = AcpiDsGetBufferFieldArguments (ObjDesc);
 108             if (ACPI_FAILURE (Status))
 109             {
 110                 return_ACPI_STATUS (Status);
 111             }
 112         }
 113     }
 114     else if ((ObjDesc->Common.Type == ACPI_TYPE_LOCAL_REGION_FIELD) &&
 115              (ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_SMBUS ||

 116               ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_IPMI))
 117     {
 118         /*
 119          * This is an SMBus or IPMI read. We must create a buffer to hold
 120          * the data and then directly access the region handler.
 121          *
 122          * Note: Smbus protocol value is passed in upper 16-bits of Function
 123          */
 124         if (ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_SMBUS)
 125         {
 126             Length = ACPI_SMBUS_BUFFER_SIZE;
 127             Function = ACPI_READ | (ObjDesc->Field.Attribute << 16);
 128         }





 129         else /* IPMI */
 130         {
 131             Length = ACPI_IPMI_BUFFER_SIZE;
 132             Function = ACPI_READ;
 133         }
 134 
 135         BufferDesc = AcpiUtCreateBufferObject (Length);
 136         if (!BufferDesc)
 137         {
 138             return_ACPI_STATUS (AE_NO_MEMORY);
 139         }
 140 
 141         /* Lock entire transaction if requested */
 142 
 143         AcpiExAcquireGlobalLock (ObjDesc->CommonField.FieldFlags);
 144 
 145         /* Call the region handler for the read */
 146 
 147         Status = AcpiExAccessRegion (ObjDesc, 0,
 148                     ACPI_CAST_PTR (UINT64, BufferDesc->Buffer.Pointer),


 257         return_ACPI_STATUS (AE_AML_NO_OPERAND);
 258     }
 259 
 260     if (ObjDesc->Common.Type == ACPI_TYPE_BUFFER_FIELD)
 261     {
 262         /*
 263          * If the BufferField arguments have not been previously evaluated,
 264          * evaluate them now and save the results.
 265          */
 266         if (!(ObjDesc->Common.Flags & AOPOBJ_DATA_VALID))
 267         {
 268             Status = AcpiDsGetBufferFieldArguments (ObjDesc);
 269             if (ACPI_FAILURE (Status))
 270             {
 271                 return_ACPI_STATUS (Status);
 272             }
 273         }
 274     }
 275     else if ((ObjDesc->Common.Type == ACPI_TYPE_LOCAL_REGION_FIELD) &&
 276              (ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_SMBUS ||

 277               ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_IPMI))
 278     {
 279         /*
 280          * This is an SMBus or IPMI write. We will bypass the entire field
 281          * mechanism and handoff the buffer directly to the handler. For
 282          * these address spaces, the buffer is bi-directional; on a write,
 283          * return data is returned in the same buffer.
 284          *
 285          * Source must be a buffer of sufficient size:
 286          * ACPI_SMBUS_BUFFER_SIZE or ACPI_IPMI_BUFFER_SIZE.
 287          *
 288          * Note: SMBus protocol type is passed in upper 16-bits of Function
 289          */
 290         if (SourceDesc->Common.Type != ACPI_TYPE_BUFFER)
 291         {
 292             ACPI_ERROR ((AE_INFO,
 293                 "SMBus or IPMI write requires Buffer, found type %s",
 294                 AcpiUtGetObjectTypeName (SourceDesc)));
 295 
 296             return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
 297         }
 298 
 299         if (ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_SMBUS)
 300         {
 301             Length = ACPI_SMBUS_BUFFER_SIZE;
 302             Function = ACPI_WRITE | (ObjDesc->Field.Attribute << 16);
 303         }





 304         else /* IPMI */
 305         {
 306             Length = ACPI_IPMI_BUFFER_SIZE;
 307             Function = ACPI_WRITE;
 308         }
 309 
 310         if (SourceDesc->Buffer.Length < Length)
 311         {
 312             ACPI_ERROR ((AE_INFO,
 313                 "SMBus or IPMI write requires Buffer of length %u, found length %u",
 314                 Length, SourceDesc->Buffer.Length));
 315 
 316             return_ACPI_STATUS (AE_AML_BUFFER_LIMIT);
 317         }
 318 
 319         /* Create the bi-directional buffer */
 320 
 321         BufferDesc = AcpiUtCreateBufferObject (Length);
 322         if (!BufferDesc)
 323         {
 324             return_ACPI_STATUS (AE_NO_MEMORY);
 325         }
 326 
 327         Buffer = BufferDesc->Buffer.Pointer;
 328         ACPI_MEMCPY (Buffer, SourceDesc->Buffer.Pointer, Length);
 329 
 330         /* Lock entire transaction if requested */
 331 
 332         AcpiExAcquireGlobalLock (ObjDesc->CommonField.FieldFlags);
 333 
 334         /*
 335          * Perform the write (returns status and perhaps data in the
 336          * same buffer)
 337          */
 338         Status = AcpiExAccessRegion (ObjDesc, 0,
 339                     (UINT64 *) Buffer, Function);
 340         AcpiExReleaseGlobalLock (ObjDesc->CommonField.FieldFlags);
 341 
 342         *ResultDesc = BufferDesc;
 343         return_ACPI_STATUS (Status);
 344     }
 345 
 346     /* Get a pointer to the data to be written */
 347 
 348     switch (SourceDesc->Common.Type)
 349     {
 350     case ACPI_TYPE_INTEGER:

 351         Buffer = &SourceDesc->Integer.Value;
 352         Length = sizeof (SourceDesc->Integer.Value);
 353         break;
 354 
 355     case ACPI_TYPE_BUFFER:

 356         Buffer = SourceDesc->Buffer.Pointer;
 357         Length = SourceDesc->Buffer.Length;
 358         break;
 359 
 360     case ACPI_TYPE_STRING:

 361         Buffer = SourceDesc->String.Pointer;
 362         Length = SourceDesc->String.Length;
 363         break;
 364 
 365     default:

 366         return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
 367     }
 368 
 369     ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
 370         "FieldWrite [FROM]: Obj %p (%s:%X), Buf %p, ByteLen %X\n",
 371         SourceDesc, AcpiUtGetTypeName (SourceDesc->Common.Type),
 372         SourceDesc->Common.Type, Buffer, Length));
 373 
 374     ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
 375         "FieldWrite [TO]:   Obj %p (%s:%X), BitLen %X, BitOff %X, ByteOff %X\n",
 376         ObjDesc, AcpiUtGetTypeName (ObjDesc->Common.Type),
 377         ObjDesc->Common.Type,
 378         ObjDesc->CommonField.BitLength,
 379         ObjDesc->CommonField.StartFieldBitOffset,
 380         ObjDesc->CommonField.BaseByteOffset));
 381 
 382     /* Lock entire transaction if requested */
 383 
 384     AcpiExAcquireGlobalLock (ObjDesc->CommonField.FieldFlags);
 385 
 386     /* Write to the field */
 387 
 388     Status = AcpiExInsertIntoField (ObjDesc, Buffer, Length);
 389     AcpiExReleaseGlobalLock (ObjDesc->CommonField.FieldFlags);
 390 
 391     return_ACPI_STATUS (Status);
 392 }
 393 
 394 
   1 /******************************************************************************
   2  *
   3  * Module Name: exfield - ACPI AML (p-code) execution - field manipulation
   4  *
   5  *****************************************************************************/
   6 
   7 /*
   8  * Copyright (C) 2000 - 2014, Intel Corp.
   9  * All rights reserved.
  10  *
  11  * Redistribution and use in source and binary forms, with or without
  12  * modification, are permitted provided that the following conditions
  13  * are met:
  14  * 1. Redistributions of source code must retain the above copyright
  15  *    notice, this list of conditions, and the following disclaimer,
  16  *    without modification.
  17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  18  *    substantially similar to the "NO WARRANTY" disclaimer below
  19  *    ("Disclaimer") and any redistribution must be conditioned upon
  20  *    including a substantially similar Disclaimer requirement for further
  21  *    binary redistribution.
  22  * 3. Neither the names of the above-listed copyright holders nor the names
  23  *    of any contributors may be used to endorse or promote products derived
  24  *    from this software without specific prior written permission.
  25  *
  26  * Alternatively, this software may be distributed under the terms of the
  27  * GNU General Public License ("GPL") version 2 as published by the Free
  28  * Software Foundation.


  96         return_ACPI_STATUS (AE_BAD_PARAMETER);
  97     }
  98 
  99     if (ObjDesc->Common.Type == ACPI_TYPE_BUFFER_FIELD)
 100     {
 101         /*
 102          * If the BufferField arguments have not been previously evaluated,
 103          * evaluate them now and save the results.
 104          */
 105         if (!(ObjDesc->Common.Flags & AOPOBJ_DATA_VALID))
 106         {
 107             Status = AcpiDsGetBufferFieldArguments (ObjDesc);
 108             if (ACPI_FAILURE (Status))
 109             {
 110                 return_ACPI_STATUS (Status);
 111             }
 112         }
 113     }
 114     else if ((ObjDesc->Common.Type == ACPI_TYPE_LOCAL_REGION_FIELD) &&
 115              (ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_SMBUS ||
 116               ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GSBUS ||
 117               ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_IPMI))
 118     {
 119         /*
 120          * This is an SMBus, GSBus or IPMI read. We must create a buffer to hold
 121          * the data and then directly access the region handler.
 122          *
 123          * Note: SMBus and GSBus protocol value is passed in upper 16-bits of Function
 124          */
 125         if (ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_SMBUS)
 126         {
 127             Length = ACPI_SMBUS_BUFFER_SIZE;
 128             Function = ACPI_READ | (ObjDesc->Field.Attribute << 16);
 129         }
 130         else if (ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GSBUS)
 131         {
 132             Length = ACPI_GSBUS_BUFFER_SIZE;
 133             Function = ACPI_READ | (ObjDesc->Field.Attribute << 16);
 134         }
 135         else /* IPMI */
 136         {
 137             Length = ACPI_IPMI_BUFFER_SIZE;
 138             Function = ACPI_READ;
 139         }
 140 
 141         BufferDesc = AcpiUtCreateBufferObject (Length);
 142         if (!BufferDesc)
 143         {
 144             return_ACPI_STATUS (AE_NO_MEMORY);
 145         }
 146 
 147         /* Lock entire transaction if requested */
 148 
 149         AcpiExAcquireGlobalLock (ObjDesc->CommonField.FieldFlags);
 150 
 151         /* Call the region handler for the read */
 152 
 153         Status = AcpiExAccessRegion (ObjDesc, 0,
 154                     ACPI_CAST_PTR (UINT64, BufferDesc->Buffer.Pointer),


 263         return_ACPI_STATUS (AE_AML_NO_OPERAND);
 264     }
 265 
 266     if (ObjDesc->Common.Type == ACPI_TYPE_BUFFER_FIELD)
 267     {
 268         /*
 269          * If the BufferField arguments have not been previously evaluated,
 270          * evaluate them now and save the results.
 271          */
 272         if (!(ObjDesc->Common.Flags & AOPOBJ_DATA_VALID))
 273         {
 274             Status = AcpiDsGetBufferFieldArguments (ObjDesc);
 275             if (ACPI_FAILURE (Status))
 276             {
 277                 return_ACPI_STATUS (Status);
 278             }
 279         }
 280     }
 281     else if ((ObjDesc->Common.Type == ACPI_TYPE_LOCAL_REGION_FIELD) &&
 282              (ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_SMBUS ||
 283               ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GSBUS ||
 284               ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_IPMI))
 285     {
 286         /*
 287          * This is an SMBus, GSBus or IPMI write. We will bypass the entire field
 288          * mechanism and handoff the buffer directly to the handler. For
 289          * these address spaces, the buffer is bi-directional; on a write,
 290          * return data is returned in the same buffer.
 291          *
 292          * Source must be a buffer of sufficient size:
 293          * ACPI_SMBUS_BUFFER_SIZE, ACPI_GSBUS_BUFFER_SIZE, or ACPI_IPMI_BUFFER_SIZE.
 294          *
 295          * Note: SMBus and GSBus protocol type is passed in upper 16-bits of Function
 296          */
 297         if (SourceDesc->Common.Type != ACPI_TYPE_BUFFER)
 298         {
 299             ACPI_ERROR ((AE_INFO,
 300                 "SMBus/IPMI/GenericSerialBus write requires Buffer, found type %s",
 301                 AcpiUtGetObjectTypeName (SourceDesc)));
 302 
 303             return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
 304         }
 305 
 306         if (ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_SMBUS)
 307         {
 308             Length = ACPI_SMBUS_BUFFER_SIZE;
 309             Function = ACPI_WRITE | (ObjDesc->Field.Attribute << 16);
 310         }
 311         else if (ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GSBUS)
 312         {
 313             Length = ACPI_GSBUS_BUFFER_SIZE;
 314             Function = ACPI_WRITE | (ObjDesc->Field.Attribute << 16);
 315         }
 316         else /* IPMI */
 317         {
 318             Length = ACPI_IPMI_BUFFER_SIZE;
 319             Function = ACPI_WRITE;
 320         }
 321 
 322         if (SourceDesc->Buffer.Length < Length)
 323         {
 324             ACPI_ERROR ((AE_INFO,
 325                 "SMBus/IPMI/GenericSerialBus write requires Buffer of length %u, found length %u",
 326                 Length, SourceDesc->Buffer.Length));
 327 
 328             return_ACPI_STATUS (AE_AML_BUFFER_LIMIT);
 329         }
 330 
 331         /* Create the bi-directional buffer */
 332 
 333         BufferDesc = AcpiUtCreateBufferObject (Length);
 334         if (!BufferDesc)
 335         {
 336             return_ACPI_STATUS (AE_NO_MEMORY);
 337         }
 338 
 339         Buffer = BufferDesc->Buffer.Pointer;
 340         ACPI_MEMCPY (Buffer, SourceDesc->Buffer.Pointer, Length);
 341 
 342         /* Lock entire transaction if requested */
 343 
 344         AcpiExAcquireGlobalLock (ObjDesc->CommonField.FieldFlags);
 345 
 346         /*
 347          * Perform the write (returns status and perhaps data in the
 348          * same buffer)
 349          */
 350         Status = AcpiExAccessRegion (ObjDesc, 0,
 351                     (UINT64 *) Buffer, Function);
 352         AcpiExReleaseGlobalLock (ObjDesc->CommonField.FieldFlags);
 353 
 354         *ResultDesc = BufferDesc;
 355         return_ACPI_STATUS (Status);
 356     }
 357 
 358     /* Get a pointer to the data to be written */
 359 
 360     switch (SourceDesc->Common.Type)
 361     {
 362     case ACPI_TYPE_INTEGER:
 363 
 364         Buffer = &SourceDesc->Integer.Value;
 365         Length = sizeof (SourceDesc->Integer.Value);
 366         break;
 367 
 368     case ACPI_TYPE_BUFFER:
 369 
 370         Buffer = SourceDesc->Buffer.Pointer;
 371         Length = SourceDesc->Buffer.Length;
 372         break;
 373 
 374     case ACPI_TYPE_STRING:
 375 
 376         Buffer = SourceDesc->String.Pointer;
 377         Length = SourceDesc->String.Length;
 378         break;
 379 
 380     default:
 381 
 382         return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
 383     }
 384 
 385     ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
 386         "FieldWrite [FROM]: Obj %p (%s:%X), Buf %p, ByteLen %X\n",
 387         SourceDesc, AcpiUtGetTypeName (SourceDesc->Common.Type),
 388         SourceDesc->Common.Type, Buffer, Length));
 389 
 390     ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
 391         "FieldWrite [TO]:   Obj %p (%s:%X), BitLen %X, BitOff %X, ByteOff %X\n",
 392         ObjDesc, AcpiUtGetTypeName (ObjDesc->Common.Type),
 393         ObjDesc->Common.Type,
 394         ObjDesc->CommonField.BitLength,
 395         ObjDesc->CommonField.StartFieldBitOffset,
 396         ObjDesc->CommonField.BaseByteOffset));
 397 
 398     /* Lock entire transaction if requested */
 399 
 400     AcpiExAcquireGlobalLock (ObjDesc->CommonField.FieldFlags);
 401 
 402     /* Write to the field */
 403 
 404     Status = AcpiExInsertIntoField (ObjDesc, Buffer, Length);
 405     AcpiExReleaseGlobalLock (ObjDesc->CommonField.FieldFlags);
 406 
 407     return_ACPI_STATUS (Status);
 408 }