Home | History | Annotate | Line # | Download | only in iscsi
      1 /*	$NetBSD: iscsi_pdu.h,v 1.4 2017/12/03 19:07:10 christos Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2004,2005,2006,2011 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Wasabi Systems, Inc.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 #ifndef _ISCSI_PDU_H
     32 #define _ISCSI_PDU_H
     33 
     34 #define BHS_SIZE           48	/* Basic Header Segment (without digest) */
     35 #define PDU_HEADER_SIZE    52	/* PDU Header with Digest */
     36 
     37 #define OP_IMMEDIATE       0x40	/* Bit 1 in Opcode field: immediate delivery */
     38 #define OPCODE_MASK        0x3f	/* Mask for opcode */
     39 
     40 /* PDU Flags field */
     41 
     42 #define FLAG_FINAL         0x80	/* Bit 0: Final PDU in sequence */
     43 #define FLAG_TRANSIT       0x80	/* Bit 0: Transit to next login phase */
     44 #define FLAG_CONTINUE      0x40	/* Bit 1: Continue PDU */
     45 #define FLAG_ACK           0x40	/* Bit 1: Acknowledge */
     46 #define FLAG_READ          0x40	/* Bit 1: Read Data */
     47 #define FLAG_WRITE         0x20	/* Bit 2: Write Data */
     48 #define FLAG_BIDI_OFLO     0x10	/* Bit 3: Bidirectional Read Residual Oflow */
     49 #define FLAG_BIDI_UFLOW    0x08	/* Bit 4: Bidirectional Read Residual Uflow */
     50 #define FLAG_OVERFLOW      0x04	/* Bit 5: Residual Overflow */
     51 #define FLAG_UNDERFLOW     0x02	/* Bit 6: Residual Underflow */
     52 #define FLAG_STATUS        0x01	/* Bit 7: Command Status is valid */
     53 
     54 /* CSG/NSG flag field codes */
     55 
     56 #define SG_SECURITY_NEGOTIATION           0
     57 #define SG_LOGIN_OPERATIONAL_NEGOTIATION  1
     58 #define SG_FULL_FEATURE_PHASE             3
     59 
     60 #define CSG_SHIFT          2	/* shift factor for CSG field */
     61 #define SG_MASK            3	/* mask for CSG (after shift) and NSG */
     62 
     63 #define NEXT_PHASE(ph)  ((!ph) ? 1 : 3)	/* no phase 2 */
     64 
     65 /* Task Management Function Codes (in Flags byte) */
     66 
     67 #define ABORT_TASK            1
     68 #define ABORT_TASK_SET        2
     69 #define CLEAR_ACA             3
     70 #define CLEAR_TASK_SET        4
     71 #define LOGICAL_UNIT_RESET    5
     72 #define TARGET_WARM_RESET     6
     73 #define TARGET_COLD_RESET     7
     74 #define TASK_REASSIGN         8
     75 
     76 /* ISID T-Field (first byte) */
     77 
     78 #define T_FORMAT_OUI    0x00
     79 #define T_FORMAT_EN     0x40
     80 #define T_FORMAT_RANDOM 0x80
     81 
     82 
     83 /* Task Attributes */
     84 
     85 #define ATTR_UNTAGGED         0
     86 #define ATTR_SIMPLE           1
     87 #define ATTR_ORDERED          2
     88 #define ATTR_HEAD_OF_QUEUE    3
     89 #define ATTR_ACA              4
     90 
     91 /* Initiator Opcodes */
     92 
     93 #define IOP_NOP_Out              0x00
     94 #define IOP_SCSI_Command         0x01
     95 #define IOP_SCSI_Task_Management 0x02
     96 #define IOP_Login_Request        0x03
     97 #define IOP_Text_Request         0x04
     98 #define IOP_SCSI_Data_out        0x05
     99 #define IOP_Logout_Request       0x06
    100 #define IOP_SNACK_Request        0x10
    101 
    102 /* Target Opcodes */
    103 
    104 #define TOP_NOP_In               0x20
    105 #define TOP_SCSI_Response        0x21
    106 #define TOP_SCSI_Task_Management 0x22
    107 #define TOP_Login_Response       0x23
    108 #define TOP_Text_Response        0x24
    109 #define TOP_SCSI_Data_in         0x25
    110 #define TOP_Logout_Response      0x26
    111 #define TOP_R2T                  0x31
    112 #define TOP_Asynchronous_Message 0x32
    113 #define TOP_Reject               0x3f
    114 
    115 /*
    116  * The Opcode-dependent fields of the BHS, defined per PDU
    117  */
    118 
    119 /* Command + Response */
    120 
    121 struct scsi_command_pdu_s
    122 {
    123 	uint32_t ExpectedDataTransferLength;
    124 	uint32_t CmdSN;
    125 	uint32_t ExpStatSN;
    126 	uint8_t SCSI_CDB[16];
    127 } __packed;
    128 
    129 typedef struct scsi_command_pdu_s scsi_command_pdu_t;
    130 
    131 struct scsi_response_pdu_s
    132 {
    133 	uint32_t SNACKTag;
    134 	uint32_t StatSN;
    135 	uint32_t ExpCmdSN;
    136 	uint32_t MaxCmdSN;
    137 	uint32_t ExpDataSN;
    138 	uint32_t ReadResidualCount;
    139 	uint32_t ResidualCount;
    140 } __packed;
    141 
    142 typedef struct scsi_response_pdu_s scsi_response_pdu_t;
    143 
    144 
    145 /* Task Management */
    146 
    147 struct task_management_req_pdu_s
    148 {
    149 	uint32_t ReferencedTaskTag;
    150 	uint32_t CmdSN;
    151 	uint32_t ExpStatSN;
    152 	uint32_t RefCmdSN;
    153 	uint32_t ExpDataSN;
    154 	uint8_t reserved[8];
    155 } __packed;
    156 
    157 typedef struct task_management_req_pdu_s task_management_req_pdu_t;
    158 
    159 
    160 struct task_management_rsp_pdu_s
    161 {
    162 	uint32_t reserved1;
    163 	uint32_t StatSN;
    164 	uint32_t ExpCmdSN;
    165 	uint32_t MaxCmdSN;
    166 	uint8_t reserved2[12];
    167 } __packed;
    168 
    169 typedef struct task_management_rsp_pdu_s task_management_rsp_pdu_t;
    170 
    171 
    172 /* Data Out & In, R2T */
    173 
    174 struct data_out_pdu_s
    175 {
    176 	uint32_t TargetTransferTag;
    177 	uint32_t reserved1;
    178 	uint32_t ExpStatSN;
    179 	uint32_t reserved2;
    180 	uint32_t DataSN;
    181 	uint32_t BufferOffset;
    182 	uint32_t reserved3;
    183 } __packed;
    184 
    185 typedef struct data_out_pdu_s data_out_pdu_t;
    186 
    187 
    188 struct data_in_pdu_s
    189 {
    190 	uint32_t TargetTransferTag;
    191 	uint32_t StatSN;
    192 	uint32_t ExpCmdSN;
    193 	uint32_t MaxCmdSN;
    194 	uint32_t DataSN;
    195 	uint32_t BufferOffset;
    196 	uint32_t ResidualCount;
    197 } __packed;
    198 
    199 typedef struct data_in_pdu_s data_in_pdu_t;
    200 
    201 
    202 struct r2t_pdu_s
    203 {
    204 	uint32_t TargetTransferTag;
    205 	uint32_t StatSN;
    206 	uint32_t ExpCmdSN;
    207 	uint32_t MaxCmdSN;
    208 	uint32_t R2TSN;
    209 	uint32_t BufferOffset;
    210 	uint32_t DesiredDataTransferLength;
    211 } __packed;
    212 
    213 typedef struct r2t_pdu_s r2t_pdu_t;
    214 
    215 
    216 /* Asynch message */
    217 
    218 struct asynch_pdu_s
    219 {
    220 	uint32_t reserved1;
    221 	uint32_t StatSN;
    222 	uint32_t ExpCmdSN;
    223 	uint32_t MaxCmdSN;
    224 	uint8_t AsyncEvent;
    225 	uint8_t AsyncVCode;
    226 	uint16_t Parameter1;
    227 	uint16_t Parameter2;
    228 	uint16_t Parameter3;
    229 	uint32_t reserved2;
    230 } __packed;
    231 
    232 typedef struct asynch_pdu_s asynch_pdu_t;
    233 
    234 
    235 /* Text request / response */
    236 
    237 struct text_req_pdu_s
    238 {
    239 	uint32_t TargetTransferTag;
    240 	uint32_t CmdSN;
    241 	uint32_t ExpStatSN;
    242 	uint8_t reserved[16];
    243 } __packed;
    244 
    245 typedef struct text_req_pdu_s text_req_pdu_t;
    246 
    247 
    248 struct text_rsp_pdu_s
    249 {
    250 	uint32_t TargetTransferTag;
    251 	uint32_t StatSN;
    252 	uint32_t ExpCmdSN;
    253 	uint32_t MaxCmdSN;
    254 	uint8_t reserved[12];
    255 } __packed;
    256 
    257 typedef struct text_rsp_pdu_s text_rsp_pdu_t;
    258 
    259 
    260 /* Login request / response */
    261 
    262 struct login_req_pdu_s
    263 {
    264 	uint16_t CID;
    265 	uint16_t reserved1;
    266 	uint32_t CmdSN;
    267 	uint32_t ExpStatSN;
    268 	uint8_t reserved2[16];
    269 } __packed;
    270 
    271 typedef struct login_req_pdu_s login_req_pdu_t;
    272 
    273 /* Overlays LUN field in login request and response */
    274 struct login_isid_s
    275 {
    276 	uint8_t ISID_A;
    277 	uint16_t ISID_B;
    278 	uint8_t ISID_C;
    279 	uint16_t ISID_D;
    280 	uint16_t TSIH;
    281 } __packed;
    282 
    283 typedef struct login_isid_s login_isid_t;
    284 
    285 struct login_rsp_pdu_s
    286 {
    287 	uint32_t reserved1;
    288 	uint32_t StatSN;
    289 	uint32_t ExpCmdSN;
    290 	uint32_t MaxCmdSN;
    291 	uint8_t StatusClass;
    292 	uint8_t StatusDetail;
    293 	uint8_t reserved2[10];
    294 } __packed;
    295 
    296 typedef struct login_rsp_pdu_s login_rsp_pdu_t;
    297 
    298 
    299 /* Logout request / response */
    300 
    301 struct logout_req_pdu_s
    302 {
    303 	uint16_t CID;
    304 	uint16_t reserved2;
    305 	uint32_t CmdSN;
    306 	uint32_t ExpStatSN;
    307 	uint8_t reserved3[16];
    308 } __packed;
    309 
    310 typedef struct logout_req_pdu_s logout_req_pdu_t;
    311 
    312 
    313 struct logout_rsp_pdu_s
    314 {
    315 	uint32_t reserved2;
    316 	uint32_t StatSN;
    317 	uint32_t ExpCmdSN;
    318 	uint32_t MaxCmdSN;
    319 	uint32_t reserved3;
    320 	uint16_t Time2Wait;
    321 	uint16_t Time2Retain;
    322 	uint32_t reserved4;
    323 } __packed;
    324 
    325 typedef struct logout_rsp_pdu_s logout_rsp_pdu_t;
    326 
    327 
    328 /* SNACK request */
    329 
    330 /* SNACK Types (in Flags field) */
    331 
    332 #define SNACK_DATA_NAK     0
    333 #define SNACK_STATUS_NAK   1
    334 #define SNACK_DATA_ACK     2
    335 #define SNACK_RDATA_NAK    3
    336 
    337 struct snack_req_pdu_s
    338 {
    339 	uint32_t TargetTransferTag;
    340 	uint32_t reserved1;
    341 	uint32_t ExpStatSN;
    342 	uint8_t reserved2[8];
    343 	uint32_t BegRun;
    344 	uint32_t RunLength;
    345 } __packed;
    346 
    347 typedef struct snack_req_pdu_s snack_req_pdu_t;
    348 
    349 
    350 /* Reject */
    351 
    352 #define REJECT_DIGEST_ERROR         2
    353 #define REJECT_SNACK                3
    354 #define REJECT_PROTOCOL_ERROR       4
    355 #define REJECT_CMD_NOT_SUPPORTED    5
    356 #define REJECT_IMMED_COMMAND        6
    357 #define REJECT_TASK_IN_PROGRESS     7
    358 #define REJECT_INVALID_DATA_ACK     8
    359 #define REJECT_INVALID_PDU_FIELD    9
    360 #define REJECT_LONG_OPERATION       10
    361 #define REJECT_NEGOTIATION_RESET    11
    362 #define REJECT_WAITING_FOR_LOGOUT   12
    363 
    364 
    365 struct reject_pdu_s
    366 {
    367 	uint32_t reserved2;
    368 	uint32_t StatSN;
    369 	uint32_t ExpCmdSN;
    370 	uint32_t MaxCmdSN;
    371 	uint8_t DataSN;
    372 	uint8_t reserved[8];
    373 } __packed;
    374 
    375 typedef struct reject_pdu_s reject_pdu_t;
    376 
    377 
    378 /* NOP Out & In */
    379 
    380 struct nop_out_pdu_s
    381 {
    382 	uint32_t TargetTransferTag;
    383 	uint32_t CmdSN;
    384 	uint32_t ExpStatSN;
    385 	uint8_t reserved[16];
    386 } __packed;
    387 
    388 typedef struct nop_out_pdu_s nop_out_pdu_t;
    389 
    390 
    391 struct nop_in_pdu_s
    392 {
    393 	uint32_t TargetTransferTag;
    394 	uint32_t StatSN;
    395 	uint32_t ExpCmdSN;
    396 	uint32_t MaxCmdSN;
    397 	uint8_t reserved3[12];
    398 } __packed;
    399 
    400 typedef struct nop_in_pdu_s nop_in_pdu_t;
    401 
    402 
    403 /*
    404  * The complete PDU Header.
    405  */
    406 
    407 struct pdu_header_s
    408 {
    409 	uint8_t pduh_Opcode;
    410 	uint8_t pduh_Flags;
    411 	uint8_t pduh_OpcodeSpecific[2];
    412 	uint8_t pduh_TotalAHSLength;
    413 	uint8_t pduh_DataSegmentLength[3];
    414 	uint64_t pduh_LUN;
    415 	uint32_t pduh_InitiatorTaskTag;
    416 	union
    417 	{
    418 		scsi_command_pdu_t command;
    419 		scsi_response_pdu_t response;
    420 		task_management_req_pdu_t task_req;
    421 		task_management_rsp_pdu_t task_rsp;
    422 		data_out_pdu_t data_out;
    423 		data_in_pdu_t data_in;
    424 		r2t_pdu_t r2t;
    425 		asynch_pdu_t asynch;
    426 		text_req_pdu_t text_req;
    427 		text_rsp_pdu_t text_rsp;
    428 		login_req_pdu_t login_req;
    429 		login_rsp_pdu_t login_rsp;
    430 		logout_req_pdu_t logout_req;
    431 		logout_rsp_pdu_t logout_rsp;
    432 		snack_req_pdu_t snack;
    433 		reject_pdu_t reject;
    434 		nop_out_pdu_t nop_out;
    435 		nop_in_pdu_t nop_in;
    436 	} pduh_p;
    437 	uint32_t pduh_HeaderDigest;
    438 } __packed;
    439 
    440 typedef struct pdu_header_s pdu_header_t;
    441 
    442 #endif /* !_ISCSI_PDU_H */
    443