summaryrefslogtreecommitdiffstats
path: root/src/net/tcp
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/net/tcp
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/net/tcp')
-rw-r--r--src/net/tcp/httpblock.c18
-rw-r--r--src/net/tcp/httpcore.c17
-rw-r--r--src/net/tcp/iscsi.c14
3 files changed, 13 insertions, 36 deletions
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 )