1 /*- 2 * Copyright (c) 2005-2008 Daniel Braniss <danny@cs.huji.ac.il> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD: src/sys/dev/iscsi/initiator/iscsi.h,v 1.2 2008/11/25 07:17:11 scottl Exp $ 27 */ 28 /* 29 | $Id: iscsi.h,v 1.17 2006/12/01 09:10:17 danny Exp danny $ 30 */ 31 #ifndef _KERNEL 32 #include <stdbool.h> 33 #else 34 #include <sys/stdint.h> 35 #endif 36 37 #include <sys/objcache.h> 38 #include <bus/cam/cam.h> 39 #include <sys/device.h> 40 41 #define ISCSIDEV "iscsi" 42 43 #define ISCSI_MAX_TARGETS 4 //64 44 45 #define ISCSI_MAX_LUNS 4 46 47 /* 48 | iSCSI commands 49 */ 50 51 /* 52 | Initiator Opcodes: 53 */ 54 #define ISCSI_NOP_OUT 0x00 55 #define ISCSI_SCSI_CMD 0x01 56 #define ISCSI_TASK_CMD 0x02 57 #define ISCSI_LOGIN_CMD 0x03 58 #define ISCSI_TEXT_CMD 0x04 59 #define ISCSI_WRITE_DATA 0x05 60 #define ISCSI_LOGOUT_CMD 0x06 61 #define ISCSI_SNACK 0x10 62 /* 63 | Target Opcodes: 64 */ 65 #define ISCSI_NOP_IN 0x20 66 #define ISCSI_SCSI_RSP 0x21 67 #define ISCSI_TASK_RSP 0x22 68 #define ISCSI_LOGIN_RSP 0x23 69 #define ISCSI_TEXT_RSP 0x24 70 #define ISCSI_READ_DATA 0x25 71 #define ISCSI_LOGOUT_RSP 0x26 72 #define ISCSI_R2T 0x31 73 #define ISCSI_ASYNC 0x32 74 #define ISCSI_REJECT 0x3f 75 /* 76 | PDU stuff 77 */ 78 /* 79 | BHS Basic Header Segment 80 */ 81 typedef struct bhs { 82 // the order is network byte order! 83 u_char opcode:6; 84 u_char I:1; 85 u_char _:1; 86 u_char __:7; 87 u_char F:1; // Final bit 88 u_char ___[2]; 89 90 u_int AHSLength:8; // in 4byte words 91 u_int DSLength:24; // in bytes 92 93 u_int LUN[2]; // or Opcode-specific fields 94 u_int itt; 95 u_int OpcodeSpecificFields[7]; 96 #define CmdSN OpcodeSpecificFields[1] 97 #define ExpStSN OpcodeSpecificFields[2] 98 #define MaxCmdSN OpcodeSpecificFields[3] 99 } bhs_t; 100 101 typedef struct ahs { 102 u_int len:16; 103 u_int type:8; 104 u_int spec:8; 105 char data[0]; 106 } ahs_t; 107 108 typedef struct { 109 // Sequence Numbers 110 // (computers were invented to count, right?) 111 int cmd; 112 int expcmd; 113 int maxcmd; 114 } req_sn_t; 115 116 typedef struct { 117 // Sequence Numbers 118 // (computers were invented to count, right?) 119 int stat; 120 int expcmd; 121 int maxcmd; 122 } rsp_sn_t; 123 124 typedef struct scsi_req { 125 u_char opcode:6; // 0x01 126 u_char I:1; 127 u_char _:1; 128 129 u_char attr:3; 130 u_char _0:2; 131 u_char W:1; 132 u_char R:1; 133 u_char F:1; 134 #define iSCSI_TASK_UNTAGGED 0 135 #define iSCSI_TASK_SIMPLE 1 136 #define iSCSI_TASK_ORDER 2 137 #define iSCSI_TASK_HOFQ 3 138 #define iSCSI_TASK_ACA 4 139 char _1[2]; 140 int len; 141 int lun[2]; 142 int itt; 143 int edtlen; // expectect data transfere length 144 int cmdSN; 145 int extStatSN; 146 int cdb[4]; 147 } scsi_req_t; 148 149 typedef struct scsi_rsp { 150 char opcode; // 0x21 151 u_char flag; 152 u_char response; 153 u_char status; 154 155 int len; 156 int _[2]; 157 int itt; 158 int stag; 159 rsp_sn_t sn; 160 int expdatasn; 161 int bdrcnt; // bidirectional residual count 162 int rcnt; // residual count 163 } scsi_rsp_t; 164 165 typedef struct nop_out { 166 // the order is network byte order! 167 u_char opcode:6; 168 u_char I:1; 169 u_char _:1; 170 u_char __:7; 171 u_char F:1; // Final bit 172 u_char ___[2]; 173 174 u_int len; 175 u_int lun[2]; 176 u_int itt; 177 u_int ttt; 178 req_sn_t sn; 179 u_int mbz[3]; 180 } nop_out_t; 181 182 typedef struct nop_in { 183 // the order is network byte order! 184 u_char opcode:6; 185 u_char I:1; 186 u_char _:1; 187 u_char __:7; 188 u_char F:1; // Final bit 189 u_char ___[2]; 190 191 u_int len; 192 u_int lun[2]; 193 u_int itt; 194 u_int ttt; 195 rsp_sn_t sn; 196 u_int ____[2]; 197 198 } nop_in_t; 199 200 typedef struct r2t { 201 u_char opcode:6; 202 u_char I:1; 203 u_char _:1; 204 u_char __:7; 205 u_char F:1; // Final bit 206 u_char ___[2]; 207 208 u_int len; 209 u_int lun[2]; 210 u_int itt; 211 u_int ttt; 212 rsp_sn_t sn; 213 u_int r2tSN; 214 u_int bo; 215 u_int ddtl; 216 } r2t_t; 217 218 typedef struct data_out { 219 u_char opcode:6; 220 u_char I:1; 221 u_char _:1; 222 u_char __:7; 223 u_char F:1; // Final bit 224 u_char ___[2]; 225 226 u_int len; 227 u_int lun[2]; 228 u_int itt; 229 u_int ttt; 230 rsp_sn_t sn; 231 u_int dsn; // data seq. number 232 u_int bo; 233 u_int ____; 234 } data_out_t; 235 236 typedef struct data_in { 237 u_char opcode:6; 238 u_char I:1; 239 u_char _:1; 240 241 u_char S:1; 242 u_char U:1; 243 u_char O:1; 244 u_char __:3; 245 u_char A:1; 246 u_char F:1; // Final bit 247 u_char ___[1]; 248 u_char status; 249 250 u_int len; 251 u_int lun[2]; 252 u_int itt; 253 u_int ttt; 254 rsp_sn_t sn; 255 u_int dataSN; 256 u_int bo; 257 u_int ____; 258 } data_in_t; 259 260 typedef struct reject { 261 u_char opcode:6; 262 u_char _:2; 263 u_char F:1; 264 u_char __:7; 265 u_char reason; 266 u_char ___; 267 268 u_int len; 269 u_int ____[2]; 270 u_int tt[2]; // must be -1 271 rsp_sn_t sn; 272 u_int dataSN; // or R2TSN or reserved 273 u_int _____[2]; 274 } reject_t; 275 276 typedef struct async { 277 u_char opcode:6; 278 u_char _:2; 279 u_char F:1; 280 u_char __:7; 281 u_char ___[2]; 282 283 u_int len; 284 u_int lun[2]; 285 u_int itt; // must be -1 286 u_int ____; 287 rsp_sn_t sn; 288 289 u_char asyncEvent; 290 u_char asyncVCode; 291 u_char param1[2]; 292 u_char param2[2]; 293 u_char param3[2]; 294 295 u_int _____; 296 297 } async_t; 298 299 typedef struct login_req { 300 char cmd; // 0x03 301 302 u_char NSG:2; 303 u_char CSG:2; 304 u_char _:2; 305 u_char C:1; 306 u_char T:1; 307 308 char v_max; 309 char v_min; 310 311 int len; // remapped via standard bhs 312 char isid[6]; 313 short tsih; 314 int itt; // Initiator Task Tag; 315 316 int CID:16; 317 int rsv:16; 318 319 int cmdSN; 320 int expStatSN; 321 int unused[4]; 322 } login_req_t; 323 324 typedef struct login_rsp { 325 char cmd; // 0x23 326 u_char NSG:2; 327 u_char CSG:2; 328 u_char _1:2; 329 u_char C:1; 330 u_char T:1; 331 332 char v_max; 333 char v_act; 334 335 int len; // remapped via standard bhs 336 char isid[6]; 337 short tsih; 338 int itt; // Initiator Task Tag; 339 int _2; 340 rsp_sn_t sn; 341 int status:16; 342 int _3:16; 343 int _4[2]; 344 } login_rsp_t; 345 346 typedef struct text_req { 347 char cmd; // 0x04 348 349 u_char _1:6; 350 u_char C:1; // Continuation 351 u_char F:1; // Final 352 char _2[2]; 353 354 int len; 355 int itt; // Initiator Task Tag 356 int LUN[2]; 357 int ttt; // Target Transfer Tag 358 int cmdSN; 359 int expStatSN; 360 int unused[4]; 361 } text_req_t; 362 363 typedef struct logout_req { 364 char cmd; // 0x06 365 char reason; // 0 - close session 366 // 1 - close connection 367 // 2 - remove the connection for recovery 368 char _2[2]; 369 370 int len; 371 int _r[2]; 372 int itt; // Initiator Task Tag; 373 374 u_int CID:16; 375 u_int rsv:16; 376 377 int cmdSN; 378 int expStatSN; 379 int unused[4]; 380 } logout_req_t; 381 382 typedef struct logout_rsp { 383 char cmd; // 0x26 384 char cbits; 385 char _1[2]; 386 int len; 387 int _2[2]; 388 int itt; 389 int _3; 390 rsp_sn_t sn; 391 short time2wait; 392 short time2retain; 393 int _4; 394 } logout_rsp_t; 395 396 union ipdu_u { 397 bhs_t bhs; 398 scsi_req_t scsi_req; 399 scsi_rsp_t scsi_rsp; 400 nop_out_t nop_out; 401 nop_in_t nop_in; 402 r2t_t r2t; 403 data_out_t data_out; 404 data_in_t data_in; 405 reject_t reject; 406 async_t async; 407 }; 408 409 /* 410 | Sequence Numbers 411 */ 412 typedef struct { 413 u_int itt; 414 u_int cmd; 415 u_int expCmd; 416 u_int maxCmd; 417 u_int stat; 418 u_int expStat; 419 u_int data; 420 } sn_t; 421 422 /* 423 | in-core version of a Protocol Data Unit 424 */ 425 typedef struct { 426 union ipdu_u ipdu; 427 428 ahs_t *ahs; 429 u_int ahs_len; 430 u_int ahs_size; // the allocated size 431 u_int hdr_dig; // header digest 432 433 u_char *ds; 434 u_int ds_len; 435 u_int ds_size; // the allocated size 436 u_int ds_dig; // data digest 437 } pdu_t; 438 439 typedef struct opvals { 440 int port; 441 int tags; 442 int maxluns; 443 int sockbufsize; 444 445 int maxConnections; 446 int maxRecvDataSegmentLength; 447 int maxXmitDataSegmentLength; // pseudo ... 448 int maxBurstLength; 449 int firstBurstLength; 450 int defaultTime2Wait; 451 int defaultTime2Retain; 452 int maxOutstandingR2T; 453 int errorRecoveryLevel; 454 int targetPortalGroupTag; 455 456 bool initialR2T; 457 bool immediateData; 458 bool dataPDUInOrder; 459 bool dataSequenceInOrder; 460 char *headerDigest; 461 char *dataDigest; 462 char *sessionType; 463 char *sendTargets; 464 char *targetAddress; 465 char *targetAlias; 466 char *targetName; 467 char *initiatorName; 468 char *initiatorAlias; 469 char *authMethod; 470 char *chapSecret; 471 char *chapIName; 472 char *chapDigest; 473 char *tgtChapName; 474 char *tgtChapSecret; 475 int tgtChallengeLen; 476 u_char tgtChapID; 477 char *tgtChapDigest; 478 char *iqn; 479 } isc_opt_t; 480 481 /* 482 | ioctl 483 */ 484 #define ISCSISETSES _IOR('i', 1, int) 485 #define ISCSISETSOC _IOW('i', 2, int) 486 #define ISCSISETOPT _IOW('i', 5, isc_opt_t) 487 #define ISCSIGETOPT _IOR('i', 6, isc_opt_t) 488 489 #define ISCSISEND _IOW('i', 10, pdu_t) 490 #define ISCSIRECV _IOWR('i', 11, pdu_t) 491 492 #define ISCSIPING _IO('i', 20) 493 #define ISCSISIGNAL _IOW('i', 21, int *) 494 495 #define ISCSISTART _IO('i', 30) 496 #define ISCSIRESTART _IO('i', 31) 497 #define ISCSISTOP _IO('i', 32) 498 499 typedef struct iscsi_cam { 500 path_id_t path_id; 501 target_id_t target_id; 502 int target_nluns; 503 lun_id_t target_lun[ISCSI_MAX_LUNS]; 504 } iscsi_cam_t; 505 506 #define ISCSIGETCAM _IOR('i', 33, iscsi_cam_t) 507