iscsi_tcp.h 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. /*
  2. * iSCSI Initiator TCP Transport
  3. * Copyright (C) 2004 Dmitry Yusupov
  4. * Copyright (C) 2004 Alex Aizman
  5. * Copyright (C) 2005 Mike Christie
  6. * maintained by open-iscsi@googlegroups.com
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published
  10. * by the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful, but
  14. * WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * General Public License for more details.
  17. *
  18. * See the file COPYING included with this distribution for more details.
  19. */
  20. #ifndef ISCSI_TCP_H
  21. #define ISCSI_TCP_H
  22. /* Session's states */
  23. #define ISCSI_STATE_FREE 1
  24. #define ISCSI_STATE_LOGGED_IN 2
  25. #define ISCSI_STATE_FAILED 3
  26. #define ISCSI_STATE_TERMINATE 4
  27. /* Connection's states */
  28. #define ISCSI_CONN_INITIAL_STAGE 0
  29. #define ISCSI_CONN_STARTED 1
  30. #define ISCSI_CONN_STOPPED 2
  31. #define ISCSI_CONN_CLEANUP_WAIT 3
  32. /* Connection suspend "bit" */
  33. #define SUSPEND_BIT 1
  34. /* Socket's Receive state machine */
  35. #define IN_PROGRESS_WAIT_HEADER 0x0
  36. #define IN_PROGRESS_HEADER_GATHER 0x1
  37. #define IN_PROGRESS_DATA_RECV 0x2
  38. #define IN_PROGRESS_DDIGEST_RECV 0x3
  39. /* Task Mgmt states */
  40. #define TMABORT_INITIAL 0x0
  41. #define TMABORT_SUCCESS 0x1
  42. #define TMABORT_FAILED 0x2
  43. #define TMABORT_TIMEDOUT 0x3
  44. /* xmit state machine */
  45. #define XMSTATE_IDLE 0x0
  46. #define XMSTATE_R_HDR 0x1
  47. #define XMSTATE_W_HDR 0x2
  48. #define XMSTATE_IMM_HDR 0x4
  49. #define XMSTATE_IMM_DATA 0x8
  50. #define XMSTATE_UNS_INIT 0x10
  51. #define XMSTATE_UNS_HDR 0x20
  52. #define XMSTATE_UNS_DATA 0x40
  53. #define XMSTATE_SOL_HDR 0x80
  54. #define XMSTATE_SOL_DATA 0x100
  55. #define XMSTATE_W_PAD 0x200
  56. #define XMSTATE_DATA_DIGEST 0x400
  57. #define ISCSI_CONN_MAX 1
  58. #define ISCSI_CONN_RCVBUF_MIN 262144
  59. #define ISCSI_CONN_SNDBUF_MIN 262144
  60. #define ISCSI_PAD_LEN 4
  61. #define ISCSI_R2T_MAX 16
  62. #define ISCSI_XMIT_CMDS_MAX 128 /* must be power of 2 */
  63. #define ISCSI_MGMT_CMDS_MAX 32 /* must be power of 2 */
  64. #define ISCSI_MGMT_ITT_OFFSET 0xa00
  65. #define ISCSI_SG_TABLESIZE SG_ALL
  66. #define ISCSI_CMD_PER_LUN 128
  67. #define ISCSI_TCP_MAX_CMD_LEN 16
  68. #define ITT_MASK (0xfff)
  69. #define CID_SHIFT 12
  70. #define CID_MASK (0xffff<<CID_SHIFT)
  71. #define AGE_SHIFT 28
  72. #define AGE_MASK (0xf<<AGE_SHIFT)
  73. struct iscsi_queue {
  74. struct kfifo *queue; /* FIFO Queue */
  75. void **pool; /* Pool of elements */
  76. int max; /* Max number of elements */
  77. };
  78. struct iscsi_session;
  79. struct iscsi_cmd_task;
  80. struct iscsi_mgmt_task;
  81. /* Socket connection recieve helper */
  82. struct iscsi_tcp_recv {
  83. struct iscsi_hdr *hdr;
  84. struct sk_buff *skb;
  85. int offset;
  86. int len;
  87. int hdr_offset;
  88. int copy;
  89. int copied;
  90. int padding;
  91. struct iscsi_cmd_task *ctask; /* current cmd in progress */
  92. /* copied and flipped values */
  93. int opcode;
  94. int flags;
  95. int cmd_status;
  96. int ahslen;
  97. int datalen;
  98. uint32_t itt;
  99. int datadgst;
  100. };
  101. struct iscsi_conn {
  102. struct iscsi_hdr hdr; /* header placeholder */
  103. char hdrext[4*sizeof(__u16) +
  104. sizeof(__u32)];
  105. int data_copied;
  106. char *data; /* data placeholder */
  107. struct socket *sock; /* TCP socket */
  108. int data_size; /* actual recv_dlength */
  109. int stop_stage; /* conn_stop() flag: *
  110. * stop to recover, *
  111. * stop to terminate */
  112. /* iSCSI connection-wide sequencing */
  113. uint32_t exp_statsn;
  114. int hdr_size; /* PDU header size */
  115. unsigned long suspend_rx; /* suspend Rx */
  116. struct crypto_tfm *rx_tfm; /* CRC32C (Rx) */
  117. struct crypto_tfm *data_rx_tfm; /* CRC32C (Rx) for data */
  118. /* control data */
  119. int senselen; /* scsi sense length */
  120. int id; /* CID */
  121. struct iscsi_tcp_recv in; /* TCP receive context */
  122. struct iscsi_session *session; /* parent session */
  123. struct list_head item; /* maintains list of conns */
  124. int in_progress; /* connection state machine */
  125. int c_stage; /* connection state */
  126. struct iscsi_mgmt_task *login_mtask; /* mtask used for login/text */
  127. struct iscsi_mgmt_task *mtask; /* xmit mtask in progress */
  128. struct iscsi_cmd_task *ctask; /* xmit ctask in progress */
  129. spinlock_t lock; /* FIXME: to be removed */
  130. /* old values for socket callbacks */
  131. void (*old_data_ready)(struct sock *, int);
  132. void (*old_state_change)(struct sock *);
  133. void (*old_write_space)(struct sock *);
  134. /* xmit */
  135. struct crypto_tfm *tx_tfm; /* CRC32C (Tx) */
  136. struct crypto_tfm *data_tx_tfm; /* CRC32C (Tx) for data */
  137. struct kfifo *writequeue; /* write cmds for Data-Outs */
  138. struct kfifo *immqueue; /* immediate xmit queue */
  139. struct kfifo *mgmtqueue; /* mgmt (control) xmit queue */
  140. struct kfifo *xmitqueue; /* data-path cmd queue */
  141. struct work_struct xmitwork; /* per-conn. xmit workqueue */
  142. struct semaphore xmitsema; /* serializes connection xmit,
  143. * access to kfifos: *
  144. * xmitqueue, writequeue, *
  145. * immqueue, mgmtqueue */
  146. unsigned long suspend_tx; /* suspend Tx */
  147. /* abort */
  148. wait_queue_head_t ehwait; /* used in eh_abort() */
  149. struct iscsi_tm tmhdr;
  150. struct timer_list tmabort_timer; /* abort timer */
  151. int tmabort_state; /* see TMABORT_INITIAL, etc.*/
  152. /* negotiated params */
  153. int max_recv_dlength;
  154. int max_xmit_dlength;
  155. int hdrdgst_en;
  156. int datadgst_en;
  157. /* MIB-statistics */
  158. uint64_t txdata_octets;
  159. uint64_t rxdata_octets;
  160. uint32_t scsicmd_pdus_cnt;
  161. uint32_t dataout_pdus_cnt;
  162. uint32_t scsirsp_pdus_cnt;
  163. uint32_t datain_pdus_cnt;
  164. uint32_t r2t_pdus_cnt;
  165. uint32_t tmfcmd_pdus_cnt;
  166. int32_t tmfrsp_pdus_cnt;
  167. /* custom statistics */
  168. uint32_t sendpage_failures_cnt;
  169. uint32_t discontiguous_hdr_cnt;
  170. uint32_t eh_abort_cnt;
  171. };
  172. struct iscsi_session {
  173. /* iSCSI session-wide sequencing */
  174. uint32_t cmdsn;
  175. uint32_t exp_cmdsn;
  176. uint32_t max_cmdsn;
  177. /* configuration */
  178. int initial_r2t_en;
  179. int max_r2t;
  180. int imm_data_en;
  181. int first_burst;
  182. int max_burst;
  183. int time2wait;
  184. int time2retain;
  185. int pdu_inorder_en;
  186. int dataseq_inorder_en;
  187. int erl;
  188. int ifmarker_en;
  189. int ofmarker_en;
  190. /* control data */
  191. struct Scsi_Host *host;
  192. int id;
  193. struct iscsi_conn *leadconn; /* leading connection */
  194. spinlock_t lock; /* protects session state, *
  195. * sequence numbers, *
  196. * session resources: *
  197. * - cmdpool, *
  198. * - mgmtpool, *
  199. * - r2tpool */
  200. int state; /* session state */
  201. struct list_head item;
  202. void *auth_client;
  203. int conn_cnt;
  204. int age; /* counts session re-opens */
  205. struct list_head connections; /* list of connections */
  206. int cmds_max; /* size of cmds array */
  207. struct iscsi_cmd_task **cmds; /* Original Cmds arr */
  208. struct iscsi_queue cmdpool; /* PDU's pool */
  209. int mgmtpool_max; /* size of mgmt array */
  210. struct iscsi_mgmt_task **mgmt_cmds; /* Original mgmt arr */
  211. struct iscsi_queue mgmtpool; /* Mgmt PDU's pool */
  212. };
  213. struct iscsi_buf {
  214. struct scatterlist sg;
  215. struct kvec iov;
  216. unsigned int sent;
  217. };
  218. struct iscsi_data_task {
  219. struct iscsi_data hdr; /* PDU */
  220. char hdrext[sizeof(__u32)]; /* Header-Digest */
  221. struct list_head item; /* data queue item */
  222. struct iscsi_buf digestbuf; /* digest buffer */
  223. uint32_t digest; /* data digest */
  224. };
  225. #define ISCSI_DTASK_DEFAULT_MAX ISCSI_SG_TABLESIZE * PAGE_SIZE / 512
  226. struct iscsi_mgmt_task {
  227. struct iscsi_hdr hdr; /* mgmt. PDU */
  228. char hdrext[sizeof(__u32)]; /* Header-Digest */
  229. char *data; /* mgmt payload */
  230. int xmstate; /* mgmt xmit progress */
  231. int data_count; /* counts data to be sent */
  232. struct iscsi_buf headbuf; /* header buffer */
  233. struct iscsi_buf sendbuf; /* in progress buffer */
  234. int sent;
  235. uint32_t itt; /* this ITT */
  236. };
  237. struct iscsi_r2t_info {
  238. __be32 ttt; /* copied from R2T */
  239. __be32 exp_statsn; /* copied from R2T */
  240. uint32_t data_length; /* copied from R2T */
  241. uint32_t data_offset; /* copied from R2T */
  242. struct iscsi_buf headbuf; /* Data-Out Header Buffer */
  243. struct iscsi_buf sendbuf; /* Data-Out in progress buffer*/
  244. int sent; /* R2T sequence progress */
  245. int data_count; /* DATA-Out payload progress */
  246. struct scatterlist *sg; /* per-R2T SG list */
  247. int solicit_datasn;
  248. struct iscsi_data_task *dtask; /* which data task */
  249. };
  250. struct iscsi_cmd_task {
  251. struct iscsi_cmd hdr; /* iSCSI PDU header */
  252. char hdrext[4*sizeof(__u16)+ /* AHS */
  253. sizeof(__u32)]; /* HeaderDigest */
  254. char pad[ISCSI_PAD_LEN];
  255. int itt; /* this ITT */
  256. int datasn; /* DataSN */
  257. struct iscsi_buf headbuf; /* header buf (xmit) */
  258. struct iscsi_buf sendbuf; /* in progress buffer*/
  259. int sent;
  260. struct scatterlist *sg; /* per-cmd SG list */
  261. struct scatterlist *bad_sg; /* assert statement */
  262. int sg_count; /* SG's to process */
  263. uint32_t unsol_datasn;
  264. uint32_t exp_r2tsn;
  265. int xmstate; /* xmit xtate machine */
  266. int imm_count; /* imm-data (bytes) */
  267. int unsol_count; /* unsolicited (bytes)*/
  268. int r2t_data_count; /* R2T Data-Out bytes */
  269. int data_count; /* remaining Data-Out */
  270. int pad_count; /* padded bytes */
  271. struct scsi_cmnd *sc; /* associated SCSI cmd*/
  272. int total_length;
  273. int data_offset;
  274. struct iscsi_conn *conn; /* used connection */
  275. struct iscsi_mgmt_task *mtask; /* tmf mtask in progr */
  276. struct iscsi_r2t_info *r2t; /* in progress R2T */
  277. struct iscsi_queue r2tpool;
  278. struct kfifo *r2tqueue;
  279. struct iscsi_r2t_info **r2ts;
  280. struct list_head dataqueue; /* Data-Out dataqueue */
  281. mempool_t *datapool;
  282. uint32_t datadigest; /* for recover digest */
  283. int digest_count;
  284. uint32_t immdigest; /* for imm data */
  285. struct iscsi_buf immbuf; /* for imm data digest */
  286. struct iscsi_data_task *dtask; /* data task in progress*/
  287. int digest_offset; /* for partial buff digest */
  288. };
  289. #endif /* ISCSI_H */