summaryrefslogtreecommitdiffstats
path: root/src/net
diff options
context:
space:
mode:
Diffstat (limited to 'src/net')
-rw-r--r--src/net/aoe.c90
-rw-r--r--src/net/fcp.c20
-rw-r--r--src/net/infiniband/ib_srp.c141
-rw-r--r--src/net/tcp/httpblock.c18
-rw-r--r--src/net/tcp/httpcore.c17
-rw-r--r--src/net/tcp/iscsi.c14
6 files changed, 180 insertions, 120 deletions
diff --git a/src/net/aoe.c b/src/net/aoe.c
index 2da8655b..3a6611d0 100644
--- a/src/net/aoe.c
+++ b/src/net/aoe.c
@@ -53,6 +53,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
FEATURE ( FEATURE_PROTOCOL, "AoE", DHCP_EB_FEATURE_AOE, 1 );
struct net_protocol aoe_protocol __net_protocol;
+struct acpi_model abft_model __acpi_model;
/******************************************************************************
*
@@ -91,6 +92,9 @@ struct aoe_device {
struct interface config;
/** Device is configued */
int configured;
+
+ /** ACPI descriptor */
+ struct acpi_descriptor desc;
};
/** An AoE command */
@@ -790,32 +794,13 @@ static struct device * aoedev_identify_device ( struct aoe_device *aoedev ) {
}
/**
- * Describe AoE device in an ACPI table
+ * Get AoE ACPI descriptor
*
* @v aoedev AoE device
- * @v acpi ACPI table
- * @v len Length of ACPI table
- * @ret rc Return status code
+ * @ret desc ACPI descriptor
*/
-static int aoedev_describe ( struct aoe_device *aoedev,
- struct acpi_description_header *acpi,
- size_t len ) {
- struct abft_table *abft =
- container_of ( acpi, struct abft_table, acpi );
-
- /* Sanity check */
- if ( len < sizeof ( *abft ) )
- return -ENOBUFS;
-
- /* Populate table */
- abft->acpi.signature = cpu_to_le32 ( ABFT_SIG );
- abft->acpi.length = cpu_to_le32 ( sizeof ( *abft ) );
- abft->acpi.revision = 1;
- abft->shelf = cpu_to_le16 ( aoedev->major );
- abft->slot = aoedev->minor;
- memcpy ( abft->mac, aoedev->netdev->ll_addr, sizeof ( abft->mac ) );
-
- return 0;
+static struct acpi_descriptor * aoedev_describe ( struct aoe_device *aoedev ) {
+ return &aoedev->desc;
}
/** AoE device ATA interface operations */
@@ -869,6 +854,7 @@ static int aoedev_open ( struct interface *parent, struct net_device *netdev,
aoedev->minor = minor;
memcpy ( aoedev->target, netdev->ll_broadcast,
netdev->ll_protocol->ll_addr_len );
+ acpi_init ( &aoedev->desc, &abft_model, &aoedev->refcnt );
/* Initiate configuration */
if ( ( rc = aoedev_cfg_command ( aoedev, &aoedev->config ) ) < 0 ) {
@@ -1059,3 +1045,61 @@ struct uri_opener aoe_uri_opener __uri_opener = {
.scheme = "aoe",
.open = aoe_open,
};
+
+/******************************************************************************
+ *
+ * AoE boot firmware table (aBFT)
+ *
+ ******************************************************************************
+ */
+
+/**
+ * Check if AoE boot firmware table descriptor is complete
+ *
+ * @v desc ACPI descriptor
+ * @ret rc Return status code
+ */
+static int abft_complete ( struct acpi_descriptor *desc __unused ) {
+ return 0;
+}
+
+/**
+ * Install AoE boot firmware table(s)
+ *
+ * @v install Installation method
+ * @ret rc Return status code
+ */
+static int abft_install ( int ( * install ) ( struct acpi_header *acpi ) ) {
+ struct aoe_device *aoedev;
+ struct abft_table abft;
+ int rc;
+
+ list_for_each_entry ( aoedev, &abft_model.descs, desc.list ) {
+
+ /* Populate table */
+ memset ( &abft, 0, sizeof ( abft ) );
+ abft.acpi.signature = cpu_to_le32 ( ABFT_SIG );
+ abft.acpi.length = cpu_to_le32 ( sizeof ( abft ) );
+ abft.acpi.revision = 1;
+ abft.shelf = cpu_to_le16 ( aoedev->major );
+ abft.slot = aoedev->minor;
+ memcpy ( abft.mac, aoedev->netdev->ll_addr,
+ sizeof ( abft.mac ) );
+
+ /* Install table */
+ if ( ( rc = install ( &abft.acpi ) ) != 0 ) {
+ DBGC ( aoedev, "AoE %s could not install aBFT: %s\n",
+ aoedev_name ( aoedev ), strerror ( rc ) );
+ return rc;
+ }
+ }
+
+ return 0;
+}
+
+/** aBFT model */
+struct acpi_model abft_model __acpi_model = {
+ .descs = LIST_HEAD_INIT ( abft_model.descs ),
+ .complete = abft_complete,
+ .install = abft_install,
+};
diff --git a/src/net/fcp.c b/src/net/fcp.c
index 930bf7dd..d92cfdcf 100644
--- a/src/net/fcp.c
+++ b/src/net/fcp.c
@@ -844,25 +844,6 @@ static size_t fcpdev_window ( struct fcp_device *fcpdev ) {
}
/**
- * Describe FCP device in an ACPI table
- *
- * @v fcpdev FCP device
- * @v acpi ACPI table
- * @v len Length of ACPI table
- * @ret rc Return status code
- */
-static int fcpdev_acpi_describe ( struct fcp_device *fcpdev,
- struct acpi_description_header *acpi,
- size_t len ) {
-
- DBGC ( fcpdev, "FCP %p cannot yet describe device in an ACPI table\n",
- fcpdev );
- ( void ) acpi;
- ( void ) len;
- return 0;
-}
-
-/**
* Describe FCP device using EDD
*
* @v fcpdev FCP device
@@ -917,7 +898,6 @@ static struct interface_operation fcpdev_scsi_op[] = {
INTF_OP ( scsi_command, struct fcp_device *, fcpdev_scsi_command ),
INTF_OP ( xfer_window, struct fcp_device *, fcpdev_window ),
INTF_OP ( intf_close, struct fcp_device *, fcpdev_close ),
- INTF_OP ( acpi_describe, struct fcp_device *, fcpdev_acpi_describe ),
INTF_OP ( edd_describe, struct fcp_device *, fcpdev_edd_describe ),
INTF_OP ( identify_device, struct fcp_device *,
fcpdev_identify_device ),
diff --git a/src/net/infiniband/ib_srp.c b/src/net/infiniband/ib_srp.c
index 3b4914ab..cf1ef3bf 100644
--- a/src/net/infiniband/ib_srp.c
+++ b/src/net/infiniband/ib_srp.c
@@ -60,6 +60,8 @@ FILE_LICENCE ( BSD2 );
#define EINFO_EINVAL_RP_TOO_SHORT __einfo_uniqify \
( EINFO_EINVAL, 0x04, "Root path too short" )
+struct acpi_model ib_sbft_model __acpi_model;
+
/******************************************************************************
*
* IB SRP devices
@@ -67,6 +69,20 @@ FILE_LICENCE ( BSD2 );
******************************************************************************
*/
+/**
+ * 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 */
@@ -80,10 +96,10 @@ struct ib_srp_device {
/** Infiniband device */
struct ib_device *ibdev;
- /** Destination GID (for boot firmware table) */
- union ib_gid dgid;
- /** Service ID (for boot firmware table) */
- union ib_guid service_id;
+ /** ACPI descriptor */
+ struct acpi_descriptor desc;
+ /** Boot firmware table parameters */
+ struct ipxe_ib_sbft sbft;
};
/**
@@ -113,43 +129,15 @@ static void ib_srp_close ( struct ib_srp_device *ib_srp, int rc ) {
}
/**
- * Describe IB SRP device in an ACPI table
+ * Get IB SRP ACPI descriptor
*
- * @v srpdev SRP device
- * @v acpi ACPI table
- * @v len Length of ACPI table
- * @ret rc Return status code
+ * @v ib_srp IB SRP device
+ * @ret desc ACPI descriptor
*/
-static int ib_srp_describe ( struct ib_srp_device *ib_srp,
- struct acpi_description_header *acpi,
- size_t len ) {
- struct ib_device *ibdev = ib_srp->ibdev;
- struct sbft_table *sbft =
- container_of ( acpi, struct sbft_table, acpi );
- struct sbft_ib_subtable *ib_sbft;
- size_t used;
-
- /* Sanity check */
- if ( acpi->signature != SBFT_SIG )
- return -EINVAL;
-
- /* Append IB subtable to existing table */
- used = le32_to_cpu ( sbft->acpi.length );
- sbft->ib_offset = cpu_to_le16 ( used );
- ib_sbft = ( ( ( void * ) sbft ) + used );
- used += sizeof ( *ib_sbft );
- if ( used > len )
- return -ENOBUFS;
- sbft->acpi.length = cpu_to_le32 ( used );
-
- /* Populate subtable */
- memcpy ( &ib_sbft->sgid, &ibdev->gid, sizeof ( ib_sbft->sgid ) );
- memcpy ( &ib_sbft->dgid, &ib_srp->dgid, sizeof ( ib_sbft->dgid ) );
- memcpy ( &ib_sbft->service_id, &ib_srp->service_id,
- sizeof ( ib_sbft->service_id ) );
- ib_sbft->pkey = cpu_to_le16 ( ibdev->pkey );
+static struct acpi_descriptor *
+ib_srp_describe ( struct ib_srp_device *ib_srp ) {
- return 0;
+ return &ib_srp->desc;
}
/** IB SRP CMRC interface operations */
@@ -188,6 +176,7 @@ static int ib_srp_open ( struct interface *block, struct ib_device *ibdev,
union srp_port_id *initiator,
union srp_port_id *target, struct scsi_lun *lun ) {
struct ib_srp_device *ib_srp;
+ struct ipxe_ib_sbft *sbft;
int rc;
/* Allocate and initialise structure */
@@ -200,13 +189,19 @@ static int ib_srp_open ( struct interface *block, struct ib_device *ibdev,
intf_init ( &ib_srp->srp, &ib_srp_srp_desc, &ib_srp->refcnt );
intf_init ( &ib_srp->cmrc, &ib_srp_cmrc_desc, &ib_srp->refcnt );
ib_srp->ibdev = ibdev_get ( ibdev );
+ acpi_init ( &ib_srp->desc, &ib_sbft_model, &ib_srp->refcnt );
DBGC ( ib_srp, "IBSRP %p for " IB_GID_FMT " " IB_GUID_FMT "\n",
ib_srp, IB_GID_ARGS ( dgid ), IB_GUID_ARGS ( service_id ) );
/* Preserve parameters required for boot firmware table */
- memcpy ( &ib_srp->dgid, dgid, sizeof ( ib_srp->dgid ) );
- memcpy ( &ib_srp->service_id, service_id,
- sizeof ( ib_srp->service_id ) );
+ sbft = &ib_srp->sbft;
+ memcpy ( &sbft->scsi.lun, lun, sizeof ( sbft->scsi.lun ) );
+ memcpy ( &sbft->srp.initiator, initiator,
+ sizeof ( sbft->srp.initiator ) );
+ memcpy ( &sbft->srp.target, target, sizeof ( sbft->srp.target ) );
+ memcpy ( &sbft->ib.dgid, dgid, sizeof ( sbft->ib.dgid ) );
+ memcpy ( &sbft->ib.service_id, service_id,
+ sizeof ( sbft->ib.service_id ) );
/* Open CMRC socket */
if ( ( rc = ib_cmrc_open ( &ib_srp->cmrc, ibdev, dgid,
@@ -579,3 +574,67 @@ struct uri_opener ib_srp_uri_opener __uri_opener = {
.scheme = "ib_srp",
.open = ib_srp_open_uri,
};
+
+/******************************************************************************
+ *
+ * IB SRP boot firmware table (sBFT)
+ *
+ ******************************************************************************
+ */
+
+/**
+ * Check if IB SRP boot firmware table descriptor is complete
+ *
+ * @v desc ACPI descriptor
+ * @ret rc Return status code
+ */
+static int ib_sbft_complete ( struct acpi_descriptor *desc __unused ) {
+ return 0;
+}
+
+/**
+ * Install IB SRP boot firmware table(s)
+ *
+ * @v install Installation method
+ * @ret rc Return status code
+ */
+static int ib_sbft_install ( int ( * install ) ( struct acpi_header *acpi ) ) {
+ struct ib_srp_device *ib_srp;
+ struct ipxe_ib_sbft *sbft;
+ struct ib_device *ibdev;
+ int rc;
+
+ list_for_each_entry ( ib_srp, &ib_sbft_model.descs, desc.list ) {
+
+ /* Complete table */
+ sbft = &ib_srp->sbft;
+ ibdev = ib_srp->ibdev;
+ sbft->table.acpi.signature = cpu_to_le32 ( SBFT_SIG );
+ sbft->table.acpi.length = cpu_to_le32 ( sizeof ( *sbft ) );
+ sbft->table.acpi.revision = 1;
+ sbft->table.scsi_offset =
+ cpu_to_le16 ( offsetof ( typeof ( *sbft ), scsi ) );
+ sbft->table.srp_offset =
+ cpu_to_le16 ( offsetof ( typeof ( *sbft ), srp ) );
+ sbft->table.ib_offset =
+ cpu_to_le16 ( offsetof ( typeof ( *sbft ), ib ) );
+ memcpy ( &sbft->ib.sgid, &ibdev->gid, sizeof ( sbft->ib.sgid ));
+ sbft->ib.pkey = cpu_to_le16 ( ibdev->pkey );
+
+ /* Install table */
+ if ( ( rc = install ( &sbft->table.acpi ) ) != 0 ) {
+ DBGC ( ib_srp, "IBSRP %p could not install sBFT: %s\n",
+ ib_srp, strerror ( rc ) );
+ return rc;
+ }
+ }
+
+ return 0;
+}
+
+/** IB sBFT model */
+struct acpi_model ib_sbft_model __acpi_model = {
+ .descs = LIST_HEAD_INIT ( ib_sbft_model.descs ),
+ .complete = ib_sbft_complete,
+ .install = ib_sbft_install,
+};
diff --git a/src/net/tcp/httpblock.c b/src/net/tcp/httpblock.c
index e124ad2d..1abd6b34 100644
--- a/src/net/tcp/httpblock.c
+++ b/src/net/tcp/httpblock.c
@@ -114,21 +114,3 @@ int http_block_read_capacity ( struct http_transaction *http,
err_open:
return rc;
}
-
-/**
- * Describe device in ACPI table
- *
- * @v http HTTP transaction
- * @v acpi ACPI table
- * @v len Length of ACPI table
- * @ret rc Return status code
- */
-int http_acpi_describe ( struct http_transaction *http,
- struct acpi_description_header *acpi, size_t len ) {
-
- DBGC ( http, "HTTP %p cannot yet describe device in an ACPI table\n",
- http );
- ( void ) acpi;
- ( void ) len;
- return 0;
-}
diff --git a/src/net/tcp/httpcore.c b/src/net/tcp/httpcore.c
index ec527c64..ce53a212 100644
--- a/src/net/tcp/httpcore.c
+++ b/src/net/tcp/httpcore.c
@@ -509,28 +509,11 @@ __weak int http_block_read_capacity ( struct http_transaction *http __unused,
return -ENOTSUP;
}
-/**
- * Describe device in ACPI table (when HTTP block device support is not present)
- *
- * @v http HTTP transaction
- * @v acpi ACPI table
- * @v len Length of ACPI table
- * @ret rc Return status code
- */
-__weak int http_acpi_describe ( struct http_transaction *http __unused,
- struct acpi_description_header *acpi __unused,
- size_t len __unused ) {
-
- return -ENOTSUP;
-}
-
/** HTTP data transfer interface operations */
static struct interface_operation http_xfer_operations[] = {
INTF_OP ( block_read, struct http_transaction *, http_block_read ),
INTF_OP ( block_read_capacity, struct http_transaction *,
http_block_read_capacity ),
- INTF_OP ( acpi_describe, struct http_transaction *,
- http_acpi_describe ),
INTF_OP ( xfer_window_changed, struct http_transaction *, http_step ),
INTF_OP ( intf_close, struct http_transaction *, http_close ),
};
diff --git a/src/net/tcp/iscsi.c b/src/net/tcp/iscsi.c
index 1e6fd1f5..7de4a7bf 100644
--- a/src/net/tcp/iscsi.c
+++ b/src/net/tcp/iscsi.c
@@ -1810,12 +1810,23 @@ static int iscsi_scsi_command ( struct iscsi_session *iscsi,
return iscsi->itt;
}
+/**
+ * Get iSCSI ACPI descriptor
+ *
+ * @v iscsi iSCSI session
+ * @ret desc ACPI descriptor
+ */
+static struct acpi_descriptor * iscsi_describe ( struct iscsi_session *iscsi ) {
+
+ return &iscsi->desc;
+}
+
/** iSCSI SCSI command-issuing interface operations */
static struct interface_operation iscsi_control_op[] = {
INTF_OP ( scsi_command, struct iscsi_session *, iscsi_scsi_command ),
INTF_OP ( xfer_window, struct iscsi_session *, iscsi_scsi_window ),
INTF_OP ( intf_close, struct iscsi_session *, iscsi_close ),
- INTF_OP ( acpi_describe, struct iscsi_session *, ibft_describe ),
+ INTF_OP ( acpi_describe, struct iscsi_session *, iscsi_describe ),
};
/** iSCSI SCSI command-issuing interface descriptor */
@@ -2064,6 +2075,7 @@ static int iscsi_open ( struct interface *parent, struct uri *uri ) {
intf_init ( &iscsi->socket, &iscsi_socket_desc, &iscsi->refcnt );
process_init_stopped ( &iscsi->process, &iscsi_process_desc,
&iscsi->refcnt );
+ acpi_init ( &iscsi->desc, &ibft_model, &iscsi->refcnt );
/* Parse root path */
if ( ( rc = iscsi_parse_root_path ( iscsi, uri->opaque ) ) != 0 )