mirror of
https://github.com/ipxe/ipxe
synced 2025-12-20 03:55:46 +03:00
[fcp] Allow Fibre Channel device to be described using an EFI device path
Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
@@ -17,6 +17,7 @@ struct net_device;
|
|||||||
struct uri;
|
struct uri;
|
||||||
struct iscsi_session;
|
struct iscsi_session;
|
||||||
struct aoe_device;
|
struct aoe_device;
|
||||||
|
struct fcp_description;
|
||||||
struct usb_function;
|
struct usb_function;
|
||||||
|
|
||||||
extern EFI_DEVICE_PATH_PROTOCOL *
|
extern EFI_DEVICE_PATH_PROTOCOL *
|
||||||
@@ -29,6 +30,7 @@ extern EFI_DEVICE_PATH_PROTOCOL * efi_uri_path ( struct uri *uri );
|
|||||||
extern EFI_DEVICE_PATH_PROTOCOL *
|
extern EFI_DEVICE_PATH_PROTOCOL *
|
||||||
efi_iscsi_path ( struct iscsi_session *iscsi );
|
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_fcp_path ( struct fcp_description *desc );
|
||||||
extern EFI_DEVICE_PATH_PROTOCOL * efi_usb_path ( struct usb_function *func );
|
extern EFI_DEVICE_PATH_PROTOCOL * efi_usb_path ( struct usb_function *func );
|
||||||
|
|
||||||
extern EFI_DEVICE_PATH_PROTOCOL * efi_describe ( struct interface *interface );
|
extern EFI_DEVICE_PATH_PROTOCOL * efi_describe ( struct interface *interface );
|
||||||
|
|||||||
@@ -163,4 +163,12 @@ struct fcp_prli_service_parameters {
|
|||||||
/** Enhanced discovery supported */
|
/** Enhanced discovery supported */
|
||||||
#define FCP_PRLI_ENH_DISC 0x0800
|
#define FCP_PRLI_ENH_DISC 0x0800
|
||||||
|
|
||||||
|
/** An FCP device description */
|
||||||
|
struct fcp_description {
|
||||||
|
/** Fibre Channel WWN */
|
||||||
|
struct fc_name wwn;
|
||||||
|
/** SCSI LUN */
|
||||||
|
struct scsi_lun lun;
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* _IPXE_FCP_H */
|
#endif /* _IPXE_FCP_H */
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
#include <ipxe/uri.h>
|
#include <ipxe/uri.h>
|
||||||
#include <ipxe/iscsi.h>
|
#include <ipxe/iscsi.h>
|
||||||
#include <ipxe/aoe.h>
|
#include <ipxe/aoe.h>
|
||||||
|
#include <ipxe/fcp.h>
|
||||||
#include <ipxe/usb.h>
|
#include <ipxe/usb.h>
|
||||||
#include <ipxe/efi/efi.h>
|
#include <ipxe/efi/efi.h>
|
||||||
#include <ipxe/efi/efi_driver.h>
|
#include <ipxe/efi/efi_driver.h>
|
||||||
@@ -337,6 +338,36 @@ EFI_DEVICE_PATH_PROTOCOL * efi_aoe_path ( struct aoe_device *aoedev ) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct EFI device path for Fibre Channel device
|
||||||
|
*
|
||||||
|
* @v desc FCP device description
|
||||||
|
* @ret path EFI device path, or NULL on error
|
||||||
|
*/
|
||||||
|
EFI_DEVICE_PATH_PROTOCOL * efi_fcp_path ( struct fcp_description *desc ) {
|
||||||
|
struct {
|
||||||
|
FIBRECHANNELEX_DEVICE_PATH fc;
|
||||||
|
EFI_DEVICE_PATH_PROTOCOL end;
|
||||||
|
} __attribute__ (( packed )) *path;
|
||||||
|
|
||||||
|
/* Allocate device path */
|
||||||
|
path = zalloc ( sizeof ( *path ) );
|
||||||
|
if ( ! path )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* Construct device path */
|
||||||
|
path->fc.Header.Type = MESSAGING_DEVICE_PATH;
|
||||||
|
path->fc.Header.SubType = MSG_FIBRECHANNELEX_DP;
|
||||||
|
path->fc.Header.Length[0] = sizeof ( path->fc );
|
||||||
|
memcpy ( path->fc.WWN, &desc->wwn, sizeof ( path->fc.WWN ) );
|
||||||
|
memcpy ( path->fc.Lun, &desc->lun, sizeof ( path->fc.Lun ) );
|
||||||
|
path->end.Type = END_DEVICE_PATH_TYPE;
|
||||||
|
path->end.SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
|
||||||
|
path->end.Length[0] = sizeof ( path->end );
|
||||||
|
|
||||||
|
return &path->fc.Header;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct EFI device path for USB function
|
* Construct EFI device path for USB function
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||||||
#include <ipxe/scsi.h>
|
#include <ipxe/scsi.h>
|
||||||
#include <ipxe/device.h>
|
#include <ipxe/device.h>
|
||||||
#include <ipxe/edd.h>
|
#include <ipxe/edd.h>
|
||||||
|
#include <ipxe/efi/efi_path.h>
|
||||||
#include <ipxe/fc.h>
|
#include <ipxe/fc.h>
|
||||||
#include <ipxe/fcels.h>
|
#include <ipxe/fcels.h>
|
||||||
#include <ipxe/fcp.h>
|
#include <ipxe/fcp.h>
|
||||||
@@ -158,10 +159,8 @@ struct fcp_device {
|
|||||||
/** List of active commands */
|
/** List of active commands */
|
||||||
struct list_head fcpcmds;
|
struct list_head fcpcmds;
|
||||||
|
|
||||||
/** Fibre Channel WWN (for boot firmware table) */
|
/** Device description (for boot firmware table) */
|
||||||
struct fc_name wwn;
|
struct fcp_description desc;
|
||||||
/** SCSI LUN (for boot firmware table) */
|
|
||||||
struct scsi_lun lun;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** An FCP command */
|
/** An FCP command */
|
||||||
@@ -864,9 +863,9 @@ static int fcpdev_edd_describe ( struct fcp_device *fcpdev,
|
|||||||
} lun;
|
} lun;
|
||||||
|
|
||||||
type->type = cpu_to_le64 ( EDD_INTF_TYPE_FIBRE );
|
type->type = cpu_to_le64 ( EDD_INTF_TYPE_FIBRE );
|
||||||
memcpy ( &wwn.fc, &fcpdev->wwn, sizeof ( wwn.fc ) );
|
memcpy ( &wwn.fc, &fcpdev->desc.wwn, sizeof ( wwn.fc ) );
|
||||||
path->fibre.wwn = be64_to_cpu ( wwn.u64 );
|
path->fibre.wwn = be64_to_cpu ( wwn.u64 );
|
||||||
memcpy ( &lun.scsi, &fcpdev->lun, sizeof ( lun.scsi ) );
|
memcpy ( &lun.scsi, &fcpdev->desc.lun, sizeof ( lun.scsi ) );
|
||||||
path->fibre.lun = be64_to_cpu ( lun.u64 );
|
path->fibre.lun = be64_to_cpu ( lun.u64 );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -893,6 +892,18 @@ static struct device * fcpdev_identify_device ( struct fcp_device *fcpdev ) {
|
|||||||
return identify_device ( &fcpdev->user.ulp->peer->port->transport );
|
return identify_device ( &fcpdev->user.ulp->peer->port->transport );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Describe as an EFI device path
|
||||||
|
*
|
||||||
|
* @v fcp FCP device
|
||||||
|
* @ret path EFI device path, or NULL on error
|
||||||
|
*/
|
||||||
|
static EFI_DEVICE_PATH_PROTOCOL *
|
||||||
|
fcpdev_efi_describe ( struct fcp_device *fcpdev ) {
|
||||||
|
|
||||||
|
return efi_fcp_path ( &fcpdev->desc );
|
||||||
|
}
|
||||||
|
|
||||||
/** FCP device SCSI interface operations */
|
/** FCP device SCSI interface operations */
|
||||||
static struct interface_operation fcpdev_scsi_op[] = {
|
static struct interface_operation fcpdev_scsi_op[] = {
|
||||||
INTF_OP ( scsi_command, struct fcp_device *, fcpdev_scsi_command ),
|
INTF_OP ( scsi_command, struct fcp_device *, fcpdev_scsi_command ),
|
||||||
@@ -901,6 +912,7 @@ static struct interface_operation fcpdev_scsi_op[] = {
|
|||||||
INTF_OP ( edd_describe, struct fcp_device *, fcpdev_edd_describe ),
|
INTF_OP ( edd_describe, struct fcp_device *, fcpdev_edd_describe ),
|
||||||
INTF_OP ( identify_device, struct fcp_device *,
|
INTF_OP ( identify_device, struct fcp_device *,
|
||||||
fcpdev_identify_device ),
|
fcpdev_identify_device ),
|
||||||
|
EFI_INTF_OP ( efi_describe, struct fcp_device *, fcpdev_efi_describe ),
|
||||||
};
|
};
|
||||||
|
|
||||||
/** FCP device SCSI interface descriptor */
|
/** FCP device SCSI interface descriptor */
|
||||||
@@ -965,8 +977,8 @@ static int fcpdev_open ( struct interface *parent, struct fc_name *wwn,
|
|||||||
fc_ulp_attach ( ulp, &fcpdev->user );
|
fc_ulp_attach ( ulp, &fcpdev->user );
|
||||||
|
|
||||||
/* Preserve parameters required for boot firmware table */
|
/* Preserve parameters required for boot firmware table */
|
||||||
memcpy ( &fcpdev->wwn, wwn, sizeof ( fcpdev->wwn ) );
|
memcpy ( &fcpdev->desc.wwn, wwn, sizeof ( fcpdev->desc.wwn ) );
|
||||||
memcpy ( &fcpdev->lun, lun, sizeof ( fcpdev->lun ) );
|
memcpy ( &fcpdev->desc.lun, lun, sizeof ( fcpdev->desc.lun ) );
|
||||||
|
|
||||||
/* Attach SCSI device to parent interface */
|
/* Attach SCSI device to parent interface */
|
||||||
if ( ( rc = scsi_open ( parent, &fcpdev->scsi, lun ) ) != 0 ) {
|
if ( ( rc = scsi_open ( parent, &fcpdev->scsi, lun ) ) != 0 ) {
|
||||||
|
|||||||
Reference in New Issue
Block a user