diff options
Diffstat (limited to 'src/include')
| -rw-r--r-- | src/include/ipxe/acpi.h | 22 | ||||
| -rw-r--r-- | src/include/ipxe/aoe.h | 67 | ||||
| -rw-r--r-- | src/include/ipxe/ata.h | 85 | ||||
| -rw-r--r-- | src/include/ipxe/blockdev.h | 70 | ||||
| -rw-r--r-- | src/include/ipxe/errfile.h | 3 | ||||
| -rw-r--r-- | src/include/ipxe/ib_srp.h | 75 | ||||
| -rw-r--r-- | src/include/ipxe/ibft.h | 271 | ||||
| -rw-r--r-- | src/include/ipxe/iscsi.h | 71 | ||||
| -rw-r--r-- | src/include/ipxe/null_sanboot.h | 18 | ||||
| -rw-r--r-- | src/include/ipxe/ramdisk.h | 24 | ||||
| -rw-r--r-- | src/include/ipxe/sanboot.h | 91 | ||||
| -rw-r--r-- | src/include/ipxe/scsi.h | 100 | ||||
| -rw-r--r-- | src/include/ipxe/srp.h | 193 |
13 files changed, 681 insertions, 409 deletions
diff --git a/src/include/ipxe/acpi.h b/src/include/ipxe/acpi.h index eabbec390..282b6d92d 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 d2a128585..60f3bd959 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 043e37051..b7f02d655 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 5c1ab136a..9f0a9f787 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 ad32ed1b8..d78f28229 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 b773f9648..902bef562 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 000000000..73372122d --- /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 a604e1e4f..e711459c9 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 000000000..341a9a1d2 --- /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 012ac7362..000000000 --- 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 d27452cb6..913282eb5 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 b56ab7578..b90aa3aa0 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 e519838a4..acde7c94a 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 */ |
