#ifndef _ISCSI_PDU_H
#define _ISCSI_PDU_H
#define BHS_SIZE 48
#define PDU_HEADER_SIZE 52
#define OP_IMMEDIATE 0x40
#define OPCODE_MASK 0x3f
#define FLAG_FINAL 0x80
#define FLAG_TRANSIT 0x80
#define FLAG_CONTINUE 0x40
#define FLAG_ACK 0x40
#define FLAG_READ 0x40
#define FLAG_WRITE 0x20
#define FLAG_BIDI_OFLO 0x10
#define FLAG_BIDI_UFLOW 0x08
#define FLAG_OVERFLOW 0x04
#define FLAG_UNDERFLOW 0x02
#define FLAG_STATUS 0x01
#define SG_SECURITY_NEGOTIATION 0
#define SG_LOGIN_OPERATIONAL_NEGOTIATION 1
#define SG_FULL_FEATURE_PHASE 3
#define CSG_SHIFT 2
#define SG_MASK 3
#define NEXT_PHASE(ph) ((!ph) ? 1 : 3)
#define ABORT_TASK 1
#define ABORT_TASK_SET 2
#define CLEAR_ACA 3
#define CLEAR_TASK_SET 4
#define LOGICAL_UNIT_RESET 5
#define TARGET_WARM_RESET 6
#define TARGET_COLD_RESET 7
#define TASK_REASSIGN 8
#define T_FORMAT_OUI 0x00
#define T_FORMAT_EN 0x40
#define T_FORMAT_RANDOM 0x80
#define ATTR_UNTAGGED 0
#define ATTR_SIMPLE 1
#define ATTR_ORDERED 2
#define ATTR_HEAD_OF_QUEUE 3
#define ATTR_ACA 4
#define IOP_NOP_Out 0x00
#define IOP_SCSI_Command 0x01
#define IOP_SCSI_Task_Management 0x02
#define IOP_Login_Request 0x03
#define IOP_Text_Request 0x04
#define IOP_SCSI_Data_out 0x05
#define IOP_Logout_Request 0x06
#define IOP_SNACK_Request 0x10
#define TOP_NOP_In 0x20
#define TOP_SCSI_Response 0x21
#define TOP_SCSI_Task_Management 0x22
#define TOP_Login_Response 0x23
#define TOP_Text_Response 0x24
#define TOP_SCSI_Data_in 0x25
#define TOP_Logout_Response 0x26
#define TOP_R2T 0x31
#define TOP_Asynchronous_Message 0x32
#define TOP_Reject 0x3f
struct scsi_command_pdu_s
{
uint32_t ExpectedDataTransferLength;
uint32_t CmdSN;
uint32_t ExpStatSN;
uint8_t SCSI_CDB[16];
} __packed;
typedef struct scsi_command_pdu_s scsi_command_pdu_t;
struct scsi_response_pdu_s
{
uint32_t SNACKTag;
uint32_t StatSN;
uint32_t ExpCmdSN;
uint32_t MaxCmdSN;
uint32_t ExpDataSN;
uint32_t ReadResidualCount;
uint32_t ResidualCount;
} __packed;
typedef struct scsi_response_pdu_s scsi_response_pdu_t;
struct task_management_req_pdu_s
{
uint32_t ReferencedTaskTag;
uint32_t CmdSN;
uint32_t ExpStatSN;
uint32_t RefCmdSN;
uint32_t ExpDataSN;
uint8_t reserved[8];
} __packed;
typedef struct task_management_req_pdu_s task_management_req_pdu_t;
struct task_management_rsp_pdu_s
{
uint32_t reserved1;
uint32_t StatSN;
uint32_t ExpCmdSN;
uint32_t MaxCmdSN;
uint8_t reserved2[12];
} __packed;
typedef struct task_management_rsp_pdu_s task_management_rsp_pdu_t;
struct data_out_pdu_s
{
uint32_t TargetTransferTag;
uint32_t reserved1;
uint32_t ExpStatSN;
uint32_t reserved2;
uint32_t DataSN;
uint32_t BufferOffset;
uint32_t reserved3;
} __packed;
typedef struct data_out_pdu_s data_out_pdu_t;
struct data_in_pdu_s
{
uint32_t TargetTransferTag;
uint32_t StatSN;
uint32_t ExpCmdSN;
uint32_t MaxCmdSN;
uint32_t DataSN;
uint32_t BufferOffset;
uint32_t ResidualCount;
} __packed;
typedef struct data_in_pdu_s data_in_pdu_t;
struct r2t_pdu_s
{
uint32_t TargetTransferTag;
uint32_t StatSN;
uint32_t ExpCmdSN;
uint32_t MaxCmdSN;
uint32_t R2TSN;
uint32_t BufferOffset;
uint32_t DesiredDataTransferLength;
} __packed;
typedef struct r2t_pdu_s r2t_pdu_t;
struct asynch_pdu_s
{
uint32_t reserved1;
uint32_t StatSN;
uint32_t ExpCmdSN;
uint32_t MaxCmdSN;
uint8_t AsyncEvent;
uint8_t AsyncVCode;
uint16_t Parameter1;
uint16_t Parameter2;
uint16_t Parameter3;
uint32_t reserved2;
} __packed;
typedef struct asynch_pdu_s asynch_pdu_t;
struct text_req_pdu_s
{
uint32_t TargetTransferTag;
uint32_t CmdSN;
uint32_t ExpStatSN;
uint8_t reserved[16];
} __packed;
typedef struct text_req_pdu_s text_req_pdu_t;
struct text_rsp_pdu_s
{
uint32_t TargetTransferTag;
uint32_t StatSN;
uint32_t ExpCmdSN;
uint32_t MaxCmdSN;
uint8_t reserved[12];
} __packed;
typedef struct text_rsp_pdu_s text_rsp_pdu_t;
struct login_req_pdu_s
{
uint16_t CID;
uint16_t reserved1;
uint32_t CmdSN;
uint32_t ExpStatSN;
uint8_t reserved2[16];
} __packed;
typedef struct login_req_pdu_s login_req_pdu_t;
struct login_isid_s
{
uint8_t ISID_A;
uint16_t ISID_B;
uint8_t ISID_C;
uint16_t ISID_D;
uint16_t TSIH;
} __packed;
typedef struct login_isid_s login_isid_t;
struct login_rsp_pdu_s
{
uint32_t reserved1;
uint32_t StatSN;
uint32_t ExpCmdSN;
uint32_t MaxCmdSN;
uint8_t StatusClass;
uint8_t StatusDetail;
uint8_t reserved2[10];
} __packed;
typedef struct login_rsp_pdu_s login_rsp_pdu_t;
struct logout_req_pdu_s
{
uint16_t CID;
uint16_t reserved2;
uint32_t CmdSN;
uint32_t ExpStatSN;
uint8_t reserved3[16];
} __packed;
typedef struct logout_req_pdu_s logout_req_pdu_t;
struct logout_rsp_pdu_s
{
uint32_t reserved2;
uint32_t StatSN;
uint32_t ExpCmdSN;
uint32_t MaxCmdSN;
uint32_t reserved3;
uint16_t Time2Wait;
uint16_t Time2Retain;
uint32_t reserved4;
} __packed;
typedef struct logout_rsp_pdu_s logout_rsp_pdu_t;
#define SNACK_DATA_NAK 0
#define SNACK_STATUS_NAK 1
#define SNACK_DATA_ACK 2
#define SNACK_RDATA_NAK 3
struct snack_req_pdu_s
{
uint32_t TargetTransferTag;
uint32_t reserved1;
uint32_t ExpStatSN;
uint8_t reserved2[8];
uint32_t BegRun;
uint32_t RunLength;
} __packed;
typedef struct snack_req_pdu_s snack_req_pdu_t;
#define REJECT_DIGEST_ERROR 2
#define REJECT_SNACK 3
#define REJECT_PROTOCOL_ERROR 4
#define REJECT_CMD_NOT_SUPPORTED 5
#define REJECT_IMMED_COMMAND 6
#define REJECT_TASK_IN_PROGRESS 7
#define REJECT_INVALID_DATA_ACK 8
#define REJECT_INVALID_PDU_FIELD 9
#define REJECT_LONG_OPERATION 10
#define REJECT_NEGOTIATION_RESET 11
#define REJECT_WAITING_FOR_LOGOUT 12
struct reject_pdu_s
{
uint32_t reserved2;
uint32_t StatSN;
uint32_t ExpCmdSN;
uint32_t MaxCmdSN;
uint8_t DataSN;
uint8_t reserved[8];
} __packed;
typedef struct reject_pdu_s reject_pdu_t;
struct nop_out_pdu_s
{
uint32_t TargetTransferTag;
uint32_t CmdSN;
uint32_t ExpStatSN;
uint8_t reserved[16];
} __packed;
typedef struct nop_out_pdu_s nop_out_pdu_t;
struct nop_in_pdu_s
{
uint32_t TargetTransferTag;
uint32_t StatSN;
uint32_t ExpCmdSN;
uint32_t MaxCmdSN;
uint8_t reserved3[12];
} __packed;
typedef struct nop_in_pdu_s nop_in_pdu_t;
struct pdu_header_s
{
uint8_t pduh_Opcode;
uint8_t pduh_Flags;
uint8_t pduh_OpcodeSpecific[2];
uint8_t pduh_TotalAHSLength;
uint8_t pduh_DataSegmentLength[3];
uint64_t pduh_LUN;
uint32_t pduh_InitiatorTaskTag;
union
{
scsi_command_pdu_t command;
scsi_response_pdu_t response;
task_management_req_pdu_t task_req;
task_management_rsp_pdu_t task_rsp;
data_out_pdu_t data_out;
data_in_pdu_t data_in;
r2t_pdu_t r2t;
asynch_pdu_t asynch;
text_req_pdu_t text_req;
text_rsp_pdu_t text_rsp;
login_req_pdu_t login_req;
login_rsp_pdu_t login_rsp;
logout_req_pdu_t logout_req;
logout_rsp_pdu_t logout_rsp;
snack_req_pdu_t snack;
reject_pdu_t reject;
nop_out_pdu_t nop_out;
nop_in_pdu_t nop_in;
} pduh_p;
uint32_t pduh_HeaderDigest;
} __packed;
typedef struct pdu_header_s pdu_header_t;
#endif