drvsup.c 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167
  1. /*++
  2. Copyright (c) 2014 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. drvsup.c
  5. Abstract:
  6. This module implements UEFI core driver support routines.
  7. Author:
  8. Evan Green 5-Mar-2014
  9. Environment:
  10. Firmware
  11. --*/
  12. //
  13. // ------------------------------------------------------------------- Includes
  14. //
  15. #include "ueficore.h"
  16. #include <minoca/uefi/protocol/drvbind.h>
  17. #include <minoca/uefi/protocol/drvplato.h>
  18. #include <minoca/uefi/protocol/drvfamov.h>
  19. #include <minoca/uefi/protocol/drvbusov.h>
  20. //
  21. // ---------------------------------------------------------------- Definitions
  22. //
  23. //
  24. // ------------------------------------------------------ Data Type Definitions
  25. //
  26. //
  27. // ----------------------------------------------- Internal Function Prototypes
  28. //
  29. EFI_STATUS
  30. EfipCoreConnectSingleController (
  31. EFI_HANDLE ControllerHandle,
  32. EFI_HANDLE *ContextDriverImageHandles,
  33. EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
  34. );
  35. VOID
  36. EfipCoreAddSortedDriverBindingProtocol (
  37. EFI_HANDLE DriverBindingHandle,
  38. UINTN *NumberOfSortedDriverBindingProtocols,
  39. EFI_DRIVER_BINDING_PROTOCOL **SortedDriverBindingProtocols,
  40. UINTN DriverBindingHandleCount,
  41. EFI_HANDLE *DriverBindingHandleBuffer,
  42. BOOLEAN IsImageHandle
  43. );
  44. //
  45. // -------------------------------------------------------------------- Globals
  46. //
  47. EFI_GUID EfiDriverBindingProtocolGuid = EFI_DRIVER_BINDING_PROTOCOL_GUID;
  48. EFI_GUID EfiPlatformDriverOverrideProtocolGuid =
  49. EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL_GUID;
  50. EFI_GUID EfiDriverFamilyOverrideProtocolGuid =
  51. EFI_DRIVER_FAMILY_OVERRIDE_PROTOCOL_GUID;
  52. EFI_GUID EfiBusSpecificDriverOverrideProtocolGuid =
  53. EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL_GUID;
  54. //
  55. // ------------------------------------------------------------------ Functions
  56. //
  57. EFIAPI
  58. EFI_STATUS
  59. EfiCoreConnectController (
  60. EFI_HANDLE ControllerHandle,
  61. EFI_HANDLE *DriverImageHandle,
  62. EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath,
  63. BOOLEAN Recursive
  64. )
  65. /*++
  66. Routine Description:
  67. This routine connects one or more drivers to a controller.
  68. Arguments:
  69. ControllerHandle - Supplies the handle of the controller which driver(s)
  70. are connecting to.
  71. DriverImageHandle - Supplies a pointer to an ordered list of handles that
  72. support the EFI_DRIVER_BINDING_PROTOCOL.
  73. RemainingDevicePath - Supplies an optional pointer to the device path that
  74. specifies a child of the controller specified by the controller handle.
  75. Recursive - Supplies a boolean indicating if this routine should be called
  76. recursively until the entire tree of controllers below the specified
  77. controller has been connected. If FALSE, then the tree of controllers
  78. is only expanded one level.
  79. Return Value:
  80. EFI_SUCCESS on success.
  81. EFI_INVALID_PARAMETER if the controller handle is NULL.
  82. EFI_NOT_FOUND if either there are no EFI_DRIVER_BINDING_PROTOCOL instances
  83. present in the system, or no drivers were connected to the controller
  84. handle.
  85. EFI_SECURITY_VIOLATION if the user has no permission to start UEFI device
  86. drivers on the device associated with the controller handle or specified
  87. by the remaining device path.
  88. --*/
  89. {
  90. EFI_DEVICE_PATH_PROTOCOL *AlignedRemainingDevicePath;
  91. EFI_HANDLE *ChildHandleBuffer;
  92. UINTN ChildHandleCount;
  93. PLIST_ENTRY CurrentEntry;
  94. PEFI_HANDLE_DATA Handle;
  95. UINTN Index;
  96. PEFI_OPEN_PROTOCOL_DATA OpenData;
  97. PLIST_ENTRY OpenEntry;
  98. PEFI_PROTOCOL_INTERFACE ProtocolInterface;
  99. EFI_STATUS ReturnStatus;
  100. EFI_STATUS Status;
  101. Status = EfipCoreValidateHandle(ControllerHandle);
  102. if (EFI_ERROR(Status)) {
  103. return Status;
  104. }
  105. Handle = ControllerHandle;
  106. //
  107. // Make a copy of the device path to ensure it is aligned.
  108. //
  109. AlignedRemainingDevicePath = NULL;
  110. if (RemainingDevicePath != NULL) {
  111. AlignedRemainingDevicePath = EfiCoreDuplicateDevicePath(
  112. RemainingDevicePath);
  113. if (AlignedRemainingDevicePath == NULL) {
  114. return EFI_OUT_OF_RESOURCES;
  115. }
  116. }
  117. //
  118. // Connect all drivers to the controller handle. If the connection routine
  119. // returns EFI_NOT_READY, then the number of driver binding protocols in
  120. // the handle database has increased during the call so the connect
  121. // operation must be restarted.
  122. //
  123. do {
  124. ReturnStatus = EfipCoreConnectSingleController(
  125. ControllerHandle,
  126. DriverImageHandle,
  127. AlignedRemainingDevicePath);
  128. } while (ReturnStatus == EFI_NOT_READY);
  129. if (AlignedRemainingDevicePath != NULL) {
  130. EfiCoreFreePool(AlignedRemainingDevicePath);
  131. }
  132. //
  133. // If recursive, then connect all drivers to all of the controller handle's
  134. // children.
  135. //
  136. if (Recursive != FALSE) {
  137. EfiCoreAcquireLock(&EfiProtocolDatabaseLock);
  138. //
  139. // Make sure the driver binding handle is valid.
  140. //
  141. Status = EfipCoreValidateHandle(ControllerHandle);
  142. if (EFI_ERROR(Status)) {
  143. EfiCoreReleaseLock(&EfiProtocolDatabaseLock);
  144. return Status;
  145. }
  146. //
  147. // Count the controller handle's children.
  148. //
  149. ChildHandleCount = 0;
  150. CurrentEntry = Handle->ProtocolList.Next;
  151. while (CurrentEntry != &(Handle->ProtocolList)) {
  152. ProtocolInterface = LIST_VALUE(CurrentEntry,
  153. EFI_PROTOCOL_INTERFACE,
  154. ListEntry);
  155. ASSERT(ProtocolInterface->Magic == EFI_PROTOCOL_INTERFACE_MAGIC);
  156. CurrentEntry = CurrentEntry->Next;
  157. OpenEntry = ProtocolInterface->OpenList.Next;
  158. while (OpenEntry != &(ProtocolInterface->OpenList)) {
  159. OpenData = LIST_VALUE(OpenEntry,
  160. EFI_OPEN_PROTOCOL_DATA,
  161. ListEntry);
  162. ASSERT(OpenData->Magic == EFI_OPEN_PROTOCOL_MAGIC);
  163. OpenEntry = OpenEntry->Next;
  164. if ((OpenData->Attributes &
  165. EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
  166. ChildHandleCount += 1;
  167. }
  168. }
  169. }
  170. //
  171. // Allocate an array for the controller handle's children.
  172. //
  173. ChildHandleBuffer = EfiCoreAllocateBootPool(
  174. ChildHandleCount * sizeof(EFI_HANDLE));
  175. if (ChildHandleBuffer == NULL) {
  176. EfiCoreReleaseLock(&EfiProtocolDatabaseLock);
  177. return EFI_OUT_OF_RESOURCES;
  178. }
  179. //
  180. // Fill in the handle buffer with the controller handle's children.
  181. //
  182. ChildHandleCount = 0;
  183. CurrentEntry = Handle->ProtocolList.Next;
  184. while (CurrentEntry != &(Handle->ProtocolList)) {
  185. ProtocolInterface = LIST_VALUE(CurrentEntry,
  186. EFI_PROTOCOL_INTERFACE,
  187. ListEntry);
  188. ASSERT(ProtocolInterface->Magic == EFI_PROTOCOL_INTERFACE_MAGIC);
  189. CurrentEntry = CurrentEntry->Next;
  190. OpenEntry = ProtocolInterface->OpenList.Next;
  191. while (OpenEntry != &(ProtocolInterface->OpenList)) {
  192. OpenData = LIST_VALUE(OpenEntry,
  193. EFI_OPEN_PROTOCOL_DATA,
  194. ListEntry);
  195. ASSERT(OpenData->Magic == EFI_OPEN_PROTOCOL_MAGIC);
  196. OpenEntry = OpenEntry->Next;
  197. if ((OpenData->Attributes &
  198. EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
  199. ChildHandleBuffer[ChildHandleCount] =
  200. OpenData->ControllerHandle;
  201. ChildHandleCount += 1;
  202. }
  203. }
  204. }
  205. EfiCoreReleaseLock(&EfiProtocolDatabaseLock);
  206. //
  207. // Recursively connect each child.
  208. //
  209. for (Index = 0; Index < ChildHandleCount; Index += 1) {
  210. EfiCoreConnectController(ChildHandleBuffer[Index],
  211. NULL,
  212. NULL,
  213. TRUE);
  214. }
  215. EfiCoreFreePool(ChildHandleBuffer);
  216. }
  217. return ReturnStatus;
  218. }
  219. EFIAPI
  220. EFI_STATUS
  221. EfiCoreDisconnectController (
  222. EFI_HANDLE ControllerHandle,
  223. EFI_HANDLE DriverImageHandle,
  224. EFI_HANDLE ChildHandle
  225. )
  226. /*++
  227. Routine Description:
  228. This routine disconnects one or more drivers to a controller.
  229. Arguments:
  230. ControllerHandle - Supplies the handle of the controller which driver(s)
  231. are disconnecting from.
  232. DriverImageHandle - Supplies an optional pointer to the driver to
  233. disconnect from the controller. If NULL, all drivers are disconnected.
  234. ChildHandle - Supplies an optional pointer to the handle of the child to
  235. destroy.
  236. Return Value:
  237. EFI_SUCCESS if one or more drivers were disconnected, no drivers are
  238. managing the handle, or a driver image handle was supplied and it is not
  239. controlling the given handle.
  240. EFI_INVALID_PARAMETER if the controller handle or driver handle is not a
  241. valid EFI handle, or the driver image handle doesn't support the
  242. EFI_DRIVER_BINDING_PROTOCOL.
  243. EFI_OUT_OF_RESOURCES if there are not enough resources are available to
  244. disconnect the controller(s).
  245. EFI_DEVICE_ERROR if the controller could not be disconnected because of a
  246. device error.
  247. --*/
  248. {
  249. EFI_HANDLE *ChildBuffer;
  250. UINTN ChildBufferCount;
  251. BOOLEAN ChildHandleValid;
  252. UINTN ChildrenToStop;
  253. PLIST_ENTRY CurrentEntry;
  254. EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
  255. EFI_HANDLE *DriverImageHandleBuffer;
  256. UINTN DriverImageHandleCount;
  257. BOOLEAN DriverImageHandleValid;
  258. BOOLEAN Duplicate;
  259. PEFI_HANDLE_DATA Handle;
  260. UINTN HandleIndex;
  261. UINTN Index;
  262. PEFI_OPEN_PROTOCOL_DATA OpenData;
  263. PLIST_ENTRY OpenEntry;
  264. PEFI_PROTOCOL_INTERFACE ProtocolInterface;
  265. EFI_STATUS Status;
  266. UINTN StopCount;
  267. Status = EfipCoreValidateHandle(ControllerHandle);
  268. if (EFI_ERROR(Status)) {
  269. return Status;
  270. }
  271. //
  272. // Make sure the child handle is valid if supplied.
  273. //
  274. if (ChildHandle != NULL) {
  275. Status = EfipCoreValidateHandle(ChildHandle);
  276. if (EFI_ERROR(Status)) {
  277. return Status;
  278. }
  279. }
  280. Handle = ControllerHandle;
  281. //
  282. // Get a list of drivers managing the controller handle.
  283. //
  284. DriverImageHandleBuffer = NULL;
  285. DriverImageHandleCount = 0;
  286. if (DriverImageHandle == NULL) {
  287. DriverImageHandleCount = 0;
  288. EfiCoreAcquireLock(&EfiProtocolDatabaseLock);
  289. CurrentEntry = Handle->ProtocolList.Next;
  290. while (CurrentEntry != &(Handle->ProtocolList)) {
  291. ProtocolInterface = LIST_VALUE(CurrentEntry,
  292. EFI_PROTOCOL_INTERFACE,
  293. ListEntry);
  294. ASSERT(ProtocolInterface->Magic == EFI_PROTOCOL_INTERFACE_MAGIC);
  295. OpenEntry = ProtocolInterface->OpenList.Next;
  296. while (OpenEntry != &(ProtocolInterface->OpenList)) {
  297. OpenData = LIST_VALUE(OpenEntry,
  298. EFI_OPEN_PROTOCOL_DATA,
  299. ListEntry);
  300. ASSERT(OpenData->Magic == EFI_OPEN_PROTOCOL_MAGIC);
  301. OpenEntry = OpenEntry->Next;
  302. if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
  303. DriverImageHandleCount += 1;
  304. }
  305. }
  306. CurrentEntry = CurrentEntry->Next;
  307. }
  308. EfiCoreReleaseLock(&EfiProtocolDatabaseLock);
  309. //
  310. // If there are no drivers managing this controller, then there's no
  311. // work to do.
  312. //
  313. if (DriverImageHandleCount == 0) {
  314. Status = EFI_SUCCESS;
  315. goto CoreDisconnectControllerEnd;
  316. }
  317. DriverImageHandleBuffer = EfiCoreAllocateBootPool(
  318. DriverImageHandleCount * sizeof(EFI_HANDLE));
  319. if (DriverImageHandleBuffer == NULL) {
  320. Status = EFI_OUT_OF_RESOURCES;
  321. goto CoreDisconnectControllerEnd;
  322. }
  323. DriverImageHandleCount = 0;
  324. EfiCoreAcquireLock(&EfiProtocolDatabaseLock);
  325. CurrentEntry = Handle->ProtocolList.Next;
  326. while (CurrentEntry != &(Handle->ProtocolList)) {
  327. ProtocolInterface = LIST_VALUE(CurrentEntry,
  328. EFI_PROTOCOL_INTERFACE,
  329. ListEntry);
  330. ASSERT(ProtocolInterface->Magic == EFI_PROTOCOL_INTERFACE_MAGIC);
  331. OpenEntry = ProtocolInterface->OpenList.Next;
  332. while (OpenEntry != &(ProtocolInterface->OpenList)) {
  333. OpenData = LIST_VALUE(OpenEntry,
  334. EFI_OPEN_PROTOCOL_DATA,
  335. ListEntry);
  336. OpenEntry = OpenEntry->Next;
  337. if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
  338. Duplicate = FALSE;
  339. for (Index = 0;
  340. Index < DriverImageHandleCount;
  341. Index += 1) {
  342. if (DriverImageHandleBuffer[Index] ==
  343. OpenData->AgentHandle) {
  344. Duplicate = TRUE;
  345. break;
  346. }
  347. }
  348. if (Duplicate == FALSE) {
  349. DriverImageHandleBuffer[DriverImageHandleCount] =
  350. OpenData->AgentHandle;
  351. DriverImageHandleCount += 1;
  352. }
  353. }
  354. }
  355. CurrentEntry = CurrentEntry->Next;
  356. }
  357. EfiCoreReleaseLock(&EfiProtocolDatabaseLock);
  358. }
  359. //
  360. // Loop through each driver that has this controller open.
  361. //
  362. StopCount = 0;
  363. for (HandleIndex = 0;
  364. HandleIndex < DriverImageHandleCount;
  365. HandleIndex += 1) {
  366. if (DriverImageHandleBuffer != NULL) {
  367. DriverImageHandle = DriverImageHandleBuffer[HandleIndex];
  368. }
  369. //
  370. // Get the driver binding protocol of the driver managing this
  371. // controller.
  372. //
  373. Status = EfiCoreHandleProtocol(DriverImageHandle,
  374. &EfiDriverBindingProtocolGuid,
  375. (VOID **)&DriverBinding);
  376. if ((EFI_ERROR(Status)) || (DriverBinding == NULL)) {
  377. Status = EFI_INVALID_PARAMETER;
  378. goto CoreDisconnectControllerEnd;
  379. }
  380. //
  381. // Look at each protocol interface for a match.
  382. //
  383. DriverImageHandleValid = FALSE;
  384. ChildBufferCount = 0;
  385. EfiCoreAcquireLock(&EfiProtocolDatabaseLock);
  386. CurrentEntry = Handle->ProtocolList.Next;
  387. while (CurrentEntry != &(Handle->ProtocolList)) {
  388. ProtocolInterface = LIST_VALUE(CurrentEntry,
  389. EFI_PROTOCOL_INTERFACE,
  390. ListEntry);
  391. ASSERT(ProtocolInterface->Magic == EFI_PROTOCOL_INTERFACE_MAGIC);
  392. OpenEntry = ProtocolInterface->OpenList.Next;
  393. while (OpenEntry != &(ProtocolInterface->OpenList)) {
  394. OpenData = LIST_VALUE(OpenEntry,
  395. EFI_OPEN_PROTOCOL_DATA,
  396. ListEntry);
  397. OpenEntry = OpenEntry->Next;
  398. ASSERT(OpenData->Magic == EFI_OPEN_PROTOCOL_MAGIC);
  399. if (OpenData->AgentHandle == DriverImageHandle) {
  400. if ((OpenData->Attributes &
  401. EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
  402. ChildBufferCount += 1;
  403. }
  404. if ((OpenData->Attributes &
  405. EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
  406. //
  407. // The driver really does have the controller open.
  408. //
  409. DriverImageHandleValid = TRUE;
  410. }
  411. }
  412. }
  413. CurrentEntry = CurrentEntry->Next;
  414. }
  415. EfiCoreReleaseLock(&EfiProtocolDatabaseLock);
  416. //
  417. // If the driver really has the controller open, stop it.
  418. //
  419. if (DriverImageHandleValid != FALSE) {
  420. ChildHandleValid = FALSE;
  421. ChildBuffer = NULL;
  422. if (ChildBufferCount != 0) {
  423. ChildBuffer = EfiCoreAllocateBootPool(
  424. ChildBufferCount * sizeof(EFI_HANDLE));
  425. if (ChildBuffer == NULL) {
  426. Status = EFI_OUT_OF_RESOURCES;
  427. goto CoreDisconnectControllerEnd;
  428. }
  429. ChildBufferCount = 0;
  430. EfiCoreAcquireLock(&EfiProtocolDatabaseLock);
  431. CurrentEntry = Handle->ProtocolList.Next;
  432. while (CurrentEntry != &(Handle->ProtocolList)) {
  433. ProtocolInterface = LIST_VALUE(CurrentEntry,
  434. EFI_PROTOCOL_INTERFACE,
  435. ListEntry);
  436. ASSERT(ProtocolInterface->Magic ==
  437. EFI_PROTOCOL_INTERFACE_MAGIC);
  438. OpenEntry = ProtocolInterface->OpenList.Next;
  439. while (OpenEntry != &(ProtocolInterface->OpenList)) {
  440. OpenData = LIST_VALUE(OpenEntry,
  441. EFI_OPEN_PROTOCOL_DATA,
  442. ListEntry);
  443. OpenEntry = OpenEntry->Next;
  444. if ((OpenData->AgentHandle == DriverImageHandle) &&
  445. ((OpenData->Attributes &
  446. EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0)) {
  447. Duplicate = FALSE;
  448. for (Index = 0;
  449. Index < ChildBufferCount;
  450. Index += 1) {
  451. if (ChildBuffer[Index] ==
  452. OpenData->ControllerHandle) {
  453. Duplicate = TRUE;
  454. break;
  455. }
  456. }
  457. if (Duplicate == FALSE) {
  458. ChildBuffer[ChildBufferCount] =
  459. OpenData->ControllerHandle;
  460. if (ChildHandle ==
  461. ChildBuffer[ChildBufferCount]) {
  462. ChildHandleValid = TRUE;
  463. }
  464. ChildBufferCount += 1;
  465. }
  466. }
  467. }
  468. CurrentEntry = CurrentEntry->Next;
  469. }
  470. EfiCoreReleaseLock(&EfiProtocolDatabaseLock);
  471. }
  472. if ((ChildHandle == NULL) || (ChildHandleValid != FALSE)) {
  473. ChildrenToStop = 0;
  474. Status = EFI_SUCCESS;
  475. if (ChildBufferCount > 0) {
  476. if (ChildHandle != NULL) {
  477. ChildrenToStop = 1;
  478. Status = DriverBinding->Stop(DriverBinding,
  479. ControllerHandle,
  480. ChildrenToStop,
  481. &ChildHandle);
  482. } else {
  483. ChildrenToStop = ChildBufferCount;
  484. Status = DriverBinding->Stop(DriverBinding,
  485. ControllerHandle,
  486. ChildrenToStop,
  487. ChildBuffer);
  488. }
  489. }
  490. if ((!EFI_ERROR(Status)) &&
  491. ((ChildHandle == NULL) ||
  492. (ChildBufferCount == ChildrenToStop))) {
  493. Status = DriverBinding->Stop(DriverBinding,
  494. ControllerHandle,
  495. 0,
  496. NULL);
  497. }
  498. if (!EFI_ERROR(Status)) {
  499. StopCount += 1;
  500. }
  501. }
  502. if (ChildBuffer != NULL) {
  503. EfiCoreFreePool(ChildBuffer);
  504. }
  505. }
  506. }
  507. if (StopCount > 0) {
  508. Status = EFI_SUCCESS;
  509. } else {
  510. Status = EFI_NOT_FOUND;
  511. }
  512. CoreDisconnectControllerEnd:
  513. if (DriverImageHandleBuffer != NULL) {
  514. EfiCoreFreePool(DriverImageHandleBuffer);
  515. }
  516. return Status;
  517. }
  518. //
  519. // --------------------------------------------------------- Internal Functions
  520. //
  521. EFI_STATUS
  522. EfipCoreConnectSingleController (
  523. EFI_HANDLE ControllerHandle,
  524. EFI_HANDLE *ContextDriverImageHandles,
  525. EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
  526. )
  527. /*++
  528. Routine Description:
  529. This routine connects one controller to a driver.
  530. Arguments:
  531. ControllerHandle - Supplies the handle of the controller to connect.
  532. ContextDriverImageHandles - Supplies a pointer to an ordered list of driver
  533. image handles.
  534. RemainingDevicePath - Supplies a pointer to the device path that specifies
  535. a child of the controller.
  536. Return Value:
  537. EFI status code.
  538. --*/
  539. {
  540. EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *BusSpecificDriverOverride;
  541. EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
  542. EFI_HANDLE *DriverBindingHandleBuffer;
  543. UINTN DriverBindingHandleCount;
  544. EFI_DRIVER_FAMILY_OVERRIDE_PROTOCOL *DriverFamilyOverride;
  545. UINT32 DriverFamilyOverrideVersion;
  546. BOOLEAN DriverFound;
  547. EFI_HANDLE DriverImageHandle;
  548. UINTN HighestIndex;
  549. UINT32 HighestVersion;
  550. UINTN Index;
  551. EFI_HANDLE *NewDriverBindingHandleBuffer;
  552. UINTN NewDriverBindingHandleCount;
  553. UINTN NumberOfSortedDriverBindingProtocols;
  554. BOOLEAN OneStarted;
  555. EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *PlatformDriverOverride;
  556. EFI_DRIVER_BINDING_PROTOCOL **SortedDriverBindingProtocols;
  557. UINTN SortIndex;
  558. EFI_STATUS Status;
  559. DriverBindingHandleCount = 0;
  560. DriverBindingHandleBuffer = NULL;
  561. NumberOfSortedDriverBindingProtocols = 0;
  562. SortedDriverBindingProtocols = NULL;
  563. //
  564. // Get a list of all driver binding protocol instances.
  565. //
  566. Status = EfiCoreLocateHandleBuffer(ByProtocol,
  567. &EfiDriverBindingProtocolGuid,
  568. NULL,
  569. &DriverBindingHandleCount,
  570. &DriverBindingHandleBuffer);
  571. if ((EFI_ERROR(Status)) || (DriverBindingHandleCount == 0)) {
  572. return EFI_NOT_FOUND;
  573. }
  574. //
  575. // Allocate a duplicate array for the sorted driver binding protocol
  576. // instances.
  577. //
  578. SortedDriverBindingProtocols = EfiCoreAllocateBootPool(
  579. DriverBindingHandleCount * sizeof(EFI_HANDLE));
  580. if (SortedDriverBindingProtocols == NULL) {
  581. EfiCoreFreePool(DriverBindingHandleBuffer);
  582. return EFI_OUT_OF_RESOURCES;
  583. }
  584. //
  585. // Add Driver Binding Protocols from Context Driver Image Handles first.
  586. //
  587. if (ContextDriverImageHandles != NULL) {
  588. Index = 0;
  589. while (ContextDriverImageHandles[Index] != NULL) {
  590. EfipCoreAddSortedDriverBindingProtocol(
  591. ContextDriverImageHandles[Index],
  592. &NumberOfSortedDriverBindingProtocols,
  593. SortedDriverBindingProtocols,
  594. DriverBindingHandleCount,
  595. DriverBindingHandleBuffer,
  596. FALSE);
  597. Index += 1;
  598. }
  599. }
  600. //
  601. // Add the Platform Driver Override Protocol drivers for the controller
  602. // handle next.
  603. //
  604. Status = EfiCoreLocateProtocol(&EfiPlatformDriverOverrideProtocolGuid,
  605. NULL,
  606. (VOID **)&PlatformDriverOverride);
  607. if ((!EFI_ERROR(Status)) && (PlatformDriverOverride != NULL)) {
  608. DriverImageHandle = NULL;
  609. do {
  610. Status = PlatformDriverOverride->GetDriver(PlatformDriverOverride,
  611. ControllerHandle,
  612. &DriverImageHandle);
  613. if (!EFI_ERROR(Status)) {
  614. EfipCoreAddSortedDriverBindingProtocol(
  615. DriverImageHandle,
  616. &NumberOfSortedDriverBindingProtocols,
  617. SortedDriverBindingProtocols,
  618. DriverBindingHandleCount,
  619. DriverBindingHandleBuffer,
  620. TRUE);
  621. }
  622. } while (!EFI_ERROR(Status));
  623. }
  624. //
  625. // Add the Driver Family Override Protocol drivers fot he controller handle.
  626. //
  627. while (TRUE) {
  628. HighestIndex = DriverBindingHandleCount;
  629. HighestVersion = 0;
  630. for (Index = 0; Index < DriverBindingHandleCount; Index += 1) {
  631. Status = EfiCoreHandleProtocol(DriverBindingHandleBuffer[Index],
  632. &EfiDriverFamilyOverrideProtocolGuid,
  633. (VOID **)&DriverFamilyOverride);
  634. if ((!EFI_ERROR(Status)) && (DriverFamilyOverride != NULL)) {
  635. DriverFamilyOverrideVersion = DriverFamilyOverride->GetVersion(
  636. DriverFamilyOverride);
  637. if ((HighestIndex == DriverBindingHandleCount) ||
  638. (DriverFamilyOverrideVersion > HighestVersion)) {
  639. HighestVersion = DriverFamilyOverrideVersion;
  640. HighestIndex = Index;
  641. }
  642. }
  643. }
  644. if (HighestIndex == DriverBindingHandleCount) {
  645. break;
  646. }
  647. EfipCoreAddSortedDriverBindingProtocol(
  648. DriverBindingHandleBuffer[HighestIndex],
  649. &NumberOfSortedDriverBindingProtocols,
  650. SortedDriverBindingProtocols,
  651. DriverBindingHandleCount,
  652. DriverBindingHandleBuffer,
  653. FALSE);
  654. }
  655. //
  656. // Get the Bus Specific Driver Override Protocol instance on the controller
  657. // handle.
  658. //
  659. Status = EfiCoreHandleProtocol(ControllerHandle,
  660. &EfiBusSpecificDriverOverrideProtocolGuid,
  661. (VOID **)&BusSpecificDriverOverride);
  662. if ((!EFI_ERROR(Status)) && (BusSpecificDriverOverride != NULL)) {
  663. DriverImageHandle = NULL;
  664. do {
  665. Status = BusSpecificDriverOverride->GetDriver(
  666. BusSpecificDriverOverride,
  667. &DriverImageHandle);
  668. if (!EFI_ERROR(Status)) {
  669. EfipCoreAddSortedDriverBindingProtocol(
  670. DriverImageHandle,
  671. &NumberOfSortedDriverBindingProtocols,
  672. SortedDriverBindingProtocols,
  673. DriverBindingHandleCount,
  674. DriverBindingHandleBuffer,
  675. TRUE);
  676. }
  677. } while (!EFI_ERROR(Status));
  678. }
  679. //
  680. // Finally, add all remaining Driver Binding Protocols.
  681. //
  682. SortIndex = NumberOfSortedDriverBindingProtocols;
  683. for (Index = 0; Index < DriverBindingHandleCount; Index += 1) {
  684. EfipCoreAddSortedDriverBindingProtocol(
  685. DriverBindingHandleBuffer[Index],
  686. &NumberOfSortedDriverBindingProtocols,
  687. SortedDriverBindingProtocols,
  688. DriverBindingHandleCount,
  689. DriverBindingHandleBuffer,
  690. FALSE);
  691. }
  692. EfiCoreFreePool(DriverBindingHandleBuffer);
  693. //
  694. // If the number of Driver Binding Protocols has increased since this
  695. // function started, return "not ready" so it will be restarted.
  696. //
  697. Status = EfiCoreLocateHandleBuffer(ByProtocol,
  698. &EfiDriverBindingProtocolGuid,
  699. NULL,
  700. &NewDriverBindingHandleCount,
  701. &NewDriverBindingHandleBuffer);
  702. EfiCoreFreePool(NewDriverBindingHandleBuffer);
  703. if (NewDriverBindingHandleCount > DriverBindingHandleCount) {
  704. EfiCoreFreePool(SortedDriverBindingProtocols);
  705. return EFI_NOT_READY;
  706. }
  707. //
  708. // Sort the remaining driver binding protocols based on their version field
  709. // from highest to lowest.
  710. //
  711. while (SortIndex < NumberOfSortedDriverBindingProtocols) {
  712. HighestVersion = SortedDriverBindingProtocols[SortIndex]->Version;
  713. HighestIndex = SortIndex;
  714. for (Index = SortIndex + 1;
  715. Index < NumberOfSortedDriverBindingProtocols;
  716. Index += 1) {
  717. if (SortedDriverBindingProtocols[Index]->Version > HighestVersion) {
  718. HighestVersion = SortedDriverBindingProtocols[Index]->Version;
  719. HighestIndex = Index;
  720. }
  721. }
  722. if (SortIndex != HighestIndex) {
  723. DriverBinding = SortedDriverBindingProtocols[SortIndex];
  724. SortedDriverBindingProtocols[SortIndex] =
  725. SortedDriverBindingProtocols[HighestIndex];
  726. SortedDriverBindingProtocols[HighestIndex] = DriverBinding;
  727. }
  728. SortIndex += 1;
  729. }
  730. //
  731. // Loop until no more drivers can be started on the controller handle.
  732. //
  733. OneStarted = FALSE;
  734. do {
  735. //
  736. // Loop through the sorted driver binding protocol instance in order,
  737. // and see if any of the driver binding protocols support the
  738. // controller.
  739. //
  740. DriverBinding = NULL;
  741. DriverFound = FALSE;
  742. for (Index = 0;
  743. Index < NumberOfSortedDriverBindingProtocols;
  744. Index += 1) {
  745. if (DriverFound != FALSE) {
  746. break;
  747. }
  748. if (SortedDriverBindingProtocols[Index] != NULL) {
  749. DriverBinding = SortedDriverBindingProtocols[Index];
  750. Status = DriverBinding->Supported(DriverBinding,
  751. ControllerHandle,
  752. RemainingDevicePath);
  753. if (!EFI_ERROR(Status)) {
  754. SortedDriverBindingProtocols[Index] = NULL;
  755. DriverFound = TRUE;
  756. //
  757. // A driver was found that claims to support the controller,
  758. // so start the driver on the controller.
  759. //
  760. Status = DriverBinding->Start(DriverBinding,
  761. ControllerHandle,
  762. RemainingDevicePath);
  763. if (!EFI_ERROR(Status)) {
  764. OneStarted = TRUE;
  765. }
  766. }
  767. }
  768. }
  769. } while (DriverFound != FALSE);
  770. EfiCoreFreePool(SortedDriverBindingProtocols);
  771. //
  772. // If at least one driver started, declare success.
  773. //
  774. if (OneStarted != FALSE) {
  775. return EFI_SUCCESS;
  776. }
  777. //
  778. // If no drivers started and the remaining device path is an end device
  779. // node, return success.
  780. //
  781. if (RemainingDevicePath != NULL) {
  782. if (EfiCoreIsDevicePathEnd(RemainingDevicePath) != FALSE) {
  783. return EFI_SUCCESS;
  784. }
  785. }
  786. //
  787. // No drivers were started on the controller.
  788. //
  789. return EFI_NOT_FOUND;
  790. }
  791. VOID
  792. EfipCoreAddSortedDriverBindingProtocol (
  793. EFI_HANDLE DriverBindingHandle,
  794. UINTN *NumberOfSortedDriverBindingProtocols,
  795. EFI_DRIVER_BINDING_PROTOCOL **SortedDriverBindingProtocols,
  796. UINTN DriverBindingHandleCount,
  797. EFI_HANDLE *DriverBindingHandleBuffer,
  798. BOOLEAN IsImageHandle
  799. )
  800. /*++
  801. Routine Description:
  802. This routine adds a driver binding protocol to a sorted driver binding
  803. protocol list.
  804. Arguments:
  805. DriverBindingHandle - Supplies the handle of the driver binding protcol.
  806. NumberOfSortedDriverBindingProtocols - Supplies a pointer containing the
  807. number os sorted driver binding protocols. This will be incremented by
  808. this function.
  809. SortedDriverBindingProtocols - Supplies the sorted protocol list.
  810. DriverBindingHandleCount - Supplies the number of handles in the driver
  811. binding handle buffer.
  812. DriverBindingHandleBuffer - Supplies the buffer of driver binding handles
  813. to be modified.
  814. IsImageHandle - Supplies a boolean indicating if the driver binding handle
  815. is an image handle.
  816. Return Value:
  817. None.
  818. --*/
  819. {
  820. EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
  821. UINTN Index;
  822. EFI_STATUS Status;
  823. Status = EfipCoreValidateHandle(DriverBindingHandle);
  824. if (EFI_ERROR(Status)) {
  825. ASSERT(FALSE);
  826. return;
  827. }
  828. //
  829. // If the handle is an image handle, find all the driver binding handles
  830. // associated with that image handle and add them to the sorted list.
  831. //
  832. if (IsImageHandle != FALSE) {
  833. for (Index = 0; Index < DriverBindingHandleCount; Index += 1) {
  834. Status = EfiCoreHandleProtocol(DriverBindingHandleBuffer[Index],
  835. &EfiDriverBindingProtocolGuid,
  836. (VOID **)&DriverBinding);
  837. if ((EFI_ERROR(Status)) || (DriverBinding == NULL)) {
  838. continue;
  839. }
  840. //
  841. // If the image handle associated with the driver binding matches
  842. // the driver binding handle, then add the driver binding to the
  843. // list.
  844. //
  845. if (DriverBinding->ImageHandle == DriverBindingHandle) {
  846. EfipCoreAddSortedDriverBindingProtocol(
  847. DriverBindingHandleBuffer[Index],
  848. NumberOfSortedDriverBindingProtocols,
  849. SortedDriverBindingProtocols,
  850. DriverBindingHandleCount,
  851. DriverBindingHandleBuffer,
  852. FALSE);
  853. }
  854. }
  855. return;
  856. }
  857. Status = EfiCoreHandleProtocol(DriverBindingHandle,
  858. &EfiDriverBindingProtocolGuid,
  859. (VOID **)&DriverBinding);
  860. if ((EFI_ERROR(Status)) || (DriverBinding == NULL)) {
  861. return;
  862. }
  863. //
  864. // See if the driver binding is already on the list.
  865. //
  866. for (Index = 0;
  867. Index < *NumberOfSortedDriverBindingProtocols;
  868. Index += 1) {
  869. if (Index >= DriverBindingHandleCount) {
  870. break;
  871. }
  872. if (DriverBinding == SortedDriverBindingProtocols[Index]) {
  873. return;
  874. }
  875. }
  876. //
  877. // Add the driver binding to the end of the list.
  878. //
  879. if (*NumberOfSortedDriverBindingProtocols < DriverBindingHandleCount) {
  880. SortedDriverBindingProtocols[*NumberOfSortedDriverBindingProtocols] =
  881. DriverBinding;
  882. }
  883. *NumberOfSortedDriverBindingProtocols += 1;
  884. //
  885. // Mark the corresponding handle in the driver binding handle buffer as
  886. // used.
  887. //
  888. for (Index = 0; Index < DriverBindingHandleCount; Index += 1) {
  889. if (DriverBindingHandleBuffer[Index] == DriverBindingHandle) {
  890. DriverBindingHandleBuffer[Index] = NULL;
  891. }
  892. }
  893. return;
  894. }