]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[infiniband] Allow SRP device to be described using an EFI device path
authorMichael Brown <mcb30@ipxe.org>
Fri, 23 Oct 2020 14:26:30 +0000 (15:26 +0100)
committerMichael Brown <mcb30@ipxe.org>
Fri, 23 Oct 2020 14:34:35 +0000 (15:34 +0100)
The UEFI specification provides a partial definition of an Infiniband
device path structure.  Use this structure to construct what may be a
plausible path containing at least some of the information required to
identify an SRP target device.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/include/ipxe/efi/efi_path.h
src/include/ipxe/ib_srp.h
src/interface/efi/efi_path.c
src/net/infiniband/ib_srp.c

index 91a6c255d0c5ee3873af802b7ab7553333172a9a..76ded728c6bc6732a9769868fbd6b8a21ae08ee9 100644 (file)
@@ -18,6 +18,7 @@ struct uri;
 struct iscsi_session;
 struct aoe_device;
 struct fcp_description;
+struct ib_srp_device;
 struct usb_function;
 
 extern EFI_DEVICE_PATH_PROTOCOL *
@@ -31,6 +32,8 @@ 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_ib_srp_path ( struct ib_srp_device *ib_srp );
 extern EFI_DEVICE_PATH_PROTOCOL * efi_usb_path ( struct usb_function *func );
 
 extern EFI_DEVICE_PATH_PROTOCOL * efi_describe ( struct interface *interface );
index ad407b0cfffbf4f5b21fc6eeca23b0843af5fccf..4b6df8d3b4a760ece2d51986af32d923b7b56c2b 100644 (file)
@@ -10,6 +10,8 @@
 FILE_LICENCE ( BSD2 );
 
 #include <stdint.h>
+#include <ipxe/acpi.h>
+#include <ipxe/interface.h>
 #include <ipxe/infiniband.h>
 #include <ipxe/srp.h>
 
@@ -55,4 +57,37 @@ struct sbft_ib_subtable {
        uint8_t reserved[6];
 } __attribute__ (( packed ));
 
+/**
+ * An Infiniband SRP sBFT created by iPXE
+ */
+struct ipxe_ib_sbft {
+       /** The table header */
+       struct sbft_table table;
+       /** The SCSI subtable */
+       struct sbft_scsi_subtable scsi;
+       /** The SRP subtable */
+       struct sbft_srp_subtable srp;
+       /** The Infiniband subtable */
+       struct sbft_ib_subtable ib;
+};
+
+/** An Infiniband SRP device */
+struct ib_srp_device {
+       /** Reference count */
+       struct refcnt refcnt;
+
+       /** SRP transport interface */
+       struct interface srp;
+       /** CMRC interface */
+       struct interface cmrc;
+
+       /** Infiniband device */
+       struct ib_device *ibdev;
+
+       /** ACPI descriptor */
+       struct acpi_descriptor desc;
+       /** Boot firmware table parameters */
+       struct ipxe_ib_sbft sbft;
+};
+
 #endif /* _IPXE_IB_SRP_H */
index 76b1e4daede18af509c02a3f2f84778ce439fac3..bae0ac4b54138ff5b5c6b77dcb1cbbad2f3f4f90 100644 (file)
@@ -28,6 +28,7 @@
 #include <ipxe/iscsi.h>
 #include <ipxe/aoe.h>
 #include <ipxe/fcp.h>
+#include <ipxe/ib_srp.h>
 #include <ipxe/usb.h>
 #include <ipxe/efi/efi.h>
 #include <ipxe/efi/efi_driver.h>
@@ -368,6 +369,60 @@ EFI_DEVICE_PATH_PROTOCOL * efi_fcp_path ( struct fcp_description *desc ) {
        return &path->fc.Header;
 }
 
+/**
+ * Construct EFI device path for Infiniband SRP device
+ *
+ * @v ib_srp           Infiniband SRP device
+ * @ret path           EFI device path, or NULL on error
+ */
+EFI_DEVICE_PATH_PROTOCOL * efi_ib_srp_path ( struct ib_srp_device *ib_srp ) {
+       const struct ipxe_ib_sbft *sbft = &ib_srp->sbft;
+       union ib_srp_target_port_id *id =
+               container_of ( &sbft->srp.target, union ib_srp_target_port_id,
+                              srp );
+       struct efi_device *efidev;
+       EFI_DEVICE_PATH_PROTOCOL *path;
+       INFINIBAND_DEVICE_PATH *ibpath;
+       EFI_DEVICE_PATH_PROTOCOL *end;
+       size_t prefix_len;
+       size_t len;
+
+       /* Find parent EFI device */
+       efidev = efidev_parent ( ib_srp->ibdev->dev );
+       if ( ! efidev )
+               return NULL;
+
+       /* Calculate device path length */
+       prefix_len = efi_path_len ( efidev->path );
+       len = ( prefix_len + sizeof ( *ibpath ) + sizeof ( *end ) );
+
+       /* Allocate device path */
+       path = zalloc ( len );
+       if ( ! path )
+               return NULL;
+
+       /* Construct device path */
+       memcpy ( path, efidev->path, prefix_len );
+       ibpath = ( ( ( void * ) path ) + prefix_len );
+       ibpath->Header.Type = MESSAGING_DEVICE_PATH;
+       ibpath->Header.SubType = MSG_INFINIBAND_DP;
+       ibpath->Header.Length[0] = sizeof ( *ibpath );
+       ibpath->ResourceFlags = INFINIBAND_RESOURCE_FLAG_STORAGE_PROTOCOL;
+       memcpy ( ibpath->PortGid, &sbft->ib.dgid, sizeof ( ibpath->PortGid ) );
+       memcpy ( &ibpath->ServiceId, &sbft->ib.service_id,
+                sizeof ( ibpath->ServiceId ) );
+       memcpy ( &ibpath->TargetPortId, &id->ib.ioc_guid,
+                sizeof ( ibpath->TargetPortId ) );
+       memcpy ( &ibpath->DeviceId, &id->ib.id_ext,
+                sizeof ( ibpath->DeviceId ) );
+       end = ( ( ( void * ) ibpath ) + sizeof ( *ibpath ) );
+       end->Type = END_DEVICE_PATH_TYPE;
+       end->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
+       end->Length[0] = sizeof ( *end );
+
+       return path;
+}
+
 /**
  * Construct EFI device path for USB function
  *
index 4913f449c2c70fb1de9680ee0d53c0f163688654..e6b43291ffa7582a142f0f7ba4af9cf5b28362ec 100644 (file)
@@ -37,6 +37,7 @@ FILE_LICENCE ( BSD2 );
 #include <ipxe/open.h>
 #include <ipxe/base16.h>
 #include <ipxe/acpi.h>
+#include <ipxe/efi/efi_path.h>
 #include <ipxe/srp.h>
 #include <ipxe/infiniband.h>
 #include <ipxe/ib_cmrc.h>
@@ -69,39 +70,6 @@ struct acpi_model ib_sbft_model __acpi_model;
  ******************************************************************************
  */
 
-/**
- * An IB SRP sBFT created by iPXE
- */
-struct ipxe_ib_sbft {
-       /** The table header */
-       struct sbft_table table;
-       /** The SCSI subtable */
-       struct sbft_scsi_subtable scsi;
-       /** The SRP subtable */
-       struct sbft_srp_subtable srp;
-       /** The Infiniband subtable */
-       struct sbft_ib_subtable ib;
-};
-
-/** An Infiniband SRP device */
-struct ib_srp_device {
-       /** Reference count */
-       struct refcnt refcnt;
-
-       /** SRP transport interface */
-       struct interface srp;
-       /** CMRC interface */
-       struct interface cmrc;
-
-       /** Infiniband device */
-       struct ib_device *ibdev;
-
-       /** ACPI descriptor */
-       struct acpi_descriptor desc;
-       /** Boot firmware table parameters */
-       struct ipxe_ib_sbft sbft;
-};
-
 /**
  * Free IB SRP device
  *
@@ -153,6 +121,7 @@ static struct interface_descriptor ib_srp_cmrc_desc =
 static struct interface_operation ib_srp_srp_op[] = {
        INTF_OP ( acpi_describe, struct ib_srp_device *, ib_srp_describe ),
        INTF_OP ( intf_close, struct ib_srp_device *, ib_srp_close ),
+       EFI_INTF_OP ( efi_describe, struct ib_srp_device *, efi_ib_srp_path ),
 };
 
 /** IB SRP SRP interface descriptor */