| /** @file | |
| Implement the driver binding protocol for the socket layer. | |
| Copyright (c) 2011, Intel Corporation | |
| All rights reserved. This program and the accompanying materials | |
| are licensed and made available under the terms and conditions of the BSD License | |
| which accompanies this distribution. The full text of the license may be found at | |
| http://opensource.org/licenses/bsd-license.php | |
| THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
| WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
| \section NetworkAdapterManagement Network Adapter Management | |
| Network adapters may come and go over the life if a system running | |
| UEFI. The SocketDxe driver uses the driver binding API to manage | |
| the connections to network adapters. | |
| The ::DriverSupported routine selects network adapters that the | |
| socket layer is not using. This determination by the lack of the | |
| tag GUID associated with the network protocol in the | |
| ::cEslSocketBinding array. The selected network adapters are | |
| passed to the ::DriverStart routine. | |
| The ::DriverStart routine calls the ::EslServiceConnect routine | |
| to create an ::ESL_SERVICE structure to manage the network adapter | |
| for the socket layer. EslServiceConnect also installs the tag | |
| GUID on the network adapter to prevent future calls from | |
| ::DriverSupported. EslService also calls the network specific | |
| initialization routine listed in ESL_SOCKET_BINDING::pfnInitialize | |
| field of the ::cEslSocketBinding entry. | |
| The ::DriverStop routine calls the ::EslServiceDisconnect routine | |
| to undo the work done by ::DriverStart. The socket layer must break | |
| the active network connections, then remove the tag GUIDs from the | |
| controller handle and free ::ESL_SERVICE structure. | |
| **/ | |
| #include "Socket.h" | |
| /** | |
| Verify the controller type | |
| This routine walks the cEslSocketBinding array to determines if | |
| the controller is a network adapter by supporting any of the | |
| network protocols required by the sockets layer. If so, the | |
| routine verifies that the socket layer is not already using the | |
| support by looking for the tag GUID listed in the corresponding | |
| array entry. The controller handle is passed to the ::DriverStart | |
| routine if sockets can use the network adapter. | |
| See the \ref NetworkAdapterManagement section. | |
| This routine is called by the UEFI driver framework during connect | |
| processing. | |
| @param [in] pThis Protocol instance pointer. | |
| @param [in] Controller Handle of device to test. | |
| @param [in] pRemainingDevicePath Not used. | |
| @retval EFI_SUCCESS This driver supports this device. | |
| @retval other This driver does not support this device. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| DriverSupported ( | |
| IN EFI_DRIVER_BINDING_PROTOCOL * pThis, | |
| IN EFI_HANDLE Controller, | |
| IN EFI_DEVICE_PATH_PROTOCOL * pRemainingDevicePath | |
| ) | |
| { | |
| CONST ESL_SOCKET_BINDING * pEnd; | |
| VOID * pInterface; | |
| CONST ESL_SOCKET_BINDING * pSocketBinding; | |
| EFI_STATUS Status; | |
| // | |
| // Assume the list is empty | |
| // | |
| Status = EFI_UNSUPPORTED; | |
| // | |
| // Walk the list of network connection points | |
| // | |
| pSocketBinding = &cEslSocketBinding[0]; | |
| pEnd = &pSocketBinding[ cEslSocketBindingEntries ]; | |
| while ( pEnd > pSocketBinding ) { | |
| // | |
| // Determine if the controller supports the network protocol | |
| // | |
| Status = gBS->OpenProtocol ( | |
| Controller, | |
| pSocketBinding->pNetworkBinding, | |
| &pInterface, | |
| pThis->DriverBindingHandle, | |
| Controller, | |
| EFI_OPEN_PROTOCOL_GET_PROTOCOL | |
| ); | |
| if ( !EFI_ERROR ( Status )) { | |
| // | |
| // Determine if the driver is already connected | |
| // | |
| Status = gBS->OpenProtocol ( | |
| Controller, | |
| (EFI_GUID *)pSocketBinding->pTagGuid, | |
| &pInterface, | |
| pThis->DriverBindingHandle, | |
| Controller, | |
| EFI_OPEN_PROTOCOL_GET_PROTOCOL | |
| ); | |
| if ( !EFI_ERROR ( Status )) { | |
| Status = EFI_ALREADY_STARTED; | |
| } | |
| else { | |
| if ( EFI_UNSUPPORTED == Status ) { | |
| // | |
| // Connect the driver since the tag is not present | |
| // | |
| Status = EFI_SUCCESS; | |
| } | |
| } | |
| } | |
| // | |
| // Set the next network protocol | |
| // | |
| pSocketBinding += 1; | |
| } | |
| // | |
| // Return the device supported status | |
| // | |
| return Status; | |
| } | |
| /** | |
| Connect to a network adapter | |
| This routine calls ::EslServiceConnect to connect the socket | |
| layer to the network adapters. See the \ref NetworkAdapterManagement | |
| section. | |
| This routine is called by the UEFI driver framework during connect | |
| processing if the controller passes the tests in ::DriverSupported. | |
| @param [in] pThis Protocol instance pointer. | |
| @param [in] Controller Handle of device to work with. | |
| @param [in] pRemainingDevicePath Not used, always produce all possible children. | |
| @retval EFI_SUCCESS This driver is added to Controller. | |
| @retval other This driver does not support this device. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| DriverStart ( | |
| IN EFI_DRIVER_BINDING_PROTOCOL * pThis, | |
| IN EFI_HANDLE Controller, | |
| IN EFI_DEVICE_PATH_PROTOCOL * pRemainingDevicePath | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| DBG_ENTER ( ); | |
| // | |
| // Connect to this network adapter | |
| // | |
| Status = EslServiceConnect ( pThis->DriverBindingHandle, | |
| Controller ); | |
| // | |
| // Display the driver start status | |
| // | |
| DBG_EXIT_STATUS ( Status ); | |
| return Status; | |
| } | |
| /** | |
| Disconnect from a network adapter | |
| This routine calls ::EslServiceDisconnect to disconnect the socket | |
| layer from the network adapters. See the \ref NetworkAdapterManagement | |
| section. | |
| This routine is called by ::DriverUnload when the socket layer | |
| is being unloaded. This routine should also called by the UEFI | |
| driver framework when a network adapter is being unloaded from | |
| the system. | |
| @param [in] pThis Protocol instance pointer. | |
| @param [in] Controller Handle of device to stop driver on. | |
| @param [in] NumberOfChildren How many children need to be stopped. | |
| @param [in] pChildHandleBuffer Not used. | |
| @retval EFI_SUCCESS This driver is removed Controller. | |
| @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error. | |
| @retval other This driver was not removed from this device. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| DriverStop ( | |
| IN EFI_DRIVER_BINDING_PROTOCOL * pThis, | |
| IN EFI_HANDLE Controller, | |
| IN UINTN NumberOfChildren, | |
| IN EFI_HANDLE * pChildHandleBuffer | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| DBG_ENTER ( ); | |
| // | |
| // Disconnect the network adapters | |
| // | |
| Status = EslServiceDisconnect ( pThis->DriverBindingHandle, | |
| Controller ); | |
| // | |
| // Display the driver start status | |
| // | |
| DBG_EXIT_STATUS ( Status ); | |
| return Status; | |
| } | |
| /** | |
| Driver binding protocol for the SocketDxe driver. | |
| **/ | |
| EFI_DRIVER_BINDING_PROTOCOL mDriverBinding = { | |
| DriverSupported, | |
| DriverStart, | |
| DriverStop, | |
| 0xa, | |
| NULL, | |
| NULL | |
| }; |