]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[aoe] Allow AoE device to be described using an EFI device path
authorMichael Brown <mcb30@ipxe.org>
Mon, 19 Oct 2020 13:42:11 +0000 (14:42 +0100)
committerMichael Brown <mcb30@ipxe.org>
Mon, 19 Oct 2020 13:45:49 +0000 (14:45 +0100)
There is no standard defined for AoE device paths in the UEFI
specification, and it seems unlikely that any standard will be adopted
in future.

Choose to construct an AoE device path using a concatenation of the
network device path and a SATA device path, treating the AoE major and
minor numbers as the HBA port number and port multiplier port number
respectively.

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

index a51044d153a4a2a07e55608d5189a5c8be3c9c7a..14d11c5cb0879cc872cdfd7912bff5d51c233360 100644 (file)
@@ -15,6 +15,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <ipxe/retry.h>
 #include <ipxe/ata.h>
 #include <ipxe/acpi.h>
+#include <ipxe/netdevice.h>
+#include <ipxe/interface.h>
 
 /** An AoE config command */
 struct aoecfg {
@@ -109,6 +111,35 @@ struct aoehdr {
 /** Maximum number of sectors per packet */
 #define AOE_MAX_COUNT 2
 
+/** An AoE device */
+struct aoe_device {
+       /** Reference counter */
+       struct refcnt refcnt;
+
+       /** Network device */
+       struct net_device *netdev;
+       /** ATA command issuing interface */
+       struct interface ata;
+
+       /** Major number */
+       uint16_t major;
+       /** Minor number */
+       uint8_t minor;
+       /** Target MAC address */
+       uint8_t target[MAX_LL_ADDR_LEN];
+
+       /** Saved timeout value */
+       unsigned long timeout;
+
+       /** Configuration command interface */
+       struct interface config;
+       /** Device is configued */
+       int configured;
+
+       /** ACPI descriptor */
+       struct acpi_descriptor desc;
+};
+
 /** AoE boot firmware table signature */
 #define ABFT_SIG ACPI_SIGNATURE ( 'a', 'B', 'F', 'T' )
 
index b27441d07ccb5e350f03171a37865ce5cda82bc5..3921fcee2648ebc3f9e6be137ea5ad6b6f8eeb6c 100644 (file)
@@ -15,6 +15,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 
 struct net_device;
 struct uri;
+struct aoe_device;
 struct usb_function;
 
 extern EFI_DEVICE_PATH_PROTOCOL *
@@ -24,6 +25,7 @@ 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_uri_path ( struct uri *uri );
+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_describe ( struct interface *interface );
index 3c8a3be573b7961c2fafffde534e7f982c37373e..8636c965b8caf28e42c087f1765f082d1067c9e8 100644 (file)
@@ -24,6 +24,7 @@
 #include <ipxe/netdevice.h>
 #include <ipxe/vlan.h>
 #include <ipxe/uri.h>
+#include <ipxe/aoe.h>
 #include <ipxe/usb.h>
 #include <ipxe/efi/efi.h>
 #include <ipxe/efi/efi_driver.h>
@@ -220,6 +221,52 @@ EFI_DEVICE_PATH_PROTOCOL * efi_uri_path ( struct uri *uri ) {
        return path;
 }
 
+/**
+ * Construct EFI device path for AoE device
+ *
+ * @v aoedev           AoE device
+ * @ret path           EFI device path, or NULL on error
+ */
+EFI_DEVICE_PATH_PROTOCOL * efi_aoe_path ( struct aoe_device *aoedev ) {
+       struct {
+               SATA_DEVICE_PATH sata;
+               EFI_DEVICE_PATH_PROTOCOL end;
+       } satapath;
+       EFI_DEVICE_PATH_PROTOCOL *netpath;
+       EFI_DEVICE_PATH_PROTOCOL *path;
+
+       /* Get network device path */
+       netpath = efi_netdev_path ( aoedev->netdev );
+       if ( ! netpath )
+               goto err_netdev;
+
+       /* Construct SATA path */
+       memset ( &satapath, 0, sizeof ( satapath ) );
+       satapath.sata.Header.Type = MESSAGING_DEVICE_PATH;
+       satapath.sata.Header.SubType = MSG_SATA_DP;
+       satapath.sata.Header.Length[0] = sizeof ( satapath.sata );
+       satapath.sata.HBAPortNumber = aoedev->major;
+       satapath.sata.PortMultiplierPortNumber = aoedev->minor;
+       satapath.end.Type = END_DEVICE_PATH_TYPE;
+       satapath.end.SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
+       satapath.end.Length[0] = sizeof ( satapath.end );
+
+       /* Construct overall device path */
+       path = efi_paths ( netpath, &satapath, NULL );
+       if ( ! path )
+               goto err_paths;
+
+       /* Free temporary paths */
+       free ( netpath );
+
+       return path;
+
+ err_paths:
+       free ( netpath );
+ err_netdev:
+       return NULL;
+}
+
 /**
  * Construct EFI device path for USB function
  *
index 3a6611d04d1682b4dbf28a41058e20c3770254fc..e785e8979afcc6249d097a35f3d7b7d703e3d117 100644 (file)
@@ -42,6 +42,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <ipxe/open.h>
 #include <ipxe/ata.h>
 #include <ipxe/device.h>
+#include <ipxe/efi/efi_path.h>
 #include <ipxe/aoe.h>
 
 /** @file
@@ -68,35 +69,6 @@ static LIST_HEAD ( aoe_devices );
 /** List of active AoE commands */
 static LIST_HEAD ( aoe_commands );
 
-/** An AoE device */
-struct aoe_device {
-       /** Reference counter */
-       struct refcnt refcnt;
-
-       /** Network device */
-       struct net_device *netdev;
-       /** ATA command issuing interface */
-       struct interface ata;
-
-       /** Major number */
-       uint16_t major;
-       /** Minor number */
-       uint8_t minor;
-       /** Target MAC address */
-       uint8_t target[MAX_LL_ADDR_LEN];
-
-       /** Saved timeout value */
-       unsigned long timeout;
-
-       /** Configuration command interface */
-       struct interface config;
-       /** Device is configued */
-       int configured;
-
-       /** ACPI descriptor */
-       struct acpi_descriptor desc;
-};
-
 /** An AoE command */
 struct aoe_command {
        /** Reference count */
@@ -811,6 +783,7 @@ static struct interface_operation aoedev_ata_op[] = {
        INTF_OP ( acpi_describe, struct aoe_device *, aoedev_describe ),
        INTF_OP ( identify_device, struct aoe_device *,
                  aoedev_identify_device ),
+       EFI_INTF_OP ( efi_describe, struct aoe_device *, efi_aoe_path ),
 };
 
 /** AoE device ATA interface descriptor */