1/** @file
2  This file implements I2C IO Protocol which enables the user to manipulate a single
3  I2C device independent of the host controller and I2C design.
4
5  Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.<BR>
6  This program and the accompanying materials
7  are licensed and made available under the terms and conditions of the BSD License
8  which accompanies this distribution.  The full text of the license may be found at
9  http://opensource.org/licenses/bsd-license.php
10
11  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14**/
15
16#include "I2cDxe.h"
17
18//
19//  EFI_DRIVER_BINDING_PROTOCOL instance
20//
21EFI_DRIVER_BINDING_PROTOCOL gI2cBusDriverBinding = {
22  I2cBusDriverSupported,
23  I2cBusDriverStart,
24  I2cBusDriverStop,
25  0x10,
26  NULL,
27  NULL
28};
29
30//
31// Template for I2C Bus Child Device.
32//
33I2C_DEVICE_CONTEXT gI2cDeviceContextTemplate = {
34  I2C_DEVICE_SIGNATURE,
35  NULL,
36  {                     // I2cIo Protocol
37    I2cBusQueueRequest, // QueueRequest
38    NULL,               // DeviceGuid
39    0,                  // DeviceIndex
40    0,                  // HardwareRevision
41    NULL                // I2cControllerCapabilities
42  },
43  NULL,                 // DevicePath
44  NULL,                 // I2cDevice
45  NULL,                 // I2cBusContext
46};
47
48//
49// Template for controller device path node.
50//
51CONTROLLER_DEVICE_PATH gControllerDevicePathTemplate = {
52  {
53    HARDWARE_DEVICE_PATH,
54    HW_CONTROLLER_DP,
55    {
56      (UINT8) (sizeof (CONTROLLER_DEVICE_PATH)),
57      (UINT8) ((sizeof (CONTROLLER_DEVICE_PATH)) >> 8)
58    }
59  },
60  0
61};
62
63//
64// Template for vendor device path node.
65//
66VENDOR_DEVICE_PATH gVendorDevicePathTemplate = {
67  {
68    HARDWARE_DEVICE_PATH,
69    HW_VENDOR_DP,
70    {
71      (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
72      (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
73    }
74  },
75  { 0x0, 0x0, 0x0, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }}
76};
77
78//
79// Driver name table
80//
81GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mI2cBusDriverNameTable[] = {
82  { "eng;en", (CHAR16 *) L"I2C Bus Driver" },
83  { NULL , NULL }
84};
85
86//
87// EFI Component Name Protocol
88//
89GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL  gI2cBusComponentName = {
90  (EFI_COMPONENT_NAME_GET_DRIVER_NAME) I2cBusComponentNameGetDriverName,
91  (EFI_COMPONENT_NAME_GET_CONTROLLER_NAME) I2cBusComponentNameGetControllerName,
92  "eng"
93};
94
95//
96// EFI Component Name 2 Protocol
97//
98GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gI2cBusComponentName2 = {
99  I2cBusComponentNameGetDriverName,
100  I2cBusComponentNameGetControllerName,
101  "en"
102};
103
104/**
105  Retrieves a Unicode string that is the user readable name of the driver.
106
107  This function retrieves the user readable name of a driver in the form of a
108  Unicode string. If the driver specified by This has a user readable name in
109  the language specified by Language, then a pointer to the driver name is
110  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
111  by This does not support the language specified by Language,
112  then EFI_UNSUPPORTED is returned.
113
114  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
115                                EFI_COMPONENT_NAME_PROTOCOL instance.
116
117  @param  Language[in]          A pointer to a Null-terminated ASCII string
118                                array indicating the language. This is the
119                                language of the driver name that the caller is
120                                requesting, and it must match one of the
121                                languages specified in SupportedLanguages. The
122                                number of languages supported by a driver is up
123                                to the driver writer. Language is specified
124                                in RFC 4646 or ISO 639-2 language code format.
125
126  @param  DriverName[out]       A pointer to the Unicode string to return.
127                                This Unicode string is the name of the
128                                driver specified by This in the language
129                                specified by Language.
130
131  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
132                                This and the language specified by Language was
133                                returned in DriverName.
134
135  @retval EFI_INVALID_PARAMETER Language is NULL.
136
137  @retval EFI_INVALID_PARAMETER DriverName is NULL.
138
139  @retval EFI_UNSUPPORTED       The driver specified by This does not support
140                                the language specified by Language.
141
142**/
143EFI_STATUS
144EFIAPI
145I2cBusComponentNameGetDriverName (
146  IN  EFI_COMPONENT_NAME2_PROTOCOL  *This,
147  IN  CHAR8                        *Language,
148  OUT CHAR16                       **DriverName
149  )
150{
151  return LookupUnicodeString2 (
152           Language,
153           This->SupportedLanguages,
154           mI2cBusDriverNameTable,
155           DriverName,
156           (BOOLEAN)(This != &gI2cBusComponentName2)
157           );
158}
159
160/**
161  Retrieves a Unicode string that is the user readable name of the controller
162  that is being managed by a driver.
163
164  This function retrieves the user readable name of the controller specified by
165  ControllerHandle and ChildHandle in the form of a Unicode string. If the
166  driver specified by This has a user readable name in the language specified by
167  Language, then a pointer to the controller name is returned in ControllerName,
168  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
169  managing the controller specified by ControllerHandle and ChildHandle,
170  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
171  support the language specified by Language, then EFI_UNSUPPORTED is returned.
172
173  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
174                                EFI_COMPONENT_NAME_PROTOCOL instance.
175
176  @param  ControllerHandle[in]  The handle of a controller that the driver
177                                specified by This is managing.  This handle
178                                specifies the controller whose name is to be
179                                returned.
180
181  @param  ChildHandle[in]       The handle of the child controller to retrieve
182                                the name of.  This is an optional parameter that
183                                may be NULL.  It will be NULL for device
184                                drivers.  It will also be NULL for a bus drivers
185                                that wish to retrieve the name of the bus
186                                controller.  It will not be NULL for a bus
187                                driver that wishes to retrieve the name of a
188                                child controller.
189
190  @param  Language[in]          A pointer to a Null-terminated ASCII string
191                                array indicating the language.  This is the
192                                language of the driver name that the caller is
193                                requesting, and it must match one of the
194                                languages specified in SupportedLanguages. The
195                                number of languages supported by a driver is up
196                                to the driver writer. Language is specified in
197                                RFC 4646 or ISO 639-2 language code format.
198
199  @param  ControllerName[out]   A pointer to the Unicode string to return.
200                                This Unicode string is the name of the
201                                controller specified by ControllerHandle and
202                                ChildHandle in the language specified by
203                                Language from the point of view of the driver
204                                specified by This.
205
206  @retval EFI_SUCCESS           The Unicode string for the user readable name in
207                                the language specified by Language for the
208                                driver specified by This was returned in
209                                DriverName.
210
211  @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
212
213  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
214                                EFI_HANDLE.
215
216  @retval EFI_INVALID_PARAMETER Language is NULL.
217
218  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
219
220  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
221                                managing the controller specified by
222                                ControllerHandle and ChildHandle.
223
224  @retval EFI_UNSUPPORTED       The driver specified by This does not support
225                                the language specified by Language.
226
227**/
228EFI_STATUS
229EFIAPI
230I2cBusComponentNameGetControllerName (
231  IN  EFI_COMPONENT_NAME2_PROTOCOL                     *This,
232  IN  EFI_HANDLE                                      ControllerHandle,
233  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,
234  IN  CHAR8                                           *Language,
235  OUT CHAR16                                          **ControllerName
236  )
237{
238  return EFI_UNSUPPORTED;
239}
240
241/**
242  Check if the child of I2C controller has been created.
243
244  @param[in] This                         A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
245  @param[in] Controller                   I2C controller handle.
246  @param[in] RemainingDevicePath          A pointer to the remaining portion of a device path.
247  @param[in] RemainingHasControllerNode   Indicate if RemainingDevicePath contains CONTROLLER_DEVICE_PATH.
248  @param[in] RemainingControllerNumber    Controller number in CONTROLLER_DEVICE_PATH.
249
250  @retval EFI_SUCCESS                     The child of I2C controller is not created.
251  @retval Others                          The child of I2C controller has been created or other errors happen.
252
253**/
254EFI_STATUS
255CheckRemainingDevicePath (
256  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
257  IN EFI_HANDLE                   Controller,
258  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath,
259  IN BOOLEAN                      RemainingHasControllerNode,
260  IN UINT32                       RemainingControllerNumber
261  )
262{
263  EFI_STATUS                              Status;
264  EFI_DEVICE_PATH_PROTOCOL                *SystemDevicePath;
265  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY     *OpenInfoBuffer;
266  UINTN                                   EntryCount;
267  UINTN                                   Index;
268  BOOLEAN                                 SystemHasControllerNode;
269  UINT32                                  SystemControllerNumber;
270
271  SystemHasControllerNode = FALSE;
272  SystemControllerNumber    = 0;
273
274  Status = gBS->OpenProtocolInformation (
275                  Controller,
276                  &gEfiI2cHostProtocolGuid,
277                  &OpenInfoBuffer,
278                  &EntryCount
279                  );
280  if (EFI_ERROR (Status)) {
281    return Status;
282  }
283
284  for (Index = 0; Index < EntryCount; Index++) {
285    if ((OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
286      Status = gBS->OpenProtocol (
287                      OpenInfoBuffer[Index].ControllerHandle,
288                      &gEfiDevicePathProtocolGuid,
289                      (VOID **) &SystemDevicePath,
290                      This->DriverBindingHandle,
291                      Controller,
292                      EFI_OPEN_PROTOCOL_GET_PROTOCOL
293                      );
294      if (!EFI_ERROR (Status)) {
295        //
296        // Find vendor device path node and compare
297        //
298        while (!IsDevicePathEnd (SystemDevicePath)) {
299          if ((DevicePathType (SystemDevicePath) == HARDWARE_DEVICE_PATH) &&
300              (DevicePathSubType (SystemDevicePath) == HW_VENDOR_DP)) {
301            //
302            // Check if vendor device path is same between system device path and remaining device path
303            //
304            if (CompareMem (SystemDevicePath, RemainingDevicePath, sizeof (VENDOR_DEVICE_PATH)) == 0) {
305              //
306              // Get controller node appended after vendor node
307              //
308              SystemDevicePath = NextDevicePathNode (SystemDevicePath);
309              if ((DevicePathType (SystemDevicePath) == HARDWARE_DEVICE_PATH) &&
310                  (DevicePathSubType (SystemDevicePath) == HW_CONTROLLER_DP)) {
311                SystemHasControllerNode = TRUE;
312                SystemControllerNumber    = ((CONTROLLER_DEVICE_PATH *) SystemDevicePath)->ControllerNumber;
313              } else {
314                SystemHasControllerNode = FALSE;
315                SystemControllerNumber    = 0;
316              }
317              if (((SystemHasControllerNode)  && (!RemainingHasControllerNode) && (SystemControllerNumber == 0)) ||
318                  ((!SystemHasControllerNode) && (RemainingHasControllerNode)  && (RemainingControllerNumber == 0)) ||
319                  ((SystemHasControllerNode)  && (RemainingHasControllerNode)  && (SystemControllerNumber == RemainingControllerNumber)) ||
320                  ((!SystemHasControllerNode) && (!RemainingHasControllerNode))) {
321                  DEBUG ((EFI_D_ERROR, "This I2C device has been already started.\n"));
322                  Status = EFI_UNSUPPORTED;
323                  break;
324              }
325            }
326          }
327          SystemDevicePath = NextDevicePathNode (SystemDevicePath);
328        }
329        if (EFI_ERROR (Status)) {
330          break;
331        }
332      }
333    }
334  }
335  FreePool (OpenInfoBuffer);
336  return Status;
337}
338
339/**
340  Tests to see if this driver supports a given controller. If a child device is provided,
341  it further tests to see if this driver supports creating a handle for the specified child device.
342
343  This function checks to see if the driver specified by This supports the device specified by
344  ControllerHandle. Drivers will typically use the device path attached to
345  ControllerHandle and/or the services from the bus I/O abstraction attached to
346  ControllerHandle to determine if the driver supports ControllerHandle. This function
347  may be called many times during platform initialization. In order to reduce boot times, the tests
348  performed by this function must be very small, and take as little time as possible to execute. This
349  function must not change the state of any hardware devices, and this function must be aware that the
350  device specified by ControllerHandle may already be managed by the same driver or a
351  different driver. This function must match its calls to AllocatePages() with FreePages(),
352  AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
353  Since ControllerHandle may have been previously started by the same driver, if a protocol is
354  already in the opened state, then it must not be closed with CloseProtocol(). This is required
355  to guarantee the state of ControllerHandle is not modified by this function.
356
357  @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
358  @param[in]  ControllerHandle     The handle of the controller to test. This handle
359                                   must support a protocol interface that supplies
360                                   an I/O abstraction to the driver.
361  @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
362                                   parameter is ignored by device drivers, and is optional for bus
363                                   drivers. For bus drivers, if this parameter is not NULL, then
364                                   the bus driver must determine if the bus controller specified
365                                   by ControllerHandle and the child controller specified
366                                   by RemainingDevicePath are both supported by this
367                                   bus driver.
368
369  @retval EFI_SUCCESS              The device specified by ControllerHandle and
370                                   RemainingDevicePath is supported by the driver specified by This.
371  @retval EFI_ALREADY_STARTED      The device specified by ControllerHandle and
372                                   RemainingDevicePath is already being managed by the driver
373                                   specified by This.
374  @retval EFI_ACCESS_DENIED        The device specified by ControllerHandle and
375                                   RemainingDevicePath is already being managed by a different
376                                   driver or an application that requires exclusive access.
377                                   Currently not implemented.
378  @retval EFI_UNSUPPORTED          The device specified by ControllerHandle and
379                                   RemainingDevicePath is not supported by the driver specified by This.
380**/
381EFI_STATUS
382EFIAPI
383I2cBusDriverSupported (
384  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
385  IN EFI_HANDLE                   Controller,
386  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
387  )
388{
389  EFI_STATUS                          Status;
390  EFI_I2C_ENUMERATE_PROTOCOL          *I2cEnumerate;
391  EFI_I2C_HOST_PROTOCOL               *I2cHost;
392  EFI_DEVICE_PATH_PROTOCOL            *ParentDevicePath;
393  EFI_DEVICE_PATH_PROTOCOL            *DevPathNode;
394  BOOLEAN                             RemainingHasControllerNode;
395  UINT32                              RemainingControllerNumber;
396
397  RemainingHasControllerNode = FALSE;
398  RemainingControllerNumber    = 0;
399
400  //
401  //  Determine if the I2c Enumerate Protocol is available
402  //
403  Status = gBS->OpenProtocol (
404                  Controller,
405                  &gEfiI2cEnumerateProtocolGuid,
406                  (VOID **) &I2cEnumerate,
407                  This->DriverBindingHandle,
408                  Controller,
409                  EFI_OPEN_PROTOCOL_BY_DRIVER
410                  );
411  if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) {
412    return Status;
413  }
414
415  if (!EFI_ERROR (Status)) {
416    gBS->CloseProtocol (
417          Controller,
418          &gEfiI2cEnumerateProtocolGuid,
419          This->DriverBindingHandle,
420          Controller
421          );
422  }
423
424  Status = gBS->OpenProtocol (
425                  Controller,
426                  &gEfiDevicePathProtocolGuid,
427                  (VOID **) &ParentDevicePath,
428                  This->DriverBindingHandle,
429                  Controller,
430                  EFI_OPEN_PROTOCOL_BY_DRIVER
431                  );
432
433  if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) {
434    return Status;
435  }
436
437  if (!EFI_ERROR (Status)) {
438    gBS->CloseProtocol (
439          Controller,
440          &gEfiDevicePathProtocolGuid,
441          This->DriverBindingHandle,
442          Controller
443          );
444  }
445
446  if ((RemainingDevicePath != NULL) && !IsDevicePathEnd (RemainingDevicePath)) {
447    //
448    // Check if the first node of RemainingDevicePath is a hardware vendor device path
449    //
450    if ((DevicePathType (RemainingDevicePath) != HARDWARE_DEVICE_PATH) ||
451        (DevicePathSubType (RemainingDevicePath) != HW_VENDOR_DP)) {
452      return EFI_UNSUPPORTED;
453    }
454    //
455    // Check if the second node of RemainingDevicePath is a controller node
456    //
457    DevPathNode = NextDevicePathNode (RemainingDevicePath);
458    if (!IsDevicePathEnd (DevPathNode)) {
459      if ((DevicePathType (DevPathNode) != HARDWARE_DEVICE_PATH) ||
460          (DevicePathSubType (DevPathNode) != HW_CONTROLLER_DP)) {
461        return EFI_UNSUPPORTED;
462      } else {
463        RemainingHasControllerNode = TRUE;
464        RemainingControllerNumber    = ((CONTROLLER_DEVICE_PATH *) DevPathNode)->ControllerNumber;
465      }
466    }
467  }
468
469  //
470  // Determine if the I2C Host Protocol is available
471  //
472  Status = gBS->OpenProtocol (
473                  Controller,
474                  &gEfiI2cHostProtocolGuid,
475                  (VOID **) &I2cHost,
476                  This->DriverBindingHandle,
477                  Controller,
478                  EFI_OPEN_PROTOCOL_BY_DRIVER
479                  );
480
481  if (!EFI_ERROR (Status)) {
482    gBS->CloseProtocol (
483          Controller,
484          &gEfiI2cHostProtocolGuid,
485          This->DriverBindingHandle,
486          Controller
487          );
488  }
489
490
491  if (Status == EFI_ALREADY_STARTED) {
492    if ((RemainingDevicePath == NULL) ||
493        ((RemainingDevicePath != NULL) && IsDevicePathEnd (RemainingDevicePath))) {
494      //
495      // If RemainingDevicePath is NULL or is the End of Device Path Node, return EFI_SUCCESS.
496      //
497      Status = EFI_SUCCESS;
498    } else {
499      //
500      // Test if the child with the RemainingDevicePath has already been created.
501      //
502      Status = CheckRemainingDevicePath (
503                 This,
504                 Controller,
505                 RemainingDevicePath,
506                 RemainingHasControllerNode,
507                 RemainingControllerNumber
508                 );
509    }
510  }
511
512  return Status;
513}
514
515/**
516  Starts a device controller or a bus controller.
517
518  The Start() function is designed to be invoked from the EFI boot service ConnectController().
519  As a result, much of the error checking on the parameters to Start() has been moved into this
520  common boot service. It is legal to call Start() from other locations,
521  but the following calling restrictions must be followed or the system behavior will not be deterministic.
522  1. ControllerHandle must be a valid EFI_HANDLE.
523  2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
524     EFI_DEVICE_PATH_PROTOCOL.
525  3. Prior to calling Start(), the Supported() function for the driver specified by This must
526     have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
527
528  @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
529  @param[in]  ControllerHandle     The handle of the controller to start. This handle
530                                   must support a protocol interface that supplies
531                                   an I/O abstraction to the driver.
532  @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
533                                   parameter is ignored by device drivers, and is optional for bus
534                                   drivers. For a bus driver, if this parameter is NULL, then handles
535                                   for all the children of Controller are created by this driver.
536                                   If this parameter is not NULL and the first Device Path Node is
537                                   not the End of Device Path Node, then only the handle for the
538                                   child device specified by the first Device Path Node of
539                                   RemainingDevicePath is created by this driver.
540                                   If the first Device Path Node of RemainingDevicePath is
541                                   the End of Device Path Node, no child handle is created by this
542                                   driver.
543
544  @retval EFI_SUCCESS              The device was started.
545  @retval EFI_DEVICE_ERROR         The device could not be started due to a device error.Currently not implemented.
546  @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.
547  @retval Others                   The driver failded to start the device.
548
549**/
550EFI_STATUS
551EFIAPI
552I2cBusDriverStart (
553  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
554  IN EFI_HANDLE                   Controller,
555  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
556  )
557{
558  EFI_I2C_ENUMERATE_PROTOCOL *I2cEnumerate;
559  EFI_I2C_HOST_PROTOCOL      *I2cHost;
560  I2C_BUS_CONTEXT            *I2cBusContext;
561  EFI_STATUS                 Status;
562  EFI_DEVICE_PATH_PROTOCOL   *ParentDevicePath;
563
564  I2cBusContext     = NULL;
565  ParentDevicePath  = NULL;
566  I2cEnumerate      = NULL;
567  I2cHost           = NULL;
568
569  //
570  //  Determine if the I2C controller is available
571  //
572  Status = gBS->OpenProtocol (
573                  Controller,
574                  &gEfiI2cHostProtocolGuid,
575                  (VOID**)&I2cHost,
576                  This->DriverBindingHandle,
577                  Controller,
578                  EFI_OPEN_PROTOCOL_BY_DRIVER
579                  );
580  if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
581    DEBUG ((EFI_D_ERROR, "I2cBus: open I2C host error, Status = %r\n", Status));
582    return Status;
583  }
584
585  if (Status == EFI_ALREADY_STARTED) {
586    Status = gBS->OpenProtocol (
587                    Controller,
588                    &gEfiCallerIdGuid,
589                    (VOID **) &I2cBusContext,
590                    This->DriverBindingHandle,
591                    Controller,
592                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
593                    );
594    if (EFI_ERROR (Status)) {
595      DEBUG ((EFI_D_ERROR, "I2cBus: open private protocol error, Status = %r.\n", Status));
596      return Status;
597    }
598  }
599
600  //
601  //  Get the I2C bus enumeration API
602  //
603  Status = gBS->OpenProtocol (
604                  Controller,
605                  &gEfiI2cEnumerateProtocolGuid,
606                  (VOID**)&I2cEnumerate,
607                  This->DriverBindingHandle,
608                  Controller,
609                  EFI_OPEN_PROTOCOL_BY_DRIVER
610                  );
611  if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
612    DEBUG ((EFI_D_ERROR, "I2cBus: open I2C enumerate error, Status = %r\n", Status));
613    goto Error;
614  }
615
616  Status = gBS->OpenProtocol (
617                   Controller,
618                   &gEfiDevicePathProtocolGuid,
619                   (VOID **) &ParentDevicePath,
620                   This->DriverBindingHandle,
621                   Controller,
622                   EFI_OPEN_PROTOCOL_BY_DRIVER
623                   );
624  if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
625    DEBUG ((EFI_D_ERROR, "I2cBus: open device path error, Status = %r\n", Status));
626    goto Error;
627  }
628
629  if ((RemainingDevicePath != NULL) && IsDevicePathEnd (RemainingDevicePath)) {
630    //
631    // If RemainingDevicePath is the End of Device Path Node,
632    // don't create any child device and return EFI_SUCESS
633    //
634    return EFI_SUCCESS;
635  }
636
637  //
638  // Allocate the buffer for I2C_BUS_CONTEXT if it is not allocated before.
639  //
640  if (I2cBusContext == NULL) {
641    //
642    //  Allocate the I2C context structure for the current I2C controller
643    //
644    I2cBusContext = AllocateZeroPool (sizeof (I2C_BUS_CONTEXT));
645    if (I2cBusContext == NULL) {
646      DEBUG ((EFI_D_ERROR, "I2cBus: there is no enough memory to allocate.\n"));
647      Status = EFI_OUT_OF_RESOURCES;
648      goto Error;
649    }
650
651    /*
652       +----------------+
653    .->| I2C_BUS_CONTEXT|<----- This file Protocol (gEfiCallerIdGuid) installed on I2C Controller handle
654    |  +----------------+
655    |
656    |  +----------------------------+
657    |  | I2C_DEVICE_CONTEXT         |
658    `--|                            |
659       |                            |
660       | I2C IO Protocol Structure  | <----- I2C IO Protocol
661       |                            |
662       +----------------------------+
663
664    */
665    I2cBusContext->I2cHost      = I2cHost;
666    I2cBusContext->I2cEnumerate = I2cEnumerate;
667    //
668    // Parent controller used to create children
669    //
670    I2cBusContext->Controller   = Controller;
671    //
672    // Parent controller device path used to create children device path
673    //
674    I2cBusContext->ParentDevicePath = ParentDevicePath;
675
676    I2cBusContext->DriverBindingHandle = This->DriverBindingHandle;
677
678    Status = gBS->InstallMultipleProtocolInterfaces (
679                    &Controller,
680                    &gEfiCallerIdGuid,
681                    I2cBusContext,
682                    NULL
683                    );
684    if (EFI_ERROR (Status)) {
685      DEBUG ((EFI_D_ERROR, "I2cBus: install private protocol error, Status = %r.\n", Status));
686      goto Error;
687    }
688  }
689
690  //
691  //  Start the driver
692  //
693  Status = RegisterI2cDevice (I2cBusContext, Controller, RemainingDevicePath);
694
695  return Status;
696
697Error:
698  if (EFI_ERROR (Status)) {
699    DEBUG ((EFI_D_ERROR, "I2cBus: Start() function failed, Status = %r\n", Status));
700    if (ParentDevicePath != NULL) {
701      gBS->CloseProtocol (
702            Controller,
703            &gEfiDevicePathProtocolGuid,
704            This->DriverBindingHandle,
705            Controller
706            );
707    }
708
709    if (I2cHost != NULL) {
710      gBS->CloseProtocol (
711            Controller,
712            &gEfiI2cHostProtocolGuid,
713            This->DriverBindingHandle,
714            Controller
715            );
716    }
717
718    if (I2cEnumerate != NULL) {
719      gBS->CloseProtocol (
720            Controller,
721            &gEfiI2cEnumerateProtocolGuid,
722            This->DriverBindingHandle,
723            Controller
724            );
725    }
726
727    if (I2cBusContext != NULL) {
728      Status = gBS->UninstallMultipleProtocolInterfaces (
729                      &Controller,
730                      gEfiCallerIdGuid,
731                      I2cBusContext,
732                      NULL
733                      );
734      FreePool (I2cBusContext);
735    }
736  }
737
738  //
739  //  Return the operation status.
740  //
741  return Status;
742}
743
744
745/**
746  Stops a device controller or a bus controller.
747
748  The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
749  As a result, much of the error checking on the parameters to Stop() has been moved
750  into this common boot service. It is legal to call Stop() from other locations,
751  but the following calling restrictions must be followed or the system behavior will not be deterministic.
752  1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
753     same driver's Start() function.
754  2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
755     EFI_HANDLE. In addition, all of these handles must have been created in this driver's
756     Start() function, and the Start() function must have called OpenProtocol() on
757     ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
758
759  @param[in]  This              A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
760  @param[in]  ControllerHandle  A handle to the device being stopped. The handle must
761                                support a bus specific I/O protocol for the driver
762                                to use to stop the device.
763  @param[in]  NumberOfChildren  The number of child device handles in ChildHandleBuffer.
764  @param[in]  ChildHandleBuffer An array of child handles to be freed. May be NULL
765                                if NumberOfChildren is 0.
766
767  @retval EFI_SUCCESS           The device was stopped.
768  @retval EFI_DEVICE_ERROR      The device could not be stopped due to a device error.
769
770**/
771EFI_STATUS
772EFIAPI
773I2cBusDriverStop (
774  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
775  IN  EFI_HANDLE                   Controller,
776  IN  UINTN                        NumberOfChildren,
777  IN  EFI_HANDLE                   *ChildHandleBuffer
778  )
779{
780  I2C_BUS_CONTEXT             *I2cBusContext;
781  EFI_STATUS                  Status;
782  BOOLEAN                     AllChildrenStopped;
783  UINTN                       Index;
784
785  if (NumberOfChildren == 0) {
786    gBS->CloseProtocol (
787          Controller,
788          &gEfiDevicePathProtocolGuid,
789          This->DriverBindingHandle,
790          Controller
791          );
792
793    gBS->CloseProtocol (
794          Controller,
795          &gEfiI2cHostProtocolGuid,
796          This->DriverBindingHandle,
797          Controller
798          );
799
800    gBS->CloseProtocol (
801          Controller,
802          &gEfiI2cEnumerateProtocolGuid,
803          This->DriverBindingHandle,
804          Controller
805          );
806
807    Status = gBS->OpenProtocol (
808                    Controller,
809                    &gEfiCallerIdGuid,
810                    (VOID **) &I2cBusContext,
811                    This->DriverBindingHandle,
812                    Controller,
813                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
814                    );
815    if (!EFI_ERROR (Status)) {
816      gBS->UninstallMultipleProtocolInterfaces (
817            Controller,
818            &gEfiCallerIdGuid,
819            I2cBusContext,
820            NULL
821            );
822      //
823      // No more child now, free bus context data.
824      //
825      FreePool (I2cBusContext);
826    }
827    return Status;
828  }
829
830  AllChildrenStopped = TRUE;
831
832  for (Index = 0; Index < NumberOfChildren; Index++) {
833
834    Status = UnRegisterI2cDevice (This, Controller, ChildHandleBuffer[Index]);
835    if (EFI_ERROR (Status)) {
836      AllChildrenStopped = FALSE;
837    }
838  }
839
840  if (!AllChildrenStopped) {
841    return EFI_DEVICE_ERROR;
842  }
843  return EFI_SUCCESS;
844}
845
846/**
847  Enumerate the I2C bus
848
849  This routine walks the platform specific data describing the
850  I2C bus to create the I2C devices where driver GUIDs were
851  specified.
852
853  @param[in] I2cBusContext            Address of an I2C_BUS_CONTEXT structure
854  @param[in] Controller               Handle to the controller
855  @param[in] RemainingDevicePath      A pointer to the remaining portion of a device path.
856
857  @retval EFI_SUCCESS       The bus is successfully configured
858
859**/
860EFI_STATUS
861RegisterI2cDevice (
862  IN I2C_BUS_CONTEXT            *I2cBusContext,
863  IN EFI_HANDLE                 Controller,
864  IN EFI_DEVICE_PATH_PROTOCOL   *RemainingDevicePath
865  )
866{
867  I2C_DEVICE_CONTEXT                *I2cDeviceContext;
868  EFI_STATUS                        Status;
869  CONST EFI_I2C_DEVICE              *Device;
870  CONST EFI_I2C_DEVICE              *TempDevice;
871  UINT32                            RemainingPathDeviceIndex;
872  EFI_DEVICE_PATH_PROTOCOL          *DevPathNode;
873  BOOLEAN                           BuildControllerNode;
874  UINTN                             Count;
875
876  Status                   = EFI_SUCCESS;
877  BuildControllerNode      = TRUE;
878
879  //
880  // Default DeviceIndex
881  //
882  RemainingPathDeviceIndex = 0;
883
884  //
885  // Determine the controller number in Controller Node Device Path when RemainingDevicePath is not NULL.
886  //
887  if (RemainingDevicePath != NULL) {
888    //
889    // Check if there is a controller node appended after vendor node
890    //
891    DevPathNode = NextDevicePathNode (RemainingDevicePath);
892    if ((DevicePathType (DevPathNode) == HARDWARE_DEVICE_PATH) &&
893        (DevicePathSubType(DevPathNode) == HW_CONTROLLER_DP)) {
894      //
895      // RemainingDevicePath != NULL and RemainingDevicePath contains Controller Node,
896      // add Controller Node to Device Path on child handle.
897      //
898      RemainingPathDeviceIndex = ((CONTROLLER_DEVICE_PATH *) DevPathNode)->ControllerNumber;
899    } else {
900      //
901      // RemainingDevicePath != NULL and RemainingDevicePath does not contain Controller Node,
902      // do not add controller node to Device Path on child handle.
903      //
904      BuildControllerNode = FALSE;
905    }
906  }
907
908  //
909  //  Walk the list of I2C devices on this bus
910  //
911  Device = NULL;
912  while (TRUE) {
913    //
914    //  Get the next I2C device
915    //
916    Status = I2cBusContext->I2cEnumerate->Enumerate (I2cBusContext->I2cEnumerate, &Device);
917    if (EFI_ERROR (Status) || Device == NULL) {
918      if (RemainingDevicePath != NULL) {
919        Status = EFI_NOT_FOUND;
920      } else {
921        Status = EFI_SUCCESS;
922      }
923      break;
924    }
925
926    //
927    //  Determine if the device info is valid
928    //
929    if ((Device->DeviceGuid == NULL) || (Device->SlaveAddressCount == 0) || (Device->SlaveAddressArray == NULL)) {
930      DEBUG ((EFI_D_ERROR, "Invalid EFI_I2C_DEVICE reported by I2c Enumerate protocol.\n"));
931      continue;
932    }
933
934    if (RemainingDevicePath == NULL) {
935      if (Device->DeviceIndex == 0) {
936        //
937        // Determine if the controller node is necessary when controller number is zero in I2C device
938        //
939        TempDevice = NULL;
940        Count      = 0;
941        while (TRUE) {
942          //
943          //  Get the next I2C device
944          //
945          Status = I2cBusContext->I2cEnumerate->Enumerate (I2cBusContext->I2cEnumerate, &TempDevice);
946          if (EFI_ERROR (Status) || TempDevice == NULL) {
947            Status = EFI_SUCCESS;
948            break;
949          }
950          if (CompareGuid (Device->DeviceGuid, TempDevice->DeviceGuid)) {
951            Count++;
952          }
953        }
954        if (Count == 1) {
955          //
956          // RemainingDevicePath == NULL and only DeviceIndex 0 is present on the I2C bus,
957          // do not add Controller Node to Device Path on child handle.
958          //
959          BuildControllerNode = FALSE;
960        }
961      }
962    } else {
963      //
964      // Find I2C device reported in Remaining Device Path
965      //
966      if ((!CompareGuid (&((VENDOR_DEVICE_PATH *)RemainingDevicePath)->Guid, Device->DeviceGuid)) ||
967          (RemainingPathDeviceIndex != Device->DeviceIndex)) {
968        continue;
969      }
970    }
971
972    //
973    // Build the device context for current I2C device.
974    //
975    I2cDeviceContext = NULL;
976    I2cDeviceContext = AllocateCopyPool (sizeof (I2C_DEVICE_CONTEXT), &gI2cDeviceContextTemplate);
977    ASSERT (I2cDeviceContext != NULL);
978    if (I2cDeviceContext == NULL) {
979      continue;
980    }
981
982    //
983    //  Initialize the specific device context
984    //
985    I2cDeviceContext->I2cBusContext          = I2cBusContext;
986    I2cDeviceContext->I2cDevice              = Device;
987    I2cDeviceContext->I2cIo.DeviceGuid       = Device->DeviceGuid;
988    I2cDeviceContext->I2cIo.DeviceIndex      = Device->DeviceIndex;
989    I2cDeviceContext->I2cIo.HardwareRevision = Device->HardwareRevision;
990    I2cDeviceContext->I2cIo.I2cControllerCapabilities = I2cBusContext->I2cHost->I2cControllerCapabilities;
991
992    //
993    //  Build the device path
994    //
995    Status = I2cBusDevicePathAppend (I2cDeviceContext, BuildControllerNode);
996    ASSERT_EFI_ERROR (Status);
997    if (EFI_ERROR (Status)) {
998      continue;
999    }
1000
1001    //
1002    //  Install the protocol
1003    //
1004    Status = gBS->InstallMultipleProtocolInterfaces (
1005              &I2cDeviceContext->Handle,
1006              &gEfiI2cIoProtocolGuid,
1007              &I2cDeviceContext->I2cIo,
1008              &gEfiDevicePathProtocolGuid,
1009              I2cDeviceContext->DevicePath,
1010              NULL );
1011    if (EFI_ERROR (Status)) {
1012      //
1013      // Free resources for this I2C device
1014      //
1015      ReleaseI2cDeviceContext (I2cDeviceContext);
1016      continue;
1017    }
1018
1019    //
1020    // Create the child handle
1021    //
1022    Status = gBS->OpenProtocol (
1023                    Controller,
1024                    &gEfiI2cHostProtocolGuid,
1025                    (VOID **) &I2cBusContext->I2cHost,
1026                    I2cBusContext->DriverBindingHandle,
1027                    I2cDeviceContext->Handle,
1028                    EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1029                    );
1030    if (EFI_ERROR (Status)) {
1031      Status = gBS->UninstallMultipleProtocolInterfaces (
1032                      I2cDeviceContext->Handle,
1033                      &gEfiDevicePathProtocolGuid,
1034                      I2cDeviceContext->DevicePath,
1035                      &gEfiI2cIoProtocolGuid,
1036                      &I2cDeviceContext->I2cIo,
1037                      NULL
1038                      );
1039      //
1040      // Free resources for this I2C device
1041      //
1042      ReleaseI2cDeviceContext (I2cDeviceContext);
1043      continue;
1044    }
1045
1046    if (RemainingDevicePath != NULL) {
1047      //
1048      // Child has been created successfully
1049      //
1050      break;
1051    }
1052  }
1053
1054  return Status;
1055}
1056
1057
1058/**
1059  Queue an I2C transaction for execution on the I2C device.
1060
1061  This routine must be called at or below TPL_NOTIFY.  For synchronous
1062  requests this routine must be called at or below TPL_CALLBACK.
1063
1064  This routine queues an I2C transaction to the I2C controller for
1065  execution on the I2C bus.
1066
1067  When Event is NULL, QueueRequest() operates synchronously and returns
1068  the I2C completion status as its return value.
1069
1070  When Event is not NULL, QueueRequest() synchronously returns EFI_SUCCESS
1071  indicating that the asynchronous I2C transaction was queued.  The values
1072  above are returned in the buffer pointed to by I2cStatus upon the
1073  completion of the I2C transaction when I2cStatus is not NULL.
1074
1075  The upper layer driver writer provides the following to the platform
1076  vendor:
1077
1078  1.  Vendor specific GUID for the I2C part
1079  2.  Guidance on proper construction of the slave address array when the
1080      I2C device uses more than one slave address.  The I2C bus protocol
1081      uses the SlaveAddressIndex to perform relative to physical address
1082      translation to access the blocks of hardware within the I2C device.
1083
1084  @param[in] This               Pointer to an EFI_I2C_IO_PROTOCOL structure.
1085  @param[in] SlaveAddressIndex  Index value into an array of slave addresses
1086                                for the I2C device.  The values in the array
1087                                are specified by the board designer, with the
1088                                third party I2C device driver writer providing
1089                                the slave address order.
1090
1091                                For devices that have a single slave address,
1092                                this value must be zero.  If the I2C device
1093                                uses more than one slave address then the
1094                                third party (upper level) I2C driver writer
1095                                needs to specify the order of entries in the
1096                                slave address array.
1097
1098                                \ref ThirdPartyI2cDrivers "Third Party I2C
1099                                Drivers" section in I2cMaster.h.
1100  @param[in] Event              Event to signal for asynchronous transactions,
1101                                NULL for synchronous transactions
1102  @param[in] RequestPacket      Pointer to an EFI_I2C_REQUEST_PACKET structure
1103                                describing the I2C transaction
1104  @param[out] I2cStatus         Optional buffer to receive the I2C transaction
1105                                completion status
1106
1107  @retval EFI_SUCCESS           The asynchronous transaction was successfully
1108                                queued when Event is not NULL.
1109  @retval EFI_SUCCESS           The transaction completed successfully when
1110                                Event is NULL.
1111  @retval EFI_BAD_BUFFER_SIZE   The RequestPacket->LengthInBytes value is too
1112                                large.
1113  @retval EFI_DEVICE_ERROR      There was an I2C error (NACK) during the
1114                                transaction.
1115  @retval EFI_INVALID_PARAMETER RequestPacket is NULL
1116  @retval EFI_NO_MAPPING        The EFI_I2C_HOST_PROTOCOL could not set the
1117                                bus configuration required to access this I2C
1118                                device.
1119  @retval EFI_NO_RESPONSE       The I2C device is not responding to the slave
1120                                address selected by SlaveAddressIndex.
1121                                EFI_DEVICE_ERROR will be returned if the
1122                                controller cannot distinguish when the NACK
1123                                occurred.
1124  @retval EFI_OUT_OF_RESOURCES  Insufficient memory for I2C transaction
1125  @retval EFI_UNSUPPORTED       The controller does not support the requested
1126                                transaction.
1127
1128**/
1129EFI_STATUS
1130EFIAPI
1131I2cBusQueueRequest (
1132  IN CONST EFI_I2C_IO_PROTOCOL  *This,
1133  IN UINTN                      SlaveAddressIndex,
1134  IN EFI_EVENT                  Event               OPTIONAL,
1135  IN EFI_I2C_REQUEST_PACKET     *RequestPacket,
1136  OUT EFI_STATUS                *I2cStatus          OPTIONAL
1137  )
1138{
1139  CONST EFI_I2C_DEVICE        *I2cDevice;
1140  I2C_BUS_CONTEXT             *I2cBusContext;
1141  CONST EFI_I2C_HOST_PROTOCOL *I2cHost;
1142  I2C_DEVICE_CONTEXT          *I2cDeviceContext;
1143  EFI_STATUS                  Status;
1144
1145  if (RequestPacket == NULL) {
1146    return EFI_INVALID_PARAMETER;
1147  }
1148
1149  //
1150  //  Validate the I2C slave index
1151  //
1152  I2cDeviceContext = I2C_DEVICE_CONTEXT_FROM_PROTOCOL (This);
1153  I2cDevice        = I2cDeviceContext->I2cDevice;
1154  if ( SlaveAddressIndex >= I2cDevice->SlaveAddressCount ) {
1155    return EFI_INVALID_PARAMETER;
1156  }
1157
1158  //
1159  //  Locate the I2c Host Protocol to queue request
1160  //
1161  I2cBusContext = I2cDeviceContext->I2cBusContext;
1162  I2cHost       = I2cBusContext->I2cHost;
1163
1164  //
1165  //  Start the I2C operation
1166  //
1167  Status = I2cHost->QueueRequest (
1168                      I2cHost,
1169                      I2cDevice->I2cBusConfiguration,
1170                      I2cDevice->SlaveAddressArray [SlaveAddressIndex],
1171                      Event,
1172                      RequestPacket,
1173                      I2cStatus
1174                      );
1175
1176  return Status;
1177}
1178
1179/**
1180  Release all the resources allocated for the I2C device.
1181
1182  This function releases all the resources allocated for the I2C device.
1183
1184  @param  I2cDeviceContext         The I2C child device involved for the operation.
1185
1186**/
1187VOID
1188ReleaseI2cDeviceContext (
1189  IN I2C_DEVICE_CONTEXT          *I2cDeviceContext
1190  )
1191{
1192  if (I2cDeviceContext == NULL) {
1193    return;
1194  }
1195
1196  if (I2cDeviceContext->DevicePath != NULL) {
1197    FreePool (I2cDeviceContext->DevicePath);
1198  }
1199
1200  FreePool (I2cDeviceContext);
1201}
1202
1203/**
1204  Unregister an I2C device.
1205
1206  This function removes the protocols installed on the controller handle and
1207  frees the resources allocated for the I2C device.
1208
1209  @param  This                  The pointer to EFI_DRIVER_BINDING_PROTOCOL instance.
1210  @param  Controller            The controller handle of the I2C device.
1211  @param  Handle                The child handle.
1212
1213  @retval EFI_SUCCESS           The I2C device is successfully unregistered.
1214  @return Others                Some error occurs when unregistering the I2C device.
1215
1216**/
1217EFI_STATUS
1218UnRegisterI2cDevice (
1219  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,
1220  IN  EFI_HANDLE                     Controller,
1221  IN  EFI_HANDLE                     Handle
1222  )
1223{
1224  EFI_STATUS                  Status;
1225  I2C_DEVICE_CONTEXT          *I2cDeviceContext;
1226  EFI_I2C_IO_PROTOCOL         *I2cIo;
1227  EFI_I2C_HOST_PROTOCOL       *I2cHost;
1228
1229  I2cIo = NULL;
1230
1231  Status = gBS->OpenProtocol (
1232                  Handle,
1233                  &gEfiI2cIoProtocolGuid,
1234                  (VOID **) &I2cIo,
1235                  This->DriverBindingHandle,
1236                  Controller,
1237                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
1238                  );
1239  if (EFI_ERROR (Status)) {
1240    return Status;
1241  }
1242
1243  //
1244  // Get I2c device context data.
1245  //
1246  I2cDeviceContext = I2C_DEVICE_CONTEXT_FROM_PROTOCOL (I2cIo);
1247
1248  //
1249  // Close the child handle
1250  //
1251  gBS->CloseProtocol (
1252         Controller,
1253         &gEfiI2cHostProtocolGuid,
1254         This->DriverBindingHandle,
1255         Handle
1256         );
1257
1258  //
1259  // The I2C Bus driver installs the I2C Io and Device Path Protocol in the DriverBindingStart().
1260  // Here should uninstall them.
1261  //
1262  Status = gBS->UninstallMultipleProtocolInterfaces (
1263                  Handle,
1264                  &gEfiDevicePathProtocolGuid,
1265                  I2cDeviceContext->DevicePath,
1266                  &gEfiI2cIoProtocolGuid,
1267                  &I2cDeviceContext->I2cIo,
1268                  NULL
1269                  );
1270
1271  if (EFI_ERROR (Status)) {
1272    //
1273    // Keep parent and child relationship
1274    //
1275    gBS->OpenProtocol (
1276          Controller,
1277          &gEfiI2cHostProtocolGuid,
1278          (VOID **) &I2cHost,
1279          This->DriverBindingHandle,
1280          Handle,
1281          EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1282          );
1283    return Status;
1284  }
1285
1286  //
1287  // Free resources for this I2C device
1288  //
1289  ReleaseI2cDeviceContext (I2cDeviceContext);
1290
1291  return EFI_SUCCESS;
1292}
1293
1294/**
1295  Create a path for the I2C device
1296
1297  Append the I2C slave path to the I2C master controller path.
1298
1299  @param[in] I2cDeviceContext           Address of an I2C_DEVICE_CONTEXT structure.
1300  @param[in] BuildControllerNode        Flag to build controller node in device path.
1301
1302  @retval EFI_SUCCESS           The I2C device path is built successfully.
1303  @return Others                It is failed to built device path.
1304
1305**/
1306EFI_STATUS
1307I2cBusDevicePathAppend (
1308  IN I2C_DEVICE_CONTEXT     *I2cDeviceContext,
1309  IN BOOLEAN                BuildControllerNode
1310  )
1311{
1312  EFI_DEVICE_PATH_PROTOCOL  *PreviousDevicePath;
1313
1314  PreviousDevicePath = NULL;
1315
1316  //
1317  // Build vendor device path
1318  //
1319  CopyMem (&gVendorDevicePathTemplate.Guid, I2cDeviceContext->I2cDevice->DeviceGuid, sizeof (EFI_GUID));
1320  I2cDeviceContext->DevicePath                    = AppendDevicePathNode (
1321                                                      I2cDeviceContext->I2cBusContext->ParentDevicePath,
1322                                                      (EFI_DEVICE_PATH_PROTOCOL *) &gVendorDevicePathTemplate
1323                                                      );
1324  ASSERT (I2cDeviceContext->DevicePath != NULL);
1325  if (I2cDeviceContext->DevicePath == NULL) {
1326    return EFI_OUT_OF_RESOURCES;
1327  }
1328
1329  if ((BuildControllerNode) && (I2cDeviceContext->DevicePath != NULL)) {
1330    //
1331    // Build the final I2C device path with controller node
1332    //
1333    PreviousDevicePath = I2cDeviceContext->DevicePath;
1334    gControllerDevicePathTemplate.ControllerNumber = I2cDeviceContext->I2cDevice->DeviceIndex;
1335    I2cDeviceContext->DevicePath          = AppendDevicePathNode (
1336                                              I2cDeviceContext->DevicePath,
1337                                              (EFI_DEVICE_PATH_PROTOCOL *) &gControllerDevicePathTemplate
1338                                              );
1339    gBS->FreePool (PreviousDevicePath);
1340    ASSERT (I2cDeviceContext->DevicePath != NULL);
1341    if (I2cDeviceContext->DevicePath == NULL) {
1342      return EFI_OUT_OF_RESOURCES;
1343    }
1344  }
1345
1346  return EFI_SUCCESS;
1347}
1348
1349/**
1350  The user entry point for the I2C bus module. The user code starts with
1351  this function.
1352
1353  @param[in] ImageHandle    The firmware allocated handle for the EFI image.
1354  @param[in] SystemTable    A pointer to the EFI System Table.
1355
1356  @retval EFI_SUCCESS       The entry point is executed successfully.
1357  @retval other             Some error occurs when executing this entry point.
1358
1359**/
1360EFI_STATUS
1361EFIAPI
1362InitializeI2cBus(
1363  IN EFI_HANDLE           ImageHandle,
1364  IN EFI_SYSTEM_TABLE     *SystemTable
1365  )
1366{
1367  EFI_STATUS              Status;
1368
1369  //
1370  // Install driver model protocol(s).
1371  //
1372  Status = EfiLibInstallDriverBindingComponentName2 (
1373             ImageHandle,
1374             SystemTable,
1375             &gI2cBusDriverBinding,
1376             NULL,
1377             &gI2cBusComponentName,
1378             &gI2cBusComponentName2
1379             );
1380  ASSERT_EFI_ERROR (Status);
1381
1382
1383  return Status;
1384}
1385
1386/**
1387  This is the unload handle for I2C bus module.
1388
1389  Disconnect the driver specified by ImageHandle from all the devices in the handle database.
1390  Uninstall all the protocols installed in the driver entry point.
1391
1392  @param[in] ImageHandle           The drivers' driver image.
1393
1394  @retval    EFI_SUCCESS           The image is unloaded.
1395  @retval    Others                Failed to unload the image.
1396
1397**/
1398EFI_STATUS
1399EFIAPI
1400I2cBusUnload (
1401  IN EFI_HANDLE             ImageHandle
1402  )
1403{
1404  EFI_STATUS                        Status;
1405  EFI_HANDLE                        *DeviceHandleBuffer;
1406  UINTN                             DeviceHandleCount;
1407  UINTN                             Index;
1408  EFI_COMPONENT_NAME_PROTOCOL       *ComponentName;
1409  EFI_COMPONENT_NAME2_PROTOCOL      *ComponentName2;
1410
1411  //
1412  // Get the list of all I2C Controller handles in the handle database.
1413  // If there is an error getting the list, then the unload
1414  // operation fails.
1415  //
1416  Status = gBS->LocateHandleBuffer (
1417                  ByProtocol,
1418                  &gEfiI2cHostProtocolGuid,
1419                  NULL,
1420                  &DeviceHandleCount,
1421                  &DeviceHandleBuffer
1422                  );
1423
1424  if (!EFI_ERROR (Status)) {
1425    //
1426    // Disconnect the driver specified by Driver BindingHandle from all
1427    // the devices in the handle database.
1428    //
1429    for (Index = 0; Index < DeviceHandleCount; Index++) {
1430      Status = gBS->DisconnectController (
1431                      DeviceHandleBuffer[Index],
1432                      gI2cBusDriverBinding.DriverBindingHandle,
1433                      NULL
1434                      );
1435      if (EFI_ERROR (Status)) {
1436        goto Done;
1437      }
1438    }
1439  }
1440
1441  //
1442  // Uninstall all the protocols installed in the driver entry point
1443  //
1444  Status = gBS->UninstallMultipleProtocolInterfaces (
1445                  gI2cBusDriverBinding.DriverBindingHandle,
1446                  &gEfiDriverBindingProtocolGuid,
1447                  &gI2cBusDriverBinding,
1448                  NULL
1449                  );
1450  ASSERT_EFI_ERROR (Status);
1451
1452  //
1453  // Note we have to one by one uninstall the following protocols.
1454  // It's because some of them are optionally installed based on
1455  // the following PCD settings.
1456  //   gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnosticsDisable
1457  //   gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable
1458  //   gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnostics2Disable
1459  //   gEfiMdePkgTokenSpaceGuid.PcdComponentName2Disable
1460  //
1461  Status = gBS->HandleProtocol (
1462                  gI2cBusDriverBinding.DriverBindingHandle,
1463                  &gEfiComponentNameProtocolGuid,
1464                  (VOID **) &ComponentName
1465                  );
1466  if (!EFI_ERROR (Status)) {
1467    gBS->UninstallProtocolInterface (
1468           gI2cBusDriverBinding.DriverBindingHandle,
1469           &gEfiComponentNameProtocolGuid,
1470           ComponentName
1471           );
1472  }
1473
1474  Status = gBS->HandleProtocol (
1475                  gI2cBusDriverBinding.DriverBindingHandle,
1476                  &gEfiComponentName2ProtocolGuid,
1477                  (VOID **) &ComponentName2
1478                  );
1479  if (!EFI_ERROR (Status)) {
1480    gBS->UninstallProtocolInterface (
1481           gI2cBusDriverBinding.DriverBindingHandle,
1482           &gEfiComponentName2ProtocolGuid,
1483           ComponentName2
1484           );
1485  }
1486
1487  Status = EFI_SUCCESS;
1488
1489Done:
1490  //
1491  // Free the buffer containing the list of handles from the handle database
1492  //
1493  if (DeviceHandleBuffer != NULL) {
1494    gBS->FreePool (DeviceHandleBuffer);
1495  }
1496
1497  return Status;
1498}
1499