drvsup.c 37 KB

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