1/** @file
2Implementation of SmBusLib class library for DXE phase.
3
4Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
5This program and the accompanying materials
6are licensed and made available under the terms and conditions of the BSD License
7which accompanies this distribution.  The full text of the license may be found at
8http://opensource.org/licenses/bsd-license.php.
9
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11WITHOUT 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**/
44VOID
45EFIAPI
46SmBusQuickRead (
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**/
85VOID
86EFIAPI
87SmBusQuickWrite (
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**/
129UINT8
130EFIAPI
131SmBusReceiveByte (
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**/
177UINT8
178EFIAPI
179SmBusSendByte (
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**/
225UINT8
226EFIAPI
227SmBusReadDataByte (
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**/
272UINT8
273EFIAPI
274SmBusWriteDataByte (
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**/
320UINT16
321EFIAPI
322SmBusReadDataWord (
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**/
368UINT16
369EFIAPI
370SmBusWriteDataWord (
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**/
418UINT16
419EFIAPI
420SmBusProcessCall (
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**/
469UINTN
470EFIAPI
471SmBusReadBlock (
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**/
516UINTN
517EFIAPI
518SmBusWriteBlock (
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**/
569UINTN
570EFIAPI
571SmBusBlockProcessCall (
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