1 /** @file
2 Implementation of SmBusLib class library for PEI phase.
3 
4 Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution.  The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9 
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 
13 
14 **/
15 
16 #include "InternalSmbusLib.h"
17 
18 /**
19   Executes an SMBUS quick read command.
20 
21   Executes an SMBUS quick read command on the SMBUS device specified by SmBusAddress.
22   Only the SMBUS slave address field of SmBusAddress is required.
23   If Status is not NULL, then the status of the executed command is returned in Status.
24   If PEC is set in SmBusAddress, then ASSERT().
25   If Command in SmBusAddress is not zero, then ASSERT().
26   If Length in SmBusAddress is not zero, then ASSERT().
27   If any reserved bits of SmBusAddress are set, then ASSERT().
28 
29   @param  SmBusAddress  The address that encodes the SMBUS Slave Address,
30                         SMBUS Command, SMBUS Data Length, and PEC.
31   @param  Status        Return status for the executed command.
32                         This is an optional parameter and may be NULL.
33                         RETURN_SUCCESS:  The SMBUS command was executed.
34                         RETURN_TIMEOUT:  A timeout occurred while executing the
35                         SMBUS command.
36                         RETURN_DEVICE_ERROR: The request was not completed because
37                         a failure reflected in the Host Status Register bit.
38                         Device errors are a result of a transaction collision,
39                         illegal command field, unclaimed cycle
40                         (host initiated), or bus errors (collisions).
41                         RETURN_UNSUPPORTED:  The SMBus operation is not supported.
42 
43 **/
44 VOID
45 EFIAPI
SmBusQuickRead(IN UINTN SmBusAddress,OUT RETURN_STATUS * Status OPTIONAL)46 SmBusQuickRead (
47   IN  UINTN                     SmBusAddress,
48   OUT RETURN_STATUS             *Status       OPTIONAL
49   )
50 {
51   ASSERT (!SMBUS_LIB_PEC (SmBusAddress));
52   ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)   == 0);
53   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);
54   ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
55 
56   InternalSmBusExec (EfiSmbusQuickRead, SmBusAddress, 0, NULL, Status);
57 }
58 
59 /**
60   Executes an SMBUS quick write command.
61 
62   Executes an SMBUS quick write command on the SMBUS device specified by SmBusAddress.
63   Only the SMBUS slave address field of SmBusAddress is required.
64   If Status is not NULL, then the status of the executed command is returned in Status.
65   If PEC is set in SmBusAddress, then ASSERT().
66   If Command in SmBusAddress is not zero, then ASSERT().
67   If Length in SmBusAddress is not zero, then ASSERT().
68   If any reserved bits of SmBusAddress are set, then ASSERT().
69 
70   @param  SmBusAddress  The address that encodes the SMBUS Slave Address,
71                         SMBUS Command, SMBUS Data Length, and PEC.
72   @param  Status        Return status for the executed command.
73                         This is an optional parameter and may be NULL.
74                         RETURN_SUCCESS: The SMBUS command was executed.
75                         RETURN_TIMEOUT: A timeout occurred while executing the
76                         SMBUS command.
77                         RETURN_DEVICE_ERROR:  The request was not completed because
78                         a failure reflected in the Host Status Register bit.  Device
79                         errors are a result of a transaction collision, illegal
80                         command field, unclaimed cycle (host initiated), or bus
81                         errors (collisions).
82                         RETURN_UNSUPPORTED::  The SMBus operation is not supported.
83 
84 **/
85 VOID
86 EFIAPI
SmBusQuickWrite(IN UINTN SmBusAddress,OUT RETURN_STATUS * Status OPTIONAL)87 SmBusQuickWrite (
88   IN  UINTN                     SmBusAddress,
89   OUT RETURN_STATUS             *Status       OPTIONAL
90   )
91 {
92   ASSERT (!SMBUS_LIB_PEC (SmBusAddress));
93   ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)   == 0);
94   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);
95   ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
96 
97   InternalSmBusExec (EfiSmbusQuickWrite, SmBusAddress, 0, NULL, Status);
98 }
99 
100 /**
101   Executes an SMBUS receive byte command.
102 
103   Executes an SMBUS receive byte command on the SMBUS device specified by SmBusAddress.
104   Only the SMBUS slave address field of SmBusAddress is required.
105   The byte received from the SMBUS is returned.
106   If Status is not NULL, then the status of the executed command is returned in Status.
107   If Command in SmBusAddress is not zero, then ASSERT().
108   If Length in SmBusAddress is not zero, then ASSERT().
109   If any reserved bits of SmBusAddress are set, then ASSERT().
110 
111   @param  SmBusAddress  The address that encodes the SMBUS Slave Address,
112                         SMBUS Command, SMBUS Data Length, and PEC.
113   @param  Status        Return status for the executed command.
114                         This is an optional parameter and may be NULL.
115                         RETURN_SUCCESS: The SMBUS command was executed.
116                         RETURN_TIMEOUT: A timeout occurred while executing the
117                         SMBUS command.
118                         RETURN_DEVICE_ERROR:  The request was not completed because
119                         a failure reflected in the Host Status Register bit.
120                         Device errors are a result of a transaction collision,
121                         illegal command field, unclaimed cycle (host initiated),
122                         or bus errors (collisions).
123                         RETURN_CRC_ERROR:  The checksum is not correct. (PEC is incorrect.)
124                         RETURN_UNSUPPORTED:  The SMBus operation is not supported.
125 
126   @return The byte received from the SMBUS.
127 
128 **/
129 UINT8
130 EFIAPI
SmBusReceiveByte(IN UINTN SmBusAddress,OUT RETURN_STATUS * Status OPTIONAL)131 SmBusReceiveByte (
132   IN  UINTN          SmBusAddress,
133   OUT RETURN_STATUS  *Status        OPTIONAL
134   )
135 {
136   UINT8   Byte;
137 
138   ASSERT (SMBUS_LIB_COMMAND (SmBusAddress) == 0);
139   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)  == 0);
140   ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
141 
142   InternalSmBusExec (EfiSmbusReceiveByte, SmBusAddress, 1, &Byte, Status);
143 
144   return Byte;
145 }
146 
147 /**
148   Executes an SMBUS send byte command.
149 
150   Executes an SMBUS send byte command on the SMBUS device specified by SmBusAddress.
151   The byte specified by Value is sent.
152   Only the SMBUS slave address field of SmBusAddress is required.  Value is returned.
153   If Status is not NULL, then the status of the executed command is returned in Status.
154   If Command in SmBusAddress is not zero, then ASSERT().
155   If Length in SmBusAddress is not zero, then ASSERT().
156   If any reserved bits of SmBusAddress are set, then ASSERT().
157 
158   @param  SmBusAddress  The address that encodes the SMBUS Slave Address,
159                         SMBUS Command, SMBUS Data Length, and PEC.
160   @param  Value         The 8-bit value to send.
161   @param  Status        Return status for the executed command.
162                         This is an optional parameter and may be NULL.
163                         RETURN_SUCCESS: The SMBUS command was executed.
164                         RETURN_TIMEOUT: A timeout occurred while executing the
165                         SMBUS command.
166                         RETURN_DEVICE_ERROR:  The request was not completed because
167                         a failure reflected in the Host Status Register bit.  Device
168                         errors are a result of a transaction collision, illegal
169                         command field, unclaimed cycle (host initiated), or bus
170                         errors (collisions).
171                         RETURN_CRC_ERROR:  The checksum is not correct. (PEC is incorrect.)
172                         RETURN_UNSUPPORTED:  The SMBus operation is not supported.
173 
174   @return The parameter of Value.
175 
176 **/
177 UINT8
178 EFIAPI
SmBusSendByte(IN UINTN SmBusAddress,IN UINT8 Value,OUT RETURN_STATUS * Status OPTIONAL)179 SmBusSendByte (
180   IN  UINTN          SmBusAddress,
181   IN  UINT8          Value,
182   OUT RETURN_STATUS  *Status        OPTIONAL
183   )
184 {
185   UINT8   Byte;
186 
187   ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)   == 0);
188   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);
189   ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
190 
191   Byte   = Value;
192   InternalSmBusExec (EfiSmbusSendByte, SmBusAddress, 1, &Byte, Status);
193 
194   return Value;
195 }
196 
197 /**
198   Executes an SMBUS read data byte command.
199 
200   Executes an SMBUS read data byte command on the SMBUS device specified by SmBusAddress.
201   Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
202   The 8-bit value read from the SMBUS is returned.
203   If Status is not NULL, then the status of the executed command is returned in Status.
204   If Length in SmBusAddress is not zero, then ASSERT().
205   If any reserved bits of SmBusAddress are set, then ASSERT().
206 
207   @param  SmBusAddress    The address that encodes the SMBUS Slave Address,
208                           SMBUS Command, SMBUS Data Length, and PEC.
209   @param  Status        Return status for the executed command.
210                         This is an optional parameter and may be NULL.
211                         RETURN_SUCCESS: The SMBUS command was executed.
212                         RETURN_TIMEOUT: A timeout occurred while executing the
213                         SMBUS command.
214                         RETURN_DEVICE_ERROR:  The request was not completed because
215                         a failure reflected in the Host Status Register bit.
216                         Device errors are a result of a transaction collision,
217                         illegal command field, unclaimed cycle (host initiated),
218                        or bus errors (collisions).
219                         RETURN_CRC_ERROR:  The checksum is not correct. (PEC is incorrect.)
220                         RETURN_UNSUPPORTED:  The SMBus operation is not supported.
221 
222   @return The byte read from the SMBUS.
223 
224 **/
225 UINT8
226 EFIAPI
SmBusReadDataByte(IN UINTN SmBusAddress,OUT RETURN_STATUS * Status OPTIONAL)227 SmBusReadDataByte (
228   IN  UINTN          SmBusAddress,
229   OUT RETURN_STATUS  *Status        OPTIONAL
230   )
231 {
232   UINT8   Byte;
233 
234   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);
235   ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
236 
237   InternalSmBusExec (EfiSmbusReadByte, SmBusAddress, 1, &Byte, Status);
238 
239   return Byte;
240 }
241 
242 /**
243   Executes an SMBUS write data byte command.
244 
245   Executes an SMBUS write data byte command on the SMBUS device specified by SmBusAddress.
246   The 8-bit value specified by Value is written.
247   Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
248   Value is returned.
249   If Status is not NULL, then the status of the executed command is returned in Status.
250   If Length in SmBusAddress is not zero, then ASSERT().
251   If any reserved bits of SmBusAddress are set, then ASSERT().
252 
253   @param  SmBusAddress  The address that encodes the SMBUS Slave Address,
254                         SMBUS Command, SMBUS Data Length, and PEC.
255   @param  Value         The 8-bit value to write.
256   @param  Status        Return status for the executed command.
257                         This is an optional parameter and may be NULL.
258                         RETURN_SUCCESS: The SMBUS command was executed.
259                         RETURN_TIMEOUT: A timeout occurred while executing the
260                         SMBUS command.
261                         RETURN_DEVICE_ERROR:  The request was not completed because
262                         a failure reflected in the Host Status Register bit.
263                         Device errors are a result of a transaction collision,
264                         illegal command field, unclaimed cycle (host initiated),
265                         or bus errors (collisions).
266                         RETURN_CRC_ERROR:  The checksum is not correct. (PEC is incorrect.)
267                         RETURN_UNSUPPORTED:  The SMBus operation is not supported.
268 
269   @return The parameter of Value.
270 
271 **/
272 UINT8
273 EFIAPI
SmBusWriteDataByte(IN UINTN SmBusAddress,IN UINT8 Value,OUT RETURN_STATUS * Status OPTIONAL)274 SmBusWriteDataByte (
275   IN  UINTN          SmBusAddress,
276   IN  UINT8          Value,
277   OUT RETURN_STATUS  *Status        OPTIONAL
278   )
279 {
280   UINT8   Byte;
281 
282   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);
283   ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
284 
285   Byte = Value;
286   InternalSmBusExec (EfiSmbusWriteByte, SmBusAddress, 1, &Byte, Status);
287 
288   return Value;
289 }
290 
291 /**
292   Executes an SMBUS read data word command.
293 
294   Executes an SMBUS read data word command on the SMBUS device specified by SmBusAddress.
295   Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
296   The 16-bit value read from the SMBUS is returned.
297   If Status is not NULL, then the status of the executed command is returned in Status.
298   If Length in SmBusAddress is not zero, then ASSERT().
299   If any reserved bits of SmBusAddress are set, then ASSERT().
300 
301   @param  SmBusAddress  The address that encodes the SMBUS Slave Address,
302                         SMBUS Command, SMBUS Data Length, and PEC.
303   @param  Status        Return status for the executed command.
304                         This is an optional parameter and may be NULL.
305                         RETURN_SUCCESS: The SMBUS command was executed.
306                         RETURN_TIMEOUT: A timeout occurred while executing the
307                         SMBUS command.
308                         RETURN_DEVICE_ERROR:  The request was not completed because
309                         a failure reflected in the Host Status Register bit.
310                         Device errors are a result of a transaction collision,
311                         illegal command field, unclaimed cycle (host initiated),
312                         or bus errors (collisions).
313                         RETURN_CRC_ERROR:  The checksum is not correct. (PEC is incorrect.)
314                         RETURN_UNSUPPORTED:  The SMBus operation is not supported.
315 
316   @return The byte read from the SMBUS.
317 
318 **/
319 UINT16
320 EFIAPI
SmBusReadDataWord(IN UINTN SmBusAddress,OUT RETURN_STATUS * Status OPTIONAL)321 SmBusReadDataWord (
322   IN  UINTN          SmBusAddress,
323   OUT RETURN_STATUS  *Status        OPTIONAL
324   )
325 {
326   UINT16  Word;
327 
328   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);
329   ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
330 
331   InternalSmBusExec (EfiSmbusReadWord, SmBusAddress, 2, &Word, Status);
332 
333   return Word;
334 }
335 
336 /**
337   Executes an SMBUS write data word command.
338 
339   Executes an SMBUS write data word command on the SMBUS device specified by SmBusAddress.
340   The 16-bit value specified by Value is written.
341   Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
342   Value is returned.
343   If Status is not NULL, then the status of the executed command is returned in Status.
344   If Length in SmBusAddress is not zero, then ASSERT().
345   If any reserved bits of SmBusAddress are set, then ASSERT().
346 
347   @param  SmBusAddress  The address that encodes the SMBUS Slave Address,
348                         SMBUS Command, SMBUS Data Length, and PEC.
349   @param  Value         The 16-bit value to write.
350   @param  Status        Return status for the executed command.
351                         This is an optional parameter and may be NULL.
352                         RETURN_SUCCESS: The SMBUS command was executed.
353                         RETURN_TIMEOUT: A timeout occurred while executing the
354                         SMBUS command.
355                         RETURN_DEVICE_ERROR:  The request was not completed because
356                         a failure reflected in the Host Status Register bit.
357                         Device errors are a result of a transaction collision,
358                         illegal command field, unclaimed cycle (host initiated),
359                         or bus errors (collisions).
360                         RETURN_CRC_ERROR:  The checksum is not correct. (PEC is incorrect.)
361                         RETURN_UNSUPPORTED:  The SMBus operation is not supported.
362 
363   @return The parameter of Value.
364 
365 **/
366 UINT16
367 EFIAPI
SmBusWriteDataWord(IN UINTN SmBusAddress,IN UINT16 Value,OUT RETURN_STATUS * Status OPTIONAL)368 SmBusWriteDataWord (
369   IN  UINTN          SmBusAddress,
370   IN  UINT16         Value,
371   OUT RETURN_STATUS  *Status        OPTIONAL
372   )
373 {
374   UINT16  Word;
375 
376   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);
377   ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
378 
379   Word = Value;
380   InternalSmBusExec (EfiSmbusWriteWord, SmBusAddress, 2, &Word, Status);
381 
382   return Value;
383 }
384 
385 /**
386   Executes an SMBUS process call command.
387 
388   Executes an SMBUS process call command on the SMBUS device specified by SmBusAddress.
389   The 16-bit value specified by Value is written.
390   Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
391   The 16-bit value returned by the process call command is returned.
392   If Status is not NULL, then the status of the executed command is returned in Status.
393   If Length in SmBusAddress is not zero, then ASSERT().
394   If any reserved bits of SmBusAddress are set, then ASSERT().
395 
396   @param  SmBusAddress  The address that encodes the SMBUS Slave Address,
397                         SMBUS Command, SMBUS Data Length, and PEC.
398   @param  Value         The 16-bit value to write.
399   @param  Status        Return status for the executed command.
400                         This is an optional parameter and may be NULL.
401                         RETURN_SUCCESS: The SMBUS command was executed.
402                         RETURN_TIMEOUT: A timeout occurred while executing the
403                         SMBUS command.
404                         RETURN_DEVICE_ERROR:  The request was not completed because
405                         a failure reflected in the Host Status Register bit.
406                         Device errors are a result of a transaction collision,
407                         illegal command field, unclaimed cycle (host initiated),
408                         or bus errors (collisions).
409                         RETURN_CRC_ERROR:  The checksum is not correct. (PEC is incorrect.)
410                         RETURN_UNSUPPORTED:  The SMBus operation is not supported.
411 
412   @return The 16-bit value returned by the process call command.
413 
414 **/
415 UINT16
416 EFIAPI
SmBusProcessCall(IN UINTN SmBusAddress,IN UINT16 Value,OUT RETURN_STATUS * Status OPTIONAL)417 SmBusProcessCall (
418   IN  UINTN          SmBusAddress,
419   IN  UINT16         Value,
420   OUT RETURN_STATUS  *Status        OPTIONAL
421   )
422 {
423   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);
424   ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
425 
426   InternalSmBusExec (EfiSmbusProcessCall, SmBusAddress, 2, &Value, Status);
427 
428   return Value;
429 }
430 
431 /**
432   Executes an SMBUS read block command.
433 
434   Executes an SMBUS read block command on the SMBUS device specified by SmBusAddress.
435   Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
436   Bytes are read from the SMBUS and stored in Buffer.
437   The number of bytes read is returned, and will never return a value larger than 32-bytes.
438   If Status is not NULL, then the status of the executed command is returned in Status.
439   It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
440   SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.
441   If Length in SmBusAddress is not zero, then ASSERT().
442   If Buffer is NULL, then ASSERT().
443   If any reserved bits of SmBusAddress are set, then ASSERT().
444 
445   @param  SmBusAddress  The address that encodes the SMBUS Slave Address,
446                         SMBUS Command, SMBUS Data Length, and PEC.
447   @param  Buffer        The pointer to the buffer to store the bytes read from the SMBUS.
448   @param  Status        Return status for the executed command.
449                         This is an optional parameter and may be NULL.
450                         RETURN_SUCCESS: The SMBUS command was executed.
451                         RETURN_TIMEOUT: A timeout occurred while executing the
452                         SMBUS command.
453                         RETURN_DEVICE_ERROR:  The request was not completed because
454                         a failure reflected in the Host Status Register bit.
455                         Device errors are a result of a transaction collision,
456                         illegal command field, unclaimed cycle (host initiated),
457                         or bus errors (collisions).
458                         RETURN_CRC_ERROR:  The checksum is not correct. (PEC is incorrect.)
459                         RETURN_UNSUPPORTED:  The SMBus operation is not supported.
460 
461   @return The number of bytes read.
462 
463 **/
464 UINTN
465 EFIAPI
SmBusReadBlock(IN UINTN SmBusAddress,OUT VOID * Buffer,OUT RETURN_STATUS * Status OPTIONAL)466 SmBusReadBlock (
467   IN  UINTN          SmBusAddress,
468   OUT VOID           *Buffer,
469   OUT RETURN_STATUS  *Status        OPTIONAL
470   )
471 {
472   ASSERT (Buffer != NULL);
473   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);
474   ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
475 
476   return InternalSmBusExec (EfiSmbusReadBlock, SmBusAddress, 0x20, Buffer, Status);
477 }
478 
479 /**
480   Executes an SMBUS write block command.
481 
482   Executes an SMBUS write block command on the SMBUS device specified by SmBusAddress.
483   The SMBUS slave address, SMBUS command, and SMBUS length fields of SmBusAddress are required.
484   Bytes are written to the SMBUS from Buffer.
485   The number of bytes written is returned, and will never return a value larger than 32-bytes.
486   If Status is not NULL, then the status of the executed command is returned in Status.
487   If Length in SmBusAddress is zero or greater than 32, then ASSERT().
488   If Buffer is NULL, then ASSERT().
489   If any reserved bits of SmBusAddress are set, then ASSERT().
490 
491   @param  SmBusAddress  The address that encodes the SMBUS Slave Address,
492                         MBUS Command, SMBUS Data Length, and PEC.
493   @param  Buffer        The pointer to the buffer to store the bytes read from the SMBUS.
494   @param  Status        Return status for the executed command.
495                         This is an optional parameter and may be NULL.
496                         RETURN_TIMEOUT: A timeout occurred while executing the
497                         SMBUS command.
498                         RETURN_DEVICE_ERROR:  The request was not completed because
499                         a failure reflected in the Host Status Register bit.
500                         Device errors are a result of a transaction collision,
501                         illegal command field, unclaimed cycle (host initiated),
502                         or bus errors (collisions).
503                         RETURN_CRC_ERROR:  The checksum is not correct (PEC is incorrect)
504                         RETURN_UNSUPPORTED:  The SMBus operation is not supported.
505 
506   @return The number of bytes written.
507 
508 **/
509 UINTN
510 EFIAPI
SmBusWriteBlock(IN UINTN SmBusAddress,OUT VOID * Buffer,OUT RETURN_STATUS * Status OPTIONAL)511 SmBusWriteBlock (
512   IN  UINTN          SmBusAddress,
513   OUT VOID           *Buffer,
514   OUT RETURN_STATUS  *Status        OPTIONAL
515   )
516 {
517   UINTN  Length;
518 
519   ASSERT (Buffer != NULL);
520   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) >= 1);
521   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) <= 32);
522   ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
523 
524   Length = SMBUS_LIB_LENGTH (SmBusAddress);
525   return InternalSmBusExec (EfiSmbusWriteBlock, SmBusAddress, Length, Buffer, Status);
526 }
527 
528 /**
529   Executes an SMBUS block process call command.
530 
531   Executes an SMBUS block process call command on the SMBUS device specified by SmBusAddress.
532   The SMBUS slave address, SMBUS command, and SMBUS length fields of SmBusAddress are required.
533   Bytes are written to the SMBUS from WriteBuffer.  Bytes are then read from the SMBUS into ReadBuffer.
534   If Status is not NULL, then the status of the executed command is returned in Status.
535   It is the caller's responsibility to make sure ReadBuffer is large enough for the total number of bytes read.
536   SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.
537   If Length in SmBusAddress is zero or greater than 32, then ASSERT().
538   If WriteBuffer is NULL, then ASSERT().
539   If ReadBuffer is NULL, then ASSERT().
540   If any reserved bits of SmBusAddress are set, then ASSERT().
541 
542   @param  SmBusAddress  The address that encodes the SMBUS Slave Address,
543                         SMBUS Command, SMBUS Data Length, and PEC.
544   @param  WriteBuffer   The pointer to the buffer of bytes to write to the SMBUS.
545   @param  ReadBuffer    The pointer to the buffer of bytes to read from the SMBUS.
546   @param  Status        Return status for the executed command.
547                         This is an optional parameter and may be NULL.
548                         RETURN_TIMEOUT: A timeout occurred while executing the
549                         SMBUS command.
550                         RETURN_DEVICE_ERROR:  The request was not completed because
551                         a failure reflected in the Host Status Register bit.
552                         Device errors are a result of a transaction collision,
553                         illegal command field, unclaimed cycle (host initiated),
554                         or bus errors (collisions).
555                         RETURN_CRC_ERROR  The checksum is not correct. (PEC is incorrect.)
556                         RETURN_UNSUPPORTED:  The SMBus operation is not supported.
557 
558   @return The number of bytes written.
559 
560 **/
561 UINTN
562 EFIAPI
SmBusBlockProcessCall(IN UINTN SmBusAddress,IN VOID * WriteBuffer,OUT VOID * ReadBuffer,OUT RETURN_STATUS * Status OPTIONAL)563 SmBusBlockProcessCall (
564   IN  UINTN          SmBusAddress,
565   IN  VOID           *WriteBuffer,
566   OUT VOID           *ReadBuffer,
567   OUT RETURN_STATUS  *Status        OPTIONAL
568   )
569 {
570   UINTN   Length;
571 
572   ASSERT (WriteBuffer != NULL);
573   ASSERT (ReadBuffer  != NULL);
574   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) >= 1);
575   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) <= 32);
576   ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
577 
578   Length = SMBUS_LIB_LENGTH (SmBusAddress);
579   //
580   // Assuming that ReadBuffer is large enough to save another memory copy.
581   //
582   ReadBuffer = CopyMem (ReadBuffer, WriteBuffer, Length);
583   return InternalSmBusExec (EfiSmbusBWBRProcessCall, SmBusAddress, Length, ReadBuffer, Status);
584 }
585