1 /** @file
2 Implementation of SmBusLib class library for DXE phase.
3 
4 Copyright (c) 2006 - 2010, 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
37                         completed because a failure reflected in the Host Status
38                         Register bit.  Device errors are a result of a transaction
39                         collision, illegal command field, unclaimed cycle (host
40                         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.
79                         Device errors are a result of a transaction collision,
80                         illegal command field, unclaimed cycle (host initiated),
81                         or bus 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.  Device
120                         errors are a result of a transaction collision, illegal
121                         command field, unclaimed cycle(host initiated), or bus
122                         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 failurereflected in the Host Status Register bit.  Device
216                         errors are a result of a transaction collision, illegal
217                         command field, unclaimed cycle (host initiated), or bus
218                         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.  Device
263                         errors are a result of a transaction collision, illegal
264                         command field, unclaimed cycle host initiated), or bus
265                         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
314                         incorrect.)
315                         RETURN_UNSUPPORTED:  The SMBus operation is not supported.
316 
317   @return The byte read from the SMBUS.
318 
319 **/
320 UINT16
321 EFIAPI
SmBusReadDataWord(IN UINTN SmBusAddress,OUT RETURN_STATUS * Status OPTIONAL)322 SmBusReadDataWord (
323   IN  UINTN          SmBusAddress,
324   OUT RETURN_STATUS  *Status        OPTIONAL
325   )
326 {
327   UINT16  Word;
328 
329   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);
330   ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
331 
332   InternalSmBusExec (EfiSmbusReadWord, SmBusAddress, 2, &Word, Status);
333 
334   return Word;
335 }
336 
337 /**
338   Executes an SMBUS write data word command.
339 
340   Executes an SMBUS write data word command on the SMBUS device specified by SmBusAddress.
341   The 16-bit value specified by Value is written.
342   Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
343   Value is returned.
344   If Status is not NULL, then the status of the executed command is returned in Status.
345   If Length in SmBusAddress is not zero, then ASSERT().
346   If any reserved bits of SmBusAddress are set, then ASSERT().
347 
348   @param  SmBusAddress  The address that encodes the SMBUS Slave Address,
349                         SMBUS Command, SMBUS Data Length, and PEC.
350   @param  Value         The 16-bit value to write.
351   @param  Status        Return status for the executed command.
352                         This is an optional parameter and may be NULL.
353                         RETURN_SUCCESS: The SMBUS command was executed.
354                         RETURN_TIMEOUT: A timeout occurred while executing the SMBUS
355                         command.
356                         RETURN_DEVICE_ERROR:  The request was not completed because
357                         a failure reflected in the Host Status Register bit.
358                         Device errors are a result of a transaction collision,
359                         illegal command field, unclaimed cycle (host initiated),
360                         or bus errors (collisions).
361                         RETURN_CRC_ERROR:  The checksum is not correct.
362                         (PEC is incorrect.)
363                         RETURN_UNSUPPORTED:  The SMBus operation is not supported.
364 
365   @return The parameter of Value.
366 
367 **/
368 UINT16
369 EFIAPI
SmBusWriteDataWord(IN UINTN SmBusAddress,IN UINT16 Value,OUT RETURN_STATUS * Status OPTIONAL)370 SmBusWriteDataWord (
371   IN  UINTN          SmBusAddress,
372   IN  UINT16         Value,
373   OUT RETURN_STATUS  *Status        OPTIONAL
374   )
375 {
376   UINT16  Word;
377 
378   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);
379   ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
380 
381   Word = Value;
382   InternalSmBusExec (EfiSmbusWriteWord, SmBusAddress, 2, &Word, Status);
383 
384   return Value;
385 }
386 
387 /**
388   Executes an SMBUS process call command.
389 
390   Executes an SMBUS process call command on the SMBUS device specified by SmBusAddress.
391   The 16-bit value specified by Value is written.
392   Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
393   The 16-bit value returned by the process call command is returned.
394   If Status is not NULL, then the status of the executed command is returned in Status.
395   If Length in SmBusAddress is not zero, then ASSERT().
396   If any reserved bits of SmBusAddress are set, then ASSERT().
397 
398   @param  SmBusAddress  The address that encodes the SMBUS Slave Address,
399                         SMBUS Command, SMBUS Data Length, and PEC.
400   @param  Value         The 16-bit value to write.
401   @param  Status        Return status for the executed command.
402                         This is an optional parameter and may be NULL.
403                         RETURN_SUCCESS: The SMBUS command was executed.
404                         RETURN_TIMEOUT: A timeout occurred while executing the
405                         SMBUS command.
406                         RETURN_DEVICE_ERROR:  The request was not completed because
407                         a failure reflected in the Host Status Register bit.
408                         Device errors are a result of a transaction collision,
409                         illegal command field, unclaimed cycle (host initiated),
410                         or bus errors (collisions).
411                         RETURN_CRC_ERROR:  The checksum is not correct. (PEC is
412                         incorrect.)
413                         RETURN_UNSUPPORTED:  The SMBus operation is not supported.
414 
415   @return The 16-bit value returned by the process call command.
416 
417 **/
418 UINT16
419 EFIAPI
SmBusProcessCall(IN UINTN SmBusAddress,IN UINT16 Value,OUT RETURN_STATUS * Status OPTIONAL)420 SmBusProcessCall (
421   IN  UINTN          SmBusAddress,
422   IN  UINT16         Value,
423   OUT RETURN_STATUS  *Status        OPTIONAL
424   )
425 {
426   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);
427   ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
428 
429   InternalSmBusExec (EfiSmbusProcessCall, SmBusAddress, 2, &Value, Status);
430 
431   return Value;
432 }
433 
434 /**
435   Executes an SMBUS read block command.
436 
437   Executes an SMBUS read block command on the SMBUS device specified by SmBusAddress.
438   Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
439   Bytes are read from the SMBUS and stored in Buffer.
440   The number of bytes read is returned, and will never return a value larger than 32-bytes.
441   If Status is not NULL, then the status of the executed command is returned in Status.
442   It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
443   SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.
444   If Length in SmBusAddress is not zero, then ASSERT().
445   If Buffer is NULL, then ASSERT().
446   If any reserved bits of SmBusAddress are set, then ASSERT().
447 
448   @param  SmBusAddress  The address that encodes the SMBUS Slave Address,
449                         SMBUS Command, SMBUS Data Length, and PEC.
450   @param  Buffer        The pointer to the buffer to store the bytes read from
451                         the SMBUS.
452   @param  Status        Return status for the executed command.
453                         This is an optional parameter and may be NULL.
454                         RETURN_SUCCESS: The SMBUS command was executed.
455                         RETURN_TIMEOUT: A timeout occurred while executing the SMBUS
456                         command.
457                         RETURN_DEVICE_ERROR:  The request was not completed because
458                         a failure reflected in the Host Status Register bit.  Device
459                         errors are a result of a transaction collision, illegal
460                         command field, unclaimed cycle (host initiated), or bus
461                         errors (collisions).
462                         RETURN_CRC_ERROR:  The checksum is not correct. (PEC is
463                         incorrect.)
464                         RETURN_UNSUPPORTED:  The SMBus operation is not supported.
465 
466   @return The number of bytes read.
467 
468 **/
469 UINTN
470 EFIAPI
SmBusReadBlock(IN UINTN SmBusAddress,OUT VOID * Buffer,OUT RETURN_STATUS * Status OPTIONAL)471 SmBusReadBlock (
472   IN  UINTN          SmBusAddress,
473   OUT VOID           *Buffer,
474   OUT RETURN_STATUS  *Status        OPTIONAL
475   )
476 {
477   ASSERT (Buffer != NULL);
478   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);
479   ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
480 
481   return InternalSmBusExec (EfiSmbusReadBlock, SmBusAddress, 0x20, Buffer, Status);
482 }
483 
484 /**
485   Executes an SMBUS write block command.
486 
487   Executes an SMBUS write block command on the SMBUS device specified by SmBusAddress.
488   The SMBUS slave address, SMBUS command, and SMBUS length fields of SmBusAddress are required.
489   Bytes are written to the SMBUS from Buffer.
490   The number of bytes written is returned, and will never return a value larger than 32-bytes.
491   If Status is not NULL, then the status of the executed command is returned in Status.
492   If Length in SmBusAddress is zero or greater than 32, then ASSERT().
493   If Buffer is NULL, then ASSERT().
494   If any reserved bits of SmBusAddress are set, then ASSERT().
495 
496   @param  SmBusAddress  The address that encodes the SMBUS Slave Address,
497                         MBUS Command, SMBUS Data Length, and PEC.
498   @param  Buffer        The pointer to the buffer to store the bytes read from
499                         the SMBUS.
500   @param  Status        Return status for the executed command.
501                         This is an optional parameter and may be NULL.
502                         RETURN_TIMEOUT: A timeout occurred while executing the
503                         SMBUS command.
504                         RETURN_DEVICE_ERROR:  The request was not completed because
505                         a failure reflected in the Host Status Register bit.  Device
506                         errors are a result of a transaction collision, illegal
507                         command field, unclaimed cycle (host initiated), or bus
508                         errors (collisions).
509                         RETURN_CRC_ERROR:  The checksum is not correct. (PEC is
510                         incorrect.)
511                         RETURN_UNSUPPORTED:  The SMBus operation is not supported.
512 
513   @return The number of bytes written.
514 
515 **/
516 UINTN
517 EFIAPI
SmBusWriteBlock(IN UINTN SmBusAddress,OUT VOID * Buffer,OUT RETURN_STATUS * Status OPTIONAL)518 SmBusWriteBlock (
519   IN  UINTN          SmBusAddress,
520   OUT VOID           *Buffer,
521   OUT RETURN_STATUS  *Status        OPTIONAL
522   )
523 {
524   UINTN  Length;
525 
526   ASSERT (Buffer != NULL);
527   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) >= 1);
528   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) <= 32);
529   ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
530 
531   Length = SMBUS_LIB_LENGTH (SmBusAddress);
532   return InternalSmBusExec (EfiSmbusWriteBlock, SmBusAddress, Length, Buffer, Status);
533 }
534 
535 /**
536   Executes an SMBUS block process call command.
537 
538   Executes an SMBUS block process call command on the SMBUS device specified by SmBusAddress.
539   The SMBUS slave address, SMBUS command, and SMBUS length fields of SmBusAddress are required.
540   Bytes are written to the SMBUS from WriteBuffer.  Bytes are then read from the SMBUS into ReadBuffer.
541   If Status is not NULL, then the status of the executed command is returned in Status.
542   It is the caller's responsibility to make sure ReadBuffer is large enough for the total number of bytes read.
543   SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.
544   If Length in SmBusAddress is zero or greater than 32, then ASSERT().
545   If WriteBuffer is NULL, then ASSERT().
546   If ReadBuffer is NULL, then ASSERT().
547   If any reserved bits of SmBusAddress are set, then ASSERT().
548 
549   @param  SmBusAddress  The address that encodes the SMBUS Slave Address,
550                         SMBUS Command, SMBUS Data Length, and PEC.
551   @param  WriteBuffer   The pointer to the buffer of bytes to write to the SMBUS.
552   @param  ReadBuffer    The pointer to the buffer of bytes to read from the SMBUS.
553   @param  Status        Return status for the executed command.
554                         This is an optional parameter and may be NULL.
555                         RETURN_TIMEOUT: A timeout occurred while executing the
556                         SMBUS command.
557                         RETURN_DEVICE_ERROR: The request was not completed because
558                         a failure reflected in the Host Status Register bit.  Device
559                         errors are a result of a transaction collision, illegal
560                         command field, unclaimed cycle (host initiated), or bus
561                         errors (collisions).
562                         RETURN_CRC_ERROR:  The checksum is not correct. (PEC is
563                         incorrect.)
564                         RETURN_UNSUPPORTED:  The SMBus operation is not supported.
565 
566   @return The number of bytes written.
567 
568 **/
569 UINTN
570 EFIAPI
SmBusBlockProcessCall(IN UINTN SmBusAddress,IN VOID * WriteBuffer,OUT VOID * ReadBuffer,OUT RETURN_STATUS * Status OPTIONAL)571 SmBusBlockProcessCall (
572   IN  UINTN          SmBusAddress,
573   IN  VOID           *WriteBuffer,
574   OUT VOID           *ReadBuffer,
575   OUT RETURN_STATUS  *Status        OPTIONAL
576   )
577 {
578   UINTN   Length;
579 
580   ASSERT (WriteBuffer != NULL);
581   ASSERT (ReadBuffer  != NULL);
582   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) >= 1);
583   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) <= 32);
584   ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
585 
586   Length = SMBUS_LIB_LENGTH (SmBusAddress);
587   //
588   // Assuming that ReadBuffer is large enough to save another memory copy.
589   //
590   ReadBuffer = CopyMem (ReadBuffer, WriteBuffer, Length);
591   return InternalSmBusExec (EfiSmbusBWBRProcessCall, SmBusAddress, Length, ReadBuffer, Status);
592 }
593