haiku/headers/private/drivers/iscsi_cmds.h
Andreas Färber 267f107882 iSCSI: Add header for protocol
Define structs for iSCSI messages, to be used by boot loader and kernel add-on.
For now it will refuse to compile for Little Endian systems (e.g., x86).


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38528 a95241bf-73f2-0310-859d-f6bbb57e9c96
2010-09-04 21:09:13 +00:00

337 lines
6.4 KiB
C

/*
* Copyright 2010, Andreas Färber <andreas.faerber@web.de>
* All rights reserved. Distributed under the terms of the MIT License.
*/
#ifndef ISCSI_CMDS_H
#define ISCSI_CMDS_H
#include <ByteOrder.h>
// TODO Add Little Endian support by introducing more macros
#if __BYTE_ORDER != __BIG_ENDIAN
#error Only Big Endian systems supported yet.
#endif
// iSCSI Basic Header Segment (BHS) (RFC 3720 10.2.1)
#define ISCSI_BHS_BYTE0 \
bool reserved : 1; \
bool immediateDelivery : 1; \
uint8 opcode : 6;
// TODO This macro is LE-incompatible
#define ISCSI_BHS_START \
ISCSI_BHS_BYTE0 \
bool final : 1;
#define ISCSI_BHS_LENGTHS \
uint8 totalAHSLength; \
uint32 dataSegmentLength : 24;
#define ISCSI_BHS_TASK_TAG \
uint32 initiatorTaskTag;
#define ISCSI_BHS_TAGS \
ISCSI_BHS_TASK_TAG \
uint32 targetTransferTag;
struct iscsi_basic_header_segment {
ISCSI_BHS_START
uint32 opcodeSpecific : 23;
ISCSI_BHS_LENGTHS
uint64 lun;
ISCSI_BHS_TASK_TAG
uint8 opcodeSpecific2[28];
} _PACKED;
// initiator opcodes
#define ISCSI_OPCODE_NOP_OUT 0x00
#define ISCSI_OPCODE_SCSI_COMMAND 0x01
#define ISCSI_OPCODE_LOGIN_REQUEST 0x03
#define ISCSI_OPCODE_TEXT_REQUEST 0x04
#define ISCSI_OPCODE_LOGOUT_REQUEST 0x06
// target opcodes
#define ISCSI_OPCODE_NOP_IN 0x20
#define ISCSI_OPCODE_SCSI_RESPONSE 0x21
#define ISCSI_OPCODE_LOGIN_RESPONSE 0x23
#define ISCSI_OPCODE_TEXT_RESPONSE 0x24
#define ISCSI_OPCODE_SCSI_DATA_IN 0x25
#define ISCSI_OPCODE_LOGOUT_RESPONSE 0x26
// SCSI Command (RFC 3720 10.3)
struct iscsi_scsi_command {
iscsi_scsi_command()
:
reserved(0),
opcode(ISCSI_OPCODE_SCSI_COMMAND),
reserved2(0),
reserved3(0)
{
}
ISCSI_BHS_START
bool r : 1;
bool w : 1;
uint8 reserved2 : 2;
uint8 attr : 3;
uint16 reserved3;
ISCSI_BHS_LENGTHS
uint64 lun;
ISCSI_BHS_TASK_TAG
uint32 expectedDataTransferLength;
uint32 cmdSN;
uint32 expStatSN;
uint8 cdb[16];
} _PACKED;
// SCSI Response (RFC 3720 10.4)
struct iscsi_scsi_response {
ISCSI_BHS_START
uint8 reserved2 : 2;
bool o : 1;
bool u : 1;
bool O : 1;
bool U : 1;
bool reserved3 : 1;
uint8 response;
uint8 status;
ISCSI_BHS_LENGTHS
uint32 reserved4[2];
ISCSI_BHS_TASK_TAG
uint32 snackTag;
uint32 statSN;
uint32 expCmdSN;
uint32 maxCmdSN;
uint32 expDataSN;
uint32 bidirectionalReadResidualCount;
uint32 residualCount;
} _PACKED;
// SCSI Data-In (RFC 3270 10.7)
struct iscsi_scsi_data_in {
ISCSI_BHS_START
bool acknowledge : 1;
uint8 reserved2 : 3;
bool O : 1;
bool U : 1;
bool S : 1;
uint8 reserved3;
uint8 status;
ISCSI_BHS_LENGTHS
uint64 lun;
ISCSI_BHS_TAGS
uint32 statSN;
uint32 expCmdSN;
uint32 maxCmdSN;
uint32 dataSN;
uint32 bufferOffset;
uint32 residualCount;
} _PACKED;
// Text Request (RFC 3720 10.10)
struct iscsi_text_request {
iscsi_text_request()
:
reserved(0),
opcode(ISCSI_OPCODE_TEXT_REQUEST),
reserved2(2)
{
reserved3[0] = 0;
reserved3[1] = 0;
reserved3[2] = 0;
reserved3[3] = 0;
}
ISCSI_BHS_START
bool c : 1; // continue
uint32 reserved2 : 22;
ISCSI_BHS_LENGTHS
uint64 lun;
ISCSI_BHS_TAGS
uint32 cmdSN;
uint32 expStatSN;
uint32 reserved3[4];
} _PACKED;
// Text Response (RFC 3720 10.11)
struct iscsi_text_response {
ISCSI_BHS_START
bool c : 1; // continue
uint32 reserved2 : 22;
ISCSI_BHS_LENGTHS
uint64 lun;
ISCSI_BHS_TAGS
uint32 statSN;
uint32 expCmdSN;
uint32 maxCmdSN;
uint32 reserved3[3];
} _PACKED;
struct iscsi_isid {
uint8 t : 2;
uint8 a : 6;
uint16 b;
uint8 c;
uint16 d;
} _PACKED;
// Login Request (RFC 3720 10.12)
struct iscsi_login_request {
iscsi_login_request()
:
reserved(false),
immediateDelivery(1),
opcode(ISCSI_OPCODE_LOGIN_REQUEST),
reserved2(0),
reserved3(0)
{
memset(reserved4, 0, sizeof(reserved4));
}
ISCSI_BHS_BYTE0
bool transit : 1;
bool c : 1; // continue
uint8 reserved2 : 2;
uint8 currentStage : 2;
uint8 nextStage : 2;
uint8 versionMax;
uint8 versionMin;
ISCSI_BHS_LENGTHS
iscsi_isid isid;
uint16 tsih;
ISCSI_BHS_TASK_TAG
uint16 cid;
uint16 reserved3;
uint32 cmdSN;
uint32 expStatSN;
uint32 reserved4[4];
} _PACKED;
#define ISCSI_SESSION_STAGE_SECURITY_NEGOTIATION 0
#define ISCSI_SESSION_STAGE_LOGIN_OPERATIONAL_NEGOTIATION 1
#define ISCSI_SESSION_STAGE_FULL_FEATURE_PHASE 3
#define ISCSI_VERSION 0x00
#define ISCSI_ISID_OUI 0
#define ISCSI_ISID_EN 1
#define ISCSI_ISID_RANDOM 2
// Login Response (RFC 3720 10.13)
struct iscsi_login_response {
ISCSI_BHS_BYTE0
bool transit : 1;
bool c : 1; // continue
uint8 reserved2 : 2;
uint8 currentStage : 2;
uint8 nextStage : 2;
uint8 versionMax;
uint8 versionActive;
ISCSI_BHS_LENGTHS
iscsi_isid isid;
uint16 tsih;
ISCSI_BHS_TASK_TAG
uint32 reserved3;
uint32 statSN;
uint32 expCmdSN;
uint32 maxCmdSN;
uint8 statusClass;
uint8 statusDetail;
uint16 reserved4;
uint32 reserved5[2];
} _PACKED;
// Logout Request (RFC 3720 10.14)
struct iscsi_logout_request {
iscsi_logout_request()
:
reserved(0),
opcode(ISCSI_OPCODE_LOGOUT_REQUEST),
final(true),
reserved2(0),
reserved4(0)
{
reserved3[0] = 0;
reserved3[1] = 0;
reserved5[0] = 0;
reserved5[1] = 0;
reserved5[2] = 0;
reserved5[3] = 0;
}
ISCSI_BHS_START
uint8 reasonCode : 7;
uint16 reserved2;
ISCSI_BHS_LENGTHS
uint32 reserved3[2];
ISCSI_BHS_TASK_TAG
uint16 cid;
uint16 reserved4;
uint32 cmdSN;
uint32 expStatSN;
uint32 reserved5[4];
} _PACKED;
#define ISCSI_LOGOUT_REASON_CLOSE_SESSION 0
#define ISCSI_LOGOUT_REASON_CLOSE_CONNECTION 1
#define ISCSI_LOGOUT_REASON_REMOVE_CONNECTION 2
// Logout Response (RFC 3720 10.15)
struct iscsi_logout_response {
ISCSI_BHS_START
uint8 reserved2 : 7;
uint8 response;
uint8 reserved3;
ISCSI_BHS_LENGTHS
uint32 reserved4[2];
ISCSI_BHS_TASK_TAG
uint32 reserved5;
uint32 statSN;
uint32 expCmdSN;
uint32 maxCmdSN;
uint32 reserved6;
uint16 time2Wait;
uint16 time2Remain;
uint32 reserved7;
} _PACKED;
// NOP-Out (RFC 3270, 10.18)
struct iscsi_nop_out {
iscsi_nop_out()
:
reserved(0),
opcode(ISCSI_OPCODE_NOP_OUT),
final(true),
reserved2(0)
{
reserved3[0] = 0;
reserved3[1] = 0;
reserved3[2] = 0;
reserved3[3] = 0;
}
ISCSI_BHS_START
uint32 reserved2 : 23;
ISCSI_BHS_LENGTHS
uint64 lun;
ISCSI_BHS_TAGS
uint32 cmdSN;
uint32 expStatSN;
uint32 reserved3[4];
} _PACKED;
// NOP-In (RFC 3270, 10.19)
struct iscsi_nop_in {
ISCSI_BHS_START
uint32 reserved2 : 23;
ISCSI_BHS_LENGTHS
uint64 lun;
ISCSI_BHS_TAGS
uint32 statSN;
uint32 expCmdSN;
uint32 maxCmdSN;
uint32 reserved3[3];
} _PACKED;
#endif