Warning, cross-references for /kernel/drivers/acpica/exfldio.c need to be fixed.
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117 #define __EXFLDIO_C__
0118
0119 #include "acpi.h"
0120 #include "accommon.h"
0121 #include "acinterp.h"
0122 #include "amlcode.h"
0123 #include "acevents.h"
0124 #include "acdispat.h"
0125
0126
0127 #define _COMPONENT ACPI_EXECUTER
0128 ACPI_MODULE_NAME ("exfldio")
0129
0130
0131
0132 static ACPI_STATUS
0133 AcpiExFieldDatumIo (
0134 ACPI_OPERAND_OBJECT *ObjDesc,
0135 UINT32 FieldDatumByteOffset,
0136 ACPI_INTEGER *Value,
0137 UINT32 ReadWrite);
0138
0139 static BOOLEAN
0140 AcpiExRegisterOverflow (
0141 ACPI_OPERAND_OBJECT *ObjDesc,
0142 ACPI_INTEGER Value);
0143
0144 static ACPI_STATUS
0145 AcpiExSetupRegion (
0146 ACPI_OPERAND_OBJECT *ObjDesc,
0147 UINT32 FieldDatumByteOffset);
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166 static ACPI_STATUS
0167 AcpiExSetupRegion (
0168 ACPI_OPERAND_OBJECT *ObjDesc,
0169 UINT32 FieldDatumByteOffset)
0170 {
0171 ACPI_STATUS Status = AE_OK;
0172 ACPI_OPERAND_OBJECT *RgnDesc;
0173
0174
0175 ACPI_FUNCTION_TRACE_U32 (ExSetupRegion, FieldDatumByteOffset);
0176
0177
0178 RgnDesc = ObjDesc->CommonField.RegionObj;
0179
0180
0181
0182 if (RgnDesc->Common.Type != ACPI_TYPE_REGION)
0183 {
0184 ACPI_ERROR ((AE_INFO, "Needed Region, found type %X (%s)",
0185 RgnDesc->Common.Type,
0186 AcpiUtGetObjectTypeName (RgnDesc)));
0187
0188 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
0189 }
0190
0191
0192
0193
0194
0195 if (!(RgnDesc->Common.Flags & AOPOBJ_DATA_VALID))
0196 {
0197 Status = AcpiDsGetRegionArguments (RgnDesc);
0198 if (ACPI_FAILURE (Status))
0199 {
0200 return_ACPI_STATUS (Status);
0201 }
0202 }
0203
0204
0205
0206
0207
0208 if (RgnDesc->Region.SpaceId == ACPI_ADR_SPACE_SMBUS ||
0209 RgnDesc->Region.SpaceId == ACPI_ADR_SPACE_IPMI)
0210 {
0211
0212
0213 return_ACPI_STATUS (AE_OK);
0214 }
0215
0216 #ifdef ACPI_UNDER_DEVELOPMENT
0217
0218
0219
0220
0221 if (!(ObjDesc->Common.Flags & AOPOBJ_DATA_VALID))
0222 {
0223 if (ACPI_FAILURE (Status))
0224 {
0225 return_ACPI_STATUS (Status);
0226 }
0227 }
0228 #endif
0229
0230
0231
0232
0233
0234
0235 if (RgnDesc->Region.Length <
0236 (ObjDesc->CommonField.BaseByteOffset +
0237 FieldDatumByteOffset +
0238 ObjDesc->CommonField.AccessByteWidth))
0239 {
0240 if (AcpiGbl_EnableInterpreterSlack)
0241 {
0242
0243
0244
0245
0246
0247 if (ACPI_ROUND_UP (RgnDesc->Region.Length,
0248 ObjDesc->CommonField.AccessByteWidth) >=
0249 ((ACPI_SIZE) ObjDesc->CommonField.BaseByteOffset +
0250 ObjDesc->CommonField.AccessByteWidth +
0251 FieldDatumByteOffset))
0252 {
0253 return_ACPI_STATUS (AE_OK);
0254 }
0255 }
0256
0257 if (RgnDesc->Region.Length < ObjDesc->CommonField.AccessByteWidth)
0258 {
0259
0260
0261
0262
0263
0264 ACPI_ERROR ((AE_INFO,
0265 "Field [%4.4s] access width (%d bytes) too large for region [%4.4s] (length %X)",
0266 AcpiUtGetNodeName (ObjDesc->CommonField.Node),
0267 ObjDesc->CommonField.AccessByteWidth,
0268 AcpiUtGetNodeName (RgnDesc->Region.Node),
0269 RgnDesc->Region.Length));
0270 }
0271
0272
0273
0274
0275
0276 ACPI_ERROR ((AE_INFO,
0277 "Field [%4.4s] Base+Offset+Width %X+%X+%X is beyond end of region [%4.4s] (length %X)",
0278 AcpiUtGetNodeName (ObjDesc->CommonField.Node),
0279 ObjDesc->CommonField.BaseByteOffset,
0280 FieldDatumByteOffset, ObjDesc->CommonField.AccessByteWidth,
0281 AcpiUtGetNodeName (RgnDesc->Region.Node),
0282 RgnDesc->Region.Length));
0283
0284 return_ACPI_STATUS (AE_AML_REGION_LIMIT);
0285 }
0286
0287 return_ACPI_STATUS (AE_OK);
0288 }
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309 ACPI_STATUS
0310 AcpiExAccessRegion (
0311 ACPI_OPERAND_OBJECT *ObjDesc,
0312 UINT32 FieldDatumByteOffset,
0313 ACPI_INTEGER *Value,
0314 UINT32 Function)
0315 {
0316 ACPI_STATUS Status;
0317 ACPI_OPERAND_OBJECT *RgnDesc;
0318 UINT32 RegionOffset;
0319
0320
0321 ACPI_FUNCTION_TRACE (ExAccessRegion);
0322
0323
0324
0325
0326
0327
0328 Status = AcpiExSetupRegion (ObjDesc, FieldDatumByteOffset);
0329 if (ACPI_FAILURE (Status))
0330 {
0331 return_ACPI_STATUS (Status);
0332 }
0333
0334
0335
0336
0337
0338
0339
0340
0341 RgnDesc = ObjDesc->CommonField.RegionObj;
0342 RegionOffset =
0343 ObjDesc->CommonField.BaseByteOffset +
0344 FieldDatumByteOffset;
0345
0346 if ((Function & ACPI_IO_MASK) == ACPI_READ)
0347 {
0348 ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "[READ]"));
0349 }
0350 else
0351 {
0352 ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "[WRITE]"));
0353 }
0354
0355 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_BFIELD,
0356 " Region [%s:%X], Width %X, ByteBase %X, Offset %X at %p\n",
0357 AcpiUtGetRegionName (RgnDesc->Region.SpaceId),
0358 RgnDesc->Region.SpaceId,
0359 ObjDesc->CommonField.AccessByteWidth,
0360 ObjDesc->CommonField.BaseByteOffset,
0361 FieldDatumByteOffset,
0362 ACPI_CAST_PTR (void, (RgnDesc->Region.Address + RegionOffset))));
0363
0364
0365
0366 Status = AcpiEvAddressSpaceDispatch (RgnDesc, Function, RegionOffset,
0367 ACPI_MUL_8 (ObjDesc->CommonField.AccessByteWidth), Value);
0368
0369 if (ACPI_FAILURE (Status))
0370 {
0371 if (Status == AE_NOT_IMPLEMENTED)
0372 {
0373 ACPI_ERROR ((AE_INFO,
0374 "Region %s(%X) not implemented",
0375 AcpiUtGetRegionName (RgnDesc->Region.SpaceId),
0376 RgnDesc->Region.SpaceId));
0377 }
0378 else if (Status == AE_NOT_EXIST)
0379 {
0380 ACPI_ERROR ((AE_INFO,
0381 "Region %s(%X) has no handler",
0382 AcpiUtGetRegionName (RgnDesc->Region.SpaceId),
0383 RgnDesc->Region.SpaceId));
0384 }
0385 }
0386
0387 return_ACPI_STATUS (Status);
0388 }
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408 static BOOLEAN
0409 AcpiExRegisterOverflow (
0410 ACPI_OPERAND_OBJECT *ObjDesc,
0411 ACPI_INTEGER Value)
0412 {
0413
0414 if (ObjDesc->CommonField.BitLength >= ACPI_INTEGER_BIT_SIZE)
0415 {
0416
0417
0418
0419
0420 return (FALSE);
0421 }
0422
0423 if (Value >= ((ACPI_INTEGER) 1 << ObjDesc->CommonField.BitLength))
0424 {
0425
0426
0427
0428
0429 return (TRUE);
0430 }
0431
0432
0433
0434 return (FALSE);
0435 }
0436
0437
0438
0439
0440
0441
0442
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456 static ACPI_STATUS
0457 AcpiExFieldDatumIo (
0458 ACPI_OPERAND_OBJECT *ObjDesc,
0459 UINT32 FieldDatumByteOffset,
0460 ACPI_INTEGER *Value,
0461 UINT32 ReadWrite)
0462 {
0463 ACPI_STATUS Status;
0464 ACPI_INTEGER LocalValue;
0465
0466
0467 ACPI_FUNCTION_TRACE_U32 (ExFieldDatumIo, FieldDatumByteOffset);
0468
0469
0470 if (ReadWrite == ACPI_READ)
0471 {
0472 if (!Value)
0473 {
0474 LocalValue = 0;
0475
0476
0477 Value = &LocalValue;
0478 }
0479
0480
0481
0482 *Value = 0;
0483 }
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493
0494
0495 switch (ObjDesc->Common.Type)
0496 {
0497 case ACPI_TYPE_BUFFER_FIELD:
0498
0499
0500
0501
0502 if (!(ObjDesc->Common.Flags & AOPOBJ_DATA_VALID))
0503 {
0504 Status = AcpiDsGetBufferFieldArguments (ObjDesc);
0505 if (ACPI_FAILURE (Status))
0506 {
0507 return_ACPI_STATUS (Status);
0508 }
0509 }
0510
0511 if (ReadWrite == ACPI_READ)
0512 {
0513
0514
0515
0516
0517 ACPI_MEMCPY (Value,
0518 (ObjDesc->BufferField.BufferObj)->Buffer.Pointer +
0519 ObjDesc->BufferField.BaseByteOffset +
0520 FieldDatumByteOffset,
0521 ObjDesc->CommonField.AccessByteWidth);
0522 }
0523 else
0524 {
0525
0526
0527
0528
0529 ACPI_MEMCPY ((ObjDesc->BufferField.BufferObj)->Buffer.Pointer +
0530 ObjDesc->BufferField.BaseByteOffset +
0531 FieldDatumByteOffset,
0532 Value, ObjDesc->CommonField.AccessByteWidth);
0533 }
0534
0535 Status = AE_OK;
0536 break;
0537
0538
0539 case ACPI_TYPE_LOCAL_BANK_FIELD:
0540
0541
0542
0543
0544
0545 if (AcpiExRegisterOverflow (ObjDesc->BankField.BankObj,
0546 (ACPI_INTEGER) ObjDesc->BankField.Value))
0547 {
0548 return_ACPI_STATUS (AE_AML_REGISTER_LIMIT);
0549 }
0550
0551
0552
0553
0554
0555 Status = AcpiExInsertIntoField (ObjDesc->BankField.BankObj,
0556 &ObjDesc->BankField.Value,
0557 sizeof (ObjDesc->BankField.Value));
0558 if (ACPI_FAILURE (Status))
0559 {
0560 return_ACPI_STATUS (Status);
0561 }
0562
0563
0564
0565
0566
0567
0568
0569
0570
0571 case ACPI_TYPE_LOCAL_REGION_FIELD:
0572
0573
0574
0575
0576 Status = AcpiExAccessRegion (ObjDesc, FieldDatumByteOffset, Value,
0577 ReadWrite);
0578 break;
0579
0580
0581 case ACPI_TYPE_LOCAL_INDEX_FIELD:
0582
0583
0584
0585
0586
0587
0588 if (AcpiExRegisterOverflow (ObjDesc->IndexField.IndexObj,
0589 (ACPI_INTEGER) ObjDesc->IndexField.Value))
0590 {
0591 return_ACPI_STATUS (AE_AML_REGISTER_LIMIT);
0592 }
0593
0594
0595
0596 FieldDatumByteOffset += ObjDesc->IndexField.Value;
0597
0598 ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
0599 "Write to Index Register: Value %8.8X\n",
0600 FieldDatumByteOffset));
0601
0602 Status = AcpiExInsertIntoField (ObjDesc->IndexField.IndexObj,
0603 &FieldDatumByteOffset,
0604 sizeof (FieldDatumByteOffset));
0605 if (ACPI_FAILURE (Status))
0606 {
0607 return_ACPI_STATUS (Status);
0608 }
0609
0610 if (ReadWrite == ACPI_READ)
0611 {
0612
0613
0614 ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
0615 "Read from Data Register\n"));
0616
0617 Status = AcpiExExtractFromField (ObjDesc->IndexField.DataObj,
0618 Value, sizeof (ACPI_INTEGER));
0619 }
0620 else
0621 {
0622
0623
0624 ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
0625 "Write to Data Register: Value %8.8X%8.8X\n",
0626 ACPI_FORMAT_UINT64 (*Value)));
0627
0628 Status = AcpiExInsertIntoField (ObjDesc->IndexField.DataObj,
0629 Value, sizeof (ACPI_INTEGER));
0630 }
0631 break;
0632
0633
0634 default:
0635
0636 ACPI_ERROR ((AE_INFO, "Wrong object type in field I/O %X",
0637 ObjDesc->Common.Type));
0638 Status = AE_AML_INTERNAL;
0639 break;
0640 }
0641
0642 if (ACPI_SUCCESS (Status))
0643 {
0644 if (ReadWrite == ACPI_READ)
0645 {
0646 ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
0647 "Value Read %8.8X%8.8X, Width %d\n",
0648 ACPI_FORMAT_UINT64 (*Value),
0649 ObjDesc->CommonField.AccessByteWidth));
0650 }
0651 else
0652 {
0653 ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
0654 "Value Written %8.8X%8.8X, Width %d\n",
0655 ACPI_FORMAT_UINT64 (*Value),
0656 ObjDesc->CommonField.AccessByteWidth));
0657 }
0658 }
0659
0660 return_ACPI_STATUS (Status);
0661 }
0662
0663
0664
0665
0666
0667
0668
0669
0670
0671
0672
0673
0674
0675
0676
0677
0678
0679 ACPI_STATUS
0680 AcpiExWriteWithUpdateRule (
0681 ACPI_OPERAND_OBJECT *ObjDesc,
0682 ACPI_INTEGER Mask,
0683 ACPI_INTEGER FieldValue,
0684 UINT32 FieldDatumByteOffset)
0685 {
0686 ACPI_STATUS Status = AE_OK;
0687 ACPI_INTEGER MergedValue;
0688 ACPI_INTEGER CurrentValue;
0689
0690
0691 ACPI_FUNCTION_TRACE_U32 (ExWriteWithUpdateRule, Mask);
0692
0693
0694
0695
0696 MergedValue = FieldValue;
0697
0698
0699
0700 if (Mask != ACPI_INTEGER_MAX)
0701 {
0702
0703
0704 switch (ObjDesc->CommonField.FieldFlags & AML_FIELD_UPDATE_RULE_MASK)
0705 {
0706 case AML_FIELD_UPDATE_PRESERVE:
0707
0708
0709
0710
0711 if ((~Mask << (ACPI_MUL_8 (sizeof (Mask)) -
0712 ACPI_MUL_8 (ObjDesc->CommonField.AccessByteWidth))) != 0)
0713 {
0714
0715
0716
0717
0718 Status = AcpiExFieldDatumIo (ObjDesc, FieldDatumByteOffset,
0719 &CurrentValue, ACPI_READ);
0720 if (ACPI_FAILURE (Status))
0721 {
0722 return_ACPI_STATUS (Status);
0723 }
0724
0725 MergedValue |= (CurrentValue & ~Mask);
0726 }
0727 break;
0728
0729 case AML_FIELD_UPDATE_WRITE_AS_ONES:
0730
0731
0732
0733 MergedValue |= ~Mask;
0734 break;
0735
0736 case AML_FIELD_UPDATE_WRITE_AS_ZEROS:
0737
0738
0739
0740 MergedValue &= Mask;
0741 break;
0742
0743 default:
0744
0745 ACPI_ERROR ((AE_INFO,
0746 "Unknown UpdateRule value: %X",
0747 (ObjDesc->CommonField.FieldFlags & AML_FIELD_UPDATE_RULE_MASK)));
0748 return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
0749 }
0750 }
0751
0752 ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
0753 "Mask %8.8X%8.8X, DatumOffset %X, Width %X, Value %8.8X%8.8X, MergedValue %8.8X%8.8X\n",
0754 ACPI_FORMAT_UINT64 (Mask),
0755 FieldDatumByteOffset,
0756 ObjDesc->CommonField.AccessByteWidth,
0757 ACPI_FORMAT_UINT64 (FieldValue),
0758 ACPI_FORMAT_UINT64 (MergedValue)));
0759
0760
0761
0762 Status = AcpiExFieldDatumIo (ObjDesc, FieldDatumByteOffset,
0763 &MergedValue, ACPI_WRITE);
0764
0765 return_ACPI_STATUS (Status);
0766 }
0767
0768
0769
0770
0771
0772
0773
0774
0775
0776
0777
0778
0779
0780
0781
0782
0783 ACPI_STATUS
0784 AcpiExExtractFromField (
0785 ACPI_OPERAND_OBJECT *ObjDesc,
0786 void *Buffer,
0787 UINT32 BufferLength)
0788 {
0789 ACPI_STATUS Status;
0790 ACPI_INTEGER RawDatum;
0791 ACPI_INTEGER MergedDatum;
0792 UINT32 FieldOffset = 0;
0793 UINT32 BufferOffset = 0;
0794 UINT32 BufferTailBits;
0795 UINT32 DatumCount;
0796 UINT32 FieldDatumCount;
0797 UINT32 i;
0798
0799
0800 ACPI_FUNCTION_TRACE (ExExtractFromField);
0801
0802
0803
0804
0805 if (BufferLength <
0806 ACPI_ROUND_BITS_UP_TO_BYTES (ObjDesc->CommonField.BitLength))
0807 {
0808 ACPI_ERROR ((AE_INFO,
0809 "Field size %X (bits) is too large for buffer (%X)",
0810 ObjDesc->CommonField.BitLength, BufferLength));
0811
0812 return_ACPI_STATUS (AE_BUFFER_OVERFLOW);
0813 }
0814 ACPI_MEMSET (Buffer, 0, BufferLength);
0815
0816
0817
0818 DatumCount = ACPI_ROUND_UP_TO (
0819 ObjDesc->CommonField.BitLength,
0820 ObjDesc->CommonField.AccessBitWidth);
0821 FieldDatumCount = ACPI_ROUND_UP_TO (
0822 ObjDesc->CommonField.BitLength +
0823 ObjDesc->CommonField.StartFieldBitOffset,
0824 ObjDesc->CommonField.AccessBitWidth);
0825
0826
0827
0828 Status = AcpiExFieldDatumIo (ObjDesc, FieldOffset, &RawDatum, ACPI_READ);
0829 if (ACPI_FAILURE (Status))
0830 {
0831 return_ACPI_STATUS (Status);
0832 }
0833 MergedDatum = RawDatum >> ObjDesc->CommonField.StartFieldBitOffset;
0834
0835
0836
0837 for (i = 1; i < FieldDatumCount; i++)
0838 {
0839
0840
0841 FieldOffset += ObjDesc->CommonField.AccessByteWidth;
0842 Status = AcpiExFieldDatumIo (ObjDesc, FieldOffset,
0843 &RawDatum, ACPI_READ);
0844 if (ACPI_FAILURE (Status))
0845 {
0846 return_ACPI_STATUS (Status);
0847 }
0848
0849
0850
0851
0852
0853
0854
0855
0856
0857 if ((ObjDesc->CommonField.AccessBitWidth -
0858 ObjDesc->CommonField.StartFieldBitOffset) < ACPI_INTEGER_BIT_SIZE)
0859 {
0860 MergedDatum |= RawDatum <<
0861 (ObjDesc->CommonField.AccessBitWidth -
0862 ObjDesc->CommonField.StartFieldBitOffset);
0863 }
0864
0865 if (i == DatumCount)
0866 {
0867 break;
0868 }
0869
0870
0871
0872 ACPI_MEMCPY (((char *) Buffer) + BufferOffset, &MergedDatum,
0873 ACPI_MIN(ObjDesc->CommonField.AccessByteWidth,
0874 BufferLength - BufferOffset));
0875
0876 BufferOffset += ObjDesc->CommonField.AccessByteWidth;
0877 MergedDatum = RawDatum >> ObjDesc->CommonField.StartFieldBitOffset;
0878 }
0879
0880
0881
0882 BufferTailBits = ObjDesc->CommonField.BitLength %
0883 ObjDesc->CommonField.AccessBitWidth;
0884 if (BufferTailBits)
0885 {
0886 MergedDatum &= ACPI_MASK_BITS_ABOVE (BufferTailBits);
0887 }
0888
0889
0890
0891 ACPI_MEMCPY (((char *) Buffer) + BufferOffset, &MergedDatum,
0892 ACPI_MIN(ObjDesc->CommonField.AccessByteWidth,
0893 BufferLength - BufferOffset));
0894
0895 return_ACPI_STATUS (AE_OK);
0896 }
0897
0898
0899
0900
0901
0902
0903
0904
0905
0906
0907
0908
0909
0910
0911
0912
0913 ACPI_STATUS
0914 AcpiExInsertIntoField (
0915 ACPI_OPERAND_OBJECT *ObjDesc,
0916 void *Buffer,
0917 UINT32 BufferLength)
0918 {
0919 ACPI_STATUS Status;
0920 ACPI_INTEGER Mask;
0921 ACPI_INTEGER WidthMask;
0922 ACPI_INTEGER MergedDatum;
0923 ACPI_INTEGER RawDatum = 0;
0924 UINT32 FieldOffset = 0;
0925 UINT32 BufferOffset = 0;
0926 UINT32 BufferTailBits;
0927 UINT32 DatumCount;
0928 UINT32 FieldDatumCount;
0929 UINT32 i;
0930 UINT32 RequiredLength;
0931 void *NewBuffer;
0932
0933
0934 ACPI_FUNCTION_TRACE (ExInsertIntoField);
0935
0936
0937
0938
0939 NewBuffer = NULL;
0940 RequiredLength = ACPI_ROUND_BITS_UP_TO_BYTES (
0941 ObjDesc->CommonField.BitLength);
0942
0943
0944
0945
0946
0947
0948 if (BufferLength < RequiredLength)
0949 {
0950
0951
0952 NewBuffer = ACPI_ALLOCATE_ZEROED (RequiredLength);
0953 if (!NewBuffer)
0954 {
0955 return_ACPI_STATUS (AE_NO_MEMORY);
0956 }
0957
0958
0959
0960
0961
0962
0963 ACPI_MEMCPY ((char *) NewBuffer, (char *) Buffer, BufferLength);
0964 Buffer = NewBuffer;
0965 BufferLength = RequiredLength;
0966 }
0967
0968
0969
0970
0971
0972
0973 if (ObjDesc->CommonField.AccessBitWidth == ACPI_INTEGER_BIT_SIZE)
0974 {
0975 WidthMask = ACPI_INTEGER_MAX;
0976 }
0977 else
0978 {
0979 WidthMask = ACPI_MASK_BITS_ABOVE (ObjDesc->CommonField.AccessBitWidth);
0980 }
0981
0982 Mask = WidthMask &
0983 ACPI_MASK_BITS_BELOW (ObjDesc->CommonField.StartFieldBitOffset);
0984
0985
0986
0987 DatumCount = ACPI_ROUND_UP_TO (ObjDesc->CommonField.BitLength,
0988 ObjDesc->CommonField.AccessBitWidth);
0989
0990 FieldDatumCount = ACPI_ROUND_UP_TO (ObjDesc->CommonField.BitLength +
0991 ObjDesc->CommonField.StartFieldBitOffset,
0992 ObjDesc->CommonField.AccessBitWidth);
0993
0994
0995
0996 ACPI_MEMCPY (&RawDatum, Buffer,
0997 ACPI_MIN(ObjDesc->CommonField.AccessByteWidth,
0998 BufferLength - BufferOffset));
0999
1000 MergedDatum = RawDatum << ObjDesc->CommonField.StartFieldBitOffset;
1001
1002
1003
1004 for (i = 1; i < FieldDatumCount; i++)
1005 {
1006
1007
1008 MergedDatum &= Mask;
1009 Status = AcpiExWriteWithUpdateRule (ObjDesc, Mask,
1010 MergedDatum, FieldOffset);
1011 if (ACPI_FAILURE (Status))
1012 {
1013 goto Exit;
1014 }
1015
1016 FieldOffset += ObjDesc->CommonField.AccessByteWidth;
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027 if ((ObjDesc->CommonField.AccessBitWidth -
1028 ObjDesc->CommonField.StartFieldBitOffset) < ACPI_INTEGER_BIT_SIZE)
1029 {
1030 MergedDatum = RawDatum >>
1031 (ObjDesc->CommonField.AccessBitWidth -
1032 ObjDesc->CommonField.StartFieldBitOffset);
1033 }
1034 else
1035 {
1036 MergedDatum = 0;
1037 }
1038
1039 Mask = WidthMask;
1040
1041 if (i == DatumCount)
1042 {
1043 break;
1044 }
1045
1046
1047
1048 BufferOffset += ObjDesc->CommonField.AccessByteWidth;
1049 ACPI_MEMCPY (&RawDatum, ((char *) Buffer) + BufferOffset,
1050 ACPI_MIN(ObjDesc->CommonField.AccessByteWidth,
1051 BufferLength - BufferOffset));
1052 MergedDatum |= RawDatum << ObjDesc->CommonField.StartFieldBitOffset;
1053 }
1054
1055
1056
1057 BufferTailBits = (ObjDesc->CommonField.BitLength +
1058 ObjDesc->CommonField.StartFieldBitOffset) %
1059 ObjDesc->CommonField.AccessBitWidth;
1060 if (BufferTailBits)
1061 {
1062 Mask &= ACPI_MASK_BITS_ABOVE (BufferTailBits);
1063 }
1064
1065
1066
1067 MergedDatum &= Mask;
1068 Status = AcpiExWriteWithUpdateRule (ObjDesc,
1069 Mask, MergedDatum, FieldOffset);
1070
1071 Exit:
1072
1073
1074 if (NewBuffer)
1075 {
1076 ACPI_FREE (NewBuffer);
1077 }
1078 return_ACPI_STATUS (Status);
1079 }
1080
1081