freebsd-dev/sys/dev/iscsi/initiator/iscsi.h
Dag-Erling Smørgrav c201d4532c - Add full support for header / data digests.
- Increase target limit from 4 to 64; this limit will be removed entirely
  at a later time.
- Improve recovery from lost network connections.
- Fix some potential deadlocks and a serious memory leak.
- Fix incorrect use of MH_ALIGN (instead of M_ALIGN), which makes no
  practical difference, but triggers a KASSERT with INVARIANTS.
- Fix some warnings in iscontrol(8) and improve the man page somewhat.

Submitted by:	Daniel Braniss <danny@cs.huji.ac.il>
Sponsored by:	Dansk Scanning A/S, Data Robotics Inc.
2010-08-09 12:36:36 +00:00

501 lines
10 KiB
C

/*-
* Copyright (c) 2005-2010 Daniel Braniss <danny@cs.huji.ac.il>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
/*
| $Id: iscsi.h 743 2009-08-08 10:54:53Z danny $
*/
#define TRUE 1
#define FALSE 0
#ifndef _KERNEL
typedef int boolean_t;
#endif
#include <cam/cam.h>
#define ISCSIDEV "iscsi"
#define ISCSI_MAX_TARGETS 64
/*
| iSCSI commands
*/
/*
| Initiator Opcodes:
*/
#define ISCSI_NOP_OUT 0x00
#define ISCSI_SCSI_CMD 0x01
#define ISCSI_TASK_CMD 0x02
#define ISCSI_LOGIN_CMD 0x03
#define ISCSI_TEXT_CMD 0x04
#define ISCSI_WRITE_DATA 0x05
#define ISCSI_LOGOUT_CMD 0x06
#define ISCSI_SNACK 0x10
/*
| Target Opcodes:
*/
#define ISCSI_NOP_IN 0x20
#define ISCSI_SCSI_RSP 0x21
#define ISCSI_TASK_RSP 0x22
#define ISCSI_LOGIN_RSP 0x23
#define ISCSI_TEXT_RSP 0x24
#define ISCSI_READ_DATA 0x25
#define ISCSI_LOGOUT_RSP 0x26
#define ISCSI_R2T 0x31
#define ISCSI_ASYNC 0x32
#define ISCSI_REJECT 0x3f
/*
| PDU stuff
*/
/*
| BHS Basic Header Segment
*/
typedef struct bhs {
// the order is network byte order!
u_char opcode:6;
u_char I:1;
u_char _:1;
u_char __:7;
u_char F:1; // Final bit
u_char ___[2];
u_int AHSLength:8; // in 4byte words
u_int DSLength:24; // in bytes
u_int LUN[2]; // or Opcode-specific fields
u_int itt;
u_int OpcodeSpecificFields[7];
#define CmdSN OpcodeSpecificFields[1]
#define ExpStSN OpcodeSpecificFields[2]
#define MaxCmdSN OpcodeSpecificFields[3]
} bhs_t;
typedef struct ahs {
u_int len:16;
u_int type:8;
u_int spec:8;
char data[0];
} ahs_t;
typedef struct {
// Sequence Numbers
// (computers were invented to count, right?)
int cmd;
int expcmd;
int maxcmd;
} req_sn_t;
typedef struct {
// Sequence Numbers
// (computers were invented to count, right?)
int stat;
int expcmd;
int maxcmd;
} rsp_sn_t;
typedef struct scsi_req {
u_char opcode:6; // 0x01
u_char I:1;
u_char _:1;
u_char attr:3;
u_char _0:2;
u_char W:1;
u_char R:1;
u_char F:1;
#define iSCSI_TASK_UNTAGGED 0
#define iSCSI_TASK_SIMPLE 1
#define iSCSI_TASK_ORDER 2
#define iSCSI_TASK_HOFQ 3
#define iSCSI_TASK_ACA 4
char _1[2];
int len;
int lun[2];
int itt;
int edtlen; // expectect data transfere length
int cmdSN;
int extStatSN;
int cdb[4];
} scsi_req_t;
typedef struct scsi_rsp {
char opcode; // 0x21
u_char flag;
u_char response;
u_char status;
int len;
int _[2];
int itt;
int stag;
rsp_sn_t sn;
int expdatasn;
int bdrcnt; // bidirectional residual count
int rcnt; // residual count
} scsi_rsp_t;
typedef struct nop_out {
// the order is network byte order!
u_char opcode:6;
u_char I:1;
u_char _:1;
u_char __:7;
u_char F:1; // Final bit
u_char ___[2];
u_int len;
u_int lun[2];
u_int itt;
u_int ttt;
req_sn_t sn;
u_int mbz[3];
} nop_out_t;
typedef struct nop_in {
// the order is network byte order!
u_char opcode:6;
u_char I:1;
u_char _:1;
u_char __:7;
u_char F:1; // Final bit
u_char ___[2];
u_int len;
u_int lun[2];
u_int itt;
u_int ttt;
rsp_sn_t sn;
u_int ____[2];
} nop_in_t;
typedef struct r2t {
u_char opcode:6;
u_char I:1;
u_char _:1;
u_char __:7;
u_char F:1; // Final bit
u_char ___[2];
u_int len;
u_int lun[2];
u_int itt;
u_int ttt;
rsp_sn_t sn;
u_int r2tSN;
u_int bo;
u_int ddtl;
} r2t_t;
typedef struct data_out {
u_char opcode:6;
u_char I:1;
u_char _:1;
u_char __:7;
u_char F:1; // Final bit
u_char ___[2];
u_int len;
u_int lun[2];
u_int itt;
u_int ttt;
rsp_sn_t sn;
u_int dsn; // data seq. number
u_int bo;
u_int ____;
} data_out_t;
typedef struct data_in {
u_char opcode:6;
u_char I:1;
u_char _:1;
u_char S:1;
u_char U:1;
u_char O:1;
u_char __:3;
u_char A:1;
u_char F:1; // Final bit
u_char ___[1];
u_char status;
u_int len;
u_int lun[2];
u_int itt;
u_int ttt;
rsp_sn_t sn;
u_int dataSN;
u_int bo;
u_int ____;
} data_in_t;
typedef struct reject {
u_char opcode:6;
u_char _:2;
u_char F:1;
u_char __:7;
u_char reason;
u_char ___;
u_int len;
u_int ____[2];
u_int tt[2]; // must be -1
rsp_sn_t sn;
u_int dataSN; // or R2TSN or reserved
u_int _____[2];
} reject_t;
typedef struct async {
u_char opcode:6;
u_char _:2;
u_char F:1;
u_char __:7;
u_char ___[2];
u_int len;
u_int lun[2];
u_int itt; // must be -1
u_int ____;
rsp_sn_t sn;
u_char asyncEvent;
u_char asyncVCode;
u_char param1[2];
u_char param2[2];
u_char param3[2];
u_int _____;
} async_t;
typedef struct login_req {
char cmd; // 0x03
u_char NSG:2;
u_char CSG:2;
u_char _:2;
u_char C:1;
u_char T:1;
char v_max;
char v_min;
int len; // remapped via standard bhs
char isid[6];
short tsih;
int itt; // Initiator Task Tag;
int CID:16;
int rsv:16;
int cmdSN;
int expStatSN;
int unused[4];
} login_req_t;
typedef struct login_rsp {
char cmd; // 0x23
u_char NSG:2;
u_char CSG:2;
u_char _1:2;
u_char C:1;
u_char T:1;
char v_max;
char v_act;
int len; // remapped via standard bhs
char isid[6];
short tsih;
int itt; // Initiator Task Tag;
int _2;
rsp_sn_t sn;
int status:16;
int _3:16;
int _4[2];
} login_rsp_t;
typedef struct text_req {
char cmd; // 0x04
u_char _1:6;
u_char C:1; // Continuation
u_char F:1; // Final
char _2[2];
int len;
int itt; // Initiator Task Tag
int LUN[2];
int ttt; // Target Transfer Tag
int cmdSN;
int expStatSN;
int unused[4];
} text_req_t;
typedef struct logout_req {
char cmd; // 0x06
char reason; // 0 - close session
// 1 - close connection
// 2 - remove the connection for recovery
char _2[2];
int len;
int _r[2];
int itt; // Initiator Task Tag;
u_int CID:16;
u_int rsv:16;
int cmdSN;
int expStatSN;
int unused[4];
} logout_req_t;
typedef struct logout_rsp {
char cmd; // 0x26
char cbits;
char _1[2];
int len;
int _2[2];
int itt;
int _3;
rsp_sn_t sn;
short time2wait;
short time2retain;
int _4;
} logout_rsp_t;
union ipdu_u {
bhs_t bhs;
scsi_req_t scsi_req;
scsi_rsp_t scsi_rsp;
nop_out_t nop_out;
nop_in_t nop_in;
r2t_t r2t;
data_out_t data_out;
data_in_t data_in;
reject_t reject;
async_t async;
};
/*
| Sequence Numbers
*/
typedef struct {
u_int itt;
u_int cmd;
u_int expCmd;
u_int maxCmd;
u_int stat;
u_int expStat;
u_int data;
} sn_t;
/*
| in-core version of a Protocol Data Unit
*/
typedef struct {
union ipdu_u ipdu;
u_int hdr_dig; // header digest
ahs_t *ahs_addr;
u_int ahs_len;
u_int ahs_size; // the allocated size
u_char *ds_addr;
u_int ds_len;
u_int ds_size; // the allocated size
u_int ds_dig; // data digest
} pdu_t;
typedef struct opvals {
int port;
int tags;
int maxluns;
int sockbufsize;
int maxConnections;
int maxRecvDataSegmentLength;
int maxXmitDataSegmentLength; // pseudo ...
int maxBurstLength;
int firstBurstLength;
int defaultTime2Wait;
int defaultTime2Retain;
int maxOutstandingR2T;
int errorRecoveryLevel;
int targetPortalGroupTag;
boolean_t initialR2T;
boolean_t immediateData;
boolean_t dataPDUInOrder;
boolean_t dataSequenceInOrder;
char *headerDigest;
char *dataDigest;
char *sessionType;
char *sendTargets;
char *targetAddress;
char *targetAlias;
char *targetName;
char *initiatorName;
char *initiatorAlias;
char *authMethod;
char *chapSecret;
char *chapIName;
char *chapDigest;
char *tgtChapName;
char *tgtChapSecret;
int tgtChallengeLen;
u_char tgtChapID;
char *tgtChapDigest;
char *iqn;
char *pidfile;
} isc_opt_t;
/*
| ioctl
*/
#define ISCSISETSES _IOR('i', 1, int)
#define ISCSISETSOC _IOW('i', 2, int)
#define ISCSISETOPT _IOW('i', 5, isc_opt_t)
#define ISCSIGETOPT _IOR('i', 6, isc_opt_t)
#define ISCSISEND _IOW('i', 10, pdu_t)
#define ISCSIRECV _IOWR('i', 11, pdu_t)
#define ISCSIPING _IO('i', 20)
#define ISCSISIGNAL _IOW('i', 21, int *)
#define ISCSISTART _IO('i', 30)
#define ISCSIRESTART _IO('i', 31)
#define ISCSISTOP _IO('i', 32)
typedef struct iscsi_cam {
path_id_t path_id;
target_id_t target_id;
int target_nluns;
} iscsi_cam_t;
#define ISCSIGETCAM _IOR('i', 33, iscsi_cam_t)