TianoCore EDK2 master
Loading...
Searching...
No Matches
DriverSupport.c
Go to the documentation of this file.
1
9#include "DxeMain.h"
10#include "Handle.h"
11
12//
13// Driver Support Functions
14//
15
43EFIAPI
45 IN EFI_HANDLE ControllerHandle,
46 IN EFI_HANDLE *DriverImageHandle OPTIONAL,
47 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL,
48 IN BOOLEAN Recursive
49 )
50{
51 EFI_STATUS Status;
52 EFI_STATUS ReturnStatus;
53 IHANDLE *Handle;
55 LIST_ENTRY *Link;
56 LIST_ENTRY *ProtLink;
57 OPEN_PROTOCOL_DATA *OpenData;
58 EFI_DEVICE_PATH_PROTOCOL *AlignedRemainingDevicePath;
59 EFI_HANDLE *ChildHandleBuffer;
60 UINTN ChildHandleCount;
61 UINTN Index;
62 UINTN HandleFilePathSize;
63 UINTN RemainingDevicePathSize;
64 EFI_DEVICE_PATH_PROTOCOL *HandleFilePath;
66 EFI_DEVICE_PATH_PROTOCOL *TempFilePath;
67
68 //
69 // Make sure ControllerHandle is valid
70 //
72
73 Status = CoreValidateHandle (ControllerHandle);
74
76
77 if (EFI_ERROR (Status)) {
78 return Status;
79 }
80
81 if (gSecurity2 != NULL) {
82 //
83 // Check whether the user has permission to start UEFI device drivers.
84 //
85 Status = CoreHandleProtocol (ControllerHandle, &gEfiDevicePathProtocolGuid, (VOID **)&HandleFilePath);
86 if (!EFI_ERROR (Status)) {
87 ASSERT (HandleFilePath != NULL);
88 FilePath = HandleFilePath;
89 TempFilePath = NULL;
90 if ((RemainingDevicePath != NULL) && !Recursive) {
91 HandleFilePathSize = GetDevicePathSize (HandleFilePath) - sizeof (EFI_DEVICE_PATH_PROTOCOL);
92 RemainingDevicePathSize = GetDevicePathSize (RemainingDevicePath);
93 TempFilePath = AllocateZeroPool (HandleFilePathSize + RemainingDevicePathSize);
94 ASSERT (TempFilePath != NULL);
95 CopyMem (TempFilePath, HandleFilePath, HandleFilePathSize);
96 CopyMem ((UINT8 *)TempFilePath + HandleFilePathSize, RemainingDevicePath, RemainingDevicePathSize);
97 FilePath = TempFilePath;
98 }
99
100 Status = gSecurity2->FileAuthentication (
101 gSecurity2,
102 FilePath,
103 NULL,
104 0,
105 FALSE
106 );
107 if (TempFilePath != NULL) {
108 FreePool (TempFilePath);
109 }
110
111 if (EFI_ERROR (Status)) {
112 return Status;
113 }
114 }
115 }
116
117 Handle = ControllerHandle;
118
119 //
120 // Make a copy of RemainingDevicePath to guanatee it is aligned
121 //
122 AlignedRemainingDevicePath = NULL;
123 if (RemainingDevicePath != NULL) {
124 AlignedRemainingDevicePath = DuplicateDevicePath (RemainingDevicePath);
125
126 if (AlignedRemainingDevicePath == NULL) {
127 return EFI_OUT_OF_RESOURCES;
128 }
129 }
130
131 //
132 // Connect all drivers to ControllerHandle
133 // If CoreConnectSingleController returns EFI_NOT_READY, then the number of
134 // Driver Binding Protocols in the handle database has increased during the call
135 // so the connect operation must be restarted
136 //
137 do {
138 ReturnStatus = CoreConnectSingleController (
139 ControllerHandle,
140 DriverImageHandle,
141 AlignedRemainingDevicePath
142 );
143 } while (ReturnStatus == EFI_NOT_READY);
144
145 //
146 // Free the aligned copy of RemainingDevicePath
147 //
148 if (AlignedRemainingDevicePath != NULL) {
149 CoreFreePool (AlignedRemainingDevicePath);
150 }
151
152 //
153 // If recursive, then connect all drivers to all of ControllerHandle's children
154 //
155 if (Recursive) {
156 //
157 // Acquire the protocol lock on the handle database so the child handles can be collected
158 //
160
161 //
162 // Make sure the DriverBindingHandle is valid
163 //
164 Status = CoreValidateHandle (ControllerHandle);
165 if (EFI_ERROR (Status)) {
166 //
167 // Release the protocol lock on the handle database
168 //
170
171 return ReturnStatus;
172 }
173
174 //
175 // Count ControllerHandle's children
176 //
177 for (Link = Handle->Protocols.ForwardLink, ChildHandleCount = 0; Link != &Handle->Protocols; Link = Link->ForwardLink) {
178 Prot = CR (Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
179 for (ProtLink = Prot->OpenList.ForwardLink;
180 ProtLink != &Prot->OpenList;
181 ProtLink = ProtLink->ForwardLink)
182 {
183 OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
184 if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
185 ChildHandleCount++;
186 }
187 }
188 }
189
190 //
191 // Allocate a handle buffer for ControllerHandle's children
192 //
193 ChildHandleBuffer = AllocatePool (ChildHandleCount * sizeof (EFI_HANDLE));
194 if (ChildHandleBuffer == NULL) {
196 return EFI_OUT_OF_RESOURCES;
197 }
198
199 //
200 // Fill in a handle buffer with ControllerHandle's children
201 //
202 for (Link = Handle->Protocols.ForwardLink, ChildHandleCount = 0; Link != &Handle->Protocols; Link = Link->ForwardLink) {
203 Prot = CR (Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
204 for (ProtLink = Prot->OpenList.ForwardLink;
205 ProtLink != &Prot->OpenList;
206 ProtLink = ProtLink->ForwardLink)
207 {
208 OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
209 if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
210 ChildHandleBuffer[ChildHandleCount] = OpenData->ControllerHandle;
211 ChildHandleCount++;
212 }
213 }
214 }
215
216 //
217 // Release the protocol lock on the handle database
218 //
220
221 //
222 // Recursively connect each child handle
223 //
224 for (Index = 0; Index < ChildHandleCount; Index++) {
226 ChildHandleBuffer[Index],
227 NULL,
228 NULL,
229 TRUE
230 );
231 }
232
233 //
234 // Free the handle buffer of ControllerHandle's children
235 //
236 CoreFreePool (ChildHandleBuffer);
237 }
238
239 return ReturnStatus;
240}
241
261VOID
263 IN EFI_HANDLE DriverBindingHandle,
264 IN OUT UINTN *NumberOfSortedDriverBindingProtocols,
265 IN OUT EFI_DRIVER_BINDING_PROTOCOL **SortedDriverBindingProtocols,
266 IN UINTN DriverBindingHandleCount,
267 IN OUT EFI_HANDLE *DriverBindingHandleBuffer,
268 IN BOOLEAN IsImageHandle
269 )
270{
271 EFI_STATUS Status;
272 EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
273 UINTN Index;
274
275 //
276 // Make sure the DriverBindingHandle is valid
277 //
279
280 Status = CoreValidateHandle (DriverBindingHandle);
281
283
284 if (EFI_ERROR (Status)) {
285 return;
286 }
287
288 //
289 // If IsImageHandle is TRUE, then DriverBindingHandle is an image handle
290 // Find all the DriverBindingHandles associated with that image handle and add them to the sorted list
291 //
292 if (IsImageHandle) {
293 //
294 // Loop through all the Driver Binding Handles
295 //
296 for (Index = 0; Index < DriverBindingHandleCount; Index++) {
297 //
298 // Retrieve the Driver Binding Protocol associated with each Driver Binding Handle
299 //
300 Status = CoreHandleProtocol (
301 DriverBindingHandleBuffer[Index],
302 &gEfiDriverBindingProtocolGuid,
303 (VOID **)&DriverBinding
304 );
305 if (EFI_ERROR (Status) || (DriverBinding == NULL)) {
306 continue;
307 }
308
309 //
310 // If the ImageHandle associated with DriverBinding matches DriverBindingHandle,
311 // then add the DriverBindingProtocol[Index] to the sorted list
312 //
313 if (DriverBinding->ImageHandle == DriverBindingHandle) {
315 DriverBindingHandleBuffer[Index],
316 NumberOfSortedDriverBindingProtocols,
317 SortedDriverBindingProtocols,
318 DriverBindingHandleCount,
319 DriverBindingHandleBuffer,
320 FALSE
321 );
322 }
323 }
324
325 return;
326 }
327
328 //
329 // Retrieve the Driver Binding Protocol from DriverBindingHandle
330 //
331 Status = CoreHandleProtocol (
332 DriverBindingHandle,
333 &gEfiDriverBindingProtocolGuid,
334 (VOID **)&DriverBinding
335 );
336 //
337 // If DriverBindingHandle does not support the Driver Binding Protocol then return
338 //
339 if (EFI_ERROR (Status) || (DriverBinding == NULL)) {
340 return;
341 }
342
343 //
344 // See if DriverBinding is already in the sorted list
345 //
346 for (Index = 0; Index < *NumberOfSortedDriverBindingProtocols && Index < DriverBindingHandleCount; Index++) {
347 if (DriverBinding == SortedDriverBindingProtocols[Index]) {
348 return;
349 }
350 }
351
352 //
353 // Add DriverBinding to the end of the list
354 //
355 if (*NumberOfSortedDriverBindingProtocols < DriverBindingHandleCount) {
356 SortedDriverBindingProtocols[*NumberOfSortedDriverBindingProtocols] = DriverBinding;
357 }
358
359 *NumberOfSortedDriverBindingProtocols = *NumberOfSortedDriverBindingProtocols + 1;
360
361 //
362 // Mark the cooresponding handle in DriverBindingHandleBuffer as used
363 //
364 for (Index = 0; Index < DriverBindingHandleCount; Index++) {
365 if (DriverBindingHandleBuffer[Index] == DriverBindingHandle) {
366 DriverBindingHandleBuffer[Index] = NULL;
367 }
368 }
369}
370
394 IN EFI_HANDLE ControllerHandle,
395 IN EFI_HANDLE *ContextDriverImageHandles OPTIONAL,
396 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
397 )
398{
399 EFI_STATUS Status;
400 UINTN Index;
401 EFI_HANDLE DriverImageHandle;
402 EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *PlatformDriverOverride;
403 EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *BusSpecificDriverOverride;
404 UINTN DriverBindingHandleCount;
405 EFI_HANDLE *DriverBindingHandleBuffer;
406 UINTN NewDriverBindingHandleCount;
407 EFI_HANDLE *NewDriverBindingHandleBuffer;
408 EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
409 EFI_DRIVER_FAMILY_OVERRIDE_PROTOCOL *DriverFamilyOverride;
410 UINTN NumberOfSortedDriverBindingProtocols;
411 EFI_DRIVER_BINDING_PROTOCOL **SortedDriverBindingProtocols;
412 UINT32 DriverFamilyOverrideVersion;
413 UINT32 HighestVersion;
414 UINTN HighestIndex;
415 UINTN SortIndex;
416 BOOLEAN OneStarted;
417 BOOLEAN DriverFound;
418
419 //
420 // Initialize local variables
421 //
422 DriverBindingHandleCount = 0;
423 DriverBindingHandleBuffer = NULL;
424 NumberOfSortedDriverBindingProtocols = 0;
425 SortedDriverBindingProtocols = NULL;
426 PlatformDriverOverride = NULL;
427 NewDriverBindingHandleBuffer = NULL;
428
429 //
430 // Get list of all Driver Binding Protocol Instances
431 //
432 Status = CoreLocateHandleBuffer (
434 &gEfiDriverBindingProtocolGuid,
435 NULL,
436 &DriverBindingHandleCount,
437 &DriverBindingHandleBuffer
438 );
439 if (EFI_ERROR (Status) || (DriverBindingHandleCount == 0)) {
440 return EFI_NOT_FOUND;
441 }
442
443 //
444 // Allocate a duplicate array for the sorted Driver Binding Protocol Instances
445 //
446 SortedDriverBindingProtocols = AllocatePool (sizeof (VOID *) * DriverBindingHandleCount);
447 if (SortedDriverBindingProtocols == NULL) {
448 CoreFreePool (DriverBindingHandleBuffer);
449 return EFI_OUT_OF_RESOURCES;
450 }
451
452 //
453 // Add Driver Binding Protocols from Context Driver Image Handles first
454 //
455 if (ContextDriverImageHandles != NULL) {
456 for (Index = 0; ContextDriverImageHandles[Index] != NULL; Index++) {
458 ContextDriverImageHandles[Index],
459 &NumberOfSortedDriverBindingProtocols,
460 SortedDriverBindingProtocols,
461 DriverBindingHandleCount,
462 DriverBindingHandleBuffer,
463 FALSE
464 );
465 }
466 }
467
468 //
469 // Add the Platform Driver Override Protocol drivers for ControllerHandle next
470 //
471 Status = CoreLocateProtocol (
472 &gEfiPlatformDriverOverrideProtocolGuid,
473 NULL,
474 (VOID **)&PlatformDriverOverride
475 );
476 if (!EFI_ERROR (Status) && (PlatformDriverOverride != NULL)) {
477 DriverImageHandle = NULL;
478 do {
479 Status = PlatformDriverOverride->GetDriver (
480 PlatformDriverOverride,
481 ControllerHandle,
482 &DriverImageHandle
483 );
484 if (!EFI_ERROR (Status)) {
486 DriverImageHandle,
487 &NumberOfSortedDriverBindingProtocols,
488 SortedDriverBindingProtocols,
489 DriverBindingHandleCount,
490 DriverBindingHandleBuffer,
491 TRUE
492 );
493 }
494 } while (!EFI_ERROR (Status));
495 }
496
497 //
498 // Add the Driver Family Override Protocol drivers for ControllerHandle
499 //
500 Status = CoreLocateProtocol (
501 &gEfiDriverFamilyOverrideProtocolGuid,
502 NULL,
503 (VOID **)&DriverFamilyOverride
504 );
505 while (!EFI_ERROR (Status) && (DriverFamilyOverride != NULL)) {
506 HighestIndex = DriverBindingHandleCount;
507 HighestVersion = 0;
508 for (Index = 0; Index < DriverBindingHandleCount; Index++) {
509 Status = CoreHandleProtocol (
510 DriverBindingHandleBuffer[Index],
511 &gEfiDriverFamilyOverrideProtocolGuid,
512 (VOID **)&DriverFamilyOverride
513 );
514 if (!EFI_ERROR (Status) && (DriverFamilyOverride != NULL)) {
515 DriverFamilyOverrideVersion = DriverFamilyOverride->GetVersion (DriverFamilyOverride);
516 if ((HighestIndex == DriverBindingHandleCount) || (DriverFamilyOverrideVersion > HighestVersion)) {
517 HighestVersion = DriverFamilyOverrideVersion;
518 HighestIndex = Index;
519 }
520 }
521 }
522
523 if (HighestIndex == DriverBindingHandleCount) {
524 break;
525 }
526
528 DriverBindingHandleBuffer[HighestIndex],
529 &NumberOfSortedDriverBindingProtocols,
530 SortedDriverBindingProtocols,
531 DriverBindingHandleCount,
532 DriverBindingHandleBuffer,
533 FALSE
534 );
535 }
536
537 //
538 // Get the Bus Specific Driver Override Protocol instance on the Controller Handle
539 //
540 Status = CoreHandleProtocol (
541 ControllerHandle,
542 &gEfiBusSpecificDriverOverrideProtocolGuid,
543 (VOID **)&BusSpecificDriverOverride
544 );
545 if (!EFI_ERROR (Status) && (BusSpecificDriverOverride != NULL)) {
546 DriverImageHandle = NULL;
547 do {
548 Status = BusSpecificDriverOverride->GetDriver (
549 BusSpecificDriverOverride,
550 &DriverImageHandle
551 );
552 if (!EFI_ERROR (Status)) {
554 DriverImageHandle,
555 &NumberOfSortedDriverBindingProtocols,
556 SortedDriverBindingProtocols,
557 DriverBindingHandleCount,
558 DriverBindingHandleBuffer,
559 TRUE
560 );
561 }
562 } while (!EFI_ERROR (Status));
563 }
564
565 //
566 // Then add all the remaining Driver Binding Protocols
567 //
568 SortIndex = NumberOfSortedDriverBindingProtocols;
569 for (Index = 0; Index < DriverBindingHandleCount; Index++) {
571 DriverBindingHandleBuffer[Index],
572 &NumberOfSortedDriverBindingProtocols,
573 SortedDriverBindingProtocols,
574 DriverBindingHandleCount,
575 DriverBindingHandleBuffer,
576 FALSE
577 );
578 }
579
580 //
581 // Free the Driver Binding Handle Buffer
582 //
583 CoreFreePool (DriverBindingHandleBuffer);
584
585 //
586 // If the number of Driver Binding Protocols has increased since this function started, then return
587 // EFI_NOT_READY, so it will be restarted
588 //
589 Status = CoreLocateHandleBuffer (
591 &gEfiDriverBindingProtocolGuid,
592 NULL,
593 &NewDriverBindingHandleCount,
594 &NewDriverBindingHandleBuffer
595 );
596 CoreFreePool (NewDriverBindingHandleBuffer);
597 if (NewDriverBindingHandleCount > DriverBindingHandleCount) {
598 //
599 // Free any buffers that were allocated with AllocatePool()
600 //
601 CoreFreePool (SortedDriverBindingProtocols);
602
603 return EFI_NOT_READY;
604 }
605
606 //
607 // Sort the remaining DriverBinding Protocol based on their Version field from
608 // highest to lowest.
609 //
610 for ( ; SortIndex < NumberOfSortedDriverBindingProtocols; SortIndex++) {
611 HighestVersion = SortedDriverBindingProtocols[SortIndex]->Version;
612 HighestIndex = SortIndex;
613 for (Index = SortIndex + 1; Index < NumberOfSortedDriverBindingProtocols; Index++) {
614 if (SortedDriverBindingProtocols[Index]->Version > HighestVersion) {
615 HighestVersion = SortedDriverBindingProtocols[Index]->Version;
616 HighestIndex = Index;
617 }
618 }
619
620 if (SortIndex != HighestIndex) {
621 DriverBinding = SortedDriverBindingProtocols[SortIndex];
622 SortedDriverBindingProtocols[SortIndex] = SortedDriverBindingProtocols[HighestIndex];
623 SortedDriverBindingProtocols[HighestIndex] = DriverBinding;
624 }
625 }
626
627 //
628 // Loop until no more drivers can be started on ControllerHandle
629 //
630 OneStarted = FALSE;
631 do {
632 //
633 // Loop through the sorted Driver Binding Protocol Instances in order, and see if
634 // any of the Driver Binding Protocols support the controller specified by
635 // ControllerHandle.
636 //
637 DriverBinding = NULL;
638 DriverFound = FALSE;
639 for (Index = 0; (Index < NumberOfSortedDriverBindingProtocols) && !DriverFound; Index++) {
640 if (SortedDriverBindingProtocols[Index] != NULL) {
641 DriverBinding = SortedDriverBindingProtocols[Index];
642 PERF_DRIVER_BINDING_SUPPORT_BEGIN (DriverBinding->DriverBindingHandle, ControllerHandle);
643 Status = DriverBinding->Supported (
644 DriverBinding,
645 ControllerHandle,
646 RemainingDevicePath
647 );
648 PERF_DRIVER_BINDING_SUPPORT_END (DriverBinding->DriverBindingHandle, ControllerHandle);
649 if (!EFI_ERROR (Status)) {
650 SortedDriverBindingProtocols[Index] = NULL;
651 DriverFound = TRUE;
652
653 //
654 // A driver was found that supports ControllerHandle, so attempt to start the driver
655 // on ControllerHandle.
656 //
657 PERF_DRIVER_BINDING_START_BEGIN (DriverBinding->DriverBindingHandle, ControllerHandle);
658 Status = DriverBinding->Start (
659 DriverBinding,
660 ControllerHandle,
661 RemainingDevicePath
662 );
663 PERF_DRIVER_BINDING_START_END (DriverBinding->DriverBindingHandle, ControllerHandle);
664
665 if (!EFI_ERROR (Status)) {
666 //
667 // The driver was successfully started on ControllerHandle, so set a flag
668 //
669 OneStarted = TRUE;
670 }
671 }
672 }
673 }
674 } while (DriverFound);
675
676 //
677 // Free any buffers that were allocated with AllocatePool()
678 //
679 CoreFreePool (SortedDriverBindingProtocols);
680
681 //
682 // If at least one driver was started on ControllerHandle, then return EFI_SUCCESS.
683 //
684 if (OneStarted) {
685 return EFI_SUCCESS;
686 }
687
688 //
689 // If no drivers started and RemainingDevicePath is an End Device Path Node, then return EFI_SUCCESS
690 //
691 if (RemainingDevicePath != NULL) {
692 if (IsDevicePathEnd (RemainingDevicePath)) {
693 return EFI_SUCCESS;
694 }
695 }
696
697 //
698 // Otherwise, no drivers were started on ControllerHandle, so return EFI_NOT_FOUND
699 //
700 return EFI_NOT_FOUND;
701}
702
736EFIAPI
738 IN EFI_HANDLE ControllerHandle,
739 IN EFI_HANDLE DriverImageHandle OPTIONAL,
740 IN EFI_HANDLE ChildHandle OPTIONAL
741 )
742{
743 EFI_STATUS Status;
744 IHANDLE *Handle;
745 EFI_HANDLE *DriverImageHandleBuffer;
746 EFI_HANDLE *ChildBuffer;
747 UINTN Index;
748 UINTN HandleIndex;
749 UINTN DriverImageHandleCount;
750 UINTN ChildrenToStop;
751 UINTN ChildBufferCount;
752 UINTN StopCount;
753 BOOLEAN Duplicate;
754 BOOLEAN ChildHandleValid;
755 BOOLEAN DriverImageHandleValid;
756 LIST_ENTRY *Link;
757 LIST_ENTRY *ProtLink;
758 OPEN_PROTOCOL_DATA *OpenData;
759 PROTOCOL_INTERFACE *Prot;
760 EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
761
762 //
763 // Make sure ControllerHandle is valid
764 //
766
767 Status = CoreValidateHandle (ControllerHandle);
768 if (EFI_ERROR (Status)) {
770 return Status;
771 }
772
773 //
774 // Make sure ChildHandle is valid if it is not NULL
775 //
776 if (ChildHandle != NULL) {
777 Status = CoreValidateHandle (ChildHandle);
778 if (EFI_ERROR (Status)) {
780 return Status;
781 }
782 }
783
785
786 Handle = ControllerHandle;
787
788 //
789 // Get list of drivers that are currently managing ControllerHandle
790 //
791 DriverImageHandleBuffer = NULL;
792 DriverImageHandleCount = 1;
793
794 if (DriverImageHandle == NULL) {
795 //
796 // Look at each protocol interface for a match
797 //
798 DriverImageHandleCount = 0;
799
801 for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
802 Prot = CR (Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
803 for (ProtLink = Prot->OpenList.ForwardLink;
804 ProtLink != &Prot->OpenList;
805 ProtLink = ProtLink->ForwardLink)
806 {
807 OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
808 if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
809 DriverImageHandleCount++;
810 }
811 }
812 }
813
815
816 //
817 // If there are no drivers managing this controller, then return EFI_SUCCESS
818 //
819 if (DriverImageHandleCount == 0) {
820 Status = EFI_SUCCESS;
821 goto Done;
822 }
823
824 DriverImageHandleBuffer = AllocatePool (sizeof (EFI_HANDLE) * DriverImageHandleCount);
825 if (DriverImageHandleBuffer == NULL) {
826 Status = EFI_OUT_OF_RESOURCES;
827 goto Done;
828 }
829
830 DriverImageHandleCount = 0;
831
833 for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
834 Prot = CR (Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
835 for (ProtLink = Prot->OpenList.ForwardLink;
836 ProtLink != &Prot->OpenList;
837 ProtLink = ProtLink->ForwardLink)
838 {
839 OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
840 if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
841 Duplicate = FALSE;
842 for (Index = 0; Index < DriverImageHandleCount; Index++) {
843 if (DriverImageHandleBuffer[Index] == OpenData->AgentHandle) {
844 Duplicate = TRUE;
845 break;
846 }
847 }
848
849 if (!Duplicate) {
850 DriverImageHandleBuffer[DriverImageHandleCount] = OpenData->AgentHandle;
851 DriverImageHandleCount++;
852 }
853 }
854 }
855 }
856
858 }
859
860 StopCount = 0;
861 for (HandleIndex = 0; HandleIndex < DriverImageHandleCount; HandleIndex++) {
862 if (DriverImageHandleBuffer != NULL) {
863 DriverImageHandle = DriverImageHandleBuffer[HandleIndex];
864 }
865
866 //
867 // Get the Driver Binding Protocol of the driver that is managing this controller
868 //
869 Status = CoreHandleProtocol (
870 DriverImageHandle,
871 &gEfiDriverBindingProtocolGuid,
872 (VOID **)&DriverBinding
873 );
874 if (EFI_ERROR (Status) || (DriverBinding == NULL)) {
875 Status = EFI_INVALID_PARAMETER;
876 goto Done;
877 }
878
879 //
880 // Look at each protocol interface for a match
881 //
882 DriverImageHandleValid = FALSE;
883 ChildBufferCount = 0;
884
886 for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
887 Prot = CR (Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
888 for (ProtLink = Prot->OpenList.ForwardLink;
889 ProtLink != &Prot->OpenList;
890 ProtLink = ProtLink->ForwardLink)
891 {
892 OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
893 if (OpenData->AgentHandle == DriverImageHandle) {
894 if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
895 ChildBufferCount++;
896 }
897
898 if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
899 DriverImageHandleValid = TRUE;
900 }
901 }
902 }
903 }
904
906
907 if (DriverImageHandleValid) {
908 ChildHandleValid = FALSE;
909 ChildBuffer = NULL;
910 if (ChildBufferCount != 0) {
911 ChildBuffer = AllocatePool (sizeof (EFI_HANDLE) * ChildBufferCount);
912 if (ChildBuffer == NULL) {
913 Status = EFI_OUT_OF_RESOURCES;
914 goto Done;
915 }
916
917 ChildBufferCount = 0;
918
920 for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
921 Prot = CR (Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
922 for (ProtLink = Prot->OpenList.ForwardLink;
923 ProtLink != &Prot->OpenList;
924 ProtLink = ProtLink->ForwardLink)
925 {
926 OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
927 if ((OpenData->AgentHandle == DriverImageHandle) &&
928 ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0))
929 {
930 Duplicate = FALSE;
931 for (Index = 0; Index < ChildBufferCount; Index++) {
932 if (ChildBuffer[Index] == OpenData->ControllerHandle) {
933 Duplicate = TRUE;
934 break;
935 }
936 }
937
938 if (!Duplicate) {
939 ChildBuffer[ChildBufferCount] = OpenData->ControllerHandle;
940 if (ChildHandle == ChildBuffer[ChildBufferCount]) {
941 ChildHandleValid = TRUE;
942 }
943
944 ChildBufferCount++;
945 }
946 }
947 }
948 }
949
951 }
952
953 if ((ChildHandle == NULL) || ChildHandleValid) {
954 ChildrenToStop = 0;
955 Status = EFI_SUCCESS;
956 if (ChildBufferCount > 0) {
957 if (ChildHandle != NULL) {
958 ChildrenToStop = 1;
959 Status = DriverBinding->Stop (DriverBinding, ControllerHandle, ChildrenToStop, &ChildHandle);
960 } else {
961 ChildrenToStop = ChildBufferCount;
962 Status = DriverBinding->Stop (DriverBinding, ControllerHandle, ChildrenToStop, ChildBuffer);
963 }
964 }
965
966 if (!EFI_ERROR (Status) && ((ChildHandle == NULL) || (ChildBufferCount == ChildrenToStop))) {
967 Status = DriverBinding->Stop (DriverBinding, ControllerHandle, 0, NULL);
968 }
969
970 if (!EFI_ERROR (Status)) {
971 StopCount++;
972 }
973 }
974
975 if (ChildBuffer != NULL) {
976 CoreFreePool (ChildBuffer);
977 }
978 }
979 }
980
981 if (StopCount > 0) {
982 Status = EFI_SUCCESS;
983 } else {
984 Status = EFI_NOT_FOUND;
985 }
986
987Done:
988
989 if (DriverImageHandleBuffer != NULL) {
990 CoreFreePool (DriverImageHandleBuffer);
991 }
992
993 return Status;
994}
UINT64 UINTN
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI IsDevicePathEnd(IN CONST VOID *Node)
UINTN EFIAPI GetDevicePathSize(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI DuplicateDevicePath(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath)
EFI_STATUS CoreConnectSingleController(IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE *ContextDriverImageHandles OPTIONAL, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL)
EFI_STATUS EFIAPI CoreDisconnectController(IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE DriverImageHandle OPTIONAL, IN EFI_HANDLE ChildHandle OPTIONAL)
VOID AddSortedDriverBindingProtocol(IN EFI_HANDLE DriverBindingHandle, IN OUT UINTN *NumberOfSortedDriverBindingProtocols, IN OUT EFI_DRIVER_BINDING_PROTOCOL **SortedDriverBindingProtocols, IN UINTN DriverBindingHandleCount, IN OUT EFI_HANDLE *DriverBindingHandleBuffer, IN BOOLEAN IsImageHandle)
EFI_STATUS EFIAPI CoreConnectController(IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE *DriverImageHandle OPTIONAL, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL, IN BOOLEAN Recursive)
Definition: DriverSupport.c:44
EFI_STATUS EFIAPI CoreHandleProtocol(IN EFI_HANDLE UserHandle, IN EFI_GUID *Protocol, OUT VOID **Interface)
Definition: Handle.c:1040
EFI_STATUS EFIAPI CoreLocateProtocol(IN EFI_GUID *Protocol, IN VOID *Registration OPTIONAL, OUT VOID **Interface)
Definition: Locate.c:575
EFI_STATUS EFIAPI CoreLocateHandleBuffer(IN EFI_LOCATE_SEARCH_TYPE SearchType, IN EFI_GUID *Protocol OPTIONAL, IN VOID *SearchKey OPTIONAL, IN OUT UINTN *NumberHandles, OUT EFI_HANDLE **Buffer)
Definition: Locate.c:667
EFI_STATUS EFIAPI CoreFreePool(IN VOID *Buffer)
Definition: Pool.c:591
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID CoreReleaseProtocolLock(VOID)
Definition: Handle.c:41
EFI_STATUS CoreValidateHandle(IN EFI_HANDLE UserHandle)
Definition: Handle.c:113
VOID CoreAcquireProtocolLock(VOID)
Definition: Handle.c:29
#define NULL
Definition: Base.h:319
#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 CR(Record, TYPE, Field, TestSignature)
Definition: DebugLib.h:659
#define PERF_DRIVER_BINDING_SUPPORT_BEGIN(ModuleHandle, ControllerHandle)
#define PERF_DRIVER_BINDING_START_BEGIN(ModuleHandle, ControllerHandle)
#define PERF_DRIVER_BINDING_SUPPORT_END(ModuleHandle, ControllerHandle)
#define PERF_DRIVER_BINDING_START_END(ModuleHandle, ControllerHandle)
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
@ ByProtocol
Definition: UefiSpec.h:1518
Definition: Handle.h:17
LIST_ENTRY Protocols
List of PROTOCOL_INTERFACE's for this handle.
Definition: Handle.h:22
LIST_ENTRY OpenList
OPEN_PROTOCOL_DATA list.
Definition: Handle.h:68