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