18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * iSCSI lib definitions 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 2006 Red Hat, Inc. All rights reserved. 68c2ecf20Sopenharmony_ci * Copyright (C) 2004 - 2006 Mike Christie 78c2ecf20Sopenharmony_ci * Copyright (C) 2004 - 2005 Dmitry Yusupov 88c2ecf20Sopenharmony_ci * Copyright (C) 2004 - 2005 Alex Aizman 98c2ecf20Sopenharmony_ci */ 108c2ecf20Sopenharmony_ci#ifndef LIBISCSI_H 118c2ecf20Sopenharmony_ci#define LIBISCSI_H 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#include <linux/types.h> 148c2ecf20Sopenharmony_ci#include <linux/wait.h> 158c2ecf20Sopenharmony_ci#include <linux/mutex.h> 168c2ecf20Sopenharmony_ci#include <linux/timer.h> 178c2ecf20Sopenharmony_ci#include <linux/workqueue.h> 188c2ecf20Sopenharmony_ci#include <linux/kfifo.h> 198c2ecf20Sopenharmony_ci#include <linux/refcount.h> 208c2ecf20Sopenharmony_ci#include <scsi/iscsi_proto.h> 218c2ecf20Sopenharmony_ci#include <scsi/iscsi_if.h> 228c2ecf20Sopenharmony_ci#include <scsi/scsi_transport_iscsi.h> 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_cistruct scsi_transport_template; 258c2ecf20Sopenharmony_cistruct scsi_host_template; 268c2ecf20Sopenharmony_cistruct scsi_device; 278c2ecf20Sopenharmony_cistruct Scsi_Host; 288c2ecf20Sopenharmony_cistruct scsi_target; 298c2ecf20Sopenharmony_cistruct scsi_cmnd; 308c2ecf20Sopenharmony_cistruct socket; 318c2ecf20Sopenharmony_cistruct iscsi_transport; 328c2ecf20Sopenharmony_cistruct iscsi_cls_session; 338c2ecf20Sopenharmony_cistruct iscsi_cls_conn; 348c2ecf20Sopenharmony_cistruct iscsi_session; 358c2ecf20Sopenharmony_cistruct iscsi_nopin; 368c2ecf20Sopenharmony_cistruct device; 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci#define ISCSI_DEF_XMIT_CMDS_MAX 128 /* must be power of 2 */ 398c2ecf20Sopenharmony_ci#define ISCSI_MGMT_CMDS_MAX 15 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci#define ISCSI_DEF_CMD_PER_LUN 32 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci/* Task Mgmt states */ 448c2ecf20Sopenharmony_cienum { 458c2ecf20Sopenharmony_ci TMF_INITIAL, 468c2ecf20Sopenharmony_ci TMF_QUEUED, 478c2ecf20Sopenharmony_ci TMF_SUCCESS, 488c2ecf20Sopenharmony_ci TMF_FAILED, 498c2ecf20Sopenharmony_ci TMF_TIMEDOUT, 508c2ecf20Sopenharmony_ci TMF_NOT_FOUND, 518c2ecf20Sopenharmony_ci}; 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci#define ISID_SIZE 6 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci/* Connection suspend "bit" */ 568c2ecf20Sopenharmony_ci#define ISCSI_SUSPEND_BIT 1 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci#define ISCSI_ITT_MASK 0x1fff 598c2ecf20Sopenharmony_ci#define ISCSI_TOTAL_CMDS_MAX 4096 608c2ecf20Sopenharmony_ci/* this must be a power of two greater than ISCSI_MGMT_CMDS_MAX */ 618c2ecf20Sopenharmony_ci#define ISCSI_TOTAL_CMDS_MIN 16 628c2ecf20Sopenharmony_ci#define ISCSI_AGE_SHIFT 28 638c2ecf20Sopenharmony_ci#define ISCSI_AGE_MASK 0xf 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci#define ISCSI_ADDRESS_BUF_LEN 64 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_cienum { 688c2ecf20Sopenharmony_ci /* this is the maximum possible storage for AHSs */ 698c2ecf20Sopenharmony_ci ISCSI_MAX_AHS_SIZE = sizeof(struct iscsi_ecdb_ahdr) + 708c2ecf20Sopenharmony_ci sizeof(struct iscsi_rlength_ahdr), 718c2ecf20Sopenharmony_ci ISCSI_DIGEST_SIZE = sizeof(__u32), 728c2ecf20Sopenharmony_ci}; 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_cienum { 768c2ecf20Sopenharmony_ci ISCSI_TASK_FREE, 778c2ecf20Sopenharmony_ci ISCSI_TASK_COMPLETED, 788c2ecf20Sopenharmony_ci ISCSI_TASK_PENDING, 798c2ecf20Sopenharmony_ci ISCSI_TASK_RUNNING, 808c2ecf20Sopenharmony_ci ISCSI_TASK_ABRT_TMF, /* aborted due to TMF */ 818c2ecf20Sopenharmony_ci ISCSI_TASK_ABRT_SESS_RECOV, /* aborted due to session recovery */ 828c2ecf20Sopenharmony_ci ISCSI_TASK_REQUEUE_SCSIQ, /* qcmd requeueing to scsi-ml */ 838c2ecf20Sopenharmony_ci}; 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_cistruct iscsi_r2t_info { 868c2ecf20Sopenharmony_ci __be32 ttt; /* copied from R2T */ 878c2ecf20Sopenharmony_ci __be32 exp_statsn; /* copied from R2T */ 888c2ecf20Sopenharmony_ci uint32_t data_length; /* copied from R2T */ 898c2ecf20Sopenharmony_ci uint32_t data_offset; /* copied from R2T */ 908c2ecf20Sopenharmony_ci int data_count; /* DATA-Out payload progress */ 918c2ecf20Sopenharmony_ci int datasn; 928c2ecf20Sopenharmony_ci /* LLDs should set/update these values */ 938c2ecf20Sopenharmony_ci int sent; /* R2T sequence progress */ 948c2ecf20Sopenharmony_ci}; 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_cistruct iscsi_task { 978c2ecf20Sopenharmony_ci /* 988c2ecf20Sopenharmony_ci * Because LLDs allocate their hdr differently, this is a pointer 998c2ecf20Sopenharmony_ci * and length to that storage. It must be setup at session 1008c2ecf20Sopenharmony_ci * creation time. 1018c2ecf20Sopenharmony_ci */ 1028c2ecf20Sopenharmony_ci struct iscsi_hdr *hdr; 1038c2ecf20Sopenharmony_ci unsigned short hdr_max; 1048c2ecf20Sopenharmony_ci unsigned short hdr_len; /* accumulated size of hdr used */ 1058c2ecf20Sopenharmony_ci /* copied values in case we need to send tmfs */ 1068c2ecf20Sopenharmony_ci itt_t hdr_itt; 1078c2ecf20Sopenharmony_ci __be32 cmdsn; 1088c2ecf20Sopenharmony_ci struct scsi_lun lun; 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci int itt; /* this ITT */ 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_ci unsigned imm_count; /* imm-data (bytes) */ 1138c2ecf20Sopenharmony_ci /* offset in unsolicited stream (bytes); */ 1148c2ecf20Sopenharmony_ci struct iscsi_r2t_info unsol_r2t; 1158c2ecf20Sopenharmony_ci char *data; /* mgmt payload */ 1168c2ecf20Sopenharmony_ci unsigned data_count; 1178c2ecf20Sopenharmony_ci struct scsi_cmnd *sc; /* associated SCSI cmd*/ 1188c2ecf20Sopenharmony_ci struct iscsi_conn *conn; /* used connection */ 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci /* data processing tracking */ 1218c2ecf20Sopenharmony_ci unsigned long last_xfer; 1228c2ecf20Sopenharmony_ci unsigned long last_timeout; 1238c2ecf20Sopenharmony_ci bool have_checked_conn; 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci /* T10 protection information */ 1268c2ecf20Sopenharmony_ci bool protected; 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci /* state set/tested under session->lock */ 1298c2ecf20Sopenharmony_ci int state; 1308c2ecf20Sopenharmony_ci refcount_t refcount; 1318c2ecf20Sopenharmony_ci struct list_head running; /* running cmd list */ 1328c2ecf20Sopenharmony_ci void *dd_data; /* driver/transport data */ 1338c2ecf20Sopenharmony_ci}; 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ci/* invalid scsi_task pointer */ 1368c2ecf20Sopenharmony_ci#define INVALID_SCSI_TASK (struct iscsi_task *)-1l 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_cistatic inline int iscsi_task_has_unsol_data(struct iscsi_task *task) 1398c2ecf20Sopenharmony_ci{ 1408c2ecf20Sopenharmony_ci return task->unsol_r2t.data_length > task->unsol_r2t.sent; 1418c2ecf20Sopenharmony_ci} 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_cistatic inline void* iscsi_next_hdr(struct iscsi_task *task) 1448c2ecf20Sopenharmony_ci{ 1458c2ecf20Sopenharmony_ci return (void*)task->hdr + task->hdr_len; 1468c2ecf20Sopenharmony_ci} 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci/* Connection's states */ 1498c2ecf20Sopenharmony_cienum { 1508c2ecf20Sopenharmony_ci ISCSI_CONN_INITIAL_STAGE, 1518c2ecf20Sopenharmony_ci ISCSI_CONN_STARTED, 1528c2ecf20Sopenharmony_ci ISCSI_CONN_STOPPED, 1538c2ecf20Sopenharmony_ci ISCSI_CONN_CLEANUP_WAIT, 1548c2ecf20Sopenharmony_ci}; 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_cistruct iscsi_conn { 1578c2ecf20Sopenharmony_ci struct iscsi_cls_conn *cls_conn; /* ptr to class connection */ 1588c2ecf20Sopenharmony_ci void *dd_data; /* iscsi_transport data */ 1598c2ecf20Sopenharmony_ci struct iscsi_session *session; /* parent session */ 1608c2ecf20Sopenharmony_ci /* 1618c2ecf20Sopenharmony_ci * conn_stop() flag: stop to recover, stop to terminate 1628c2ecf20Sopenharmony_ci */ 1638c2ecf20Sopenharmony_ci int stop_stage; 1648c2ecf20Sopenharmony_ci struct timer_list transport_timer; 1658c2ecf20Sopenharmony_ci unsigned long last_recv; 1668c2ecf20Sopenharmony_ci unsigned long last_ping; 1678c2ecf20Sopenharmony_ci int ping_timeout; 1688c2ecf20Sopenharmony_ci int recv_timeout; 1698c2ecf20Sopenharmony_ci struct iscsi_task *ping_task; 1708c2ecf20Sopenharmony_ci 1718c2ecf20Sopenharmony_ci /* iSCSI connection-wide sequencing */ 1728c2ecf20Sopenharmony_ci uint32_t exp_statsn; 1738c2ecf20Sopenharmony_ci uint32_t statsn; 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_ci /* control data */ 1768c2ecf20Sopenharmony_ci int id; /* CID */ 1778c2ecf20Sopenharmony_ci int c_stage; /* connection state */ 1788c2ecf20Sopenharmony_ci /* 1798c2ecf20Sopenharmony_ci * Preallocated buffer for pdus that have data but do not 1808c2ecf20Sopenharmony_ci * originate from scsi-ml. We never have two pdus using the 1818c2ecf20Sopenharmony_ci * buffer at the same time. It is only allocated to 1828c2ecf20Sopenharmony_ci * the default max recv size because the pdus we support 1838c2ecf20Sopenharmony_ci * should always fit in this buffer 1848c2ecf20Sopenharmony_ci */ 1858c2ecf20Sopenharmony_ci char *data; 1868c2ecf20Sopenharmony_ci struct iscsi_task *login_task; /* mtask used for login/text */ 1878c2ecf20Sopenharmony_ci struct iscsi_task *task; /* xmit task in progress */ 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_ci /* xmit */ 1908c2ecf20Sopenharmony_ci /* items must be added/deleted under frwd lock */ 1918c2ecf20Sopenharmony_ci struct list_head mgmtqueue; /* mgmt (control) xmit queue */ 1928c2ecf20Sopenharmony_ci struct list_head cmdqueue; /* data-path cmd queue */ 1938c2ecf20Sopenharmony_ci struct list_head requeue; /* tasks needing another run */ 1948c2ecf20Sopenharmony_ci struct work_struct xmitwork; /* per-conn. xmit workqueue */ 1958c2ecf20Sopenharmony_ci unsigned long suspend_tx; /* suspend Tx */ 1968c2ecf20Sopenharmony_ci unsigned long suspend_rx; /* suspend Rx */ 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_ci /* negotiated params */ 1998c2ecf20Sopenharmony_ci unsigned max_recv_dlength; /* initiator_max_recv_dsl*/ 2008c2ecf20Sopenharmony_ci unsigned max_xmit_dlength; /* target_max_recv_dsl */ 2018c2ecf20Sopenharmony_ci int hdrdgst_en; 2028c2ecf20Sopenharmony_ci int datadgst_en; 2038c2ecf20Sopenharmony_ci int ifmarker_en; 2048c2ecf20Sopenharmony_ci int ofmarker_en; 2058c2ecf20Sopenharmony_ci /* values userspace uses to id a conn */ 2068c2ecf20Sopenharmony_ci int persistent_port; 2078c2ecf20Sopenharmony_ci char *persistent_address; 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_ci unsigned max_segment_size; 2108c2ecf20Sopenharmony_ci unsigned tcp_xmit_wsf; 2118c2ecf20Sopenharmony_ci unsigned tcp_recv_wsf; 2128c2ecf20Sopenharmony_ci uint16_t keepalive_tmo; 2138c2ecf20Sopenharmony_ci uint16_t local_port; 2148c2ecf20Sopenharmony_ci uint8_t tcp_timestamp_stat; 2158c2ecf20Sopenharmony_ci uint8_t tcp_nagle_disable; 2168c2ecf20Sopenharmony_ci uint8_t tcp_wsf_disable; 2178c2ecf20Sopenharmony_ci uint8_t tcp_timer_scale; 2188c2ecf20Sopenharmony_ci uint8_t tcp_timestamp_en; 2198c2ecf20Sopenharmony_ci uint8_t fragment_disable; 2208c2ecf20Sopenharmony_ci uint8_t ipv4_tos; 2218c2ecf20Sopenharmony_ci uint8_t ipv6_traffic_class; 2228c2ecf20Sopenharmony_ci uint8_t ipv6_flow_label; 2238c2ecf20Sopenharmony_ci uint8_t is_fw_assigned_ipv6; 2248c2ecf20Sopenharmony_ci char *local_ipaddr; 2258c2ecf20Sopenharmony_ci 2268c2ecf20Sopenharmony_ci /* MIB-statistics */ 2278c2ecf20Sopenharmony_ci uint64_t txdata_octets; 2288c2ecf20Sopenharmony_ci uint64_t rxdata_octets; 2298c2ecf20Sopenharmony_ci uint32_t scsicmd_pdus_cnt; 2308c2ecf20Sopenharmony_ci uint32_t dataout_pdus_cnt; 2318c2ecf20Sopenharmony_ci uint32_t scsirsp_pdus_cnt; 2328c2ecf20Sopenharmony_ci uint32_t datain_pdus_cnt; 2338c2ecf20Sopenharmony_ci uint32_t r2t_pdus_cnt; 2348c2ecf20Sopenharmony_ci uint32_t tmfcmd_pdus_cnt; 2358c2ecf20Sopenharmony_ci int32_t tmfrsp_pdus_cnt; 2368c2ecf20Sopenharmony_ci 2378c2ecf20Sopenharmony_ci /* custom statistics */ 2388c2ecf20Sopenharmony_ci uint32_t eh_abort_cnt; 2398c2ecf20Sopenharmony_ci uint32_t fmr_unalign_cnt; 2408c2ecf20Sopenharmony_ci}; 2418c2ecf20Sopenharmony_ci 2428c2ecf20Sopenharmony_cistruct iscsi_pool { 2438c2ecf20Sopenharmony_ci struct kfifo queue; /* FIFO Queue */ 2448c2ecf20Sopenharmony_ci void **pool; /* Pool of elements */ 2458c2ecf20Sopenharmony_ci int max; /* Max number of elements */ 2468c2ecf20Sopenharmony_ci}; 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_ci/* Session's states */ 2498c2ecf20Sopenharmony_cienum { 2508c2ecf20Sopenharmony_ci ISCSI_STATE_FREE = 1, 2518c2ecf20Sopenharmony_ci ISCSI_STATE_LOGGED_IN, 2528c2ecf20Sopenharmony_ci ISCSI_STATE_FAILED, 2538c2ecf20Sopenharmony_ci ISCSI_STATE_TERMINATE, 2548c2ecf20Sopenharmony_ci ISCSI_STATE_IN_RECOVERY, 2558c2ecf20Sopenharmony_ci ISCSI_STATE_RECOVERY_FAILED, 2568c2ecf20Sopenharmony_ci ISCSI_STATE_LOGGING_OUT, 2578c2ecf20Sopenharmony_ci}; 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_cistruct iscsi_session { 2608c2ecf20Sopenharmony_ci struct iscsi_cls_session *cls_session; 2618c2ecf20Sopenharmony_ci /* 2628c2ecf20Sopenharmony_ci * Syncs up the scsi eh thread with the iscsi eh thread when sending 2638c2ecf20Sopenharmony_ci * task management functions. This must be taken before the session 2648c2ecf20Sopenharmony_ci * and recv lock. 2658c2ecf20Sopenharmony_ci */ 2668c2ecf20Sopenharmony_ci struct mutex eh_mutex; 2678c2ecf20Sopenharmony_ci /* abort */ 2688c2ecf20Sopenharmony_ci wait_queue_head_t ehwait; /* used in eh_abort() */ 2698c2ecf20Sopenharmony_ci struct iscsi_tm tmhdr; 2708c2ecf20Sopenharmony_ci struct timer_list tmf_timer; 2718c2ecf20Sopenharmony_ci int tmf_state; /* see TMF_INITIAL, etc.*/ 2728c2ecf20Sopenharmony_ci 2738c2ecf20Sopenharmony_ci /* iSCSI session-wide sequencing */ 2748c2ecf20Sopenharmony_ci uint32_t cmdsn; 2758c2ecf20Sopenharmony_ci uint32_t exp_cmdsn; 2768c2ecf20Sopenharmony_ci uint32_t max_cmdsn; 2778c2ecf20Sopenharmony_ci 2788c2ecf20Sopenharmony_ci /* This tracks the reqs queued into the initiator */ 2798c2ecf20Sopenharmony_ci uint32_t queued_cmdsn; 2808c2ecf20Sopenharmony_ci 2818c2ecf20Sopenharmony_ci /* configuration */ 2828c2ecf20Sopenharmony_ci int abort_timeout; 2838c2ecf20Sopenharmony_ci int lu_reset_timeout; 2848c2ecf20Sopenharmony_ci int tgt_reset_timeout; 2858c2ecf20Sopenharmony_ci int initial_r2t_en; 2868c2ecf20Sopenharmony_ci unsigned short max_r2t; 2878c2ecf20Sopenharmony_ci int imm_data_en; 2888c2ecf20Sopenharmony_ci unsigned first_burst; 2898c2ecf20Sopenharmony_ci unsigned max_burst; 2908c2ecf20Sopenharmony_ci int time2wait; 2918c2ecf20Sopenharmony_ci int time2retain; 2928c2ecf20Sopenharmony_ci int pdu_inorder_en; 2938c2ecf20Sopenharmony_ci int dataseq_inorder_en; 2948c2ecf20Sopenharmony_ci int erl; 2958c2ecf20Sopenharmony_ci int fast_abort; 2968c2ecf20Sopenharmony_ci int tpgt; 2978c2ecf20Sopenharmony_ci char *username; 2988c2ecf20Sopenharmony_ci char *username_in; 2998c2ecf20Sopenharmony_ci char *password; 3008c2ecf20Sopenharmony_ci char *password_in; 3018c2ecf20Sopenharmony_ci char *targetname; 3028c2ecf20Sopenharmony_ci char *targetalias; 3038c2ecf20Sopenharmony_ci char *ifacename; 3048c2ecf20Sopenharmony_ci char *initiatorname; 3058c2ecf20Sopenharmony_ci char *boot_root; 3068c2ecf20Sopenharmony_ci char *boot_nic; 3078c2ecf20Sopenharmony_ci char *boot_target; 3088c2ecf20Sopenharmony_ci char *portal_type; 3098c2ecf20Sopenharmony_ci char *discovery_parent_type; 3108c2ecf20Sopenharmony_ci uint16_t discovery_parent_idx; 3118c2ecf20Sopenharmony_ci uint16_t def_taskmgmt_tmo; 3128c2ecf20Sopenharmony_ci uint16_t tsid; 3138c2ecf20Sopenharmony_ci uint8_t auto_snd_tgt_disable; 3148c2ecf20Sopenharmony_ci uint8_t discovery_sess; 3158c2ecf20Sopenharmony_ci uint8_t chap_auth_en; 3168c2ecf20Sopenharmony_ci uint8_t discovery_logout_en; 3178c2ecf20Sopenharmony_ci uint8_t bidi_chap_en; 3188c2ecf20Sopenharmony_ci uint8_t discovery_auth_optional; 3198c2ecf20Sopenharmony_ci uint8_t isid[ISID_SIZE]; 3208c2ecf20Sopenharmony_ci 3218c2ecf20Sopenharmony_ci /* control data */ 3228c2ecf20Sopenharmony_ci struct iscsi_transport *tt; 3238c2ecf20Sopenharmony_ci struct Scsi_Host *host; 3248c2ecf20Sopenharmony_ci struct iscsi_conn *leadconn; /* leading connection */ 3258c2ecf20Sopenharmony_ci /* Between the forward and the backward locks exists a strict locking 3268c2ecf20Sopenharmony_ci * hierarchy. The mutual exclusion zone protected by the forward lock 3278c2ecf20Sopenharmony_ci * can enclose the mutual exclusion zone protected by the backward lock 3288c2ecf20Sopenharmony_ci * but not vice versa. 3298c2ecf20Sopenharmony_ci */ 3308c2ecf20Sopenharmony_ci spinlock_t frwd_lock; /* protects session state, * 3318c2ecf20Sopenharmony_ci * cmdsn, queued_cmdsn * 3328c2ecf20Sopenharmony_ci * session resources: * 3338c2ecf20Sopenharmony_ci * - cmdpool kfifo_out , * 3348c2ecf20Sopenharmony_ci * - mgmtpool, queues */ 3358c2ecf20Sopenharmony_ci spinlock_t back_lock; /* protects cmdsn_exp * 3368c2ecf20Sopenharmony_ci * cmdsn_max, * 3378c2ecf20Sopenharmony_ci * cmdpool kfifo_in */ 3388c2ecf20Sopenharmony_ci int state; /* session state */ 3398c2ecf20Sopenharmony_ci int age; /* counts session re-opens */ 3408c2ecf20Sopenharmony_ci 3418c2ecf20Sopenharmony_ci int scsi_cmds_max; /* max scsi commands */ 3428c2ecf20Sopenharmony_ci int cmds_max; /* size of cmds array */ 3438c2ecf20Sopenharmony_ci struct iscsi_task **cmds; /* Original Cmds arr */ 3448c2ecf20Sopenharmony_ci struct iscsi_pool cmdpool; /* PDU's pool */ 3458c2ecf20Sopenharmony_ci void *dd_data; /* LLD private data */ 3468c2ecf20Sopenharmony_ci}; 3478c2ecf20Sopenharmony_ci 3488c2ecf20Sopenharmony_cienum { 3498c2ecf20Sopenharmony_ci ISCSI_HOST_SETUP, 3508c2ecf20Sopenharmony_ci ISCSI_HOST_REMOVED, 3518c2ecf20Sopenharmony_ci}; 3528c2ecf20Sopenharmony_ci 3538c2ecf20Sopenharmony_cistruct iscsi_host { 3548c2ecf20Sopenharmony_ci char *initiatorname; 3558c2ecf20Sopenharmony_ci /* hw address or netdev iscsi connection is bound to */ 3568c2ecf20Sopenharmony_ci char *hwaddress; 3578c2ecf20Sopenharmony_ci char *netdev; 3588c2ecf20Sopenharmony_ci 3598c2ecf20Sopenharmony_ci wait_queue_head_t session_removal_wq; 3608c2ecf20Sopenharmony_ci /* protects sessions and state */ 3618c2ecf20Sopenharmony_ci spinlock_t lock; 3628c2ecf20Sopenharmony_ci int num_sessions; 3638c2ecf20Sopenharmony_ci int state; 3648c2ecf20Sopenharmony_ci 3658c2ecf20Sopenharmony_ci struct workqueue_struct *workq; 3668c2ecf20Sopenharmony_ci char workq_name[20]; 3678c2ecf20Sopenharmony_ci}; 3688c2ecf20Sopenharmony_ci 3698c2ecf20Sopenharmony_ci/* 3708c2ecf20Sopenharmony_ci * scsi host template 3718c2ecf20Sopenharmony_ci */ 3728c2ecf20Sopenharmony_ciextern int iscsi_eh_abort(struct scsi_cmnd *sc); 3738c2ecf20Sopenharmony_ciextern int iscsi_eh_recover_target(struct scsi_cmnd *sc); 3748c2ecf20Sopenharmony_ciextern int iscsi_eh_session_reset(struct scsi_cmnd *sc); 3758c2ecf20Sopenharmony_ciextern int iscsi_eh_device_reset(struct scsi_cmnd *sc); 3768c2ecf20Sopenharmony_ciextern int iscsi_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc); 3778c2ecf20Sopenharmony_ciextern enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc); 3788c2ecf20Sopenharmony_ci 3798c2ecf20Sopenharmony_ci/* 3808c2ecf20Sopenharmony_ci * iSCSI host helpers. 3818c2ecf20Sopenharmony_ci */ 3828c2ecf20Sopenharmony_ci#define iscsi_host_priv(_shost) \ 3838c2ecf20Sopenharmony_ci (shost_priv(_shost) + sizeof(struct iscsi_host)) 3848c2ecf20Sopenharmony_ci 3858c2ecf20Sopenharmony_ciextern int iscsi_host_set_param(struct Scsi_Host *shost, 3868c2ecf20Sopenharmony_ci enum iscsi_host_param param, char *buf, 3878c2ecf20Sopenharmony_ci int buflen); 3888c2ecf20Sopenharmony_ciextern int iscsi_host_get_param(struct Scsi_Host *shost, 3898c2ecf20Sopenharmony_ci enum iscsi_host_param param, char *buf); 3908c2ecf20Sopenharmony_ciextern int iscsi_host_add(struct Scsi_Host *shost, struct device *pdev); 3918c2ecf20Sopenharmony_ciextern struct Scsi_Host *iscsi_host_alloc(struct scsi_host_template *sht, 3928c2ecf20Sopenharmony_ci int dd_data_size, 3938c2ecf20Sopenharmony_ci bool xmit_can_sleep); 3948c2ecf20Sopenharmony_ciextern void iscsi_host_remove(struct Scsi_Host *shost); 3958c2ecf20Sopenharmony_ciextern void iscsi_host_free(struct Scsi_Host *shost); 3968c2ecf20Sopenharmony_ciextern int iscsi_target_alloc(struct scsi_target *starget); 3978c2ecf20Sopenharmony_ciextern int iscsi_host_get_max_scsi_cmds(struct Scsi_Host *shost, 3988c2ecf20Sopenharmony_ci uint16_t requested_cmds_max); 3998c2ecf20Sopenharmony_ci 4008c2ecf20Sopenharmony_ci/* 4018c2ecf20Sopenharmony_ci * session management 4028c2ecf20Sopenharmony_ci */ 4038c2ecf20Sopenharmony_ciextern struct iscsi_cls_session * 4048c2ecf20Sopenharmony_ciiscsi_session_setup(struct iscsi_transport *, struct Scsi_Host *shost, 4058c2ecf20Sopenharmony_ci uint16_t, int, int, uint32_t, unsigned int); 4068c2ecf20Sopenharmony_ciextern void iscsi_session_teardown(struct iscsi_cls_session *); 4078c2ecf20Sopenharmony_ciextern void iscsi_session_recovery_timedout(struct iscsi_cls_session *); 4088c2ecf20Sopenharmony_ciextern int iscsi_set_param(struct iscsi_cls_conn *cls_conn, 4098c2ecf20Sopenharmony_ci enum iscsi_param param, char *buf, int buflen); 4108c2ecf20Sopenharmony_ciextern int iscsi_session_get_param(struct iscsi_cls_session *cls_session, 4118c2ecf20Sopenharmony_ci enum iscsi_param param, char *buf); 4128c2ecf20Sopenharmony_ci 4138c2ecf20Sopenharmony_ci#define iscsi_session_printk(prefix, _sess, fmt, a...) \ 4148c2ecf20Sopenharmony_ci iscsi_cls_session_printk(prefix, _sess->cls_session, fmt, ##a) 4158c2ecf20Sopenharmony_ci 4168c2ecf20Sopenharmony_ci/* 4178c2ecf20Sopenharmony_ci * connection management 4188c2ecf20Sopenharmony_ci */ 4198c2ecf20Sopenharmony_ciextern struct iscsi_cls_conn *iscsi_conn_setup(struct iscsi_cls_session *, 4208c2ecf20Sopenharmony_ci int, uint32_t); 4218c2ecf20Sopenharmony_ciextern void iscsi_conn_teardown(struct iscsi_cls_conn *); 4228c2ecf20Sopenharmony_ciextern int iscsi_conn_start(struct iscsi_cls_conn *); 4238c2ecf20Sopenharmony_ciextern void iscsi_conn_stop(struct iscsi_cls_conn *, int); 4248c2ecf20Sopenharmony_ciextern int iscsi_conn_bind(struct iscsi_cls_session *, struct iscsi_cls_conn *, 4258c2ecf20Sopenharmony_ci int); 4268c2ecf20Sopenharmony_ciextern void iscsi_conn_unbind(struct iscsi_cls_conn *cls_conn, bool is_active); 4278c2ecf20Sopenharmony_ciextern void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err); 4288c2ecf20Sopenharmony_ciextern void iscsi_session_failure(struct iscsi_session *session, 4298c2ecf20Sopenharmony_ci enum iscsi_err err); 4308c2ecf20Sopenharmony_ciextern int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn, 4318c2ecf20Sopenharmony_ci enum iscsi_param param, char *buf); 4328c2ecf20Sopenharmony_ciextern int iscsi_conn_get_addr_param(struct sockaddr_storage *addr, 4338c2ecf20Sopenharmony_ci enum iscsi_param param, char *buf); 4348c2ecf20Sopenharmony_ciextern void iscsi_suspend_tx(struct iscsi_conn *conn); 4358c2ecf20Sopenharmony_ciextern void iscsi_suspend_queue(struct iscsi_conn *conn); 4368c2ecf20Sopenharmony_ciextern void iscsi_conn_queue_work(struct iscsi_conn *conn); 4378c2ecf20Sopenharmony_ci 4388c2ecf20Sopenharmony_ci#define iscsi_conn_printk(prefix, _c, fmt, a...) \ 4398c2ecf20Sopenharmony_ci iscsi_cls_conn_printk(prefix, ((struct iscsi_conn *)_c)->cls_conn, \ 4408c2ecf20Sopenharmony_ci fmt, ##a) 4418c2ecf20Sopenharmony_ci 4428c2ecf20Sopenharmony_ci/* 4438c2ecf20Sopenharmony_ci * pdu and task processing 4448c2ecf20Sopenharmony_ci */ 4458c2ecf20Sopenharmony_ciextern void iscsi_update_cmdsn(struct iscsi_session *, struct iscsi_nopin *); 4468c2ecf20Sopenharmony_ciextern void iscsi_prep_data_out_pdu(struct iscsi_task *task, 4478c2ecf20Sopenharmony_ci struct iscsi_r2t_info *r2t, 4488c2ecf20Sopenharmony_ci struct iscsi_data *hdr); 4498c2ecf20Sopenharmony_ciextern int iscsi_conn_send_pdu(struct iscsi_cls_conn *, struct iscsi_hdr *, 4508c2ecf20Sopenharmony_ci char *, uint32_t); 4518c2ecf20Sopenharmony_ciextern int iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *, 4528c2ecf20Sopenharmony_ci char *, int); 4538c2ecf20Sopenharmony_ciextern int __iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *, 4548c2ecf20Sopenharmony_ci char *, int); 4558c2ecf20Sopenharmony_ciextern int iscsi_verify_itt(struct iscsi_conn *, itt_t); 4568c2ecf20Sopenharmony_ciextern struct iscsi_task *iscsi_itt_to_ctask(struct iscsi_conn *, itt_t); 4578c2ecf20Sopenharmony_ciextern struct iscsi_task *iscsi_itt_to_task(struct iscsi_conn *, itt_t); 4588c2ecf20Sopenharmony_ciextern void iscsi_requeue_task(struct iscsi_task *task); 4598c2ecf20Sopenharmony_ciextern void iscsi_put_task(struct iscsi_task *task); 4608c2ecf20Sopenharmony_ciextern void __iscsi_put_task(struct iscsi_task *task); 4618c2ecf20Sopenharmony_ciextern void __iscsi_get_task(struct iscsi_task *task); 4628c2ecf20Sopenharmony_ciextern void iscsi_complete_scsi_task(struct iscsi_task *task, 4638c2ecf20Sopenharmony_ci uint32_t exp_cmdsn, uint32_t max_cmdsn); 4648c2ecf20Sopenharmony_ci 4658c2ecf20Sopenharmony_ci/* 4668c2ecf20Sopenharmony_ci * generic helpers 4678c2ecf20Sopenharmony_ci */ 4688c2ecf20Sopenharmony_ciextern void iscsi_pool_free(struct iscsi_pool *); 4698c2ecf20Sopenharmony_ciextern int iscsi_pool_init(struct iscsi_pool *, int, void ***, int); 4708c2ecf20Sopenharmony_ciextern int iscsi_switch_str_param(char **, char *); 4718c2ecf20Sopenharmony_ci 4728c2ecf20Sopenharmony_ci/* 4738c2ecf20Sopenharmony_ci * inline functions to deal with padding. 4748c2ecf20Sopenharmony_ci */ 4758c2ecf20Sopenharmony_cistatic inline unsigned int 4768c2ecf20Sopenharmony_ciiscsi_padded(unsigned int len) 4778c2ecf20Sopenharmony_ci{ 4788c2ecf20Sopenharmony_ci return (len + ISCSI_PAD_LEN - 1) & ~(ISCSI_PAD_LEN - 1); 4798c2ecf20Sopenharmony_ci} 4808c2ecf20Sopenharmony_ci 4818c2ecf20Sopenharmony_cistatic inline unsigned int 4828c2ecf20Sopenharmony_ciiscsi_padding(unsigned int len) 4838c2ecf20Sopenharmony_ci{ 4848c2ecf20Sopenharmony_ci len &= (ISCSI_PAD_LEN - 1); 4858c2ecf20Sopenharmony_ci if (len) 4868c2ecf20Sopenharmony_ci len = ISCSI_PAD_LEN - len; 4878c2ecf20Sopenharmony_ci return len; 4888c2ecf20Sopenharmony_ci} 4898c2ecf20Sopenharmony_ci 4908c2ecf20Sopenharmony_ci#endif 491