2 Implement the driver binding protocol for Asix AX88772 Ethernet driver.
4 Copyright (c) 2011, Intel Corporation
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 Verify the controller type
20 @param [in] pThis Protocol instance pointer.
21 @param [in] Controller Handle of device to test.
22 @param [in] pRemainingDevicePath Not used.
24 @retval EFI_SUCCESS This driver supports this device.
25 @retval other This driver does not support this device.
31 IN EFI_DRIVER_BINDING_PROTOCOL
* pThis
,
32 IN EFI_HANDLE Controller
,
33 IN EFI_DEVICE_PATH_PROTOCOL
* pRemainingDevicePath
36 EFI_USB_DEVICE_DESCRIPTOR Device
;
37 EFI_USB_IO_PROTOCOL
* pUsbIo
;
40 // Connect to the USB stack
42 Status
= gBS
->OpenProtocol (
44 &gEfiUsbIoProtocolGuid
,
46 pThis
->DriverBindingHandle
,
48 EFI_OPEN_PROTOCOL_BY_DRIVER
50 if (!EFI_ERROR ( Status
)) {
53 // Get the interface descriptor to check the USB class and find a transport
56 Status
= pUsbIo
->UsbGetDeviceDescriptor ( pUsbIo
, &Device
);
57 if (EFI_ERROR ( Status
)) {
58 Status
= EFI_UNSUPPORTED
;
62 // Validate the adapter
64 if ( VENDOR_ID
== Device
.IdVendor
) {
66 if (PRODUCT_ID
== Device
.IdProduct
) {
67 DEBUG ((EFI_D_INFO
, "Found the AX88772B\r\n"));
70 Status
= EFI_UNSUPPORTED
;
74 Status
= EFI_UNSUPPORTED
;
79 // Done with the USB stack
83 &gEfiUsbIoProtocolGuid
,
84 pThis
->DriverBindingHandle
,
93 Start this driver on Controller by opening UsbIo and DevicePath protocols.
94 Initialize PXE structures, create a copy of the Controller Device Path with the
95 NIC's MAC address appended to it, install the NetworkInterfaceIdentifier protocol
96 on the newly created Device Path.
98 @param [in] pThis Protocol instance pointer.
99 @param [in] Controller Handle of device to work with.
100 @param [in] pRemainingDevicePath Not used, always produce all possible children.
102 @retval EFI_SUCCESS This driver is added to Controller.
103 @retval other This driver does not support this device.
109 IN EFI_DRIVER_BINDING_PROTOCOL
* pThis
,
110 IN EFI_HANDLE Controller
,
111 IN EFI_DEVICE_PATH_PROTOCOL
* pRemainingDevicePath
116 NIC_DEVICE
*pNicDevice
;
118 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
= NULL
;
119 MAC_ADDR_DEVICE_PATH MacDeviceNode
;
122 // Allocate the device structure
124 LengthInBytes
= sizeof ( *pNicDevice
);
125 Status
= gBS
->AllocatePool (
126 EfiRuntimeServicesData
,
128 (VOID
**) &pNicDevice
131 if (EFI_ERROR (Status
)) {
132 DEBUG ((EFI_D_ERROR
, "gBS->AllocatePool:pNicDevice ERROR Status = %r\n", Status
));
137 // Set the structure signature
139 ZeroMem ( pNicDevice
, LengthInBytes
);
140 pNicDevice
->Signature
= DEV_SIGNATURE
;
142 Status
= gBS
->OpenProtocol (
144 &gEfiUsbIoProtocolGuid
,
145 (VOID
**) &pNicDevice
->pUsbIo
,
146 pThis
->DriverBindingHandle
,
148 EFI_OPEN_PROTOCOL_BY_DRIVER
151 if (EFI_ERROR (Status
)) {
152 DEBUG ((EFI_D_ERROR
, "gBS->OpenProtocol:EFI_USB_IO_PROTOCOL ERROR Status = %r\n", Status
));
153 gBS
->FreePool ( pNicDevice
);
158 // Initialize the simple network protocol
160 Status
= SN_Setup ( pNicDevice
);
162 if (EFI_ERROR(Status
)){
163 DEBUG ((EFI_D_ERROR
, "SN_Setup ERROR Status = %r\n", Status
));
166 &gEfiUsbIoProtocolGuid
,
167 pThis
->DriverBindingHandle
,
170 gBS
->FreePool ( pNicDevice
);
177 Status
= gBS
->OpenProtocol (
179 &gEfiDevicePathProtocolGuid
,
180 (VOID
**) &ParentDevicePath
,
181 pThis
->DriverBindingHandle
,
183 EFI_OPEN_PROTOCOL_BY_DRIVER
185 if (EFI_ERROR(Status
)) {
186 DEBUG ((EFI_D_ERROR
, "gBS->OpenProtocol:EFI_DEVICE_PATH_PROTOCOL error. Status = %r\n",
190 &gEfiUsbIoProtocolGuid
,
191 pThis
->DriverBindingHandle
,
194 gBS
->FreePool ( pNicDevice
);
198 ZeroMem (&MacDeviceNode
, sizeof (MAC_ADDR_DEVICE_PATH
));
199 MacDeviceNode
.Header
.Type
= MESSAGING_DEVICE_PATH
;
200 MacDeviceNode
.Header
.SubType
= MSG_MAC_ADDR_DP
;
202 SetDevicePathNodeLength (&MacDeviceNode
.Header
, sizeof (MAC_ADDR_DEVICE_PATH
));
204 CopyMem (&MacDeviceNode
.MacAddress
,
205 &pNicDevice
->SimpleNetworkData
.CurrentAddress
,
206 PXE_HWADDR_LEN_ETHER
);
208 MacDeviceNode
.IfType
= pNicDevice
->SimpleNetworkData
.IfType
;
210 pNicDevice
->MyDevPath
= AppendDevicePathNode (
212 (EFI_DEVICE_PATH_PROTOCOL
*) &MacDeviceNode
215 pNicDevice
->Controller
= NULL
;
218 // Install both the simple network and device path protocols.
220 Status
= gBS
->InstallMultipleProtocolInterfaces (
221 &pNicDevice
->Controller
,
224 &gEfiSimpleNetworkProtocolGuid
,
225 &pNicDevice
->SimpleNetwork
,
226 &gEfiDevicePathProtocolGuid
,
227 pNicDevice
->MyDevPath
,
231 if (EFI_ERROR(Status
)){
232 DEBUG ((EFI_D_ERROR
, "gBS->InstallMultipleProtocolInterfaces error. Status = %r\n",
236 &gEfiDevicePathProtocolGuid
,
237 pThis
->DriverBindingHandle
,
241 &gEfiUsbIoProtocolGuid
,
242 pThis
->DriverBindingHandle
,
245 gBS
->FreePool ( pNicDevice
);
250 // Open For Child Device
252 Status
= gBS
->OpenProtocol (
254 &gEfiUsbIoProtocolGuid
,
255 (VOID
**) &pNicDevice
->pUsbIo
,
256 pThis
->DriverBindingHandle
,
257 pNicDevice
->Controller
,
258 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
261 if (EFI_ERROR(Status
)){
262 gBS
->UninstallMultipleProtocolInterfaces (
263 &pNicDevice
->Controller
,
266 &gEfiSimpleNetworkProtocolGuid
,
267 &pNicDevice
->SimpleNetwork
,
268 &gEfiDevicePathProtocolGuid
,
269 pNicDevice
->MyDevPath
,
274 &gEfiDevicePathProtocolGuid
,
275 pThis
->DriverBindingHandle
,
279 &gEfiUsbIoProtocolGuid
,
280 pThis
->DriverBindingHandle
,
283 gBS
->FreePool ( pNicDevice
);
292 Stop this driver on Controller by removing NetworkInterfaceIdentifier protocol and
293 closing the DevicePath and PciIo protocols on Controller.
295 @param [in] pThis Protocol instance pointer.
296 @param [in] Controller Handle of device to stop driver on.
297 @param [in] NumberOfChildren How many children need to be stopped.
298 @param [in] pChildHandleBuffer Not used.
300 @retval EFI_SUCCESS This driver is removed Controller.
301 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
302 @retval other This driver was not removed from this device.
308 IN EFI_DRIVER_BINDING_PROTOCOL
* pThis
,
309 IN EFI_HANDLE Controller
,
310 IN UINTN NumberOfChildren
,
311 IN EFI_HANDLE
* ChildHandleBuffer
314 BOOLEAN AllChildrenStopped
;
316 EFI_SIMPLE_NETWORK_PROTOCOL
*SimpleNetwork
;
317 EFI_STATUS Status
= EFI_SUCCESS
;
318 NIC_DEVICE
*pNicDevice
;
321 // Complete all outstanding transactions to Controller.
322 // Don't allow any new transaction to Controller to be started.
324 if (NumberOfChildren
== 0) {
326 Status
= gBS
->OpenProtocol (
328 &gEfiSimpleNetworkProtocolGuid
,
329 (VOID
**) &SimpleNetwork
,
330 pThis
->DriverBindingHandle
,
332 EFI_OPEN_PROTOCOL_GET_PROTOCOL
335 if (EFI_ERROR(Status
)) {
337 // This is a 2nd type handle(multi-lun root), it needs to close devicepath
338 // and usbio protocol.
342 &gEfiDevicePathProtocolGuid
,
343 pThis
->DriverBindingHandle
,
348 &gEfiUsbIoProtocolGuid
,
349 pThis
->DriverBindingHandle
,
355 pNicDevice
= DEV_FROM_SIMPLE_NETWORK ( SimpleNetwork
);
357 Status
= gBS
->UninstallMultipleProtocolInterfaces (
361 &gEfiSimpleNetworkProtocolGuid
,
362 &pNicDevice
->SimpleNetwork
,
363 &gEfiDevicePathProtocolGuid
,
364 pNicDevice
->MyDevPath
,
368 if (EFI_ERROR (Status
)) {
372 // Close the bus driver
374 Status
= gBS
->CloseProtocol (
376 &gEfiDevicePathProtocolGuid
,
377 pThis
->DriverBindingHandle
,
381 if (EFI_ERROR(Status
)){
382 DEBUG ((EFI_D_ERROR
, "driver stop: gBS->CloseProtocol:EfiDevicePathProtocol error. Status %r\n", Status
));
385 Status
= gBS
->CloseProtocol (
387 &gEfiUsbIoProtocolGuid
,
388 pThis
->DriverBindingHandle
,
392 if (EFI_ERROR(Status
)){
393 DEBUG ((EFI_D_ERROR
, "driver stop: gBS->CloseProtocol:EfiUsbIoProtocol error. Status %r\n", Status
));
397 AllChildrenStopped
= TRUE
;
399 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
401 Status
= gBS
->OpenProtocol (
402 ChildHandleBuffer
[Index
],
403 &gEfiSimpleNetworkProtocolGuid
,
404 (VOID
**) &SimpleNetwork
,
405 pThis
->DriverBindingHandle
,
407 EFI_OPEN_PROTOCOL_GET_PROTOCOL
410 if (EFI_ERROR (Status
)) {
411 AllChildrenStopped
= FALSE
;
412 DEBUG ((EFI_D_ERROR
, "Fail to stop No.%d multi-lun child handle when opening SimpleNetwork\n", (UINT32
)Index
));
416 pNicDevice
= DEV_FROM_SIMPLE_NETWORK ( SimpleNetwork
);
420 &gEfiUsbIoProtocolGuid
,
421 pThis
->DriverBindingHandle
,
422 ChildHandleBuffer
[Index
]
425 Status
= gBS
->UninstallMultipleProtocolInterfaces (
426 ChildHandleBuffer
[Index
],
429 &gEfiSimpleNetworkProtocolGuid
,
430 &pNicDevice
->SimpleNetwork
,
431 &gEfiDevicePathProtocolGuid
,
432 pNicDevice
->MyDevPath
,
436 if (EFI_ERROR (Status
)) {
437 Status
= gBS
->OpenProtocol (
439 &gEfiUsbIoProtocolGuid
,
440 (VOID
**) &pNicDevice
->pUsbIo
,
441 pThis
->DriverBindingHandle
,
442 ChildHandleBuffer
[Index
],
443 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
448 RX_PKT
* pCurr
= pNicDevice
->QueueHead
;
451 for ( i
= 0 ; i
< MAX_QUEUE_SIZE
; i
++) {
452 if ( NULL
!= pCurr
) {
454 pCurr
= pCurr
->pNext
;
455 gBS
->FreePool (pFree
);
459 if ( NULL
!= pNicDevice
->pRxTest
)
460 gBS
->FreePool (pNicDevice
->pRxTest
);
462 if ( NULL
!= pNicDevice
->pTxTest
)
463 gBS
->FreePool (pNicDevice
->pTxTest
);
465 if ( NULL
!= pNicDevice
->MyDevPath
)
466 gBS
->FreePool (pNicDevice
->MyDevPath
);
468 if ( NULL
!= pNicDevice
)
469 gBS
->FreePool (pNicDevice
);
473 if (!AllChildrenStopped
) {
474 return EFI_DEVICE_ERROR
;
481 Driver binding protocol declaration
483 EFI_DRIVER_BINDING_PROTOCOL gDriverBinding
= {
494 Ax88772 driver unload routine.
496 @param [in] ImageHandle Handle for the image.
498 @retval EFI_SUCCESS Image may be unloaded
504 IN EFI_HANDLE ImageHandle
510 EFI_HANDLE
* pHandle
;
514 // Determine which devices are using this driver
518 Status
= gBS
->LocateHandle (
524 if ( EFI_BUFFER_TOO_SMALL
== Status
) {
527 // One or more block IO devices are present
529 Status
= gBS
->AllocatePool (
530 EfiRuntimeServicesData
,
534 if ( EFI_ERROR ( Status
)) {
535 DEBUG ((EFI_D_ERROR
, "Insufficient memory, failed handle buffer allocation\r\n"));
540 // Locate the block IO devices
542 Status
= gBS
->LocateHandle (
548 if ( EFI_ERROR ( Status
)) {
550 // Error getting handles
556 // Remove any use of the driver
558 Max
= BufferSize
/ sizeof ( pHandle
[ 0 ]);
559 for ( Index
= 0; Max
> Index
; Index
++ ) {
560 Status
= DriverStop ( &gDriverBinding
,
564 if ( EFI_ERROR ( Status
)) {
565 DEBUG ((EFI_D_ERROR
, "WARNING - Failed to shutdown the driver on handle %08x\r\n", pHandle
[ Index
]));
573 if ( EFI_NOT_FOUND
== Status
) {
575 // No devices were found
577 Status
= EFI_SUCCESS
;
582 // Free the handle array
584 if ( NULL
!= pHandle
) {
585 gBS
->FreePool ( pHandle
);
589 // Remove the protocols installed by the EntryPoint routine.
591 if ( !EFI_ERROR ( Status
)) {
592 gBS
->UninstallMultipleProtocolInterfaces (
594 &gEfiDriverBindingProtocolGuid
,
596 &gEfiComponentNameProtocolGuid
,
598 &gEfiComponentName2ProtocolGuid
,
603 DEBUG (( DEBUG_POOL
| DEBUG_INIT
| DEBUG_INFO
,
604 "Removed: gEfiComponentName2ProtocolGuid from 0x%08x\r\n",
606 DEBUG (( DEBUG_POOL
| DEBUG_INIT
| DEBUG_INFO
,
607 "Removed: gEfiComponentNameProtocolGuid from 0x%08x\r\n",
609 DEBUG (( DEBUG_POOL
| DEBUG_INIT
| DEBUG_INFO
,
610 "Removed: gEfiDriverBindingProtocolGuid from 0x%08x\r\n",
620 Ax88772 driver entry point.
622 @param [in] ImageHandle Handle for the image.
623 @param [in] pSystemTable Address of the system table.
625 @retval EFI_SUCCESS Image successfully loaded.
631 IN EFI_HANDLE ImageHandle
,
632 IN EFI_SYSTEM_TABLE
* pSystemTable
635 EFI_LOADED_IMAGE_PROTOCOL
* pLoadedImage
;
639 // Enable unload support
641 Status
= gBS
->HandleProtocol (
643 &gEfiLoadedImageProtocolGuid
,
644 (VOID
**)&pLoadedImage
646 if (!EFI_ERROR (Status
)) {
647 pLoadedImage
->Unload
= DriverUnload
;
651 // Add the driver to the list of drivers
653 Status
= EfiLibInstallDriverBindingComponentName2 (
661 if ( !EFI_ERROR ( Status
)) {
663 AsciiPrint ("Installed: gEfiDriverBindingProtocolGuid on 0x%08x\r\n",
665 AsciiPrint("Installed: gEfiComponentNameProtocolGuid on 0x%08x\r\n",
667 AsciiPrint("Installed: gEfiComponentName2ProtocolGuid on 0x%08x\r\n",