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