| /* |
| * Copyright (C) 2002 - 2003 Ardis Technologies <roman@ardistech.com> |
| * Copyright (C) 2007 - 2018 Vladislav Bolkhovitin |
| * Copyright (C) 2007 - 2018 Western Digital Corporation |
| * |
| * This program is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU General Public License |
| * as published by the Free Software Foundation, version 2 |
| * of the License. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| */ |
| |
| #ifndef __ISCSI_HDR_H__ |
| #define __ISCSI_HDR_H__ |
| |
| #include <linux/types.h> |
| #include <asm/byteorder.h> |
| |
| #define ISCSI_VERSION 0 |
| |
| #ifndef __packed |
| #error The macro __packed has not been defined. |
| #endif |
| |
| /* iSCSI command PDU header. See also section 10.3 in RFC 3720. */ |
| struct iscsi_hdr { |
| u8 opcode; /* 0 */ |
| u8 flags; |
| u8 spec1[2]; |
| #if defined(__BIG_ENDIAN_BITFIELD) |
| struct { /* 4 */ |
| unsigned ahslength:8; |
| unsigned datalength:24; |
| } length; |
| #elif defined(__LITTLE_ENDIAN_BITFIELD) |
| __be32 length; /* 4 */ |
| #endif |
| __be64 lun; /* 8 */ |
| __be32 itt; /* 16 */ |
| __be32 ttt; /* 20 */ |
| |
| /* |
| * SN fields most time stay converted to the CPU form and only received |
| * and send in the BE form. |
| */ |
| u32 sn; /* 24 */ |
| u32 exp_sn; /* 28 */ |
| u32 max_sn; /* 32 */ |
| |
| __be32 spec3[3]; /* 36 */ |
| } __packed; /* 48 */ |
| |
| /* Opcode encoding bits */ |
| #define ISCSI_OP_RETRY 0x80 |
| #define ISCSI_OP_IMMEDIATE 0x40 |
| #define ISCSI_OPCODE_MASK 0x3F |
| |
| /* Client to Server Message Opcode values */ |
| #define ISCSI_OP_NOP_OUT 0x00 |
| #define ISCSI_OP_SCSI_CMD 0x01 |
| #define ISCSI_OP_SCSI_TASK_MGT_MSG 0x02 |
| #define ISCSI_OP_LOGIN_CMD 0x03 |
| #define ISCSI_OP_TEXT_CMD 0x04 |
| #define ISCSI_OP_SCSI_DATA_OUT 0x05 |
| #define ISCSI_OP_LOGOUT_CMD 0x06 |
| #define ISCSI_OP_SNACK_CMD 0x10 |
| |
| /* Server to Client Message Opcode values */ |
| #define ISCSI_OP_NOP_IN 0x20 |
| #define ISCSI_OP_SCSI_RSP 0x21 |
| #define ISCSI_OP_SCSI_TASK_MGT_RSP 0x22 |
| #define ISCSI_OP_LOGIN_RSP 0x23 |
| #define ISCSI_OP_TEXT_RSP 0x24 |
| #define ISCSI_OP_SCSI_DATA_IN 0x25 |
| #define ISCSI_OP_LOGOUT_RSP 0x26 |
| #define ISCSI_OP_R2T 0x31 |
| #define ISCSI_OP_ASYNC_MSG 0x32 |
| #define ISCSI_OP_REJECT 0x3f |
| |
| struct iscsi_ahs_hdr { |
| __be16 ahslength; |
| u8 ahstype; |
| } __packed; |
| |
| #define ISCSI_AHSTYPE_CDB 1 |
| #define ISCSI_AHSTYPE_RLENGTH 2 |
| |
| union iscsi_sid { |
| struct { |
| u8 isid[6]; /* Initiator Session ID */ |
| __be16 tsih; /* Target Session ID */ |
| } id; |
| __be64 id64; |
| } __packed; |
| |
| struct iscsi_scsi_cmd_hdr { |
| u8 opcode; |
| u8 flags; |
| __be16 rsvd1; |
| u8 ahslength; |
| u8 datalength[3]; |
| __be64 lun; |
| __be32 itt; |
| __be32 data_length; |
| u32 cmd_sn; |
| u32 exp_stat_sn; |
| u8 scb[16]; |
| } __packed; |
| |
| #define ISCSI_CMD_FINAL 0x80 |
| #define ISCSI_CMD_READ 0x40 |
| #define ISCSI_CMD_WRITE 0x20 |
| #define ISCSI_CMD_ATTR_MASK 0x07 |
| #define ISCSI_CMD_UNTAGGED 0x00 |
| #define ISCSI_CMD_SIMPLE 0x01 |
| #define ISCSI_CMD_ORDERED 0x02 |
| #define ISCSI_CMD_HEAD_OF_QUEUE 0x03 |
| #define ISCSI_CMD_ACA 0x04 |
| |
| struct iscsi_cdb_ahdr { |
| __be16 ahslength; |
| u8 ahstype; |
| u8 reserved; |
| u8 cdb[0]; |
| } __packed; |
| |
| struct iscsi_rlength_ahdr { |
| __be16 ahslength; |
| u8 ahstype; |
| u8 reserved; |
| __be32 read_length; |
| } __packed; |
| |
| struct iscsi_scsi_rsp_hdr { |
| u8 opcode; |
| u8 flags; |
| u8 response; |
| u8 cmd_status; |
| u8 ahslength; |
| u8 datalength[3]; |
| u32 rsvd1[2]; |
| __be32 itt; |
| __be32 snack; |
| u32 stat_sn; |
| u32 exp_cmd_sn; |
| u32 max_cmd_sn; |
| u32 exp_data_sn; |
| __be32 bi_residual_count; |
| __be32 residual_count; |
| } __packed; |
| |
| #define ISCSI_FLG_RESIDUAL_UNDERFLOW 0x02 |
| #define ISCSI_FLG_RESIDUAL_OVERFLOW 0x04 |
| #define ISCSI_FLG_BIRESIDUAL_UNDERFLOW 0x08 |
| #define ISCSI_FLG_BIRESIDUAL_OVERFLOW 0x10 |
| |
| #define ISCSI_RESPONSE_COMMAND_COMPLETED 0x00 |
| #define ISCSI_RESPONSE_TARGET_FAILURE 0x01 |
| |
| struct iscsi_sense_data { |
| __be16 length; |
| u8 data[0]; |
| } __packed; |
| |
| struct iscsi_task_mgt_hdr { |
| u8 opcode; |
| u8 function; |
| __be16 rsvd1; |
| u8 ahslength; |
| u8 datalength[3]; |
| __be64 lun; |
| __be32 itt; |
| __be32 rtt; |
| u32 cmd_sn; |
| u32 exp_stat_sn; |
| u32 ref_cmd_sn; |
| u32 exp_data_sn; |
| u32 rsvd2[2]; |
| } __packed; |
| |
| #define ISCSI_FUNCTION_MASK 0x7f |
| |
| #define ISCSI_FUNCTION_ABORT_TASK 1 |
| #define ISCSI_FUNCTION_ABORT_TASK_SET 2 |
| #define ISCSI_FUNCTION_CLEAR_ACA 3 |
| #define ISCSI_FUNCTION_CLEAR_TASK_SET 4 |
| #define ISCSI_FUNCTION_LOGICAL_UNIT_RESET 5 |
| #define ISCSI_FUNCTION_TARGET_WARM_RESET 6 |
| #define ISCSI_FUNCTION_TARGET_COLD_RESET 7 |
| #define ISCSI_FUNCTION_TASK_REASSIGN 8 |
| |
| struct iscsi_task_rsp_hdr { |
| u8 opcode; |
| u8 flags; |
| u8 response; |
| u8 rsvd1; |
| u8 ahslength; |
| u8 datalength[3]; |
| u32 rsvd2[2]; |
| __be32 itt; |
| u32 rsvd3; |
| u32 stat_sn; |
| u32 exp_cmd_sn; |
| u32 max_cmd_sn; |
| u32 rsvd4[3]; |
| } __packed; |
| |
| #define ISCSI_RESPONSE_FUNCTION_COMPLETE 0 |
| #define ISCSI_RESPONSE_UNKNOWN_TASK 1 |
| #define ISCSI_RESPONSE_UNKNOWN_LUN 2 |
| #define ISCSI_RESPONSE_TASK_ALLEGIANT 3 |
| #define ISCSI_RESPONSE_ALLEGIANCE_REASSIGNMENT_UNSUPPORTED 4 |
| #define ISCSI_RESPONSE_FUNCTION_UNSUPPORTED 5 |
| #define ISCSI_RESPONSE_NO_AUTHORIZATION 6 |
| #define ISCSI_RESPONSE_FUNCTION_REJECTED 255 |
| |
| struct iscsi_data_out_hdr { |
| u8 opcode; |
| u8 flags; |
| u16 rsvd1; |
| u8 ahslength; |
| u8 datalength[3]; |
| __be64 lun; |
| __be32 itt; |
| __be32 ttt; |
| u32 rsvd2; |
| u32 exp_stat_sn; |
| u32 rsvd3; |
| __be32 data_sn; |
| __be32 buffer_offset; |
| u32 rsvd4; |
| } __packed; |
| |
| struct iscsi_data_in_hdr { |
| u8 opcode; |
| u8 flags; |
| u8 rsvd1; |
| u8 cmd_status; |
| u8 ahslength; |
| u8 datalength[3]; |
| u32 rsvd2[2]; |
| __be32 itt; |
| __be32 ttt; |
| u32 stat_sn; |
| u32 exp_cmd_sn; |
| u32 max_cmd_sn; |
| __be32 data_sn; |
| __be32 buffer_offset; |
| __be32 residual_count; |
| } __packed; |
| |
| #define ISCSI_FLG_STATUS 0x01 |
| |
| struct iscsi_r2t_hdr { |
| u8 opcode; |
| u8 flags; |
| u16 rsvd1; |
| u8 ahslength; |
| u8 datalength[3]; |
| __be64 lun; |
| __be32 itt; |
| __be32 ttt; |
| u32 stat_sn; |
| u32 exp_cmd_sn; |
| u32 max_cmd_sn; |
| u32 r2t_sn; |
| __be32 buffer_offset; |
| __be32 data_length; |
| } __packed; |
| |
| struct iscsi_async_msg_hdr { |
| u8 opcode; |
| u8 flags; |
| u16 rsvd1; |
| u8 ahslength; |
| u8 datalength[3]; |
| __be64 lun; |
| __be32 ffffffff; |
| u32 rsvd2; |
| u32 stat_sn; |
| u32 exp_cmd_sn; |
| u32 max_cmd_sn; |
| u8 async_event; |
| u8 async_vcode; |
| __be16 param1; |
| __be16 param2; |
| __be16 param3; |
| u32 rsvd3; |
| } __packed; |
| |
| #define ISCSI_ASYNC_SCSI 0 |
| #define ISCSI_ASYNC_LOGOUT 1 |
| #define ISCSI_ASYNC_DROP_CONNECTION 2 |
| #define ISCSI_ASYNC_DROP_SESSION 3 |
| #define ISCSI_ASYNC_PARAM_REQUEST 4 |
| #define ISCSI_ASYNC_VENDOR 255 |
| |
| struct iscsi_text_req_hdr { |
| u8 opcode; |
| u8 flags; |
| u16 rsvd1; |
| u8 ahslength; |
| u8 datalength[3]; |
| u32 rsvd2[2]; |
| __be32 itt; |
| __be32 ttt; |
| u32 cmd_sn; |
| u32 exp_stat_sn; |
| u32 rsvd3[4]; |
| } __packed; |
| |
| struct iscsi_text_rsp_hdr { |
| u8 opcode; |
| u8 flags; |
| u16 rsvd1; |
| u8 ahslength; |
| u8 datalength[3]; |
| u32 rsvd2[2]; |
| __be32 itt; |
| __be32 ttt; |
| u32 stat_sn; |
| u32 exp_cmd_sn; |
| u32 max_cmd_sn; |
| u32 rsvd3[3]; |
| } __packed; |
| |
| struct iscsi_login_req_hdr { |
| u8 opcode; |
| u8 flags; |
| u8 max_version; /* Max. version supported */ |
| u8 min_version; /* Min. version supported */ |
| u8 ahslength; |
| u8 datalength[3]; |
| union iscsi_sid sid; |
| __be32 itt; /* Initiator Task Tag */ |
| __be16 cid; /* Connection ID */ |
| u16 rsvd1; |
| u32 cmd_sn; |
| u32 exp_stat_sn; |
| u32 rsvd2[4]; |
| } __packed; |
| |
| struct iscsi_login_rsp_hdr { |
| u8 opcode; |
| u8 flags; |
| u8 max_version; /* Max. version supported */ |
| u8 active_version; /* Active version */ |
| u8 ahslength; |
| u8 datalength[3]; |
| union iscsi_sid sid; |
| __be32 itt; /* Initiator Task Tag */ |
| u32 rsvd1; |
| u32 stat_sn; |
| u32 exp_cmd_sn; |
| u32 max_cmd_sn; |
| u8 status_class; /* see Login RSP Status classes below */ |
| u8 status_detail; /* see Login RSP Status details below */ |
| u8 rsvd2[10]; |
| } __packed; |
| |
| #define ISCSI_FLG_FINAL 0x80 |
| #define ISCSI_FLG_TRANSIT 0x80 |
| #define ISCSI_FLG_CSG_SECURITY 0x00 |
| #define ISCSI_FLG_CSG_LOGIN 0x04 |
| #define ISCSI_FLG_CSG_FULL_FEATURE 0x0c |
| #define ISCSI_FLG_CSG_MASK 0x0c |
| #define ISCSI_FLG_NSG_SECURITY 0x00 |
| #define ISCSI_FLG_NSG_LOGIN 0x01 |
| #define ISCSI_FLG_NSG_FULL_FEATURE 0x03 |
| #define ISCSI_FLG_NSG_MASK 0x03 |
| |
| /* Login Status response classes */ |
| #define ISCSI_STATUS_SUCCESS 0x00 |
| #define ISCSI_STATUS_REDIRECT 0x01 |
| #define ISCSI_STATUS_INITIATOR_ERR 0x02 |
| #define ISCSI_STATUS_TARGET_ERR 0x03 |
| |
| /* Login Status response detail codes */ |
| /* Class-0 (Success) */ |
| #define ISCSI_STATUS_ACCEPT 0x00 |
| |
| /* Class-1 (Redirection) */ |
| #define ISCSI_STATUS_TGT_MOVED_TEMP 0x01 |
| #define ISCSI_STATUS_TGT_MOVED_PERM 0x02 |
| |
| /* Class-2 (Initiator Error) */ |
| #define ISCSI_STATUS_INIT_ERR 0x00 |
| #define ISCSI_STATUS_AUTH_FAILED 0x01 |
| #define ISCSI_STATUS_TGT_FORBIDDEN 0x02 |
| #define ISCSI_STATUS_TGT_NOT_FOUND 0x03 |
| #define ISCSI_STATUS_TGT_REMOVED 0x04 |
| #define ISCSI_STATUS_NO_VERSION 0x05 |
| #define ISCSI_STATUS_TOO_MANY_CONN 0x06 |
| #define ISCSI_STATUS_MISSING_FIELDS 0x07 |
| #define ISCSI_STATUS_CONN_ADD_FAILED 0x08 |
| #define ISCSI_STATUS_INV_SESSION_TYPE 0x09 |
| #define ISCSI_STATUS_SESSION_NOT_FOUND 0x0a |
| #define ISCSI_STATUS_INV_REQ_TYPE 0x0b |
| |
| /* Class-3 (Target Error) */ |
| #define ISCSI_STATUS_TARGET_ERROR 0x00 |
| #define ISCSI_STATUS_SVC_UNAVAILABLE 0x01 |
| #define ISCSI_STATUS_NO_RESOURCES 0x02 |
| |
| struct iscsi_logout_req_hdr { |
| u8 opcode; |
| u8 flags; |
| u16 rsvd1; |
| u8 ahslength; |
| u8 datalength[3]; |
| u32 rsvd2[2]; |
| __be32 itt; |
| __be16 cid; |
| u16 rsvd3; |
| u32 cmd_sn; |
| u32 exp_stat_sn; |
| u32 rsvd4[4]; |
| } __packed; |
| |
| struct iscsi_logout_rsp_hdr { |
| u8 opcode; |
| u8 flags; |
| u8 response; |
| u8 rsvd1; |
| u8 ahslength; |
| u8 datalength[3]; |
| u32 rsvd2[2]; |
| __be32 itt; |
| u32 rsvd3; |
| u32 stat_sn; |
| u32 exp_cmd_sn; |
| u32 max_cmd_sn; |
| u32 rsvd4; |
| __be16 time2wait; |
| __be16 time2retain; |
| u32 rsvd5; |
| } __packed; |
| |
| struct iscsi_snack_req_hdr { |
| u8 opcode; |
| u8 flags; |
| u16 rsvd1; |
| u8 ahslength; |
| u8 datalength[3]; |
| u32 rsvd2[2]; |
| __be32 itt; |
| __be32 ttt; |
| u32 rsvd3; |
| u32 exp_stat_sn; |
| u32 rsvd4[2]; |
| __be32 beg_run; |
| __be32 run_length; |
| } __packed; |
| |
| struct iscsi_reject_hdr { |
| u8 opcode; |
| u8 flags; |
| u8 reason; |
| u8 rsvd1; |
| u8 ahslength; |
| u8 datalength[3]; |
| u32 rsvd2[2]; |
| __be32 ffffffff; |
| __be32 rsvd3; |
| u32 stat_sn; |
| u32 exp_cmd_sn; |
| u32 max_cmd_sn; |
| __be32 data_sn; |
| u32 rsvd4[2]; |
| } __packed; |
| |
| #define ISCSI_REASON_RESERVED 0x01 |
| #define ISCSI_REASON_DATA_DIGEST_ERROR 0x02 |
| #define ISCSI_REASON_DATA_SNACK_REJECT 0x03 |
| #define ISCSI_REASON_PROTOCOL_ERROR 0x04 |
| #define ISCSI_REASON_UNSUPPORTED_COMMAND 0x05 |
| #define ISCSI_REASON_IMMEDIATE_COMMAND_REJECT 0x06 |
| #define ISCSI_REASON_TASK_IN_PROGRESS 0x07 |
| #define ISCSI_REASON_INVALID_DATA_ACK 0x08 |
| #define ISCSI_REASON_INVALID_PDU_FIELD 0x09 |
| #define ISCSI_REASON_OUT_OF_RESOURCES 0x0a |
| #define ISCSI_REASON_NEGOTIATION_RESET 0x0b |
| #define ISCSI_REASON_WAITING_LOGOUT 0x0c |
| |
| struct iscsi_nop_out_hdr { |
| u8 opcode; |
| u8 flags; |
| u16 rsvd1; |
| u8 ahslength; |
| u8 datalength[3]; |
| __be64 lun; |
| __be32 itt; |
| __be32 ttt; |
| u32 cmd_sn; |
| u32 exp_stat_sn; |
| u32 rsvd2[4]; |
| } __packed; |
| |
| struct iscsi_nop_in_hdr { |
| u8 opcode; |
| u8 flags; |
| u16 rsvd1; |
| u8 ahslength; |
| u8 datalength[3]; |
| __be64 lun; |
| __be32 itt; |
| __be32 ttt; |
| u32 stat_sn; |
| u32 exp_cmd_sn; |
| u32 max_cmd_sn; |
| u32 rsvd2[3]; |
| } __packed; |
| |
| #define ISCSI_RESERVED_TAG_CPU32 (0xffffffffU) |
| #define ISCSI_RESERVED_TAG (cpu_to_be32(ISCSI_RESERVED_TAG_CPU32)) |
| |
| #define cmnd_hdr(cmnd) ((struct iscsi_scsi_cmd_hdr *) (&((cmnd)->pdu.bhs))) |
| #define cmnd_opcode(cmnd) ((cmnd)->pdu.bhs.opcode & ISCSI_OPCODE_MASK) |
| #define cmnd_scsicode(cmnd) (cmnd_hdr((cmnd))->scb[0]) |
| |
| #endif /* __ISCSI_HDR_H__ */ |