HttpBootDxe.c 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332
  1. /** @file
  2. Driver Binding functions implementation for UEFI HTTP boot.
  3. Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. **/
  6. #include "HttpBootDxe.h"
  7. ///
  8. /// Driver Binding Protocol instance
  9. ///
  10. EFI_DRIVER_BINDING_PROTOCOL gHttpBootIp4DxeDriverBinding = {
  11. HttpBootIp4DxeDriverBindingSupported,
  12. HttpBootIp4DxeDriverBindingStart,
  13. HttpBootIp4DxeDriverBindingStop,
  14. HTTP_BOOT_DXE_VERSION,
  15. NULL,
  16. NULL
  17. };
  18. EFI_DRIVER_BINDING_PROTOCOL gHttpBootIp6DxeDriverBinding = {
  19. HttpBootIp6DxeDriverBindingSupported,
  20. HttpBootIp6DxeDriverBindingStart,
  21. HttpBootIp6DxeDriverBindingStop,
  22. HTTP_BOOT_DXE_VERSION,
  23. NULL,
  24. NULL
  25. };
  26. /**
  27. Check whether UNDI protocol supports IPv6.
  28. @param[in] Private Pointer to HTTP_BOOT_PRIVATE_DATA.
  29. @param[out] Ipv6Support TRUE if UNDI supports IPv6.
  30. @retval EFI_SUCCESS Get the result whether UNDI supports IPv6 by NII or AIP protocol successfully.
  31. @retval EFI_NOT_FOUND Don't know whether UNDI supports IPv6 since NII or AIP is not available.
  32. **/
  33. EFI_STATUS
  34. HttpBootCheckIpv6Support (
  35. IN HTTP_BOOT_PRIVATE_DATA *Private,
  36. OUT BOOLEAN *Ipv6Support
  37. )
  38. {
  39. EFI_HANDLE Handle;
  40. EFI_ADAPTER_INFORMATION_PROTOCOL *Aip;
  41. EFI_STATUS Status;
  42. EFI_GUID *InfoTypesBuffer;
  43. UINTN InfoTypeBufferCount;
  44. UINTN TypeIndex;
  45. BOOLEAN Supported;
  46. VOID *InfoBlock;
  47. UINTN InfoBlockSize;
  48. ASSERT (Private != NULL && Ipv6Support != NULL);
  49. //
  50. // Check whether the UNDI supports IPv6 by NII protocol.
  51. //
  52. if (Private->Nii != NULL) {
  53. *Ipv6Support = Private->Nii->Ipv6Supported;
  54. return EFI_SUCCESS;
  55. }
  56. //
  57. // Get the NIC handle by SNP protocol.
  58. //
  59. Handle = NetLibGetSnpHandle (Private->Controller, NULL);
  60. if (Handle == NULL) {
  61. return EFI_NOT_FOUND;
  62. }
  63. Aip = NULL;
  64. Status = gBS->HandleProtocol (
  65. Handle,
  66. &gEfiAdapterInformationProtocolGuid,
  67. (VOID *) &Aip
  68. );
  69. if (EFI_ERROR (Status) || Aip == NULL) {
  70. return EFI_NOT_FOUND;
  71. }
  72. InfoTypesBuffer = NULL;
  73. InfoTypeBufferCount = 0;
  74. Status = Aip->GetSupportedTypes (Aip, &InfoTypesBuffer, &InfoTypeBufferCount);
  75. if (EFI_ERROR (Status) || InfoTypesBuffer == NULL) {
  76. FreePool (InfoTypesBuffer);
  77. return EFI_NOT_FOUND;
  78. }
  79. Supported = FALSE;
  80. for (TypeIndex = 0; TypeIndex < InfoTypeBufferCount; TypeIndex++) {
  81. if (CompareGuid (&InfoTypesBuffer[TypeIndex], &gEfiAdapterInfoUndiIpv6SupportGuid)) {
  82. Supported = TRUE;
  83. break;
  84. }
  85. }
  86. FreePool (InfoTypesBuffer);
  87. if (!Supported) {
  88. return EFI_NOT_FOUND;
  89. }
  90. //
  91. // We now have adapter information block.
  92. //
  93. InfoBlock = NULL;
  94. InfoBlockSize = 0;
  95. Status = Aip->GetInformation (Aip, &gEfiAdapterInfoUndiIpv6SupportGuid, &InfoBlock, &InfoBlockSize);
  96. if (EFI_ERROR (Status) || InfoBlock == NULL) {
  97. FreePool (InfoBlock);
  98. return EFI_NOT_FOUND;
  99. }
  100. *Ipv6Support = ((EFI_ADAPTER_INFO_UNDI_IPV6_SUPPORT *) InfoBlock)->Ipv6Support;
  101. FreePool (InfoBlock);
  102. return EFI_SUCCESS;
  103. }
  104. /**
  105. Destroy the HTTP child based on IPv4 stack.
  106. @param[in] This Pointer to the EFI_DRIVER_BINDING_PROTOCOL.
  107. @param[in] Private Pointer to HTTP_BOOT_PRIVATE_DATA.
  108. **/
  109. VOID
  110. HttpBootDestroyIp4Children (
  111. IN EFI_DRIVER_BINDING_PROTOCOL *This,
  112. IN HTTP_BOOT_PRIVATE_DATA *Private
  113. )
  114. {
  115. ASSERT (This != NULL);
  116. ASSERT (Private != NULL);
  117. if (Private->Dhcp4Child != NULL) {
  118. gBS->CloseProtocol (
  119. Private->Dhcp4Child,
  120. &gEfiDhcp4ProtocolGuid,
  121. This->DriverBindingHandle,
  122. Private->Controller
  123. );
  124. NetLibDestroyServiceChild (
  125. Private->Controller,
  126. This->DriverBindingHandle,
  127. &gEfiDhcp4ServiceBindingProtocolGuid,
  128. Private->Dhcp4Child
  129. );
  130. }
  131. if (Private->Ip6Nic == NULL && Private->HttpCreated) {
  132. HttpIoDestroyIo (&Private->HttpIo);
  133. Private->HttpCreated = FALSE;
  134. }
  135. if (Private->Ip4Nic != NULL) {
  136. gBS->CloseProtocol (
  137. Private->Controller,
  138. &gEfiCallerIdGuid,
  139. This->DriverBindingHandle,
  140. Private->Ip4Nic->Controller
  141. );
  142. gBS->UninstallMultipleProtocolInterfaces (
  143. Private->Ip4Nic->Controller,
  144. &gEfiLoadFileProtocolGuid,
  145. &Private->Ip4Nic->LoadFile,
  146. &gEfiDevicePathProtocolGuid,
  147. Private->Ip4Nic->DevicePath,
  148. NULL
  149. );
  150. FreePool (Private->Ip4Nic);
  151. Private->Ip4Nic = NULL;
  152. }
  153. }
  154. /**
  155. Destroy the HTTP child based on IPv6 stack.
  156. @param[in] This Pointer to the EFI_DRIVER_BINDING_PROTOCOL.
  157. @param[in] Private Pointer to HTTP_BOOT_PRIVATE_DATA.
  158. **/
  159. VOID
  160. HttpBootDestroyIp6Children (
  161. IN EFI_DRIVER_BINDING_PROTOCOL *This,
  162. IN HTTP_BOOT_PRIVATE_DATA *Private
  163. )
  164. {
  165. ASSERT (This != NULL);
  166. ASSERT (Private != NULL);
  167. if (Private->Ip6Child != NULL) {
  168. gBS->CloseProtocol (
  169. Private->Ip6Child,
  170. &gEfiIp6ProtocolGuid,
  171. This->DriverBindingHandle,
  172. Private->Controller
  173. );
  174. NetLibDestroyServiceChild (
  175. Private->Controller,
  176. This->DriverBindingHandle,
  177. &gEfiIp6ServiceBindingProtocolGuid,
  178. Private->Ip6Child
  179. );
  180. }
  181. if (Private->Dhcp6Child != NULL) {
  182. gBS->CloseProtocol (
  183. Private->Dhcp6Child,
  184. &gEfiDhcp6ProtocolGuid,
  185. This->DriverBindingHandle,
  186. Private->Controller
  187. );
  188. NetLibDestroyServiceChild (
  189. Private->Controller,
  190. This->DriverBindingHandle,
  191. &gEfiDhcp6ServiceBindingProtocolGuid,
  192. Private->Dhcp6Child
  193. );
  194. }
  195. if (Private->Ip4Nic == NULL && Private->HttpCreated) {
  196. HttpIoDestroyIo(&Private->HttpIo);
  197. Private->HttpCreated = FALSE;
  198. }
  199. if (Private->Ip6Nic != NULL) {
  200. gBS->CloseProtocol (
  201. Private->Controller,
  202. &gEfiCallerIdGuid,
  203. This->DriverBindingHandle,
  204. Private->Ip6Nic->Controller
  205. );
  206. gBS->UninstallMultipleProtocolInterfaces (
  207. Private->Ip6Nic->Controller,
  208. &gEfiLoadFileProtocolGuid,
  209. &Private->Ip6Nic->LoadFile,
  210. &gEfiDevicePathProtocolGuid,
  211. Private->Ip6Nic->DevicePath,
  212. NULL
  213. );
  214. FreePool (Private->Ip6Nic);
  215. Private->Ip6Nic = NULL;
  216. }
  217. }
  218. /**
  219. Tests to see if this driver supports a given controller. If a child device is provided,
  220. it further tests to see if this driver supports creating a handle for the specified child device.
  221. This function checks to see if the driver specified by This supports the device specified by
  222. ControllerHandle. Drivers will typically use the device path attached to
  223. ControllerHandle and/or the services from the bus I/O abstraction attached to
  224. ControllerHandle to determine if the driver supports ControllerHandle. This function
  225. may be called many times during platform initialization. In order to reduce boot times, the tests
  226. performed by this function must be very small, and take as little time as possible to execute. This
  227. function must not change the state of any hardware devices, and this function must be aware that the
  228. device specified by ControllerHandle may already be managed by the same driver or a
  229. different driver. This function must match its calls to AllocatePages() with FreePages(),
  230. AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
  231. Because ControllerHandle may have been previously started by the same driver, if a protocol is
  232. already in the opened state, then it must not be closed with CloseProtocol(). This is required
  233. to guarantee the state of ControllerHandle is not modified by this function.
  234. @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
  235. @param[in] ControllerHandle The handle of the controller to test. This handle
  236. must support a protocol interface that supplies
  237. an I/O abstraction to the driver.
  238. @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
  239. parameter is ignored by device drivers, and is optional for bus
  240. drivers. For bus drivers, if this parameter is not NULL, then
  241. the bus driver must determine if the bus controller specified
  242. by ControllerHandle and the child controller specified
  243. by RemainingDevicePath are both supported by this
  244. bus driver.
  245. @retval EFI_SUCCESS The device specified by ControllerHandle and
  246. RemainingDevicePath is supported by the driver specified by This.
  247. @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
  248. RemainingDevicePath is already being managed by the driver
  249. specified by This.
  250. @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
  251. RemainingDevicePath is already being managed by a different
  252. driver or an application that requires exclusive access.
  253. Currently not implemented.
  254. @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
  255. RemainingDevicePath is not supported by the driver specified by This.
  256. **/
  257. EFI_STATUS
  258. EFIAPI
  259. HttpBootIp4DxeDriverBindingSupported (
  260. IN EFI_DRIVER_BINDING_PROTOCOL *This,
  261. IN EFI_HANDLE ControllerHandle,
  262. IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
  263. )
  264. {
  265. EFI_STATUS Status;
  266. //
  267. // Try to open the DHCP4, HTTP4 and Device Path protocol.
  268. //
  269. Status = gBS->OpenProtocol (
  270. ControllerHandle,
  271. &gEfiDhcp4ServiceBindingProtocolGuid,
  272. NULL,
  273. This->DriverBindingHandle,
  274. ControllerHandle,
  275. EFI_OPEN_PROTOCOL_TEST_PROTOCOL
  276. );
  277. if (EFI_ERROR (Status)) {
  278. return Status;
  279. }
  280. Status = gBS->OpenProtocol (
  281. ControllerHandle,
  282. &gEfiHttpServiceBindingProtocolGuid,
  283. NULL,
  284. This->DriverBindingHandle,
  285. ControllerHandle,
  286. EFI_OPEN_PROTOCOL_TEST_PROTOCOL
  287. );
  288. if (EFI_ERROR (Status)) {
  289. return Status;
  290. }
  291. Status = gBS->OpenProtocol (
  292. ControllerHandle,
  293. &gEfiDevicePathProtocolGuid,
  294. NULL,
  295. This->DriverBindingHandle,
  296. ControllerHandle,
  297. EFI_OPEN_PROTOCOL_TEST_PROTOCOL
  298. );
  299. return Status;
  300. }
  301. /**
  302. Starts a device controller or a bus controller.
  303. The Start() function is designed to be invoked from the EFI boot service ConnectController().
  304. As a result, much of the error checking on the parameters to Start() has been moved into this
  305. common boot service. It is legal to call Start() from other locations,
  306. but the following calling restrictions must be followed, or the system behavior will not be deterministic.
  307. 1. ControllerHandle must be a valid EFI_HANDLE.
  308. 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
  309. EFI_DEVICE_PATH_PROTOCOL.
  310. 3. Prior to calling Start(), the Supported() function for the driver specified by This must
  311. have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
  312. @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
  313. @param[in] ControllerHandle The handle of the controller to start. This handle
  314. must support a protocol interface that supplies
  315. an I/O abstraction to the driver.
  316. @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
  317. parameter is ignored by device drivers, and is optional for bus
  318. drivers. For a bus driver, if this parameter is NULL, then handles
  319. for all the children of Controller are created by this driver.
  320. If this parameter is not NULL and the first Device Path Node is
  321. not the End of Device Path Node, then only the handle for the
  322. child device specified by the first Device Path Node of
  323. RemainingDevicePath is created by this driver.
  324. If the first Device Path Node of RemainingDevicePath is
  325. the End of Device Path Node, no child handle is created by this
  326. driver.
  327. @retval EFI_SUCCESS The device was started.
  328. @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
  329. @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
  330. @retval Others The driver failded to start the device.
  331. **/
  332. EFI_STATUS
  333. EFIAPI
  334. HttpBootIp4DxeDriverBindingStart (
  335. IN EFI_DRIVER_BINDING_PROTOCOL *This,
  336. IN EFI_HANDLE ControllerHandle,
  337. IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
  338. )
  339. {
  340. EFI_STATUS Status;
  341. HTTP_BOOT_PRIVATE_DATA *Private;
  342. EFI_DEV_PATH *Node;
  343. EFI_DEVICE_PATH_PROTOCOL *DevicePath;
  344. UINT32 *Id;
  345. BOOLEAN FirstStart;
  346. FirstStart = FALSE;
  347. Status = gBS->OpenProtocol (
  348. ControllerHandle,
  349. &gEfiCallerIdGuid,
  350. (VOID **) &Id,
  351. This->DriverBindingHandle,
  352. ControllerHandle,
  353. EFI_OPEN_PROTOCOL_GET_PROTOCOL
  354. );
  355. if (!EFI_ERROR (Status)) {
  356. Private = HTTP_BOOT_PRIVATE_DATA_FROM_ID(Id);
  357. } else {
  358. FirstStart = TRUE;
  359. //
  360. // Initialize the private data structure.
  361. //
  362. Private = AllocateZeroPool (sizeof (HTTP_BOOT_PRIVATE_DATA));
  363. if (Private == NULL) {
  364. return EFI_OUT_OF_RESOURCES;
  365. }
  366. Private->Signature = HTTP_BOOT_PRIVATE_DATA_SIGNATURE;
  367. Private->Controller = ControllerHandle;
  368. InitializeListHead (&Private->CacheList);
  369. //
  370. // Get the NII interface if it exists, it's not required.
  371. //
  372. Status = gBS->OpenProtocol (
  373. ControllerHandle,
  374. &gEfiNetworkInterfaceIdentifierProtocolGuid_31,
  375. (VOID **) &Private->Nii,
  376. This->DriverBindingHandle,
  377. ControllerHandle,
  378. EFI_OPEN_PROTOCOL_GET_PROTOCOL
  379. );
  380. if (EFI_ERROR (Status)) {
  381. Private->Nii = NULL;
  382. }
  383. //
  384. // Open Device Path Protocol to prepare for appending IP and URI node.
  385. //
  386. Status = gBS->OpenProtocol (
  387. ControllerHandle,
  388. &gEfiDevicePathProtocolGuid,
  389. (VOID **) &Private->ParentDevicePath,
  390. This->DriverBindingHandle,
  391. ControllerHandle,
  392. EFI_OPEN_PROTOCOL_GET_PROTOCOL
  393. );
  394. if (EFI_ERROR (Status)) {
  395. goto ON_ERROR;
  396. }
  397. //
  398. // Initialize the HII configuration form.
  399. //
  400. Status = HttpBootConfigFormInit (Private);
  401. if (EFI_ERROR (Status)) {
  402. goto ON_ERROR;
  403. }
  404. //
  405. // Install a protocol with Caller Id Guid to the NIC, this is just to build the relationship between
  406. // NIC handle and the private data.
  407. //
  408. Status = gBS->InstallProtocolInterface (
  409. &ControllerHandle,
  410. &gEfiCallerIdGuid,
  411. EFI_NATIVE_INTERFACE,
  412. &Private->Id
  413. );
  414. if (EFI_ERROR (Status)) {
  415. goto ON_ERROR;
  416. }
  417. }
  418. if (Private->Ip4Nic != NULL) {
  419. //
  420. // Already created before
  421. //
  422. return EFI_SUCCESS;
  423. }
  424. Private->Ip4Nic = AllocateZeroPool (sizeof (HTTP_BOOT_VIRTUAL_NIC));
  425. if (Private->Ip4Nic == NULL) {
  426. Status = EFI_OUT_OF_RESOURCES;
  427. goto ON_ERROR;
  428. }
  429. Private->Ip4Nic->Private = Private;
  430. Private->Ip4Nic->ImageHandle = This->DriverBindingHandle;
  431. Private->Ip4Nic->Signature = HTTP_BOOT_VIRTUAL_NIC_SIGNATURE;
  432. //
  433. // Create DHCP4 child instance.
  434. //
  435. Status = NetLibCreateServiceChild (
  436. ControllerHandle,
  437. This->DriverBindingHandle,
  438. &gEfiDhcp4ServiceBindingProtocolGuid,
  439. &Private->Dhcp4Child
  440. );
  441. if (EFI_ERROR (Status)) {
  442. goto ON_ERROR;
  443. }
  444. Status = gBS->OpenProtocol (
  445. Private->Dhcp4Child,
  446. &gEfiDhcp4ProtocolGuid,
  447. (VOID **) &Private->Dhcp4,
  448. This->DriverBindingHandle,
  449. ControllerHandle,
  450. EFI_OPEN_PROTOCOL_BY_DRIVER
  451. );
  452. if (EFI_ERROR (Status)) {
  453. goto ON_ERROR;
  454. }
  455. //
  456. // Get the Ip4Config2 protocol, it's required to configure the default gateway address.
  457. //
  458. Status = gBS->OpenProtocol (
  459. ControllerHandle,
  460. &gEfiIp4Config2ProtocolGuid,
  461. (VOID **) &Private->Ip4Config2,
  462. This->DriverBindingHandle,
  463. ControllerHandle,
  464. EFI_OPEN_PROTOCOL_GET_PROTOCOL
  465. );
  466. if (EFI_ERROR (Status)) {
  467. goto ON_ERROR;
  468. }
  469. //
  470. // Append IPv4 device path node.
  471. //
  472. Node = AllocateZeroPool (sizeof (IPv4_DEVICE_PATH));
  473. if (Node == NULL) {
  474. Status = EFI_OUT_OF_RESOURCES;
  475. goto ON_ERROR;
  476. }
  477. Node->Ipv4.Header.Type = MESSAGING_DEVICE_PATH;
  478. Node->Ipv4.Header.SubType = MSG_IPv4_DP;
  479. SetDevicePathNodeLength (Node, sizeof (IPv4_DEVICE_PATH));
  480. Node->Ipv4.StaticIpAddress = FALSE;
  481. DevicePath = AppendDevicePathNode (Private->ParentDevicePath, (EFI_DEVICE_PATH_PROTOCOL*) Node);
  482. FreePool (Node);
  483. if (DevicePath == NULL) {
  484. Status = EFI_OUT_OF_RESOURCES;
  485. goto ON_ERROR;
  486. }
  487. //
  488. // Append URI device path node.
  489. //
  490. Node = AllocateZeroPool (sizeof (EFI_DEVICE_PATH_PROTOCOL));
  491. if (Node == NULL) {
  492. Status = EFI_OUT_OF_RESOURCES;
  493. goto ON_ERROR;
  494. }
  495. Node->DevPath.Type = MESSAGING_DEVICE_PATH;
  496. Node->DevPath.SubType = MSG_URI_DP;
  497. SetDevicePathNodeLength (Node, sizeof (EFI_DEVICE_PATH_PROTOCOL));
  498. Private->Ip4Nic->DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL*) Node);
  499. FreePool (Node);
  500. FreePool (DevicePath);
  501. if (Private->Ip4Nic->DevicePath == NULL) {
  502. Status = EFI_OUT_OF_RESOURCES;
  503. goto ON_ERROR;
  504. }
  505. //
  506. // Create a child handle for the HTTP boot and install DevPath and Load file protocol on it.
  507. //
  508. CopyMem (&Private->Ip4Nic->LoadFile, &gHttpBootDxeLoadFile, sizeof (EFI_LOAD_FILE_PROTOCOL));
  509. Status = gBS->InstallMultipleProtocolInterfaces (
  510. &Private->Ip4Nic->Controller,
  511. &gEfiLoadFileProtocolGuid,
  512. &Private->Ip4Nic->LoadFile,
  513. &gEfiDevicePathProtocolGuid,
  514. Private->Ip4Nic->DevicePath,
  515. NULL
  516. );
  517. if (EFI_ERROR (Status)) {
  518. goto ON_ERROR;
  519. }
  520. //
  521. // Open the Caller Id child to setup a parent-child relationship between
  522. // real NIC handle and the HTTP boot Ipv4 NIC handle.
  523. //
  524. Status = gBS->OpenProtocol (
  525. ControllerHandle,
  526. &gEfiCallerIdGuid,
  527. (VOID **) &Id,
  528. This->DriverBindingHandle,
  529. Private->Ip4Nic->Controller,
  530. EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
  531. );
  532. if (EFI_ERROR (Status)) {
  533. goto ON_ERROR;
  534. }
  535. return EFI_SUCCESS;
  536. ON_ERROR:
  537. if (Private != NULL) {
  538. if (FirstStart) {
  539. gBS->UninstallProtocolInterface (
  540. ControllerHandle,
  541. &gEfiCallerIdGuid,
  542. &Private->Id
  543. );
  544. }
  545. HttpBootDestroyIp4Children (This, Private);
  546. HttpBootConfigFormUnload (Private);
  547. if (FirstStart) {
  548. FreePool (Private);
  549. }
  550. }
  551. return Status;
  552. }
  553. /**
  554. Stops a device controller or a bus controller.
  555. The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
  556. As a result, much of the error checking on the parameters to Stop() has been moved
  557. into this common boot service. It is legal to call Stop() from other locations,
  558. but the following calling restrictions must be followed, or the system behavior will not be deterministic.
  559. 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
  560. same driver's Start() function.
  561. 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
  562. EFI_HANDLE. In addition, all of these handles must have been created in this driver's
  563. Start() function, and the Start() function must have called OpenProtocol() on
  564. ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
  565. @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
  566. @param[in] ControllerHandle A handle to the device being stopped. The handle must
  567. support a bus specific I/O protocol for the driver
  568. to use to stop the device.
  569. @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
  570. @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
  571. if NumberOfChildren is 0.
  572. @retval EFI_SUCCESS The device was stopped.
  573. @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
  574. **/
  575. EFI_STATUS
  576. EFIAPI
  577. HttpBootIp4DxeDriverBindingStop (
  578. IN EFI_DRIVER_BINDING_PROTOCOL *This,
  579. IN EFI_HANDLE ControllerHandle,
  580. IN UINTN NumberOfChildren,
  581. IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
  582. )
  583. {
  584. EFI_STATUS Status;
  585. EFI_LOAD_FILE_PROTOCOL *LoadFile;
  586. HTTP_BOOT_PRIVATE_DATA *Private;
  587. EFI_HANDLE NicHandle;
  588. UINT32 *Id;
  589. //
  590. // Try to get the Load File Protocol from the controller handle.
  591. //
  592. Status = gBS->OpenProtocol (
  593. ControllerHandle,
  594. &gEfiLoadFileProtocolGuid,
  595. (VOID **) &LoadFile,
  596. This->DriverBindingHandle,
  597. ControllerHandle,
  598. EFI_OPEN_PROTOCOL_GET_PROTOCOL
  599. );
  600. if (EFI_ERROR (Status)) {
  601. //
  602. // If failed, try to find the NIC handle for this controller.
  603. //
  604. NicHandle = HttpBootGetNicByIp4Children (ControllerHandle);
  605. if (NicHandle == NULL) {
  606. return EFI_SUCCESS;
  607. }
  608. //
  609. // Try to retrieve the private data by the Caller Id Guid.
  610. //
  611. Status = gBS->OpenProtocol (
  612. NicHandle,
  613. &gEfiCallerIdGuid,
  614. (VOID **) &Id,
  615. This->DriverBindingHandle,
  616. ControllerHandle,
  617. EFI_OPEN_PROTOCOL_GET_PROTOCOL
  618. );
  619. if (EFI_ERROR (Status)) {
  620. return Status;
  621. }
  622. Private = HTTP_BOOT_PRIVATE_DATA_FROM_ID (Id);
  623. } else {
  624. Private = HTTP_BOOT_PRIVATE_DATA_FROM_LOADFILE (LoadFile);
  625. NicHandle = Private->Controller;
  626. }
  627. //
  628. // Disable the HTTP boot function.
  629. //
  630. Status = HttpBootStop (Private);
  631. if (Status != EFI_SUCCESS && Status != EFI_NOT_STARTED) {
  632. return Status;
  633. }
  634. //
  635. // Destory all child instance and uninstall protocol interface.
  636. //
  637. HttpBootDestroyIp4Children (This, Private);
  638. if (Private->Ip4Nic == NULL && Private->Ip6Nic == NULL) {
  639. //
  640. // Release the cached data.
  641. //
  642. HttpBootFreeCacheList (Private);
  643. //
  644. // Unload the config form.
  645. //
  646. HttpBootConfigFormUnload (Private);
  647. gBS->UninstallProtocolInterface (
  648. NicHandle,
  649. &gEfiCallerIdGuid,
  650. &Private->Id
  651. );
  652. FreePool (Private);
  653. }
  654. return EFI_SUCCESS;
  655. }
  656. /**
  657. Tests to see if this driver supports a given controller. If a child device is provided,
  658. it further tests to see if this driver supports creating a handle for the specified child device.
  659. This function checks to see if the driver specified by This supports the device specified by
  660. ControllerHandle. Drivers will typically use the device path attached to
  661. ControllerHandle and/or the services from the bus I/O abstraction attached to
  662. ControllerHandle to determine if the driver supports ControllerHandle. This function
  663. may be called many times during platform initialization. In order to reduce boot times, the tests
  664. performed by this function must be very small, and take as little time as possible to execute. This
  665. function must not change the state of any hardware devices, and this function must be aware that the
  666. device specified by ControllerHandle may already be managed by the same driver or a
  667. different driver. This function must match its calls to AllocatePages() with FreePages(),
  668. AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
  669. Because ControllerHandle may have been previously started by the same driver, if a protocol is
  670. already in the opened state, then it must not be closed with CloseProtocol(). This is required
  671. to guarantee the state of ControllerHandle is not modified by this function.
  672. @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
  673. @param[in] ControllerHandle The handle of the controller to test. This handle
  674. must support a protocol interface that supplies
  675. an I/O abstraction to the driver.
  676. @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
  677. parameter is ignored by device drivers, and is optional for bus
  678. drivers. For bus drivers, if this parameter is not NULL, then
  679. the bus driver must determine if the bus controller specified
  680. by ControllerHandle and the child controller specified
  681. by RemainingDevicePath are both supported by this
  682. bus driver.
  683. @retval EFI_SUCCESS The device specified by ControllerHandle and
  684. RemainingDevicePath is supported by the driver specified by This.
  685. @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
  686. RemainingDevicePath is already being managed by the driver
  687. specified by This.
  688. @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
  689. RemainingDevicePath is already being managed by a different
  690. driver or an application that requires exclusive access.
  691. Currently not implemented.
  692. @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
  693. RemainingDevicePath is not supported by the driver specified by This.
  694. **/
  695. EFI_STATUS
  696. EFIAPI
  697. HttpBootIp6DxeDriverBindingSupported (
  698. IN EFI_DRIVER_BINDING_PROTOCOL *This,
  699. IN EFI_HANDLE ControllerHandle,
  700. IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
  701. )
  702. {
  703. EFI_STATUS Status;
  704. //
  705. // Try to open the DHCP6, HTTP and Device Path protocol.
  706. //
  707. Status = gBS->OpenProtocol (
  708. ControllerHandle,
  709. &gEfiDhcp6ServiceBindingProtocolGuid,
  710. NULL,
  711. This->DriverBindingHandle,
  712. ControllerHandle,
  713. EFI_OPEN_PROTOCOL_TEST_PROTOCOL
  714. );
  715. if (EFI_ERROR (Status)) {
  716. return Status;
  717. }
  718. Status = gBS->OpenProtocol (
  719. ControllerHandle,
  720. &gEfiHttpServiceBindingProtocolGuid,
  721. NULL,
  722. This->DriverBindingHandle,
  723. ControllerHandle,
  724. EFI_OPEN_PROTOCOL_TEST_PROTOCOL
  725. );
  726. if (EFI_ERROR (Status)) {
  727. return Status;
  728. }
  729. Status = gBS->OpenProtocol (
  730. ControllerHandle,
  731. &gEfiDevicePathProtocolGuid,
  732. NULL,
  733. This->DriverBindingHandle,
  734. ControllerHandle,
  735. EFI_OPEN_PROTOCOL_TEST_PROTOCOL
  736. );
  737. return Status;
  738. }
  739. /**
  740. Starts a device controller or a bus controller.
  741. The Start() function is designed to be invoked from the EFI boot service ConnectController().
  742. As a result, much of the error checking on the parameters to Start() has been moved into this
  743. common boot service. It is legal to call Start() from other locations,
  744. but the following calling restrictions must be followed, or the system behavior will not be deterministic.
  745. 1. ControllerHandle must be a valid EFI_HANDLE.
  746. 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
  747. EFI_DEVICE_PATH_PROTOCOL.
  748. 3. Prior to calling Start(), the Supported() function for the driver specified by This must
  749. have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
  750. @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
  751. @param[in] ControllerHandle The handle of the controller to start. This handle
  752. must support a protocol interface that supplies
  753. an I/O abstraction to the driver.
  754. @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
  755. parameter is ignored by device drivers, and is optional for bus
  756. drivers. For a bus driver, if this parameter is NULL, then handles
  757. for all the children of Controller are created by this driver.
  758. If this parameter is not NULL and the first Device Path Node is
  759. not the End of Device Path Node, then only the handle for the
  760. child device specified by the first Device Path Node of
  761. RemainingDevicePath is created by this driver.
  762. If the first Device Path Node of RemainingDevicePath is
  763. the End of Device Path Node, no child handle is created by this
  764. driver.
  765. @retval EFI_SUCCESS The device was started.
  766. @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
  767. @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
  768. @retval Others The driver failded to start the device.
  769. **/
  770. EFI_STATUS
  771. EFIAPI
  772. HttpBootIp6DxeDriverBindingStart (
  773. IN EFI_DRIVER_BINDING_PROTOCOL *This,
  774. IN EFI_HANDLE ControllerHandle,
  775. IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
  776. )
  777. {
  778. EFI_STATUS Status;
  779. HTTP_BOOT_PRIVATE_DATA *Private;
  780. EFI_DEV_PATH *Node;
  781. EFI_DEVICE_PATH_PROTOCOL *DevicePath;
  782. UINT32 *Id;
  783. BOOLEAN Ipv6Available;
  784. BOOLEAN FirstStart;
  785. FirstStart = FALSE;
  786. Status = gBS->OpenProtocol (
  787. ControllerHandle,
  788. &gEfiCallerIdGuid,
  789. (VOID **) &Id,
  790. This->DriverBindingHandle,
  791. ControllerHandle,
  792. EFI_OPEN_PROTOCOL_GET_PROTOCOL
  793. );
  794. if (!EFI_ERROR (Status)) {
  795. Private = HTTP_BOOT_PRIVATE_DATA_FROM_ID(Id);
  796. } else {
  797. FirstStart = TRUE;
  798. //
  799. // Initialize the private data structure.
  800. //
  801. Private = AllocateZeroPool (sizeof (HTTP_BOOT_PRIVATE_DATA));
  802. if (Private == NULL) {
  803. return EFI_OUT_OF_RESOURCES;
  804. }
  805. Private->Signature = HTTP_BOOT_PRIVATE_DATA_SIGNATURE;
  806. Private->Controller = ControllerHandle;
  807. InitializeListHead (&Private->CacheList);
  808. //
  809. // Get the NII interface if it exists, it's not required.
  810. //
  811. Status = gBS->OpenProtocol (
  812. ControllerHandle,
  813. &gEfiNetworkInterfaceIdentifierProtocolGuid_31,
  814. (VOID **) &Private->Nii,
  815. This->DriverBindingHandle,
  816. ControllerHandle,
  817. EFI_OPEN_PROTOCOL_GET_PROTOCOL
  818. );
  819. if (EFI_ERROR (Status)) {
  820. Private->Nii = NULL;
  821. }
  822. //
  823. // Open Device Path Protocol to prepare for appending IP and URI node.
  824. //
  825. Status = gBS->OpenProtocol (
  826. ControllerHandle,
  827. &gEfiDevicePathProtocolGuid,
  828. (VOID **) &Private->ParentDevicePath,
  829. This->DriverBindingHandle,
  830. ControllerHandle,
  831. EFI_OPEN_PROTOCOL_GET_PROTOCOL
  832. );
  833. if (EFI_ERROR (Status)) {
  834. goto ON_ERROR;
  835. }
  836. //
  837. // Initialize the HII configuration form.
  838. //
  839. Status = HttpBootConfigFormInit (Private);
  840. if (EFI_ERROR (Status)) {
  841. goto ON_ERROR;
  842. }
  843. //
  844. // Install a protocol with Caller Id Guid to the NIC, this is just to build the relationship between
  845. // NIC handle and the private data.
  846. //
  847. Status = gBS->InstallProtocolInterface (
  848. &ControllerHandle,
  849. &gEfiCallerIdGuid,
  850. EFI_NATIVE_INTERFACE,
  851. &Private->Id
  852. );
  853. if (EFI_ERROR (Status)) {
  854. goto ON_ERROR;
  855. }
  856. }
  857. //
  858. // Set IPv6 available flag.
  859. //
  860. Status = HttpBootCheckIpv6Support (Private, &Ipv6Available);
  861. if (EFI_ERROR (Status)) {
  862. //
  863. // Fail to get the data whether UNDI supports IPv6.
  864. // Set default value to TRUE.
  865. //
  866. Ipv6Available = TRUE;
  867. }
  868. if (!Ipv6Available) {
  869. Status = EFI_UNSUPPORTED;
  870. goto ON_ERROR;
  871. }
  872. if (Private->Ip6Nic != NULL) {
  873. //
  874. // Already created before
  875. //
  876. return EFI_SUCCESS;
  877. }
  878. Private->Ip6Nic = AllocateZeroPool (sizeof (HTTP_BOOT_VIRTUAL_NIC));
  879. if (Private->Ip6Nic == NULL) {
  880. Status = EFI_OUT_OF_RESOURCES;
  881. goto ON_ERROR;
  882. }
  883. Private->Ip6Nic->Private = Private;
  884. Private->Ip6Nic->ImageHandle = This->DriverBindingHandle;
  885. Private->Ip6Nic->Signature = HTTP_BOOT_VIRTUAL_NIC_SIGNATURE;
  886. //
  887. // Create Dhcp6 child and open Dhcp6 protocol
  888. Status = NetLibCreateServiceChild (
  889. ControllerHandle,
  890. This->DriverBindingHandle,
  891. &gEfiDhcp6ServiceBindingProtocolGuid,
  892. &Private->Dhcp6Child
  893. );
  894. if (EFI_ERROR (Status)) {
  895. goto ON_ERROR;
  896. }
  897. Status = gBS->OpenProtocol (
  898. Private->Dhcp6Child,
  899. &gEfiDhcp6ProtocolGuid,
  900. (VOID **) &Private->Dhcp6,
  901. This->DriverBindingHandle,
  902. ControllerHandle,
  903. EFI_OPEN_PROTOCOL_BY_DRIVER
  904. );
  905. if (EFI_ERROR (Status)) {
  906. goto ON_ERROR;
  907. }
  908. //
  909. // Create Ip6 child and open Ip6 protocol for background ICMP packets.
  910. //
  911. Status = NetLibCreateServiceChild (
  912. ControllerHandle,
  913. This->DriverBindingHandle,
  914. &gEfiIp6ServiceBindingProtocolGuid,
  915. &Private->Ip6Child
  916. );
  917. if (EFI_ERROR (Status)) {
  918. goto ON_ERROR;
  919. }
  920. Status = gBS->OpenProtocol (
  921. Private->Ip6Child,
  922. &gEfiIp6ProtocolGuid,
  923. (VOID **) &Private->Ip6,
  924. This->DriverBindingHandle,
  925. ControllerHandle,
  926. EFI_OPEN_PROTOCOL_BY_DRIVER
  927. );
  928. if (EFI_ERROR (Status)) {
  929. goto ON_ERROR;
  930. }
  931. //
  932. // Locate Ip6Config protocol, it's required to configure the default gateway address.
  933. //
  934. Status = gBS->OpenProtocol (
  935. ControllerHandle,
  936. &gEfiIp6ConfigProtocolGuid,
  937. (VOID **) &Private->Ip6Config,
  938. This->DriverBindingHandle,
  939. ControllerHandle,
  940. EFI_OPEN_PROTOCOL_GET_PROTOCOL
  941. );
  942. if (EFI_ERROR (Status)) {
  943. goto ON_ERROR;
  944. }
  945. //
  946. // Append IPv6 device path node.
  947. //
  948. Node = AllocateZeroPool (sizeof (IPv6_DEVICE_PATH));
  949. if (Node == NULL) {
  950. Status = EFI_OUT_OF_RESOURCES;
  951. goto ON_ERROR;
  952. }
  953. Node->Ipv6.Header.Type = MESSAGING_DEVICE_PATH;
  954. Node->Ipv6.Header.SubType = MSG_IPv6_DP;
  955. Node->Ipv6.PrefixLength = IP6_PREFIX_LENGTH;
  956. SetDevicePathNodeLength (Node, sizeof (IPv6_DEVICE_PATH));
  957. DevicePath = AppendDevicePathNode(Private->ParentDevicePath, (EFI_DEVICE_PATH*) Node);
  958. FreePool(Node);
  959. if (DevicePath == NULL) {
  960. Status = EFI_OUT_OF_RESOURCES;
  961. goto ON_ERROR;
  962. }
  963. //
  964. // Append URI device path node.
  965. //
  966. Node = AllocateZeroPool (sizeof (EFI_DEVICE_PATH_PROTOCOL));
  967. if (Node == NULL) {
  968. Status = EFI_OUT_OF_RESOURCES;
  969. goto ON_ERROR;
  970. }
  971. Node->DevPath.Type = MESSAGING_DEVICE_PATH;
  972. Node->DevPath.SubType = MSG_URI_DP;
  973. SetDevicePathNodeLength (Node, sizeof (EFI_DEVICE_PATH_PROTOCOL));
  974. Private->Ip6Nic->DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL*) Node);
  975. FreePool (Node);
  976. FreePool (DevicePath);
  977. if (Private->Ip6Nic->DevicePath == NULL) {
  978. Status = EFI_OUT_OF_RESOURCES;
  979. goto ON_ERROR;
  980. }
  981. //
  982. // Create a child handle for the HTTP boot and install DevPath and Load file protocol on it.
  983. //
  984. CopyMem (&Private->Ip6Nic->LoadFile, &gHttpBootDxeLoadFile, sizeof (Private->LoadFile));
  985. Status = gBS->InstallMultipleProtocolInterfaces (
  986. &Private->Ip6Nic->Controller,
  987. &gEfiLoadFileProtocolGuid,
  988. &Private->Ip6Nic->LoadFile,
  989. &gEfiDevicePathProtocolGuid,
  990. Private->Ip6Nic->DevicePath,
  991. NULL
  992. );
  993. if (EFI_ERROR (Status)) {
  994. goto ON_ERROR;
  995. }
  996. //
  997. // Open the Caller Id child to setup a parent-child relationship between
  998. // real NIC handle and the HTTP boot child handle.
  999. //
  1000. Status = gBS->OpenProtocol (
  1001. ControllerHandle,
  1002. &gEfiCallerIdGuid,
  1003. (VOID **) &Id,
  1004. This->DriverBindingHandle,
  1005. Private->Ip6Nic->Controller,
  1006. EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
  1007. );
  1008. if (EFI_ERROR (Status)) {
  1009. goto ON_ERROR;
  1010. }
  1011. return EFI_SUCCESS;
  1012. ON_ERROR:
  1013. if (Private != NULL) {
  1014. if (FirstStart) {
  1015. gBS->UninstallProtocolInterface (
  1016. ControllerHandle,
  1017. &gEfiCallerIdGuid,
  1018. &Private->Id
  1019. );
  1020. }
  1021. HttpBootDestroyIp6Children(This, Private);
  1022. HttpBootConfigFormUnload (Private);
  1023. if (FirstStart) {
  1024. FreePool (Private);
  1025. }
  1026. }
  1027. return Status;
  1028. }
  1029. /**
  1030. Stops a device controller or a bus controller.
  1031. The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
  1032. As a result, much of the error checking on the parameters to Stop() has been moved
  1033. into this common boot service. It is legal to call Stop() from other locations,
  1034. but the following calling restrictions must be followed, or the system behavior will not be deterministic.
  1035. 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
  1036. same driver's Start() function.
  1037. 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
  1038. EFI_HANDLE. In addition, all of these handles must have been created in this driver's
  1039. Start() function, and the Start() function must have called OpenProtocol() on
  1040. ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
  1041. @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
  1042. @param[in] ControllerHandle A handle to the device being stopped. The handle must
  1043. support a bus specific I/O protocol for the driver
  1044. to use to stop the device.
  1045. @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
  1046. @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
  1047. if NumberOfChildren is 0.
  1048. @retval EFI_SUCCESS The device was stopped.
  1049. @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
  1050. **/
  1051. EFI_STATUS
  1052. EFIAPI
  1053. HttpBootIp6DxeDriverBindingStop (
  1054. IN EFI_DRIVER_BINDING_PROTOCOL *This,
  1055. IN EFI_HANDLE ControllerHandle,
  1056. IN UINTN NumberOfChildren,
  1057. IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
  1058. )
  1059. {
  1060. EFI_STATUS Status;
  1061. EFI_LOAD_FILE_PROTOCOL *LoadFile;
  1062. HTTP_BOOT_PRIVATE_DATA *Private;
  1063. EFI_HANDLE NicHandle;
  1064. UINT32 *Id;
  1065. //
  1066. // Try to get the Load File Protocol from the controller handle.
  1067. //
  1068. Status = gBS->OpenProtocol (
  1069. ControllerHandle,
  1070. &gEfiLoadFileProtocolGuid,
  1071. (VOID **) &LoadFile,
  1072. This->DriverBindingHandle,
  1073. ControllerHandle,
  1074. EFI_OPEN_PROTOCOL_GET_PROTOCOL
  1075. );
  1076. if (EFI_ERROR (Status)) {
  1077. //
  1078. // If failed, try to find the NIC handle for this controller.
  1079. //
  1080. NicHandle = HttpBootGetNicByIp6Children (ControllerHandle);
  1081. if (NicHandle == NULL) {
  1082. return EFI_SUCCESS;
  1083. }
  1084. //
  1085. // Try to retrieve the private data by the Caller Id Guid.
  1086. //
  1087. Status = gBS->OpenProtocol (
  1088. NicHandle,
  1089. &gEfiCallerIdGuid,
  1090. (VOID **) &Id,
  1091. This->DriverBindingHandle,
  1092. ControllerHandle,
  1093. EFI_OPEN_PROTOCOL_GET_PROTOCOL
  1094. );
  1095. if (EFI_ERROR (Status)) {
  1096. return Status;
  1097. }
  1098. Private = HTTP_BOOT_PRIVATE_DATA_FROM_ID (Id);
  1099. } else {
  1100. Private = HTTP_BOOT_PRIVATE_DATA_FROM_LOADFILE (LoadFile);
  1101. NicHandle = Private->Controller;
  1102. }
  1103. //
  1104. // Disable the HTTP boot function.
  1105. //
  1106. Status = HttpBootStop (Private);
  1107. if (Status != EFI_SUCCESS && Status != EFI_NOT_STARTED) {
  1108. return Status;
  1109. }
  1110. //
  1111. // Destory all child instance and uninstall protocol interface.
  1112. //
  1113. HttpBootDestroyIp6Children (This, Private);
  1114. if (Private->Ip4Nic == NULL && Private->Ip6Nic == NULL) {
  1115. //
  1116. // Release the cached data.
  1117. //
  1118. HttpBootFreeCacheList (Private);
  1119. //
  1120. // Unload the config form.
  1121. //
  1122. HttpBootConfigFormUnload (Private);
  1123. gBS->UninstallProtocolInterface (
  1124. NicHandle,
  1125. &gEfiCallerIdGuid,
  1126. &Private->Id
  1127. );
  1128. FreePool (Private);
  1129. }
  1130. return EFI_SUCCESS;
  1131. }
  1132. /**
  1133. This is the declaration of an EFI image entry point. This entry point is
  1134. the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
  1135. both device drivers and bus drivers.
  1136. @param[in] ImageHandle The firmware allocated handle for the UEFI image.
  1137. @param[in] SystemTable A pointer to the EFI System Table.
  1138. @retval EFI_SUCCESS The operation completed successfully.
  1139. @retval Others An unexpected error occurred.
  1140. **/
  1141. EFI_STATUS
  1142. EFIAPI
  1143. HttpBootDxeDriverEntryPoint (
  1144. IN EFI_HANDLE ImageHandle,
  1145. IN EFI_SYSTEM_TABLE *SystemTable
  1146. )
  1147. {
  1148. EFI_STATUS Status;
  1149. //
  1150. // Install UEFI Driver Model protocol(s).
  1151. //
  1152. Status = EfiLibInstallDriverBindingComponentName2 (
  1153. ImageHandle,
  1154. SystemTable,
  1155. &gHttpBootIp4DxeDriverBinding,
  1156. ImageHandle,
  1157. &gHttpBootDxeComponentName,
  1158. &gHttpBootDxeComponentName2
  1159. );
  1160. if (EFI_ERROR (Status)) {
  1161. return Status;
  1162. }
  1163. Status = EfiLibInstallDriverBindingComponentName2 (
  1164. ImageHandle,
  1165. SystemTable,
  1166. &gHttpBootIp6DxeDriverBinding,
  1167. NULL,
  1168. &gHttpBootDxeComponentName,
  1169. &gHttpBootDxeComponentName2
  1170. );
  1171. if (EFI_ERROR (Status)) {
  1172. EfiLibUninstallDriverBindingComponentName2(
  1173. &gHttpBootIp4DxeDriverBinding,
  1174. &gHttpBootDxeComponentName,
  1175. &gHttpBootDxeComponentName2
  1176. );
  1177. }
  1178. return Status;
  1179. }