1 | /****************************************************************************** |
2 | * |
3 | * Module Name: exfield - ACPI AML (p-code) execution - field manipulation |
4 | * |
5 | *****************************************************************************/ |
6 | |
7 | /* |
8 | * Copyright (C) 2000 - 2016, 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. |
29 | * |
30 | * NO WARRANTY |
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR |
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
41 | * POSSIBILITY OF SUCH DAMAGES. |
42 | */ |
43 | |
44 | #include "acpi.h" |
45 | #include "accommon.h" |
46 | #include "acdispat.h" |
47 | #include "acinterp.h" |
48 | #include "amlcode.h" |
49 | |
50 | |
51 | #define _COMPONENT ACPI_EXECUTER |
52 | ACPI_MODULE_NAME ("exfield" ) |
53 | |
54 | /* Local prototypes */ |
55 | |
56 | static UINT32 |
57 | AcpiExGetSerialAccessLength ( |
58 | UINT32 AccessorType, |
59 | UINT32 AccessLength); |
60 | |
61 | |
62 | /******************************************************************************* |
63 | * |
64 | * FUNCTION: AcpiExGetSerialAccessLength |
65 | * |
66 | * PARAMETERS: AccessorType - The type of the protocol indicated by region |
67 | * field access attributes |
68 | * AccessLength - The access length of the region field |
69 | * |
70 | * RETURN: Decoded access length |
71 | * |
72 | * DESCRIPTION: This routine returns the length of the GenericSerialBus |
73 | * protocol bytes |
74 | * |
75 | ******************************************************************************/ |
76 | |
77 | static UINT32 |
78 | AcpiExGetSerialAccessLength ( |
79 | UINT32 AccessorType, |
80 | UINT32 AccessLength) |
81 | { |
82 | UINT32 Length; |
83 | |
84 | |
85 | switch (AccessorType) |
86 | { |
87 | case AML_FIELD_ATTRIB_QUICK: |
88 | |
89 | Length = 0; |
90 | break; |
91 | |
92 | case AML_FIELD_ATTRIB_SEND_RCV: |
93 | case AML_FIELD_ATTRIB_BYTE: |
94 | |
95 | Length = 1; |
96 | break; |
97 | |
98 | case AML_FIELD_ATTRIB_WORD: |
99 | case AML_FIELD_ATTRIB_WORD_CALL: |
100 | |
101 | Length = 2; |
102 | break; |
103 | |
104 | case AML_FIELD_ATTRIB_MULTIBYTE: |
105 | case AML_FIELD_ATTRIB_RAW_BYTES: |
106 | case AML_FIELD_ATTRIB_RAW_PROCESS: |
107 | |
108 | Length = AccessLength; |
109 | break; |
110 | |
111 | case AML_FIELD_ATTRIB_BLOCK: |
112 | case AML_FIELD_ATTRIB_BLOCK_CALL: |
113 | default: |
114 | |
115 | Length = ACPI_GSBUS_BUFFER_SIZE - 2; |
116 | break; |
117 | } |
118 | |
119 | return (Length); |
120 | } |
121 | |
122 | |
123 | /******************************************************************************* |
124 | * |
125 | * FUNCTION: AcpiExReadDataFromField |
126 | * |
127 | * PARAMETERS: WalkState - Current execution state |
128 | * ObjDesc - The named field |
129 | * RetBufferDesc - Where the return data object is stored |
130 | * |
131 | * RETURN: Status |
132 | * |
133 | * DESCRIPTION: Read from a named field. Returns either an Integer or a |
134 | * Buffer, depending on the size of the field. |
135 | * |
136 | ******************************************************************************/ |
137 | |
138 | ACPI_STATUS |
139 | AcpiExReadDataFromField ( |
140 | ACPI_WALK_STATE *WalkState, |
141 | ACPI_OPERAND_OBJECT *ObjDesc, |
142 | ACPI_OPERAND_OBJECT **RetBufferDesc) |
143 | { |
144 | ACPI_STATUS Status; |
145 | ACPI_OPERAND_OBJECT *BufferDesc; |
146 | ACPI_SIZE Length; |
147 | void *Buffer; |
148 | UINT32 Function; |
149 | UINT16 AccessorType; |
150 | |
151 | |
152 | ACPI_FUNCTION_TRACE_PTR (ExReadDataFromField, ObjDesc); |
153 | |
154 | |
155 | /* Parameter validation */ |
156 | |
157 | if (!ObjDesc) |
158 | { |
159 | return_ACPI_STATUS (AE_AML_NO_OPERAND); |
160 | } |
161 | if (!RetBufferDesc) |
162 | { |
163 | return_ACPI_STATUS (AE_BAD_PARAMETER); |
164 | } |
165 | |
166 | if (ObjDesc->Common.Type == ACPI_TYPE_BUFFER_FIELD) |
167 | { |
168 | /* |
169 | * If the BufferField arguments have not been previously evaluated, |
170 | * evaluate them now and save the results. |
171 | */ |
172 | if (!(ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)) |
173 | { |
174 | Status = AcpiDsGetBufferFieldArguments (ObjDesc); |
175 | if (ACPI_FAILURE (Status)) |
176 | { |
177 | return_ACPI_STATUS (Status); |
178 | } |
179 | } |
180 | } |
181 | else if ((ObjDesc->Common.Type == ACPI_TYPE_LOCAL_REGION_FIELD) && |
182 | (ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_SMBUS || |
183 | ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GSBUS || |
184 | ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_IPMI)) |
185 | { |
186 | /* |
187 | * This is an SMBus, GSBus or IPMI read. We must create a buffer to |
188 | * hold the data and then directly access the region handler. |
189 | * |
190 | * Note: SMBus and GSBus protocol value is passed in upper 16-bits |
191 | * of Function |
192 | */ |
193 | if (ObjDesc->Field.RegionObj->Region.SpaceId == |
194 | ACPI_ADR_SPACE_SMBUS) |
195 | { |
196 | Length = ACPI_SMBUS_BUFFER_SIZE; |
197 | Function = ACPI_READ | (ObjDesc->Field.Attribute << 16); |
198 | } |
199 | else if (ObjDesc->Field.RegionObj->Region.SpaceId == |
200 | ACPI_ADR_SPACE_GSBUS) |
201 | { |
202 | AccessorType = ObjDesc->Field.Attribute; |
203 | Length = AcpiExGetSerialAccessLength ( |
204 | AccessorType, ObjDesc->Field.AccessLength); |
205 | |
206 | /* |
207 | * Add additional 2 bytes for the GenericSerialBus data buffer: |
208 | * |
209 | * Status; (Byte 0 of the data buffer) |
210 | * Length; (Byte 1 of the data buffer) |
211 | * Data[x-1]: (Bytes 2-x of the arbitrary length data buffer) |
212 | */ |
213 | Length += 2; |
214 | Function = ACPI_READ | (AccessorType << 16); |
215 | } |
216 | else /* IPMI */ |
217 | { |
218 | Length = ACPI_IPMI_BUFFER_SIZE; |
219 | Function = ACPI_READ; |
220 | } |
221 | |
222 | BufferDesc = AcpiUtCreateBufferObject (Length); |
223 | if (!BufferDesc) |
224 | { |
225 | return_ACPI_STATUS (AE_NO_MEMORY); |
226 | } |
227 | |
228 | /* Lock entire transaction if requested */ |
229 | |
230 | AcpiExAcquireGlobalLock (ObjDesc->CommonField.FieldFlags); |
231 | |
232 | /* Call the region handler for the read */ |
233 | |
234 | Status = AcpiExAccessRegion (ObjDesc, 0, |
235 | ACPI_CAST_PTR (UINT64, BufferDesc->Buffer.Pointer), Function); |
236 | |
237 | AcpiExReleaseGlobalLock (ObjDesc->CommonField.FieldFlags); |
238 | goto Exit; |
239 | } |
240 | |
241 | /* |
242 | * Allocate a buffer for the contents of the field. |
243 | * |
244 | * If the field is larger than the current integer width, create |
245 | * a BUFFER to hold it. Otherwise, use an INTEGER. This allows |
246 | * the use of arithmetic operators on the returned value if the |
247 | * field size is equal or smaller than an Integer. |
248 | * |
249 | * Note: Field.length is in bits. |
250 | */ |
251 | Length = (ACPI_SIZE) ACPI_ROUND_BITS_UP_TO_BYTES ( |
252 | ObjDesc->Field.BitLength); |
253 | |
254 | if (Length > AcpiGbl_IntegerByteWidth) |
255 | { |
256 | /* Field is too large for an Integer, create a Buffer instead */ |
257 | |
258 | BufferDesc = AcpiUtCreateBufferObject (Length); |
259 | if (!BufferDesc) |
260 | { |
261 | return_ACPI_STATUS (AE_NO_MEMORY); |
262 | } |
263 | Buffer = BufferDesc->Buffer.Pointer; |
264 | } |
265 | else |
266 | { |
267 | /* Field will fit within an Integer (normal case) */ |
268 | |
269 | BufferDesc = AcpiUtCreateIntegerObject ((UINT64) 0); |
270 | if (!BufferDesc) |
271 | { |
272 | return_ACPI_STATUS (AE_NO_MEMORY); |
273 | } |
274 | |
275 | Length = AcpiGbl_IntegerByteWidth; |
276 | Buffer = &BufferDesc->Integer.Value; |
277 | } |
278 | |
279 | if ((ObjDesc->Common.Type == ACPI_TYPE_LOCAL_REGION_FIELD) && |
280 | (ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GPIO)) |
281 | { |
282 | /* |
283 | * For GPIO (GeneralPurposeIo), the Address will be the bit offset |
284 | * from the previous Connection() operator, making it effectively a |
285 | * pin number index. The BitLength is the length of the field, which |
286 | * is thus the number of pins. |
287 | */ |
288 | ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, |
289 | "GPIO FieldRead [FROM]: Pin %u Bits %u\n" , |
290 | ObjDesc->Field.PinNumberIndex, ObjDesc->Field.BitLength)); |
291 | |
292 | /* Lock entire transaction if requested */ |
293 | |
294 | AcpiExAcquireGlobalLock (ObjDesc->CommonField.FieldFlags); |
295 | |
296 | /* Perform the write */ |
297 | |
298 | Status = AcpiExAccessRegion ( |
299 | ObjDesc, 0, (UINT64 *) Buffer, ACPI_READ); |
300 | |
301 | AcpiExReleaseGlobalLock (ObjDesc->CommonField.FieldFlags); |
302 | if (ACPI_FAILURE (Status)) |
303 | { |
304 | AcpiUtRemoveReference (BufferDesc); |
305 | } |
306 | else |
307 | { |
308 | *RetBufferDesc = BufferDesc; |
309 | } |
310 | return_ACPI_STATUS (Status); |
311 | } |
312 | |
313 | ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, |
314 | "FieldRead [TO]: Obj %p, Type %X, Buf %p, ByteLen %X\n" , |
315 | ObjDesc, ObjDesc->Common.Type, Buffer, (UINT32) Length)); |
316 | ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, |
317 | "FieldRead [FROM]: BitLen %X, BitOff %X, ByteOff %X\n" , |
318 | ObjDesc->CommonField.BitLength, |
319 | ObjDesc->CommonField.StartFieldBitOffset, |
320 | ObjDesc->CommonField.BaseByteOffset)); |
321 | |
322 | /* Lock entire transaction if requested */ |
323 | |
324 | AcpiExAcquireGlobalLock (ObjDesc->CommonField.FieldFlags); |
325 | |
326 | /* Read from the field */ |
327 | |
328 | Status = AcpiExExtractFromField (ObjDesc, Buffer, (UINT32) Length); |
329 | AcpiExReleaseGlobalLock (ObjDesc->CommonField.FieldFlags); |
330 | |
331 | |
332 | Exit: |
333 | if (ACPI_FAILURE (Status)) |
334 | { |
335 | AcpiUtRemoveReference (BufferDesc); |
336 | } |
337 | else |
338 | { |
339 | *RetBufferDesc = BufferDesc; |
340 | } |
341 | |
342 | return_ACPI_STATUS (Status); |
343 | } |
344 | |
345 | |
346 | /******************************************************************************* |
347 | * |
348 | * FUNCTION: AcpiExWriteDataToField |
349 | * |
350 | * PARAMETERS: SourceDesc - Contains data to write |
351 | * ObjDesc - The named field |
352 | * ResultDesc - Where the return value is returned, if any |
353 | * |
354 | * RETURN: Status |
355 | * |
356 | * DESCRIPTION: Write to a named field |
357 | * |
358 | ******************************************************************************/ |
359 | |
360 | ACPI_STATUS |
361 | AcpiExWriteDataToField ( |
362 | ACPI_OPERAND_OBJECT *SourceDesc, |
363 | ACPI_OPERAND_OBJECT *ObjDesc, |
364 | ACPI_OPERAND_OBJECT **ResultDesc) |
365 | { |
366 | ACPI_STATUS Status; |
367 | UINT32 Length; |
368 | void *Buffer; |
369 | ACPI_OPERAND_OBJECT *BufferDesc; |
370 | UINT32 Function; |
371 | UINT16 AccessorType; |
372 | |
373 | |
374 | ACPI_FUNCTION_TRACE_PTR (ExWriteDataToField, ObjDesc); |
375 | |
376 | |
377 | /* Parameter validation */ |
378 | |
379 | if (!SourceDesc || !ObjDesc) |
380 | { |
381 | return_ACPI_STATUS (AE_AML_NO_OPERAND); |
382 | } |
383 | |
384 | if (ObjDesc->Common.Type == ACPI_TYPE_BUFFER_FIELD) |
385 | { |
386 | /* |
387 | * If the BufferField arguments have not been previously evaluated, |
388 | * evaluate them now and save the results. |
389 | */ |
390 | if (!(ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)) |
391 | { |
392 | Status = AcpiDsGetBufferFieldArguments (ObjDesc); |
393 | if (ACPI_FAILURE (Status)) |
394 | { |
395 | return_ACPI_STATUS (Status); |
396 | } |
397 | } |
398 | } |
399 | else if ((ObjDesc->Common.Type == ACPI_TYPE_LOCAL_REGION_FIELD) && |
400 | (ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_SMBUS || |
401 | ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GSBUS || |
402 | ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_IPMI)) |
403 | { |
404 | /* |
405 | * This is an SMBus, GSBus or IPMI write. We will bypass the entire |
406 | * field mechanism and handoff the buffer directly to the handler. |
407 | * For these address spaces, the buffer is bi-directional; on a |
408 | * write, return data is returned in the same buffer. |
409 | * |
410 | * Source must be a buffer of sufficient size: |
411 | * ACPI_SMBUS_BUFFER_SIZE, ACPI_GSBUS_BUFFER_SIZE, or |
412 | * ACPI_IPMI_BUFFER_SIZE. |
413 | * |
414 | * Note: SMBus and GSBus protocol type is passed in upper 16-bits |
415 | * of Function |
416 | */ |
417 | if (SourceDesc->Common.Type != ACPI_TYPE_BUFFER) |
418 | { |
419 | ACPI_ERROR ((AE_INFO, |
420 | "SMBus/IPMI/GenericSerialBus write requires " |
421 | "Buffer, found type %s" , |
422 | AcpiUtGetObjectTypeName (SourceDesc))); |
423 | |
424 | return_ACPI_STATUS (AE_AML_OPERAND_TYPE); |
425 | } |
426 | |
427 | if (ObjDesc->Field.RegionObj->Region.SpaceId == |
428 | ACPI_ADR_SPACE_SMBUS) |
429 | { |
430 | Length = ACPI_SMBUS_BUFFER_SIZE; |
431 | Function = ACPI_WRITE | (ObjDesc->Field.Attribute << 16); |
432 | } |
433 | else if (ObjDesc->Field.RegionObj->Region.SpaceId == |
434 | ACPI_ADR_SPACE_GSBUS) |
435 | { |
436 | AccessorType = ObjDesc->Field.Attribute; |
437 | Length = AcpiExGetSerialAccessLength ( |
438 | AccessorType, ObjDesc->Field.AccessLength); |
439 | |
440 | /* |
441 | * Add additional 2 bytes for the GenericSerialBus data buffer: |
442 | * |
443 | * Status; (Byte 0 of the data buffer) |
444 | * Length; (Byte 1 of the data buffer) |
445 | * Data[x-1]: (Bytes 2-x of the arbitrary length data buffer) |
446 | */ |
447 | Length += 2; |
448 | Function = ACPI_WRITE | (AccessorType << 16); |
449 | } |
450 | else /* IPMI */ |
451 | { |
452 | Length = ACPI_IPMI_BUFFER_SIZE; |
453 | Function = ACPI_WRITE; |
454 | } |
455 | |
456 | if (SourceDesc->Buffer.Length < Length) |
457 | { |
458 | ACPI_ERROR ((AE_INFO, |
459 | "SMBus/IPMI/GenericSerialBus write requires " |
460 | "Buffer of length %u, found length %u" , |
461 | Length, SourceDesc->Buffer.Length)); |
462 | |
463 | return_ACPI_STATUS (AE_AML_BUFFER_LIMIT); |
464 | } |
465 | |
466 | /* Create the bi-directional buffer */ |
467 | |
468 | BufferDesc = AcpiUtCreateBufferObject (Length); |
469 | if (!BufferDesc) |
470 | { |
471 | return_ACPI_STATUS (AE_NO_MEMORY); |
472 | } |
473 | |
474 | Buffer = BufferDesc->Buffer.Pointer; |
475 | memcpy (Buffer, SourceDesc->Buffer.Pointer, Length); |
476 | |
477 | /* Lock entire transaction if requested */ |
478 | |
479 | AcpiExAcquireGlobalLock (ObjDesc->CommonField.FieldFlags); |
480 | |
481 | /* |
482 | * Perform the write (returns status and perhaps data in the |
483 | * same buffer) |
484 | */ |
485 | Status = AcpiExAccessRegion ( |
486 | ObjDesc, 0, (UINT64 *) Buffer, Function); |
487 | AcpiExReleaseGlobalLock (ObjDesc->CommonField.FieldFlags); |
488 | |
489 | *ResultDesc = BufferDesc; |
490 | return_ACPI_STATUS (Status); |
491 | } |
492 | else if ((ObjDesc->Common.Type == ACPI_TYPE_LOCAL_REGION_FIELD) && |
493 | (ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GPIO)) |
494 | { |
495 | /* |
496 | * For GPIO (GeneralPurposeIo), we will bypass the entire field |
497 | * mechanism and handoff the bit address and bit width directly to |
498 | * the handler. The Address will be the bit offset |
499 | * from the previous Connection() operator, making it effectively a |
500 | * pin number index. The BitLength is the length of the field, which |
501 | * is thus the number of pins. |
502 | */ |
503 | if (SourceDesc->Common.Type != ACPI_TYPE_INTEGER) |
504 | { |
505 | return_ACPI_STATUS (AE_AML_OPERAND_TYPE); |
506 | } |
507 | |
508 | ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, |
509 | "GPIO FieldWrite [FROM]: (%s:%X), Val %.8X [TO]: Pin %u Bits %u\n" , |
510 | AcpiUtGetTypeName (SourceDesc->Common.Type), |
511 | SourceDesc->Common.Type, (UINT32) SourceDesc->Integer.Value, |
512 | ObjDesc->Field.PinNumberIndex, ObjDesc->Field.BitLength)); |
513 | |
514 | Buffer = &SourceDesc->Integer.Value; |
515 | |
516 | /* Lock entire transaction if requested */ |
517 | |
518 | AcpiExAcquireGlobalLock (ObjDesc->CommonField.FieldFlags); |
519 | |
520 | /* Perform the write */ |
521 | |
522 | Status = AcpiExAccessRegion ( |
523 | ObjDesc, 0, (UINT64 *) Buffer, ACPI_WRITE); |
524 | AcpiExReleaseGlobalLock (ObjDesc->CommonField.FieldFlags); |
525 | return_ACPI_STATUS (Status); |
526 | } |
527 | |
528 | /* Get a pointer to the data to be written */ |
529 | |
530 | switch (SourceDesc->Common.Type) |
531 | { |
532 | case ACPI_TYPE_INTEGER: |
533 | |
534 | Buffer = &SourceDesc->Integer.Value; |
535 | Length = sizeof (SourceDesc->Integer.Value); |
536 | break; |
537 | |
538 | case ACPI_TYPE_BUFFER: |
539 | |
540 | Buffer = SourceDesc->Buffer.Pointer; |
541 | Length = SourceDesc->Buffer.Length; |
542 | break; |
543 | |
544 | case ACPI_TYPE_STRING: |
545 | |
546 | Buffer = SourceDesc->String.Pointer; |
547 | Length = SourceDesc->String.Length; |
548 | break; |
549 | |
550 | default: |
551 | |
552 | return_ACPI_STATUS (AE_AML_OPERAND_TYPE); |
553 | } |
554 | |
555 | ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, |
556 | "FieldWrite [FROM]: Obj %p (%s:%X), Buf %p, ByteLen %X\n" , |
557 | SourceDesc, AcpiUtGetTypeName (SourceDesc->Common.Type), |
558 | SourceDesc->Common.Type, Buffer, Length)); |
559 | |
560 | ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, |
561 | "FieldWrite [TO]: Obj %p (%s:%X), BitLen %X, BitOff %X, ByteOff %X\n" , |
562 | ObjDesc, AcpiUtGetTypeName (ObjDesc->Common.Type), |
563 | ObjDesc->Common.Type, |
564 | ObjDesc->CommonField.BitLength, |
565 | ObjDesc->CommonField.StartFieldBitOffset, |
566 | ObjDesc->CommonField.BaseByteOffset)); |
567 | |
568 | /* Lock entire transaction if requested */ |
569 | |
570 | AcpiExAcquireGlobalLock (ObjDesc->CommonField.FieldFlags); |
571 | |
572 | /* Write to the field */ |
573 | |
574 | Status = AcpiExInsertIntoField (ObjDesc, Buffer, Length); |
575 | AcpiExReleaseGlobalLock (ObjDesc->CommonField.FieldFlags); |
576 | |
577 | return_ACPI_STATUS (Status); |
578 | } |
579 | |