]> git.proxmox.com Git - mirror_edk2.git/blob - EdkModulePkg/Core/Dxe/Hand/DriverSupport.c
Fix buger in DxeMain module and modify uefispec.h coding style
[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 VOID
153 AddSortedDriverBindingProtocol (
154 IN EFI_HANDLE DriverBindingHandle,
155 IN OUT UINTN *NumberOfSortedDriverBindingProtocols,
156 IN OUT EFI_DRIVER_BINDING_PROTOCOL **SortedDriverBindingProtocols,
157 IN UINTN DriverBindingHandleCount,
158 IN OUT EFI_HANDLE *DriverBindingHandleBuffer
159 )
160 /*++
161
162 Routine Description:
163
164 Add Driver Binding Protocols from Context Driver Image Handles to sorted
165 Driver Binding Protocol list.
166
167 Arguments:
168
169 DriverBindingHandle - Handle of the driver binding protocol.
170
171 NumberOfSortedDriverBindingProtocols - Number Of sorted driver binding protocols
172
173 SortedDriverBindingProtocols - The sorted protocol list.
174
175 DriverBindingHandleCount - Driver Binding Handle Count.
176
177 DriverBindingHandleBuffer - The buffer of driver binding protocol to be modified.
178
179 Returns:
180
181 None.
182
183 --*/
184 {
185 EFI_STATUS Status;
186 EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
187 UINTN Index;
188
189 //
190 // Make sure the DriverBindingHandle is valid
191 //
192 Status = CoreValidateHandle (DriverBindingHandle);
193 if (EFI_ERROR (Status)) {
194 return;
195 }
196
197 //
198 // Retrieve the Driver Binding Protocol from DriverBindingHandle
199 //
200 Status = CoreHandleProtocol(
201 DriverBindingHandle,
202 &gEfiDriverBindingProtocolGuid,
203 (VOID **)&DriverBinding
204 );
205 //
206 // If DriverBindingHandle does not support the Driver Binding Protocol then return
207 //
208 if (EFI_ERROR (Status) || DriverBinding == NULL) {
209 return;
210 }
211
212 //
213 // See if DriverBinding is already in the sorted list
214 //
215 for (Index = 0; Index < *NumberOfSortedDriverBindingProtocols; Index++) {
216 if (DriverBinding == SortedDriverBindingProtocols[Index]) {
217 return;
218 }
219 }
220
221 //
222 // Add DriverBinding to the end of the list
223 //
224 SortedDriverBindingProtocols[*NumberOfSortedDriverBindingProtocols] = DriverBinding;
225 *NumberOfSortedDriverBindingProtocols = *NumberOfSortedDriverBindingProtocols + 1;
226
227 //
228 // Mark the cooresponding handle in DriverBindingHandleBuffer as used
229 //
230 for (Index = 0; Index < DriverBindingHandleCount; Index++) {
231 if (DriverBindingHandleBuffer[Index] == DriverBindingHandle) {
232 DriverBindingHandleBuffer[Index] = NULL;
233 }
234 }
235 }
236
237 STATIC
238 EFI_STATUS
239 CoreConnectSingleController (
240 IN EFI_HANDLE ControllerHandle,
241 IN EFI_HANDLE *ContextDriverImageHandles OPTIONAL,
242 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
243 )
244 /*++
245
246 Routine Description:
247
248 Connects a controller to a driver.
249
250 Arguments:
251
252 ControllerHandle - Handle of the controller to be connected.
253 ContextDriverImageHandles - DriverImageHandle A pointer to an ordered list of driver image handles.
254 RemainingDevicePath - RemainingDevicePath A pointer to the device path that specifies a child
255 of the controller specified by ControllerHandle.
256
257 Returns:
258
259 EFI_SUCCESS - One or more drivers were connected to ControllerHandle.
260 EFI_OUT_OF_RESOURCES - No enough system resources to complete the request.
261 EFI_NOT_FOUND - No drivers were connected to ControllerHandle.
262
263 --*/
264 {
265 EFI_STATUS Status;
266 UINTN Index;
267 EFI_HANDLE DriverImageHandle;
268 UINTN PlatformDriverOverrideHandleCount;
269 EFI_HANDLE *PlatformDriverOverrideHandleBuffer;
270 EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *PlatformDriverOverride;
271 EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *BusSpecificDriverOverride;
272 UINTN DriverBindingHandleCount;
273 EFI_HANDLE *DriverBindingHandleBuffer;
274 EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
275 UINTN NumberOfSortedDriverBindingProtocols;
276 EFI_DRIVER_BINDING_PROTOCOL **SortedDriverBindingProtocols;
277 UINT32 HighestVersion;
278 UINTN HighestIndex;
279 UINTN SortIndex;
280 BOOLEAN OneStarted;
281 BOOLEAN DriverFound;
282 EFI_HANDLE DriverBindingHandle;
283
284 //
285 // DriverBindingHandle is used for performance measurement, initialize it here just in case.
286 //
287 DriverBindingHandle = NULL;
288 //
289 // Initialize local variables
290 //
291 DriverBindingHandleCount = 0;
292 DriverBindingHandleBuffer = NULL;
293 PlatformDriverOverrideHandleCount = 0;
294 PlatformDriverOverrideHandleBuffer = NULL;
295 NumberOfSortedDriverBindingProtocols = 0;
296 SortedDriverBindingProtocols = NULL;
297
298 //
299 // Get list of all Driver Binding Protocol Instances
300 //
301 Status = CoreLocateHandleBuffer (
302 ByProtocol,
303 &gEfiDriverBindingProtocolGuid,
304 NULL,
305 &DriverBindingHandleCount,
306 &DriverBindingHandleBuffer
307 );
308 if (EFI_ERROR (Status) || (DriverBindingHandleCount == 0)) {
309 return EFI_NOT_FOUND;
310 }
311
312 //
313 // Allocate a duplicate array for the sorted Driver Binding Protocol Instances
314 //
315 SortedDriverBindingProtocols = CoreAllocateBootServicesPool (sizeof (VOID *) * DriverBindingHandleCount);
316 if (SortedDriverBindingProtocols == NULL) {
317 CoreFreePool (DriverBindingHandleBuffer);
318 return EFI_OUT_OF_RESOURCES;
319 }
320
321 //
322 // Add Driver Binding Protocols from Context Driver Image Handles first
323 //
324 if (ContextDriverImageHandles != NULL) {
325 for (Index = 0; ContextDriverImageHandles[Index] != NULL; Index++) {
326 AddSortedDriverBindingProtocol (
327 ContextDriverImageHandles[Index],
328 &NumberOfSortedDriverBindingProtocols,
329 SortedDriverBindingProtocols,
330 DriverBindingHandleCount,
331 DriverBindingHandleBuffer
332 );
333 }
334 }
335
336 //
337 // Add the Platform Driver Override Protocol drivers for ControllerHandle next
338 //
339 Status = CoreLocateProtocol (
340 &gEfiPlatformDriverOverrideProtocolGuid,
341 NULL,
342 (VOID **)&PlatformDriverOverride
343 );
344 if (!EFI_ERROR (Status) && (PlatformDriverOverride != NULL)) {
345 DriverImageHandle = NULL;
346 do {
347 Status = PlatformDriverOverride->GetDriver (
348 PlatformDriverOverride,
349 ControllerHandle,
350 &DriverImageHandle
351 );
352 if (!EFI_ERROR (Status)) {
353 AddSortedDriverBindingProtocol (
354 DriverImageHandle,
355 &NumberOfSortedDriverBindingProtocols,
356 SortedDriverBindingProtocols,
357 DriverBindingHandleCount,
358 DriverBindingHandleBuffer
359 );
360 }
361 } while (!EFI_ERROR (Status));
362 }
363
364 //
365 // Get the Bus Specific Driver Override Protocol instance on the Controller Handle
366 //
367 Status = CoreHandleProtocol(
368 ControllerHandle,
369 &gEfiBusSpecificDriverOverrideProtocolGuid,
370 (VOID **)&BusSpecificDriverOverride
371 );
372 if (!EFI_ERROR (Status) && (BusSpecificDriverOverride != NULL)) {
373 DriverImageHandle = NULL;
374 do {
375 Status = BusSpecificDriverOverride->GetDriver (
376 BusSpecificDriverOverride,
377 &DriverImageHandle
378 );
379 if (!EFI_ERROR (Status)) {
380 AddSortedDriverBindingProtocol (
381 DriverImageHandle,
382 &NumberOfSortedDriverBindingProtocols,
383 SortedDriverBindingProtocols,
384 DriverBindingHandleCount,
385 DriverBindingHandleBuffer
386 );
387 }
388 } while (!EFI_ERROR (Status));
389 }
390
391 //
392 // Then add all the remaining Driver Binding Protocols
393 //
394 SortIndex = NumberOfSortedDriverBindingProtocols;
395 for (Index = 0; Index < DriverBindingHandleCount; Index++) {
396 AddSortedDriverBindingProtocol (
397 DriverBindingHandleBuffer[Index],
398 &NumberOfSortedDriverBindingProtocols,
399 SortedDriverBindingProtocols,
400 DriverBindingHandleCount,
401 DriverBindingHandleBuffer
402 );
403 }
404
405 //
406 // Free the Driver Binding Handle Buffer
407 //
408 CoreFreePool (DriverBindingHandleBuffer);
409
410 //
411 // Sort the remaining DriverBinding Protocol based on their Version field from
412 // highest to lowest.
413 //
414 for ( ; SortIndex < NumberOfSortedDriverBindingProtocols; SortIndex++) {
415 HighestVersion = SortedDriverBindingProtocols[SortIndex]->Version;
416 HighestIndex = SortIndex;
417 for (Index = SortIndex + 1; Index < NumberOfSortedDriverBindingProtocols; Index++) {
418 if (SortedDriverBindingProtocols[Index]->Version > HighestVersion) {
419 HighestVersion = SortedDriverBindingProtocols[Index]->Version;
420 HighestIndex = Index;
421 }
422 }
423 if (SortIndex != HighestIndex) {
424 DriverBinding = SortedDriverBindingProtocols[SortIndex];
425 SortedDriverBindingProtocols[SortIndex] = SortedDriverBindingProtocols[HighestIndex];
426 SortedDriverBindingProtocols[HighestIndex] = DriverBinding;
427 }
428 }
429
430 //
431 // Loop until no more drivers can be started on ControllerHandle
432 //
433 OneStarted = FALSE;
434 do {
435
436 //
437 // Loop through the sorted Driver Binding Protocol Instances in order, and see if
438 // any of the Driver Binding Protocols support the controller specified by
439 // ControllerHandle.
440 //
441 DriverBinding = NULL;
442 DriverFound = FALSE;
443 for (Index = 0; (Index < NumberOfSortedDriverBindingProtocols) && !DriverFound; Index++) {
444 if (SortedDriverBindingProtocols[Index] != NULL) {
445 DriverBinding = SortedDriverBindingProtocols[Index];
446 Status = DriverBinding->Supported(
447 DriverBinding,
448 ControllerHandle,
449 RemainingDevicePath
450 );
451 if (!EFI_ERROR (Status)) {
452 SortedDriverBindingProtocols[Index] = NULL;
453 DriverFound = TRUE;
454
455 //
456 // A driver was found that supports ControllerHandle, so attempt to start the driver
457 // on ControllerHandle.
458 //
459 PERF_CODE_BEGIN ();
460 GetHandleFromDriverBinding (DriverBinding, &DriverBindingHandle);
461 PERF_CODE_END ();
462
463 PERF_START (DriverBindingHandle, DRIVERBINDING_START_TOK, NULL, 0);
464 Status = DriverBinding->Start (
465 DriverBinding,
466 ControllerHandle,
467 RemainingDevicePath
468 );
469 PERF_END (DriverBindingHandle, DRIVERBINDING_START_TOK, NULL, 0);
470
471 if (!EFI_ERROR (Status)) {
472 //
473 // The driver was successfully started on ControllerHandle, so set a flag
474 //
475 OneStarted = TRUE;
476 }
477 }
478 }
479 }
480 } while (DriverFound);
481
482 //
483 // Free any buffers that were allocated with AllocatePool()
484 //
485 CoreFreePool (SortedDriverBindingProtocols);
486
487 //
488 // If at least one driver was started on ControllerHandle, then return EFI_SUCCESS.
489 //
490 if (OneStarted) {
491 return EFI_SUCCESS;
492 }
493
494 //
495 // If no drivers started and RemainingDevicePath is an End Device Path Node, then return EFI_SUCCESS
496 //
497 if (RemainingDevicePath != NULL) {
498 if (IsDevicePathEnd (RemainingDevicePath)) {
499 return EFI_SUCCESS;
500 }
501 }
502
503 //
504 // Otherwise, no drivers were started on ControllerHandle, so return EFI_NOT_FOUND
505 //
506 return EFI_NOT_FOUND;
507 }
508
509
510 EFI_STATUS
511 EFIAPI
512 CoreDisconnectController (
513 IN EFI_HANDLE ControllerHandle,
514 IN EFI_HANDLE DriverImageHandle OPTIONAL,
515 IN EFI_HANDLE ChildHandle OPTIONAL
516 )
517 /*++
518
519 Routine Description:
520
521 Disonnects a controller from a driver
522
523 Arguments:
524
525 ControllerHandle - ControllerHandle The handle of the controller from which driver(s)
526 are to be disconnected.
527 DriverImageHandle - DriverImageHandle The driver to disconnect from ControllerHandle.
528 ChildHandle - ChildHandle The handle of the child to destroy.
529
530 Returns:
531
532 EFI_SUCCESS - One or more drivers were disconnected from the controller.
533 EFI_SUCCESS - On entry, no drivers are managing ControllerHandle.
534 EFI_SUCCESS - DriverImageHandle is not NULL, and on entry DriverImageHandle is not managing ControllerHandle.
535 EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
536 EFI_INVALID_PARAMETER - DriverImageHandle is not NULL, and it is not a valid EFI_HANDLE.
537 EFI_INVALID_PARAMETER - ChildHandle is not NULL, and it is not a valid EFI_HANDLE.
538 EFI_OUT_OF_RESOURCES - There are not enough resources available to disconnect any drivers from ControllerHandle.
539 EFI_DEVICE_ERROR - The controller could not be disconnected because of a device error.
540
541 --*/
542 {
543 EFI_STATUS Status;
544 IHANDLE *Handle;
545 EFI_HANDLE *DriverImageHandleBuffer;
546 EFI_HANDLE *ChildBuffer;
547 UINTN Index;
548 UINTN HandleIndex;
549 UINTN DriverImageHandleCount;
550 UINTN ChildrenToStop;
551 UINTN ChildBufferCount;
552 UINTN StopCount;
553 BOOLEAN Duplicate;
554 BOOLEAN ChildHandleValid;
555 BOOLEAN DriverImageHandleValid;
556 LIST_ENTRY *Link;
557 LIST_ENTRY *ProtLink;
558 OPEN_PROTOCOL_DATA *OpenData;
559 PROTOCOL_INTERFACE *Prot;
560 EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
561
562 //
563 // Make sure ControllerHandle is valid
564 //
565 Status = CoreValidateHandle (ControllerHandle);
566 if (EFI_ERROR (Status)) {
567 return Status;
568 }
569
570 //
571 // Make sure ChildHandle is valid if it is not NULL
572 //
573 if (ChildHandle != NULL) {
574 Status = CoreValidateHandle (ChildHandle);
575 if (EFI_ERROR (Status)) {
576 return Status;
577 }
578 }
579
580 Handle = ControllerHandle;
581
582 //
583 // Get list of drivers that are currently managing ControllerHandle
584 //
585 DriverImageHandleBuffer = NULL;
586 DriverImageHandleCount = 1;
587
588 if (DriverImageHandle == NULL) {
589 //
590 // Look at each protocol interface for a match
591 //
592 DriverImageHandleCount = 0;
593
594 CoreAcquireProtocolLock ();
595 for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
596 Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
597 for (ProtLink = Prot->OpenList.ForwardLink;
598 ProtLink != &Prot->OpenList;
599 ProtLink = ProtLink->ForwardLink) {
600 OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
601 if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
602 DriverImageHandleCount++;
603 }
604 }
605 }
606 CoreReleaseProtocolLock ();
607
608 //
609 // If there are no drivers managing this controller, then return EFI_SUCCESS
610 //
611 if (DriverImageHandleCount == 0) {
612 Status = EFI_SUCCESS;
613 goto Done;
614 }
615
616 DriverImageHandleBuffer = CoreAllocateBootServicesPool (sizeof (EFI_HANDLE) * DriverImageHandleCount);
617 if (DriverImageHandleBuffer == NULL) {
618 Status = EFI_OUT_OF_RESOURCES;
619 goto Done;
620 }
621
622 DriverImageHandleCount = 0;
623
624 CoreAcquireProtocolLock ();
625 for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
626 Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
627 for (ProtLink = Prot->OpenList.ForwardLink;
628 ProtLink != &Prot->OpenList;
629 ProtLink = ProtLink->ForwardLink) {
630 OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
631 if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
632 Duplicate = FALSE;
633 for (Index = 0; Index< DriverImageHandleCount; Index++) {
634 if (DriverImageHandleBuffer[Index] == OpenData->AgentHandle) {
635 Duplicate = TRUE;
636 break;
637 }
638 }
639 if (!Duplicate) {
640 DriverImageHandleBuffer[DriverImageHandleCount] = OpenData->AgentHandle;
641 DriverImageHandleCount++;
642 }
643 }
644 }
645 }
646 CoreReleaseProtocolLock ();
647 }
648
649 StopCount = 0;
650 for (HandleIndex = 0; HandleIndex < DriverImageHandleCount; HandleIndex++) {
651
652 if (DriverImageHandleBuffer != NULL) {
653 DriverImageHandle = DriverImageHandleBuffer[HandleIndex];
654 }
655
656 //
657 // Get the Driver Binding Protocol of the driver that is managing this controller
658 //
659 Status = CoreHandleProtocol (
660 DriverImageHandle,
661 &gEfiDriverBindingProtocolGuid,
662 (VOID **)&DriverBinding
663 );
664 if (EFI_ERROR (Status)) {
665 Status = EFI_INVALID_PARAMETER;
666 goto Done;
667 }
668
669 //
670 // Look at each protocol interface for a match
671 //
672 DriverImageHandleValid = FALSE;
673 ChildBufferCount = 0;
674
675 CoreAcquireProtocolLock ();
676 for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
677 Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
678 for (ProtLink = Prot->OpenList.ForwardLink;
679 ProtLink != &Prot->OpenList;
680 ProtLink = ProtLink->ForwardLink) {
681 OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
682 if (OpenData->AgentHandle == DriverImageHandle) {
683 if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
684 ChildBufferCount++;
685 }
686 if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
687 DriverImageHandleValid = TRUE;
688 }
689 }
690 }
691 }
692 CoreReleaseProtocolLock ();
693
694 if (DriverImageHandleValid) {
695 ChildHandleValid = FALSE;
696 ChildBuffer = NULL;
697 if (ChildBufferCount != 0) {
698 ChildBuffer = CoreAllocateBootServicesPool (sizeof (EFI_HANDLE) * ChildBufferCount);
699 if (ChildBuffer == NULL) {
700 Status = EFI_OUT_OF_RESOURCES;
701 goto Done;
702 }
703
704 ChildBufferCount = 0;
705
706 CoreAcquireProtocolLock ();
707 for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
708 Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
709 for (ProtLink = Prot->OpenList.ForwardLink;
710 ProtLink != &Prot->OpenList;
711 ProtLink = ProtLink->ForwardLink) {
712 OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
713 if ((OpenData->AgentHandle == DriverImageHandle) &&
714 ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0)) {
715 Duplicate = FALSE;
716 for (Index = 0; Index < ChildBufferCount; Index++) {
717 if (ChildBuffer[Index] == OpenData->ControllerHandle) {
718 Duplicate = TRUE;
719 break;
720 }
721 }
722 if (!Duplicate) {
723 ChildBuffer[ChildBufferCount] = OpenData->ControllerHandle;
724 if (ChildHandle == ChildBuffer[ChildBufferCount]) {
725 ChildHandleValid = TRUE;
726 }
727 ChildBufferCount++;
728 }
729 }
730 }
731 }
732 CoreReleaseProtocolLock ();
733 }
734
735 if (ChildHandle == NULL || ChildHandleValid) {
736 ChildrenToStop = 0;
737 Status = EFI_SUCCESS;
738 if (ChildBufferCount > 0) {
739 if (ChildHandle != NULL) {
740 ChildrenToStop = 1;
741 Status = DriverBinding->Stop (DriverBinding, ControllerHandle, ChildrenToStop, &ChildHandle);
742 } else {
743 ChildrenToStop = ChildBufferCount;
744 Status = DriverBinding->Stop (DriverBinding, ControllerHandle, ChildrenToStop, ChildBuffer);
745 }
746 }
747 if (!EFI_ERROR (Status) && ((ChildHandle == NULL) || (ChildBufferCount == ChildrenToStop))) {
748 Status = DriverBinding->Stop (DriverBinding, ControllerHandle, 0, NULL);
749 }
750 if (!EFI_ERROR (Status)) {
751 StopCount++;
752 }
753 }
754
755 if (ChildBuffer != NULL) {
756 CoreFreePool (ChildBuffer);
757 }
758 }
759 }
760
761 if (StopCount > 0) {
762 Status = EFI_SUCCESS;
763 } else {
764 Status = EFI_NOT_FOUND;
765 }
766
767 Done:
768
769 if (DriverImageHandleBuffer != NULL) {
770 CoreFreePool (DriverImageHandleBuffer);
771 }
772
773 return Status;
774 }
775
776
777
778 STATIC
779 EFI_STATUS
780 GetHandleFromDriverBinding (
781 IN EFI_DRIVER_BINDING_PROTOCOL *DriverBindingNeed,
782 OUT EFI_HANDLE *Handle
783 )
784 /*++
785
786 Routine Description:
787
788 Locate the driver binding handle which a specified driver binding protocol installed on.
789
790 Arguments:
791
792 DriverBindingNeed - The specified driver binding protocol.
793
794 Handle - The driver binding handle which the protocol installed on.
795
796
797 Returns:
798
799 EFI_NOT_FOUND - Could not find the handle.
800
801 EFI_SUCCESS - Successfully find the associated driver binding handle.
802
803 --*/
804 {
805 EFI_STATUS Status ;
806 EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
807 UINTN DriverBindingHandleCount;
808 EFI_HANDLE *DriverBindingHandleBuffer;
809 UINTN Index;
810
811 DriverBindingHandleCount = 0;
812 DriverBindingHandleBuffer = NULL;
813 *Handle = NULL_HANDLE;
814 Status = CoreLocateHandleBuffer (
815 ByProtocol,
816 &gEfiDriverBindingProtocolGuid,
817 NULL,
818 &DriverBindingHandleCount,
819 &DriverBindingHandleBuffer
820 );
821 if (EFI_ERROR (Status) || DriverBindingHandleCount == 0) {
822 return EFI_NOT_FOUND;
823 }
824
825 for (Index = 0 ; Index < DriverBindingHandleCount; Index++ ) {
826 Status = CoreOpenProtocol(
827 DriverBindingHandleBuffer[Index],
828 &gEfiDriverBindingProtocolGuid,
829 (VOID **)&DriverBinding,
830 gDxeCoreImageHandle,
831 NULL,
832 EFI_OPEN_PROTOCOL_GET_PROTOCOL
833 );
834
835 if (!EFI_ERROR (Status) && DriverBinding != NULL) {
836
837 if ( DriverBinding == DriverBindingNeed ) {
838 *Handle = DriverBindingHandleBuffer[Index];
839 CoreFreePool (DriverBindingHandleBuffer);
840 return EFI_SUCCESS ;
841 }
842 }
843 }
844
845 CoreFreePool (DriverBindingHandleBuffer);
846 return EFI_NOT_FOUND ;
847 }
848