17996a778SMike Christie /* 27996a778SMike Christie * iSCSI lib definitions 37996a778SMike Christie * 47996a778SMike Christie * Copyright (C) 2006 Red Hat, Inc. All rights reserved. 57996a778SMike Christie * Copyright (C) 2004 - 2006 Mike Christie 67996a778SMike Christie * Copyright (C) 2004 - 2005 Dmitry Yusupov 77996a778SMike Christie * Copyright (C) 2004 - 2005 Alex Aizman 87996a778SMike Christie * 97996a778SMike Christie * This program is free software; you can redistribute it and/or modify 107996a778SMike Christie * it under the terms of the GNU General Public License as published by 117996a778SMike Christie * the Free Software Foundation; either version 2 of the License, or 127996a778SMike Christie * (at your option) any later version. 137996a778SMike Christie * 147996a778SMike Christie * This program is distributed in the hope that it will be useful, 157996a778SMike Christie * but WITHOUT ANY WARRANTY; without even the implied warranty of 167996a778SMike Christie * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 177996a778SMike Christie * GNU General Public License for more details. 187996a778SMike Christie * 197996a778SMike Christie * You should have received a copy of the GNU General Public License 207996a778SMike Christie * along with this program; if not, write to the Free Software 217996a778SMike Christie * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 227996a778SMike Christie */ 237996a778SMike Christie #ifndef LIBISCSI_H 247996a778SMike Christie #define LIBISCSI_H 257996a778SMike Christie 267996a778SMike Christie #include <linux/types.h> 2740753caaSMike Christie #include <linux/wait.h> 287996a778SMike Christie #include <linux/mutex.h> 29f6a57033SAl Viro #include <linux/timer.h> 30f6a57033SAl Viro #include <linux/workqueue.h> 317996a778SMike Christie #include <scsi/iscsi_proto.h> 327996a778SMike Christie #include <scsi/iscsi_if.h> 337996a778SMike Christie 347996a778SMike Christie struct scsi_transport_template; 35a4804cd6SMike Christie struct scsi_host_template; 367996a778SMike Christie struct scsi_device; 377996a778SMike Christie struct Scsi_Host; 387996a778SMike Christie struct scsi_cmnd; 397996a778SMike Christie struct socket; 407996a778SMike Christie struct iscsi_transport; 417996a778SMike Christie struct iscsi_cls_session; 427996a778SMike Christie struct iscsi_cls_conn; 437996a778SMike Christie struct iscsi_session; 447996a778SMike Christie struct iscsi_nopin; 45a4804cd6SMike Christie struct device; 467996a778SMike Christie 477996a778SMike Christie /* #define DEBUG_SCSI */ 487996a778SMike Christie #ifdef DEBUG_SCSI 49be2df72eSOr Gerlitz #define debug_scsi(fmt...) printk(KERN_INFO "iscsi: " fmt) 507996a778SMike Christie #else 517996a778SMike Christie #define debug_scsi(fmt...) 527996a778SMike Christie #endif 537996a778SMike Christie 541548271eSMike Christie #define ISCSI_DEF_XMIT_CMDS_MAX 128 /* must be power of 2 */ 551548271eSMike Christie #define ISCSI_MGMT_CMDS_MAX 16 /* must be power of 2 */ 567996a778SMike Christie 577996a778SMike Christie #define ISCSI_MGMT_ITT_OFFSET 0xa00 587996a778SMike Christie 597996a778SMike Christie #define ISCSI_DEF_CMD_PER_LUN 32 607996a778SMike Christie #define ISCSI_MAX_CMD_PER_LUN 128 617996a778SMike Christie 627996a778SMike Christie /* Task Mgmt states */ 63843c0a8aSMike Christie enum { 64843c0a8aSMike Christie TMF_INITIAL, 65843c0a8aSMike Christie TMF_QUEUED, 66843c0a8aSMike Christie TMF_SUCCESS, 67843c0a8aSMike Christie TMF_FAILED, 68843c0a8aSMike Christie TMF_TIMEDOUT, 69843c0a8aSMike Christie TMF_NOT_FOUND, 70843c0a8aSMike Christie }; 717996a778SMike Christie 727996a778SMike Christie /* Connection suspend "bit" */ 737996a778SMike Christie #define ISCSI_SUSPEND_BIT 1 747996a778SMike Christie 757996a778SMike Christie #define ISCSI_ITT_MASK (0xfff) 767996a778SMike Christie #define ISCSI_AGE_SHIFT 28 777996a778SMike Christie #define ISCSI_AGE_MASK (0xf << ISCSI_AGE_SHIFT) 787996a778SMike Christie 7922236961SMike Christie #define ISCSI_ADDRESS_BUF_LEN 64 8022236961SMike Christie 81da32dd68SOlaf Kirch enum { 82004d6530SBoaz Harrosh /* this is the maximum possible storage for AHSs */ 83004d6530SBoaz Harrosh ISCSI_MAX_AHS_SIZE = sizeof(struct iscsi_ecdb_ahdr) + 84004d6530SBoaz Harrosh sizeof(struct iscsi_rlength_ahdr), 85da32dd68SOlaf Kirch ISCSI_DIGEST_SIZE = sizeof(__u32), 86da32dd68SOlaf Kirch }; 87da32dd68SOlaf Kirch 887996a778SMike Christie struct iscsi_mgmt_task { 897996a778SMike Christie /* 907996a778SMike Christie * Becuae LLDs allocate their hdr differently, this is a pointer to 917996a778SMike Christie * that storage. It must be setup at session creation time. 927996a778SMike Christie */ 937996a778SMike Christie struct iscsi_hdr *hdr; 947996a778SMike Christie char *data; /* mgmt payload */ 95857ae0bdSMike Christie unsigned data_count; /* counts data to be sent */ 967996a778SMike Christie uint32_t itt; /* this ITT */ 977996a778SMike Christie void *dd_data; /* driver/transport data */ 987996a778SMike Christie struct list_head running; 997996a778SMike Christie }; 1007996a778SMike Christie 101b6c395edSMike Christie enum { 102b6c395edSMike Christie ISCSI_TASK_COMPLETED, 103b6c395edSMike Christie ISCSI_TASK_PENDING, 104b6c395edSMike Christie ISCSI_TASK_RUNNING, 105b6c395edSMike Christie }; 106b6c395edSMike Christie 1077996a778SMike Christie struct iscsi_cmd_task { 1087996a778SMike Christie /* 109004d6530SBoaz Harrosh * Because LLDs allocate their hdr differently, this is a pointer 110004d6530SBoaz Harrosh * and length to that storage. It must be setup at session 111004d6530SBoaz Harrosh * creation time. 1127996a778SMike Christie */ 1137996a778SMike Christie struct iscsi_cmd *hdr; 114004d6530SBoaz Harrosh unsigned short hdr_max; 115004d6530SBoaz Harrosh unsigned short hdr_len; /* accumulated size of hdr used */ 1167996a778SMike Christie int itt; /* this ITT */ 1177996a778SMike Christie 1187996a778SMike Christie uint32_t unsol_datasn; 119857ae0bdSMike Christie unsigned imm_count; /* imm-data (bytes) */ 120857ae0bdSMike Christie unsigned unsol_count; /* unsolicited (bytes)*/ 121ffd0436eSMike Christie /* offset in unsolicited stream (bytes); */ 122857ae0bdSMike Christie unsigned unsol_offset; 123857ae0bdSMike Christie unsigned data_count; /* remaining Data-Out */ 1247996a778SMike Christie struct scsi_cmnd *sc; /* associated SCSI cmd*/ 1257996a778SMike Christie struct iscsi_conn *conn; /* used connection */ 1267996a778SMike Christie 127b6c395edSMike Christie /* state set/tested under session->lock */ 128b6c395edSMike Christie int state; 12960ecebf5SMike Christie atomic_t refcount; 1307996a778SMike Christie struct list_head running; /* running cmd list */ 1317996a778SMike Christie void *dd_data; /* driver/transport data */ 1327996a778SMike Christie }; 1337996a778SMike Christie 134004d6530SBoaz Harrosh static inline void* iscsi_next_hdr(struct iscsi_cmd_task *ctask) 135004d6530SBoaz Harrosh { 136004d6530SBoaz Harrosh return (void*)ctask->hdr + ctask->hdr_len; 137004d6530SBoaz Harrosh } 138004d6530SBoaz Harrosh 1396eabafbeSMike Christie /* Connection's states */ 1406eabafbeSMike Christie enum { 1416eabafbeSMike Christie ISCSI_CONN_INITIAL_STAGE, 1426eabafbeSMike Christie ISCSI_CONN_STARTED, 1436eabafbeSMike Christie ISCSI_CONN_STOPPED, 1446eabafbeSMike Christie ISCSI_CONN_CLEANUP_WAIT, 1456eabafbeSMike Christie }; 1466eabafbeSMike Christie 1477996a778SMike Christie struct iscsi_conn { 1487996a778SMike Christie struct iscsi_cls_conn *cls_conn; /* ptr to class connection */ 1497996a778SMike Christie void *dd_data; /* iscsi_transport data */ 1507996a778SMike Christie struct iscsi_session *session; /* parent session */ 1517996a778SMike Christie /* 1527996a778SMike Christie * LLDs should set this lock. It protects the transport recv 1537996a778SMike Christie * code 1547996a778SMike Christie */ 1557996a778SMike Christie rwlock_t *recv_lock; 1567996a778SMike Christie /* 1577996a778SMike Christie * conn_stop() flag: stop to recover, stop to terminate 1587996a778SMike Christie */ 1597996a778SMike Christie int stop_stage; 160f6d5180cSMike Christie struct timer_list transport_timer; 161f6d5180cSMike Christie unsigned long last_recv; 162f6d5180cSMike Christie unsigned long last_ping; 163f6d5180cSMike Christie int ping_timeout; 164f6d5180cSMike Christie int recv_timeout; 165f6d5180cSMike Christie struct iscsi_mgmt_task *ping_mtask; 1667996a778SMike Christie 1677996a778SMike Christie /* iSCSI connection-wide sequencing */ 1687996a778SMike Christie uint32_t exp_statsn; 1697996a778SMike Christie 1707996a778SMike Christie /* control data */ 1717996a778SMike Christie int id; /* CID */ 1727996a778SMike Christie int c_stage; /* connection state */ 173c8dc1e52SMike Christie /* 174c8dc1e52SMike Christie * Preallocated buffer for pdus that have data but do not 175c8dc1e52SMike Christie * originate from scsi-ml. We never have two pdus using the 176c8dc1e52SMike Christie * buffer at the same time. It is only allocated to 177c8dc1e52SMike Christie * the default max recv size because the pdus we support 178c8dc1e52SMike Christie * should always fit in this buffer 179c8dc1e52SMike Christie */ 180c8dc1e52SMike Christie char *data; 1817996a778SMike Christie struct iscsi_mgmt_task *login_mtask; /* mtask used for login/text */ 1827996a778SMike Christie struct iscsi_mgmt_task *mtask; /* xmit mtask in progress */ 1837996a778SMike Christie struct iscsi_cmd_task *ctask; /* xmit ctask in progress */ 1847996a778SMike Christie 1857996a778SMike Christie /* xmit */ 186843c0a8aSMike Christie struct list_head mgmtqueue; /* mgmt (control) xmit queue */ 1877996a778SMike Christie struct list_head mgmt_run_list; /* list of control tasks */ 188b6c395edSMike Christie struct list_head xmitqueue; /* data-path cmd queue */ 1897996a778SMike Christie struct list_head run_list; /* list of cmds in progress */ 190843c0a8aSMike Christie struct list_head requeue; /* tasks needing another run */ 1917996a778SMike Christie struct work_struct xmitwork; /* per-conn. xmit workqueue */ 1927996a778SMike Christie unsigned long suspend_tx; /* suspend Tx */ 1937996a778SMike Christie unsigned long suspend_rx; /* suspend Rx */ 1947996a778SMike Christie 1957996a778SMike Christie /* abort */ 1967996a778SMike Christie wait_queue_head_t ehwait; /* used in eh_abort() */ 1977996a778SMike Christie struct iscsi_tm tmhdr; 198843c0a8aSMike Christie struct timer_list tmf_timer; 199843c0a8aSMike Christie int tmf_state; /* see TMF_INITIAL, etc.*/ 2007996a778SMike Christie 2017996a778SMike Christie /* negotiated params */ 202857ae0bdSMike Christie unsigned max_recv_dlength; /* initiator_max_recv_dsl*/ 203857ae0bdSMike Christie unsigned max_xmit_dlength; /* target_max_recv_dsl */ 2047996a778SMike Christie int hdrdgst_en; 2057996a778SMike Christie int datadgst_en; 206a54a52caSMike Christie int ifmarker_en; 207a54a52caSMike Christie int ofmarker_en; 208a54a52caSMike Christie /* values userspace uses to id a conn */ 209a54a52caSMike Christie int persistent_port; 210a54a52caSMike Christie char *persistent_address; 21122236961SMike Christie /* remote portal currently connected to */ 21222236961SMike Christie int portal_port; 21322236961SMike Christie char portal_address[ISCSI_ADDRESS_BUF_LEN]; 2147996a778SMike Christie 2157996a778SMike Christie /* MIB-statistics */ 2167996a778SMike Christie uint64_t txdata_octets; 2177996a778SMike Christie uint64_t rxdata_octets; 2187996a778SMike Christie uint32_t scsicmd_pdus_cnt; 2197996a778SMike Christie uint32_t dataout_pdus_cnt; 2207996a778SMike Christie uint32_t scsirsp_pdus_cnt; 2217996a778SMike Christie uint32_t datain_pdus_cnt; 2227996a778SMike Christie uint32_t r2t_pdus_cnt; 2237996a778SMike Christie uint32_t tmfcmd_pdus_cnt; 2247996a778SMike Christie int32_t tmfrsp_pdus_cnt; 2257996a778SMike Christie 2267996a778SMike Christie /* custom statistics */ 2277996a778SMike Christie uint32_t eh_abort_cnt; 22887528227SEli Dorfman uint32_t fmr_unalign_cnt; 2297996a778SMike Christie }; 2307996a778SMike Christie 2316320377fSOlaf Kirch struct iscsi_pool { 2327996a778SMike Christie struct kfifo *queue; /* FIFO Queue */ 2337996a778SMike Christie void **pool; /* Pool of elements */ 2347996a778SMike Christie int max; /* Max number of elements */ 2357996a778SMike Christie }; 2367996a778SMike Christie 2376eabafbeSMike Christie /* Session's states */ 2386eabafbeSMike Christie enum { 2396eabafbeSMike Christie ISCSI_STATE_FREE = 1, 2406eabafbeSMike Christie ISCSI_STATE_LOGGED_IN, 2416eabafbeSMike Christie ISCSI_STATE_FAILED, 2426eabafbeSMike Christie ISCSI_STATE_TERMINATE, 2436eabafbeSMike Christie ISCSI_STATE_IN_RECOVERY, 2446eabafbeSMike Christie ISCSI_STATE_RECOVERY_FAILED, 2456eabafbeSMike Christie ISCSI_STATE_LOGGING_OUT, 2466eabafbeSMike Christie }; 2476eabafbeSMike Christie 2487996a778SMike Christie struct iscsi_session { 24975613521SMike Christie struct iscsi_cls_session *cls_session; 2506724add1SMike Christie /* 2516724add1SMike Christie * Syncs up the scsi eh thread with the iscsi eh thread when sending 2526724add1SMike Christie * task management functions. This must be taken before the session 2536724add1SMike Christie * and recv lock. 2546724add1SMike Christie */ 2556724add1SMike Christie struct mutex eh_mutex; 2566724add1SMike Christie 2577996a778SMike Christie /* iSCSI session-wide sequencing */ 2587996a778SMike Christie uint32_t cmdsn; 2597996a778SMike Christie uint32_t exp_cmdsn; 2607996a778SMike Christie uint32_t max_cmdsn; 2617996a778SMike Christie 262e0726407SMike Christie /* This tracks the reqs queued into the initiator */ 263e0726407SMike Christie uint32_t queued_cmdsn; 264e0726407SMike Christie 2657996a778SMike Christie /* configuration */ 266f6d5180cSMike Christie int abort_timeout; 267f6d5180cSMike Christie int lu_reset_timeout; 2687996a778SMike Christie int initial_r2t_en; 269857ae0bdSMike Christie unsigned max_r2t; 2707996a778SMike Christie int imm_data_en; 271857ae0bdSMike Christie unsigned first_burst; 272857ae0bdSMike Christie unsigned max_burst; 2737996a778SMike Christie int time2wait; 2747996a778SMike Christie int time2retain; 2757996a778SMike Christie int pdu_inorder_en; 2767996a778SMike Christie int dataseq_inorder_en; 2777996a778SMike Christie int erl; 278843c0a8aSMike Christie int fast_abort; 279a54a52caSMike Christie int tpgt; 280b2c64167SMike Christie char *username; 281b2c64167SMike Christie char *username_in; 282b2c64167SMike Christie char *password; 283b2c64167SMike Christie char *password_in; 284a54a52caSMike Christie char *targetname; 2857996a778SMike Christie /* control data */ 2867996a778SMike Christie struct iscsi_transport *tt; 2877996a778SMike Christie struct Scsi_Host *host; 2887996a778SMike Christie struct iscsi_conn *leadconn; /* leading connection */ 2897996a778SMike Christie spinlock_t lock; /* protects session state, * 2907996a778SMike Christie * sequence numbers, * 2917996a778SMike Christie * session resources: * 2927996a778SMike Christie * - cmdpool, * 2937996a778SMike Christie * - mgmtpool, * 2947996a778SMike Christie * - r2tpool */ 2957996a778SMike Christie int state; /* session state */ 2967996a778SMike Christie int age; /* counts session re-opens */ 2977996a778SMike Christie 2987996a778SMike Christie int cmds_max; /* size of cmds array */ 2997996a778SMike Christie struct iscsi_cmd_task **cmds; /* Original Cmds arr */ 3006320377fSOlaf Kirch struct iscsi_pool cmdpool; /* PDU's pool */ 3017996a778SMike Christie int mgmtpool_max; /* size of mgmt array */ 3027996a778SMike Christie struct iscsi_mgmt_task **mgmt_cmds; /* Original mgmt arr */ 3036320377fSOlaf Kirch struct iscsi_pool mgmtpool; /* Mgmt PDU's pool */ 3047996a778SMike Christie }; 3057996a778SMike Christie 30675613521SMike Christie struct iscsi_host { 30775613521SMike Christie char *initiatorname; 30875613521SMike Christie /* hw address or netdev iscsi connection is bound to */ 30975613521SMike Christie char *hwaddress; 31075613521SMike Christie char *netdev; 31175613521SMike Christie /* local address */ 31275613521SMike Christie int local_port; 31375613521SMike Christie char local_address[ISCSI_ADDRESS_BUF_LEN]; 31475613521SMike Christie }; 31575613521SMike Christie 3167996a778SMike Christie /* 3177996a778SMike Christie * scsi host template 3187996a778SMike Christie */ 3197996a778SMike Christie extern int iscsi_change_queue_depth(struct scsi_device *sdev, int depth); 3207996a778SMike Christie extern int iscsi_eh_abort(struct scsi_cmnd *sc); 3217996a778SMike Christie extern int iscsi_eh_host_reset(struct scsi_cmnd *sc); 322843c0a8aSMike Christie extern int iscsi_eh_device_reset(struct scsi_cmnd *sc); 3237996a778SMike Christie extern int iscsi_queuecommand(struct scsi_cmnd *sc, 3247996a778SMike Christie void (*done)(struct scsi_cmnd *)); 3257996a778SMike Christie 3260801c242SMike Christie /* 3270801c242SMike Christie * iSCSI host helpers. 3280801c242SMike Christie */ 3295d91e209SMike Christie #define iscsi_host_priv(_shost) \ 3305d91e209SMike Christie (shost_priv(_shost) + sizeof(struct iscsi_host)) 3315d91e209SMike Christie 3320801c242SMike Christie extern int iscsi_host_set_param(struct Scsi_Host *shost, 3330801c242SMike Christie enum iscsi_host_param param, char *buf, 3340801c242SMike Christie int buflen); 3350801c242SMike Christie extern int iscsi_host_get_param(struct Scsi_Host *shost, 3360801c242SMike Christie enum iscsi_host_param param, char *buf); 337a4804cd6SMike Christie extern int iscsi_host_add(struct Scsi_Host *shost, struct device *pdev); 338a4804cd6SMike Christie extern struct Scsi_Host *iscsi_host_alloc(struct scsi_host_template *sht, 339a4804cd6SMike Christie int dd_data_size, uint16_t qdepth); 340a4804cd6SMike Christie extern void iscsi_host_remove(struct Scsi_Host *shost); 341a4804cd6SMike Christie extern void iscsi_host_free(struct Scsi_Host *shost); 3420801c242SMike Christie 3437996a778SMike Christie /* 3447996a778SMike Christie * session management 3457996a778SMike Christie */ 3467996a778SMike Christie extern struct iscsi_cls_session * 34775613521SMike Christie iscsi_session_setup(struct iscsi_transport *, struct Scsi_Host *shost, 34875613521SMike Christie uint16_t, int, int, uint32_t); 3497996a778SMike Christie extern void iscsi_session_teardown(struct iscsi_cls_session *); 3507996a778SMike Christie extern void iscsi_session_recovery_timedout(struct iscsi_cls_session *); 351a54a52caSMike Christie extern int iscsi_set_param(struct iscsi_cls_conn *cls_conn, 352a54a52caSMike Christie enum iscsi_param param, char *buf, int buflen); 353a54a52caSMike Christie extern int iscsi_session_get_param(struct iscsi_cls_session *cls_session, 354a54a52caSMike Christie enum iscsi_param param, char *buf); 3557996a778SMike Christie 356322d739dSMike Christie #define iscsi_session_printk(prefix, _sess, fmt, a...) \ 35775613521SMike Christie iscsi_cls_session_printk(prefix, _sess->cls_session, fmt, ##a) 358322d739dSMike Christie 3597996a778SMike Christie /* 3607996a778SMike Christie * connection management 3617996a778SMike Christie */ 3627996a778SMike Christie extern struct iscsi_cls_conn *iscsi_conn_setup(struct iscsi_cls_session *, 3635d91e209SMike Christie int, uint32_t); 3647996a778SMike Christie extern void iscsi_conn_teardown(struct iscsi_cls_conn *); 3657996a778SMike Christie extern int iscsi_conn_start(struct iscsi_cls_conn *); 3667996a778SMike Christie extern void iscsi_conn_stop(struct iscsi_cls_conn *, int); 3677996a778SMike Christie extern int iscsi_conn_bind(struct iscsi_cls_session *, struct iscsi_cls_conn *, 3687996a778SMike Christie int); 3697996a778SMike Christie extern void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err); 370a54a52caSMike Christie extern int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn, 371a54a52caSMike Christie enum iscsi_param param, char *buf); 372*5af3e91dSMike Christie extern void iscsi_suspend_tx(struct iscsi_conn *conn); 3737996a778SMike Christie 374322d739dSMike Christie #define iscsi_conn_printk(prefix, _c, fmt, a...) \ 375*5af3e91dSMike Christie iscsi_cls_conn_printk(prefix, ((struct iscsi_conn *)_c)->cls_conn, \ 376*5af3e91dSMike Christie fmt, ##a) 377322d739dSMike Christie 3787996a778SMike Christie /* 3797996a778SMike Christie * pdu and task processing 3807996a778SMike Christie */ 38177a23c21SMike Christie extern void iscsi_update_cmdsn(struct iscsi_session *, struct iscsi_nopin *); 3827996a778SMike Christie extern void iscsi_prep_unsolicit_data_pdu(struct iscsi_cmd_task *, 383ffd0436eSMike Christie struct iscsi_data *hdr); 3847996a778SMike Christie extern int iscsi_conn_send_pdu(struct iscsi_cls_conn *, struct iscsi_hdr *, 3857996a778SMike Christie char *, uint32_t); 3867996a778SMike Christie extern int iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *, 3877996a778SMike Christie char *, int); 3887996a778SMike Christie extern int iscsi_verify_itt(struct iscsi_conn *, struct iscsi_hdr *, 3897996a778SMike Christie uint32_t *); 390843c0a8aSMike Christie extern void iscsi_requeue_ctask(struct iscsi_cmd_task *ctask); 391b3a7ea8dSMike Christie extern void iscsi_free_mgmt_task(struct iscsi_conn *conn, 392b3a7ea8dSMike Christie struct iscsi_mgmt_task *mtask); 3937996a778SMike Christie 3947996a778SMike Christie /* 3957996a778SMike Christie * generic helpers 3967996a778SMike Christie */ 3976320377fSOlaf Kirch extern void iscsi_pool_free(struct iscsi_pool *); 3986320377fSOlaf Kirch extern int iscsi_pool_init(struct iscsi_pool *, int, void ***, int); 3997996a778SMike Christie 400004d6530SBoaz Harrosh /* 401004d6530SBoaz Harrosh * inline functions to deal with padding. 402004d6530SBoaz Harrosh */ 403004d6530SBoaz Harrosh static inline unsigned int 404004d6530SBoaz Harrosh iscsi_padded(unsigned int len) 405004d6530SBoaz Harrosh { 406004d6530SBoaz Harrosh return (len + ISCSI_PAD_LEN - 1) & ~(ISCSI_PAD_LEN - 1); 407004d6530SBoaz Harrosh } 408004d6530SBoaz Harrosh 409004d6530SBoaz Harrosh static inline unsigned int 410004d6530SBoaz Harrosh iscsi_padding(unsigned int len) 411004d6530SBoaz Harrosh { 412004d6530SBoaz Harrosh len &= (ISCSI_PAD_LEN - 1); 413004d6530SBoaz Harrosh if (len) 414004d6530SBoaz Harrosh len = ISCSI_PAD_LEN - len; 415004d6530SBoaz Harrosh return len; 416004d6530SBoaz Harrosh } 417004d6530SBoaz Harrosh 4187996a778SMike Christie #endif 419