DriverSupport.c revision ec90508b3d3ff22a698a0446cb09d551d7466045
123c98c9417908188207408afa3f6901b8aca826aqhuang/** @file
2504214c4870e9183418014634268ce630eb5332algao  Support functions to connect/disconnect UEFI Driver model Protocol
3504214c4870e9183418014634268ce630eb5332algao
423c98c9417908188207408afa3f6901b8aca826aqhuangCopyright (c) 2006 - 2008, Intel Corporation. <BR>
523c98c9417908188207408afa3f6901b8aca826aqhuangAll rights reserved. This program and the accompanying materials
623c98c9417908188207408afa3f6901b8aca826aqhuangare licensed and made available under the terms and conditions of the BSD License
723c98c9417908188207408afa3f6901b8aca826aqhuangwhich accompanies this distribution.  The full text of the license may be found at
823c98c9417908188207408afa3f6901b8aca826aqhuanghttp://opensource.org/licenses/bsd-license.php
923c98c9417908188207408afa3f6901b8aca826aqhuang
1023c98c9417908188207408afa3f6901b8aca826aqhuangTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
1123c98c9417908188207408afa3f6901b8aca826aqhuangWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
1228a00297189c323096aae8e2975de94e8549613cyshang
13504214c4870e9183418014634268ce630eb5332algao**/
1428a00297189c323096aae8e2975de94e8549613cyshang
159c4ac31cca01b4a503c36616770ea3157bf3bb9eqhuang#include "DxeMain.h"
16ec90508b3d3ff22a698a0446cb09d551d7466045eric_tian#include "Handle.h"
1728a00297189c323096aae8e2975de94e8549613cyshang
1828a00297189c323096aae8e2975de94e8549613cyshang
1928a00297189c323096aae8e2975de94e8549613cyshang//
2028a00297189c323096aae8e2975de94e8549613cyshang// Driver Support Functions
2128a00297189c323096aae8e2975de94e8549613cyshang//
22162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
23162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  Connects one or more drivers to a controller.
24162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
25022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  ControllerHandle                      Handle of the controller to be
26022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                                connected.
27022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  DriverImageHandle                     DriverImageHandle A pointer to an
28022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                                ordered list of driver image
29022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                                handles.
30022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  RemainingDevicePath                   RemainingDevicePath A pointer to
31022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                                the device path that specifies a
32022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                                child of the controller specified
33022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                                by ControllerHandle.
34022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  Recursive                             Whether the function would be
35022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                                called recursively or not.
36162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
37162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  @return Status code.
38162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
39162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
40022c6d45ef78605c173023f53984e4dfaf7b11f4qhuangEFI_STATUS
4128a00297189c323096aae8e2975de94e8549613cyshangEFIAPI
4228a00297189c323096aae8e2975de94e8549613cyshangCoreConnectController (
4328a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_HANDLE                ControllerHandle,
4428a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_HANDLE                *DriverImageHandle    OPTIONAL,
4528a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_DEVICE_PATH_PROTOCOL  *RemainingDevicePath  OPTIONAL,
4628a00297189c323096aae8e2975de94e8549613cyshang  IN  BOOLEAN                   Recursive
4728a00297189c323096aae8e2975de94e8549613cyshang  )
4828a00297189c323096aae8e2975de94e8549613cyshang{
4928a00297189c323096aae8e2975de94e8549613cyshang  EFI_STATUS                           Status;
5028a00297189c323096aae8e2975de94e8549613cyshang  EFI_STATUS                           ReturnStatus;
5128a00297189c323096aae8e2975de94e8549613cyshang  IHANDLE                              *Handle;
5228a00297189c323096aae8e2975de94e8549613cyshang  PROTOCOL_INTERFACE                   *Prot;
5328a00297189c323096aae8e2975de94e8549613cyshang  LIST_ENTRY                           *Link;
5428a00297189c323096aae8e2975de94e8549613cyshang  LIST_ENTRY                           *ProtLink;
5528a00297189c323096aae8e2975de94e8549613cyshang  OPEN_PROTOCOL_DATA                   *OpenData;
5628a00297189c323096aae8e2975de94e8549613cyshang  EFI_DEVICE_PATH_PROTOCOL             *AlignedRemainingDevicePath;
5785658066182d23e210209299770edaef26d09085mdkinney  EFI_HANDLE                           *ChildHandleBuffer;
5885658066182d23e210209299770edaef26d09085mdkinney  UINTN                                ChildHandleCount;
5985658066182d23e210209299770edaef26d09085mdkinney  UINTN                                Index;
60022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
6128a00297189c323096aae8e2975de94e8549613cyshang  //
6228a00297189c323096aae8e2975de94e8549613cyshang  // Make sure ControllerHandle is valid
6328a00297189c323096aae8e2975de94e8549613cyshang  //
6428a00297189c323096aae8e2975de94e8549613cyshang  Status = CoreValidateHandle (ControllerHandle);
6528a00297189c323096aae8e2975de94e8549613cyshang  if (EFI_ERROR (Status)) {
6628a00297189c323096aae8e2975de94e8549613cyshang    return Status;
6728a00297189c323096aae8e2975de94e8549613cyshang  }
6828a00297189c323096aae8e2975de94e8549613cyshang
6928a00297189c323096aae8e2975de94e8549613cyshang  Handle = ControllerHandle;
7028a00297189c323096aae8e2975de94e8549613cyshang
7128a00297189c323096aae8e2975de94e8549613cyshang  //
7285658066182d23e210209299770edaef26d09085mdkinney  // Make a copy of RemainingDevicePath to guanatee it is aligned
7328a00297189c323096aae8e2975de94e8549613cyshang  //
7428a00297189c323096aae8e2975de94e8549613cyshang  AlignedRemainingDevicePath = NULL;
7528a00297189c323096aae8e2975de94e8549613cyshang  if (RemainingDevicePath != NULL) {
769c4ac31cca01b4a503c36616770ea3157bf3bb9eqhuang    AlignedRemainingDevicePath = DuplicateDevicePath (RemainingDevicePath);
776c857d668cb7d2b219351be1daeec0bcd597e377qwang
786c857d668cb7d2b219351be1daeec0bcd597e377qwang    if (AlignedRemainingDevicePath == NULL) {
796c857d668cb7d2b219351be1daeec0bcd597e377qwang      return EFI_OUT_OF_RESOURCES;
806c857d668cb7d2b219351be1daeec0bcd597e377qwang    }
8128a00297189c323096aae8e2975de94e8549613cyshang  }
8228a00297189c323096aae8e2975de94e8549613cyshang
8328a00297189c323096aae8e2975de94e8549613cyshang  //
8485658066182d23e210209299770edaef26d09085mdkinney  // Connect all drivers to ControllerHandle
8585658066182d23e210209299770edaef26d09085mdkinney  // If CoreConnectSingleController returns EFI_NOT_READY, then the number of
8685658066182d23e210209299770edaef26d09085mdkinney  // Driver Binding Protocols in the handle database has increased during the call
8785658066182d23e210209299770edaef26d09085mdkinney  // so the connect operation must be restarted
8828a00297189c323096aae8e2975de94e8549613cyshang  //
8985658066182d23e210209299770edaef26d09085mdkinney  do {
9085658066182d23e210209299770edaef26d09085mdkinney    ReturnStatus = CoreConnectSingleController (
91e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang                     ControllerHandle,
92e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang                     DriverImageHandle,
93e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang                     AlignedRemainingDevicePath
94e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang                     );
9585658066182d23e210209299770edaef26d09085mdkinney  } while (ReturnStatus == EFI_NOT_READY);
9685658066182d23e210209299770edaef26d09085mdkinney
9785658066182d23e210209299770edaef26d09085mdkinney  //
9885658066182d23e210209299770edaef26d09085mdkinney  // Free the aligned copy of RemainingDevicePath
9985658066182d23e210209299770edaef26d09085mdkinney  //
10085658066182d23e210209299770edaef26d09085mdkinney  if (AlignedRemainingDevicePath != NULL) {
10185658066182d23e210209299770edaef26d09085mdkinney    CoreFreePool (AlignedRemainingDevicePath);
10228a00297189c323096aae8e2975de94e8549613cyshang  }
10328a00297189c323096aae8e2975de94e8549613cyshang
10428a00297189c323096aae8e2975de94e8549613cyshang  //
10528a00297189c323096aae8e2975de94e8549613cyshang  // If recursive, then connect all drivers to all of ControllerHandle's children
10628a00297189c323096aae8e2975de94e8549613cyshang  //
10785658066182d23e210209299770edaef26d09085mdkinney  if (Recursive) {
10885658066182d23e210209299770edaef26d09085mdkinney    //
10985658066182d23e210209299770edaef26d09085mdkinney    // Acquire the protocol lock on the handle database so the child handles can be collected
11085658066182d23e210209299770edaef26d09085mdkinney    //
11185658066182d23e210209299770edaef26d09085mdkinney    CoreAcquireProtocolLock ();
11285658066182d23e210209299770edaef26d09085mdkinney
11385658066182d23e210209299770edaef26d09085mdkinney    //
11485658066182d23e210209299770edaef26d09085mdkinney    // Make sure the DriverBindingHandle is valid
11585658066182d23e210209299770edaef26d09085mdkinney    //
11685658066182d23e210209299770edaef26d09085mdkinney    Status = CoreValidateHandle (ControllerHandle);
11785658066182d23e210209299770edaef26d09085mdkinney    if (EFI_ERROR (Status)) {
11885658066182d23e210209299770edaef26d09085mdkinney      //
11985658066182d23e210209299770edaef26d09085mdkinney      // Release the protocol lock on the handle database
12085658066182d23e210209299770edaef26d09085mdkinney      //
12185658066182d23e210209299770edaef26d09085mdkinney      CoreReleaseProtocolLock ();
12285658066182d23e210209299770edaef26d09085mdkinney
12385658066182d23e210209299770edaef26d09085mdkinney      return ReturnStatus;
12485658066182d23e210209299770edaef26d09085mdkinney    }
12585658066182d23e210209299770edaef26d09085mdkinney
12685658066182d23e210209299770edaef26d09085mdkinney
12785658066182d23e210209299770edaef26d09085mdkinney    //
12885658066182d23e210209299770edaef26d09085mdkinney    // Count ControllerHandle's children
12985658066182d23e210209299770edaef26d09085mdkinney    //
13085658066182d23e210209299770edaef26d09085mdkinney    for (Link = Handle->Protocols.ForwardLink, ChildHandleCount = 0; Link != &Handle->Protocols; Link = Link->ForwardLink) {
13185658066182d23e210209299770edaef26d09085mdkinney      Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
132022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang      for (ProtLink = Prot->OpenList.ForwardLink;
133022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang          ProtLink != &Prot->OpenList;
13485658066182d23e210209299770edaef26d09085mdkinney          ProtLink = ProtLink->ForwardLink) {
13585658066182d23e210209299770edaef26d09085mdkinney        OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
13685658066182d23e210209299770edaef26d09085mdkinney        if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
13785658066182d23e210209299770edaef26d09085mdkinney          ChildHandleCount++;
13885658066182d23e210209299770edaef26d09085mdkinney        }
13985658066182d23e210209299770edaef26d09085mdkinney      }
14085658066182d23e210209299770edaef26d09085mdkinney    }
14185658066182d23e210209299770edaef26d09085mdkinney
14285658066182d23e210209299770edaef26d09085mdkinney    //
14385658066182d23e210209299770edaef26d09085mdkinney    // Allocate a handle buffer for ControllerHandle's children
14485658066182d23e210209299770edaef26d09085mdkinney    //
1459c4ac31cca01b4a503c36616770ea3157bf3bb9eqhuang    ChildHandleBuffer = AllocatePool (ChildHandleCount * sizeof(EFI_HANDLE));
1466c857d668cb7d2b219351be1daeec0bcd597e377qwang    if (ChildHandleBuffer == NULL) {
147fa3c419fec30282afb85a788cb71e12fd1a51804qwang      CoreReleaseProtocolLock ();
1486c857d668cb7d2b219351be1daeec0bcd597e377qwang      return EFI_OUT_OF_RESOURCES;
1496c857d668cb7d2b219351be1daeec0bcd597e377qwang    }
15085658066182d23e210209299770edaef26d09085mdkinney
15185658066182d23e210209299770edaef26d09085mdkinney    //
15285658066182d23e210209299770edaef26d09085mdkinney    // Fill in a handle buffer with ControllerHandle's children
15385658066182d23e210209299770edaef26d09085mdkinney    //
15485658066182d23e210209299770edaef26d09085mdkinney    for (Link = Handle->Protocols.ForwardLink, ChildHandleCount = 0; Link != &Handle->Protocols; Link = Link->ForwardLink) {
15585658066182d23e210209299770edaef26d09085mdkinney      Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
156022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang      for (ProtLink = Prot->OpenList.ForwardLink;
157022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang          ProtLink != &Prot->OpenList;
15885658066182d23e210209299770edaef26d09085mdkinney          ProtLink = ProtLink->ForwardLink) {
15928a00297189c323096aae8e2975de94e8549613cyshang        OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
16028a00297189c323096aae8e2975de94e8549613cyshang        if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
16185658066182d23e210209299770edaef26d09085mdkinney          ChildHandleBuffer[ChildHandleCount] = OpenData->ControllerHandle;
16285658066182d23e210209299770edaef26d09085mdkinney          ChildHandleCount++;
16385658066182d23e210209299770edaef26d09085mdkinney        }
16485658066182d23e210209299770edaef26d09085mdkinney      }
16585658066182d23e210209299770edaef26d09085mdkinney    }
16685658066182d23e210209299770edaef26d09085mdkinney
16785658066182d23e210209299770edaef26d09085mdkinney    //
16885658066182d23e210209299770edaef26d09085mdkinney    // Release the protocol lock on the handle database
16985658066182d23e210209299770edaef26d09085mdkinney    //
17085658066182d23e210209299770edaef26d09085mdkinney    CoreReleaseProtocolLock ();
17185658066182d23e210209299770edaef26d09085mdkinney
17285658066182d23e210209299770edaef26d09085mdkinney    //
17385658066182d23e210209299770edaef26d09085mdkinney    // Recursively connect each child handle
17485658066182d23e210209299770edaef26d09085mdkinney    //
17585658066182d23e210209299770edaef26d09085mdkinney    for (Index = 0; Index < ChildHandleCount; Index++) {
17685658066182d23e210209299770edaef26d09085mdkinney      CoreConnectController (
17785658066182d23e210209299770edaef26d09085mdkinney        ChildHandleBuffer[Index],
17885658066182d23e210209299770edaef26d09085mdkinney        NULL,
17985658066182d23e210209299770edaef26d09085mdkinney        NULL,
18085658066182d23e210209299770edaef26d09085mdkinney        TRUE
181022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang        );
18285658066182d23e210209299770edaef26d09085mdkinney    }
18385658066182d23e210209299770edaef26d09085mdkinney
18485658066182d23e210209299770edaef26d09085mdkinney    //
18585658066182d23e210209299770edaef26d09085mdkinney    // Free the handle buffer of ControllerHandle's children
18685658066182d23e210209299770edaef26d09085mdkinney    //
18785658066182d23e210209299770edaef26d09085mdkinney    CoreFreePool (ChildHandleBuffer);
18885658066182d23e210209299770edaef26d09085mdkinney  }
18985658066182d23e210209299770edaef26d09085mdkinney
19028a00297189c323096aae8e2975de94e8549613cyshang  return ReturnStatus;
19128a00297189c323096aae8e2975de94e8549613cyshang}
19228a00297189c323096aae8e2975de94e8549613cyshang
193162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
194162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
195162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  Add Driver Binding Protocols from Context Driver Image Handles to sorted
196162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  Driver Binding Protocol list.
197162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
198022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  DriverBindingHandle                   Handle of the driver binding
199022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                                protocol.
200022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  NumberOfSortedDriverBindingProtocols  Number Of sorted driver binding
201022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                                protocols
202022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  SortedDriverBindingProtocols          The sorted protocol list.
203022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  DriverBindingHandleCount              Driver Binding Handle Count.
204022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  DriverBindingHandleBuffer             The buffer of driver binding
205022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                                protocol to be modified.
206022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  IsImageHandle                         Indicate whether
207022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                                DriverBindingHandle is an image
208022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                                handle
209162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
210162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  @return None.
211162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
212162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
21328a00297189c323096aae8e2975de94e8549613cyshangVOID
21428a00297189c323096aae8e2975de94e8549613cyshangAddSortedDriverBindingProtocol (
21528a00297189c323096aae8e2975de94e8549613cyshang  IN      EFI_HANDLE                   DriverBindingHandle,
216022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  IN OUT  UINTN                        *NumberOfSortedDriverBindingProtocols,
21728a00297189c323096aae8e2975de94e8549613cyshang  IN OUT  EFI_DRIVER_BINDING_PROTOCOL  **SortedDriverBindingProtocols,
21828a00297189c323096aae8e2975de94e8549613cyshang  IN      UINTN                        DriverBindingHandleCount,
219adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney  IN OUT  EFI_HANDLE                   *DriverBindingHandleBuffer,
220adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney  IN      BOOLEAN                      IsImageHandle
22128a00297189c323096aae8e2975de94e8549613cyshang  )
22228a00297189c323096aae8e2975de94e8549613cyshang{
22328a00297189c323096aae8e2975de94e8549613cyshang  EFI_STATUS                   Status;
22428a00297189c323096aae8e2975de94e8549613cyshang  EFI_DRIVER_BINDING_PROTOCOL  *DriverBinding;
22528a00297189c323096aae8e2975de94e8549613cyshang  UINTN                        Index;
22628a00297189c323096aae8e2975de94e8549613cyshang
22728a00297189c323096aae8e2975de94e8549613cyshang  //
22828a00297189c323096aae8e2975de94e8549613cyshang  // Make sure the DriverBindingHandle is valid
22928a00297189c323096aae8e2975de94e8549613cyshang  //
23028a00297189c323096aae8e2975de94e8549613cyshang  Status = CoreValidateHandle (DriverBindingHandle);
23128a00297189c323096aae8e2975de94e8549613cyshang  if (EFI_ERROR (Status)) {
23228a00297189c323096aae8e2975de94e8549613cyshang    return;
23328a00297189c323096aae8e2975de94e8549613cyshang  }
23428a00297189c323096aae8e2975de94e8549613cyshang
23528a00297189c323096aae8e2975de94e8549613cyshang  //
236adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney  // If IsImageHandle is TRUE, then DriverBindingHandle is an image handle
237adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney  // Find all the DriverBindingHandles associated with that image handle and add them to the sorted list
238adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney  //
239adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney  if (IsImageHandle) {
240adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney    //
241adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney    // Loop through all the Driver Binding Handles
242adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney    //
243adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney    for (Index = 0; Index < DriverBindingHandleCount; Index++) {
244adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney      //
245adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney      // Retrieve the Driver Binding Protocol associated with each Driver Binding Handle
246adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney      //
247adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney      Status = CoreHandleProtocol (
248adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney                DriverBindingHandleBuffer[Index],
249adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney                &gEfiDriverBindingProtocolGuid,
250e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang                (VOID **) &DriverBinding
251adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney                );
25270279390ba9a0774e020af36120f8b9ba1c217dbmdkinney      if (EFI_ERROR (Status) || DriverBinding == NULL) {
25370279390ba9a0774e020af36120f8b9ba1c217dbmdkinney        continue;
25470279390ba9a0774e020af36120f8b9ba1c217dbmdkinney      }
25570279390ba9a0774e020af36120f8b9ba1c217dbmdkinney
256adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney      //
257adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney      // If the ImageHandle associated with DriverBinding matches DriverBindingHandle,
258adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney      // then add the DriverBindingProtocol[Index] to the sorted list
259adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney      //
260adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney      if (DriverBinding->ImageHandle == DriverBindingHandle) {
261adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney        AddSortedDriverBindingProtocol (
262adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney          DriverBindingHandleBuffer[Index],
263022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang          NumberOfSortedDriverBindingProtocols,
264adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney          SortedDriverBindingProtocols,
265adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney          DriverBindingHandleCount,
266adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney          DriverBindingHandleBuffer,
267adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney          FALSE
268adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney          );
269adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney      }
270adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney    }
271adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney    return;
272adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney  }
273adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney
274adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney  //
27528a00297189c323096aae8e2975de94e8549613cyshang  // Retrieve the Driver Binding Protocol from DriverBindingHandle
27628a00297189c323096aae8e2975de94e8549613cyshang  //
27728a00297189c323096aae8e2975de94e8549613cyshang  Status = CoreHandleProtocol(
27828a00297189c323096aae8e2975de94e8549613cyshang             DriverBindingHandle,
27928a00297189c323096aae8e2975de94e8549613cyshang             &gEfiDriverBindingProtocolGuid,
280e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang             (VOID **) &DriverBinding
28128a00297189c323096aae8e2975de94e8549613cyshang             );
28228a00297189c323096aae8e2975de94e8549613cyshang  //
28328a00297189c323096aae8e2975de94e8549613cyshang  // If DriverBindingHandle does not support the Driver Binding Protocol then return
28428a00297189c323096aae8e2975de94e8549613cyshang  //
28528a00297189c323096aae8e2975de94e8549613cyshang  if (EFI_ERROR (Status) || DriverBinding == NULL) {
28628a00297189c323096aae8e2975de94e8549613cyshang    return;
28728a00297189c323096aae8e2975de94e8549613cyshang  }
28828a00297189c323096aae8e2975de94e8549613cyshang
28928a00297189c323096aae8e2975de94e8549613cyshang  //
29028a00297189c323096aae8e2975de94e8549613cyshang  // See if DriverBinding is already in the sorted list
29128a00297189c323096aae8e2975de94e8549613cyshang  //
29285658066182d23e210209299770edaef26d09085mdkinney  for (Index = 0; Index < *NumberOfSortedDriverBindingProtocols && Index < DriverBindingHandleCount; Index++) {
29328a00297189c323096aae8e2975de94e8549613cyshang    if (DriverBinding == SortedDriverBindingProtocols[Index]) {
29428a00297189c323096aae8e2975de94e8549613cyshang      return;
29528a00297189c323096aae8e2975de94e8549613cyshang    }
29628a00297189c323096aae8e2975de94e8549613cyshang  }
29728a00297189c323096aae8e2975de94e8549613cyshang
29828a00297189c323096aae8e2975de94e8549613cyshang  //
29928a00297189c323096aae8e2975de94e8549613cyshang  // Add DriverBinding to the end of the list
30028a00297189c323096aae8e2975de94e8549613cyshang  //
30185658066182d23e210209299770edaef26d09085mdkinney  if (*NumberOfSortedDriverBindingProtocols < DriverBindingHandleCount) {
30285658066182d23e210209299770edaef26d09085mdkinney    SortedDriverBindingProtocols[*NumberOfSortedDriverBindingProtocols] = DriverBinding;
30385658066182d23e210209299770edaef26d09085mdkinney  }
30428a00297189c323096aae8e2975de94e8549613cyshang  *NumberOfSortedDriverBindingProtocols = *NumberOfSortedDriverBindingProtocols + 1;
30528a00297189c323096aae8e2975de94e8549613cyshang
30628a00297189c323096aae8e2975de94e8549613cyshang  //
30728a00297189c323096aae8e2975de94e8549613cyshang  // Mark the cooresponding handle in DriverBindingHandleBuffer as used
30828a00297189c323096aae8e2975de94e8549613cyshang  //
30928a00297189c323096aae8e2975de94e8549613cyshang  for (Index = 0; Index < DriverBindingHandleCount; Index++) {
31028a00297189c323096aae8e2975de94e8549613cyshang    if (DriverBindingHandleBuffer[Index] == DriverBindingHandle) {
31128a00297189c323096aae8e2975de94e8549613cyshang      DriverBindingHandleBuffer[Index] = NULL;
31228a00297189c323096aae8e2975de94e8549613cyshang    }
31328a00297189c323096aae8e2975de94e8549613cyshang  }
31428a00297189c323096aae8e2975de94e8549613cyshang}
315022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
316162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
317162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
318162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  Connects a controller to a driver.
319162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
320022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  ControllerHandle                      Handle of the controller to be
321022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                                connected.
322022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  ContextDriverImageHandles             DriverImageHandle A pointer to an
323022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                                ordered list of driver image
324022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                                handles.
325022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  RemainingDevicePath                   RemainingDevicePath A pointer to
326022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                                the device path that specifies a
327022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                                child  of the controller
328022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                                specified by ControllerHandle.
329022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
330022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval EFI_SUCCESS                           One or more drivers were
331022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                                connected to ControllerHandle.
332022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval EFI_OUT_OF_RESOURCES                  No enough system resources to
333022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                                complete the request.
334022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval EFI_NOT_FOUND                         No drivers were connected to
335162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang                                                ControllerHandle.
336162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
337162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
338022c6d45ef78605c173023f53984e4dfaf7b11f4qhuangEFI_STATUS
33928a00297189c323096aae8e2975de94e8549613cyshangCoreConnectSingleController (
34028a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_HANDLE                ControllerHandle,
34128a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_HANDLE                *ContextDriverImageHandles OPTIONAL,
342022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  IN  EFI_DEVICE_PATH_PROTOCOL  *RemainingDevicePath       OPTIONAL
34328a00297189c323096aae8e2975de94e8549613cyshang  )
34428a00297189c323096aae8e2975de94e8549613cyshang{
34528a00297189c323096aae8e2975de94e8549613cyshang  EFI_STATUS                                 Status;
34628a00297189c323096aae8e2975de94e8549613cyshang  UINTN                                      Index;
34728a00297189c323096aae8e2975de94e8549613cyshang  EFI_HANDLE                                 DriverImageHandle;
34828a00297189c323096aae8e2975de94e8549613cyshang  EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL      *PlatformDriverOverride;
34928a00297189c323096aae8e2975de94e8549613cyshang  EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL  *BusSpecificDriverOverride;
35028a00297189c323096aae8e2975de94e8549613cyshang  UINTN                                      DriverBindingHandleCount;
35128a00297189c323096aae8e2975de94e8549613cyshang  EFI_HANDLE                                 *DriverBindingHandleBuffer;
35270279390ba9a0774e020af36120f8b9ba1c217dbmdkinney  UINTN                                      NewDriverBindingHandleCount;
35370279390ba9a0774e020af36120f8b9ba1c217dbmdkinney  EFI_HANDLE                                 *NewDriverBindingHandleBuffer;
35428a00297189c323096aae8e2975de94e8549613cyshang  EFI_DRIVER_BINDING_PROTOCOL                *DriverBinding;
35528a00297189c323096aae8e2975de94e8549613cyshang  UINTN                                      NumberOfSortedDriverBindingProtocols;
35628a00297189c323096aae8e2975de94e8549613cyshang  EFI_DRIVER_BINDING_PROTOCOL                **SortedDriverBindingProtocols;
35728a00297189c323096aae8e2975de94e8549613cyshang  UINT32                                     HighestVersion;
35828a00297189c323096aae8e2975de94e8549613cyshang  UINTN                                      HighestIndex;
35928a00297189c323096aae8e2975de94e8549613cyshang  UINTN                                      SortIndex;
36028a00297189c323096aae8e2975de94e8549613cyshang  BOOLEAN                                    OneStarted;
36128a00297189c323096aae8e2975de94e8549613cyshang  BOOLEAN                                    DriverFound;
36228a00297189c323096aae8e2975de94e8549613cyshang
36328a00297189c323096aae8e2975de94e8549613cyshang  //
36428a00297189c323096aae8e2975de94e8549613cyshang  // Initialize local variables
36528a00297189c323096aae8e2975de94e8549613cyshang  //
36628a00297189c323096aae8e2975de94e8549613cyshang  DriverBindingHandleCount              = 0;
36728a00297189c323096aae8e2975de94e8549613cyshang  DriverBindingHandleBuffer             = NULL;
36828a00297189c323096aae8e2975de94e8549613cyshang  NumberOfSortedDriverBindingProtocols  = 0;
36928a00297189c323096aae8e2975de94e8549613cyshang  SortedDriverBindingProtocols          = NULL;
37028a00297189c323096aae8e2975de94e8549613cyshang
37128a00297189c323096aae8e2975de94e8549613cyshang  //
37228a00297189c323096aae8e2975de94e8549613cyshang  // Get list of all Driver Binding Protocol Instances
37328a00297189c323096aae8e2975de94e8549613cyshang  //
37428a00297189c323096aae8e2975de94e8549613cyshang  Status = CoreLocateHandleBuffer (
375022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang             ByProtocol,
376022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang             &gEfiDriverBindingProtocolGuid,
37728a00297189c323096aae8e2975de94e8549613cyshang             NULL,
378022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang             &DriverBindingHandleCount,
37928a00297189c323096aae8e2975de94e8549613cyshang             &DriverBindingHandleBuffer
38028a00297189c323096aae8e2975de94e8549613cyshang             );
38128a00297189c323096aae8e2975de94e8549613cyshang  if (EFI_ERROR (Status) || (DriverBindingHandleCount == 0)) {
38228a00297189c323096aae8e2975de94e8549613cyshang    return EFI_NOT_FOUND;
38328a00297189c323096aae8e2975de94e8549613cyshang  }
38428a00297189c323096aae8e2975de94e8549613cyshang
38528a00297189c323096aae8e2975de94e8549613cyshang  //
38628a00297189c323096aae8e2975de94e8549613cyshang  // Allocate a duplicate array for the sorted Driver Binding Protocol Instances
38728a00297189c323096aae8e2975de94e8549613cyshang  //
3889c4ac31cca01b4a503c36616770ea3157bf3bb9eqhuang  SortedDriverBindingProtocols = AllocatePool (sizeof (VOID *) * DriverBindingHandleCount);
38928a00297189c323096aae8e2975de94e8549613cyshang  if (SortedDriverBindingProtocols == NULL) {
39028a00297189c323096aae8e2975de94e8549613cyshang    CoreFreePool (DriverBindingHandleBuffer);
39128a00297189c323096aae8e2975de94e8549613cyshang    return EFI_OUT_OF_RESOURCES;
39228a00297189c323096aae8e2975de94e8549613cyshang  }
39328a00297189c323096aae8e2975de94e8549613cyshang
39428a00297189c323096aae8e2975de94e8549613cyshang  //
39528a00297189c323096aae8e2975de94e8549613cyshang  // Add Driver Binding Protocols from Context Driver Image Handles first
39628a00297189c323096aae8e2975de94e8549613cyshang  //
39728a00297189c323096aae8e2975de94e8549613cyshang  if (ContextDriverImageHandles != NULL) {
39828a00297189c323096aae8e2975de94e8549613cyshang    for (Index = 0; ContextDriverImageHandles[Index] != NULL; Index++) {
39928a00297189c323096aae8e2975de94e8549613cyshang      AddSortedDriverBindingProtocol (
40028a00297189c323096aae8e2975de94e8549613cyshang        ContextDriverImageHandles[Index],
401022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang        &NumberOfSortedDriverBindingProtocols,
40228a00297189c323096aae8e2975de94e8549613cyshang        SortedDriverBindingProtocols,
40328a00297189c323096aae8e2975de94e8549613cyshang        DriverBindingHandleCount,
404adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney        DriverBindingHandleBuffer,
405adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney        FALSE
40628a00297189c323096aae8e2975de94e8549613cyshang        );
40728a00297189c323096aae8e2975de94e8549613cyshang    }
40828a00297189c323096aae8e2975de94e8549613cyshang  }
40928a00297189c323096aae8e2975de94e8549613cyshang
41028a00297189c323096aae8e2975de94e8549613cyshang  //
41128a00297189c323096aae8e2975de94e8549613cyshang  // Add the Platform Driver Override Protocol drivers for ControllerHandle next
41228a00297189c323096aae8e2975de94e8549613cyshang  //
41328a00297189c323096aae8e2975de94e8549613cyshang  Status = CoreLocateProtocol (
414022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang             &gEfiPlatformDriverOverrideProtocolGuid,
415022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang             NULL,
416e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang             (VOID **) &PlatformDriverOverride
41728a00297189c323096aae8e2975de94e8549613cyshang             );
41828a00297189c323096aae8e2975de94e8549613cyshang  if (!EFI_ERROR (Status) && (PlatformDriverOverride != NULL)) {
41928a00297189c323096aae8e2975de94e8549613cyshang    DriverImageHandle = NULL;
42028a00297189c323096aae8e2975de94e8549613cyshang    do {
42128a00297189c323096aae8e2975de94e8549613cyshang      Status = PlatformDriverOverride->GetDriver (
42228a00297189c323096aae8e2975de94e8549613cyshang                                         PlatformDriverOverride,
42328a00297189c323096aae8e2975de94e8549613cyshang                                         ControllerHandle,
42428a00297189c323096aae8e2975de94e8549613cyshang                                         &DriverImageHandle
42528a00297189c323096aae8e2975de94e8549613cyshang                                         );
42628a00297189c323096aae8e2975de94e8549613cyshang      if (!EFI_ERROR (Status)) {
42728a00297189c323096aae8e2975de94e8549613cyshang        AddSortedDriverBindingProtocol (
42828a00297189c323096aae8e2975de94e8549613cyshang          DriverImageHandle,
429022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang          &NumberOfSortedDriverBindingProtocols,
43028a00297189c323096aae8e2975de94e8549613cyshang          SortedDriverBindingProtocols,
43128a00297189c323096aae8e2975de94e8549613cyshang          DriverBindingHandleCount,
432adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney          DriverBindingHandleBuffer,
433adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney          TRUE
43428a00297189c323096aae8e2975de94e8549613cyshang          );
43528a00297189c323096aae8e2975de94e8549613cyshang      }
43628a00297189c323096aae8e2975de94e8549613cyshang    } while (!EFI_ERROR (Status));
43728a00297189c323096aae8e2975de94e8549613cyshang  }
43828a00297189c323096aae8e2975de94e8549613cyshang
43928a00297189c323096aae8e2975de94e8549613cyshang  //
44028a00297189c323096aae8e2975de94e8549613cyshang  // Get the Bus Specific Driver Override Protocol instance on the Controller Handle
44128a00297189c323096aae8e2975de94e8549613cyshang  //
442adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney  Status = CoreHandleProtocol (
443022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang             ControllerHandle,
444022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang             &gEfiBusSpecificDriverOverrideProtocolGuid,
445e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang             (VOID **) &BusSpecificDriverOverride
44628a00297189c323096aae8e2975de94e8549613cyshang             );
44728a00297189c323096aae8e2975de94e8549613cyshang  if (!EFI_ERROR (Status) && (BusSpecificDriverOverride != NULL)) {
44828a00297189c323096aae8e2975de94e8549613cyshang    DriverImageHandle = NULL;
44928a00297189c323096aae8e2975de94e8549613cyshang    do {
45028a00297189c323096aae8e2975de94e8549613cyshang      Status = BusSpecificDriverOverride->GetDriver (
45128a00297189c323096aae8e2975de94e8549613cyshang                                            BusSpecificDriverOverride,
45228a00297189c323096aae8e2975de94e8549613cyshang                                            &DriverImageHandle
45328a00297189c323096aae8e2975de94e8549613cyshang                                            );
45428a00297189c323096aae8e2975de94e8549613cyshang      if (!EFI_ERROR (Status)) {
45528a00297189c323096aae8e2975de94e8549613cyshang        AddSortedDriverBindingProtocol (
45628a00297189c323096aae8e2975de94e8549613cyshang          DriverImageHandle,
457022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang          &NumberOfSortedDriverBindingProtocols,
45828a00297189c323096aae8e2975de94e8549613cyshang          SortedDriverBindingProtocols,
45928a00297189c323096aae8e2975de94e8549613cyshang          DriverBindingHandleCount,
460adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney          DriverBindingHandleBuffer,
461adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney          TRUE
46228a00297189c323096aae8e2975de94e8549613cyshang          );
46328a00297189c323096aae8e2975de94e8549613cyshang      }
46428a00297189c323096aae8e2975de94e8549613cyshang    } while (!EFI_ERROR (Status));
46528a00297189c323096aae8e2975de94e8549613cyshang  }
46628a00297189c323096aae8e2975de94e8549613cyshang
46728a00297189c323096aae8e2975de94e8549613cyshang  //
46828a00297189c323096aae8e2975de94e8549613cyshang  // Then add all the remaining Driver Binding Protocols
46928a00297189c323096aae8e2975de94e8549613cyshang  //
47028a00297189c323096aae8e2975de94e8549613cyshang  SortIndex = NumberOfSortedDriverBindingProtocols;
47128a00297189c323096aae8e2975de94e8549613cyshang  for (Index = 0; Index < DriverBindingHandleCount; Index++) {
47228a00297189c323096aae8e2975de94e8549613cyshang    AddSortedDriverBindingProtocol (
47328a00297189c323096aae8e2975de94e8549613cyshang      DriverBindingHandleBuffer[Index],
474022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang      &NumberOfSortedDriverBindingProtocols,
47528a00297189c323096aae8e2975de94e8549613cyshang      SortedDriverBindingProtocols,
47628a00297189c323096aae8e2975de94e8549613cyshang      DriverBindingHandleCount,
477adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney      DriverBindingHandleBuffer,
478adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney      FALSE
47928a00297189c323096aae8e2975de94e8549613cyshang      );
48028a00297189c323096aae8e2975de94e8549613cyshang  }
48128a00297189c323096aae8e2975de94e8549613cyshang
48228a00297189c323096aae8e2975de94e8549613cyshang  //
48328a00297189c323096aae8e2975de94e8549613cyshang  // Free the Driver Binding Handle Buffer
48428a00297189c323096aae8e2975de94e8549613cyshang  //
48528a00297189c323096aae8e2975de94e8549613cyshang  CoreFreePool (DriverBindingHandleBuffer);
48628a00297189c323096aae8e2975de94e8549613cyshang
48728a00297189c323096aae8e2975de94e8549613cyshang  //
48885658066182d23e210209299770edaef26d09085mdkinney  // If the number of Driver Binding Protocols has increased since this function started, then return
48985658066182d23e210209299770edaef26d09085mdkinney  // EFI_NOT_READY, so it will be restarted
49085658066182d23e210209299770edaef26d09085mdkinney  //
49170279390ba9a0774e020af36120f8b9ba1c217dbmdkinney  Status = CoreLocateHandleBuffer (
492022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang             ByProtocol,
493022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang             &gEfiDriverBindingProtocolGuid,
49470279390ba9a0774e020af36120f8b9ba1c217dbmdkinney             NULL,
495022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang             &NewDriverBindingHandleCount,
49670279390ba9a0774e020af36120f8b9ba1c217dbmdkinney             &NewDriverBindingHandleBuffer
49770279390ba9a0774e020af36120f8b9ba1c217dbmdkinney             );
49870279390ba9a0774e020af36120f8b9ba1c217dbmdkinney  CoreFreePool (NewDriverBindingHandleBuffer);
49970279390ba9a0774e020af36120f8b9ba1c217dbmdkinney  if (NewDriverBindingHandleCount > DriverBindingHandleCount) {
50085658066182d23e210209299770edaef26d09085mdkinney    //
50185658066182d23e210209299770edaef26d09085mdkinney    // Free any buffers that were allocated with AllocatePool()
50285658066182d23e210209299770edaef26d09085mdkinney    //
50385658066182d23e210209299770edaef26d09085mdkinney    CoreFreePool (SortedDriverBindingProtocols);
50485658066182d23e210209299770edaef26d09085mdkinney
50585658066182d23e210209299770edaef26d09085mdkinney    return EFI_NOT_READY;
50685658066182d23e210209299770edaef26d09085mdkinney  }
50785658066182d23e210209299770edaef26d09085mdkinney
50885658066182d23e210209299770edaef26d09085mdkinney  //
50928a00297189c323096aae8e2975de94e8549613cyshang  // Sort the remaining DriverBinding Protocol based on their Version field from
51028a00297189c323096aae8e2975de94e8549613cyshang  // highest to lowest.
51128a00297189c323096aae8e2975de94e8549613cyshang  //
51228a00297189c323096aae8e2975de94e8549613cyshang  for ( ; SortIndex < NumberOfSortedDriverBindingProtocols; SortIndex++) {
51328a00297189c323096aae8e2975de94e8549613cyshang    HighestVersion = SortedDriverBindingProtocols[SortIndex]->Version;
51428a00297189c323096aae8e2975de94e8549613cyshang    HighestIndex   = SortIndex;
51528a00297189c323096aae8e2975de94e8549613cyshang    for (Index = SortIndex + 1; Index < NumberOfSortedDriverBindingProtocols; Index++) {
51628a00297189c323096aae8e2975de94e8549613cyshang      if (SortedDriverBindingProtocols[Index]->Version > HighestVersion) {
51728a00297189c323096aae8e2975de94e8549613cyshang        HighestVersion = SortedDriverBindingProtocols[Index]->Version;
51828a00297189c323096aae8e2975de94e8549613cyshang        HighestIndex   = Index;
51928a00297189c323096aae8e2975de94e8549613cyshang      }
52028a00297189c323096aae8e2975de94e8549613cyshang    }
52128a00297189c323096aae8e2975de94e8549613cyshang    if (SortIndex != HighestIndex) {
52228a00297189c323096aae8e2975de94e8549613cyshang      DriverBinding = SortedDriverBindingProtocols[SortIndex];
52328a00297189c323096aae8e2975de94e8549613cyshang      SortedDriverBindingProtocols[SortIndex] = SortedDriverBindingProtocols[HighestIndex];
52428a00297189c323096aae8e2975de94e8549613cyshang      SortedDriverBindingProtocols[HighestIndex] = DriverBinding;
52528a00297189c323096aae8e2975de94e8549613cyshang    }
52628a00297189c323096aae8e2975de94e8549613cyshang  }
52728a00297189c323096aae8e2975de94e8549613cyshang
52828a00297189c323096aae8e2975de94e8549613cyshang  //
52928a00297189c323096aae8e2975de94e8549613cyshang  // Loop until no more drivers can be started on ControllerHandle
53028a00297189c323096aae8e2975de94e8549613cyshang  //
53128a00297189c323096aae8e2975de94e8549613cyshang  OneStarted = FALSE;
53228a00297189c323096aae8e2975de94e8549613cyshang  do {
53328a00297189c323096aae8e2975de94e8549613cyshang
53428a00297189c323096aae8e2975de94e8549613cyshang    //
53528a00297189c323096aae8e2975de94e8549613cyshang    // Loop through the sorted Driver Binding Protocol Instances in order, and see if
536022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang    // any of the Driver Binding Protocols support the controller specified by
53728a00297189c323096aae8e2975de94e8549613cyshang    // ControllerHandle.
53828a00297189c323096aae8e2975de94e8549613cyshang    //
53928a00297189c323096aae8e2975de94e8549613cyshang    DriverBinding = NULL;
54028a00297189c323096aae8e2975de94e8549613cyshang    DriverFound = FALSE;
54128a00297189c323096aae8e2975de94e8549613cyshang    for (Index = 0; (Index < NumberOfSortedDriverBindingProtocols) && !DriverFound; Index++) {
54228a00297189c323096aae8e2975de94e8549613cyshang      if (SortedDriverBindingProtocols[Index] != NULL) {
54328a00297189c323096aae8e2975de94e8549613cyshang        DriverBinding = SortedDriverBindingProtocols[Index];
54428a00297189c323096aae8e2975de94e8549613cyshang        Status = DriverBinding->Supported(
545022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                  DriverBinding,
54628a00297189c323096aae8e2975de94e8549613cyshang                                  ControllerHandle,
54728a00297189c323096aae8e2975de94e8549613cyshang                                  RemainingDevicePath
54828a00297189c323096aae8e2975de94e8549613cyshang                                  );
54928a00297189c323096aae8e2975de94e8549613cyshang        if (!EFI_ERROR (Status)) {
55028a00297189c323096aae8e2975de94e8549613cyshang          SortedDriverBindingProtocols[Index] = NULL;
55128a00297189c323096aae8e2975de94e8549613cyshang          DriverFound = TRUE;
55228a00297189c323096aae8e2975de94e8549613cyshang
55328a00297189c323096aae8e2975de94e8549613cyshang          //
55428a00297189c323096aae8e2975de94e8549613cyshang          // A driver was found that supports ControllerHandle, so attempt to start the driver
55528a00297189c323096aae8e2975de94e8549613cyshang          // on ControllerHandle.
55628a00297189c323096aae8e2975de94e8549613cyshang          //
557adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney          PERF_START (DriverBinding->DriverBindingHandle, DRIVERBINDING_START_TOK, NULL, 0);
55828a00297189c323096aae8e2975de94e8549613cyshang          Status = DriverBinding->Start (
559022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                    DriverBinding,
56028a00297189c323096aae8e2975de94e8549613cyshang                                    ControllerHandle,
56128a00297189c323096aae8e2975de94e8549613cyshang                                    RemainingDevicePath
56228a00297189c323096aae8e2975de94e8549613cyshang                                    );
563adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney          PERF_END (DriverBinding->DriverBindingHandle, DRIVERBINDING_START_TOK, NULL, 0);
56428a00297189c323096aae8e2975de94e8549613cyshang
56528a00297189c323096aae8e2975de94e8549613cyshang          if (!EFI_ERROR (Status)) {
56628a00297189c323096aae8e2975de94e8549613cyshang            //
56728a00297189c323096aae8e2975de94e8549613cyshang            // The driver was successfully started on ControllerHandle, so set a flag
56828a00297189c323096aae8e2975de94e8549613cyshang            //
56928a00297189c323096aae8e2975de94e8549613cyshang            OneStarted = TRUE;
57028a00297189c323096aae8e2975de94e8549613cyshang          }
57128a00297189c323096aae8e2975de94e8549613cyshang        }
57228a00297189c323096aae8e2975de94e8549613cyshang      }
57328a00297189c323096aae8e2975de94e8549613cyshang    }
57428a00297189c323096aae8e2975de94e8549613cyshang  } while (DriverFound);
57528a00297189c323096aae8e2975de94e8549613cyshang
57628a00297189c323096aae8e2975de94e8549613cyshang  //
57728a00297189c323096aae8e2975de94e8549613cyshang  // Free any buffers that were allocated with AllocatePool()
57828a00297189c323096aae8e2975de94e8549613cyshang  //
57928a00297189c323096aae8e2975de94e8549613cyshang  CoreFreePool (SortedDriverBindingProtocols);
58028a00297189c323096aae8e2975de94e8549613cyshang
58128a00297189c323096aae8e2975de94e8549613cyshang  //
58228a00297189c323096aae8e2975de94e8549613cyshang  // If at least one driver was started on ControllerHandle, then return EFI_SUCCESS.
58328a00297189c323096aae8e2975de94e8549613cyshang  //
58428a00297189c323096aae8e2975de94e8549613cyshang  if (OneStarted) {
58528a00297189c323096aae8e2975de94e8549613cyshang    return EFI_SUCCESS;
586022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  }
58728a00297189c323096aae8e2975de94e8549613cyshang
58828a00297189c323096aae8e2975de94e8549613cyshang  //
58928a00297189c323096aae8e2975de94e8549613cyshang  // If no drivers started and RemainingDevicePath is an End Device Path Node, then return EFI_SUCCESS
59028a00297189c323096aae8e2975de94e8549613cyshang  //
59128a00297189c323096aae8e2975de94e8549613cyshang  if (RemainingDevicePath != NULL) {
59228a00297189c323096aae8e2975de94e8549613cyshang    if (IsDevicePathEnd (RemainingDevicePath)) {
59328a00297189c323096aae8e2975de94e8549613cyshang      return EFI_SUCCESS;
59428a00297189c323096aae8e2975de94e8549613cyshang    }
595022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  }
59628a00297189c323096aae8e2975de94e8549613cyshang
59728a00297189c323096aae8e2975de94e8549613cyshang  //
59828a00297189c323096aae8e2975de94e8549613cyshang  // Otherwise, no drivers were started on ControllerHandle, so return EFI_NOT_FOUND
59928a00297189c323096aae8e2975de94e8549613cyshang  //
60028a00297189c323096aae8e2975de94e8549613cyshang  return EFI_NOT_FOUND;
60128a00297189c323096aae8e2975de94e8549613cyshang}
60228a00297189c323096aae8e2975de94e8549613cyshang
60328a00297189c323096aae8e2975de94e8549613cyshang
604162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
605162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
606162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  Disonnects a controller from a driver
607162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
608022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  ControllerHandle                      ControllerHandle The handle of
609022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                                the controller from which
610022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                                driver(s)  are to be
611022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                                disconnected.
612022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  DriverImageHandle                     DriverImageHandle The driver to
613022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                                disconnect from ControllerHandle.
614022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  ChildHandle                           ChildHandle The handle of the
615022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                                child to destroy.
616022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
617022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval EFI_SUCCESS                           One or more drivers were
618022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                                disconnected from the controller.
619022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval EFI_SUCCESS                           On entry, no drivers are managing
620022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                                ControllerHandle.
621022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval EFI_SUCCESS                           DriverImageHandle is not NULL,
622022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                                and on entry DriverImageHandle is
623022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                                not managing ControllerHandle.
624022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval EFI_INVALID_PARAMETER                 ControllerHandle is not a valid
625022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                                EFI_HANDLE.
626022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval EFI_INVALID_PARAMETER                 DriverImageHandle is not NULL,
627022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                                and it is not a valid EFI_HANDLE.
628022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval EFI_INVALID_PARAMETER                 ChildHandle is not NULL, and it
629022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                                is not a valid EFI_HANDLE.
630022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval EFI_OUT_OF_RESOURCES                  There are not enough resources
631022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                                available to disconnect any
632022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                                drivers from ControllerHandle.
633022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval EFI_DEVICE_ERROR                      The controller could not be
634022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                                disconnected because of a device
635162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang                                                error.
636162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
637162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
638022c6d45ef78605c173023f53984e4dfaf7b11f4qhuangEFI_STATUS
63928a00297189c323096aae8e2975de94e8549613cyshangEFIAPI
64028a00297189c323096aae8e2975de94e8549613cyshangCoreDisconnectController (
64128a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_HANDLE  ControllerHandle,
64228a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_HANDLE  DriverImageHandle  OPTIONAL,
64328a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_HANDLE  ChildHandle        OPTIONAL
64428a00297189c323096aae8e2975de94e8549613cyshang  )
64528a00297189c323096aae8e2975de94e8549613cyshang{
64628a00297189c323096aae8e2975de94e8549613cyshang  EFI_STATUS                          Status;
64728a00297189c323096aae8e2975de94e8549613cyshang  IHANDLE                             *Handle;
64828a00297189c323096aae8e2975de94e8549613cyshang  EFI_HANDLE                          *DriverImageHandleBuffer;
64928a00297189c323096aae8e2975de94e8549613cyshang  EFI_HANDLE                          *ChildBuffer;
65028a00297189c323096aae8e2975de94e8549613cyshang  UINTN                               Index;
65128a00297189c323096aae8e2975de94e8549613cyshang  UINTN                               HandleIndex;
65228a00297189c323096aae8e2975de94e8549613cyshang  UINTN                               DriverImageHandleCount;
65328a00297189c323096aae8e2975de94e8549613cyshang  UINTN                               ChildrenToStop;
65428a00297189c323096aae8e2975de94e8549613cyshang  UINTN                               ChildBufferCount;
65528a00297189c323096aae8e2975de94e8549613cyshang  UINTN                               StopCount;
65628a00297189c323096aae8e2975de94e8549613cyshang  BOOLEAN                             Duplicate;
65728a00297189c323096aae8e2975de94e8549613cyshang  BOOLEAN                             ChildHandleValid;
65828a00297189c323096aae8e2975de94e8549613cyshang  BOOLEAN                             DriverImageHandleValid;
65928a00297189c323096aae8e2975de94e8549613cyshang  LIST_ENTRY                          *Link;
66028a00297189c323096aae8e2975de94e8549613cyshang  LIST_ENTRY                          *ProtLink;
66128a00297189c323096aae8e2975de94e8549613cyshang  OPEN_PROTOCOL_DATA                  *OpenData;
66228a00297189c323096aae8e2975de94e8549613cyshang  PROTOCOL_INTERFACE                  *Prot;
66328a00297189c323096aae8e2975de94e8549613cyshang  EFI_DRIVER_BINDING_PROTOCOL         *DriverBinding;
66428a00297189c323096aae8e2975de94e8549613cyshang
66528a00297189c323096aae8e2975de94e8549613cyshang  //
66628a00297189c323096aae8e2975de94e8549613cyshang  // Make sure ControllerHandle is valid
66728a00297189c323096aae8e2975de94e8549613cyshang  //
66828a00297189c323096aae8e2975de94e8549613cyshang  Status = CoreValidateHandle (ControllerHandle);
66928a00297189c323096aae8e2975de94e8549613cyshang  if (EFI_ERROR (Status)) {
67028a00297189c323096aae8e2975de94e8549613cyshang    return Status;
67128a00297189c323096aae8e2975de94e8549613cyshang  }
67228a00297189c323096aae8e2975de94e8549613cyshang
67328a00297189c323096aae8e2975de94e8549613cyshang  //
67428a00297189c323096aae8e2975de94e8549613cyshang  // Make sure ChildHandle is valid if it is not NULL
67528a00297189c323096aae8e2975de94e8549613cyshang  //
67628a00297189c323096aae8e2975de94e8549613cyshang  if (ChildHandle != NULL) {
67728a00297189c323096aae8e2975de94e8549613cyshang    Status = CoreValidateHandle (ChildHandle);
67828a00297189c323096aae8e2975de94e8549613cyshang    if (EFI_ERROR (Status)) {
67928a00297189c323096aae8e2975de94e8549613cyshang      return Status;
68028a00297189c323096aae8e2975de94e8549613cyshang    }
68128a00297189c323096aae8e2975de94e8549613cyshang  }
68228a00297189c323096aae8e2975de94e8549613cyshang
68328a00297189c323096aae8e2975de94e8549613cyshang  Handle = ControllerHandle;
68428a00297189c323096aae8e2975de94e8549613cyshang
68528a00297189c323096aae8e2975de94e8549613cyshang  //
68628a00297189c323096aae8e2975de94e8549613cyshang  // Get list of drivers that are currently managing ControllerHandle
68728a00297189c323096aae8e2975de94e8549613cyshang  //
68828a00297189c323096aae8e2975de94e8549613cyshang  DriverImageHandleBuffer = NULL;
689022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  DriverImageHandleCount  = 1;
690022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
69128a00297189c323096aae8e2975de94e8549613cyshang  if (DriverImageHandle == NULL) {
69228a00297189c323096aae8e2975de94e8549613cyshang    //
69328a00297189c323096aae8e2975de94e8549613cyshang    // Look at each protocol interface for a match
69428a00297189c323096aae8e2975de94e8549613cyshang    //
69528a00297189c323096aae8e2975de94e8549613cyshang    DriverImageHandleCount = 0;
69628a00297189c323096aae8e2975de94e8549613cyshang
69728a00297189c323096aae8e2975de94e8549613cyshang    CoreAcquireProtocolLock ();
69828a00297189c323096aae8e2975de94e8549613cyshang    for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
69928a00297189c323096aae8e2975de94e8549613cyshang      Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
700022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang      for (ProtLink = Prot->OpenList.ForwardLink;
701022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang           ProtLink != &Prot->OpenList;
70228a00297189c323096aae8e2975de94e8549613cyshang           ProtLink = ProtLink->ForwardLink) {
70328a00297189c323096aae8e2975de94e8549613cyshang        OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
70428a00297189c323096aae8e2975de94e8549613cyshang        if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
70528a00297189c323096aae8e2975de94e8549613cyshang          DriverImageHandleCount++;
70628a00297189c323096aae8e2975de94e8549613cyshang        }
70728a00297189c323096aae8e2975de94e8549613cyshang      }
70828a00297189c323096aae8e2975de94e8549613cyshang    }
70928a00297189c323096aae8e2975de94e8549613cyshang    CoreReleaseProtocolLock ();
710022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
71128a00297189c323096aae8e2975de94e8549613cyshang    //
71228a00297189c323096aae8e2975de94e8549613cyshang    // If there are no drivers managing this controller, then return EFI_SUCCESS
71328a00297189c323096aae8e2975de94e8549613cyshang    //
71428a00297189c323096aae8e2975de94e8549613cyshang    if (DriverImageHandleCount == 0) {
71528a00297189c323096aae8e2975de94e8549613cyshang      Status = EFI_SUCCESS;
71628a00297189c323096aae8e2975de94e8549613cyshang      goto Done;
71728a00297189c323096aae8e2975de94e8549613cyshang    }
71828a00297189c323096aae8e2975de94e8549613cyshang
7199c4ac31cca01b4a503c36616770ea3157bf3bb9eqhuang    DriverImageHandleBuffer = AllocatePool (sizeof (EFI_HANDLE) * DriverImageHandleCount);
72028a00297189c323096aae8e2975de94e8549613cyshang    if (DriverImageHandleBuffer == NULL) {
72128a00297189c323096aae8e2975de94e8549613cyshang      Status = EFI_OUT_OF_RESOURCES;
72228a00297189c323096aae8e2975de94e8549613cyshang      goto Done;
72328a00297189c323096aae8e2975de94e8549613cyshang    }
72428a00297189c323096aae8e2975de94e8549613cyshang
72528a00297189c323096aae8e2975de94e8549613cyshang    DriverImageHandleCount = 0;
72628a00297189c323096aae8e2975de94e8549613cyshang
72728a00297189c323096aae8e2975de94e8549613cyshang    CoreAcquireProtocolLock ();
72828a00297189c323096aae8e2975de94e8549613cyshang    for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
72928a00297189c323096aae8e2975de94e8549613cyshang      Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
730022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang      for (ProtLink = Prot->OpenList.ForwardLink;
731022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang           ProtLink != &Prot->OpenList;
73228a00297189c323096aae8e2975de94e8549613cyshang           ProtLink = ProtLink->ForwardLink) {
73328a00297189c323096aae8e2975de94e8549613cyshang        OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
73428a00297189c323096aae8e2975de94e8549613cyshang        if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
73528a00297189c323096aae8e2975de94e8549613cyshang          Duplicate = FALSE;
73628a00297189c323096aae8e2975de94e8549613cyshang          for (Index = 0; Index< DriverImageHandleCount; Index++) {
73728a00297189c323096aae8e2975de94e8549613cyshang            if (DriverImageHandleBuffer[Index] == OpenData->AgentHandle) {
73828a00297189c323096aae8e2975de94e8549613cyshang              Duplicate = TRUE;
73928a00297189c323096aae8e2975de94e8549613cyshang              break;
74028a00297189c323096aae8e2975de94e8549613cyshang            }
74128a00297189c323096aae8e2975de94e8549613cyshang          }
74228a00297189c323096aae8e2975de94e8549613cyshang          if (!Duplicate) {
74328a00297189c323096aae8e2975de94e8549613cyshang            DriverImageHandleBuffer[DriverImageHandleCount] = OpenData->AgentHandle;
74428a00297189c323096aae8e2975de94e8549613cyshang            DriverImageHandleCount++;
74528a00297189c323096aae8e2975de94e8549613cyshang          }
74628a00297189c323096aae8e2975de94e8549613cyshang        }
74728a00297189c323096aae8e2975de94e8549613cyshang      }
74828a00297189c323096aae8e2975de94e8549613cyshang    }
74928a00297189c323096aae8e2975de94e8549613cyshang    CoreReleaseProtocolLock ();
75028a00297189c323096aae8e2975de94e8549613cyshang  }
75128a00297189c323096aae8e2975de94e8549613cyshang
75228a00297189c323096aae8e2975de94e8549613cyshang  StopCount = 0;
75328a00297189c323096aae8e2975de94e8549613cyshang  for (HandleIndex = 0; HandleIndex < DriverImageHandleCount; HandleIndex++) {
75428a00297189c323096aae8e2975de94e8549613cyshang
75528a00297189c323096aae8e2975de94e8549613cyshang    if (DriverImageHandleBuffer != NULL) {
75628a00297189c323096aae8e2975de94e8549613cyshang      DriverImageHandle = DriverImageHandleBuffer[HandleIndex];
75728a00297189c323096aae8e2975de94e8549613cyshang    }
75828a00297189c323096aae8e2975de94e8549613cyshang
75928a00297189c323096aae8e2975de94e8549613cyshang    //
76028a00297189c323096aae8e2975de94e8549613cyshang    // Get the Driver Binding Protocol of the driver that is managing this controller
76128a00297189c323096aae8e2975de94e8549613cyshang    //
76228a00297189c323096aae8e2975de94e8549613cyshang    Status = CoreHandleProtocol (
763022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang               DriverImageHandle,
764022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang               &gEfiDriverBindingProtocolGuid,
76528a00297189c323096aae8e2975de94e8549613cyshang               (VOID **)&DriverBinding
76628a00297189c323096aae8e2975de94e8549613cyshang               );
76728a00297189c323096aae8e2975de94e8549613cyshang    if (EFI_ERROR (Status)) {
76828a00297189c323096aae8e2975de94e8549613cyshang      Status = EFI_INVALID_PARAMETER;
76928a00297189c323096aae8e2975de94e8549613cyshang      goto Done;
77028a00297189c323096aae8e2975de94e8549613cyshang    }
77128a00297189c323096aae8e2975de94e8549613cyshang
77228a00297189c323096aae8e2975de94e8549613cyshang    //
77328a00297189c323096aae8e2975de94e8549613cyshang    // Look at each protocol interface for a match
77428a00297189c323096aae8e2975de94e8549613cyshang    //
77528a00297189c323096aae8e2975de94e8549613cyshang    DriverImageHandleValid = FALSE;
77628a00297189c323096aae8e2975de94e8549613cyshang    ChildBufferCount = 0;
77728a00297189c323096aae8e2975de94e8549613cyshang
77828a00297189c323096aae8e2975de94e8549613cyshang    CoreAcquireProtocolLock ();
77928a00297189c323096aae8e2975de94e8549613cyshang    for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
78028a00297189c323096aae8e2975de94e8549613cyshang      Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
781022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang      for (ProtLink = Prot->OpenList.ForwardLink;
782022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang           ProtLink != &Prot->OpenList;
78328a00297189c323096aae8e2975de94e8549613cyshang           ProtLink = ProtLink->ForwardLink) {
78428a00297189c323096aae8e2975de94e8549613cyshang        OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
78528a00297189c323096aae8e2975de94e8549613cyshang        if (OpenData->AgentHandle == DriverImageHandle) {
78628a00297189c323096aae8e2975de94e8549613cyshang          if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
78728a00297189c323096aae8e2975de94e8549613cyshang            ChildBufferCount++;
788022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang          }
78928a00297189c323096aae8e2975de94e8549613cyshang          if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
79028a00297189c323096aae8e2975de94e8549613cyshang            DriverImageHandleValid = TRUE;
79128a00297189c323096aae8e2975de94e8549613cyshang          }
79228a00297189c323096aae8e2975de94e8549613cyshang        }
79328a00297189c323096aae8e2975de94e8549613cyshang      }
79428a00297189c323096aae8e2975de94e8549613cyshang    }
79528a00297189c323096aae8e2975de94e8549613cyshang    CoreReleaseProtocolLock ();
79628a00297189c323096aae8e2975de94e8549613cyshang
79728a00297189c323096aae8e2975de94e8549613cyshang    if (DriverImageHandleValid) {
79828a00297189c323096aae8e2975de94e8549613cyshang      ChildHandleValid = FALSE;
79928a00297189c323096aae8e2975de94e8549613cyshang      ChildBuffer = NULL;
80028a00297189c323096aae8e2975de94e8549613cyshang      if (ChildBufferCount != 0) {
8019c4ac31cca01b4a503c36616770ea3157bf3bb9eqhuang        ChildBuffer = AllocatePool (sizeof (EFI_HANDLE) * ChildBufferCount);
80228a00297189c323096aae8e2975de94e8549613cyshang        if (ChildBuffer == NULL) {
80328a00297189c323096aae8e2975de94e8549613cyshang          Status = EFI_OUT_OF_RESOURCES;
80428a00297189c323096aae8e2975de94e8549613cyshang          goto Done;
80528a00297189c323096aae8e2975de94e8549613cyshang        }
80628a00297189c323096aae8e2975de94e8549613cyshang
80728a00297189c323096aae8e2975de94e8549613cyshang        ChildBufferCount = 0;
80828a00297189c323096aae8e2975de94e8549613cyshang
80928a00297189c323096aae8e2975de94e8549613cyshang        CoreAcquireProtocolLock ();
81028a00297189c323096aae8e2975de94e8549613cyshang        for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
81128a00297189c323096aae8e2975de94e8549613cyshang          Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
812022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang          for (ProtLink = Prot->OpenList.ForwardLink;
813022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang               ProtLink != &Prot->OpenList;
81428a00297189c323096aae8e2975de94e8549613cyshang               ProtLink = ProtLink->ForwardLink) {
81528a00297189c323096aae8e2975de94e8549613cyshang            OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
81628a00297189c323096aae8e2975de94e8549613cyshang            if ((OpenData->AgentHandle == DriverImageHandle) &&
81728a00297189c323096aae8e2975de94e8549613cyshang                ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0)) {
81828a00297189c323096aae8e2975de94e8549613cyshang              Duplicate = FALSE;
81928a00297189c323096aae8e2975de94e8549613cyshang              for (Index = 0; Index < ChildBufferCount; Index++) {
82028a00297189c323096aae8e2975de94e8549613cyshang                if (ChildBuffer[Index] == OpenData->ControllerHandle) {
82128a00297189c323096aae8e2975de94e8549613cyshang                  Duplicate = TRUE;
82228a00297189c323096aae8e2975de94e8549613cyshang                  break;
82328a00297189c323096aae8e2975de94e8549613cyshang                }
82428a00297189c323096aae8e2975de94e8549613cyshang              }
82528a00297189c323096aae8e2975de94e8549613cyshang              if (!Duplicate) {
82628a00297189c323096aae8e2975de94e8549613cyshang                ChildBuffer[ChildBufferCount] = OpenData->ControllerHandle;
82728a00297189c323096aae8e2975de94e8549613cyshang                if (ChildHandle == ChildBuffer[ChildBufferCount]) {
82828a00297189c323096aae8e2975de94e8549613cyshang                  ChildHandleValid = TRUE;
82928a00297189c323096aae8e2975de94e8549613cyshang                }
83028a00297189c323096aae8e2975de94e8549613cyshang                ChildBufferCount++;
83128a00297189c323096aae8e2975de94e8549613cyshang              }
83228a00297189c323096aae8e2975de94e8549613cyshang            }
83328a00297189c323096aae8e2975de94e8549613cyshang          }
83428a00297189c323096aae8e2975de94e8549613cyshang        }
83528a00297189c323096aae8e2975de94e8549613cyshang        CoreReleaseProtocolLock ();
83628a00297189c323096aae8e2975de94e8549613cyshang      }
83728a00297189c323096aae8e2975de94e8549613cyshang
83828a00297189c323096aae8e2975de94e8549613cyshang      if (ChildHandle == NULL || ChildHandleValid) {
83928a00297189c323096aae8e2975de94e8549613cyshang        ChildrenToStop = 0;
84028a00297189c323096aae8e2975de94e8549613cyshang        Status = EFI_SUCCESS;
84128a00297189c323096aae8e2975de94e8549613cyshang        if (ChildBufferCount > 0) {
84228a00297189c323096aae8e2975de94e8549613cyshang          if (ChildHandle != NULL) {
84328a00297189c323096aae8e2975de94e8549613cyshang            ChildrenToStop = 1;
84428a00297189c323096aae8e2975de94e8549613cyshang            Status = DriverBinding->Stop (DriverBinding, ControllerHandle, ChildrenToStop, &ChildHandle);
84528a00297189c323096aae8e2975de94e8549613cyshang          } else {
84628a00297189c323096aae8e2975de94e8549613cyshang            ChildrenToStop = ChildBufferCount;
84728a00297189c323096aae8e2975de94e8549613cyshang            Status = DriverBinding->Stop (DriverBinding, ControllerHandle, ChildrenToStop, ChildBuffer);
84828a00297189c323096aae8e2975de94e8549613cyshang          }
84928a00297189c323096aae8e2975de94e8549613cyshang        }
85028a00297189c323096aae8e2975de94e8549613cyshang        if (!EFI_ERROR (Status) && ((ChildHandle == NULL) || (ChildBufferCount == ChildrenToStop))) {
85128a00297189c323096aae8e2975de94e8549613cyshang          Status = DriverBinding->Stop (DriverBinding, ControllerHandle, 0, NULL);
85228a00297189c323096aae8e2975de94e8549613cyshang        }
85328a00297189c323096aae8e2975de94e8549613cyshang        if (!EFI_ERROR (Status)) {
85428a00297189c323096aae8e2975de94e8549613cyshang          StopCount++;
85528a00297189c323096aae8e2975de94e8549613cyshang        }
85628a00297189c323096aae8e2975de94e8549613cyshang      }
85728a00297189c323096aae8e2975de94e8549613cyshang
85828a00297189c323096aae8e2975de94e8549613cyshang      if (ChildBuffer != NULL) {
85928a00297189c323096aae8e2975de94e8549613cyshang        CoreFreePool (ChildBuffer);
86028a00297189c323096aae8e2975de94e8549613cyshang      }
86128a00297189c323096aae8e2975de94e8549613cyshang    }
86228a00297189c323096aae8e2975de94e8549613cyshang  }
86328a00297189c323096aae8e2975de94e8549613cyshang
86428a00297189c323096aae8e2975de94e8549613cyshang  if (StopCount > 0) {
86528a00297189c323096aae8e2975de94e8549613cyshang    Status = EFI_SUCCESS;
86628a00297189c323096aae8e2975de94e8549613cyshang  } else {
86728a00297189c323096aae8e2975de94e8549613cyshang    Status = EFI_NOT_FOUND;
86828a00297189c323096aae8e2975de94e8549613cyshang  }
869022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
870022c6d45ef78605c173023f53984e4dfaf7b11f4qhuangDone:
87128a00297189c323096aae8e2975de94e8549613cyshang
87228a00297189c323096aae8e2975de94e8549613cyshang  if (DriverImageHandleBuffer != NULL) {
87328a00297189c323096aae8e2975de94e8549613cyshang    CoreFreePool (DriverImageHandleBuffer);
87428a00297189c323096aae8e2975de94e8549613cyshang  }
87528a00297189c323096aae8e2975de94e8549613cyshang
87628a00297189c323096aae8e2975de94e8549613cyshang  return Status;
87728a00297189c323096aae8e2975de94e8549613cyshang}
878