diff options
-rw-r--r-- | src/include/ipxe/efi/efi_path.h | 2 | ||||
-rw-r--r-- | src/include/ipxe/fcp.h | 8 | ||||
-rw-r--r-- | src/interface/efi/efi_path.c | 31 | ||||
-rw-r--r-- | src/net/fcp.c | 28 |
4 files changed, 61 insertions, 8 deletions
diff --git a/src/include/ipxe/efi/efi_path.h b/src/include/ipxe/efi/efi_path.h index 370197601..91a6c255d 100644 --- a/src/include/ipxe/efi/efi_path.h +++ b/src/include/ipxe/efi/efi_path.h @@ -17,6 +17,7 @@ struct net_device; struct uri; struct iscsi_session; struct aoe_device; +struct fcp_description; struct usb_function; 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 * 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_fcp_path ( struct fcp_description *desc ); extern EFI_DEVICE_PATH_PROTOCOL * efi_usb_path ( struct usb_function *func ); extern EFI_DEVICE_PATH_PROTOCOL * efi_describe ( struct interface *interface ); diff --git a/src/include/ipxe/fcp.h b/src/include/ipxe/fcp.h index 853ca13f6..d86afab42 100644 --- a/src/include/ipxe/fcp.h +++ b/src/include/ipxe/fcp.h @@ -163,4 +163,12 @@ struct fcp_prli_service_parameters { /** Enhanced discovery supported */ #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 */ diff --git a/src/interface/efi/efi_path.c b/src/interface/efi/efi_path.c index 3c14a2ee6..76b1e4dae 100644 --- a/src/interface/efi/efi_path.c +++ b/src/interface/efi/efi_path.c @@ -27,6 +27,7 @@ #include <ipxe/uri.h> #include <ipxe/iscsi.h> #include <ipxe/aoe.h> +#include <ipxe/fcp.h> #include <ipxe/usb.h> #include <ipxe/efi/efi.h> #include <ipxe/efi/efi_driver.h> @@ -338,6 +339,36 @@ EFI_DEVICE_PATH_PROTOCOL * efi_aoe_path ( struct aoe_device *aoedev ) { } /** + * 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 * * @v func USB function diff --git a/src/net/fcp.c b/src/net/fcp.c index d92cfdcf3..f78f7bd9b 100644 --- a/src/net/fcp.c +++ b/src/net/fcp.c @@ -43,6 +43,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <ipxe/scsi.h> #include <ipxe/device.h> #include <ipxe/edd.h> +#include <ipxe/efi/efi_path.h> #include <ipxe/fc.h> #include <ipxe/fcels.h> #include <ipxe/fcp.h> @@ -158,10 +159,8 @@ struct fcp_device { /** List of active commands */ struct list_head fcpcmds; - /** Fibre Channel WWN (for boot firmware table) */ - struct fc_name wwn; - /** SCSI LUN (for boot firmware table) */ - struct scsi_lun lun; + /** Device description (for boot firmware table) */ + struct fcp_description desc; }; /** An FCP command */ @@ -864,9 +863,9 @@ static int fcpdev_edd_describe ( struct fcp_device *fcpdev, } lun; 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 ); - 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 ); 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 ); } +/** + * 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 */ static struct interface_operation fcpdev_scsi_op[] = { 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 ( identify_device, struct fcp_device *, fcpdev_identify_device ), + EFI_INTF_OP ( efi_describe, struct fcp_device *, fcpdev_efi_describe ), }; /** 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 ); /* Preserve parameters required for boot firmware table */ - memcpy ( &fcpdev->wwn, wwn, sizeof ( fcpdev->wwn ) ); - memcpy ( &fcpdev->lun, lun, sizeof ( fcpdev->lun ) ); + memcpy ( &fcpdev->desc.wwn, wwn, sizeof ( fcpdev->desc.wwn ) ); + memcpy ( &fcpdev->desc.lun, lun, sizeof ( fcpdev->desc.lun ) ); /* Attach SCSI device to parent interface */ if ( ( rc = scsi_open ( parent, &fcpdev->scsi, lun ) ) != 0 ) { |