1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2012 The FreeBSD Foundation 5 * 6 * This software was developed by Edward Tomasz Napierala under sponsorship 7 * from the FreeBSD Foundation. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30 31 #ifndef ICL_H 32 #define ICL_H 33 34 /* 35 * iSCSI Common Layer. It's used by both the initiator and target to send 36 * and receive iSCSI PDUs. 37 */ 38 39 #include <sys/types.h> 40 #include <sys/kobj.h> 41 #include <sys/condvar.h> 42 #include <sys/sysctl.h> 43 44 SYSCTL_DECL(_kern_icl); 45 46 extern int icl_debug; 47 48 #define ICL_DEBUG(X, ...) \ 49 do { \ 50 if (icl_debug > 1) \ 51 printf("%s: " X "\n", __func__, ## __VA_ARGS__);\ 52 } while (0) 53 54 #define ICL_WARN(X, ...) \ 55 do { \ 56 if (icl_debug > 0) { \ 57 printf("WARNING: %s: " X "\n", \ 58 __func__, ## __VA_ARGS__); \ 59 } \ 60 } while (0) 61 62 struct icl_conn; 63 struct ccb_scsiio; 64 union ctl_io; 65 66 struct icl_pdu { 67 STAILQ_ENTRY(icl_pdu) ip_next; 68 struct icl_conn *ip_conn; 69 struct iscsi_bhs *ip_bhs; 70 struct mbuf *ip_bhs_mbuf; 71 size_t ip_ahs_len; 72 struct mbuf *ip_ahs_mbuf; 73 size_t ip_data_len; 74 struct mbuf *ip_data_mbuf; 75 76 /* 77 * When a "large" received PDU represents multiple on-the-wire 78 * PDUs, this is the count of additional on-the-wire PDUs. 79 * For PDUs that match on-the-wire PDUs, this should be set to 80 * zero. 81 */ 82 u_int ip_additional_pdus; 83 84 /* 85 * User (initiator or provider) private fields. 86 */ 87 void *ip_prv0; 88 void *ip_prv1; 89 }; 90 91 #define ICL_NOCOPY (1 << 30) 92 93 struct icl_conn { 94 KOBJ_FIELDS; 95 struct mtx *ic_lock; 96 struct socket *ic_socket; 97 #ifdef DIAGNOSTIC 98 volatile u_int ic_outstanding_pdus; 99 #endif 100 uint32_t ic_max_recv_data_segment_length; 101 uint32_t ic_max_send_data_segment_length; 102 size_t ic_hw_isomax; 103 size_t ic_maxtags; 104 bool ic_header_crc32c; 105 bool ic_data_crc32c; 106 bool ic_disconnecting; 107 bool ic_iser; 108 bool ic_unmapped; 109 const char *ic_name; 110 const char *ic_offload; 111 112 void (*ic_receive)(struct icl_pdu *); 113 void (*ic_error)(struct icl_conn *); 114 115 /* 116 * User (initiator or provider) private fields. 117 */ 118 void *ic_prv0; 119 }; 120 121 #define ICL_CONN_LOCK(X) mtx_lock(X->ic_lock) 122 #define ICL_CONN_UNLOCK(X) mtx_unlock(X->ic_lock) 123 #define ICL_CONN_LOCK_ASSERT(X) mtx_assert(X->ic_lock, MA_OWNED) 124 #define ICL_CONN_LOCK_ASSERT_NOT(X) mtx_assert(X->ic_lock, MA_NOTOWNED) 125 126 struct icl_drv_limits { 127 int idl_max_recv_data_segment_length; 128 int idl_max_send_data_segment_length; 129 int idl_max_burst_length; 130 int idl_first_burst_length; 131 int spare[4]; 132 }; 133 134 typedef void (*icl_pdu_cb)(struct icl_pdu *, int error); 135 136 struct icl_conn *icl_new_conn(const char *offload, bool iser, const char *name, 137 struct mtx *lock); 138 int icl_limits(const char *offload, bool iser, int socket, 139 struct icl_drv_limits *idl); 140 int icl_register(const char *offload, bool iser, int priority, 141 int (*limits)(struct icl_drv_limits *, int), 142 struct icl_conn *(*new_conn)(const char *, struct mtx *)); 143 int icl_unregister(const char *offload, bool rdma); 144 145 #ifdef ICL_KERNEL_PROXY 146 147 struct sockaddr; 148 struct icl_listen; 149 150 /* 151 * Target part. 152 */ 153 struct icl_listen *icl_listen_new(void (*accept_cb)(struct socket *, 154 struct sockaddr *, int)); 155 void icl_listen_free(struct icl_listen *il); 156 int icl_listen_add(struct icl_listen *il, bool rdma, 157 int domain, int socktype, int protocol, 158 struct sockaddr *sa, int portal_id); 159 int icl_listen_remove(struct icl_listen *il, struct sockaddr *sa); 160 161 /* 162 * Those two are not a public API; only to be used between icl_soft.c 163 * and icl_soft_proxy.c. 164 */ 165 int icl_soft_handoff_sock(struct icl_conn *ic, struct socket *so); 166 int icl_soft_proxy_connect(struct icl_conn *ic, int domain, 167 int socktype, int protocol, struct sockaddr *from_sa, 168 struct sockaddr *to_sa); 169 #endif /* ICL_KERNEL_PROXY */ 170 #endif /* !ICL_H */ 171