2 Implement the driver binding protocol for Asix AX88772 Ethernet driver.
4 Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
5 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
;
41 // Connect to the USB stack
43 Status
= gBS
->OpenProtocol (
45 &gEfiUsbIoProtocolGuid
,
47 pThis
->DriverBindingHandle
,
49 EFI_OPEN_PROTOCOL_BY_DRIVER
51 if (!EFI_ERROR ( Status
)) {
54 // Get the interface descriptor to check the USB class and find a transport
57 Status
= pUsbIo
->UsbGetDeviceDescriptor ( pUsbIo
, &Device
);
58 if (!EFI_ERROR ( Status
)) {
61 // Validate the adapter
63 if (( VENDOR_ID
!= Device
.IdVendor
)
64 || ( PRODUCT_ID
!= Device
.IdProduct
)) {
65 Status
= EFI_UNSUPPORTED
;
70 // Done with the USB stack
74 &gEfiUsbIoProtocolGuid
,
75 pThis
->DriverBindingHandle
,
81 // Return the device supported status
88 Start this driver on Controller by opening UsbIo and DevicePath protocols.
89 Initialize PXE structures, create a copy of the Controller Device Path with the
90 NIC's MAC address appended to it, install the NetworkInterfaceIdentifier protocol
91 on the newly created Device Path.
93 @param [in] pThis Protocol instance pointer.
94 @param [in] Controller Handle of device to work with.
95 @param [in] pRemainingDevicePath Not used, always produce all possible children.
97 @retval EFI_SUCCESS This driver is added to Controller.
98 @retval other This driver does not support this device.
104 IN EFI_DRIVER_BINDING_PROTOCOL
* pThis
,
105 IN EFI_HANDLE Controller
,
106 IN EFI_DEVICE_PATH_PROTOCOL
* pRemainingDevicePath
110 NIC_DEVICE
* pNicDevice
;
116 // Allocate the device structure
118 LengthInBytes
= sizeof ( *pNicDevice
);
119 Status
= gBS
->AllocatePool (
120 EfiRuntimeServicesData
,
122 (VOID
**) &pNicDevice
124 if ( !EFI_ERROR ( Status
)) {
125 DEBUG (( DEBUG_POOL
| DEBUG_INIT
,
126 "0x%08x: Allocate pNicDevice, %d bytes\r\n",
128 sizeof ( *pNicDevice
)));
131 // Set the structure signature
133 ZeroMem ( pNicDevice
, LengthInBytes
);
134 pNicDevice
->Signature
= DEV_SIGNATURE
;
137 // Connect to the USB I/O protocol
139 Status
= gBS
->OpenProtocol (
141 &gEfiUsbIoProtocolGuid
,
142 (VOID
**) &pNicDevice
->pUsbIo
,
143 pThis
->DriverBindingHandle
,
145 EFI_OPEN_PROTOCOL_BY_DRIVER
148 if ( !EFI_ERROR ( Status
)) {
150 // Allocate the necessary events
152 Status
= gBS
->CreateEvent ( EVT_TIMER
,
154 (EFI_EVENT_NOTIFY
)Ax88772Timer
,
156 (VOID
**)&pNicDevice
->Timer
);
157 if ( !EFI_ERROR ( Status
)) {
158 DEBUG (( DEBUG_POOL
| DEBUG_INIT
| DEBUG_INFO
,
159 "0x%08x: Allocated timer\r\n",
160 pNicDevice
->Timer
));
163 // Initialize the simple network protocol
165 pNicDevice
->Controller
= Controller
;
166 SN_Setup ( pNicDevice
);
171 Status
= gBS
->SetTimer ( pNicDevice
->Timer
,
174 if ( !EFI_ERROR ( Status
)) {
176 // Install both the simple network and device path protocols.
178 Status
= gBS
->InstallMultipleProtocolInterfaces (
182 &gEfiSimpleNetworkProtocolGuid
,
183 &pNicDevice
->SimpleNetwork
,
187 if ( !EFI_ERROR ( Status
)) {
188 DEBUG (( DEBUG_POOL
| DEBUG_INIT
| DEBUG_INFO
,
189 "Installed: gEfiCallerIdGuid on 0x%08x\r\n",
191 DEBUG (( DEBUG_POOL
| DEBUG_INIT
| DEBUG_INFO
,
192 "Installed: gEfiSimpleNetworkProtocolGuid on 0x%08x\r\n",
194 DBG_EXIT_STATUS ( Status
);
197 DEBUG (( DEBUG_ERROR
| DEBUG_INIT
| DEBUG_INFO
,
198 "ERROR - Failed to install gEfiSimpleNetworkProtocol on 0x%08x\r\n",
202 DEBUG (( DEBUG_ERROR
| DEBUG_INIT
| DEBUG_INFO
,
203 "ERROR - Failed to start the timer, Status: %r\r\n",
208 DEBUG (( DEBUG_ERROR
| DEBUG_INIT
| DEBUG_INFO
,
209 "ERROR - Failed to create timer event, Status: %r\r\n",
214 // Done with the USB stack
218 &gEfiUsbIoProtocolGuid
,
219 pThis
->DriverBindingHandle
,
225 // Done with the device
227 gBS
->FreePool ( pNicDevice
);
231 // Display the driver start status
233 DBG_EXIT_STATUS ( Status
);
239 Stop this driver on Controller by removing NetworkInterfaceIdentifier protocol and
240 closing the DevicePath and PciIo protocols on Controller.
242 @param [in] pThis Protocol instance pointer.
243 @param [in] Controller Handle of device to stop driver on.
244 @param [in] NumberOfChildren How many children need to be stopped.
245 @param [in] pChildHandleBuffer Not used.
247 @retval EFI_SUCCESS This driver is removed Controller.
248 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
249 @retval other This driver was not removed from this device.
255 IN EFI_DRIVER_BINDING_PROTOCOL
* pThis
,
256 IN EFI_HANDLE Controller
,
257 IN UINTN NumberOfChildren
,
258 IN EFI_HANDLE
* pChildHandleBuffer
261 NIC_DEVICE
* pNicDevice
;
267 // Determine if this driver is already attached
269 Status
= gBS
->OpenProtocol (
272 (VOID
**) &pNicDevice
,
273 pThis
->DriverBindingHandle
,
275 EFI_OPEN_PROTOCOL_GET_PROTOCOL
277 if ( !EFI_ERROR ( Status
)) {
279 // AX88772 driver is no longer running on this device
281 gBS
->UninstallMultipleProtocolInterfaces (
283 &gEfiSimpleNetworkProtocolGuid
,
284 &pNicDevice
->SimpleNetwork
,
288 DEBUG (( DEBUG_POOL
| DEBUG_INIT
,
289 "Removed: gEfiSimpleNetworkProtocolGuid from 0x%08x\r\n",
291 DEBUG (( DEBUG_POOL
| DEBUG_INIT
,
292 "Removed: gEfiCallerIdGuid from 0x%08x\r\n",
298 if ( NULL
!= pNicDevice
->Timer
) {
299 gBS
->SetTimer ( pNicDevice
->Timer
, TimerCancel
, 0 );
300 gBS
->CloseEvent ( pNicDevice
->Timer
);
301 DEBUG (( DEBUG_POOL
| DEBUG_INIT
| DEBUG_INFO
,
302 "0x%08x: Released timer\r\n",
303 pNicDevice
->Timer
));
307 // Done with the device context
309 DEBUG (( DEBUG_POOL
| DEBUG_INIT
,
310 "0x%08x: Free pNicDevice, %d bytes\r\n",
312 sizeof ( *pNicDevice
)));
313 gBS
->FreePool ( pNicDevice
);
317 // Return the shutdown status
319 DBG_EXIT_STATUS ( Status
);
325 Driver binding protocol declaration
327 EFI_DRIVER_BINDING_PROTOCOL gDriverBinding
= {
338 Ax88772 driver unload routine.
340 @param [in] ImageHandle Handle for the image.
342 @retval EFI_SUCCESS Image may be unloaded
348 IN EFI_HANDLE ImageHandle
354 EFI_HANDLE
* pHandle
;
358 // Determine which devices are using this driver
362 Status
= gBS
->LocateHandle (
368 if ( EFI_BUFFER_TOO_SMALL
== Status
) {
371 // One or more block IO devices are present
373 Status
= gBS
->AllocatePool (
374 EfiRuntimeServicesData
,
378 if ( EFI_ERROR ( Status
)) {
379 DEBUG (( DEBUG_ERROR
| DEBUG_POOL
| DEBUG_INIT
| DEBUG_INFO
,
380 "Insufficient memory, failed handle buffer allocation\r\n" ));
385 // Locate the block IO devices
387 Status
= gBS
->LocateHandle (
393 if ( EFI_ERROR ( Status
)) {
395 // Error getting handles
397 DEBUG (( DEBUG_ERROR
| DEBUG_INIT
| DEBUG_INFO
,
398 "Failure getting Telnet handles\r\n" ));
403 // Remove any use of the driver
405 Max
= BufferSize
/ sizeof ( pHandle
[ 0 ]);
406 for ( Index
= 0; Max
> Index
; Index
++ ) {
407 Status
= DriverStop ( &gDriverBinding
,
411 if ( EFI_ERROR ( Status
)) {
412 DEBUG (( DEBUG_WARN
| DEBUG_INIT
| DEBUG_INFO
,
413 "WARNING - Failed to shutdown the driver on handle %08x\r\n", pHandle
[ Index
]));
421 if ( EFI_NOT_FOUND
== Status
) {
423 // No devices were found
425 Status
= EFI_SUCCESS
;
430 // Free the handle array
432 if ( NULL
!= pHandle
) {
433 gBS
->FreePool ( pHandle
);
437 // Remove the protocols installed by the EntryPoint routine.
439 if ( !EFI_ERROR ( Status
)) {
440 gBS
->UninstallMultipleProtocolInterfaces (
442 &gEfiDriverBindingProtocolGuid
,
444 &gEfiComponentNameProtocolGuid
,
446 &gEfiComponentName2ProtocolGuid
,
450 DEBUG (( DEBUG_POOL
| DEBUG_INIT
| DEBUG_INFO
,
451 "Removed: gEfiComponentName2ProtocolGuid from 0x%08x\r\n",
453 DEBUG (( DEBUG_POOL
| DEBUG_INIT
| DEBUG_INFO
,
454 "Removed: gEfiComponentNameProtocolGuid from 0x%08x\r\n",
456 DEBUG (( DEBUG_POOL
| DEBUG_INIT
| DEBUG_INFO
,
457 "Removed: gEfiDriverBindingProtocolGuid from 0x%08x\r\n",
462 // Return the unload status
469 Ax88772 driver entry point.
471 @param [in] ImageHandle Handle for the image.
472 @param [in] pSystemTable Address of the system table.
474 @retval EFI_SUCCESS Image successfully loaded.
480 IN EFI_HANDLE ImageHandle
,
481 IN EFI_SYSTEM_TABLE
* pSystemTable
484 EFI_LOADED_IMAGE_PROTOCOL
* pLoadedImage
;
490 // Enable unload support
492 Status
= gBS
->HandleProtocol (
494 &gEfiLoadedImageProtocolGuid
,
495 (VOID
**)&pLoadedImage
497 if (!EFI_ERROR (Status
)) {
498 pLoadedImage
->Unload
= DriverUnload
;
502 // Add the driver to the list of drivers
504 Status
= EfiLibInstallDriverBindingComponentName2 (
512 ASSERT_EFI_ERROR (Status
);
513 if ( !EFI_ERROR ( Status
)) {
514 DEBUG (( DEBUG_POOL
| DEBUG_INIT
| DEBUG_INFO
,
515 "Installed: gEfiDriverBindingProtocolGuid on 0x%08x\r\n",
517 DEBUG (( DEBUG_POOL
| DEBUG_INIT
| DEBUG_INFO
,
518 "Installed: gEfiComponentNameProtocolGuid on 0x%08x\r\n",
520 DEBUG (( DEBUG_POOL
| DEBUG_INIT
| DEBUG_INFO
,
521 "Installed: gEfiComponentName2ProtocolGuid on 0x%08x\r\n",
524 DBG_EXIT_STATUS ( Status
);