mirror of https://github.com/acidanthera/audk.git
242 lines
7.3 KiB
C
242 lines
7.3 KiB
C
/** @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
|
|
};
|