mirror of
https://github.com/ipxe/ipxe
synced 2026-01-30 16:40:24 +03:00
[iscsi] Allow iSCSI device to be described using an EFI device path
Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
@@ -15,6 +15,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||||||
|
|
||||||
struct net_device;
|
struct net_device;
|
||||||
struct uri;
|
struct uri;
|
||||||
|
struct iscsi_session;
|
||||||
struct aoe_device;
|
struct aoe_device;
|
||||||
struct usb_function;
|
struct usb_function;
|
||||||
|
|
||||||
@@ -25,6 +26,8 @@ extern EFI_DEVICE_PATH_PROTOCOL * efi_paths ( EFI_DEVICE_PATH_PROTOCOL *first,
|
|||||||
... );
|
... );
|
||||||
extern EFI_DEVICE_PATH_PROTOCOL * efi_netdev_path ( struct net_device *netdev );
|
extern EFI_DEVICE_PATH_PROTOCOL * efi_netdev_path ( struct net_device *netdev );
|
||||||
extern EFI_DEVICE_PATH_PROTOCOL * efi_uri_path ( struct uri *uri );
|
extern EFI_DEVICE_PATH_PROTOCOL * efi_uri_path ( struct uri *uri );
|
||||||
|
extern EFI_DEVICE_PATH_PROTOCOL *
|
||||||
|
efi_iscsi_path ( struct iscsi_session *iscsi );
|
||||||
extern EFI_DEVICE_PATH_PROTOCOL * efi_aoe_path ( struct aoe_device *aoedev );
|
extern EFI_DEVICE_PATH_PROTOCOL * efi_aoe_path ( struct aoe_device *aoedev );
|
||||||
extern EFI_DEVICE_PATH_PROTOCOL * efi_usb_path ( struct usb_function *func );
|
extern EFI_DEVICE_PATH_PROTOCOL * efi_usb_path ( struct usb_function *func );
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,9 @@
|
|||||||
#include <byteswap.h>
|
#include <byteswap.h>
|
||||||
#include <ipxe/netdevice.h>
|
#include <ipxe/netdevice.h>
|
||||||
#include <ipxe/vlan.h>
|
#include <ipxe/vlan.h>
|
||||||
|
#include <ipxe/tcpip.h>
|
||||||
#include <ipxe/uri.h>
|
#include <ipxe/uri.h>
|
||||||
|
#include <ipxe/iscsi.h>
|
||||||
#include <ipxe/aoe.h>
|
#include <ipxe/aoe.h>
|
||||||
#include <ipxe/usb.h>
|
#include <ipxe/usb.h>
|
||||||
#include <ipxe/efi/efi.h>
|
#include <ipxe/efi/efi.h>
|
||||||
@@ -221,6 +223,74 @@ EFI_DEVICE_PATH_PROTOCOL * efi_uri_path ( struct uri *uri ) {
|
|||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct EFI device path for iSCSI device
|
||||||
|
*
|
||||||
|
* @v iscsi iSCSI session
|
||||||
|
* @ret path EFI device path, or NULL on error
|
||||||
|
*/
|
||||||
|
EFI_DEVICE_PATH_PROTOCOL * efi_iscsi_path ( struct iscsi_session *iscsi ) {
|
||||||
|
struct sockaddr_tcpip *st_target;
|
||||||
|
struct net_device *netdev;
|
||||||
|
EFI_DEVICE_PATH_PROTOCOL *netpath;
|
||||||
|
EFI_DEVICE_PATH_PROTOCOL *path;
|
||||||
|
EFI_DEVICE_PATH_PROTOCOL *end;
|
||||||
|
ISCSI_DEVICE_PATH *iscsipath;
|
||||||
|
char *name;
|
||||||
|
size_t prefix_len;
|
||||||
|
size_t name_len;
|
||||||
|
size_t iscsi_len;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
/* Get network device associated with target address */
|
||||||
|
st_target = ( ( struct sockaddr_tcpip * ) &iscsi->target_sockaddr );
|
||||||
|
netdev = tcpip_netdev ( st_target );
|
||||||
|
if ( ! netdev )
|
||||||
|
goto err_netdev;
|
||||||
|
|
||||||
|
/* Get network device path */
|
||||||
|
netpath = efi_netdev_path ( netdev );
|
||||||
|
if ( ! netpath )
|
||||||
|
goto err_netpath;
|
||||||
|
|
||||||
|
/* Calculate device path length */
|
||||||
|
prefix_len = efi_path_len ( netpath );
|
||||||
|
name_len = ( strlen ( iscsi->target_iqn ) + 1 /* NUL */ );
|
||||||
|
iscsi_len = ( sizeof ( *iscsipath ) + name_len );
|
||||||
|
len = ( prefix_len + iscsi_len + sizeof ( *end ) );
|
||||||
|
|
||||||
|
/* Allocate device path */
|
||||||
|
path = zalloc ( len );
|
||||||
|
if ( ! path )
|
||||||
|
goto err_alloc;
|
||||||
|
|
||||||
|
/* Construct device path */
|
||||||
|
memcpy ( path, netpath, prefix_len );
|
||||||
|
iscsipath = ( ( ( void * ) path ) + prefix_len );
|
||||||
|
iscsipath->Header.Type = MESSAGING_DEVICE_PATH;
|
||||||
|
iscsipath->Header.SubType = MSG_ISCSI_DP;
|
||||||
|
iscsipath->Header.Length[0] = iscsi_len;
|
||||||
|
iscsipath->LoginOption = ISCSI_LOGIN_OPTION_AUTHMETHOD_NON;
|
||||||
|
memcpy ( &iscsipath->Lun, &iscsi->lun, sizeof ( iscsipath->Lun ) );
|
||||||
|
name = ( ( ( void * ) iscsipath ) + sizeof ( *iscsipath ) );
|
||||||
|
memcpy ( name, iscsi->target_iqn, name_len );
|
||||||
|
end = ( ( ( void * ) name ) + name_len );
|
||||||
|
end->Type = END_DEVICE_PATH_TYPE;
|
||||||
|
end->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
|
||||||
|
end->Length[0] = sizeof ( *end );
|
||||||
|
|
||||||
|
/* Free temporary paths */
|
||||||
|
free ( netpath );
|
||||||
|
|
||||||
|
return path;
|
||||||
|
|
||||||
|
err_alloc:
|
||||||
|
free ( netpath );
|
||||||
|
err_netpath:
|
||||||
|
err_netdev:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct EFI device path for AoE device
|
* Construct EFI device path for AoE device
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||||||
#include <ipxe/base16.h>
|
#include <ipxe/base16.h>
|
||||||
#include <ipxe/base64.h>
|
#include <ipxe/base64.h>
|
||||||
#include <ipxe/ibft.h>
|
#include <ipxe/ibft.h>
|
||||||
|
#include <ipxe/efi/efi_path.h>
|
||||||
#include <ipxe/iscsi.h>
|
#include <ipxe/iscsi.h>
|
||||||
|
|
||||||
/** @file
|
/** @file
|
||||||
@@ -1863,6 +1864,7 @@ static struct interface_operation iscsi_control_op[] = {
|
|||||||
INTF_OP ( xfer_window, struct iscsi_session *, iscsi_scsi_window ),
|
INTF_OP ( xfer_window, struct iscsi_session *, iscsi_scsi_window ),
|
||||||
INTF_OP ( intf_close, struct iscsi_session *, iscsi_close ),
|
INTF_OP ( intf_close, struct iscsi_session *, iscsi_close ),
|
||||||
INTF_OP ( acpi_describe, struct iscsi_session *, iscsi_describe ),
|
INTF_OP ( acpi_describe, struct iscsi_session *, iscsi_describe ),
|
||||||
|
EFI_INTF_OP ( efi_describe, struct iscsi_session *, efi_iscsi_path ),
|
||||||
};
|
};
|
||||||
|
|
||||||
/** iSCSI SCSI command-issuing interface descriptor */
|
/** iSCSI SCSI command-issuing interface descriptor */
|
||||||
|
|||||||
Reference in New Issue
Block a user