summaryrefslogtreecommitdiffstats
path: root/src/drivers/block
diff options
context:
space:
mode:
authorMichael Brown2017-03-27 17:20:34 +0200
committerMichael Brown2017-03-28 18:12:48 +0200
commit7cfdd769aac76d605aa31146c69ba518b194bea7 (patch)
tree7c09e144792833f81297e6dacf0823733a2a399a /src/drivers/block
parent[block] Ignore redundant xfer_window_changed() messages (diff)
downloadipxe-7cfdd769aac76d605aa31146c69ba518b194bea7.tar.gz
ipxe-7cfdd769aac76d605aa31146c69ba518b194bea7.tar.xz
ipxe-7cfdd769aac76d605aa31146c69ba518b194bea7.zip
[block] Describe all SAN devices via ACPI tables
Describe all SAN devices via ACPI tables such as the iBFT. For tables that can describe only a single device (i.e. the aBFT and sBFT), one table is installed per device. For multi-device tables (i.e. the iBFT), all devices are described in a single table. An underlying SAN device connection may be closed at the time that we need to construct an ACPI table. We therefore introduce the concept of an "ACPI descriptor" which enables the SAN boot code to maintain an opaque pointer to the underlying object, and an "ACPI model" which can build tables from a list of such descriptors. This separates the lifecycles of ACPI descriptions from the lifecycles of the block device interfaces, and allows for construction of the ACPI tables even if the block device interface has been closed. For a multipath SAN device, iPXE will wait until sufficient information is available to describe all devices but will not wait for all paths to connect successfully. For example: with a multipath iSCSI boot iPXE will wait until at least one path has become available and name resolution has completed on all other paths. We do this since the iBFT has to include IP addresses rather than DNS names. We will commence booting without waiting for the inactive paths to either become available or close; this avoids unnecessary boot delays. Note that the Linux kernel will refuse to accept an iBFT with more than two NIC or target structures. We therefore describe only the NICs that are actually required in order to reach the described targets. Any iBFT with at most two targets is therefore guaranteed to describe at most two NICs. Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/drivers/block')
-rw-r--r--src/drivers/block/ibft.c392
-rw-r--r--src/drivers/block/srp.c68
2 files changed, 287 insertions, 173 deletions
diff --git a/src/drivers/block/ibft.c b/src/drivers/block/ibft.c
index 91a808d8..a9d21f9a 100644
--- a/src/drivers/block/ibft.c
+++ b/src/drivers/block/ibft.c
@@ -28,6 +28,7 @@
FILE_LICENCE ( BSD2 );
#include <stdint.h>
+#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
@@ -38,6 +39,7 @@ FILE_LICENCE ( BSD2 );
#include <ipxe/netdevice.h>
#include <ipxe/ethernet.h>
#include <ipxe/vlan.h>
+#include <ipxe/tcpip.h>
#include <ipxe/dhcp.h>
#include <ipxe/iscsi.h>
#include <ipxe/ibft.h>
@@ -54,38 +56,32 @@ FILE_LICENCE ( BSD2 );
*/
/**
- * An iBFT created by iPXE
- *
- */
-struct ipxe_ibft {
- /** The fixed section */
- struct ibft_table table;
- /** The Initiator section */
- struct ibft_initiator initiator __attribute__ (( aligned ( 16 ) ));
- /** The NIC section */
- struct ibft_nic nic __attribute__ (( aligned ( 16 ) ));
- /** The Target section */
- struct ibft_target target __attribute__ (( aligned ( 16 ) ));
- /** Strings block */
- char strings[0];
-} __attribute__ (( packed, aligned ( 16 ) ));
-
-/**
- * iSCSI string block descriptor
+ * iSCSI string buffer
*
* This is an internal structure that we use to keep track of the
* allocation of string data.
*/
struct ibft_strings {
- /** The iBFT containing these strings */
- struct ibft_table *table;
- /** Offset of first free byte within iBFT */
- size_t offset;
- /** Total length of the iBFT */
+ /** Strings data */
+ char *data;
+ /** Starting offset of strings */
+ size_t start;
+ /** Total length */
size_t len;
};
/**
+ * Align structure within iBFT
+ *
+ * @v len Unaligned length (or offset)
+ * @ret len Aligned length (or offset)
+ */
+static inline size_t ibft_align ( size_t len ) {
+
+ return ( ( len + IBFT_ALIGN - 1 ) & ~( IBFT_ALIGN - 1 ) );
+}
+
+/**
* Fill in an IP address field within iBFT
*
* @v ipaddr IP address field
@@ -141,15 +137,29 @@ static const char * ibft_ipaddr ( struct ibft_ipaddr *ipaddr ) {
*/
static char * ibft_alloc_string ( struct ibft_strings *strings,
struct ibft_string *string, size_t len ) {
+ size_t new_len;
+ char *new_data;
+ char *dest;
- if ( ( strings->offset + len ) >= strings->len )
+ /* Extend string data buffer */
+ new_len = ( strings->len + len + 1 /* NUL */ );
+ new_data = realloc ( strings->data, new_len );
+ if ( ! new_data )
return NULL;
+ strings->data = new_data;
- string->offset = cpu_to_le16 ( strings->offset );
+ /* Fill in string field */
+ string->offset = cpu_to_le16 ( strings->start + strings->len );
string->len = cpu_to_le16 ( len );
- strings->offset += ( len + 1 );
- return ( ( ( char * ) strings->table ) + string->offset );
+ /* Zero string */
+ dest = ( strings->data + strings->len );
+ memset ( dest, 0, ( len + 1 /* NUL */ ) );
+
+ /* Update allocated length */
+ strings->len = new_len;
+
+ return dest;
}
/**
@@ -217,8 +227,28 @@ static int ibft_set_string_setting ( struct settings *settings,
*/
static const char * ibft_string ( struct ibft_strings *strings,
struct ibft_string *string ) {
- return ( string->offset ?
- ( ( ( char * ) strings->table ) + string->offset ) : NULL );
+ size_t offset = le16_to_cpu ( string->offset );
+
+ return ( offset ? ( strings->data + offset - strings->start ) : NULL );
+}
+
+/**
+ * Check if network device is required for the iBFT
+ *
+ * @v netdev Network device
+ * @ret is_required Network device is required
+ */
+static int ibft_netdev_is_required ( struct net_device *netdev ) {
+ struct iscsi_session *iscsi;
+ struct sockaddr_tcpip *st_target;
+
+ list_for_each_entry ( iscsi, &ibft_model.descs, desc.list ) {
+ st_target = ( struct sockaddr_tcpip * ) &iscsi->target_sockaddr;
+ if ( tcpip_netdev ( st_target ) == netdev )
+ return 1;
+ }
+
+ return 0;
}
/**
@@ -245,29 +275,33 @@ static int ibft_fill_nic ( struct ibft_nic *nic,
nic->header.length = cpu_to_le16 ( sizeof ( *nic ) );
nic->header.flags = ( IBFT_FL_NIC_BLOCK_VALID |
IBFT_FL_NIC_FIRMWARE_BOOT_SELECTED );
+ DBG ( "iBFT NIC %d is %s\n", nic->header.index, netdev->name );
/* Determine origin of IP address */
fetch_setting ( parent, &ip_setting, &origin, NULL, NULL, 0 );
nic->origin = ( ( origin == parent ) ?
IBFT_NIC_ORIGIN_MANUAL : IBFT_NIC_ORIGIN_DHCP );
- DBG ( "iBFT NIC origin = %d\n", nic->origin );
+ DBG ( "iBFT NIC %d origin = %d\n", nic->header.index, nic->origin );
/* Extract values from configuration settings */
ibft_set_ipaddr_setting ( parent, &nic->ip_address, &ip_setting, 1 );
- DBG ( "iBFT NIC IP = %s\n", ibft_ipaddr ( &nic->ip_address ) );
+ DBG ( "iBFT NIC %d IP = %s\n",
+ nic->header.index, ibft_ipaddr ( &nic->ip_address ) );
ibft_set_ipaddr_setting ( parent, &nic->gateway, &gateway_setting, 1 );
- DBG ( "iBFT NIC gateway = %s\n", ibft_ipaddr ( &nic->gateway ) );
+ DBG ( "iBFT NIC %d gateway = %s\n",
+ nic->header.index, ibft_ipaddr ( &nic->gateway ) );
ibft_set_ipaddr_setting ( NULL, &nic->dns[0], &dns_setting,
( sizeof ( nic->dns ) /
sizeof ( nic->dns[0] ) ) );
ibft_set_ipaddr_setting ( parent, &nic->dhcp, &dhcp_server_setting, 1 );
- DBG ( "iBFT NIC DNS = %s", ibft_ipaddr ( &nic->dns[0] ) );
+ DBG ( "iBFT NIC %d DNS = %s",
+ nic->header.index, ibft_ipaddr ( &nic->dns[0] ) );
DBG ( ", %s\n", ibft_ipaddr ( &nic->dns[1] ) );
if ( ( rc = ibft_set_string_setting ( NULL, strings, &nic->hostname,
&hostname_setting ) ) != 0 )
return rc;
- DBG ( "iBFT NIC hostname = %s\n",
- ibft_string ( strings, &nic->hostname ) );
+ DBG ( "iBFT NIC %d hostname = %s\n",
+ nic->header.index, ibft_string ( strings, &nic->hostname ) );
/* Derive subnet mask prefix from subnet mask */
fetch_ipv4_setting ( parent, &netmask_setting, &netmask_addr );
@@ -277,19 +311,24 @@ static int ibft_fill_nic ( struct ibft_nic *nic,
netmask_addr.s_addr >>= 1;
}
nic->subnet_mask_prefix = netmask_count;
- DBG ( "iBFT NIC subnet = /%d\n", nic->subnet_mask_prefix );
+ DBG ( "iBFT NIC %d subnet = /%d\n",
+ nic->header.index, nic->subnet_mask_prefix );
/* Extract values from net-device configuration */
nic->vlan = cpu_to_le16 ( vlan_tag ( netdev ) );
- DBG ( "iBFT NIC VLAN = %02x\n", le16_to_cpu ( nic->vlan ) );
+ DBG ( "iBFT NIC %d VLAN = %02x\n",
+ nic->header.index, le16_to_cpu ( nic->vlan ) );
if ( ( rc = ll_protocol->eth_addr ( netdev->ll_addr,
nic->mac_address ) ) != 0 ) {
- DBG ( "Could not determine iBFT MAC: %s\n", strerror ( rc ) );
+ DBG ( "Could not determine %s MAC: %s\n",
+ netdev->name, strerror ( rc ) );
return rc;
}
- DBG ( "iBFT NIC MAC = %s\n", eth_ntoa ( nic->mac_address ) );
+ DBG ( "iBFT NIC %d MAC = %s\n",
+ nic->header.index, eth_ntoa ( nic->mac_address ) );
nic->pci_bus_dev_func = cpu_to_le16 ( netdev->dev->desc.location );
- DBG ( "iBFT NIC PCI = %04x\n", le16_to_cpu ( nic->pci_bus_dev_func ) );
+ DBG ( "iBFT NIC %d PCI = %04x\n",
+ nic->header.index, le16_to_cpu ( nic->pci_bus_dev_func ) );
return 0;
}
@@ -299,12 +338,10 @@ static int ibft_fill_nic ( struct ibft_nic *nic,
*
* @v initiator Initiator portion of iBFT
* @v strings iBFT string block descriptor
- * @v iscsi iSCSI session
* @ret rc Return status code
*/
static int ibft_fill_initiator ( struct ibft_initiator *initiator,
- struct ibft_strings *strings,
- struct iscsi_session *iscsi ) {
+ struct ibft_strings *strings ) {
int rc;
/* Fill in common header */
@@ -314,17 +351,58 @@ static int ibft_fill_initiator ( struct ibft_initiator *initiator,
initiator->header.flags = ( IBFT_FL_INITIATOR_BLOCK_VALID |
IBFT_FL_INITIATOR_FIRMWARE_BOOT_SELECTED );
- /* Fill in hostname */
- if ( ( rc = ibft_set_string ( strings, &initiator->initiator_name,
- iscsi->initiator_iqn ) ) != 0 )
+ /* Fill in initiator name */
+ if ( ( rc = ibft_set_string_setting ( NULL, strings,
+ &initiator->initiator_name,
+ &initiator_iqn_setting ) ) != 0 )
return rc;
- DBG ( "iBFT initiator hostname = %s\n",
+ DBG ( "iBFT initiator name = %s\n",
ibft_string ( strings, &initiator->initiator_name ) );
return 0;
}
/**
+ * Fill in Target NIC association
+ *
+ * @v target Target portion of iBFT
+ * @v iscsi iSCSI session
+ * @ret rc Return status code
+ */
+static int ibft_fill_target_nic_association ( struct ibft_target *target,
+ struct iscsi_session *iscsi ) {
+ struct sockaddr_tcpip *st_target =
+ ( struct sockaddr_tcpip * ) &iscsi->target_sockaddr;
+ struct net_device *associated;
+ struct net_device *netdev;
+
+ /* Find network device used to reach target */
+ associated = tcpip_netdev ( st_target );
+ if ( ! associated ) {
+ DBG ( "iBFT target %d has no net device\n",
+ target->header.index );
+ return -EHOSTUNREACH;
+ }
+
+ /* Calculate association */
+ for_each_netdev ( netdev ) {
+ if ( netdev == associated ) {
+ DBG ( "iBFT target %d uses NIC %d (%s)\n",
+ target->header.index, target->nic_association,
+ netdev->name );
+ return 0;
+ }
+ if ( ! ibft_netdev_is_required ( netdev ) )
+ continue;
+ target->nic_association++;
+ }
+
+ DBG ( "iBFT target %d has impossible NIC %s\n",
+ target->header.index, netdev->name );
+ return -EINVAL;
+}
+
+/**
* Fill in Target CHAP portion of iBFT
*
* @v target Target portion of iBFT
@@ -347,12 +425,12 @@ static int ibft_fill_target_chap ( struct ibft_target *target,
if ( ( rc = ibft_set_string ( strings, &target->chap_name,
iscsi->initiator_username ) ) != 0 )
return rc;
- DBG ( "iBFT target username = %s\n",
+ DBG ( "iBFT target %d username = %s\n", target->header.index,
ibft_string ( strings, &target->chap_name ) );
if ( ( rc = ibft_set_string ( strings, &target->chap_secret,
iscsi->initiator_password ) ) != 0 )
return rc;
- DBG ( "iBFT target password = <redacted>\n" );
+ DBG ( "iBFT target %d password = <redacted>\n", target->header.index );
return 0;
}
@@ -382,12 +460,13 @@ static int ibft_fill_target_reverse_chap ( struct ibft_target *target,
if ( ( rc = ibft_set_string ( strings, &target->reverse_chap_name,
iscsi->target_username ) ) != 0 )
return rc;
- DBG ( "iBFT target reverse username = %s\n",
+ DBG ( "iBFT target %d reverse username = %s\n", target->header.index,
ibft_string ( strings, &target->chap_name ) );
if ( ( rc = ibft_set_string ( strings, &target->reverse_chap_secret,
iscsi->target_password ) ) != 0 )
return rc;
- DBG ( "iBFT target reverse password = <redacted>\n" );
+ DBG ( "iBFT target %d reverse password = <redacted>\n",
+ target->header.index );
return 0;
}
@@ -403,6 +482,8 @@ static int ibft_fill_target_reverse_chap ( struct ibft_target *target,
static int ibft_fill_target ( struct ibft_target *target,
struct ibft_strings *strings,
struct iscsi_session *iscsi ) {
+ struct sockaddr_tcpip *st_target =
+ ( struct sockaddr_tcpip * ) &iscsi->target_sockaddr;
struct sockaddr_in *sin_target =
( struct sockaddr_in * ) &iscsi->target_sockaddr;
int rc;
@@ -416,17 +497,21 @@ static int ibft_fill_target ( struct ibft_target *target,
/* Fill in Target values */
ibft_set_ipaddr ( &target->ip_address, sin_target->sin_addr );
- DBG ( "iBFT target IP = %s\n", ibft_ipaddr ( &target->ip_address ) );
- target->socket = cpu_to_le16 ( ntohs ( sin_target->sin_port ) );
- DBG ( "iBFT target port = %d\n", target->socket );
+ DBG ( "iBFT target %d IP = %s\n",
+ target->header.index, ibft_ipaddr ( &target->ip_address ) );
+ target->socket = cpu_to_le16 ( ntohs ( st_target->st_port ) );
+ DBG ( "iBFT target %d port = %d\n",
+ target->header.index, target->socket );
memcpy ( &target->boot_lun, &iscsi->lun, sizeof ( target->boot_lun ) );
- DBG ( "iBFT target boot LUN = " SCSI_LUN_FORMAT "\n",
- SCSI_LUN_DATA ( target->boot_lun ) );
+ DBG ( "iBFT target %d boot LUN = " SCSI_LUN_FORMAT "\n",
+ target->header.index, SCSI_LUN_DATA ( target->boot_lun ) );
if ( ( rc = ibft_set_string ( strings, &target->target_name,
iscsi->target_iqn ) ) != 0 )
return rc;
- DBG ( "iBFT target name = %s\n",
+ DBG ( "iBFT target %d name = %s\n", target->header.index,
ibft_string ( strings, &target->target_name ) );
+ if ( ( rc = ibft_fill_target_nic_association ( target, iscsi ) ) != 0 )
+ return rc;
if ( ( rc = ibft_fill_target_chap ( target, strings, iscsi ) ) != 0 )
return rc;
if ( ( rc = ibft_fill_target_reverse_chap ( target, strings,
@@ -437,62 +522,159 @@ static int ibft_fill_target ( struct ibft_target *target,
}
/**
- * Fill in iBFT
+ * Check if iBFT descriptor is complete
*
- * @v iscsi iSCSI session
- * @v acpi ACPI table
- * @v len Length of ACPI table
+ * @v desc ACPI descriptor
* @ret rc Return status code
*/
-int ibft_describe ( struct iscsi_session *iscsi,
- struct acpi_description_header *acpi,
- size_t len ) {
- struct ipxe_ibft *ibft =
- container_of ( acpi, struct ipxe_ibft, table.acpi );
- struct ibft_strings strings = {
- .table = &ibft->table,
- .offset = offsetof ( typeof ( *ibft ), strings ),
- .len = len,
- };
+static int ibft_complete ( struct acpi_descriptor *desc ) {
+ struct iscsi_session *iscsi =
+ container_of ( desc, struct iscsi_session, desc );
+
+ /* Fail if we do not yet have the target address */
+ if ( ! iscsi->target_sockaddr.sa_family )
+ return -EAGAIN;
+
+ return 0;
+}
+
+/**
+ * Install iBFT
+ *
+ * @v install Installation method
+ * @ret rc Return status code
+ */
+static int ibft_install ( int ( * install ) ( struct acpi_header *acpi ) ) {
struct net_device *netdev;
+ struct iscsi_session *iscsi;
+ struct ibft_table *table;
+ struct ibft_initiator *initiator;
+ struct ibft_nic *nic;
+ struct ibft_target *target;
+ struct ibft_strings strings;
+ struct acpi_header *acpi;
+ void *data;
+ unsigned int targets = 0;
+ unsigned int pairs = 0;
+ size_t offset = 0;
+ size_t table_len;
+ size_t control_len;
+ size_t initiator_offset;
+ size_t nic_offset;
+ size_t target_offset;
+ size_t strings_offset;
+ size_t len;
+ unsigned int i;
int rc;
- /* Ugly hack. Now that we have a generic interface mechanism
- * that can support ioctls, we can potentially eliminate this.
- */
- netdev = last_opened_netdev();
- if ( ! netdev ) {
- DBGC ( iscsi, "iSCSI %p cannot guess network device\n",
- iscsi );
- return -ENODEV;
+ /* Calculate table sizes and offsets */
+ list_for_each_entry ( iscsi, &ibft_model.descs, desc.list )
+ targets++;
+ pairs = ( sizeof ( table->control.pair ) /
+ sizeof ( table->control.pair[0] ) );
+ if ( pairs < targets )
+ pairs = targets;
+ offset = offsetof ( typeof ( *table ), control.pair );
+ offset += ( pairs * sizeof ( table->control.pair[0] ) );
+ table_len = offset;
+ control_len = ( table_len - offsetof ( typeof ( *table ), control ) );
+ offset = ibft_align ( offset );
+ initiator_offset = offset;
+ offset += ibft_align ( sizeof ( *initiator ) );
+ nic_offset = offset;
+ offset += ( pairs * ibft_align ( sizeof ( *nic ) ) );
+ target_offset = offset;
+ offset += ( pairs * ibft_align ( sizeof ( *target ) ) );
+ strings_offset = offset;
+ strings.data = NULL;
+ strings.start = strings_offset;
+ strings.len = 0;
+ len = offset;
+
+ /* Allocate table */
+ data = zalloc ( len );
+ if ( ! data ) {
+ rc = -ENOMEM;
+ goto err_alloc;
}
- /* Fill in ACPI header */
- ibft->table.acpi.signature = cpu_to_le32 ( IBFT_SIG );
- ibft->table.acpi.length = cpu_to_le32 ( len );
- ibft->table.acpi.revision = 1;
-
/* Fill in Control block */
- ibft->table.control.header.structure_id = IBFT_STRUCTURE_ID_CONTROL;
- ibft->table.control.header.version = 1;
- ibft->table.control.header.length =
- cpu_to_le16 ( sizeof ( ibft->table.control ) );
- ibft->table.control.initiator =
- cpu_to_le16 ( offsetof ( typeof ( *ibft ), initiator ) );
- ibft->table.control.nic_0 =
- cpu_to_le16 ( offsetof ( typeof ( *ibft ), nic ) );
- ibft->table.control.target_0 =
- cpu_to_le16 ( offsetof ( typeof ( *ibft ), target ) );
-
- /* Fill in NIC, Initiator and Target blocks */
- if ( ( rc = ibft_fill_nic ( &ibft->nic, &strings, netdev ) ) != 0 )
- return rc;
- if ( ( rc = ibft_fill_initiator ( &ibft->initiator, &strings,
- iscsi ) ) != 0 )
- return rc;
- if ( ( rc = ibft_fill_target ( &ibft->target, &strings,
- iscsi ) ) != 0 )
- return rc;
+ table = data;
+ table->control.header.structure_id = IBFT_STRUCTURE_ID_CONTROL;
+ table->control.header.version = 1;
+ table->control.header.length = cpu_to_le16 ( control_len );
+
+ /* Fill in Initiator block */
+ initiator = ( data + initiator_offset );
+ table->control.initiator = cpu_to_le16 ( initiator_offset );
+ if ( ( rc = ibft_fill_initiator ( initiator, &strings ) ) != 0 )
+ goto err_initiator;
+
+ /* Fill in NIC blocks */
+ i = 0;
+ for_each_netdev ( netdev ) {
+ if ( ! ibft_netdev_is_required ( netdev ) )
+ continue;
+ assert ( i < pairs );
+ table->control.pair[i].nic = nic_offset;
+ nic = ( data + nic_offset );
+ nic->header.index = i;
+ if ( ( rc = ibft_fill_nic ( nic, &strings, netdev ) ) != 0 )
+ goto err_nic;
+ i++;
+ nic_offset += ibft_align ( sizeof ( *nic ) );
+ }
- return 0;
+ /* Fill in Target blocks */
+ i = 0;
+ list_for_each_entry ( iscsi, &ibft_model.descs, desc.list ) {
+ assert ( i < pairs );
+ table->control.pair[i].target = target_offset;
+ target = ( data + target_offset );
+ target->header.index = i;
+ if ( ( rc = ibft_fill_target ( target, &strings, iscsi ) ) != 0)
+ goto err_target;
+ i++;
+ target_offset += ibft_align ( sizeof ( *target ) );
+ }
+
+ /* Reallocate table to include space for strings */
+ len += strings.len;
+ acpi = realloc ( data, len );
+ if ( ! acpi )
+ goto err_realloc;
+ data = NULL;
+
+ /* Fill in ACPI header */
+ acpi->signature = cpu_to_le32 ( IBFT_SIG );
+ acpi->length = cpu_to_le32 ( len );
+ acpi->revision = 1;
+
+ /* Append strings */
+ memcpy ( ( ( ( void * ) acpi ) + strings_offset ), strings.data,
+ strings.len );
+
+ /* Install ACPI table */
+ if ( ( rc = install ( acpi ) ) != 0 ) {
+ DBG ( "iBFT could not install: %s\n", strerror ( rc ) );
+ goto err_install;
+ }
+
+ err_install:
+ free ( acpi );
+ err_realloc:
+ err_target:
+ err_nic:
+ err_initiator:
+ free ( data );
+ err_alloc:
+ free ( strings.data );
+ return rc;
}
+
+/** iBFT model */
+struct acpi_model ibft_model __acpi_model = {
+ .descs = LIST_HEAD_INIT ( ibft_model.descs ),
+ .complete = ibft_complete,
+ .install = ibft_install,
+};
diff --git a/src/drivers/block/srp.c b/src/drivers/block/srp.c
index 7edf69ac..ab481251 100644
--- a/src/drivers/block/srp.c
+++ b/src/drivers/block/srp.c
@@ -113,13 +113,6 @@ struct srp_device {
/** Login completed successfully */
int logged_in;
- /** Initiator port ID (for boot firmware table) */
- union srp_port_id initiator;
- /** Target port ID (for boot firmware table) */
- union srp_port_id target;
- /** SCSI LUN (for boot firmware table) */
- struct scsi_lun lun;
-
/** List of active commands */
struct list_head commands;
};
@@ -684,61 +677,6 @@ static size_t srpdev_window ( struct srp_device *srpdev ) {
return ( srpdev->logged_in ? ~( ( size_t ) 0 ) : 0 );
}
-/**
- * A (transport-independent) sBFT created by iPXE
- */
-struct ipxe_sbft {
- /** The table header */
- struct sbft_table table;
- /** The SCSI subtable */
- struct sbft_scsi_subtable scsi;
- /** The SRP subtable */
- struct sbft_srp_subtable srp;
-} __attribute__ (( packed, aligned ( 16 ) ));
-
-/**
- * Describe SRP device in an ACPI table
- *
- * @v srpdev SRP device
- * @v acpi ACPI table
- * @v len Length of ACPI table
- * @ret rc Return status code
- */
-static int srpdev_describe ( struct srp_device *srpdev,
- struct acpi_description_header *acpi,
- size_t len ) {
- struct ipxe_sbft *sbft =
- container_of ( acpi, struct ipxe_sbft, table.acpi );
- int rc;
-
- /* Sanity check */
- if ( len < sizeof ( *sbft ) )
- return -ENOBUFS;
-
- /* Populate table */
- 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 ) );
- memcpy ( &sbft->scsi.lun, &srpdev->lun, sizeof ( sbft->scsi.lun ) );
- sbft->table.srp_offset =
- cpu_to_le16 ( offsetof ( typeof ( *sbft ), srp ) );
- memcpy ( &sbft->srp.initiator, &srpdev->initiator,
- sizeof ( sbft->srp.initiator ) );
- memcpy ( &sbft->srp.target, &srpdev->target,
- sizeof ( sbft->srp.target ) );
-
- /* Ask transport layer to describe transport-specific portions */
- if ( ( rc = acpi_describe ( &srpdev->socket, acpi, len ) ) != 0 ) {
- DBGC ( srpdev, "SRP %p cannot describe transport layer: %s\n",
- srpdev, strerror ( rc ) );
- return rc;
- }
-
- return 0;
-}
-
/** SRP device socket interface operations */
static struct interface_operation srpdev_socket_op[] = {
INTF_OP ( xfer_deliver, struct srp_device *, srpdev_deliver ),
@@ -755,7 +693,6 @@ static struct interface_operation srpdev_scsi_op[] = {
INTF_OP ( scsi_command, struct srp_device *, srpdev_scsi_command ),
INTF_OP ( xfer_window, struct srp_device *, srpdev_window ),
INTF_OP ( intf_close, struct srp_device *, srpdev_close ),
- INTF_OP ( acpi_describe, struct srp_device *, srpdev_describe ),
};
/** SRP device SCSI interface descriptor */
@@ -797,11 +734,6 @@ int srp_open ( struct interface *block, struct interface *socket,
ntohl ( target->dwords[0] ), ntohl ( target->dwords[1] ),
ntohl ( target->dwords[2] ), ntohl ( target->dwords[3] ) );
- /* Preserve parameters required for boot firmware table */
- memcpy ( &srpdev->initiator, initiator, sizeof ( srpdev->initiator ) );
- memcpy ( &srpdev->target, target, sizeof ( srpdev->target ) );
- memcpy ( &srpdev->lun, lun, sizeof ( srpdev->lun ) );
-
/* Attach to socket interface and initiate login */
intf_plug_plug ( &srpdev->socket, socket );
tag = srp_new_tag ( srpdev );