1*7978SPeter.Dunlap@Sun.COM /* 2*7978SPeter.Dunlap@Sun.COM * CDDL HEADER START 3*7978SPeter.Dunlap@Sun.COM * 4*7978SPeter.Dunlap@Sun.COM * The contents of this file are subject to the terms of the 5*7978SPeter.Dunlap@Sun.COM * Common Development and Distribution License (the "License"). 6*7978SPeter.Dunlap@Sun.COM * You may not use this file except in compliance with the License. 7*7978SPeter.Dunlap@Sun.COM * 8*7978SPeter.Dunlap@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*7978SPeter.Dunlap@Sun.COM * or http://www.opensolaris.org/os/licensing. 10*7978SPeter.Dunlap@Sun.COM * See the License for the specific language governing permissions 11*7978SPeter.Dunlap@Sun.COM * and limitations under the License. 12*7978SPeter.Dunlap@Sun.COM * 13*7978SPeter.Dunlap@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 14*7978SPeter.Dunlap@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*7978SPeter.Dunlap@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 16*7978SPeter.Dunlap@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 17*7978SPeter.Dunlap@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 18*7978SPeter.Dunlap@Sun.COM * 19*7978SPeter.Dunlap@Sun.COM * CDDL HEADER END 20*7978SPeter.Dunlap@Sun.COM */ 21*7978SPeter.Dunlap@Sun.COM /* 22*7978SPeter.Dunlap@Sun.COM * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23*7978SPeter.Dunlap@Sun.COM * Use is subject to license terms. 24*7978SPeter.Dunlap@Sun.COM */ 25*7978SPeter.Dunlap@Sun.COM #ifndef _IDM_IMPL_H_ 26*7978SPeter.Dunlap@Sun.COM #define _IDM_IMPL_H_ 27*7978SPeter.Dunlap@Sun.COM 28*7978SPeter.Dunlap@Sun.COM #ifdef __cplusplus 29*7978SPeter.Dunlap@Sun.COM extern "C" { 30*7978SPeter.Dunlap@Sun.COM #endif 31*7978SPeter.Dunlap@Sun.COM 32*7978SPeter.Dunlap@Sun.COM #include <sys/avl.h> 33*7978SPeter.Dunlap@Sun.COM #include <sys/socket_impl.h> 34*7978SPeter.Dunlap@Sun.COM 35*7978SPeter.Dunlap@Sun.COM /* 36*7978SPeter.Dunlap@Sun.COM * IDM lock order: 37*7978SPeter.Dunlap@Sun.COM * 38*7978SPeter.Dunlap@Sun.COM * idm_taskid_table_lock, idm_task_t.idt_mutex 39*7978SPeter.Dunlap@Sun.COM */ 40*7978SPeter.Dunlap@Sun.COM 41*7978SPeter.Dunlap@Sun.COM #define CF_LOGIN_READY 0x00000001 42*7978SPeter.Dunlap@Sun.COM #define CF_INITIAL_LOGIN 0x00000002 43*7978SPeter.Dunlap@Sun.COM #define CF_ERROR 0x80000000 44*7978SPeter.Dunlap@Sun.COM 45*7978SPeter.Dunlap@Sun.COM typedef enum { 46*7978SPeter.Dunlap@Sun.COM CONN_TYPE_INI = 1, 47*7978SPeter.Dunlap@Sun.COM CONN_TYPE_TGT 48*7978SPeter.Dunlap@Sun.COM } idm_conn_type_t; 49*7978SPeter.Dunlap@Sun.COM 50*7978SPeter.Dunlap@Sun.COM /* 51*7978SPeter.Dunlap@Sun.COM * Watchdog interval in seconds 52*7978SPeter.Dunlap@Sun.COM */ 53*7978SPeter.Dunlap@Sun.COM #define IDM_WD_INTERVAL 5 54*7978SPeter.Dunlap@Sun.COM 55*7978SPeter.Dunlap@Sun.COM /* 56*7978SPeter.Dunlap@Sun.COM * Timeout period before a TRANSPORT_FAIL event is generated in seconds 57*7978SPeter.Dunlap@Sun.COM * if the connection is idle. 58*7978SPeter.Dunlap@Sun.COM */ 59*7978SPeter.Dunlap@Sun.COM #define IDM_TRANSPORT_FAIL_IDLE_TIMEOUT 30 60*7978SPeter.Dunlap@Sun.COM 61*7978SPeter.Dunlap@Sun.COM /* 62*7978SPeter.Dunlap@Sun.COM * IDM reference count structure. Audit code is shamelessly adapted 63*7978SPeter.Dunlap@Sun.COM * from CIFS server. 64*7978SPeter.Dunlap@Sun.COM */ 65*7978SPeter.Dunlap@Sun.COM 66*7978SPeter.Dunlap@Sun.COM #define REFCNT_AUDIT_STACK_DEPTH 16 67*7978SPeter.Dunlap@Sun.COM #define REFCNT_AUDIT_BUF_MAX_REC 16 68*7978SPeter.Dunlap@Sun.COM 69*7978SPeter.Dunlap@Sun.COM typedef struct { 70*7978SPeter.Dunlap@Sun.COM uint32_t anr_refcnt; 71*7978SPeter.Dunlap@Sun.COM int anr_depth; 72*7978SPeter.Dunlap@Sun.COM pc_t anr_stack[REFCNT_AUDIT_STACK_DEPTH]; 73*7978SPeter.Dunlap@Sun.COM } refcnt_audit_record_t; 74*7978SPeter.Dunlap@Sun.COM 75*7978SPeter.Dunlap@Sun.COM typedef struct { 76*7978SPeter.Dunlap@Sun.COM int anb_index; 77*7978SPeter.Dunlap@Sun.COM int anb_max_index; 78*7978SPeter.Dunlap@Sun.COM refcnt_audit_record_t anb_records[REFCNT_AUDIT_BUF_MAX_REC]; 79*7978SPeter.Dunlap@Sun.COM } refcnt_audit_buf_t; 80*7978SPeter.Dunlap@Sun.COM 81*7978SPeter.Dunlap@Sun.COM #define REFCNT_AUDIT(_rf_) { \ 82*7978SPeter.Dunlap@Sun.COM refcnt_audit_record_t *anr; \ 83*7978SPeter.Dunlap@Sun.COM \ 84*7978SPeter.Dunlap@Sun.COM anr = (_rf_)->ir_audit_buf.anb_records; \ 85*7978SPeter.Dunlap@Sun.COM anr += (_rf_)->ir_audit_buf.anb_index; \ 86*7978SPeter.Dunlap@Sun.COM (_rf_)->ir_audit_buf.anb_index++; \ 87*7978SPeter.Dunlap@Sun.COM (_rf_)->ir_audit_buf.anb_index &= \ 88*7978SPeter.Dunlap@Sun.COM (_rf_)->ir_audit_buf.anb_max_index; \ 89*7978SPeter.Dunlap@Sun.COM anr->anr_refcnt = (_rf_)->ir_refcnt; \ 90*7978SPeter.Dunlap@Sun.COM anr->anr_depth = getpcstack(anr->anr_stack, \ 91*7978SPeter.Dunlap@Sun.COM REFCNT_AUDIT_STACK_DEPTH); \ 92*7978SPeter.Dunlap@Sun.COM } 93*7978SPeter.Dunlap@Sun.COM 94*7978SPeter.Dunlap@Sun.COM struct idm_refcnt_s; 95*7978SPeter.Dunlap@Sun.COM 96*7978SPeter.Dunlap@Sun.COM typedef void (idm_refcnt_cb_t)(void *ref_obj); 97*7978SPeter.Dunlap@Sun.COM 98*7978SPeter.Dunlap@Sun.COM typedef enum { 99*7978SPeter.Dunlap@Sun.COM REF_NOWAIT, 100*7978SPeter.Dunlap@Sun.COM REF_WAIT_SYNC, 101*7978SPeter.Dunlap@Sun.COM REF_WAIT_ASYNC 102*7978SPeter.Dunlap@Sun.COM } idm_refcnt_wait_t; 103*7978SPeter.Dunlap@Sun.COM 104*7978SPeter.Dunlap@Sun.COM typedef struct idm_refcnt_s { 105*7978SPeter.Dunlap@Sun.COM int ir_refcnt; 106*7978SPeter.Dunlap@Sun.COM void *ir_referenced_obj; 107*7978SPeter.Dunlap@Sun.COM idm_refcnt_wait_t ir_waiting; 108*7978SPeter.Dunlap@Sun.COM kmutex_t ir_mutex; 109*7978SPeter.Dunlap@Sun.COM kcondvar_t ir_cv; 110*7978SPeter.Dunlap@Sun.COM idm_refcnt_cb_t *ir_cb; 111*7978SPeter.Dunlap@Sun.COM refcnt_audit_buf_t ir_audit_buf; 112*7978SPeter.Dunlap@Sun.COM } idm_refcnt_t; 113*7978SPeter.Dunlap@Sun.COM 114*7978SPeter.Dunlap@Sun.COM /* 115*7978SPeter.Dunlap@Sun.COM * connection parameters - These parameters would be populated at 116*7978SPeter.Dunlap@Sun.COM * connection create, or during key-value negotiation at login 117*7978SPeter.Dunlap@Sun.COM */ 118*7978SPeter.Dunlap@Sun.COM typedef struct idm_conn_params_s { 119*7978SPeter.Dunlap@Sun.COM uint32_t max_dataseglen; 120*7978SPeter.Dunlap@Sun.COM } idm_conn_param_t; 121*7978SPeter.Dunlap@Sun.COM 122*7978SPeter.Dunlap@Sun.COM typedef struct idm_svc_s { 123*7978SPeter.Dunlap@Sun.COM list_node_t is_list_node; 124*7978SPeter.Dunlap@Sun.COM kmutex_t is_mutex; 125*7978SPeter.Dunlap@Sun.COM kcondvar_t is_cv; 126*7978SPeter.Dunlap@Sun.COM kmutex_t is_count_mutex; 127*7978SPeter.Dunlap@Sun.COM kcondvar_t is_count_cv; 128*7978SPeter.Dunlap@Sun.COM idm_refcnt_t is_refcnt; 129*7978SPeter.Dunlap@Sun.COM int is_online; 130*7978SPeter.Dunlap@Sun.COM /* transport-specific service components */ 131*7978SPeter.Dunlap@Sun.COM void *is_so_svc; 132*7978SPeter.Dunlap@Sun.COM void *is_iser_svc; 133*7978SPeter.Dunlap@Sun.COM idm_svc_req_t is_svc_req; 134*7978SPeter.Dunlap@Sun.COM } idm_svc_t; 135*7978SPeter.Dunlap@Sun.COM 136*7978SPeter.Dunlap@Sun.COM typedef struct idm_conn_s { 137*7978SPeter.Dunlap@Sun.COM list_node_t ic_list_node; 138*7978SPeter.Dunlap@Sun.COM void *ic_handle; 139*7978SPeter.Dunlap@Sun.COM idm_refcnt_t ic_refcnt; 140*7978SPeter.Dunlap@Sun.COM idm_svc_t *ic_svc_binding; /* Target conn. only */ 141*7978SPeter.Dunlap@Sun.COM idm_sockaddr_t ic_ini_dst_addr; 142*7978SPeter.Dunlap@Sun.COM struct sockaddr_storage ic_laddr; /* conn local address */ 143*7978SPeter.Dunlap@Sun.COM struct sockaddr_storage ic_raddr; /* conn remote address */ 144*7978SPeter.Dunlap@Sun.COM idm_conn_state_t ic_state; 145*7978SPeter.Dunlap@Sun.COM idm_conn_state_t ic_last_state; 146*7978SPeter.Dunlap@Sun.COM sm_audit_buf_t ic_state_audit; 147*7978SPeter.Dunlap@Sun.COM kmutex_t ic_state_mutex; 148*7978SPeter.Dunlap@Sun.COM kcondvar_t ic_state_cv; 149*7978SPeter.Dunlap@Sun.COM uint32_t ic_state_flags; 150*7978SPeter.Dunlap@Sun.COM timeout_id_t ic_state_timeout; 151*7978SPeter.Dunlap@Sun.COM struct idm_conn_s *ic_reinstate_conn; /* For conn reinst. */ 152*7978SPeter.Dunlap@Sun.COM struct idm_conn_s *ic_logout_conn; /* For other conn logout */ 153*7978SPeter.Dunlap@Sun.COM taskq_t *ic_state_taskq; 154*7978SPeter.Dunlap@Sun.COM int ic_pdu_events; 155*7978SPeter.Dunlap@Sun.COM boolean_t ic_login_info_valid; 156*7978SPeter.Dunlap@Sun.COM boolean_t ic_rdma_extensions; 157*7978SPeter.Dunlap@Sun.COM uint16_t ic_login_cid; 158*7978SPeter.Dunlap@Sun.COM 159*7978SPeter.Dunlap@Sun.COM kmutex_t ic_mutex; 160*7978SPeter.Dunlap@Sun.COM kcondvar_t ic_cv; 161*7978SPeter.Dunlap@Sun.COM idm_status_t ic_conn_sm_status; 162*7978SPeter.Dunlap@Sun.COM 163*7978SPeter.Dunlap@Sun.COM boolean_t ic_ffp; 164*7978SPeter.Dunlap@Sun.COM uint32_t ic_internal_cid; 165*7978SPeter.Dunlap@Sun.COM 166*7978SPeter.Dunlap@Sun.COM uint32_t ic_conn_flags; 167*7978SPeter.Dunlap@Sun.COM idm_conn_type_t ic_conn_type; 168*7978SPeter.Dunlap@Sun.COM idm_conn_ops_t ic_conn_ops; 169*7978SPeter.Dunlap@Sun.COM idm_transport_ops_t *ic_transport_ops; 170*7978SPeter.Dunlap@Sun.COM idm_transport_type_t ic_transport_type; 171*7978SPeter.Dunlap@Sun.COM int ic_transport_hdrlen; 172*7978SPeter.Dunlap@Sun.COM void *ic_transport_private; 173*7978SPeter.Dunlap@Sun.COM idm_conn_param_t ic_conn_params; 174*7978SPeter.Dunlap@Sun.COM /* 175*7978SPeter.Dunlap@Sun.COM * Save client callback to interpose idm callback 176*7978SPeter.Dunlap@Sun.COM */ 177*7978SPeter.Dunlap@Sun.COM idm_pdu_cb_t *ic_client_callback; 178*7978SPeter.Dunlap@Sun.COM clock_t ic_timestamp; 179*7978SPeter.Dunlap@Sun.COM } idm_conn_t; 180*7978SPeter.Dunlap@Sun.COM 181*7978SPeter.Dunlap@Sun.COM #define IDM_CONN_HEADER_DIGEST 0x00000001 182*7978SPeter.Dunlap@Sun.COM #define IDM_CONN_DATA_DIGEST 0x00000002 183*7978SPeter.Dunlap@Sun.COM #define IDM_CONN_USE_SCOREBOARD 0x00000004 184*7978SPeter.Dunlap@Sun.COM 185*7978SPeter.Dunlap@Sun.COM #define IDM_CONN_ISINI(ICI_IC) ((ICI_IC)->ic_conn_type == CONN_TYPE_INI) 186*7978SPeter.Dunlap@Sun.COM #define IDM_CONN_ISTGT(ICI_IC) ((ICI_IC)->ic_conn_type == CONN_TYPE_TGT) 187*7978SPeter.Dunlap@Sun.COM 188*7978SPeter.Dunlap@Sun.COM /* 189*7978SPeter.Dunlap@Sun.COM * An IDM target task can transfer data using multiple buffers. The task 190*7978SPeter.Dunlap@Sun.COM * will maintain a list of buffers, and each buffer will contain the relative 191*7978SPeter.Dunlap@Sun.COM * offset of the transfer and a pointer to the next buffer in the list. 192*7978SPeter.Dunlap@Sun.COM * 193*7978SPeter.Dunlap@Sun.COM * Note on client private data: 194*7978SPeter.Dunlap@Sun.COM * idt_private is intended to be a pointer to some sort of client- 195*7978SPeter.Dunlap@Sun.COM * specific state. 196*7978SPeter.Dunlap@Sun.COM * 197*7978SPeter.Dunlap@Sun.COM * idt_client_handle is a more generic client-private piece of data that can 198*7978SPeter.Dunlap@Sun.COM * be used by the client for the express purpose of task lookup. The driving 199*7978SPeter.Dunlap@Sun.COM * use case for this is for the client to store the initiator task tag for 200*7978SPeter.Dunlap@Sun.COM * a given task so that it may be more easily retrieved for task management. 201*7978SPeter.Dunlap@Sun.COM * 202*7978SPeter.Dunlap@Sun.COM * The key take away here is that clients should never call 203*7978SPeter.Dunlap@Sun.COM * idm_task_find_by_handle in the performance path. 204*7978SPeter.Dunlap@Sun.COM * 205*7978SPeter.Dunlap@Sun.COM * An initiator will require only one buffer per task, the offset will be 0. 206*7978SPeter.Dunlap@Sun.COM */ 207*7978SPeter.Dunlap@Sun.COM 208*7978SPeter.Dunlap@Sun.COM typedef struct idm_task_s { 209*7978SPeter.Dunlap@Sun.COM idm_conn_t *idt_ic; /* Associated connection */ 210*7978SPeter.Dunlap@Sun.COM /* connection type is in idt_ic->ic_conn_type */ 211*7978SPeter.Dunlap@Sun.COM kmutex_t idt_mutex; 212*7978SPeter.Dunlap@Sun.COM void *idt_private; /* Client private data */ 213*7978SPeter.Dunlap@Sun.COM uintptr_t idt_client_handle; /* Client private */ 214*7978SPeter.Dunlap@Sun.COM uint32_t idt_tt; /* Task tag */ 215*7978SPeter.Dunlap@Sun.COM uint32_t idt_r2t_ttt; /* R2T Target Task tag */ 216*7978SPeter.Dunlap@Sun.COM idm_task_state_t idt_state; 217*7978SPeter.Dunlap@Sun.COM idm_refcnt_t idt_refcnt; 218*7978SPeter.Dunlap@Sun.COM 219*7978SPeter.Dunlap@Sun.COM /* 220*7978SPeter.Dunlap@Sun.COM * Statistics 221*7978SPeter.Dunlap@Sun.COM */ 222*7978SPeter.Dunlap@Sun.COM int idt_tx_to_ini_start; 223*7978SPeter.Dunlap@Sun.COM int idt_tx_to_ini_done; 224*7978SPeter.Dunlap@Sun.COM int idt_rx_from_ini_start; 225*7978SPeter.Dunlap@Sun.COM int idt_rx_from_ini_done; 226*7978SPeter.Dunlap@Sun.COM 227*7978SPeter.Dunlap@Sun.COM uint32_t idt_exp_datasn; /* expected datasn */ 228*7978SPeter.Dunlap@Sun.COM uint32_t idt_exp_rttsn; /* expected rttsn */ 229*7978SPeter.Dunlap@Sun.COM list_t idt_inbufv; /* chunks of IN buffers */ 230*7978SPeter.Dunlap@Sun.COM list_t idt_outbufv; /* chunks of OUT buffers */ 231*7978SPeter.Dunlap@Sun.COM 232*7978SPeter.Dunlap@Sun.COM /* 233*7978SPeter.Dunlap@Sun.COM * Transport header, which describes this tasks remote tagged buffer 234*7978SPeter.Dunlap@Sun.COM */ 235*7978SPeter.Dunlap@Sun.COM int idt_transport_hdrlen; 236*7978SPeter.Dunlap@Sun.COM void *idt_transport_hdr; 237*7978SPeter.Dunlap@Sun.COM } idm_task_t; 238*7978SPeter.Dunlap@Sun.COM 239*7978SPeter.Dunlap@Sun.COM int idm_task_constructor(void *task_void, void *arg, int flags); 240*7978SPeter.Dunlap@Sun.COM void idm_task_destructor(void *task_void, void *arg); 241*7978SPeter.Dunlap@Sun.COM 242*7978SPeter.Dunlap@Sun.COM #define IDM_TASKIDS_MAX 16384 243*7978SPeter.Dunlap@Sun.COM #define IDM_BUF_MAGIC 0x49425546 /* "IBUF" */ 244*7978SPeter.Dunlap@Sun.COM 245*7978SPeter.Dunlap@Sun.COM /* Protect with task mutex */ 246*7978SPeter.Dunlap@Sun.COM typedef struct idm_buf_s { 247*7978SPeter.Dunlap@Sun.COM uint32_t idb_magic; /* "IBUF" */ 248*7978SPeter.Dunlap@Sun.COM 249*7978SPeter.Dunlap@Sun.COM /* 250*7978SPeter.Dunlap@Sun.COM * Note: idm_tx_link *must* be the second element in the list for 251*7978SPeter.Dunlap@Sun.COM * proper TX PDU ordering. 252*7978SPeter.Dunlap@Sun.COM */ 253*7978SPeter.Dunlap@Sun.COM list_node_t idm_tx_link; /* link in a list of TX objects */ 254*7978SPeter.Dunlap@Sun.COM 255*7978SPeter.Dunlap@Sun.COM list_node_t idb_buflink; /* link in a multi-buffer data xfer */ 256*7978SPeter.Dunlap@Sun.COM idm_conn_t *idb_ic; /* Associated connection */ 257*7978SPeter.Dunlap@Sun.COM void *idb_buf; /* data */ 258*7978SPeter.Dunlap@Sun.COM uint64_t idb_buflen; /* length of buffer */ 259*7978SPeter.Dunlap@Sun.COM size_t idb_bufoffset; /* offset in a multi-buffer xfer */ 260*7978SPeter.Dunlap@Sun.COM boolean_t idb_bufalloc; /* true if alloc'd in idm_buf_alloc */ 261*7978SPeter.Dunlap@Sun.COM /* 262*7978SPeter.Dunlap@Sun.COM * DataPDUInOrder=Yes, so to track that the PDUs in a sequence are sent 263*7978SPeter.Dunlap@Sun.COM * in continuously increasing address order, check that offsets for a 264*7978SPeter.Dunlap@Sun.COM * single buffer xfer are in order. 265*7978SPeter.Dunlap@Sun.COM */ 266*7978SPeter.Dunlap@Sun.COM uint32_t idb_exp_offset; 267*7978SPeter.Dunlap@Sun.COM size_t idb_xfer_len; /* Current requested xfer len */ 268*7978SPeter.Dunlap@Sun.COM void *idb_buf_private; /* transport-specific buf handle */ 269*7978SPeter.Dunlap@Sun.COM void *idb_reg_private; /* transport-specific reg handle */ 270*7978SPeter.Dunlap@Sun.COM idm_buf_cb_t *idb_buf_cb; /* Data Completion Notify, tgt only */ 271*7978SPeter.Dunlap@Sun.COM void *idb_cb_arg; /* Client private data */ 272*7978SPeter.Dunlap@Sun.COM idm_task_t *idb_task_binding; 273*7978SPeter.Dunlap@Sun.COM boolean_t idb_in_transport; 274*7978SPeter.Dunlap@Sun.COM boolean_t idb_tx_thread; /* Sockets only */ 275*7978SPeter.Dunlap@Sun.COM iscsi_hdr_t idb_data_hdr_tmpl; /* Sockets only */ 276*7978SPeter.Dunlap@Sun.COM idm_status_t idb_status; 277*7978SPeter.Dunlap@Sun.COM } idm_buf_t; 278*7978SPeter.Dunlap@Sun.COM 279*7978SPeter.Dunlap@Sun.COM #define PDU_MAX_IOVLEN 12 280*7978SPeter.Dunlap@Sun.COM #define IDM_PDU_MAGIC 0x49504455 /* "IPDU" */ 281*7978SPeter.Dunlap@Sun.COM 282*7978SPeter.Dunlap@Sun.COM typedef struct idm_pdu_s { 283*7978SPeter.Dunlap@Sun.COM uint32_t isp_magic; /* "IPDU" */ 284*7978SPeter.Dunlap@Sun.COM 285*7978SPeter.Dunlap@Sun.COM /* 286*7978SPeter.Dunlap@Sun.COM * Internal - Order is vital. idm_tx_link *must* be the second 287*7978SPeter.Dunlap@Sun.COM * element in this structure for proper TX PDU ordering. 288*7978SPeter.Dunlap@Sun.COM */ 289*7978SPeter.Dunlap@Sun.COM list_node_t idm_tx_link; 290*7978SPeter.Dunlap@Sun.COM 291*7978SPeter.Dunlap@Sun.COM list_node_t isp_client_lnd; 292*7978SPeter.Dunlap@Sun.COM 293*7978SPeter.Dunlap@Sun.COM idm_conn_t *isp_ic; /* Must be set */ 294*7978SPeter.Dunlap@Sun.COM iscsi_hdr_t *isp_hdr; 295*7978SPeter.Dunlap@Sun.COM uint_t isp_hdrlen; 296*7978SPeter.Dunlap@Sun.COM uint8_t *isp_data; 297*7978SPeter.Dunlap@Sun.COM uint_t isp_datalen; 298*7978SPeter.Dunlap@Sun.COM 299*7978SPeter.Dunlap@Sun.COM /* Transport header */ 300*7978SPeter.Dunlap@Sun.COM void *isp_transport_hdr; 301*7978SPeter.Dunlap@Sun.COM uint32_t isp_transport_hdrlen; 302*7978SPeter.Dunlap@Sun.COM void *isp_transport_private; 303*7978SPeter.Dunlap@Sun.COM 304*7978SPeter.Dunlap@Sun.COM /* 305*7978SPeter.Dunlap@Sun.COM * isp_data is used for sending SCSI status, NOP, text, scsi and 306*7978SPeter.Dunlap@Sun.COM * non-scsi data. Data is received using isp_iov and isp_iovlen 307*7978SPeter.Dunlap@Sun.COM * to support data over multiple buffers. 308*7978SPeter.Dunlap@Sun.COM */ 309*7978SPeter.Dunlap@Sun.COM void *isp_private; 310*7978SPeter.Dunlap@Sun.COM idm_pdu_cb_t *isp_callback; 311*7978SPeter.Dunlap@Sun.COM idm_status_t isp_status; 312*7978SPeter.Dunlap@Sun.COM 313*7978SPeter.Dunlap@Sun.COM /* 314*7978SPeter.Dunlap@Sun.COM * The following four elements are only used in 315*7978SPeter.Dunlap@Sun.COM * idm_sorecv_scsidata() currently. 316*7978SPeter.Dunlap@Sun.COM */ 317*7978SPeter.Dunlap@Sun.COM struct iovec isp_iov[PDU_MAX_IOVLEN]; 318*7978SPeter.Dunlap@Sun.COM int isp_iovlen; 319*7978SPeter.Dunlap@Sun.COM idm_buf_t *isp_sorx_buf; 320*7978SPeter.Dunlap@Sun.COM 321*7978SPeter.Dunlap@Sun.COM /* Implementation data for idm_pdu_alloc and sorx PDU cache */ 322*7978SPeter.Dunlap@Sun.COM uint32_t isp_flags; 323*7978SPeter.Dunlap@Sun.COM uint_t isp_hdrbuflen; 324*7978SPeter.Dunlap@Sun.COM uint_t isp_databuflen; 325*7978SPeter.Dunlap@Sun.COM } idm_pdu_t; 326*7978SPeter.Dunlap@Sun.COM 327*7978SPeter.Dunlap@Sun.COM /* 328*7978SPeter.Dunlap@Sun.COM * This "generic" object is used when removing an item from the ic_tx_list 329*7978SPeter.Dunlap@Sun.COM * in order to determine whether it's an idm_pdu_t or an idm_buf_t 330*7978SPeter.Dunlap@Sun.COM */ 331*7978SPeter.Dunlap@Sun.COM 332*7978SPeter.Dunlap@Sun.COM typedef struct { 333*7978SPeter.Dunlap@Sun.COM uint32_t idm_tx_obj_magic; 334*7978SPeter.Dunlap@Sun.COM /* 335*7978SPeter.Dunlap@Sun.COM * idm_tx_link *must* be the second element in this structure. 336*7978SPeter.Dunlap@Sun.COM */ 337*7978SPeter.Dunlap@Sun.COM list_node_t idm_tx_link; 338*7978SPeter.Dunlap@Sun.COM } idm_tx_obj_t; 339*7978SPeter.Dunlap@Sun.COM 340*7978SPeter.Dunlap@Sun.COM 341*7978SPeter.Dunlap@Sun.COM #define IDM_PDU_OPCODE(PDU) \ 342*7978SPeter.Dunlap@Sun.COM ((PDU)->isp_hdr->opcode & ISCSI_OPCODE_MASK) 343*7978SPeter.Dunlap@Sun.COM 344*7978SPeter.Dunlap@Sun.COM #define IDM_PDU_ALLOC 0x00000001 345*7978SPeter.Dunlap@Sun.COM #define IDM_PDU_ADDL_HDR 0x00000002 346*7978SPeter.Dunlap@Sun.COM #define IDM_PDU_ADDL_DATA 0x00000004 347*7978SPeter.Dunlap@Sun.COM #define IDM_PDU_LOGIN_TX 0x00000008 348*7978SPeter.Dunlap@Sun.COM 349*7978SPeter.Dunlap@Sun.COM #define OSD_EXT_CDB_AHSLEN (200 - 15) 350*7978SPeter.Dunlap@Sun.COM #define BIDI_AHS_LENGTH 5 351*7978SPeter.Dunlap@Sun.COM #define IDM_SORX_CACHE_AHSLEN \ 352*7978SPeter.Dunlap@Sun.COM (((OSD_EXT_CDB_AHSLEN + 3) + \ 353*7978SPeter.Dunlap@Sun.COM (BIDI_AHS_LENGTH + 3)) / sizeof (uint32_t)) 354*7978SPeter.Dunlap@Sun.COM #define IDM_SORX_CACHE_HDRLEN (sizeof (iscsi_hdr_t) + IDM_SORX_CACHE_AHSLEN) 355*7978SPeter.Dunlap@Sun.COM 356*7978SPeter.Dunlap@Sun.COM /* 357*7978SPeter.Dunlap@Sun.COM * ID pool 358*7978SPeter.Dunlap@Sun.COM */ 359*7978SPeter.Dunlap@Sun.COM 360*7978SPeter.Dunlap@Sun.COM #define IDM_IDPOOL_MAGIC 0x4944504C /* IDPL */ 361*7978SPeter.Dunlap@Sun.COM #define IDM_IDPOOL_MIN_SIZE 64 /* Number of IDs to begin with */ 362*7978SPeter.Dunlap@Sun.COM #define IDM_IDPOOL_MAX_SIZE 64 * 1024 363*7978SPeter.Dunlap@Sun.COM 364*7978SPeter.Dunlap@Sun.COM typedef struct idm_idpool { 365*7978SPeter.Dunlap@Sun.COM uint32_t id_magic; 366*7978SPeter.Dunlap@Sun.COM kmutex_t id_mutex; 367*7978SPeter.Dunlap@Sun.COM uint8_t *id_pool; 368*7978SPeter.Dunlap@Sun.COM uint32_t id_size; 369*7978SPeter.Dunlap@Sun.COM uint8_t id_bit; 370*7978SPeter.Dunlap@Sun.COM uint8_t id_bit_idx; 371*7978SPeter.Dunlap@Sun.COM uint32_t id_idx; 372*7978SPeter.Dunlap@Sun.COM uint32_t id_idx_msk; 373*7978SPeter.Dunlap@Sun.COM uint32_t id_free_counter; 374*7978SPeter.Dunlap@Sun.COM uint32_t id_max_free_counter; 375*7978SPeter.Dunlap@Sun.COM } idm_idpool_t; 376*7978SPeter.Dunlap@Sun.COM 377*7978SPeter.Dunlap@Sun.COM /* 378*7978SPeter.Dunlap@Sun.COM * Global IDM state structure 379*7978SPeter.Dunlap@Sun.COM */ 380*7978SPeter.Dunlap@Sun.COM typedef struct { 381*7978SPeter.Dunlap@Sun.COM kmutex_t idm_global_mutex; 382*7978SPeter.Dunlap@Sun.COM taskq_t *idm_global_taskq; 383*7978SPeter.Dunlap@Sun.COM kthread_t *idm_wd_thread; 384*7978SPeter.Dunlap@Sun.COM kt_did_t idm_wd_thread_did; 385*7978SPeter.Dunlap@Sun.COM boolean_t idm_wd_thread_running; 386*7978SPeter.Dunlap@Sun.COM kcondvar_t idm_wd_cv; 387*7978SPeter.Dunlap@Sun.COM list_t idm_tgt_svc_list; 388*7978SPeter.Dunlap@Sun.COM kcondvar_t idm_tgt_svc_cv; 389*7978SPeter.Dunlap@Sun.COM list_t idm_tgt_conn_list; 390*7978SPeter.Dunlap@Sun.COM int idm_tgt_conn_count; 391*7978SPeter.Dunlap@Sun.COM list_t idm_ini_conn_list; 392*7978SPeter.Dunlap@Sun.COM kmem_cache_t *idm_buf_cache; 393*7978SPeter.Dunlap@Sun.COM kmem_cache_t *idm_task_cache; 394*7978SPeter.Dunlap@Sun.COM krwlock_t idm_taskid_table_lock; 395*7978SPeter.Dunlap@Sun.COM idm_task_t **idm_taskid_table; 396*7978SPeter.Dunlap@Sun.COM uint32_t idm_taskid_next; 397*7978SPeter.Dunlap@Sun.COM uint32_t idm_taskid_max; 398*7978SPeter.Dunlap@Sun.COM idm_idpool_t idm_conn_id_pool; 399*7978SPeter.Dunlap@Sun.COM kmem_cache_t *idm_sotx_pdu_cache; 400*7978SPeter.Dunlap@Sun.COM kmem_cache_t *idm_sorx_pdu_cache; 401*7978SPeter.Dunlap@Sun.COM } idm_global_t; 402*7978SPeter.Dunlap@Sun.COM 403*7978SPeter.Dunlap@Sun.COM idm_global_t idm; /* Global state */ 404*7978SPeter.Dunlap@Sun.COM 405*7978SPeter.Dunlap@Sun.COM int 406*7978SPeter.Dunlap@Sun.COM idm_idpool_create(idm_idpool_t *pool); 407*7978SPeter.Dunlap@Sun.COM 408*7978SPeter.Dunlap@Sun.COM void 409*7978SPeter.Dunlap@Sun.COM idm_idpool_destroy(idm_idpool_t *pool); 410*7978SPeter.Dunlap@Sun.COM 411*7978SPeter.Dunlap@Sun.COM int 412*7978SPeter.Dunlap@Sun.COM idm_idpool_alloc(idm_idpool_t *pool, uint16_t *id); 413*7978SPeter.Dunlap@Sun.COM 414*7978SPeter.Dunlap@Sun.COM void 415*7978SPeter.Dunlap@Sun.COM idm_idpool_free(idm_idpool_t *pool, uint16_t id); 416*7978SPeter.Dunlap@Sun.COM 417*7978SPeter.Dunlap@Sun.COM void 418*7978SPeter.Dunlap@Sun.COM idm_pdu_rx(idm_conn_t *ic, idm_pdu_t *pdu); 419*7978SPeter.Dunlap@Sun.COM 420*7978SPeter.Dunlap@Sun.COM void 421*7978SPeter.Dunlap@Sun.COM idm_pdu_tx_forward(idm_conn_t *ic, idm_pdu_t *pdu); 422*7978SPeter.Dunlap@Sun.COM 423*7978SPeter.Dunlap@Sun.COM boolean_t 424*7978SPeter.Dunlap@Sun.COM idm_pdu_rx_forward_ffp(idm_conn_t *ic, idm_pdu_t *pdu); 425*7978SPeter.Dunlap@Sun.COM 426*7978SPeter.Dunlap@Sun.COM void 427*7978SPeter.Dunlap@Sun.COM idm_pdu_rx_forward(idm_conn_t *ic, idm_pdu_t *pdu); 428*7978SPeter.Dunlap@Sun.COM 429*7978SPeter.Dunlap@Sun.COM void 430*7978SPeter.Dunlap@Sun.COM idm_pdu_tx_protocol_error(idm_conn_t *ic, idm_pdu_t *pdu); 431*7978SPeter.Dunlap@Sun.COM 432*7978SPeter.Dunlap@Sun.COM void 433*7978SPeter.Dunlap@Sun.COM idm_pdu_rx_protocol_error(idm_conn_t *ic, idm_pdu_t *pdu); 434*7978SPeter.Dunlap@Sun.COM 435*7978SPeter.Dunlap@Sun.COM void idm_parse_login_rsp(idm_conn_t *ic, idm_pdu_t *logout_req_pdu, 436*7978SPeter.Dunlap@Sun.COM boolean_t rx); 437*7978SPeter.Dunlap@Sun.COM 438*7978SPeter.Dunlap@Sun.COM void idm_parse_logout_req(idm_conn_t *ic, idm_pdu_t *logout_req_pdu, 439*7978SPeter.Dunlap@Sun.COM boolean_t rx); 440*7978SPeter.Dunlap@Sun.COM 441*7978SPeter.Dunlap@Sun.COM void idm_parse_logout_rsp(idm_conn_t *ic, idm_pdu_t *login_rsp_pdu, 442*7978SPeter.Dunlap@Sun.COM boolean_t rx); 443*7978SPeter.Dunlap@Sun.COM 444*7978SPeter.Dunlap@Sun.COM idm_status_t idm_svc_conn_create(idm_svc_t *is, idm_transport_type_t type, 445*7978SPeter.Dunlap@Sun.COM idm_conn_t **ic_result); 446*7978SPeter.Dunlap@Sun.COM 447*7978SPeter.Dunlap@Sun.COM void idm_svc_conn_destroy(idm_conn_t *ic); 448*7978SPeter.Dunlap@Sun.COM 449*7978SPeter.Dunlap@Sun.COM idm_status_t idm_ini_conn_finish(idm_conn_t *ic); 450*7978SPeter.Dunlap@Sun.COM 451*7978SPeter.Dunlap@Sun.COM idm_status_t idm_tgt_conn_finish(idm_conn_t *ic); 452*7978SPeter.Dunlap@Sun.COM 453*7978SPeter.Dunlap@Sun.COM idm_conn_t *idm_conn_create_common(idm_conn_type_t conn_type, 454*7978SPeter.Dunlap@Sun.COM idm_transport_type_t tt, idm_conn_ops_t *conn_ops); 455*7978SPeter.Dunlap@Sun.COM 456*7978SPeter.Dunlap@Sun.COM void idm_conn_destroy_common(idm_conn_t *ic); 457*7978SPeter.Dunlap@Sun.COM 458*7978SPeter.Dunlap@Sun.COM void idm_conn_close(idm_conn_t *ic); 459*7978SPeter.Dunlap@Sun.COM 460*7978SPeter.Dunlap@Sun.COM uint32_t idm_cid_alloc(void); 461*7978SPeter.Dunlap@Sun.COM 462*7978SPeter.Dunlap@Sun.COM void idm_cid_free(uint32_t cid); 463*7978SPeter.Dunlap@Sun.COM 464*7978SPeter.Dunlap@Sun.COM uint32_t idm_crc32c(void *address, unsigned long length); 465*7978SPeter.Dunlap@Sun.COM 466*7978SPeter.Dunlap@Sun.COM uint32_t idm_crc32c_continued(void *address, unsigned long length, 467*7978SPeter.Dunlap@Sun.COM uint32_t crc); 468*7978SPeter.Dunlap@Sun.COM 469*7978SPeter.Dunlap@Sun.COM void idm_listbuf_insert(list_t *lst, idm_buf_t *buf); 470*7978SPeter.Dunlap@Sun.COM 471*7978SPeter.Dunlap@Sun.COM int idm_task_compare(const void *v1, const void *v2); 472*7978SPeter.Dunlap@Sun.COM 473*7978SPeter.Dunlap@Sun.COM idm_conn_t *idm_lookup_conn(uint8_t *isid, uint16_t tsih, uint16_t cid); 474*7978SPeter.Dunlap@Sun.COM 475*7978SPeter.Dunlap@Sun.COM #ifdef __cplusplus 476*7978SPeter.Dunlap@Sun.COM } 477*7978SPeter.Dunlap@Sun.COM #endif 478*7978SPeter.Dunlap@Sun.COM 479*7978SPeter.Dunlap@Sun.COM #endif /* _IDM_IMPL_H_ */ 480