summaryrefslogtreecommitdiffstats
path: root/src/include/ipxe
diff options
context:
space:
mode:
authorMichael Brown2010-09-03 17:11:51 +0200
committerMichael Brown2010-09-14 21:37:15 +0200
commit220495f8bf2222e1dc1aa7db554d23997b545546 (patch)
treef04aa0d123a0b643fc41e178db81cfe63ba913bf /src/include/ipxe
parent[hermon] Use correct alignment for doorbell records (diff)
downloadipxe-220495f8bf2222e1dc1aa7db554d23997b545546.tar.gz
ipxe-220495f8bf2222e1dc1aa7db554d23997b545546.tar.xz
ipxe-220495f8bf2222e1dc1aa7db554d23997b545546.zip
[block] Replace gPXE block-device API with an iPXE asynchronous interface
The block device interface used in gPXE predates the invention of even the old gPXE data-transfer interface, let alone the current iPXE generic asynchronous interface mechanism. Bring this old code up to date, with the following benefits: o Block device commands can be cancelled by the requestor. The INT 13 layer uses this to provide a global timeout on all INT 13 calls, with the result that an unexpected passive failure mode (such as an iSCSI target ACKing the request but never sending a response) will lead to a timeout that gets reported back to the INT 13 user, rather than simply freezing the system. o INT 13,00 (reset drive) is now able to reset the underlying block device. INT 13 users, such as DOS, that use INT 13,00 as a method for error recovery now have a chance of recovering. o All block device commands are tagged, with a numerical tag that will show up in debugging output and in packet captures; this will allow easier interpretation of bug reports that include both sources of information. o The extremely ugly hacks used to generate the boot firmware tables have been eradicated and replaced with a generic acpi_describe() method (exploiting the ability of iPXE interfaces to pass through methods to an underlying interface). The ACPI tables are now built in a shared data block within .bss16, rather than each requiring dedicated space in .data16. o The architecture-independent concept of a SAN device has been exposed to the iPXE core through the sanboot API, which provides calls to hook, unhook, boot, and describe SAN devices. This allows for much more flexible usage patterns (such as hooking an empty SAN device and then running an OS installer via TFTP). Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/include/ipxe')
-rw-r--r--src/include/ipxe/acpi.h22
-rw-r--r--src/include/ipxe/aoe.h67
-rw-r--r--src/include/ipxe/ata.h85
-rw-r--r--src/include/ipxe/blockdev.h70
-rw-r--r--src/include/ipxe/errfile.h3
-rw-r--r--src/include/ipxe/ib_srp.h75
-rw-r--r--src/include/ipxe/ibft.h271
-rw-r--r--src/include/ipxe/iscsi.h71
-rw-r--r--src/include/ipxe/null_sanboot.h18
-rw-r--r--src/include/ipxe/ramdisk.h24
-rw-r--r--src/include/ipxe/sanboot.h91
-rw-r--r--src/include/ipxe/scsi.h100
-rw-r--r--src/include/ipxe/srp.h193
13 files changed, 681 insertions, 409 deletions
diff --git a/src/include/ipxe/acpi.h b/src/include/ipxe/acpi.h
index eabbec39..282b6d92 100644
--- a/src/include/ipxe/acpi.h
+++ b/src/include/ipxe/acpi.h
@@ -10,6 +10,7 @@
FILE_LICENCE ( GPL2_OR_LATER );
#include <stdint.h>
+#include <ipxe/interface.h>
/**
* An ACPI description header
@@ -19,7 +20,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
*/
struct acpi_description_header {
/** ACPI signature (4 ASCII characters) */
- char signature[4];
+ uint32_t signature;
/** Length of table, in bytes, including header */
uint32_t length;
/** ACPI Specification minor version number */
@@ -38,6 +39,25 @@ struct acpi_description_header {
uint32_t asl_compiler_revision;
} __attribute__ (( packed ));
+/**
+ * Build ACPI signature
+ *
+ * @v a First character of ACPI signature
+ * @v b Second character of ACPI signature
+ * @v c Third character of ACPI signature
+ * @v d Fourth character of ACPI signature
+ * @ret signature ACPI signature
+ */
+#define ACPI_SIGNATURE( a, b, c, d ) \
+ ( ( (a) << 0 ) | ( (b) << 8 ) | ( (c) << 16 ) | ( (d) << 24 ) )
+
+extern int acpi_describe ( struct interface *interface,
+ struct acpi_description_header *acpi, size_t len );
+#define acpi_describe_TYPE( object_type ) \
+ typeof ( int ( object_type, \
+ struct acpi_description_header *acpi, \
+ size_t len ) )
+
extern void acpi_fix_checksum ( struct acpi_description_header *acpi );
#endif /* _IPXE_ACPI_H */
diff --git a/src/include/ipxe/aoe.h b/src/include/ipxe/aoe.h
index d2a12858..60f3bd95 100644
--- a/src/include/ipxe/aoe.h
+++ b/src/include/ipxe/aoe.h
@@ -14,10 +14,11 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <ipxe/if_ether.h>
#include <ipxe/retry.h>
#include <ipxe/ata.h>
+#include <ipxe/acpi.h>
/** An AoE config command */
struct aoecfg {
- /** AoE Queue depth */
+ /** AoE queue depth */
uint16_t bufcnt;
/** ATA target firmware version */
uint16_t fwver;
@@ -78,7 +79,7 @@ struct aoehdr {
/** Tag, in network byte order */
uint32_t tag;
/** Payload */
- union aoecmd cmd[0];
+ union aoecmd payload[0];
} __attribute__ (( packed ));
#define AOE_VERSION 0x10 /**< Version 1 */
@@ -93,58 +94,38 @@ struct aoehdr {
#define AOE_CMD_ATA 0x00 /**< Issue ATA command */
#define AOE_CMD_CONFIG 0x01 /**< Query Config Information */
-#define AOE_TAG_MAGIC 0xebeb0000
-
#define AOE_ERR_BAD_COMMAND 1 /**< Unrecognised command code */
#define AOE_ERR_BAD_PARAMETER 2 /**< Bad argument parameter */
#define AOE_ERR_UNAVAILABLE 3 /**< Device unavailable */
#define AOE_ERR_CONFIG_EXISTS 4 /**< Config string present */
#define AOE_ERR_BAD_VERSION 5 /**< Unsupported version */
-/** An AoE session */
-struct aoe_session {
- /** Reference counter */
- struct refcnt refcnt;
-
- /** List of all AoE sessions */
- struct list_head list;
-
- /** Network device */
- struct net_device *netdev;
-
- /** Major number */
- uint16_t major;
- /** Minor number */
- uint8_t minor;
- /** Target MAC address */
- uint8_t target[ETH_ALEN];
-
- /** Tag for current AoE command */
- uint32_t tag;
-
- /** Current AOE command */
- uint8_t aoe_cmd_type;
- /** Current ATA command */
- struct ata_command *command;
- /** Overall status of current ATA command */
- unsigned int status;
- /** Byte offset within command's data buffer */
- unsigned int command_offset;
- /** Return status code for command */
- int rc;
-
- /** Retransmission timer */
- struct retry_timer timer;
-};
-
#define AOE_STATUS_ERR_MASK 0x0f /**< Error portion of status code */
#define AOE_STATUS_PENDING 0x80 /**< Command pending */
+/** AoE tag magic marker */
+#define AOE_TAG_MAGIC 0x18ae0000
+
/** Maximum number of sectors per packet */
#define AOE_MAX_COUNT 2
-extern void aoe_detach ( struct ata_device *ata );
-extern int aoe_attach ( struct ata_device *ata, struct net_device *netdev,
- const char *root_path );
+/** AoE boot firmware table signature */
+#define ABFT_SIG ACPI_SIGNATURE ( 'a', 'B', 'F', 'T' )
+
+/**
+ * AoE Boot Firmware Table (aBFT)
+ */
+struct abft_table {
+ /** ACPI header */
+ struct acpi_description_header acpi;
+ /** AoE shelf */
+ uint16_t shelf;
+ /** AoE slot */
+ uint8_t slot;
+ /** Reserved */
+ uint8_t reserved_a;
+ /** MAC address */
+ uint8_t mac[ETH_ALEN];
+} __attribute__ (( packed ));
#endif /* _IPXE_AOE_H */
diff --git a/src/include/ipxe/ata.h b/src/include/ipxe/ata.h
index 043e3705..b7f02d65 100644
--- a/src/include/ipxe/ata.h
+++ b/src/include/ipxe/ata.h
@@ -2,9 +2,8 @@
#define _IPXE_ATA_H
#include <stdint.h>
-#include <ipxe/blockdev.h>
#include <ipxe/uaccess.h>
-#include <ipxe/refcnt.h>
+#include <ipxe/interface.h>
/** @file
*
@@ -104,7 +103,7 @@ struct ata_cb {
uint8_t device;
/** Command/status register */
uint8_t cmd_stat;
- /** LBA48 addressing flag */
+ /** Use LBA48 extended addressing */
int lba48;
};
@@ -138,25 +137,8 @@ struct ata_cb {
/** "Identify" command */
#define ATA_CMD_IDENTIFY 0xec
-/** An ATA command */
-struct ata_command {
- /** ATA command block */
- struct ata_cb cb;
- /** Data-out buffer (may be NULL)
- *
- * If non-NULL, this buffer must be ata_command::cb::count
- * sectors in size.
- */
- userptr_t data_out;
- /** Data-in buffer (may be NULL)
- *
- * If non-NULL, this buffer must be ata_command::cb::count
- * sectors in size.
- */
- userptr_t data_in;
- /** Command status code */
- int rc;
-};
+/** Command completed in error */
+#define ATA_STAT_ERR 0x01
/**
* Structure returned by ATA IDENTIFY command
@@ -165,13 +147,15 @@ struct ata_command {
* so we implement only a few fields.
*/
struct ata_identity {
- uint16_t ignore_a[60]; /* words 0-59 */
+ uint16_t ignore_a[27]; /* words 0-26 */
+ uint16_t model[20]; /* words 27-46 */
+ uint16_t ignore_b[13]; /* words 47-59 */
uint32_t lba_sectors; /* words 60-61 */
- uint16_t ignore_b[21]; /* words 62-82 */
+ uint16_t ignore_c[21]; /* words 62-82 */
uint16_t supports_lba48; /* word 83 */
- uint16_t ignore_c[16]; /* words 84-99 */
+ uint16_t ignore_d[16]; /* words 84-99 */
uint64_t lba48_sectors; /* words 100-103 */
- uint16_t ignore_d[152]; /* words 104-255 */
+ uint16_t ignore_e[152]; /* words 104-255 */
};
/** Supports LBA48 flag */
@@ -180,30 +164,41 @@ struct ata_identity {
/** ATA sector size */
#define ATA_SECTOR_SIZE 512
-/** An ATA device */
-struct ata_device {
- /** Block device interface */
- struct block_device blockdev;
- /** Device number
+/** An ATA command information unit */
+struct ata_cmd {
+ /** ATA command block */
+ struct ata_cb cb;
+ /** Data-out buffer (may be NULL)
*
- * Must be ATA_DEV_MASTER or ATA_DEV_SLAVE.
+ * If non-NULL, this buffer must be ata_command::cb::count
+ * sectors in size.
*/
- int device;
- /** LBA48 extended addressing */
- int lba48;
- /**
- * Issue ATA command
+ userptr_t data_out;
+ /** Data-out buffer length
*
- * @v ata ATA device
- * @v command ATA command
- * @ret rc Return status code
+ * Must be zero if @c data_out is NULL
*/
- int ( * command ) ( struct ata_device *ata,
- struct ata_command *command );
- /** Backing device */
- struct refcnt *backend;
+ size_t data_out_len;
+ /** Data-in buffer (may be NULL)
+ *
+ * If non-NULL, this buffer must be ata_command::cb::count
+ * sectors in size.
+ */
+ userptr_t data_in;
+ /** Data-in buffer length
+ *
+ * Must be zero if @c data_in is NULL
+ */
+ size_t data_in_len;
};
-extern int init_atadev ( struct ata_device *ata );
+extern int ata_command ( struct interface *control, struct interface *data,
+ struct ata_cmd *command );
+#define ata_command_TYPE( object_type ) \
+ typeof ( int ( object_type, struct interface *data, \
+ struct ata_cmd *command ) )
+
+extern int ata_open ( struct interface *block, struct interface *ata,
+ unsigned int device, unsigned int max_count );
#endif /* _IPXE_ATA_H */
diff --git a/src/include/ipxe/blockdev.h b/src/include/ipxe/blockdev.h
index 5c1ab136..9f0a9f78 100644
--- a/src/include/ipxe/blockdev.h
+++ b/src/include/ipxe/blockdev.h
@@ -10,44 +10,46 @@
FILE_LICENCE ( GPL2_OR_LATER );
+#include <stdint.h>
#include <ipxe/uaccess.h>
+#include <ipxe/interface.h>
-struct block_device;
-
-/** Block device operations */
-struct block_device_operations {
- /**
- * Read block
- *
- * @v blockdev Block device
- * @v block Block number
- * @v count Block count
- * @v buffer Data buffer
- * @ret rc Return status code
- */
- int ( * read ) ( struct block_device *blockdev, uint64_t block,
- unsigned long count, userptr_t buffer );
- /**
- * Write block
- *
- * @v blockdev Block device
- * @v block Block number
- * @v count Block count
- * @v buffer Data buffer
- * @ret rc Return status code
- */
- int ( * write ) ( struct block_device *blockdev, uint64_t block,
- unsigned long count, userptr_t buffer );
-};
-
-/** A block device */
-struct block_device {
- /** Block device operations */
- struct block_device_operations *op;
- /** Block size */
- size_t blksize;
+/** Block device capacity */
+struct block_device_capacity {
/** Total number of blocks */
uint64_t blocks;
+ /** Block size */
+ size_t blksize;
+ /** Maximum number of blocks per single transfer */
+ unsigned int max_count;
};
+extern int block_read ( struct interface *control, struct interface *data,
+ uint64_t lba, unsigned int count,
+ userptr_t buffer, size_t len );
+#define block_read_TYPE( object_type ) \
+ typeof ( int ( object_type, struct interface *data, \
+ uint64_t lba, unsigned int count, \
+ userptr_t buffer, size_t len ) )
+
+extern int block_write ( struct interface *control, struct interface *data,
+ uint64_t lba, unsigned int count,
+ userptr_t buffer, size_t len );
+#define block_write_TYPE( object_type ) \
+ typeof ( int ( object_type, struct interface *data, \
+ uint64_t lba, unsigned int count, \
+ userptr_t buffer, size_t len ) )
+
+extern int block_read_capacity ( struct interface *control,
+ struct interface *data );
+#define block_read_capacity_TYPE( object_type ) \
+ typeof ( int ( object_type, struct interface *data ) )
+
+extern void block_capacity ( struct interface *intf,
+ struct block_device_capacity *capacity );
+#define block_capacity_TYPE( object_type ) \
+ typeof ( void ( object_type, \
+ struct block_device_capacity *capacity ) )
+
+
#endif /* _IPXE_BLOCKDEV_H */
diff --git a/src/include/ipxe/errfile.h b/src/include/ipxe/errfile.h
index ad32ed1b..d78f2822 100644
--- a/src/include/ipxe/errfile.h
+++ b/src/include/ipxe/errfile.h
@@ -55,6 +55,9 @@ FILE_LICENCE ( GPL2_OR_LATER );
#define ERRFILE_bitmap ( ERRFILE_CORE | 0x000f0000 )
#define ERRFILE_base64 ( ERRFILE_CORE | 0x00100000 )
#define ERRFILE_base16 ( ERRFILE_CORE | 0x00110000 )
+#define ERRFILE_blockdev ( ERRFILE_CORE | 0x00120000 )
+#define ERRFILE_acpi ( ERRFILE_CORE | 0x00130000 )
+#define ERRFILE_null_sanboot ( ERRFILE_CORE | 0x00140000 )
#define ERRFILE_eisa ( ERRFILE_DRIVER | 0x00000000 )
#define ERRFILE_isa ( ERRFILE_DRIVER | 0x00010000 )
diff --git a/src/include/ipxe/ib_srp.h b/src/include/ipxe/ib_srp.h
index b773f964..902bef56 100644
--- a/src/include/ipxe/ib_srp.h
+++ b/src/include/ipxe/ib_srp.h
@@ -14,45 +14,35 @@ FILE_LICENCE ( BSD2 );
#include <ipxe/srp.h>
/** SRP initiator port identifier for Infiniband */
-struct ib_srp_initiator_port_id {
- /** Identifier extension */
- struct ib_gid_half id_ext;
- /** IB channel adapter GUID */
- struct ib_gid_half hca_guid;
-} __attribute__ (( packed ));
+union ib_srp_initiator_port_id {
+ /** SRP version of port identifier */
+ union srp_port_id srp;
+ /** Infiniband version of port identifier */
+ struct {
+ /** Identifier extension */
+ struct ib_gid_half id_ext;
+ /** IB channel adapter GUID */
+ struct ib_gid_half hca_guid;
+ } __attribute__ (( packed )) ib;
+};
/** SRP target port identifier for Infiniband */
-struct ib_srp_target_port_id {
- /** Identifier extension */
- struct ib_gid_half id_ext;
- /** I/O controller GUID */
- struct ib_gid_half ioc_guid;
-} __attribute__ (( packed ));
-
-/**
- * Get Infiniband-specific initiator port ID
- *
- * @v port_ids SRP port IDs
- * @ret initiator_port_id Infiniband-specific initiator port ID
- */
-static inline __always_inline struct ib_srp_initiator_port_id *
-ib_srp_initiator_port_id ( struct srp_port_ids *port_ids ) {
- return ( ( struct ib_srp_initiator_port_id * ) &port_ids->initiator );
-}
+union ib_srp_target_port_id {
+ /** SRP version of port identifier */
+ union srp_port_id srp;
+ /** Infiniband version of port identifier */
+ struct {
+ /** Identifier extension */
+ struct ib_gid_half id_ext;
+ /** I/O controller GUID */
+ struct ib_gid_half ioc_guid;
+ } __attribute__ (( packed )) ib;
+};
/**
- * Get Infiniband-specific target port ID
- *
- * @v port_ids SRP port IDs
- * @ret target_port_id Infiniband-specific target port ID
+ * sBFT Infiniband subtable
*/
-static inline __always_inline struct ib_srp_target_port_id *
-ib_srp_target_port_id ( struct srp_port_ids *port_ids ) {
- return ( ( struct ib_srp_target_port_id * ) &port_ids->target );
-}
-
-/** Infiniband-specific SRP parameters */
-struct ib_srp_parameters {
+struct sbft_ib_subtable {
/** Source GID */
struct ib_gid sgid;
/** Destination GID */
@@ -61,19 +51,8 @@ struct ib_srp_parameters {
struct ib_gid_half service_id;
/** Partition key */
uint16_t pkey;
-};
-
-/**
- * Get Infiniband-specific transport parameters
- *
- * @v srp SRP device
- * @ret ib_params Infiniband-specific transport parameters
- */
-static inline __always_inline struct ib_srp_parameters *
-ib_srp_params ( struct srp_device *srp ) {
- return srp_transport_priv ( srp );
-}
-
-extern struct srp_transport_type ib_srp_transport;
+ /** Reserved */
+ uint8_t reserved[6];
+} __attribute__ (( packed ));
#endif /* _IPXE_IB_SRP_H */
diff --git a/src/include/ipxe/ibft.h b/src/include/ipxe/ibft.h
new file mode 100644
index 00000000..73372122
--- /dev/null
+++ b/src/include/ipxe/ibft.h
@@ -0,0 +1,271 @@
+#ifndef _IPXE_IBFT_H
+#define _IPXE_IBFT_H
+
+/*
+ * Copyright Fen Systems Ltd. 2007. Portions of this code are derived
+ * from IBM Corporation Sample Programs. Copyright IBM Corporation
+ * 2004, 2007. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+FILE_LICENCE ( BSD2 );
+
+/** @file
+ *
+ * iSCSI boot firmware table
+ *
+ * The information in this file is derived from the document "iSCSI
+ * Boot Firmware Table (iBFT)" as published by IBM at
+ *
+ * ftp://ftp.software.ibm.com/systems/support/system_x_pdf/ibm_iscsi_boot_firmware_table_v1.02.pdf
+ *
+ */
+
+#include <stdint.h>
+#include <ipxe/acpi.h>
+#include <ipxe/scsi.h>
+#include <ipxe/in.h>
+
+/** iSCSI Boot Firmware Table signature */
+#define IBFT_SIG ACPI_SIGNATURE ( 'i', 'B', 'F', 'T' )
+
+/** An offset from the start of the iBFT */
+typedef uint16_t ibft_off_t;
+
+/** Length of a string within the iBFT (excluding terminating NUL) */
+typedef uint16_t ibft_size_t;
+
+/** A string within the iBFT */
+struct ibft_string {
+ /** Length of string */
+ ibft_size_t len;
+ /** Offset to string */
+ ibft_off_t offset;
+} __attribute__ (( packed ));
+
+/** An IP address within the iBFT */
+struct ibft_ipaddr {
+ /** Reserved; must be zero */
+ uint16_t zeroes[5];
+ /** Must be 0xffff if IPv4 address is present, otherwise zero */
+ uint16_t ones;
+ /** The IPv4 address, or zero if not present */
+ struct in_addr in;
+} __attribute__ (( packed ));
+
+/**
+ * iBFT structure header
+ *
+ * This structure is common to several sections within the iBFT.
+ */
+struct ibft_header {
+ /** Structure ID
+ *
+ * This is an IBFT_STRUCTURE_ID_XXX constant
+ */
+ uint8_t structure_id;
+ /** Version (always 1) */
+ uint8_t version;
+ /** Length, including this header */
+ uint16_t length;
+ /** Index
+ *
+ * This is the number of the NIC or Target, when applicable.
+ */
+ uint8_t index;
+ /** Flags */
+ uint8_t flags;
+} __attribute__ (( packed ));
+
+/**
+ * iBFT Control structure
+ *
+ */
+struct ibft_control {
+ /** Common header */
+ struct ibft_header header;
+ /** Extensions */
+ uint16_t extensions;
+ /** Offset to Initiator structure */
+ ibft_off_t initiator;
+ /** Offset to NIC structure for NIC 0 */
+ ibft_off_t nic_0;
+ /** Offset to Target structure for target 0 */
+ ibft_off_t target_0;
+ /** Offset to NIC structure for NIC 1 */
+ ibft_off_t nic_1;
+ /** Offset to Target structure for target 1 */
+ ibft_off_t target_1;
+} __attribute__ (( packed ));
+
+/** Structure ID for Control section */
+#define IBFT_STRUCTURE_ID_CONTROL 0x01
+
+/** Attempt login only to specified target
+ *
+ * If this flag is not set, all targets will be logged in to.
+ */
+#define IBFT_FL_CONTROL_SINGLE_LOGIN_ONLY 0x01
+
+/**
+ * iBFT Initiator structure
+ *
+ */
+struct ibft_initiator {
+ /** Common header */
+ struct ibft_header header;
+ /** iSNS server */
+ struct ibft_ipaddr isns_server;
+ /** SLP server */
+ struct ibft_ipaddr slp_server;
+ /** Primary and secondary Radius servers */
+ struct ibft_ipaddr radius[2];
+ /** Initiator name */
+ struct ibft_string initiator_name;
+} __attribute__ (( packed ));
+
+/** Structure ID for Initiator section */
+#define IBFT_STRUCTURE_ID_INITIATOR 0x02
+
+/** Initiator block valid */
+#define IBFT_FL_INITIATOR_BLOCK_VALID 0x01
+
+/** Initiator firmware boot selected */
+#define IBFT_FL_INITIATOR_FIRMWARE_BOOT_SELECTED 0x02
+
+/**
+ * iBFT NIC structure
+ *
+ */
+struct ibft_nic {
+ /** Common header */
+ struct ibft_header header;
+ /** IP address */
+ struct ibft_ipaddr ip_address;
+ /** Subnet mask
+ *
+ * This is the length of the subnet mask in bits (e.g. /24).
+ */
+ uint8_t subnet_mask_prefix;
+ /** Origin */
+ uint8_t origin;
+ /** Default gateway */
+ struct ibft_ipaddr gateway;
+ /** Primary and secondary DNS servers */
+ struct ibft_ipaddr dns[2];
+ /** DHCP server */
+ struct ibft_ipaddr dhcp;
+ /** VLAN tag */
+ uint16_t vlan;
+ /** MAC address */
+ uint8_t mac_address[6];
+ /** PCI bus:dev:fn */
+ uint16_t pci_bus_dev_func;
+ /** Hostname */
+ struct ibft_string hostname;
+} __attribute__ (( packed ));
+
+/** Structure ID for NIC section */
+#define IBFT_STRUCTURE_ID_NIC 0x03
+
+/** NIC block valid */
+#define IBFT_FL_NIC_BLOCK_VALID 0x01
+
+/** NIC firmware boot selected */
+#define IBFT_FL_NIC_FIRMWARE_BOOT_SELECTED 0x02
+
+/** NIC global / link local */
+#define IBFT_FL_NIC_GLOBAL 0x04
+
+/**
+ * iBFT Target structure
+ *
+ */
+struct ibft_target {
+ /** Common header */
+ struct ibft_header header;
+ /** IP address */
+ struct ibft_ipaddr ip_address;
+ /** TCP port */
+ uint16_t socket;
+ /** Boot LUN */
+ struct scsi_lun boot_lun;
+ /** CHAP type
+ *
+ * This is an IBFT_CHAP_XXX constant.
+ */
+ uint8_t chap_type;
+ /** NIC association */
+ uint8_t nic_association;
+ /** Target name */
+ struct ibft_string target_name;
+ /** CHAP name */
+ struct ibft_string chap_name;
+ /** CHAP secret */
+ struct ibft_string chap_secret;
+ /** Reverse CHAP name */
+ struct ibft_string reverse_chap_name;
+ /** Reverse CHAP secret */
+ struct ibft_string reverse_chap_secret;
+} __attribute__ (( packed ));
+
+/** Structure ID for Target section */
+#define IBFT_STRUCTURE_ID_TARGET 0x04
+
+/** Target block valid */
+#define IBFT_FL_TARGET_BLOCK_VALID 0x01
+
+/** Target firmware boot selected */
+#define IBFT_FL_TARGET_FIRMWARE_BOOT_SELECTED 0x02
+
+/** Target use Radius CHAP */
+#define IBFT_FL_TARGET_USE_CHAP 0x04
+
+/** Target use Radius rCHAP */
+#define IBFT_FL_TARGET_USE_RCHAP 0x08
+
+/* Values for chap_type */
+#define IBFT_CHAP_NONE 0 /**< No CHAP authentication */
+#define IBFT_CHAP_ONE_WAY 1 /**< One-way CHAP */
+#define IBFT_CHAP_MUTUAL 2 /**< Mutual CHAP */
+
+/**
+ * iSCSI Boot Firmware Table (iBFT)
+ */
+struct ibft_table {
+ /** ACPI header */
+ struct acpi_description_header acpi;
+ /** Reserved */
+ uint8_t reserved[12];
+ /** Control structure */
+ struct ibft_control control;
+} __attribute__ (( packed ));
+
+struct iscsi_session;
+struct net_device;
+
+extern int ibft_describe ( struct iscsi_session *iscsi,
+ struct acpi_description_header *acpi,
+ size_t len );
+
+#endif /* _IPXE_IBFT_H */
diff --git a/src/include/ipxe/iscsi.h b/src/include/ipxe/iscsi.h
index a604e1e4..e711459c 100644
--- a/src/include/ipxe/iscsi.h
+++ b/src/include/ipxe/iscsi.h
@@ -90,6 +90,9 @@ struct iscsi_bhs_common {
/** Final PDU of a sequence */
#define ISCSI_FLAG_FINAL 0x80
+/** iSCSI tag magic marker */
+#define ISCSI_TAG_MAGIC 0x18ae0000
+
/**
* iSCSI basic header segment common request fields
*
@@ -307,8 +310,10 @@ struct iscsi_bhs_scsi_response {
uint32_t maxcmdsn;
/** Expected data sequence number */
uint32_t expdatasn;
- /** Reserved */
- uint8_t reserved_b[8];
+ /** Bidirectional read residual count */
+ uint32_t bidi_residual_count;
+ /** Residual count */
+ uint32_t residual_count;
};
/** SCSI response opcode */
@@ -320,13 +325,11 @@ struct iscsi_bhs_scsi_response {
/** SCSI target failure */
#define ISCSI_RESPONSE_TARGET_FAILURE 0x01
-/** SCSI sense response code offset
- *
- * The SCSI response may contain unsolicited sense data in the data
- * segment. If it does, this is the offset to the sense response code
- * byte, which is the only byte we care about.
- */
-#define ISCSI_SENSE_RESPONSE_CODE_OFFSET 2
+/** Data overflow occurred */
+#define ISCSI_RESPONSE_FLAG_OVERFLOW 0x20
+
+/** Data underflow occurred */
+#define ISCSI_RESPONSE_FLAG_UNDERFLOW 0x40
/**
* iSCSI data-in basic header segment
@@ -497,6 +500,10 @@ struct iscsi_session {
/** Reference counter */
struct refcnt refcnt;
+ /** SCSI command-issuing interface */
+ struct interface control;
+ /** SCSI command interface */
+ struct interface data;
/** Transport-layer socket */
struct interface socket;
@@ -506,10 +513,6 @@ struct iscsi_session {
unsigned int target_port;
/** Target IQN */
char *target_iqn;
- /** Logical Unit Number (LUN) */
- struct scsi_lun lun;
- /** Target socket address (recorded only for iBFT) */
- struct sockaddr target_sockaddr;
/** Session status
*
@@ -517,12 +520,6 @@ struct iscsi_session {
* constants.
*/
int status;
- /** Retry count
- *
- * Number of times that the connection has been retried.
- * Reset upon a successful connection.
- */
- int retry_count;
/** Initiator username (if any) */
char *initiator_username;
@@ -542,12 +539,6 @@ struct iscsi_session {
/** CHAP response (used for both initiator and target auth) */
struct chap_response chap;
- /** Target session identifying handle
- *
- * This is assigned by the target when we first log in, and
- * must be reused on subsequent login attempts.
- */
- uint16_t tsih;
/** Initiator task tag
*
* This is the tag of the current command. It is incremented
@@ -560,15 +551,13 @@ struct iscsi_session {
* response to an R2T.
*/
uint32_t ttt;
- /**
- * Transfer offset
+ /** Transfer offset
*
* This is the offset for an in-progress sequence of data-out
* PDUs in response to an R2T.
*/
uint32_t transfer_offset;
- /**
- * Transfer length
+ /** Transfer length
*
* This is the length for an in-progress sequence of data-out
* PDUs in response to an R2T.
@@ -609,18 +598,13 @@ struct iscsi_session {
/** Buffer for received data (not always used) */
void *rx_buffer;
- /** Current SCSI command
- *
- * Set to NULL when command is complete.
- */
- struct scsi_command *command;
- /** Instant return code
- *
- * Set to a non-zero value if all requests should return
- * immediately. This can be used to e.g. avoid retrying
- * logins that are doomed to fail authentication.
- */
- int instant_rc;
+ /** Current SCSI command, if any */
+ struct scsi_cmd *command;
+
+ /** Target socket address (for boot firmware table) */
+ struct sockaddr target_sockaddr;
+ /** SCSI LUN (for boot firmware table) */
+ struct scsi_lun lun;
};
/** iSCSI session is currently in the security negotiation phase */
@@ -668,11 +652,6 @@ struct iscsi_session {
/** Target authenticated itself correctly */
#define ISCSI_STATUS_AUTH_REVERSE_OK 0x00040000
-/** Maximum number of retries at connecting */
-#define ISCSI_MAX_RETRIES 2
-
-extern int iscsi_attach ( struct scsi_device *scsi, const char *root_path );
-extern void iscsi_detach ( struct scsi_device *scsi );
extern const char * iscsi_initiator_iqn ( void );
#endif /* _IPXE_ISCSI_H */
diff --git a/src/include/ipxe/null_sanboot.h b/src/include/ipxe/null_sanboot.h
new file mode 100644
index 00000000..341a9a1d
--- /dev/null
+++ b/src/include/ipxe/null_sanboot.h
@@ -0,0 +1,18 @@
+#ifndef _IPXE_NULL_SANBOOT_H
+#define _IPXE_NULL_SANBOOT_H
+
+/** @file
+ *
+ * Standard do-nothing sanboot interface
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#ifdef SANBOOT_NULL
+#define SANBOOT_PREFIX_null
+#else
+#define SANBOOT_PREFIX_null __null_
+#endif
+
+#endif /* _IPXE_NULL_SANBOOT_H */
diff --git a/src/include/ipxe/ramdisk.h b/src/include/ipxe/ramdisk.h
deleted file mode 100644
index 012ac736..00000000
--- a/src/include/ipxe/ramdisk.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifndef _IPXE_RAMDISK_H
-#define _IPXE_RAMDISK_H
-
-/**
- * @file
- *
- * RAM disks
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include <ipxe/uaccess.h>
-#include <ipxe/blockdev.h>
-
-struct ramdisk {
- struct block_device blockdev;
- userptr_t data;
-};
-
-extern int init_ramdisk ( struct ramdisk *ramdisk, userptr_t data, size_t len,
- unsigned int blksize );
-
-#endif /* _IPXE_RAMDISK_H */
diff --git a/src/include/ipxe/sanboot.h b/src/include/ipxe/sanboot.h
index d27452cb..913282eb 100644
--- a/src/include/ipxe/sanboot.h
+++ b/src/include/ipxe/sanboot.h
@@ -1,20 +1,93 @@
#ifndef _IPXE_SANBOOT_H
#define _IPXE_SANBOOT_H
+/** @file
+ *
+ * iPXE sanboot API
+ *
+ * The sanboot API provides methods for hooking, unhooking,
+ * describing, and booting from SAN devices.
+ *
+ * The standard methods (readl()/writel() etc.) do not strictly check
+ * the type of the address parameter; this is because traditional
+ * usage does not necessarily provide the correct pointer type. For
+ * example, code written for ISA devices at fixed I/O addresses (such
+ * as the keyboard controller) tend to use plain integer constants for
+ * the address parameter.
+ */
+
FILE_LICENCE ( GPL2_OR_LATER );
-#include <ipxe/tables.h>
+#include <ipxe/api.h>
+#include <config/sanboot.h>
+
+struct uri;
+
+/**
+ * Calculate static inline sanboot API function name
+ *
+ * @v _prefix Subsystem prefix
+ * @v _api_func API function
+ * @ret _subsys_func Subsystem API function
+ */
+#define SANBOOT_INLINE( _subsys, _api_func ) \
+ SINGLE_API_INLINE ( SANBOOT_PREFIX_ ## _subsys, _api_func )
+
+/**
+ * Provide a sanboot API implementation
+ *
+ * @v _prefix Subsystem prefix
+ * @v _api_func API function
+ * @v _func Implementing function
+ */
+#define PROVIDE_SANBOOT( _subsys, _api_func, _func ) \
+ PROVIDE_SINGLE_API ( SANBOOT_PREFIX_ ## _subsys, _api_func, _func )
+
+/**
+ * Provide a static inline sanboot API implementation
+ *
+ * @v _prefix Subsystem prefix
+ * @v _api_func API function
+ */
+#define PROVIDE_SANBOOT_INLINE( _subsys, _api_func ) \
+ PROVIDE_SINGLE_API_INLINE ( SANBOOT_PREFIX_ ## _subsys, _api_func )
+
+/* Include all architecture-independent sanboot API headers */
+#include <ipxe/null_sanboot.h>
+
+/* Include all architecture-dependent sanboot API headers */
+#include <bits/sanboot.h>
-struct sanboot_protocol {
- const char *prefix;
- int ( * boot ) ( const char *root_path );
-};
+/**
+ * Hook SAN device
+ *
+ * @v uri URI
+ * @v drive Requested drive number
+ * @ret drive Assigned drive number, or negative error
+ */
+int san_hook ( struct uri *uri, unsigned int drive );
-#define SANBOOT_PROTOCOLS \
- __table ( struct sanboot_protocol, "sanboot_protocols" )
+/**
+ * Unhook SAN device
+ *
+ * @v drive Drive number
+ */
+void san_unhook ( unsigned int drive );
-#define __sanboot_protocol __table_entry ( SANBOOT_PROTOCOLS, 01 )
+/**
+ * Attempt to boot from a SAN device
+ *
+ * @v drive Drive number
+ * @ret rc Return status code
+ */
+int san_boot ( unsigned int drive );
-extern int keep_san ( void );
+/**
+ * Describe SAN device for SAN-booted operating system
+ *
+ * @v drive Drive number
+ * @ret rc Return status code
+ */
+int san_describe ( unsigned int drive );
#endif /* _IPXE_SANBOOT_H */
diff --git a/src/include/ipxe/scsi.h b/src/include/ipxe/scsi.h
index b56ab757..b90aa3aa 100644
--- a/src/include/ipxe/scsi.h
+++ b/src/include/ipxe/scsi.h
@@ -2,9 +2,8 @@
#define _IPXE_SCSI_H
#include <stdint.h>
-#include <ipxe/blockdev.h>
#include <ipxe/uaccess.h>
-#include <ipxe/refcnt.h>
+#include <ipxe/interface.h>
/** @file
*
@@ -14,6 +13,9 @@
FILE_LICENCE ( GPL2_OR_LATER );
+/** Maximum block for READ/WRITE (10) commands */
+#define SCSI_MAX_BLOCK_10 0xffffffffULL
+
/**
* @defgroup scsiops SCSI operation codes
* @{
@@ -214,8 +216,27 @@ union scsi_cdb {
/** @} */
-/** A SCSI command */
-struct scsi_command {
+/** A SCSI LUN
+ *
+ * This is a four-level LUN as specified by SAM-2, in big-endian
+ * order.
+ */
+struct scsi_lun {
+ uint16_t u16[4];
+} __attribute__ (( packed ));
+
+/** printf() format for dumping a scsi_lun */
+#define SCSI_LUN_FORMAT "%04x-%04x-%04x-%04x"
+
+/** printf() parameters for dumping a scsi_lun */
+#define SCSI_LUN_DATA(lun) \
+ ntohs ( (lun).u16[0] ), ntohs ( (lun).u16[1] ), \
+ ntohs ( (lun).u16[2] ), ntohs ( (lun).u16[3] )
+
+/** A SCSI command information unit */
+struct scsi_cmd {
+ /** LUN */
+ struct scsi_lun lun;
/** CDB for this command */
union scsi_cdb cdb;
/** Data-out buffer (may be NULL) */
@@ -232,50 +253,43 @@ struct scsi_command {
* Must be zero if @c data_in is NULL
*/
size_t data_in_len;
- /** SCSI status code */
- uint8_t status;
- /** SCSI sense response code */
- uint8_t sense_response;
- /** Command status code */
- int rc;
};
-/** A SCSI LUN
- *
- * This is a four-level LUN as specified by SAM-2, in big-endian
- * order.
- */
-struct scsi_lun {
- uint16_t u16[4];
-} __attribute__ (( packed ));
+/** SCSI sense data */
+struct scsi_sns {
+ /** Response code */
+ uint8_t code;
+ /** Reserved */
+ uint8_t reserved;
+ /** Sense key */
+ uint8_t key;
+ /** Information */
+ uint32_t info;
+};
-/** A SCSI device */
-struct scsi_device {
- /** Block device interface */
- struct block_device blockdev;
- /**
- * Issue SCSI command
- *
- * @v scsi SCSI device
- * @v command SCSI command
- * @ret rc Return status code
- *
- * Note that a successful return status code indicates only
- * that the SCSI command was issued. The caller must check
- * the status field in the command structure to see when the
- * command completes and whether, for example, the device
- * returned CHECK CONDITION or some other non-success status
- * code.
- */
- int ( * command ) ( struct scsi_device *scsi,
- struct scsi_command *command );
- /** Backing device */
- struct refcnt *backend;
+/** A SCSI response information unit */
+struct scsi_rsp {
+ /** SCSI status code */
+ uint8_t status;
+ /** Data overrun (or negative underrun) */
+ ssize_t overrun;
+ /** Autosense data (if any) */
+ struct scsi_sns sense;
};
-extern int scsi_detached_command ( struct scsi_device *scsi,
- struct scsi_command *command );
-extern int init_scsidev ( struct scsi_device *scsi );
extern int scsi_parse_lun ( const char *lun_string, struct scsi_lun *lun );
+extern int scsi_command ( struct interface *control, struct interface *data,
+ struct scsi_cmd *command );
+#define scsi_command_TYPE( object_type ) \
+ typeof ( int ( object_type, struct interface *data, \
+ struct scsi_cmd *command ) )
+
+extern void scsi_response ( struct interface *intf, struct scsi_rsp *response );
+#define scsi_response_TYPE( object_type ) \
+ typeof ( void ( object_type, struct scsi_rsp *response ) )
+
+extern int scsi_open ( struct interface *block, struct interface *scsi,
+ struct scsi_lun *lun );
+
#endif /* _IPXE_SCSI_H */
diff --git a/src/include/ipxe/srp.h b/src/include/ipxe/srp.h
index e519838a..acde7c94 100644
--- a/src/include/ipxe/srp.h
+++ b/src/include/ipxe/srp.h
@@ -14,6 +14,7 @@ FILE_LICENCE ( BSD2 );
#include <ipxe/iobuf.h>
#include <ipxe/xfer.h>
#include <ipxe/scsi.h>
+#include <ipxe/acpi.h>
/*****************************************************************************
*
@@ -23,21 +24,18 @@ FILE_LICENCE ( BSD2 );
*/
/** An SRP information unit tag */
-struct srp_tag {
+union srp_tag {
+ uint8_t bytes[8];
uint32_t dwords[2];
} __attribute__ (( packed ));
+/** SRP tag magic marker */
+#define SRP_TAG_MAGIC 0x69505845
+
/** An SRP port ID */
-struct srp_port_id {
+union srp_port_id {
uint8_t bytes[16];
-} __attribute__ (( packed ));
-
-/** An SRP port ID pair */
-struct srp_port_ids {
- /** Initiator port ID */
- struct srp_port_id initiator;
- /** Target port ID */
- struct srp_port_id target;
+ uint32_t dwords[4];
} __attribute__ (( packed ));
/** SRP information unit common fields */
@@ -47,7 +45,7 @@ struct srp_common {
/** Reserved */
uint8_t reserved0[7];
/** Tag */
- struct srp_tag tag;
+ union srp_tag tag;
} __attribute__ (( packed ));
/*****************************************************************************
@@ -67,7 +65,7 @@ struct srp_login_req {
/** Reserved */
uint8_t reserved0[7];
/** Tag */
- struct srp_tag tag;
+ union srp_tag tag;
/** Requested maximum initiator to target IU length */
uint32_t max_i_t_iu_len;
/** Reserved */
@@ -87,8 +85,10 @@ struct srp_login_req {
uint8_t flags;
/** Reserved */
uint8_t reserved2[5];
- /** Initiator and target port identifiers */
- struct srp_port_ids port_ids;
+ /** Initiator port identifier */
+ union srp_port_id initiator;
+ /** Target port identifier */
+ union srp_port_id target;
} __attribute__ (( packed ));
/** Type of an SRP login request */
@@ -137,7 +137,7 @@ struct srp_login_rsp {
/** Request limit delta */
uint32_t request_limit_delta;
/** Tag */
- struct srp_tag tag;
+ union srp_tag tag;
/** Maximum initiator to target IU length */
uint32_t max_i_t_iu_len;
/** Maximum target to initiator IU length */
@@ -205,7 +205,7 @@ struct srp_login_rej {
*/
uint32_t reason;
/** Tag */
- struct srp_tag tag;
+ union srp_tag tag;
/** Reserved */
uint8_t reserved1[8];
/** Supported buffer formats
@@ -265,7 +265,7 @@ struct srp_i_logout {
/** Reserved */
uint8_t reserved0[7];
/** Tag */
- struct srp_tag tag;
+ union srp_tag tag;
} __attribute__ (( packed ));
/** Type of an SRP initiator logout request */
@@ -299,7 +299,7 @@ struct srp_t_logout {
*/
uint32_t reason;
/** Tag */
- struct srp_tag tag;
+ union srp_tag tag;
} __attribute__ (( packed ));
/** Type of an SRP target logout request */
@@ -355,7 +355,7 @@ struct srp_tsk_mgmt {
/** Reserved */
uint8_t reserved0[6];
/** Tag */
- struct srp_tag tag;
+ union srp_tag tag;
/** Reserved */
uint8_t reserved1[4];
/** Logical unit number */
@@ -370,7 +370,7 @@ struct srp_tsk_mgmt {
/** Reserved */
uint8_t reserved3[1];
/** Tag of task to be managed */
- struct srp_tag managed_tag;
+ union srp_tag managed_tag;
/** Reserved */
uint8_t reserved4[8];
} __attribute__ (( packed ));
@@ -432,7 +432,7 @@ struct srp_cmd {
/** Data-in buffer descriptor count */
uint8_t data_in_buffer_count;
/** Tag */
- struct srp_tag tag;
+ union srp_tag tag;
/** Reserved */
uint8_t reserved1[4];
/** Logical unit number */
@@ -526,7 +526,7 @@ struct srp_rsp {
/** Request limit delta */
uint32_t request_limit_delta;
/** Tag */
- struct srp_tag tag;
+ union srp_tag tag;
/** Reserved */
uint8_t reserved1[2];
/** Valid fields
@@ -580,9 +580,9 @@ struct srp_rsp {
* @v rsp SCSI response
* @ret response_data Response data, or NULL if not present
*/
-static inline void * srp_rsp_response_data ( struct srp_rsp *rsp ) {
+static inline const void * srp_rsp_response_data ( const struct srp_rsp *rsp ) {
return ( ( rsp->valid & SRP_RSP_VALID_RSPVALID ) ?
- ( ( ( void * ) rsp ) + sizeof ( *rsp ) ) : NULL );
+ ( ( ( const void * ) rsp ) + sizeof ( *rsp ) ) : NULL );
}
/**
@@ -591,7 +591,7 @@ static inline void * srp_rsp_response_data ( struct srp_rsp *rsp ) {
* @v rsp SCSI response
* @ret response_data_len Response data length
*/
-static inline size_t srp_rsp_response_data_len ( struct srp_rsp *rsp ) {
+static inline size_t srp_rsp_response_data_len ( const struct srp_rsp *rsp ) {
return ( ( rsp->valid & SRP_RSP_VALID_RSPVALID ) ?
ntohl ( rsp->response_data_len ) : 0 );
}
@@ -602,9 +602,9 @@ static inline size_t srp_rsp_response_data_len ( struct srp_rsp *rsp ) {
* @v rsp SCSI response
* @ret sense_data Sense data, or NULL if not present
*/
-static inline void * srp_rsp_sense_data ( struct srp_rsp *rsp ) {
+static inline const void * srp_rsp_sense_data ( const struct srp_rsp *rsp ) {
return ( ( rsp->valid & SRP_RSP_VALID_SNSVALID ) ?
- ( ( ( void * ) rsp ) + sizeof ( *rsp ) +
+ ( ( ( const void * ) rsp ) + sizeof ( *rsp ) +
srp_rsp_response_data_len ( rsp ) ) : NULL );
}
@@ -614,7 +614,7 @@ static inline void * srp_rsp_sense_data ( struct srp_rsp *rsp ) {
* @v rsp SCSI response
* @ret sense_data_len Sense data length
*/
-static inline size_t srp_rsp_sense_data_len ( struct srp_rsp *rsp ) {
+static inline size_t srp_rsp_sense_data_len ( const struct srp_rsp *rsp ) {
return ( ( rsp->valid & SRP_RSP_VALID_SNSVALID ) ?
ntohl ( rsp->sense_data_len ) : 0 );
}
@@ -644,7 +644,7 @@ struct srp_cred_req {
/** Request limit delta */
uint32_t request_limit_delta;
/** Tag */
- struct srp_tag tag;
+ union srp_tag tag;
} __attribute__ (( packed ));
/** Type of an SRP credit request */
@@ -670,7 +670,7 @@ struct srp_cred_rsp {
/** Reserved */
uint8_t reserved0[7];
/** Tag */
- struct srp_tag tag;
+ union srp_tag tag;
} __attribute__ (( packed ));
/** Type of an SRP credit response */
@@ -701,7 +701,7 @@ struct srp_aer_req {
/** Request limit delta */
uint32_t request_limit_delta;
/** Tag */
- struct srp_tag tag;
+ union srp_tag tag;
/** Reserved */
uint8_t reserved1[4];
/** Logical unit number */
@@ -757,7 +757,7 @@ struct srp_aer_rsp {
/** Reserved */
uint8_t reserved0[7];
/** Tag */
- struct srp_tag tag;
+ union srp_tag tag;
} __attribute__ (( packed ));
/** Type of an SRP asynchronous event response */
@@ -765,104 +765,65 @@ struct srp_aer_rsp {
/*****************************************************************************
*
- * Information units
- *
- *****************************************************************************
- */
-
-/** Maximum length of any initiator-to-target IU that we will send
+ * SRP boot firmware table
*
- * The longest IU is a SRP_CMD with no additional CDB and two direct
- * data buffer descriptors, which comes to 80 bytes.
- */
-#define SRP_MAX_I_T_IU_LEN 80
-
-/*****************************************************************************
+ * The working draft specification for the SRP boot firmware table can
+ * be found at
*
- * SRP device
+ * http://ipxe.org/wiki/srp/sbft
*
*****************************************************************************
*/
-struct srp_device;
+/** SRP Boot Firmware Table signature */
+#define SBFT_SIG ACPI_SIGNATURE ( 's', 'B', 'F', 'T' )
-/** An SRP transport type */
-struct srp_transport_type {
- /** Length of transport private data */
- size_t priv_len;
- /** Parse root path
- *
- * @v srp SRP device
- * @v root_path Root path
- * @ret Return status code
- */
- int ( * parse_root_path ) ( struct srp_device *srp,
- const char *root_path );
- /** Connect SRP session
- *
- * @v srp SRP device
- * @ret rc Return status code
- *
- * This method should open the underlying socket.
- */
- int ( * connect ) ( struct srp_device *srp );
-};
+/** An offset from the start of the sBFT */
+typedef uint16_t sbft_off_t;
-/** An SRP device */
-struct srp_device {
- /** Reference count */
- struct refcnt refcnt;
+/**
+ * SRP Boot Firmware Table
+ */
+struct sbft_table {
+ /** ACPI header */
+ struct acpi_description_header acpi;
+ /** Offset to SCSI subtable */
+ sbft_off_t scsi_offset;
+ /** Offset to SRP subtable */
+ sbft_off_t srp_offset;
+ /** Offset to IB subtable, if present */
+ sbft_off_t ib_offset;
+ /** Reserved */
+ uint8_t reserved[6];
+} __attribute__ (( packed ));
- /** Initiator and target port IDs */
- struct srp_port_ids port_ids;
- /** Logical unit number */
+/**
+ * sBFT SCSI subtable
+ */
+struct sbft_scsi_subtable {
+ /** LUN */
struct scsi_lun lun;
- /** Memory handle */
- uint32_t memory_handle;
-
- /** Current state
- *
- * This is the bitwise-OR of zero or more @c SRP_STATE_XXX
- * flags.
- */
- unsigned int state;
- /** Retry counter */
- unsigned int retry_count;
- /** Current SCSI command */
- struct scsi_command *command;
-
- /** Underlying data transfer interface */
- struct interface socket;
-
- /** Transport type */
- struct srp_transport_type *transport;
- /** Transport private data */
- char transport_priv[0];
-};
+} __attribute__ (( packed ));
/**
- * Get SRP transport private data
- *
- * @v srp SRP device
- * @ret priv SRP transport private data
+ * sBFT SRP subtable
*/
-static inline __always_inline void *
-srp_transport_priv ( struct srp_device *srp ) {
- return ( ( void * ) srp->transport_priv );
-}
-
-/** SRP state flags */
-enum srp_state {
- /** Underlying socket is open */
- SRP_STATE_SOCKET_OPEN = 0x0001,
- /** Session is logged in */
- SRP_STATE_LOGGED_IN = 0x0002,
-};
+struct sbft_srp_subtable {
+ /** Initiator port identifier */
+ union srp_port_id initiator;
+ /** Target port identifier */
+ union srp_port_id target;
+} __attribute__ (( packed ));
-/** Maximum number of SRP retry attempts */
-#define SRP_MAX_RETRIES 3
+/*****************************************************************************
+ *
+ * SRP devices
+ *
+ *****************************************************************************
+ */
-extern int srp_attach ( struct scsi_device *scsi, const char *root_path );
-extern void srp_detach ( struct scsi_device *scsi );
+extern int srp_open ( struct interface *block, struct interface *socket,
+ union srp_port_id *initiator, union srp_port_id *target,
+ uint32_t memory_handle, struct scsi_lun *lun );
#endif /* _IPXE_SRP_H */