]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Core/Dxe/Hand/DriverSupport.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / Hand / DriverSupport.c
1 /** @file
2 Support functions to connect/disconnect UEFI Driver model Protocol
3
4 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include "DxeMain.h"
10 #include "Handle.h"
11
12 //
13 // Driver Support Functions
14 //
15
16 /**
17 Connects one or more drivers to a controller.
18
19 @param ControllerHandle The handle of the controller to which driver(s) are to be connected.
20 @param DriverImageHandle A pointer to an ordered list handles that support the
21 EFI_DRIVER_BINDING_PROTOCOL.
22 @param RemainingDevicePath A pointer to the device path that specifies a child of the
23 controller specified by ControllerHandle.
24 @param Recursive If TRUE, then ConnectController() is called recursively
25 until the entire tree of controllers below the controller specified
26 by ControllerHandle have been created. If FALSE, then
27 the tree of controllers is only expanded one level.
28
29 @retval EFI_SUCCESS 1) One or more drivers were connected to ControllerHandle.
30 2) No drivers were connected to ControllerHandle, but
31 RemainingDevicePath is not NULL, and it is an End Device
32 Path Node.
33 @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
34 @retval EFI_NOT_FOUND 1) There are no EFI_DRIVER_BINDING_PROTOCOL instances
35 present in the system.
36 2) No drivers were connected to ControllerHandle.
37 @retval EFI_SECURITY_VIOLATION
38 The user has no permission to start UEFI device drivers on the device path
39 associated with the ControllerHandle or specified by the RemainingDevicePath.
40
41 **/
42 EFI_STATUS
43 EFIAPI
44 CoreConnectController (
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;
54 PROTOCOL_INTERFACE *Prot;
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;
65 EFI_DEVICE_PATH_PROTOCOL *FilePath;
66 EFI_DEVICE_PATH_PROTOCOL *TempFilePath;
67
68 //
69 // Make sure ControllerHandle is valid
70 //
71 CoreAcquireProtocolLock ();
72
73 Status = CoreValidateHandle (ControllerHandle);
74
75 CoreReleaseProtocolLock ();
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 //
159 CoreAcquireProtocolLock ();
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 //
169 CoreReleaseProtocolLock ();
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) {
195 CoreReleaseProtocolLock ();
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 //
219 CoreReleaseProtocolLock ();
220
221 //
222 // Recursively connect each child handle
223 //
224 for (Index = 0; Index < ChildHandleCount; Index++) {
225 CoreConnectController (
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
242 /**
243 Add Driver Binding Protocols from Context Driver Image Handles to sorted
244 Driver Binding Protocol list.
245
246 @param DriverBindingHandle Handle of the driver binding
247 protocol.
248 @param NumberOfSortedDriverBindingProtocols Number Of sorted driver binding
249 protocols
250 @param SortedDriverBindingProtocols The sorted protocol list.
251 @param DriverBindingHandleCount Driver Binding Handle Count.
252 @param DriverBindingHandleBuffer The buffer of driver binding
253 protocol to be modified.
254 @param IsImageHandle Indicate whether
255 DriverBindingHandle is an image
256 handle
257
258 @return None.
259
260 **/
261 VOID
262 AddSortedDriverBindingProtocol (
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 //
278 CoreAcquireProtocolLock ();
279
280 Status = CoreValidateHandle (DriverBindingHandle);
281
282 CoreReleaseProtocolLock ();
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) {
314 AddSortedDriverBindingProtocol (
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
371 /**
372 Connects a controller to a driver.
373
374 @param ControllerHandle Handle of the controller to be
375 connected.
376 @param ContextDriverImageHandles DriverImageHandle A pointer to an
377 ordered list of driver image
378 handles.
379 @param RemainingDevicePath RemainingDevicePath A pointer to
380 the device path that specifies a
381 child of the controller
382 specified by ControllerHandle.
383
384 @retval EFI_SUCCESS One or more drivers were
385 connected to ControllerHandle.
386 @retval EFI_OUT_OF_RESOURCES No enough system resources to
387 complete the request.
388 @retval EFI_NOT_FOUND No drivers were connected to
389 ControllerHandle.
390
391 **/
392 EFI_STATUS
393 CoreConnectSingleController (
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 (
433 ByProtocol,
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++) {
457 AddSortedDriverBindingProtocol (
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)) {
485 AddSortedDriverBindingProtocol (
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 while (TRUE) {
501 HighestIndex = DriverBindingHandleCount;
502 HighestVersion = 0;
503 for (Index = 0; Index < DriverBindingHandleCount; Index++) {
504 Status = CoreHandleProtocol (
505 DriverBindingHandleBuffer[Index],
506 &gEfiDriverFamilyOverrideProtocolGuid,
507 (VOID **)&DriverFamilyOverride
508 );
509 if (!EFI_ERROR (Status) && (DriverFamilyOverride != NULL)) {
510 DriverFamilyOverrideVersion = DriverFamilyOverride->GetVersion (DriverFamilyOverride);
511 if ((HighestIndex == DriverBindingHandleCount) || (DriverFamilyOverrideVersion > HighestVersion)) {
512 HighestVersion = DriverFamilyOverrideVersion;
513 HighestIndex = Index;
514 }
515 }
516 }
517
518 if (HighestIndex == DriverBindingHandleCount) {
519 break;
520 }
521
522 AddSortedDriverBindingProtocol (
523 DriverBindingHandleBuffer[HighestIndex],
524 &NumberOfSortedDriverBindingProtocols,
525 SortedDriverBindingProtocols,
526 DriverBindingHandleCount,
527 DriverBindingHandleBuffer,
528 FALSE
529 );
530 }
531
532 //
533 // Get the Bus Specific Driver Override Protocol instance on the Controller Handle
534 //
535 Status = CoreHandleProtocol (
536 ControllerHandle,
537 &gEfiBusSpecificDriverOverrideProtocolGuid,
538 (VOID **)&BusSpecificDriverOverride
539 );
540 if (!EFI_ERROR (Status) && (BusSpecificDriverOverride != NULL)) {
541 DriverImageHandle = NULL;
542 do {
543 Status = BusSpecificDriverOverride->GetDriver (
544 BusSpecificDriverOverride,
545 &DriverImageHandle
546 );
547 if (!EFI_ERROR (Status)) {
548 AddSortedDriverBindingProtocol (
549 DriverImageHandle,
550 &NumberOfSortedDriverBindingProtocols,
551 SortedDriverBindingProtocols,
552 DriverBindingHandleCount,
553 DriverBindingHandleBuffer,
554 TRUE
555 );
556 }
557 } while (!EFI_ERROR (Status));
558 }
559
560 //
561 // Then add all the remaining Driver Binding Protocols
562 //
563 SortIndex = NumberOfSortedDriverBindingProtocols;
564 for (Index = 0; Index < DriverBindingHandleCount; Index++) {
565 AddSortedDriverBindingProtocol (
566 DriverBindingHandleBuffer[Index],
567 &NumberOfSortedDriverBindingProtocols,
568 SortedDriverBindingProtocols,
569 DriverBindingHandleCount,
570 DriverBindingHandleBuffer,
571 FALSE
572 );
573 }
574
575 //
576 // Free the Driver Binding Handle Buffer
577 //
578 CoreFreePool (DriverBindingHandleBuffer);
579
580 //
581 // If the number of Driver Binding Protocols has increased since this function started, then return
582 // EFI_NOT_READY, so it will be restarted
583 //
584 Status = CoreLocateHandleBuffer (
585 ByProtocol,
586 &gEfiDriverBindingProtocolGuid,
587 NULL,
588 &NewDriverBindingHandleCount,
589 &NewDriverBindingHandleBuffer
590 );
591 CoreFreePool (NewDriverBindingHandleBuffer);
592 if (NewDriverBindingHandleCount > DriverBindingHandleCount) {
593 //
594 // Free any buffers that were allocated with AllocatePool()
595 //
596 CoreFreePool (SortedDriverBindingProtocols);
597
598 return EFI_NOT_READY;
599 }
600
601 //
602 // Sort the remaining DriverBinding Protocol based on their Version field from
603 // highest to lowest.
604 //
605 for ( ; SortIndex < NumberOfSortedDriverBindingProtocols; SortIndex++) {
606 HighestVersion = SortedDriverBindingProtocols[SortIndex]->Version;
607 HighestIndex = SortIndex;
608 for (Index = SortIndex + 1; Index < NumberOfSortedDriverBindingProtocols; Index++) {
609 if (SortedDriverBindingProtocols[Index]->Version > HighestVersion) {
610 HighestVersion = SortedDriverBindingProtocols[Index]->Version;
611 HighestIndex = Index;
612 }
613 }
614
615 if (SortIndex != HighestIndex) {
616 DriverBinding = SortedDriverBindingProtocols[SortIndex];
617 SortedDriverBindingProtocols[SortIndex] = SortedDriverBindingProtocols[HighestIndex];
618 SortedDriverBindingProtocols[HighestIndex] = DriverBinding;
619 }
620 }
621
622 //
623 // Loop until no more drivers can be started on ControllerHandle
624 //
625 OneStarted = FALSE;
626 do {
627 //
628 // Loop through the sorted Driver Binding Protocol Instances in order, and see if
629 // any of the Driver Binding Protocols support the controller specified by
630 // ControllerHandle.
631 //
632 DriverBinding = NULL;
633 DriverFound = FALSE;
634 for (Index = 0; (Index < NumberOfSortedDriverBindingProtocols) && !DriverFound; Index++) {
635 if (SortedDriverBindingProtocols[Index] != NULL) {
636 DriverBinding = SortedDriverBindingProtocols[Index];
637 PERF_DRIVER_BINDING_SUPPORT_BEGIN (DriverBinding->DriverBindingHandle, ControllerHandle);
638 Status = DriverBinding->Supported (
639 DriverBinding,
640 ControllerHandle,
641 RemainingDevicePath
642 );
643 PERF_DRIVER_BINDING_SUPPORT_END (DriverBinding->DriverBindingHandle, ControllerHandle);
644 if (!EFI_ERROR (Status)) {
645 SortedDriverBindingProtocols[Index] = NULL;
646 DriverFound = TRUE;
647
648 //
649 // A driver was found that supports ControllerHandle, so attempt to start the driver
650 // on ControllerHandle.
651 //
652 PERF_DRIVER_BINDING_START_BEGIN (DriverBinding->DriverBindingHandle, ControllerHandle);
653 Status = DriverBinding->Start (
654 DriverBinding,
655 ControllerHandle,
656 RemainingDevicePath
657 );
658 PERF_DRIVER_BINDING_START_END (DriverBinding->DriverBindingHandle, ControllerHandle);
659
660 if (!EFI_ERROR (Status)) {
661 //
662 // The driver was successfully started on ControllerHandle, so set a flag
663 //
664 OneStarted = TRUE;
665 }
666 }
667 }
668 }
669 } while (DriverFound);
670
671 //
672 // Free any buffers that were allocated with AllocatePool()
673 //
674 CoreFreePool (SortedDriverBindingProtocols);
675
676 //
677 // If at least one driver was started on ControllerHandle, then return EFI_SUCCESS.
678 //
679 if (OneStarted) {
680 return EFI_SUCCESS;
681 }
682
683 //
684 // If no drivers started and RemainingDevicePath is an End Device Path Node, then return EFI_SUCCESS
685 //
686 if (RemainingDevicePath != NULL) {
687 if (IsDevicePathEnd (RemainingDevicePath)) {
688 return EFI_SUCCESS;
689 }
690 }
691
692 //
693 // Otherwise, no drivers were started on ControllerHandle, so return EFI_NOT_FOUND
694 //
695 return EFI_NOT_FOUND;
696 }
697
698 /**
699 Disonnects a controller from a driver
700
701 @param ControllerHandle ControllerHandle The handle of
702 the controller from which
703 driver(s) are to be
704 disconnected.
705 @param DriverImageHandle DriverImageHandle The driver to
706 disconnect from ControllerHandle.
707 @param ChildHandle ChildHandle The handle of the
708 child to destroy.
709
710 @retval EFI_SUCCESS One or more drivers were
711 disconnected from the controller.
712 @retval EFI_SUCCESS On entry, no drivers are managing
713 ControllerHandle.
714 @retval EFI_SUCCESS DriverImageHandle is not NULL,
715 and on entry DriverImageHandle is
716 not managing ControllerHandle.
717 @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
718 @retval EFI_INVALID_PARAMETER DriverImageHandle is not NULL,
719 and it is not a valid EFI_HANDLE.
720 @retval EFI_INVALID_PARAMETER ChildHandle is not NULL, and it
721 is not a valid EFI_HANDLE.
722 @retval EFI_OUT_OF_RESOURCES There are not enough resources
723 available to disconnect any
724 drivers from ControllerHandle.
725 @retval EFI_DEVICE_ERROR The controller could not be
726 disconnected because of a device
727 error.
728
729 **/
730 EFI_STATUS
731 EFIAPI
732 CoreDisconnectController (
733 IN EFI_HANDLE ControllerHandle,
734 IN EFI_HANDLE DriverImageHandle OPTIONAL,
735 IN EFI_HANDLE ChildHandle OPTIONAL
736 )
737 {
738 EFI_STATUS Status;
739 IHANDLE *Handle;
740 EFI_HANDLE *DriverImageHandleBuffer;
741 EFI_HANDLE *ChildBuffer;
742 UINTN Index;
743 UINTN HandleIndex;
744 UINTN DriverImageHandleCount;
745 UINTN ChildrenToStop;
746 UINTN ChildBufferCount;
747 UINTN StopCount;
748 BOOLEAN Duplicate;
749 BOOLEAN ChildHandleValid;
750 BOOLEAN DriverImageHandleValid;
751 LIST_ENTRY *Link;
752 LIST_ENTRY *ProtLink;
753 OPEN_PROTOCOL_DATA *OpenData;
754 PROTOCOL_INTERFACE *Prot;
755 EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
756
757 //
758 // Make sure ControllerHandle is valid
759 //
760 CoreAcquireProtocolLock ();
761
762 Status = CoreValidateHandle (ControllerHandle);
763 if (EFI_ERROR (Status)) {
764 CoreReleaseProtocolLock ();
765 return Status;
766 }
767
768 //
769 // Make sure ChildHandle is valid if it is not NULL
770 //
771 if (ChildHandle != NULL) {
772 Status = CoreValidateHandle (ChildHandle);
773 if (EFI_ERROR (Status)) {
774 CoreReleaseProtocolLock ();
775 return Status;
776 }
777 }
778
779 CoreReleaseProtocolLock ();
780
781 Handle = ControllerHandle;
782
783 //
784 // Get list of drivers that are currently managing ControllerHandle
785 //
786 DriverImageHandleBuffer = NULL;
787 DriverImageHandleCount = 1;
788
789 if (DriverImageHandle == NULL) {
790 //
791 // Look at each protocol interface for a match
792 //
793 DriverImageHandleCount = 0;
794
795 CoreAcquireProtocolLock ();
796 for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
797 Prot = CR (Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
798 for (ProtLink = Prot->OpenList.ForwardLink;
799 ProtLink != &Prot->OpenList;
800 ProtLink = ProtLink->ForwardLink)
801 {
802 OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
803 if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
804 DriverImageHandleCount++;
805 }
806 }
807 }
808
809 CoreReleaseProtocolLock ();
810
811 //
812 // If there are no drivers managing this controller, then return EFI_SUCCESS
813 //
814 if (DriverImageHandleCount == 0) {
815 Status = EFI_SUCCESS;
816 goto Done;
817 }
818
819 DriverImageHandleBuffer = AllocatePool (sizeof (EFI_HANDLE) * DriverImageHandleCount);
820 if (DriverImageHandleBuffer == NULL) {
821 Status = EFI_OUT_OF_RESOURCES;
822 goto Done;
823 }
824
825 DriverImageHandleCount = 0;
826
827 CoreAcquireProtocolLock ();
828 for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
829 Prot = CR (Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
830 for (ProtLink = Prot->OpenList.ForwardLink;
831 ProtLink != &Prot->OpenList;
832 ProtLink = ProtLink->ForwardLink)
833 {
834 OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
835 if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
836 Duplicate = FALSE;
837 for (Index = 0; Index < DriverImageHandleCount; Index++) {
838 if (DriverImageHandleBuffer[Index] == OpenData->AgentHandle) {
839 Duplicate = TRUE;
840 break;
841 }
842 }
843
844 if (!Duplicate) {
845 DriverImageHandleBuffer[DriverImageHandleCount] = OpenData->AgentHandle;
846 DriverImageHandleCount++;
847 }
848 }
849 }
850 }
851
852 CoreReleaseProtocolLock ();
853 }
854
855 StopCount = 0;
856 for (HandleIndex = 0; HandleIndex < DriverImageHandleCount; HandleIndex++) {
857 if (DriverImageHandleBuffer != NULL) {
858 DriverImageHandle = DriverImageHandleBuffer[HandleIndex];
859 }
860
861 //
862 // Get the Driver Binding Protocol of the driver that is managing this controller
863 //
864 Status = CoreHandleProtocol (
865 DriverImageHandle,
866 &gEfiDriverBindingProtocolGuid,
867 (VOID **)&DriverBinding
868 );
869 if (EFI_ERROR (Status) || (DriverBinding == NULL)) {
870 Status = EFI_INVALID_PARAMETER;
871 goto Done;
872 }
873
874 //
875 // Look at each protocol interface for a match
876 //
877 DriverImageHandleValid = FALSE;
878 ChildBufferCount = 0;
879
880 CoreAcquireProtocolLock ();
881 for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
882 Prot = CR (Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
883 for (ProtLink = Prot->OpenList.ForwardLink;
884 ProtLink != &Prot->OpenList;
885 ProtLink = ProtLink->ForwardLink)
886 {
887 OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
888 if (OpenData->AgentHandle == DriverImageHandle) {
889 if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
890 ChildBufferCount++;
891 }
892
893 if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
894 DriverImageHandleValid = TRUE;
895 }
896 }
897 }
898 }
899
900 CoreReleaseProtocolLock ();
901
902 if (DriverImageHandleValid) {
903 ChildHandleValid = FALSE;
904 ChildBuffer = NULL;
905 if (ChildBufferCount != 0) {
906 ChildBuffer = AllocatePool (sizeof (EFI_HANDLE) * ChildBufferCount);
907 if (ChildBuffer == NULL) {
908 Status = EFI_OUT_OF_RESOURCES;
909 goto Done;
910 }
911
912 ChildBufferCount = 0;
913
914 CoreAcquireProtocolLock ();
915 for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
916 Prot = CR (Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
917 for (ProtLink = Prot->OpenList.ForwardLink;
918 ProtLink != &Prot->OpenList;
919 ProtLink = ProtLink->ForwardLink)
920 {
921 OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
922 if ((OpenData->AgentHandle == DriverImageHandle) &&
923 ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0))
924 {
925 Duplicate = FALSE;
926 for (Index = 0; Index < ChildBufferCount; Index++) {
927 if (ChildBuffer[Index] == OpenData->ControllerHandle) {
928 Duplicate = TRUE;
929 break;
930 }
931 }
932
933 if (!Duplicate) {
934 ChildBuffer[ChildBufferCount] = OpenData->ControllerHandle;
935 if (ChildHandle == ChildBuffer[ChildBufferCount]) {
936 ChildHandleValid = TRUE;
937 }
938
939 ChildBufferCount++;
940 }
941 }
942 }
943 }
944
945 CoreReleaseProtocolLock ();
946 }
947
948 if ((ChildHandle == NULL) || ChildHandleValid) {
949 ChildrenToStop = 0;
950 Status = EFI_SUCCESS;
951 if (ChildBufferCount > 0) {
952 if (ChildHandle != NULL) {
953 ChildrenToStop = 1;
954 Status = DriverBinding->Stop (DriverBinding, ControllerHandle, ChildrenToStop, &ChildHandle);
955 } else {
956 ChildrenToStop = ChildBufferCount;
957 Status = DriverBinding->Stop (DriverBinding, ControllerHandle, ChildrenToStop, ChildBuffer);
958 }
959 }
960
961 if (!EFI_ERROR (Status) && ((ChildHandle == NULL) || (ChildBufferCount == ChildrenToStop))) {
962 Status = DriverBinding->Stop (DriverBinding, ControllerHandle, 0, NULL);
963 }
964
965 if (!EFI_ERROR (Status)) {
966 StopCount++;
967 }
968 }
969
970 if (ChildBuffer != NULL) {
971 CoreFreePool (ChildBuffer);
972 }
973 }
974 }
975
976 if (StopCount > 0) {
977 Status = EFI_SUCCESS;
978 } else {
979 Status = EFI_NOT_FOUND;
980 }
981
982 Done:
983
984 if (DriverImageHandleBuffer != NULL) {
985 CoreFreePool (DriverImageHandleBuffer);
986 }
987
988 return Status;
989 }