DriverBinding.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. /** @file
  2. Implement the driver binding protocol for Asix AX88772 Ethernet driver.
  3. Copyright (c) 2011-2013, Intel Corporation. All rights reserved.<BR>
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. **/
  6. #include "Ax88772.h"
  7. /**
  8. Verify the controller type
  9. @param [in] pThis Protocol instance pointer.
  10. @param [in] Controller Handle of device to test.
  11. @param [in] pRemainingDevicePath Not used.
  12. @retval EFI_SUCCESS This driver supports this device.
  13. @retval other This driver does not support this device.
  14. **/
  15. EFI_STATUS
  16. EFIAPI
  17. DriverSupported (
  18. IN EFI_DRIVER_BINDING_PROTOCOL * pThis,
  19. IN EFI_HANDLE Controller,
  20. IN EFI_DEVICE_PATH_PROTOCOL * pRemainingDevicePath
  21. )
  22. {
  23. EFI_USB_DEVICE_DESCRIPTOR Device;
  24. EFI_USB_IO_PROTOCOL * pUsbIo;
  25. EFI_STATUS Status;
  26. //
  27. // Connect to the USB stack
  28. //
  29. Status = gBS->OpenProtocol (
  30. Controller,
  31. &gEfiUsbIoProtocolGuid,
  32. (VOID **) &pUsbIo,
  33. pThis->DriverBindingHandle,
  34. Controller,
  35. EFI_OPEN_PROTOCOL_BY_DRIVER
  36. );
  37. if (!EFI_ERROR ( Status )) {
  38. //
  39. // Get the interface descriptor to check the USB class and find a transport
  40. // protocol handler.
  41. //
  42. Status = pUsbIo->UsbGetDeviceDescriptor ( pUsbIo, &Device );
  43. if (!EFI_ERROR ( Status )) {
  44. //
  45. // Validate the adapter
  46. //
  47. if (( VENDOR_ID != Device.IdVendor )
  48. || ( PRODUCT_ID != Device.IdProduct )) {
  49. Status = EFI_UNSUPPORTED;
  50. }
  51. }
  52. //
  53. // Done with the USB stack
  54. //
  55. gBS->CloseProtocol (
  56. Controller,
  57. &gEfiUsbIoProtocolGuid,
  58. pThis->DriverBindingHandle,
  59. Controller
  60. );
  61. }
  62. //
  63. // Return the device supported status
  64. //
  65. return Status;
  66. }
  67. /**
  68. Start this driver on Controller by opening UsbIo and DevicePath protocols.
  69. Initialize PXE structures, create a copy of the Controller Device Path with the
  70. NIC's MAC address appended to it, install the NetworkInterfaceIdentifier protocol
  71. on the newly created Device Path.
  72. @param [in] pThis Protocol instance pointer.
  73. @param [in] Controller Handle of device to work with.
  74. @param [in] pRemainingDevicePath Not used, always produce all possible children.
  75. @retval EFI_SUCCESS This driver is added to Controller.
  76. @retval other This driver does not support this device.
  77. **/
  78. EFI_STATUS
  79. EFIAPI
  80. DriverStart (
  81. IN EFI_DRIVER_BINDING_PROTOCOL * pThis,
  82. IN EFI_HANDLE Controller,
  83. IN EFI_DEVICE_PATH_PROTOCOL * pRemainingDevicePath
  84. )
  85. {
  86. EFI_STATUS Status;
  87. NIC_DEVICE * pNicDevice;
  88. UINTN LengthInBytes;
  89. DBG_ENTER ( );
  90. //
  91. // Allocate the device structure
  92. //
  93. LengthInBytes = sizeof ( *pNicDevice );
  94. Status = gBS->AllocatePool (
  95. EfiRuntimeServicesData,
  96. LengthInBytes,
  97. (VOID **) &pNicDevice
  98. );
  99. if ( !EFI_ERROR ( Status )) {
  100. DEBUG (( DEBUG_POOL | DEBUG_INIT,
  101. "0x%08x: Allocate pNicDevice, %d bytes\r\n",
  102. pNicDevice,
  103. sizeof ( *pNicDevice )));
  104. //
  105. // Set the structure signature
  106. //
  107. ZeroMem ( pNicDevice, LengthInBytes );
  108. pNicDevice->Signature = DEV_SIGNATURE;
  109. //
  110. // Connect to the USB I/O protocol
  111. //
  112. Status = gBS->OpenProtocol (
  113. Controller,
  114. &gEfiUsbIoProtocolGuid,
  115. (VOID **) &pNicDevice->pUsbIo,
  116. pThis->DriverBindingHandle,
  117. Controller,
  118. EFI_OPEN_PROTOCOL_BY_DRIVER
  119. );
  120. if ( !EFI_ERROR ( Status )) {
  121. //
  122. // Allocate the necessary events
  123. //
  124. Status = gBS->CreateEvent ( EVT_TIMER,
  125. TPL_AX88772,
  126. (EFI_EVENT_NOTIFY)Ax88772Timer,
  127. pNicDevice,
  128. (VOID **)&pNicDevice->Timer );
  129. if ( !EFI_ERROR ( Status )) {
  130. DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
  131. "0x%08x: Allocated timer\r\n",
  132. pNicDevice->Timer ));
  133. //
  134. // Initialize the simple network protocol
  135. //
  136. pNicDevice->Controller = Controller;
  137. SN_Setup ( pNicDevice );
  138. //
  139. // Start the timer
  140. //
  141. Status = gBS->SetTimer ( pNicDevice->Timer,
  142. TimerPeriodic,
  143. TIMER_MSEC );
  144. if ( !EFI_ERROR ( Status )) {
  145. //
  146. // Install both the simple network and device path protocols.
  147. //
  148. Status = gBS->InstallMultipleProtocolInterfaces (
  149. &Controller,
  150. &gEfiCallerIdGuid,
  151. pNicDevice,
  152. &gEfiSimpleNetworkProtocolGuid,
  153. &pNicDevice->SimpleNetwork,
  154. NULL
  155. );
  156. if ( !EFI_ERROR ( Status )) {
  157. DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
  158. "Installed: gEfiCallerIdGuid on 0x%08x\r\n",
  159. Controller ));
  160. DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
  161. "Installed: gEfiSimpleNetworkProtocolGuid on 0x%08x\r\n",
  162. Controller ));
  163. DBG_EXIT_STATUS ( Status );
  164. return Status;
  165. }
  166. DEBUG (( DEBUG_ERROR | DEBUG_INIT | DEBUG_INFO,
  167. "ERROR - Failed to install gEfiSimpleNetworkProtocol on 0x%08x\r\n",
  168. Controller ));
  169. }
  170. else {
  171. DEBUG (( DEBUG_ERROR | DEBUG_INIT | DEBUG_INFO,
  172. "ERROR - Failed to start the timer, Status: %r\r\n",
  173. Status ));
  174. }
  175. }
  176. else {
  177. DEBUG (( DEBUG_ERROR | DEBUG_INIT | DEBUG_INFO,
  178. "ERROR - Failed to create timer event, Status: %r\r\n",
  179. Status ));
  180. }
  181. //
  182. // Done with the USB stack
  183. //
  184. gBS->CloseProtocol (
  185. Controller,
  186. &gEfiUsbIoProtocolGuid,
  187. pThis->DriverBindingHandle,
  188. Controller
  189. );
  190. }
  191. //
  192. // Done with the device
  193. //
  194. gBS->FreePool ( pNicDevice );
  195. }
  196. //
  197. // Display the driver start status
  198. //
  199. DBG_EXIT_STATUS ( Status );
  200. return Status;
  201. }
  202. /**
  203. Stop this driver on Controller by removing NetworkInterfaceIdentifier protocol and
  204. closing the DevicePath and PciIo protocols on Controller.
  205. @param [in] pThis Protocol instance pointer.
  206. @param [in] Controller Handle of device to stop driver on.
  207. @param [in] NumberOfChildren How many children need to be stopped.
  208. @param [in] pChildHandleBuffer Not used.
  209. @retval EFI_SUCCESS This driver is removed Controller.
  210. @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
  211. @retval other This driver was not removed from this device.
  212. **/
  213. EFI_STATUS
  214. EFIAPI
  215. DriverStop (
  216. IN EFI_DRIVER_BINDING_PROTOCOL * pThis,
  217. IN EFI_HANDLE Controller,
  218. IN UINTN NumberOfChildren,
  219. IN EFI_HANDLE * pChildHandleBuffer
  220. )
  221. {
  222. NIC_DEVICE * pNicDevice;
  223. EFI_STATUS Status;
  224. DBG_ENTER ( );
  225. //
  226. // Determine if this driver is already attached
  227. //
  228. Status = gBS->OpenProtocol (
  229. Controller,
  230. &gEfiCallerIdGuid,
  231. (VOID **) &pNicDevice,
  232. pThis->DriverBindingHandle,
  233. Controller,
  234. EFI_OPEN_PROTOCOL_GET_PROTOCOL
  235. );
  236. if ( !EFI_ERROR ( Status )) {
  237. //
  238. // AX88772 driver is no longer running on this device
  239. //
  240. gBS->UninstallMultipleProtocolInterfaces (
  241. Controller,
  242. &gEfiSimpleNetworkProtocolGuid,
  243. &pNicDevice->SimpleNetwork,
  244. &gEfiCallerIdGuid,
  245. pNicDevice,
  246. NULL );
  247. DEBUG (( DEBUG_POOL | DEBUG_INIT,
  248. "Removed: gEfiSimpleNetworkProtocolGuid from 0x%08x\r\n",
  249. Controller ));
  250. DEBUG (( DEBUG_POOL | DEBUG_INIT,
  251. "Removed: gEfiCallerIdGuid from 0x%08x\r\n",
  252. Controller ));
  253. //
  254. // Stop the timer
  255. //
  256. if ( NULL != pNicDevice->Timer ) {
  257. gBS->SetTimer ( pNicDevice->Timer, TimerCancel, 0 );
  258. gBS->CloseEvent ( pNicDevice->Timer );
  259. DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
  260. "0x%08x: Released timer\r\n",
  261. pNicDevice->Timer ));
  262. }
  263. //
  264. // Done with the device context
  265. //
  266. DEBUG (( DEBUG_POOL | DEBUG_INIT,
  267. "0x%08x: Free pNicDevice, %d bytes\r\n",
  268. pNicDevice,
  269. sizeof ( *pNicDevice )));
  270. gBS->FreePool ( pNicDevice );
  271. }
  272. //
  273. // Return the shutdown status
  274. //
  275. DBG_EXIT_STATUS ( Status );
  276. return Status;
  277. }
  278. /**
  279. Driver binding protocol declaration
  280. **/
  281. EFI_DRIVER_BINDING_PROTOCOL gDriverBinding = {
  282. DriverSupported,
  283. DriverStart,
  284. DriverStop,
  285. 0xa,
  286. NULL,
  287. NULL
  288. };
  289. /**
  290. Ax88772 driver unload routine.
  291. @param [in] ImageHandle Handle for the image.
  292. @retval EFI_SUCCESS Image may be unloaded
  293. **/
  294. EFI_STATUS
  295. EFIAPI
  296. DriverUnload (
  297. IN EFI_HANDLE ImageHandle
  298. )
  299. {
  300. UINTN BufferSize;
  301. UINTN Index;
  302. UINTN Max;
  303. EFI_HANDLE * pHandle;
  304. EFI_STATUS Status;
  305. //
  306. // Determine which devices are using this driver
  307. //
  308. BufferSize = 0;
  309. pHandle = NULL;
  310. Status = gBS->LocateHandle (
  311. ByProtocol,
  312. &gEfiCallerIdGuid,
  313. NULL,
  314. &BufferSize,
  315. NULL );
  316. if ( EFI_BUFFER_TOO_SMALL == Status ) {
  317. for ( ; ; ) {
  318. //
  319. // One or more block IO devices are present
  320. //
  321. Status = gBS->AllocatePool (
  322. EfiRuntimeServicesData,
  323. BufferSize,
  324. (VOID **) &pHandle
  325. );
  326. if ( EFI_ERROR ( Status )) {
  327. DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
  328. "Insufficient memory, failed handle buffer allocation\r\n" ));
  329. break;
  330. }
  331. //
  332. // Locate the block IO devices
  333. //
  334. Status = gBS->LocateHandle (
  335. ByProtocol,
  336. &gEfiCallerIdGuid,
  337. NULL,
  338. &BufferSize,
  339. pHandle );
  340. if ( EFI_ERROR ( Status )) {
  341. //
  342. // Error getting handles
  343. //
  344. DEBUG (( DEBUG_ERROR | DEBUG_INIT | DEBUG_INFO,
  345. "Failure getting Telnet handles\r\n" ));
  346. break;
  347. }
  348. //
  349. // Remove any use of the driver
  350. //
  351. Max = BufferSize / sizeof ( pHandle[ 0 ]);
  352. for ( Index = 0; Max > Index; Index++ ) {
  353. Status = DriverStop ( &gDriverBinding,
  354. pHandle[ Index ],
  355. 0,
  356. NULL );
  357. if ( EFI_ERROR ( Status )) {
  358. DEBUG (( DEBUG_WARN | DEBUG_INIT | DEBUG_INFO,
  359. "WARNING - Failed to shutdown the driver on handle %08x\r\n", pHandle[ Index ]));
  360. break;
  361. }
  362. }
  363. break;
  364. }
  365. }
  366. else {
  367. if ( EFI_NOT_FOUND == Status ) {
  368. //
  369. // No devices were found
  370. //
  371. Status = EFI_SUCCESS;
  372. }
  373. }
  374. //
  375. // Free the handle array
  376. //
  377. if ( NULL != pHandle ) {
  378. gBS->FreePool ( pHandle );
  379. }
  380. //
  381. // Remove the protocols installed by the EntryPoint routine.
  382. //
  383. if ( !EFI_ERROR ( Status )) {
  384. gBS->UninstallMultipleProtocolInterfaces (
  385. ImageHandle,
  386. &gEfiDriverBindingProtocolGuid,
  387. &gDriverBinding,
  388. &gEfiComponentNameProtocolGuid,
  389. &gComponentName,
  390. &gEfiComponentName2ProtocolGuid,
  391. &gComponentName2,
  392. NULL
  393. );
  394. DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
  395. "Removed: gEfiComponentName2ProtocolGuid from 0x%08x\r\n",
  396. ImageHandle ));
  397. DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
  398. "Removed: gEfiComponentNameProtocolGuid from 0x%08x\r\n",
  399. ImageHandle ));
  400. DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
  401. "Removed: gEfiDriverBindingProtocolGuid from 0x%08x\r\n",
  402. ImageHandle ));
  403. }
  404. //
  405. // Return the unload status
  406. //
  407. return Status;
  408. }
  409. /**
  410. Ax88772 driver entry point.
  411. @param [in] ImageHandle Handle for the image.
  412. @param [in] pSystemTable Address of the system table.
  413. @retval EFI_SUCCESS Image successfully loaded.
  414. **/
  415. EFI_STATUS
  416. EFIAPI
  417. EntryPoint (
  418. IN EFI_HANDLE ImageHandle,
  419. IN EFI_SYSTEM_TABLE * pSystemTable
  420. )
  421. {
  422. EFI_STATUS Status;
  423. DBG_ENTER ( );
  424. //
  425. // Add the driver to the list of drivers
  426. //
  427. Status = EfiLibInstallDriverBindingComponentName2 (
  428. ImageHandle,
  429. pSystemTable,
  430. &gDriverBinding,
  431. ImageHandle,
  432. &gComponentName,
  433. &gComponentName2
  434. );
  435. ASSERT_EFI_ERROR (Status);
  436. if ( !EFI_ERROR ( Status )) {
  437. DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
  438. "Installed: gEfiDriverBindingProtocolGuid on 0x%08x\r\n",
  439. ImageHandle ));
  440. DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
  441. "Installed: gEfiComponentNameProtocolGuid on 0x%08x\r\n",
  442. ImageHandle ));
  443. DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
  444. "Installed: gEfiComponentName2ProtocolGuid on 0x%08x\r\n",
  445. ImageHandle ));
  446. }
  447. DBG_EXIT_STATUS ( Status );
  448. return Status;
  449. }