TianoCore EDK2 master
Loading...
Searching...
No Matches
I2cBus.c
Go to the documentation of this file.
1
10#include "I2cDxe.h"
11
12//
13// EFI_DRIVER_BINDING_PROTOCOL instance
14//
15EFI_DRIVER_BINDING_PROTOCOL gI2cBusDriverBinding = {
19 0x10,
20 NULL,
21 NULL
22};
23
24//
25// Template for I2C Bus Child Device.
26//
27I2C_DEVICE_CONTEXT gI2cDeviceContextTemplate = {
28 I2C_DEVICE_SIGNATURE,
29 NULL,
30 { // I2cIo Protocol
31 I2cBusQueueRequest, // QueueRequest
32 NULL, // DeviceGuid
33 0, // DeviceIndex
34 0, // HardwareRevision
35 NULL // I2cControllerCapabilities
36 },
37 NULL, // DevicePath
38 NULL, // I2cDevice
39 NULL, // I2cBusContext
40};
41
42//
43// Template for controller device path node.
44//
45CONTROLLER_DEVICE_PATH gControllerDevicePathTemplate = {
46 {
49 {
50 (UINT8)(sizeof (CONTROLLER_DEVICE_PATH)),
51 (UINT8)((sizeof (CONTROLLER_DEVICE_PATH)) >> 8)
52 }
53 },
54 0
55};
56
57//
58// Template for vendor device path node.
59//
60VENDOR_DEVICE_PATH gVendorDevicePathTemplate = {
61 {
64 {
65 (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
66 (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
67 }
68 },
69 { 0x0, 0x0, 0x0, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }
70 }
71};
72
73//
74// Driver name table
75//
77 { "eng;en", (CHAR16 *)L"I2C Bus Driver" },
78 { NULL, NULL }
79};
80
81//
82// EFI Component Name Protocol
83//
87 "eng"
88};
89
90//
91// EFI Component Name 2 Protocol
92//
96 "en"
97};
98
139EFIAPI
142 IN CHAR8 *Language,
143 OUT CHAR16 **DriverName
144 )
145{
146 return LookupUnicodeString2 (
147 Language,
148 This->SupportedLanguages,
149 mI2cBusDriverNameTable,
150 DriverName,
151 (BOOLEAN)(This != &gI2cBusComponentName2)
152 );
153}
154
224EFIAPI
227 IN EFI_HANDLE ControllerHandle,
228 IN EFI_HANDLE ChildHandle OPTIONAL,
229 IN CHAR8 *Language,
230 OUT CHAR16 **ControllerName
231 )
232{
233 return EFI_UNSUPPORTED;
234}
235
252 IN EFI_HANDLE Controller,
253 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath,
254 IN BOOLEAN RemainingHasControllerNode,
255 IN UINT32 RemainingControllerNumber
256 )
257{
258 EFI_STATUS Status;
259 EFI_DEVICE_PATH_PROTOCOL *SystemDevicePath;
261 UINTN EntryCount;
262 UINTN Index;
263 BOOLEAN SystemHasControllerNode;
264 UINT32 SystemControllerNumber;
265
266 SystemHasControllerNode = FALSE;
267 SystemControllerNumber = 0;
268
269 Status = gBS->OpenProtocolInformation (
270 Controller,
272 &OpenInfoBuffer,
273 &EntryCount
274 );
275 if (EFI_ERROR (Status)) {
276 return Status;
277 }
278
279 for (Index = 0; Index < EntryCount; Index++) {
280 if ((OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
281 Status = gBS->OpenProtocol (
282 OpenInfoBuffer[Index].ControllerHandle,
283 &gEfiDevicePathProtocolGuid,
284 (VOID **)&SystemDevicePath,
285 This->DriverBindingHandle,
286 Controller,
287 EFI_OPEN_PROTOCOL_GET_PROTOCOL
288 );
289 if (!EFI_ERROR (Status)) {
290 //
291 // Find vendor device path node and compare
292 //
293 while (!IsDevicePathEnd (SystemDevicePath)) {
294 if ((DevicePathType (SystemDevicePath) == HARDWARE_DEVICE_PATH) &&
295 (DevicePathSubType (SystemDevicePath) == HW_VENDOR_DP))
296 {
297 //
298 // Check if vendor device path is same between system device path and remaining device path
299 //
300 if (CompareMem (SystemDevicePath, RemainingDevicePath, sizeof (VENDOR_DEVICE_PATH)) == 0) {
301 //
302 // Get controller node appended after vendor node
303 //
304 SystemDevicePath = NextDevicePathNode (SystemDevicePath);
305 if ((DevicePathType (SystemDevicePath) == HARDWARE_DEVICE_PATH) &&
306 (DevicePathSubType (SystemDevicePath) == HW_CONTROLLER_DP))
307 {
308 SystemHasControllerNode = TRUE;
309 SystemControllerNumber = ((CONTROLLER_DEVICE_PATH *)SystemDevicePath)->ControllerNumber;
310 } else {
311 SystemHasControllerNode = FALSE;
312 SystemControllerNumber = 0;
313 }
314
315 if (((SystemHasControllerNode) && (!RemainingHasControllerNode) && (SystemControllerNumber == 0)) ||
316 ((!SystemHasControllerNode) && (RemainingHasControllerNode) && (RemainingControllerNumber == 0)) ||
317 ((SystemHasControllerNode) && (RemainingHasControllerNode) && (SystemControllerNumber == RemainingControllerNumber)) ||
318 ((!SystemHasControllerNode) && (!RemainingHasControllerNode)))
319 {
320 DEBUG ((DEBUG_ERROR, "This I2C device has been already started.\n"));
321 Status = EFI_UNSUPPORTED;
322 break;
323 }
324 }
325 }
326
327 SystemDevicePath = NextDevicePathNode (SystemDevicePath);
328 }
329
330 if (EFI_ERROR (Status)) {
331 break;
332 }
333 }
334 }
335 }
336
337 FreePool (OpenInfoBuffer);
338 return Status;
339}
340
384EFIAPI
387 IN EFI_HANDLE Controller,
388 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
389 )
390{
391 EFI_STATUS Status;
392 EFI_I2C_ENUMERATE_PROTOCOL *I2cEnumerate;
393 EFI_I2C_HOST_PROTOCOL *I2cHost;
394 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
395 EFI_DEVICE_PATH_PROTOCOL *DevPathNode;
396 BOOLEAN RemainingHasControllerNode;
397 UINT32 RemainingControllerNumber;
398
399 RemainingHasControllerNode = FALSE;
400 RemainingControllerNumber = 0;
401
402 //
403 // Determine if the I2c Enumerate Protocol is available
404 //
405 Status = gBS->OpenProtocol (
406 Controller,
408 (VOID **)&I2cEnumerate,
409 This->DriverBindingHandle,
410 Controller,
411 EFI_OPEN_PROTOCOL_BY_DRIVER
412 );
413 if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) {
414 return Status;
415 }
416
417 if (!EFI_ERROR (Status)) {
418 gBS->CloseProtocol (
419 Controller,
421 This->DriverBindingHandle,
422 Controller
423 );
424 }
425
426 Status = gBS->OpenProtocol (
427 Controller,
428 &gEfiDevicePathProtocolGuid,
429 (VOID **)&ParentDevicePath,
430 This->DriverBindingHandle,
431 Controller,
432 EFI_OPEN_PROTOCOL_BY_DRIVER
433 );
434
435 if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) {
436 return Status;
437 }
438
439 if (!EFI_ERROR (Status)) {
440 gBS->CloseProtocol (
441 Controller,
442 &gEfiDevicePathProtocolGuid,
443 This->DriverBindingHandle,
444 Controller
445 );
446 }
447
448 if ((RemainingDevicePath != NULL) && !IsDevicePathEnd (RemainingDevicePath)) {
449 //
450 // Check if the first node of RemainingDevicePath is a hardware vendor device path
451 //
452 if ((DevicePathType (RemainingDevicePath) != HARDWARE_DEVICE_PATH) ||
453 (DevicePathSubType (RemainingDevicePath) != HW_VENDOR_DP))
454 {
455 return EFI_UNSUPPORTED;
456 }
457
458 //
459 // Check if the second node of RemainingDevicePath is a controller node
460 //
461 DevPathNode = NextDevicePathNode (RemainingDevicePath);
462 if (!IsDevicePathEnd (DevPathNode)) {
463 if ((DevicePathType (DevPathNode) != HARDWARE_DEVICE_PATH) ||
464 (DevicePathSubType (DevPathNode) != HW_CONTROLLER_DP))
465 {
466 return EFI_UNSUPPORTED;
467 } else {
468 RemainingHasControllerNode = TRUE;
469 RemainingControllerNumber = ((CONTROLLER_DEVICE_PATH *)DevPathNode)->ControllerNumber;
470 }
471 }
472 }
473
474 //
475 // Determine if the I2C Host Protocol is available
476 //
477 Status = gBS->OpenProtocol (
478 Controller,
480 (VOID **)&I2cHost,
481 This->DriverBindingHandle,
482 Controller,
483 EFI_OPEN_PROTOCOL_BY_DRIVER
484 );
485
486 if (!EFI_ERROR (Status)) {
487 gBS->CloseProtocol (
488 Controller,
490 This->DriverBindingHandle,
491 Controller
492 );
493 }
494
495 if (Status == EFI_ALREADY_STARTED) {
496 if ((RemainingDevicePath == NULL) ||
497 ((RemainingDevicePath != NULL) && IsDevicePathEnd (RemainingDevicePath)))
498 {
499 //
500 // If RemainingDevicePath is NULL or is the End of Device Path Node, return EFI_SUCCESS.
501 //
502 Status = EFI_SUCCESS;
503 } else {
504 //
505 // Test if the child with the RemainingDevicePath has already been created.
506 //
507 Status = CheckRemainingDevicePath (
508 This,
509 Controller,
510 RemainingDevicePath,
511 RemainingHasControllerNode,
512 RemainingControllerNumber
513 );
514 }
515 }
516
517 return Status;
518}
519
556EFIAPI
559 IN EFI_HANDLE Controller,
560 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
561 )
562{
563 EFI_I2C_ENUMERATE_PROTOCOL *I2cEnumerate;
564 EFI_I2C_HOST_PROTOCOL *I2cHost;
565 I2C_BUS_CONTEXT *I2cBusContext;
566 EFI_STATUS Status;
567 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
568
569 I2cBusContext = NULL;
570 ParentDevicePath = NULL;
571 I2cEnumerate = NULL;
572 I2cHost = NULL;
573
574 //
575 // Determine if the I2C controller is available
576 //
577 Status = gBS->OpenProtocol (
578 Controller,
580 (VOID **)&I2cHost,
581 This->DriverBindingHandle,
582 Controller,
583 EFI_OPEN_PROTOCOL_BY_DRIVER
584 );
585 if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
586 DEBUG ((DEBUG_ERROR, "I2cBus: open I2C host error, Status = %r\n", Status));
587 return Status;
588 }
589
590 if (Status == EFI_ALREADY_STARTED) {
591 Status = gBS->OpenProtocol (
592 Controller,
593 &gEfiCallerIdGuid,
594 (VOID **)&I2cBusContext,
595 This->DriverBindingHandle,
596 Controller,
597 EFI_OPEN_PROTOCOL_GET_PROTOCOL
598 );
599 if (EFI_ERROR (Status)) {
600 DEBUG ((DEBUG_ERROR, "I2cBus: open private protocol error, Status = %r.\n", Status));
601 return Status;
602 }
603 }
604
605 //
606 // Get the I2C bus enumeration API
607 //
608 Status = gBS->OpenProtocol (
609 Controller,
611 (VOID **)&I2cEnumerate,
612 This->DriverBindingHandle,
613 Controller,
614 EFI_OPEN_PROTOCOL_BY_DRIVER
615 );
616 if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
617 DEBUG ((DEBUG_ERROR, "I2cBus: open I2C enumerate error, Status = %r\n", Status));
618 goto Error;
619 }
620
621 Status = gBS->OpenProtocol (
622 Controller,
623 &gEfiDevicePathProtocolGuid,
624 (VOID **)&ParentDevicePath,
625 This->DriverBindingHandle,
626 Controller,
627 EFI_OPEN_PROTOCOL_BY_DRIVER
628 );
629 if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
630 DEBUG ((DEBUG_ERROR, "I2cBus: open device path error, Status = %r\n", Status));
631 goto Error;
632 }
633
634 if ((RemainingDevicePath != NULL) && IsDevicePathEnd (RemainingDevicePath)) {
635 //
636 // If RemainingDevicePath is the End of Device Path Node,
637 // don't create any child device and return EFI_SUCCESS
638 //
639 return EFI_SUCCESS;
640 }
641
642 //
643 // Allocate the buffer for I2C_BUS_CONTEXT if it is not allocated before.
644 //
645 if (I2cBusContext == NULL) {
646 //
647 // Allocate the I2C context structure for the current I2C controller
648 //
649 I2cBusContext = AllocateZeroPool (sizeof (I2C_BUS_CONTEXT));
650 if (I2cBusContext == NULL) {
651 DEBUG ((DEBUG_ERROR, "I2cBus: there is no enough memory to allocate.\n"));
652 Status = EFI_OUT_OF_RESOURCES;
653 goto Error;
654 }
655
656 /*
657 +----------------+
658 .->| I2C_BUS_CONTEXT|<----- This file Protocol (gEfiCallerIdGuid) installed on I2C Controller handle
659 | +----------------+
660 |
661 | +----------------------------+
662 | | I2C_DEVICE_CONTEXT |
663 `--| |
664 | |
665 | I2C IO Protocol Structure | <----- I2C IO Protocol
666 | |
667 +----------------------------+
668
669 */
670 I2cBusContext->I2cHost = I2cHost;
671 I2cBusContext->I2cEnumerate = I2cEnumerate;
672 //
673 // Parent controller used to create children
674 //
675 I2cBusContext->Controller = Controller;
676 //
677 // Parent controller device path used to create children device path
678 //
679 I2cBusContext->ParentDevicePath = ParentDevicePath;
680
681 I2cBusContext->DriverBindingHandle = This->DriverBindingHandle;
682
683 Status = gBS->InstallMultipleProtocolInterfaces (
684 &Controller,
685 &gEfiCallerIdGuid,
686 I2cBusContext,
687 NULL
688 );
689 if (EFI_ERROR (Status)) {
690 DEBUG ((DEBUG_ERROR, "I2cBus: install private protocol error, Status = %r.\n", Status));
691 goto Error;
692 }
693 }
694
695 //
696 // Start the driver
697 //
698 Status = RegisterI2cDevice (I2cBusContext, Controller, RemainingDevicePath);
699
700 return Status;
701
702Error:
703 if (EFI_ERROR (Status)) {
704 DEBUG ((DEBUG_ERROR, "I2cBus: Start() function failed, Status = %r\n", Status));
705 if (ParentDevicePath != NULL) {
706 gBS->CloseProtocol (
707 Controller,
708 &gEfiDevicePathProtocolGuid,
709 This->DriverBindingHandle,
710 Controller
711 );
712 }
713
714 if (I2cHost != NULL) {
715 gBS->CloseProtocol (
716 Controller,
718 This->DriverBindingHandle,
719 Controller
720 );
721 }
722
723 if (I2cEnumerate != NULL) {
724 gBS->CloseProtocol (
725 Controller,
727 This->DriverBindingHandle,
728 Controller
729 );
730 }
731
732 if (I2cBusContext != NULL) {
733 Status = gBS->UninstallMultipleProtocolInterfaces (
734 Controller,
735 gEfiCallerIdGuid,
736 I2cBusContext,
737 NULL
738 );
739 FreePool (I2cBusContext);
740 }
741 }
742
743 //
744 // Return the operation status.
745 //
746 return Status;
747}
748
776EFIAPI
779 IN EFI_HANDLE Controller,
780 IN UINTN NumberOfChildren,
781 IN EFI_HANDLE *ChildHandleBuffer
782 )
783{
784 I2C_BUS_CONTEXT *I2cBusContext;
785 EFI_STATUS Status;
786 BOOLEAN AllChildrenStopped;
787 UINTN Index;
788
789 if (NumberOfChildren == 0) {
790 gBS->CloseProtocol (
791 Controller,
792 &gEfiDevicePathProtocolGuid,
793 This->DriverBindingHandle,
794 Controller
795 );
796
797 gBS->CloseProtocol (
798 Controller,
800 This->DriverBindingHandle,
801 Controller
802 );
803
804 gBS->CloseProtocol (
805 Controller,
807 This->DriverBindingHandle,
808 Controller
809 );
810
811 Status = gBS->OpenProtocol (
812 Controller,
813 &gEfiCallerIdGuid,
814 (VOID **)&I2cBusContext,
815 This->DriverBindingHandle,
816 Controller,
817 EFI_OPEN_PROTOCOL_GET_PROTOCOL
818 );
819 if (!EFI_ERROR (Status)) {
820 gBS->UninstallMultipleProtocolInterfaces (
821 Controller,
822 &gEfiCallerIdGuid,
823 I2cBusContext,
824 NULL
825 );
826 //
827 // No more child now, free bus context data.
828 //
829 FreePool (I2cBusContext);
830 }
831
832 return Status;
833 }
834
835 AllChildrenStopped = TRUE;
836
837 for (Index = 0; Index < NumberOfChildren; Index++) {
838 Status = UnRegisterI2cDevice (This, Controller, ChildHandleBuffer[Index]);
839 if (EFI_ERROR (Status)) {
840 AllChildrenStopped = FALSE;
841 }
842 }
843
844 if (!AllChildrenStopped) {
845 return EFI_DEVICE_ERROR;
846 }
847
848 return EFI_SUCCESS;
849}
850
867 IN I2C_BUS_CONTEXT *I2cBusContext,
868 IN EFI_HANDLE Controller,
869 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
870 )
871{
872 I2C_DEVICE_CONTEXT *I2cDeviceContext;
873 EFI_STATUS Status;
874 CONST EFI_I2C_DEVICE *Device;
875 CONST EFI_I2C_DEVICE *TempDevice;
876 UINT32 RemainingPathDeviceIndex;
877 EFI_DEVICE_PATH_PROTOCOL *DevPathNode;
878 BOOLEAN BuildControllerNode;
879 UINTN Count;
880
881 Status = EFI_SUCCESS;
882 BuildControllerNode = TRUE;
883
884 //
885 // Default DeviceIndex
886 //
887 RemainingPathDeviceIndex = 0;
888
889 //
890 // Determine the controller number in Controller Node Device Path when RemainingDevicePath is not NULL.
891 //
892 if (RemainingDevicePath != NULL) {
893 //
894 // Check if there is a controller node appended after vendor node
895 //
896 DevPathNode = NextDevicePathNode (RemainingDevicePath);
897 if ((DevicePathType (DevPathNode) == HARDWARE_DEVICE_PATH) &&
898 (DevicePathSubType (DevPathNode) == HW_CONTROLLER_DP))
899 {
900 //
901 // RemainingDevicePath != NULL and RemainingDevicePath contains Controller Node,
902 // add Controller Node to Device Path on child handle.
903 //
904 RemainingPathDeviceIndex = ((CONTROLLER_DEVICE_PATH *)DevPathNode)->ControllerNumber;
905 } else {
906 //
907 // RemainingDevicePath != NULL and RemainingDevicePath does not contain Controller Node,
908 // do not add controller node to Device Path on child handle.
909 //
910 BuildControllerNode = FALSE;
911 }
912 }
913
914 //
915 // Walk the list of I2C devices on this bus
916 //
917 Device = NULL;
918 while (TRUE) {
919 //
920 // Get the next I2C device
921 //
922 Status = I2cBusContext->I2cEnumerate->Enumerate (I2cBusContext->I2cEnumerate, &Device);
923 if (EFI_ERROR (Status) || (Device == NULL)) {
924 if (RemainingDevicePath != NULL) {
925 Status = EFI_NOT_FOUND;
926 } else {
927 Status = EFI_SUCCESS;
928 }
929
930 break;
931 }
932
933 //
934 // Determine if the device info is valid
935 //
936 if ((Device->DeviceGuid == NULL) || (Device->SlaveAddressCount == 0) || (Device->SlaveAddressArray == NULL)) {
937 DEBUG ((DEBUG_ERROR, "Invalid EFI_I2C_DEVICE reported by I2c Enumerate protocol.\n"));
938 continue;
939 }
940
941 if (RemainingDevicePath == NULL) {
942 if (Device->DeviceIndex == 0) {
943 //
944 // Determine if the controller node is necessary when controller number is zero in I2C device
945 //
946 TempDevice = NULL;
947 Count = 0;
948 while (TRUE) {
949 //
950 // Get the next I2C device
951 //
952 Status = I2cBusContext->I2cEnumerate->Enumerate (I2cBusContext->I2cEnumerate, &TempDevice);
953 if (EFI_ERROR (Status) || (TempDevice == NULL)) {
954 Status = EFI_SUCCESS;
955 break;
956 }
957
958 if (CompareGuid (Device->DeviceGuid, TempDevice->DeviceGuid)) {
959 Count++;
960 }
961 }
962
963 if (Count == 1) {
964 //
965 // RemainingDevicePath == NULL and only DeviceIndex 0 is present on the I2C bus,
966 // do not add Controller Node to Device Path on child handle.
967 //
968 BuildControllerNode = FALSE;
969 }
970 }
971 } else {
972 //
973 // Find I2C device reported in Remaining Device Path
974 //
975 if ((!CompareGuid (&((VENDOR_DEVICE_PATH *)RemainingDevicePath)->Guid, Device->DeviceGuid)) ||
976 (RemainingPathDeviceIndex != Device->DeviceIndex))
977 {
978 continue;
979 }
980 }
981
982 //
983 // Build the device context for current I2C device.
984 //
985 I2cDeviceContext = NULL;
986 I2cDeviceContext = AllocateCopyPool (sizeof (I2C_DEVICE_CONTEXT), &gI2cDeviceContextTemplate);
987 ASSERT (I2cDeviceContext != NULL);
988 if (I2cDeviceContext == NULL) {
989 continue;
990 }
991
992 //
993 // Initialize the specific device context
994 //
995 I2cDeviceContext->I2cBusContext = I2cBusContext;
996 I2cDeviceContext->I2cDevice = Device;
997 I2cDeviceContext->I2cIo.DeviceGuid = Device->DeviceGuid;
998 I2cDeviceContext->I2cIo.DeviceIndex = Device->DeviceIndex;
999 I2cDeviceContext->I2cIo.HardwareRevision = Device->HardwareRevision;
1000 I2cDeviceContext->I2cIo.I2cControllerCapabilities = I2cBusContext->I2cHost->I2cControllerCapabilities;
1001
1002 //
1003 // Build the device path
1004 //
1005 Status = I2cBusDevicePathAppend (I2cDeviceContext, BuildControllerNode);
1006 ASSERT_EFI_ERROR (Status);
1007 if (EFI_ERROR (Status)) {
1008 continue;
1009 }
1010
1011 //
1012 // Install the protocol
1013 //
1014 Status = gBS->InstallMultipleProtocolInterfaces (
1015 &I2cDeviceContext->Handle,
1017 &I2cDeviceContext->I2cIo,
1018 &gEfiDevicePathProtocolGuid,
1019 I2cDeviceContext->DevicePath,
1020 NULL
1021 );
1022 if (EFI_ERROR (Status)) {
1023 //
1024 // Free resources for this I2C device
1025 //
1026 ReleaseI2cDeviceContext (I2cDeviceContext);
1027 continue;
1028 }
1029
1030 //
1031 // Create the child handle
1032 //
1033 Status = gBS->OpenProtocol (
1034 Controller,
1036 (VOID **)&I2cBusContext->I2cHost,
1037 I2cBusContext->DriverBindingHandle,
1038 I2cDeviceContext->Handle,
1039 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1040 );
1041 if (EFI_ERROR (Status)) {
1042 Status = gBS->UninstallMultipleProtocolInterfaces (
1043 I2cDeviceContext->Handle,
1044 &gEfiDevicePathProtocolGuid,
1045 I2cDeviceContext->DevicePath,
1047 &I2cDeviceContext->I2cIo,
1048 NULL
1049 );
1050 //
1051 // Free resources for this I2C device
1052 //
1053 ReleaseI2cDeviceContext (I2cDeviceContext);
1054 continue;
1055 }
1056
1057 if (RemainingDevicePath != NULL) {
1058 //
1059 // Child has been created successfully
1060 //
1061 break;
1062 }
1063 }
1064
1065 return Status;
1066}
1067
1140EFIAPI
1143 IN UINTN SlaveAddressIndex,
1144 IN EFI_EVENT Event OPTIONAL,
1145 IN EFI_I2C_REQUEST_PACKET *RequestPacket,
1146 OUT EFI_STATUS *I2cStatus OPTIONAL
1147 )
1148{
1149 CONST EFI_I2C_DEVICE *I2cDevice;
1150 I2C_BUS_CONTEXT *I2cBusContext;
1152 I2C_DEVICE_CONTEXT *I2cDeviceContext;
1153 EFI_STATUS Status;
1154
1155 if (RequestPacket == NULL) {
1156 return EFI_INVALID_PARAMETER;
1157 }
1158
1159 //
1160 // Validate the I2C slave index
1161 //
1162 I2cDeviceContext = I2C_DEVICE_CONTEXT_FROM_PROTOCOL (This);
1163 I2cDevice = I2cDeviceContext->I2cDevice;
1164 if ( SlaveAddressIndex >= I2cDevice->SlaveAddressCount ) {
1165 return EFI_INVALID_PARAMETER;
1166 }
1167
1168 //
1169 // Locate the I2c Host Protocol to queue request
1170 //
1171 I2cBusContext = I2cDeviceContext->I2cBusContext;
1172 I2cHost = I2cBusContext->I2cHost;
1173
1174 //
1175 // Start the I2C operation
1176 //
1177 Status = I2cHost->QueueRequest (
1178 I2cHost,
1179 I2cDevice->I2cBusConfiguration,
1180 I2cDevice->SlaveAddressArray[SlaveAddressIndex],
1181 Event,
1182 RequestPacket,
1183 I2cStatus
1184 );
1185
1186 return Status;
1187}
1188
1197VOID
1199 IN I2C_DEVICE_CONTEXT *I2cDeviceContext
1200 )
1201{
1202 if (I2cDeviceContext == NULL) {
1203 return;
1204 }
1205
1206 if (I2cDeviceContext->DevicePath != NULL) {
1207 FreePool (I2cDeviceContext->DevicePath);
1208 }
1209
1210 FreePool (I2cDeviceContext);
1211}
1212
1230 IN EFI_HANDLE Controller,
1231 IN EFI_HANDLE Handle
1232 )
1233{
1234 EFI_STATUS Status;
1235 I2C_DEVICE_CONTEXT *I2cDeviceContext;
1236 EFI_I2C_IO_PROTOCOL *I2cIo;
1237 EFI_I2C_HOST_PROTOCOL *I2cHost;
1238
1239 I2cIo = NULL;
1240
1241 Status = gBS->OpenProtocol (
1242 Handle,
1244 (VOID **)&I2cIo,
1245 This->DriverBindingHandle,
1246 Controller,
1247 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1248 );
1249 if (EFI_ERROR (Status)) {
1250 return Status;
1251 }
1252
1253 //
1254 // Get I2c device context data.
1255 //
1256 I2cDeviceContext = I2C_DEVICE_CONTEXT_FROM_PROTOCOL (I2cIo);
1257
1258 //
1259 // Close the child handle
1260 //
1261 gBS->CloseProtocol (
1262 Controller,
1264 This->DriverBindingHandle,
1265 Handle
1266 );
1267
1268 //
1269 // The I2C Bus driver installs the I2C Io and Device Path Protocol in the DriverBindingStart().
1270 // Here should uninstall them.
1271 //
1272 Status = gBS->UninstallMultipleProtocolInterfaces (
1273 Handle,
1274 &gEfiDevicePathProtocolGuid,
1275 I2cDeviceContext->DevicePath,
1277 &I2cDeviceContext->I2cIo,
1278 NULL
1279 );
1280
1281 if (EFI_ERROR (Status)) {
1282 //
1283 // Keep parent and child relationship
1284 //
1285 gBS->OpenProtocol (
1286 Controller,
1288 (VOID **)&I2cHost,
1289 This->DriverBindingHandle,
1290 Handle,
1291 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1292 );
1293 return Status;
1294 }
1295
1296 //
1297 // Free resources for this I2C device
1298 //
1299 ReleaseI2cDeviceContext (I2cDeviceContext);
1300
1301 return EFI_SUCCESS;
1302}
1303
1318 IN I2C_DEVICE_CONTEXT *I2cDeviceContext,
1319 IN BOOLEAN BuildControllerNode
1320 )
1321{
1322 EFI_DEVICE_PATH_PROTOCOL *PreviousDevicePath;
1323
1324 PreviousDevicePath = NULL;
1325
1326 //
1327 // Build vendor device path
1328 //
1329 CopyMem (&gVendorDevicePathTemplate.Guid, I2cDeviceContext->I2cDevice->DeviceGuid, sizeof (EFI_GUID));
1330 I2cDeviceContext->DevicePath = AppendDevicePathNode (
1331 I2cDeviceContext->I2cBusContext->ParentDevicePath,
1332 (EFI_DEVICE_PATH_PROTOCOL *)&gVendorDevicePathTemplate
1333 );
1334 ASSERT (I2cDeviceContext->DevicePath != NULL);
1335 if (I2cDeviceContext->DevicePath == NULL) {
1336 return EFI_OUT_OF_RESOURCES;
1337 }
1338
1339 if ((BuildControllerNode) && (I2cDeviceContext->DevicePath != NULL)) {
1340 //
1341 // Build the final I2C device path with controller node
1342 //
1343 PreviousDevicePath = I2cDeviceContext->DevicePath;
1344 gControllerDevicePathTemplate.ControllerNumber = I2cDeviceContext->I2cDevice->DeviceIndex;
1345 I2cDeviceContext->DevicePath = AppendDevicePathNode (
1346 I2cDeviceContext->DevicePath,
1347 (EFI_DEVICE_PATH_PROTOCOL *)&gControllerDevicePathTemplate
1348 );
1349 gBS->FreePool (PreviousDevicePath);
1350 ASSERT (I2cDeviceContext->DevicePath != NULL);
1351 if (I2cDeviceContext->DevicePath == NULL) {
1352 return EFI_OUT_OF_RESOURCES;
1353 }
1354 }
1355
1356 return EFI_SUCCESS;
1357}
1358
1371EFIAPI
1373 IN EFI_HANDLE ImageHandle,
1374 IN EFI_SYSTEM_TABLE *SystemTable
1375 )
1376{
1377 EFI_STATUS Status;
1378
1379 //
1380 // Install driver model protocol(s).
1381 //
1383 ImageHandle,
1384 SystemTable,
1385 &gI2cBusDriverBinding,
1386 NULL,
1387 &gI2cBusComponentName,
1388 &gI2cBusComponentName2
1389 );
1390 ASSERT_EFI_ERROR (Status);
1391
1392 return Status;
1393}
1394
1408EFIAPI
1410 IN EFI_HANDLE ImageHandle
1411 )
1412{
1413 EFI_STATUS Status;
1414 EFI_HANDLE *DeviceHandleBuffer;
1415 UINTN DeviceHandleCount;
1416 UINTN Index;
1417 EFI_COMPONENT_NAME_PROTOCOL *ComponentName;
1418 EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2;
1419
1420 //
1421 // Get the list of all I2C Controller handles in the handle database.
1422 // If there is an error getting the list, then the unload
1423 // operation fails.
1424 //
1425 Status = gBS->LocateHandleBuffer (
1426 ByProtocol,
1428 NULL,
1429 &DeviceHandleCount,
1430 &DeviceHandleBuffer
1431 );
1432
1433 if (!EFI_ERROR (Status)) {
1434 //
1435 // Disconnect the driver specified by Driver BindingHandle from all
1436 // the devices in the handle database.
1437 //
1438 for (Index = 0; Index < DeviceHandleCount; Index++) {
1439 Status = gBS->DisconnectController (
1440 DeviceHandleBuffer[Index],
1441 gI2cBusDriverBinding.DriverBindingHandle,
1442 NULL
1443 );
1444 if (EFI_ERROR (Status)) {
1445 goto Done;
1446 }
1447 }
1448 }
1449
1450 //
1451 // Uninstall all the protocols installed in the driver entry point
1452 //
1453 Status = gBS->UninstallMultipleProtocolInterfaces (
1454 gI2cBusDriverBinding.DriverBindingHandle,
1455 &gEfiDriverBindingProtocolGuid,
1456 &gI2cBusDriverBinding,
1457 NULL
1458 );
1459 ASSERT_EFI_ERROR (Status);
1460
1461 //
1462 // Note we have to one by one uninstall the following protocols.
1463 // It's because some of them are optionally installed based on
1464 // the following PCD settings.
1465 // gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnosticsDisable
1466 // gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable
1467 // gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnostics2Disable
1468 // gEfiMdePkgTokenSpaceGuid.PcdComponentName2Disable
1469 //
1470 Status = gBS->HandleProtocol (
1471 gI2cBusDriverBinding.DriverBindingHandle,
1472 &gEfiComponentNameProtocolGuid,
1473 (VOID **)&ComponentName
1474 );
1475 if (!EFI_ERROR (Status)) {
1476 gBS->UninstallProtocolInterface (
1477 gI2cBusDriverBinding.DriverBindingHandle,
1478 &gEfiComponentNameProtocolGuid,
1479 ComponentName
1480 );
1481 }
1482
1483 Status = gBS->HandleProtocol (
1484 gI2cBusDriverBinding.DriverBindingHandle,
1485 &gEfiComponentName2ProtocolGuid,
1486 (VOID **)&ComponentName2
1487 );
1488 if (!EFI_ERROR (Status)) {
1489 gBS->UninstallProtocolInterface (
1490 gI2cBusDriverBinding.DriverBindingHandle,
1491 &gEfiComponentName2ProtocolGuid,
1492 ComponentName2
1493 );
1494 }
1495
1496 Status = EFI_SUCCESS;
1497
1498Done:
1499 //
1500 // Free the buffer containing the list of handles from the handle database
1501 //
1502 if (DeviceHandleBuffer != NULL) {
1503 gBS->FreePool (DeviceHandleBuffer);
1504 }
1505
1506 return Status;
1507}
UINT64 UINTN
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
#define HARDWARE_DEVICE_PATH
Definition: DevicePath.h:68
#define HW_VENDOR_DP
Definition: DevicePath.h:133
#define HW_CONTROLLER_DP
Definition: DevicePath.h:154
UINT8 EFIAPI DevicePathType(IN CONST VOID *Node)
UINT8 EFIAPI DevicePathSubType(IN CONST VOID *Node)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI AppendDevicePathNode(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL, IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL)
BOOLEAN EFIAPI IsDevicePathEnd(IN CONST VOID *Node)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI NextDevicePathNode(IN CONST VOID *Node)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID *EFIAPI AllocateCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
EFI_STATUS EFIAPI I2cBusUnload(IN EFI_HANDLE ImageHandle)
Definition: I2cBus.c:1409
EFI_STATUS UnRegisterI2cDevice(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_HANDLE Handle)
Definition: I2cBus.c:1228
EFI_STATUS RegisterI2cDevice(IN I2C_BUS_CONTEXT *I2cBusContext, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
Definition: I2cBus.c:866
EFI_STATUS EFIAPI I2cBusDriverStart(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
Definition: I2cBus.c:557
EFI_STATUS I2cBusDevicePathAppend(IN I2C_DEVICE_CONTEXT *I2cDeviceContext, IN BOOLEAN BuildControllerNode)
Definition: I2cBus.c:1317
VOID ReleaseI2cDeviceContext(IN I2C_DEVICE_CONTEXT *I2cDeviceContext)
Definition: I2cBus.c:1198
EFI_STATUS EFIAPI I2cBusDriverSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
Definition: I2cBus.c:385
EFI_STATUS EFIAPI I2cBusQueueRequest(IN CONST EFI_I2C_IO_PROTOCOL *This, IN UINTN SlaveAddressIndex, IN EFI_EVENT Event OPTIONAL, IN EFI_I2C_REQUEST_PACKET *RequestPacket, OUT EFI_STATUS *I2cStatus OPTIONAL)
Definition: I2cBus.c:1141
EFI_STATUS EFIAPI InitializeI2cBus(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
Definition: I2cBus.c:1372
EFI_STATUS EFIAPI I2cBusDriverStop(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer)
Definition: I2cBus.c:777
EFI_STATUS CheckRemainingDevicePath(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath, IN BOOLEAN RemainingHasControllerNode, IN UINT32 RemainingControllerNumber)
Definition: I2cBus.c:250
EFI_STATUS EFIAPI I2cBusComponentNameGetControllerName(IN EFI_COMPONENT_NAME2_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE ChildHandle OPTIONAL, IN CHAR8 *Language, OUT CHAR16 **ControllerName)
Definition: I2cBus.c:225
EFI_STATUS EFIAPI I2cBusComponentNameGetDriverName(IN EFI_COMPONENT_NAME2_PROTOCOL *This, IN CHAR8 *Language, OUT CHAR16 **DriverName)
Definition: I2cBus.c:140
EFI_GUID gEfiI2cEnumerateProtocolGuid
EFI_GUID gEfiI2cHostProtocolGuid
EFI_GUID gEfiI2cIoProtocolGuid
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define GLOBAL_REMOVE_IF_UNREFERENCED
Definition: Base.h:48
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
EFI_STATUS(EFIAPI * EFI_COMPONENT_NAME_GET_CONTROLLER_NAME)(IN EFI_COMPONENT_NAME_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE ChildHandle OPTIONAL, IN CHAR8 *Language, OUT CHAR16 **ControllerName)
Definition: ComponentName.h:96
EFI_STATUS(EFIAPI * EFI_COMPONENT_NAME_GET_DRIVER_NAME)(IN EFI_COMPONENT_NAME_PROTOCOL *This, IN CHAR8 *Language, OUT CHAR16 **DriverName)
Definition: ComponentName.h:48
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_EVENT
Definition: UefiBaseType.h:37
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
EFI_STATUS EFIAPI LookupUnicodeString2(IN CONST CHAR8 *Language, IN CONST CHAR8 *SupportedLanguages, IN CONST EFI_UNICODE_STRING_TABLE *UnicodeStringTable, OUT CHAR16 **UnicodeString, IN BOOLEAN Iso639Language)
Definition: UefiLib.c:801
EFI_STATUS EFIAPI EfiLibInstallDriverBindingComponentName2(IN CONST EFI_HANDLE ImageHandle, IN CONST EFI_SYSTEM_TABLE *SystemTable, IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding, IN EFI_HANDLE DriverBindingHandle, IN CONST EFI_COMPONENT_NAME_PROTOCOL *ComponentName OPTIONAL, IN CONST EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2 OPTIONAL)
@ ByProtocol
Definition: UefiSpec.h:1518
EFI_I2C_HOST_PROTOCOL_QUEUE_REQUEST QueueRequest
Definition: I2cHost.h:131
UINT32 DeviceIndex
Definition: I2cIo.h:144
CONST EFI_GUID * DeviceGuid
Definition: I2cIo.h:139
UINT32 HardwareRevision
Definition: I2cIo.h:151
CONST EFI_I2C_CONTROLLER_CAPABILITIES * I2cControllerCapabilities
Definition: I2cIo.h:157
Definition: Base.h:213