diff options
Diffstat (limited to 'src/net')
-rw-r--r-- | src/net/aoe.c | 90 | ||||
-rw-r--r-- | src/net/fcp.c | 20 | ||||
-rw-r--r-- | src/net/infiniband/ib_srp.c | 141 | ||||
-rw-r--r-- | src/net/tcp/httpblock.c | 18 | ||||
-rw-r--r-- | src/net/tcp/httpcore.c | 17 | ||||
-rw-r--r-- | src/net/tcp/iscsi.c | 14 |
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 ) |