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