1a081c13eSMike Christie /* 2a081c13eSMike Christie * iSCSI over TCP/IP Data-Path lib 3a081c13eSMike Christie * 4a081c13eSMike Christie * Copyright (C) 2008 Mike Christie 5a081c13eSMike Christie * Copyright (C) 2008 Red Hat, Inc. All rights reserved. 6a081c13eSMike Christie * maintained by open-iscsi@googlegroups.com 7a081c13eSMike Christie * 8a081c13eSMike Christie * This program is free software; you can redistribute it and/or modify 9a081c13eSMike Christie * it under the terms of the GNU General Public License as published 10a081c13eSMike Christie * by the Free Software Foundation; either version 2 of the License, or 11a081c13eSMike Christie * (at your option) any later version. 12a081c13eSMike Christie * 13a081c13eSMike Christie * This program is distributed in the hope that it will be useful, but 14a081c13eSMike Christie * WITHOUT ANY WARRANTY; without even the implied warranty of 15a081c13eSMike Christie * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16a081c13eSMike Christie * General Public License for more details. 17a081c13eSMike Christie * 18a081c13eSMike Christie * See the file COPYING included with this distribution for more details. 19a081c13eSMike Christie */ 20a081c13eSMike Christie 21a081c13eSMike Christie #ifndef LIBISCSI_TCP_H 22a081c13eSMike Christie #define LIBISCSI_TCP_H 23a081c13eSMike Christie 24a081c13eSMike Christie #include <scsi/libiscsi.h> 25a081c13eSMike Christie 26a081c13eSMike Christie struct iscsi_tcp_conn; 27a081c13eSMike Christie struct iscsi_segment; 28a081c13eSMike Christie struct sk_buff; 29a081c13eSMike Christie struct hash_desc; 30a081c13eSMike Christie 31a081c13eSMike Christie typedef int iscsi_segment_done_fn_t(struct iscsi_tcp_conn *, 32a081c13eSMike Christie struct iscsi_segment *); 33a081c13eSMike Christie 34a081c13eSMike Christie struct iscsi_segment { 35a081c13eSMike Christie unsigned char *data; 36a081c13eSMike Christie unsigned int size; 37a081c13eSMike Christie unsigned int copied; 38a081c13eSMike Christie unsigned int total_size; 39a081c13eSMike Christie unsigned int total_copied; 40a081c13eSMike Christie 41a081c13eSMike Christie struct hash_desc *hash; 422856830bSKaren Xie unsigned char padbuf[ISCSI_PAD_LEN]; 43a081c13eSMike Christie unsigned char recv_digest[ISCSI_DIGEST_SIZE]; 44a081c13eSMike Christie unsigned char digest[ISCSI_DIGEST_SIZE]; 45a081c13eSMike Christie unsigned int digest_len; 46a081c13eSMike Christie 47a081c13eSMike Christie struct scatterlist *sg; 48a081c13eSMike Christie void *sg_mapped; 49a081c13eSMike Christie unsigned int sg_offset; 5070c7c88aSMike Christie bool atomic_mapped; 51a081c13eSMike Christie 52a081c13eSMike Christie iscsi_segment_done_fn_t *done; 53a081c13eSMike Christie }; 54a081c13eSMike Christie 55a081c13eSMike Christie /* Socket connection recieve helper */ 56a081c13eSMike Christie struct iscsi_tcp_recv { 57a081c13eSMike Christie struct iscsi_hdr *hdr; 58a081c13eSMike Christie struct iscsi_segment segment; 59a081c13eSMike Christie 60a081c13eSMike Christie /* Allocate buffer for BHS + AHS */ 61a081c13eSMike Christie uint32_t hdr_buf[64]; 62a081c13eSMike Christie 63a081c13eSMike Christie /* copied and flipped values */ 64a081c13eSMike Christie int datalen; 65a081c13eSMike Christie }; 66a081c13eSMike Christie 67a081c13eSMike Christie struct iscsi_tcp_conn { 68a081c13eSMike Christie struct iscsi_conn *iscsi_conn; 69a081c13eSMike Christie void *dd_data; 70a081c13eSMike Christie int stop_stage; /* conn_stop() flag: * 71a081c13eSMike Christie * stop to recover, * 72a081c13eSMike Christie * stop to terminate */ 73a081c13eSMike Christie /* control data */ 74a081c13eSMike Christie struct iscsi_tcp_recv in; /* TCP receive context */ 75a081c13eSMike Christie /* CRC32C (Rx) LLD should set this is they do not offload */ 76a081c13eSMike Christie struct hash_desc *rx_hash; 77a081c13eSMike Christie }; 78a081c13eSMike Christie 79a081c13eSMike Christie struct iscsi_tcp_task { 80a081c13eSMike Christie uint32_t exp_datasn; /* expected target's R2TSN/DataSN */ 81a081c13eSMike Christie int data_offset; 82a081c13eSMike Christie struct iscsi_r2t_info *r2t; /* in progress solict R2T */ 83a081c13eSMike Christie struct iscsi_pool r2tpool; 8445465487SStefani Seibold struct kfifo r2tqueue; 85a081c13eSMike Christie void *dd_data; 86a081c13eSMike Christie }; 87a081c13eSMike Christie 88a081c13eSMike Christie enum { 89a081c13eSMike Christie ISCSI_TCP_SEGMENT_DONE, /* curr seg has been processed */ 90a081c13eSMike Christie ISCSI_TCP_SKB_DONE, /* skb is out of data */ 91a081c13eSMike Christie ISCSI_TCP_CONN_ERR, /* iscsi layer has fired a conn err */ 92a081c13eSMike Christie ISCSI_TCP_SUSPENDED, /* conn is suspended */ 93a081c13eSMike Christie }; 94a081c13eSMike Christie 95a081c13eSMike Christie extern void iscsi_tcp_hdr_recv_prep(struct iscsi_tcp_conn *tcp_conn); 96a081c13eSMike Christie extern int iscsi_tcp_recv_skb(struct iscsi_conn *conn, struct sk_buff *skb, 97a081c13eSMike Christie unsigned int offset, bool offloaded, int *status); 98a081c13eSMike Christie extern void iscsi_tcp_cleanup_task(struct iscsi_task *task); 99a081c13eSMike Christie extern int iscsi_tcp_task_init(struct iscsi_task *task); 100a081c13eSMike Christie extern int iscsi_tcp_task_xmit(struct iscsi_task *task); 101a081c13eSMike Christie 102a081c13eSMike Christie /* segment helpers */ 103a081c13eSMike Christie extern int iscsi_tcp_recv_segment_is_hdr(struct iscsi_tcp_conn *tcp_conn); 1046df19a79SMike Christie extern int iscsi_tcp_segment_done(struct iscsi_tcp_conn *tcp_conn, 1056df19a79SMike Christie struct iscsi_segment *segment, int recv, 106a081c13eSMike Christie unsigned copied); 107a081c13eSMike Christie extern void iscsi_tcp_segment_unmap(struct iscsi_segment *segment); 108a081c13eSMike Christie 109a081c13eSMike Christie extern void iscsi_segment_init_linear(struct iscsi_segment *segment, 110a081c13eSMike Christie void *data, size_t size, 111a081c13eSMike Christie iscsi_segment_done_fn_t *done, 112a081c13eSMike Christie struct hash_desc *hash); 113a081c13eSMike Christie extern int 114a081c13eSMike Christie iscsi_segment_seek_sg(struct iscsi_segment *segment, 115a081c13eSMike Christie struct scatterlist *sg_list, unsigned int sg_count, 116a081c13eSMike Christie unsigned int offset, size_t size, 117a081c13eSMike Christie iscsi_segment_done_fn_t *done, struct hash_desc *hash); 118a081c13eSMike Christie 119a081c13eSMike Christie /* digest helpers */ 120a081c13eSMike Christie extern void iscsi_tcp_dgst_header(struct hash_desc *hash, const void *hdr, 121a081c13eSMike Christie size_t hdrlen, 122a081c13eSMike Christie unsigned char digest[ISCSI_DIGEST_SIZE]); 123a081c13eSMike Christie extern struct iscsi_cls_conn * 124a081c13eSMike Christie iscsi_tcp_conn_setup(struct iscsi_cls_session *cls_session, int dd_data_size, 125a081c13eSMike Christie uint32_t conn_idx); 126a081c13eSMike Christie extern void iscsi_tcp_conn_teardown(struct iscsi_cls_conn *cls_conn); 127a081c13eSMike Christie 128a081c13eSMike Christie /* misc helpers */ 129a081c13eSMike Christie extern int iscsi_tcp_r2tpool_alloc(struct iscsi_session *session); 130a081c13eSMike Christie extern void iscsi_tcp_r2tpool_free(struct iscsi_session *session); 131a081c13eSMike Christie 132a081c13eSMike Christie extern void iscsi_tcp_conn_get_stats(struct iscsi_cls_conn *cls_conn, 133a081c13eSMike Christie struct iscsi_stats *stats); 134a081c13eSMike Christie #endif /* LIBISCSI_TCP_H */ 135