]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Core/Dxe/Hand/DriverSupport.c
MdeModulePkg DxeCore: Fix issue to print GUID value %g without pointer
[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 - 2014, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include "DxeMain.h"
16 #include "Handle.h"
17
18
19 //
20 // Driver Support Functions
21 //
22 /**
23 Connects one or more drivers to a controller.
24
25 @param ControllerHandle The handle of the controller to which driver(s) are to be connected.
26 @param DriverImageHandle A pointer to an ordered list handles that support the
27 EFI_DRIVER_BINDING_PROTOCOL.
28 @param RemainingDevicePath A pointer to the device path that specifies a child of the
29 controller specified by ControllerHandle.
30 @param Recursive If TRUE, then ConnectController() is called recursively
31 until the entire tree of controllers below the controller specified
32 by ControllerHandle have been created. If FALSE, then
33 the tree of controllers is only expanded one level.
34
35 @retval EFI_SUCCESS 1) One or more drivers were connected to ControllerHandle.
36 2) No drivers were connected to ControllerHandle, but
37 RemainingDevicePath is not NULL, and it is an End Device
38 Path Node.
39 @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
40 @retval EFI_NOT_FOUND 1) There are no EFI_DRIVER_BINDING_PROTOCOL instances
41 present in the system.
42 2) No drivers were connected to ControllerHandle.
43 @retval EFI_SECURITY_VIOLATION
44 The user has no permission to start UEFI device drivers on the device path
45 associated with the ControllerHandle or specified by the RemainingDevicePath.
46
47 **/
48 EFI_STATUS
49 EFIAPI
50 CoreConnectController (
51 IN EFI_HANDLE ControllerHandle,
52 IN EFI_HANDLE *DriverImageHandle OPTIONAL,
53 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL,
54 IN BOOLEAN Recursive
55 )
56 {
57 EFI_STATUS Status;
58 EFI_STATUS ReturnStatus;
59 IHANDLE *Handle;
60 PROTOCOL_INTERFACE *Prot;
61 LIST_ENTRY *Link;
62 LIST_ENTRY *ProtLink;
63 OPEN_PROTOCOL_DATA *OpenData;
64 EFI_DEVICE_PATH_PROTOCOL *AlignedRemainingDevicePath;
65 EFI_HANDLE *ChildHandleBuffer;
66 UINTN ChildHandleCount;
67 UINTN Index;
68 UINTN HandleFilePathSize;
69 UINTN RemainingDevicePathSize;
70 EFI_DEVICE_PATH_PROTOCOL *HandleFilePath;
71 EFI_DEVICE_PATH_PROTOCOL *FilePath;
72 EFI_DEVICE_PATH_PROTOCOL *TempFilePath;
73
74 //
75 // Make sure ControllerHandle is valid
76 //
77 Status = CoreValidateHandle (ControllerHandle);
78 if (EFI_ERROR (Status)) {
79 return Status;
80 }
81
82 if (gSecurity2 != NULL) {
83 //
84 // Check whether the user has permission to start UEFI device drivers.
85 //
86 Status = CoreHandleProtocol (ControllerHandle, &gEfiDevicePathProtocolGuid, (VOID **)&HandleFilePath);
87 if (!EFI_ERROR (Status)) {
88 ASSERT (HandleFilePath != NULL);
89 FilePath = HandleFilePath;
90 TempFilePath = NULL;
91 if (RemainingDevicePath != NULL && !Recursive) {
92 HandleFilePathSize = GetDevicePathSize (HandleFilePath) - sizeof (EFI_DEVICE_PATH_PROTOCOL);
93 RemainingDevicePathSize = GetDevicePathSize (RemainingDevicePath);
94 TempFilePath = AllocateZeroPool (HandleFilePathSize + RemainingDevicePathSize);
95 ASSERT (TempFilePath != NULL);
96 CopyMem (TempFilePath, HandleFilePath, HandleFilePathSize);
97 CopyMem ((UINT8 *) TempFilePath + HandleFilePathSize, RemainingDevicePath, RemainingDevicePathSize);
98 FilePath = TempFilePath;
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 if (EFI_ERROR (Status)) {
111 return Status;
112 }
113 }
114 }
115
116 Handle = ControllerHandle;
117
118 //
119 // Make a copy of RemainingDevicePath to guanatee it is aligned
120 //
121 AlignedRemainingDevicePath = NULL;
122 if (RemainingDevicePath != NULL) {
123 AlignedRemainingDevicePath = DuplicateDevicePath (RemainingDevicePath);
124
125 if (AlignedRemainingDevicePath == NULL) {
126 return EFI_OUT_OF_RESOURCES;
127 }
128 }
129
130 //
131 // Connect all drivers to ControllerHandle
132 // If CoreConnectSingleController returns EFI_NOT_READY, then the number of
133 // Driver Binding Protocols in the handle database has increased during the call
134 // so the connect operation must be restarted
135 //
136 do {
137 ReturnStatus = CoreConnectSingleController (
138 ControllerHandle,
139 DriverImageHandle,
140 AlignedRemainingDevicePath
141 );
142 } while (ReturnStatus == EFI_NOT_READY);
143
144 //
145 // Free the aligned copy of RemainingDevicePath
146 //
147 if (AlignedRemainingDevicePath != NULL) {
148 CoreFreePool (AlignedRemainingDevicePath);
149 }
150
151 //
152 // If recursive, then connect all drivers to all of ControllerHandle's children
153 //
154 if (Recursive) {
155 //
156 // Acquire the protocol lock on the handle database so the child handles can be collected
157 //
158 CoreAcquireProtocolLock ();
159
160 //
161 // Make sure the DriverBindingHandle is valid
162 //
163 Status = CoreValidateHandle (ControllerHandle);
164 if (EFI_ERROR (Status)) {
165 //
166 // Release the protocol lock on the handle database
167 //
168 CoreReleaseProtocolLock ();
169
170 return ReturnStatus;
171 }
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 OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
183 if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
184 ChildHandleCount++;
185 }
186 }
187 }
188
189 //
190 // Allocate a handle buffer for ControllerHandle's children
191 //
192 ChildHandleBuffer = AllocatePool (ChildHandleCount * sizeof(EFI_HANDLE));
193 if (ChildHandleBuffer == NULL) {
194 CoreReleaseProtocolLock ();
195 return EFI_OUT_OF_RESOURCES;
196 }
197
198 //
199 // Fill in a handle buffer with ControllerHandle's children
200 //
201 for (Link = Handle->Protocols.ForwardLink, ChildHandleCount = 0; Link != &Handle->Protocols; Link = Link->ForwardLink) {
202 Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
203 for (ProtLink = Prot->OpenList.ForwardLink;
204 ProtLink != &Prot->OpenList;
205 ProtLink = ProtLink->ForwardLink) {
206 OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
207 if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
208 ChildHandleBuffer[ChildHandleCount] = OpenData->ControllerHandle;
209 ChildHandleCount++;
210 }
211 }
212 }
213
214 //
215 // Release the protocol lock on the handle database
216 //
217 CoreReleaseProtocolLock ();
218
219 //
220 // Recursively connect each child handle
221 //
222 for (Index = 0; Index < ChildHandleCount; Index++) {
223 CoreConnectController (
224 ChildHandleBuffer[Index],
225 NULL,
226 NULL,
227 TRUE
228 );
229 }
230
231 //
232 // Free the handle buffer of ControllerHandle's children
233 //
234 CoreFreePool (ChildHandleBuffer);
235 }
236
237 return ReturnStatus;
238 }
239
240
241 /**
242 Add Driver Binding Protocols from Context Driver Image Handles to sorted
243 Driver Binding Protocol list.
244
245 @param DriverBindingHandle Handle of the driver binding
246 protocol.
247 @param NumberOfSortedDriverBindingProtocols Number Of sorted driver binding
248 protocols
249 @param SortedDriverBindingProtocols The sorted protocol list.
250 @param DriverBindingHandleCount Driver Binding Handle Count.
251 @param DriverBindingHandleBuffer The buffer of driver binding
252 protocol to be modified.
253 @param IsImageHandle Indicate whether
254 DriverBindingHandle is an image
255 handle
256
257 @return None.
258
259 **/
260 VOID
261 AddSortedDriverBindingProtocol (
262 IN EFI_HANDLE DriverBindingHandle,
263 IN OUT UINTN *NumberOfSortedDriverBindingProtocols,
264 IN OUT EFI_DRIVER_BINDING_PROTOCOL **SortedDriverBindingProtocols,
265 IN UINTN DriverBindingHandleCount,
266 IN OUT EFI_HANDLE *DriverBindingHandleBuffer,
267 IN BOOLEAN IsImageHandle
268 )
269 {
270 EFI_STATUS Status;
271 EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
272 UINTN Index;
273
274 //
275 // Make sure the DriverBindingHandle is valid
276 //
277 Status = CoreValidateHandle (DriverBindingHandle);
278 if (EFI_ERROR (Status)) {
279 return;
280 }
281
282 //
283 // If IsImageHandle is TRUE, then DriverBindingHandle is an image handle
284 // Find all the DriverBindingHandles associated with that image handle and add them to the sorted list
285 //
286 if (IsImageHandle) {
287 //
288 // Loop through all the Driver Binding Handles
289 //
290 for (Index = 0; Index < DriverBindingHandleCount; Index++) {
291 //
292 // Retrieve the Driver Binding Protocol associated with each Driver Binding Handle
293 //
294 Status = CoreHandleProtocol (
295 DriverBindingHandleBuffer[Index],
296 &gEfiDriverBindingProtocolGuid,
297 (VOID **) &DriverBinding
298 );
299 if (EFI_ERROR (Status) || DriverBinding == NULL) {
300 continue;
301 }
302
303 //
304 // If the ImageHandle associated with DriverBinding matches DriverBindingHandle,
305 // then add the DriverBindingProtocol[Index] to the sorted list
306 //
307 if (DriverBinding->ImageHandle == DriverBindingHandle) {
308 AddSortedDriverBindingProtocol (
309 DriverBindingHandleBuffer[Index],
310 NumberOfSortedDriverBindingProtocols,
311 SortedDriverBindingProtocols,
312 DriverBindingHandleCount,
313 DriverBindingHandleBuffer,
314 FALSE
315 );
316 }
317 }
318 return;
319 }
320
321 //
322 // Retrieve the Driver Binding Protocol from DriverBindingHandle
323 //
324 Status = CoreHandleProtocol(
325 DriverBindingHandle,
326 &gEfiDriverBindingProtocolGuid,
327 (VOID **) &DriverBinding
328 );
329 //
330 // If DriverBindingHandle does not support the Driver Binding Protocol then return
331 //
332 if (EFI_ERROR (Status) || DriverBinding == NULL) {
333 return;
334 }
335
336 //
337 // See if DriverBinding is already in the sorted list
338 //
339 for (Index = 0; Index < *NumberOfSortedDriverBindingProtocols && Index < DriverBindingHandleCount; Index++) {
340 if (DriverBinding == SortedDriverBindingProtocols[Index]) {
341 return;
342 }
343 }
344
345 //
346 // Add DriverBinding to the end of the list
347 //
348 if (*NumberOfSortedDriverBindingProtocols < DriverBindingHandleCount) {
349 SortedDriverBindingProtocols[*NumberOfSortedDriverBindingProtocols] = DriverBinding;
350 }
351 *NumberOfSortedDriverBindingProtocols = *NumberOfSortedDriverBindingProtocols + 1;
352
353 //
354 // Mark the cooresponding handle in DriverBindingHandleBuffer as used
355 //
356 for (Index = 0; Index < DriverBindingHandleCount; Index++) {
357 if (DriverBindingHandleBuffer[Index] == DriverBindingHandle) {
358 DriverBindingHandleBuffer[Index] = NULL;
359 }
360 }
361 }
362
363
364 /**
365 Connects a controller to a driver.
366
367 @param ControllerHandle Handle of the controller to be
368 connected.
369 @param ContextDriverImageHandles DriverImageHandle A pointer to an
370 ordered list of driver image
371 handles.
372 @param RemainingDevicePath RemainingDevicePath A pointer to
373 the device path that specifies a
374 child of the controller
375 specified by ControllerHandle.
376
377 @retval EFI_SUCCESS One or more drivers were
378 connected to ControllerHandle.
379 @retval EFI_OUT_OF_RESOURCES No enough system resources to
380 complete the request.
381 @retval EFI_NOT_FOUND No drivers were connected to
382 ControllerHandle.
383
384 **/
385 EFI_STATUS
386 CoreConnectSingleController (
387 IN EFI_HANDLE ControllerHandle,
388 IN EFI_HANDLE *ContextDriverImageHandles OPTIONAL,
389 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
390 )
391 {
392 EFI_STATUS Status;
393 UINTN Index;
394 EFI_HANDLE DriverImageHandle;
395 EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *PlatformDriverOverride;
396 EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *BusSpecificDriverOverride;
397 UINTN DriverBindingHandleCount;
398 EFI_HANDLE *DriverBindingHandleBuffer;
399 UINTN NewDriverBindingHandleCount;
400 EFI_HANDLE *NewDriverBindingHandleBuffer;
401 EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
402 EFI_DRIVER_FAMILY_OVERRIDE_PROTOCOL *DriverFamilyOverride;
403 UINTN NumberOfSortedDriverBindingProtocols;
404 EFI_DRIVER_BINDING_PROTOCOL **SortedDriverBindingProtocols;
405 UINT32 DriverFamilyOverrideVersion;
406 UINT32 HighestVersion;
407 UINTN HighestIndex;
408 UINTN SortIndex;
409 BOOLEAN OneStarted;
410 BOOLEAN DriverFound;
411
412 //
413 // Initialize local variables
414 //
415 DriverBindingHandleCount = 0;
416 DriverBindingHandleBuffer = NULL;
417 NumberOfSortedDriverBindingProtocols = 0;
418 SortedDriverBindingProtocols = NULL;
419 PlatformDriverOverride = NULL;
420 NewDriverBindingHandleBuffer = NULL;
421
422 //
423 // Get list of all Driver Binding Protocol Instances
424 //
425 Status = CoreLocateHandleBuffer (
426 ByProtocol,
427 &gEfiDriverBindingProtocolGuid,
428 NULL,
429 &DriverBindingHandleCount,
430 &DriverBindingHandleBuffer
431 );
432 if (EFI_ERROR (Status) || (DriverBindingHandleCount == 0)) {
433 return EFI_NOT_FOUND;
434 }
435
436 //
437 // Allocate a duplicate array for the sorted Driver Binding Protocol Instances
438 //
439 SortedDriverBindingProtocols = AllocatePool (sizeof (VOID *) * DriverBindingHandleCount);
440 if (SortedDriverBindingProtocols == NULL) {
441 CoreFreePool (DriverBindingHandleBuffer);
442 return EFI_OUT_OF_RESOURCES;
443 }
444
445 //
446 // Add Driver Binding Protocols from Context Driver Image Handles first
447 //
448 if (ContextDriverImageHandles != NULL) {
449 for (Index = 0; ContextDriverImageHandles[Index] != NULL; Index++) {
450 AddSortedDriverBindingProtocol (
451 ContextDriverImageHandles[Index],
452 &NumberOfSortedDriverBindingProtocols,
453 SortedDriverBindingProtocols,
454 DriverBindingHandleCount,
455 DriverBindingHandleBuffer,
456 FALSE
457 );
458 }
459 }
460
461 //
462 // Add the Platform Driver Override Protocol drivers for ControllerHandle next
463 //
464 Status = CoreLocateProtocol (
465 &gEfiPlatformDriverOverrideProtocolGuid,
466 NULL,
467 (VOID **) &PlatformDriverOverride
468 );
469 if (!EFI_ERROR (Status) && (PlatformDriverOverride != NULL)) {
470 DriverImageHandle = NULL;
471 do {
472 Status = PlatformDriverOverride->GetDriver (
473 PlatformDriverOverride,
474 ControllerHandle,
475 &DriverImageHandle
476 );
477 if (!EFI_ERROR (Status)) {
478 AddSortedDriverBindingProtocol (
479 DriverImageHandle,
480 &NumberOfSortedDriverBindingProtocols,
481 SortedDriverBindingProtocols,
482 DriverBindingHandleCount,
483 DriverBindingHandleBuffer,
484 TRUE
485 );
486 }
487 } while (!EFI_ERROR (Status));
488 }
489
490 //
491 // Add the Driver Family Override Protocol drivers for ControllerHandle
492 //
493 while (TRUE) {
494 HighestIndex = DriverBindingHandleCount;
495 HighestVersion = 0;
496 for (Index = 0; Index < DriverBindingHandleCount; Index++) {
497 Status = CoreHandleProtocol (
498 DriverBindingHandleBuffer[Index],
499 &gEfiDriverFamilyOverrideProtocolGuid,
500 (VOID **) &DriverFamilyOverride
501 );
502 if (!EFI_ERROR (Status) && (DriverFamilyOverride != NULL)) {
503 DriverFamilyOverrideVersion = DriverFamilyOverride->GetVersion (DriverFamilyOverride);
504 if ((HighestIndex == DriverBindingHandleCount) || (DriverFamilyOverrideVersion > HighestVersion)) {
505 HighestVersion = DriverFamilyOverrideVersion;
506 HighestIndex = Index;
507 }
508 }
509 }
510
511 if (HighestIndex == DriverBindingHandleCount) {
512 break;
513 }
514
515 AddSortedDriverBindingProtocol (
516 DriverBindingHandleBuffer[HighestIndex],
517 &NumberOfSortedDriverBindingProtocols,
518 SortedDriverBindingProtocols,
519 DriverBindingHandleCount,
520 DriverBindingHandleBuffer,
521 FALSE
522 );
523 }
524
525 //
526 // Get the Bus Specific Driver Override Protocol instance on the Controller Handle
527 //
528 Status = CoreHandleProtocol (
529 ControllerHandle,
530 &gEfiBusSpecificDriverOverrideProtocolGuid,
531 (VOID **) &BusSpecificDriverOverride
532 );
533 if (!EFI_ERROR (Status) && (BusSpecificDriverOverride != NULL)) {
534 DriverImageHandle = NULL;
535 do {
536 Status = BusSpecificDriverOverride->GetDriver (
537 BusSpecificDriverOverride,
538 &DriverImageHandle
539 );
540 if (!EFI_ERROR (Status)) {
541 AddSortedDriverBindingProtocol (
542 DriverImageHandle,
543 &NumberOfSortedDriverBindingProtocols,
544 SortedDriverBindingProtocols,
545 DriverBindingHandleCount,
546 DriverBindingHandleBuffer,
547 TRUE
548 );
549 }
550 } while (!EFI_ERROR (Status));
551 }
552
553 //
554 // Then add all the remaining Driver Binding Protocols
555 //
556 SortIndex = NumberOfSortedDriverBindingProtocols;
557 for (Index = 0; Index < DriverBindingHandleCount; Index++) {
558 AddSortedDriverBindingProtocol (
559 DriverBindingHandleBuffer[Index],
560 &NumberOfSortedDriverBindingProtocols,
561 SortedDriverBindingProtocols,
562 DriverBindingHandleCount,
563 DriverBindingHandleBuffer,
564 FALSE
565 );
566 }
567
568 //
569 // Free the Driver Binding Handle Buffer
570 //
571 CoreFreePool (DriverBindingHandleBuffer);
572
573 //
574 // If the number of Driver Binding Protocols has increased since this function started, then return
575 // EFI_NOT_READY, so it will be restarted
576 //
577 Status = CoreLocateHandleBuffer (
578 ByProtocol,
579 &gEfiDriverBindingProtocolGuid,
580 NULL,
581 &NewDriverBindingHandleCount,
582 &NewDriverBindingHandleBuffer
583 );
584 CoreFreePool (NewDriverBindingHandleBuffer);
585 if (NewDriverBindingHandleCount > DriverBindingHandleCount) {
586 //
587 // Free any buffers that were allocated with AllocatePool()
588 //
589 CoreFreePool (SortedDriverBindingProtocols);
590
591 return EFI_NOT_READY;
592 }
593
594 //
595 // Sort the remaining DriverBinding Protocol based on their Version field from
596 // highest to lowest.
597 //
598 for ( ; SortIndex < NumberOfSortedDriverBindingProtocols; SortIndex++) {
599 HighestVersion = SortedDriverBindingProtocols[SortIndex]->Version;
600 HighestIndex = SortIndex;
601 for (Index = SortIndex + 1; Index < NumberOfSortedDriverBindingProtocols; Index++) {
602 if (SortedDriverBindingProtocols[Index]->Version > HighestVersion) {
603 HighestVersion = SortedDriverBindingProtocols[Index]->Version;
604 HighestIndex = Index;
605 }
606 }
607 if (SortIndex != HighestIndex) {
608 DriverBinding = SortedDriverBindingProtocols[SortIndex];
609 SortedDriverBindingProtocols[SortIndex] = SortedDriverBindingProtocols[HighestIndex];
610 SortedDriverBindingProtocols[HighestIndex] = DriverBinding;
611 }
612 }
613
614 //
615 // Loop until no more drivers can be started on ControllerHandle
616 //
617 OneStarted = FALSE;
618 do {
619
620 //
621 // Loop through the sorted Driver Binding Protocol Instances in order, and see if
622 // any of the Driver Binding Protocols support the controller specified by
623 // ControllerHandle.
624 //
625 DriverBinding = NULL;
626 DriverFound = FALSE;
627 for (Index = 0; (Index < NumberOfSortedDriverBindingProtocols) && !DriverFound; Index++) {
628 if (SortedDriverBindingProtocols[Index] != NULL) {
629 DriverBinding = SortedDriverBindingProtocols[Index];
630 PERF_START (DriverBinding->DriverBindingHandle, "DB:Support:", NULL, 0);
631 Status = DriverBinding->Supported(
632 DriverBinding,
633 ControllerHandle,
634 RemainingDevicePath
635 );
636 PERF_END (DriverBinding->DriverBindingHandle, "DB:Support:", NULL, 0);
637 if (!EFI_ERROR (Status)) {
638 SortedDriverBindingProtocols[Index] = NULL;
639 DriverFound = TRUE;
640
641 //
642 // A driver was found that supports ControllerHandle, so attempt to start the driver
643 // on ControllerHandle.
644 //
645 PERF_START (DriverBinding->DriverBindingHandle, "DB:Start:", NULL, 0);
646 Status = DriverBinding->Start (
647 DriverBinding,
648 ControllerHandle,
649 RemainingDevicePath
650 );
651 PERF_END (DriverBinding->DriverBindingHandle, "DB:Start:", NULL, 0);
652
653 if (!EFI_ERROR (Status)) {
654 //
655 // The driver was successfully started on ControllerHandle, so set a flag
656 //
657 OneStarted = TRUE;
658 }
659 }
660 }
661 }
662 } while (DriverFound);
663
664 //
665 // Free any buffers that were allocated with AllocatePool()
666 //
667 CoreFreePool (SortedDriverBindingProtocols);
668
669 //
670 // If at least one driver was started on ControllerHandle, then return EFI_SUCCESS.
671 //
672 if (OneStarted) {
673 return EFI_SUCCESS;
674 }
675
676 //
677 // If no drivers started and RemainingDevicePath is an End Device Path Node, then return EFI_SUCCESS
678 //
679 if (RemainingDevicePath != NULL) {
680 if (IsDevicePathEnd (RemainingDevicePath)) {
681 return EFI_SUCCESS;
682 }
683 }
684
685 //
686 // Otherwise, no drivers were started on ControllerHandle, so return EFI_NOT_FOUND
687 //
688 return EFI_NOT_FOUND;
689 }
690
691
692
693 /**
694 Disonnects a controller from a driver
695
696 @param ControllerHandle ControllerHandle The handle of
697 the controller from which
698 driver(s) are to be
699 disconnected.
700 @param DriverImageHandle DriverImageHandle The driver to
701 disconnect from ControllerHandle.
702 @param ChildHandle ChildHandle The handle of the
703 child to destroy.
704
705 @retval EFI_SUCCESS One or more drivers were
706 disconnected from the controller.
707 @retval EFI_SUCCESS On entry, no drivers are managing
708 ControllerHandle.
709 @retval EFI_SUCCESS DriverImageHandle is not NULL,
710 and on entry DriverImageHandle is
711 not managing ControllerHandle.
712 @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
713 @retval EFI_INVALID_PARAMETER DriverImageHandle is not NULL,
714 and it is not a valid EFI_HANDLE.
715 @retval EFI_INVALID_PARAMETER ChildHandle is not NULL, and it
716 is not a valid EFI_HANDLE.
717 @retval EFI_OUT_OF_RESOURCES There are not enough resources
718 available to disconnect any
719 drivers from ControllerHandle.
720 @retval EFI_DEVICE_ERROR The controller could not be
721 disconnected because of a device
722 error.
723
724 **/
725 EFI_STATUS
726 EFIAPI
727 CoreDisconnectController (
728 IN EFI_HANDLE ControllerHandle,
729 IN EFI_HANDLE DriverImageHandle OPTIONAL,
730 IN EFI_HANDLE ChildHandle OPTIONAL
731 )
732 {
733 EFI_STATUS Status;
734 IHANDLE *Handle;
735 EFI_HANDLE *DriverImageHandleBuffer;
736 EFI_HANDLE *ChildBuffer;
737 UINTN Index;
738 UINTN HandleIndex;
739 UINTN DriverImageHandleCount;
740 UINTN ChildrenToStop;
741 UINTN ChildBufferCount;
742 UINTN StopCount;
743 BOOLEAN Duplicate;
744 BOOLEAN ChildHandleValid;
745 BOOLEAN DriverImageHandleValid;
746 LIST_ENTRY *Link;
747 LIST_ENTRY *ProtLink;
748 OPEN_PROTOCOL_DATA *OpenData;
749 PROTOCOL_INTERFACE *Prot;
750 EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
751
752 //
753 // Make sure ControllerHandle is valid
754 //
755 Status = CoreValidateHandle (ControllerHandle);
756 if (EFI_ERROR (Status)) {
757 return Status;
758 }
759
760 //
761 // Make sure ChildHandle is valid if it is not NULL
762 //
763 if (ChildHandle != NULL) {
764 Status = CoreValidateHandle (ChildHandle);
765 if (EFI_ERROR (Status)) {
766 return Status;
767 }
768 }
769
770 Handle = ControllerHandle;
771
772 //
773 // Get list of drivers that are currently managing ControllerHandle
774 //
775 DriverImageHandleBuffer = NULL;
776 DriverImageHandleCount = 1;
777
778 if (DriverImageHandle == NULL) {
779 //
780 // Look at each protocol interface for a match
781 //
782 DriverImageHandleCount = 0;
783
784 CoreAcquireProtocolLock ();
785 for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
786 Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
787 for (ProtLink = Prot->OpenList.ForwardLink;
788 ProtLink != &Prot->OpenList;
789 ProtLink = ProtLink->ForwardLink) {
790 OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
791 if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
792 DriverImageHandleCount++;
793 }
794 }
795 }
796 CoreReleaseProtocolLock ();
797
798 //
799 // If there are no drivers managing this controller, then return EFI_SUCCESS
800 //
801 if (DriverImageHandleCount == 0) {
802 Status = EFI_SUCCESS;
803 goto Done;
804 }
805
806 DriverImageHandleBuffer = AllocatePool (sizeof (EFI_HANDLE) * DriverImageHandleCount);
807 if (DriverImageHandleBuffer == NULL) {
808 Status = EFI_OUT_OF_RESOURCES;
809 goto Done;
810 }
811
812 DriverImageHandleCount = 0;
813
814 CoreAcquireProtocolLock ();
815 for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
816 Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
817 for (ProtLink = Prot->OpenList.ForwardLink;
818 ProtLink != &Prot->OpenList;
819 ProtLink = ProtLink->ForwardLink) {
820 OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
821 if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
822 Duplicate = FALSE;
823 for (Index = 0; Index< DriverImageHandleCount; Index++) {
824 if (DriverImageHandleBuffer[Index] == OpenData->AgentHandle) {
825 Duplicate = TRUE;
826 break;
827 }
828 }
829 if (!Duplicate) {
830 DriverImageHandleBuffer[DriverImageHandleCount] = OpenData->AgentHandle;
831 DriverImageHandleCount++;
832 }
833 }
834 }
835 }
836 CoreReleaseProtocolLock ();
837 }
838
839 StopCount = 0;
840 for (HandleIndex = 0; HandleIndex < DriverImageHandleCount; HandleIndex++) {
841
842 if (DriverImageHandleBuffer != NULL) {
843 DriverImageHandle = DriverImageHandleBuffer[HandleIndex];
844 }
845
846 //
847 // Get the Driver Binding Protocol of the driver that is managing this controller
848 //
849 Status = CoreHandleProtocol (
850 DriverImageHandle,
851 &gEfiDriverBindingProtocolGuid,
852 (VOID **)&DriverBinding
853 );
854 if (EFI_ERROR (Status) || DriverBinding == NULL) {
855 Status = EFI_INVALID_PARAMETER;
856 goto Done;
857 }
858
859 //
860 // Look at each protocol interface for a match
861 //
862 DriverImageHandleValid = FALSE;
863 ChildBufferCount = 0;
864
865 CoreAcquireProtocolLock ();
866 for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
867 Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
868 for (ProtLink = Prot->OpenList.ForwardLink;
869 ProtLink != &Prot->OpenList;
870 ProtLink = ProtLink->ForwardLink) {
871 OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
872 if (OpenData->AgentHandle == DriverImageHandle) {
873 if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
874 ChildBufferCount++;
875 }
876 if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
877 DriverImageHandleValid = TRUE;
878 }
879 }
880 }
881 }
882 CoreReleaseProtocolLock ();
883
884 if (DriverImageHandleValid) {
885 ChildHandleValid = FALSE;
886 ChildBuffer = NULL;
887 if (ChildBufferCount != 0) {
888 ChildBuffer = AllocatePool (sizeof (EFI_HANDLE) * ChildBufferCount);
889 if (ChildBuffer == NULL) {
890 Status = EFI_OUT_OF_RESOURCES;
891 goto Done;
892 }
893
894 ChildBufferCount = 0;
895
896 CoreAcquireProtocolLock ();
897 for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
898 Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
899 for (ProtLink = Prot->OpenList.ForwardLink;
900 ProtLink != &Prot->OpenList;
901 ProtLink = ProtLink->ForwardLink) {
902 OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
903 if ((OpenData->AgentHandle == DriverImageHandle) &&
904 ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0)) {
905 Duplicate = FALSE;
906 for (Index = 0; Index < ChildBufferCount; Index++) {
907 if (ChildBuffer[Index] == OpenData->ControllerHandle) {
908 Duplicate = TRUE;
909 break;
910 }
911 }
912 if (!Duplicate) {
913 ChildBuffer[ChildBufferCount] = OpenData->ControllerHandle;
914 if (ChildHandle == ChildBuffer[ChildBufferCount]) {
915 ChildHandleValid = TRUE;
916 }
917 ChildBufferCount++;
918 }
919 }
920 }
921 }
922 CoreReleaseProtocolLock ();
923 }
924
925 if (ChildHandle == NULL || ChildHandleValid) {
926 ChildrenToStop = 0;
927 Status = EFI_SUCCESS;
928 if (ChildBufferCount > 0) {
929 if (ChildHandle != NULL) {
930 ChildrenToStop = 1;
931 Status = DriverBinding->Stop (DriverBinding, ControllerHandle, ChildrenToStop, &ChildHandle);
932 } else {
933 ChildrenToStop = ChildBufferCount;
934 Status = DriverBinding->Stop (DriverBinding, ControllerHandle, ChildrenToStop, ChildBuffer);
935 }
936 }
937 if (!EFI_ERROR (Status) && ((ChildHandle == NULL) || (ChildBufferCount == ChildrenToStop))) {
938 Status = DriverBinding->Stop (DriverBinding, ControllerHandle, 0, NULL);
939 }
940 if (!EFI_ERROR (Status)) {
941 StopCount++;
942 }
943 }
944
945 if (ChildBuffer != NULL) {
946 CoreFreePool (ChildBuffer);
947 }
948 }
949 }
950
951 if (StopCount > 0) {
952 Status = EFI_SUCCESS;
953 } else {
954 Status = EFI_NOT_FOUND;
955 }
956
957 Done:
958
959 if (DriverImageHandleBuffer != NULL) {
960 CoreFreePool (DriverImageHandleBuffer);
961 }
962
963 return Status;
964 }