176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifndef _GPXE_ISCSI_H
276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define _GPXE_ISCSI_H
376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** @file
576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * iSCSI protocol
776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
1076d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanFILE_LICENCE ( GPL2_OR_LATER );
1176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
1276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <stdint.h>
1376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/socket.h>
1476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/scsi.h>
1576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/chap.h>
1676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/refcnt.h>
1776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/xfer.h>
1876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/process.h>
1976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
2076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Default iSCSI port */
2176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_PORT 3260
2276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
2376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
2476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * iSCSI segment lengths
2576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
2676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * iSCSI uses an icky structure with one one-byte field (a dword
2776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * count) and one three-byte field (a byte count).  This structure,
2876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * and the accompanying macros, relieve some of the pain.
2976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
3076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanunion iscsi_segment_lengths {
3176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct {
3276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		/** The AHS length (measured in dwords) */
3376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		uint8_t ahs_len;
3476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		/** The data length (measured in bytes), in network
3576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		 * byte order
3676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		 */
3776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		uint8_t data_len[3];
3876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	} bytes;
3976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Ths data length (measured in bytes), in network byte
4076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * order, with ahs_len as the first byte.
4176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
4276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t ahs_and_data_len;
4376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
4476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
4576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** The length of the additional header segment, in dwords */
4676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_AHS_LEN( segment_lengths ) \
4776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	( (segment_lengths).bytes.ahs_len )
4876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
4976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** The length of the data segment, in bytes, excluding any padding */
5076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_DATA_LEN( segment_lengths ) \
5176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	( ntohl ( (segment_lengths).ahs_and_data_len ) & 0xffffff )
5276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
5376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** The padding of the data segment, in bytes */
5476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_DATA_PAD_LEN( segment_lengths ) \
5576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	( ( 0 - (segment_lengths).bytes.data_len[2] ) & 0x03 )
5676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
5776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Set additional header and data segment lengths */
5876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_SET_LENGTHS( segment_lengths, ahs_len, data_len ) do {	\
5976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	(segment_lengths).ahs_and_data_len =				\
6076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		htonl ( data_len | ( ahs_len << 24 ) );			\
6176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	} while ( 0 )
6276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
6376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
6476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * iSCSI basic header segment common fields
6576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
6676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
6776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct iscsi_bhs_common {
6876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Opcode */
6976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t opcode;
7076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Flags */
7176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t flags;
7276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Fields specific to the PDU type */
7376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t other_a[2];
7476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Segment lengths */
7576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	union iscsi_segment_lengths lengths;
7676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Fields specific to the PDU type */
7776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t other_b[8];
7876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Initiator Task Tag */
7976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t itt;
8076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Fields specific to the PDU type */
8176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t other_c[28];
8276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
8376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
8476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Opcode mask */
8576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_OPCODE_MASK 0x3f
8676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
8776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Immediate delivery */
8876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_FLAG_IMMEDIATE 0x40
8976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
9076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Final PDU of a sequence */
9176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_FLAG_FINAL 0x80
9276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
9376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
9476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * iSCSI basic header segment common request fields
9576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
9676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
9776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct iscsi_bhs_common_response {
9876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Opcode */
9976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t opcode;
10076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Flags */
10176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t flags;
10276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Fields specific to the PDU type */
10376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t other_a[2];
10476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Segment lengths */
10576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	union iscsi_segment_lengths lengths;
10676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Fields specific to the PDU type */
10776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t other_b[8];
10876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Initiator Task Tag */
10976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t itt;
11076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Fields specific to the PDU type */
11176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t other_c[4];
11276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Status sequence number */
11376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t statsn;
11476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Expected command sequence number */
11576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t expcmdsn;
11676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Fields specific to the PDU type */
11776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t other_d[16];
11876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
11976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
12076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
12176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * iSCSI login request basic header segment
12276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
12376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
12476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct iscsi_bhs_login_request {
12576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Opcode */
12676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t opcode;
12776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Flags */
12876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t flags;
12976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Maximum supported version number */
13076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t version_max;
13176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Minimum supported version number */
13276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t version_min;
13376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Segment lengths */
13476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	union iscsi_segment_lengths lengths;
13576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Initiator session ID (IANA format) enterprise number and flags */
13676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t isid_iana_en;
13776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Initiator session ID (IANA format) qualifier */
13876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint16_t isid_iana_qual;
13976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Target session identifying handle */
14076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint16_t tsih;
14176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Initiator Task Tag */
14276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t itt;
14376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Connection ID */
14476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint16_t cid;
14576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Reserved */
14676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint16_t reserved_a;
14776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Command sequence number */
14876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t cmdsn;
14976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Expected status sequence number */
15076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t expstatsn;
15176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Reserved */
15276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t reserved_b[16];
15376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
15476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
15576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Login request opcode */
15676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_OPCODE_LOGIN_REQUEST 0x03
15776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
15876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Willingness to transition to next stage */
15976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_LOGIN_FLAG_TRANSITION 0x80
16076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
16176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Key=value pairs continued in subsequent request */
16276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_LOGIN_FLAG_CONTINUE 0x40
16376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
16476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Current stage values and mask */
16576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_LOGIN_CSG_MASK 0x0c
16676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_LOGIN_CSG_SECURITY_NEGOTIATION 0x00
16776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_LOGIN_CSG_OPERATIONAL_NEGOTIATION 0x04
16876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_LOGIN_CSG_FULL_FEATURE_PHASE 0x0c
16976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
17076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Next stage values and mask */
17176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_LOGIN_NSG_MASK 0x03
17276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_LOGIN_NSG_SECURITY_NEGOTIATION 0x00
17376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_LOGIN_NSG_OPERATIONAL_NEGOTIATION 0x01
17476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_LOGIN_NSG_FULL_FEATURE_PHASE 0x03
17576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
17676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** ISID IANA format marker */
17776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_ISID_IANA 0x40000000
17876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
17976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Fen Systems Ltd. IANA enterprise number
18076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
18176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Permission is hereby granted to use Fen Systems Ltd.'s IANA
18276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * enterprise number with this iSCSI implementation.
18376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
18476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define IANA_EN_FEN_SYSTEMS 10019
18576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
18676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
18776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * iSCSI login response basic header segment
18876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
18976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
19076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct iscsi_bhs_login_response {
19176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Opcode */
19276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t opcode;
19376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Flags */
19476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t flags;
19576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Maximum supported version number */
19676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t version_max;
19776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Minimum supported version number */
19876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t version_min;
19976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Segment lengths */
20076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	union iscsi_segment_lengths lengths;
20176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Initiator session ID (IANA format) enterprise number and flags */
20276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t isid_iana_en;
20376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Initiator session ID (IANA format) qualifier */
20476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint16_t isid_iana_qual;
20576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Target session identifying handle */
20676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint16_t tsih;
20776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Initiator Task Tag */
20876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t itt;
20976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Reserved */
21076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t reserved_a;
21176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Status sequence number */
21276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t statsn;
21376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Expected command sequence number */
21476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t expcmdsn;
21576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Maximum command sequence number */
21676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t maxcmdsn;
21776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Status class */
21876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t status_class;
21976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Status detail */
22076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t status_detail;
22176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Reserved */
22276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t reserved_b[10];
22376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
22476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
22576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Login response opcode */
22676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_OPCODE_LOGIN_RESPONSE 0x23
22776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
22876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Login response status codes */
22976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_STATUS_SUCCESS			0x00
23076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_STATUS_REDIRECT			0x01
23176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_STATUS_INITIATOR_ERROR		0x02
23276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_STATUS_INITIATOR_ERROR_AUTHENTICATION	0x01
23376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_STATUS_INITIATOR_ERROR_AUTHORISATION	0x02
23476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_STATUS_INITIATOR_ERROR_NOT_FOUND		0x03
23576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_STATUS_INITIATOR_ERROR_REMOVED		0x04
23676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_STATUS_TARGET_ERROR		0x03
23776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
23876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
23976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * iSCSI SCSI command basic header segment
24076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
24176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
24276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct iscsi_bhs_scsi_command {
24376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Opcode */
24476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t opcode;
24576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Flags */
24676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t flags;
24776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Reserved */
24876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint16_t reserved_a;
24976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Segment lengths */
25076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	union iscsi_segment_lengths lengths;
25176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** SCSI Logical Unit Number */
25276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct scsi_lun lun;
25376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Initiator Task Tag */
25476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t itt;
25576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Expected data transfer length */
25676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t exp_len;
25776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Command sequence number */
25876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t cmdsn;
25976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Expected status sequence number */
26076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t expstatsn;
26176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** SCSI Command Descriptor Block (CDB) */
26276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	union scsi_cdb cdb;
26376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
26476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
26576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** SCSI command opcode */
26676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_OPCODE_SCSI_COMMAND 0x01
26776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
26876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Command will read data */
26976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_COMMAND_FLAG_READ 0x40
27076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
27176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Command will write data */
27276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_COMMAND_FLAG_WRITE 0x20
27376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
27476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Task attributes */
27576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_COMMAND_ATTR_UNTAGGED 0x00
27676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_COMMAND_ATTR_SIMPLE 0x01
27776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_COMMAND_ATTR_ORDERED 0x02
27876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_COMMAND_ATTR_HEAD_OF_QUEUE 0x03
27976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_COMMAND_ATTR_ACA 0x04
28076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
28176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
28276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * iSCSI SCSI response basic header segment
28376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
28476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
28576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct iscsi_bhs_scsi_response {
28676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Opcode */
28776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t opcode;
28876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Flags */
28976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t flags;
29076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Response code */
29176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t response;
29276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** SCSI status code */
29376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t status;
29476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Segment lengths */
29576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	union iscsi_segment_lengths lengths;
29676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Reserved */
29776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t reserved_a[8];
29876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Initiator Task Tag */
29976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t itt;
30076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** SNACK tag */
30176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t snack;
30276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Status sequence number */
30376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t statsn;
30476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Expected command sequence number */
30576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t expcmdsn;
30676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Maximum command sequence number */
30776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t maxcmdsn;
30876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Expected data sequence number */
30976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t expdatasn;
31076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Reserved */
31176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t reserved_b[8];
31276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
31376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
31476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** SCSI response opcode */
31576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_OPCODE_SCSI_RESPONSE 0x21
31676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
31776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** SCSI command completed at target */
31876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_RESPONSE_COMMAND_COMPLETE 0x00
31976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
32076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** SCSI target failure */
32176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_RESPONSE_TARGET_FAILURE 0x01
32276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
32376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** SCSI sense response code offset
32476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
32576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * The SCSI response may contain unsolicited sense data in the data
32676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * segment.  If it does, this is the offset to the sense response code
32776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * byte, which is the only byte we care about.
32876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
32976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_SENSE_RESPONSE_CODE_OFFSET 2
33076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
33176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
33276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * iSCSI data-in basic header segment
33376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
33476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
33576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct iscsi_bhs_data_in {
33676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Opcode */
33776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t opcode;
33876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Flags */
33976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t flags;
34076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Reserved */
34176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t reserved_a;
34276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** SCSI status code */
34376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t status;
34476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Segment lengths */
34576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	union iscsi_segment_lengths lengths;
34676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Logical Unit Number */
34776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct scsi_lun lun;
34876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Initiator Task Tag */
34976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t itt;
35076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Target Transfer Tag */
35176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t ttt;
35276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Status sequence number */
35376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t statsn;
35476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Expected command sequence number */
35576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t expcmdsn;
35676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Maximum command sequence number */
35776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t maxcmdsn;
35876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Data sequence number */
35976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t datasn;
36076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Buffer offset */
36176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t offset;
36276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Residual count */
36376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t residual_count;
36476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
36576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
36676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Data-in opcode */
36776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_OPCODE_DATA_IN 0x25
36876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
36976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Data requires acknowledgement */
37076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_DATA_FLAG_ACKNOWLEDGE 0x40
37176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
37276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Data overflow occurred */
37376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_DATA_FLAG_OVERFLOW 0x04
37476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
37576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Data underflow occurred */
37676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_DATA_FLAG_UNDERFLOW 0x02
37776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
37876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** SCSI status code and overflow/underflow flags are valid */
37976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_DATA_FLAG_STATUS 0x01
38076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
38176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
38276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * iSCSI data-out basic header segment
38376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
38476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
38576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct iscsi_bhs_data_out {
38676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Opcode */
38776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t opcode;
38876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Flags */
38976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t flags;
39076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Reserved */
39176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint16_t reserved_a;
39276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Segment lengths */
39376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	union iscsi_segment_lengths lengths;
39476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Logical Unit Number */
39576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct scsi_lun lun;
39676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Initiator Task Tag */
39776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t itt;
39876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Target Transfer Tag */
39976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t ttt;
40076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Reserved */
40176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t reserved_b;
40276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Expected status sequence number */
40376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t expstatsn;
40476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Reserved */
40576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t reserved_c;
40676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Data sequence number */
40776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t datasn;
40876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Buffer offset */
40976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t offset;
41076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Reserved */
41176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t reserved_d;
41276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
41376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
41476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Data-out opcode */
41576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_OPCODE_DATA_OUT 0x05
41676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
41776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
41876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * iSCSI request to transfer basic header segment
41976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
42076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
42176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct iscsi_bhs_r2t {
42276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Opcode */
42376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t opcode;
42476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Flags */
42576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t flags;
42676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Reserved */
42776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint16_t reserved_a;
42876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Segment lengths */
42976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	union iscsi_segment_lengths lengths;
43076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Logical Unit Number */
43176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct scsi_lun lun;
43276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Initiator Task Tag */
43376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t itt;
43476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Target Transfer Tag */
43576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t ttt;
43676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Status sequence number */
43776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t statsn;
43876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Expected command sequence number */
43976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t expcmdsn;
44076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Maximum command sequence number */
44176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t maxcmdsn;
44276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** R2T sequence number */
44376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t r2tsn;
44476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Buffer offset */
44576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t offset;
44676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Desired data transfer length */
44776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t len;
44876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
44976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
45076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** R2T opcode */
45176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_OPCODE_R2T 0x31
45276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
45376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
45476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * An iSCSI basic header segment
45576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
45676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanunion iscsi_bhs {
45776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct iscsi_bhs_common common;
45876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct iscsi_bhs_common_response common_response;
45976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct iscsi_bhs_login_request login_request;
46076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct iscsi_bhs_login_response login_response;
46176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct iscsi_bhs_scsi_command scsi_command;
46276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct iscsi_bhs_scsi_response scsi_response;
46376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct iscsi_bhs_data_in data_in;
46476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct iscsi_bhs_data_out data_out;
46576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct iscsi_bhs_r2t r2t;
46676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	unsigned char bytes[ sizeof ( struct iscsi_bhs_common ) ];
46776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
46876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
46976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** State of an iSCSI TX engine */
47076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanenum iscsi_tx_state {
47176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Nothing to send */
47276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	ISCSI_TX_IDLE = 0,
47376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Sending the basic header segment */
47476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	ISCSI_TX_BHS,
47576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Sending the additional header segment */
47676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	ISCSI_TX_AHS,
47776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Sending the data segment */
47876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	ISCSI_TX_DATA,
47976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Sending the data segment padding */
48076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	ISCSI_TX_DATA_PADDING,
48176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
48276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
48376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** State of an iSCSI RX engine */
48476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanenum iscsi_rx_state {
48576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Receiving the basic header segment */
48676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	ISCSI_RX_BHS = 0,
48776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Receiving the additional header segment */
48876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	ISCSI_RX_AHS,
48976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Receiving the data segment */
49076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	ISCSI_RX_DATA,
49176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Receiving the data segment padding */
49276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	ISCSI_RX_DATA_PADDING,
49376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
49476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
49576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** An iSCSI session */
49676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct iscsi_session {
49776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Reference counter */
49876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct refcnt refcnt;
49976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
50076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Transport-layer socket */
50176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct xfer_interface socket;
50276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
50376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Target address */
50476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	char *target_address;
50576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Target port */
50676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	unsigned int target_port;
50776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Target IQN */
50876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	char *target_iqn;
50976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Logical Unit Number (LUN) */
51076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct scsi_lun lun;
51176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Target socket address (recorded only for iBFT) */
51276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct sockaddr target_sockaddr;
51376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
51476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Session status
51576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
51676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * This is the bitwise-OR of zero or more ISCSI_STATUS_XXX
51776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * constants.
51876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
51976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int status;
52076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Retry count
52176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
52276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * Number of times that the connection has been retried.
52376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * Reset upon a successful connection.
52476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
52576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int retry_count;
52676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
52776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Initiator username (if any) */
52876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	char *initiator_username;
52976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Initiator password (if any) */
53076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	char *initiator_password;
53176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Target username (if any) */
53276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	char *target_username;
53376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Target password (if any) */
53476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	char *target_password;
53576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** CHAP challenge (for target auth only)
53676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
53776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * This is a block of random data; the first byte is used as
53876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * the CHAP identifier (CHAP_I) and the remainder as the CHAP
53976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * challenge (CHAP_C).
54076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
54176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	unsigned char chap_challenge[17];
54276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** CHAP response (used for both initiator and target auth) */
54376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct chap_response chap;
54476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
54576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Target session identifying handle
54676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
54776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * This is assigned by the target when we first log in, and
54876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * must be reused on subsequent login attempts.
54976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
55076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint16_t tsih;
55176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Initiator task tag
55276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
55376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * This is the tag of the current command.  It is incremented
55476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * whenever a new command is started.
55576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
55676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t itt;
55776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Target transfer tag
55876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
55976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * This is the tag attached to a sequence of data-out PDUs in
56076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * response to an R2T.
56176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
56276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t ttt;
56376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/**
56476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * Transfer offset
56576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
56676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * This is the offset for an in-progress sequence of data-out
56776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * PDUs in response to an R2T.
56876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
56976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t transfer_offset;
57076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/**
57176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * Transfer length
57276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
57376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * This is the length for an in-progress sequence of data-out
57476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * PDUs in response to an R2T.
57576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
57676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t transfer_len;
57776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Command sequence number
57876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
57976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * This is the sequence number of the current command, used to
58076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * fill out the CmdSN field in iSCSI request PDUs.  It is
58176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * updated with the value of the ExpCmdSN field whenever we
58276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * receive an iSCSI response PDU containing such a field.
58376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
58476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t cmdsn;
58576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Status sequence number
58676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
58776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * This is the most recent status sequence number present in
58876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * the StatSN field of an iSCSI response PDU containing such a
58976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * field.  Whenever we send an iSCSI request PDU, we fill out
59076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * the ExpStatSN field with this value plus one.
59176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
59276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t statsn;
59376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
59476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Basic header segment for current TX PDU */
59576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	union iscsi_bhs tx_bhs;
59676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** State of the TX engine */
59776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	enum iscsi_tx_state tx_state;
59876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** TX process */
59976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct process process;
60076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
60176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Basic header segment for current RX PDU */
60276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	union iscsi_bhs rx_bhs;
60376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** State of the RX engine */
60476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	enum iscsi_rx_state rx_state;
60576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Byte offset within the current RX state */
60676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	size_t rx_offset;
60776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Length of the current RX state */
60876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	size_t rx_len;
60976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Buffer for received data (not always used) */
61076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	void *rx_buffer;
61176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
61276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Current SCSI command
61376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
61476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * Set to NULL when command is complete.
61576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
61676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct scsi_command *command;
61776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Instant return code
61876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
61976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * Set to a non-zero value if all requests should return
62076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * immediately.  This can be used to e.g. avoid retrying
62176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * logins that are doomed to fail authentication.
62276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
62376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int instant_rc;
62476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
62576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
62676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** iSCSI session is currently in the security negotiation phase */
62776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_STATUS_SECURITY_NEGOTIATION_PHASE		\
62876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	( ISCSI_LOGIN_CSG_SECURITY_NEGOTIATION |	\
62976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	  ISCSI_LOGIN_NSG_OPERATIONAL_NEGOTIATION )
63076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
63176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** iSCSI session is currently in the operational parameter
63276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * negotiation phase
63376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
63476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_STATUS_OPERATIONAL_NEGOTIATION_PHASE	\
63576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	( ISCSI_LOGIN_CSG_OPERATIONAL_NEGOTIATION |	\
63676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	  ISCSI_LOGIN_NSG_FULL_FEATURE_PHASE )
63776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
63876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** iSCSI session is currently in the full feature phase */
63976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_STATUS_FULL_FEATURE_PHASE	ISCSI_LOGIN_CSG_FULL_FEATURE_PHASE
64076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
64176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Mask for all iSCSI session phases */
64276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_STATUS_PHASE_MASK ( ISCSI_LOGIN_CSG_MASK | ISCSI_LOGIN_NSG_MASK )
64376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
64476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** iSCSI session needs to send the initial security negotiation strings */
64576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_STATUS_STRINGS_SECURITY 0x0100
64676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
64776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** iSCSI session needs to send the CHAP_A string */
64876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_STATUS_STRINGS_CHAP_ALGORITHM 0x0200
64976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
65076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** iSCSI session needs to send the CHAP response */
65176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_STATUS_STRINGS_CHAP_RESPONSE 0x0400
65276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
65376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** iSCSI session needs to send the mutual CHAP challenge */
65476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_STATUS_STRINGS_CHAP_CHALLENGE 0x0800
65576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
65676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** iSCSI session needs to send the operational negotiation strings */
65776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_STATUS_STRINGS_OPERATIONAL 0x1000
65876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
65976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Mask for all iSCSI "needs to send" flags */
66076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_STATUS_STRINGS_MASK 0xff00
66176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
66276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Target has requested forward (initiator) authentication */
66376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_STATUS_AUTH_FORWARD_REQUIRED 0x00010000
66476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
66576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Initiator requires target (reverse) authentication */
66676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_STATUS_AUTH_REVERSE_REQUIRED 0x00020000
66776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
66876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Target authenticated itself correctly */
66976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_STATUS_AUTH_REVERSE_OK 0x00040000
67076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
67176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Maximum number of retries at connecting */
67276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ISCSI_MAX_RETRIES 2
67376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
67476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern int iscsi_attach ( struct scsi_device *scsi, const char *root_path );
67576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern void iscsi_detach ( struct scsi_device *scsi );
67676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern const char * iscsi_initiator_iqn ( void );
67776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
67876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif /* _GPXE_ISCSI_H */
679