X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=include%2Fscsi%2Flibiscsi.h;h=278011fb3c2fd5612a6cd1916583f46fc9ad57da;hb=6eabafbe6616266e8de61980a7dac5ecc1ba1113;hp=007d442412e2224a987bb36145e6f4f771a4760d;hpb=2f63251ed0a803ddbe7bf2577b69d467aa872f68;p=linux-2.6 diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index 007d442412..278011fb3c 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h @@ -57,11 +57,14 @@ struct iscsi_nopin; #define ISCSI_MAX_CMD_PER_LUN 128 /* Task Mgmt states */ -#define TMABORT_INITIAL 0x0 -#define TMABORT_SUCCESS 0x1 -#define TMABORT_FAILED 0x2 -#define TMABORT_TIMEDOUT 0x3 -#define TMABORT_NOT_FOUND 0x4 +enum { + TMF_INITIAL, + TMF_QUEUED, + TMF_SUCCESS, + TMF_FAILED, + TMF_TIMEDOUT, + TMF_NOT_FOUND, +}; /* Connection suspend "bit" */ #define ISCSI_SUSPEND_BIT 1 @@ -74,6 +77,13 @@ struct iscsi_nopin; #define ISCSI_ADDRESS_BUF_LEN 64 +enum { + /* this is the maximum possible storage for AHSs */ + ISCSI_MAX_AHS_SIZE = sizeof(struct iscsi_ecdb_ahdr) + + sizeof(struct iscsi_rlength_ahdr), + ISCSI_DIGEST_SIZE = sizeof(__u32), +}; + struct iscsi_mgmt_task { /* * Becuae LLDs allocate their hdr differently, this is a pointer to @@ -91,15 +101,17 @@ enum { ISCSI_TASK_COMPLETED, ISCSI_TASK_PENDING, ISCSI_TASK_RUNNING, - ISCSI_TASK_ABORTING, }; struct iscsi_cmd_task { /* - * Becuae LLDs allocate their hdr differently, this is a pointer to - * that storage. It must be setup at session creation time. + * Because LLDs allocate their hdr differently, this is a pointer + * and length to that storage. It must be setup at session + * creation time. */ struct iscsi_cmd *hdr; + unsigned short hdr_max; + unsigned short hdr_len; /* accumulated size of hdr used */ int itt; /* this ITT */ uint32_t unsol_datasn; @@ -110,7 +122,6 @@ struct iscsi_cmd_task { unsigned data_count; /* remaining Data-Out */ struct scsi_cmnd *sc; /* associated SCSI cmd*/ struct iscsi_conn *conn; /* used connection */ - struct iscsi_mgmt_task *mtask; /* tmf mtask in progr */ /* state set/tested under session->lock */ int state; @@ -119,6 +130,19 @@ struct iscsi_cmd_task { void *dd_data; /* driver/transport data */ }; +static inline void* iscsi_next_hdr(struct iscsi_cmd_task *ctask) +{ + return (void*)ctask->hdr + ctask->hdr_len; +} + +/* Connection's states */ +enum { + ISCSI_CONN_INITIAL_STAGE, + ISCSI_CONN_STARTED, + ISCSI_CONN_STOPPED, + ISCSI_CONN_CLEANUP_WAIT, +}; + struct iscsi_conn { struct iscsi_cls_conn *cls_conn; /* ptr to class connection */ void *dd_data; /* iscsi_transport data */ @@ -132,6 +156,12 @@ struct iscsi_conn { * conn_stop() flag: stop to recover, stop to terminate */ int stop_stage; + struct timer_list transport_timer; + unsigned long last_recv; + unsigned long last_ping; + int ping_timeout; + int recv_timeout; + struct iscsi_mgmt_task *ping_mtask; /* iSCSI connection-wide sequencing */ uint32_t exp_statsn; @@ -152,10 +182,11 @@ struct iscsi_conn { struct iscsi_cmd_task *ctask; /* xmit ctask in progress */ /* xmit */ - struct kfifo *mgmtqueue; /* mgmt (control) xmit queue */ + struct list_head mgmtqueue; /* mgmt (control) xmit queue */ struct list_head mgmt_run_list; /* list of control tasks */ struct list_head xmitqueue; /* data-path cmd queue */ struct list_head run_list; /* list of cmds in progress */ + struct list_head requeue; /* tasks needing another run */ struct work_struct xmitwork; /* per-conn. xmit workqueue */ unsigned long suspend_tx; /* suspend Tx */ unsigned long suspend_rx; /* suspend Rx */ @@ -163,8 +194,8 @@ struct iscsi_conn { /* abort */ wait_queue_head_t ehwait; /* used in eh_abort() */ struct iscsi_tm tmhdr; - struct timer_list tmabort_timer; - int tmabort_state; /* see TMABORT_INITIAL, etc.*/ + struct timer_list tmf_timer; + int tmf_state; /* see TMF_INITIAL, etc.*/ /* negotiated params */ unsigned max_recv_dlength; /* initiator_max_recv_dsl*/ @@ -198,13 +229,31 @@ struct iscsi_conn { uint32_t eh_abort_cnt; }; -struct iscsi_queue { +struct iscsi_pool { struct kfifo *queue; /* FIFO Queue */ void **pool; /* Pool of elements */ int max; /* Max number of elements */ }; +/* Session's states */ +enum { + ISCSI_STATE_FREE = 1, + ISCSI_STATE_LOGGED_IN, + ISCSI_STATE_FAILED, + ISCSI_STATE_TERMINATE, + ISCSI_STATE_IN_RECOVERY, + ISCSI_STATE_RECOVERY_FAILED, + ISCSI_STATE_LOGGING_OUT, +}; + struct iscsi_session { + /* + * Syncs up the scsi eh thread with the iscsi eh thread when sending + * task management functions. This must be taken before the session + * and recv lock. + */ + struct mutex eh_mutex; + /* iSCSI session-wide sequencing */ uint32_t cmdsn; uint32_t exp_cmdsn; @@ -214,6 +263,8 @@ struct iscsi_session { uint32_t queued_cmdsn; /* configuration */ + int abort_timeout; + int lu_reset_timeout; int initial_r2t_en; unsigned max_r2t; int imm_data_en; @@ -224,6 +275,7 @@ struct iscsi_session { int pdu_inorder_en; int dataseq_inorder_en; int erl; + int fast_abort; int tpgt; char *username; char *username_in; @@ -249,10 +301,10 @@ struct iscsi_session { int cmds_max; /* size of cmds array */ struct iscsi_cmd_task **cmds; /* Original Cmds arr */ - struct iscsi_queue cmdpool; /* PDU's pool */ + struct iscsi_pool cmdpool; /* PDU's pool */ int mgmtpool_max; /* size of mgmt array */ struct iscsi_mgmt_task **mgmt_cmds; /* Original mgmt arr */ - struct iscsi_queue mgmtpool; /* Mgmt PDU's pool */ + struct iscsi_pool mgmtpool; /* Mgmt PDU's pool */ }; /* @@ -261,6 +313,7 @@ struct iscsi_session { extern int iscsi_change_queue_depth(struct scsi_device *sdev, int depth); extern int iscsi_eh_abort(struct scsi_cmnd *sc); extern int iscsi_eh_host_reset(struct scsi_cmnd *sc); +extern int iscsi_eh_device_reset(struct scsi_cmnd *sc); extern int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)); @@ -315,15 +368,34 @@ extern int iscsi_conn_send_pdu(struct iscsi_cls_conn *, struct iscsi_hdr *, char *, uint32_t); extern int iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *, char *, int); -extern int __iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *, - char *, int); extern int iscsi_verify_itt(struct iscsi_conn *, struct iscsi_hdr *, uint32_t *); +extern void iscsi_requeue_ctask(struct iscsi_cmd_task *ctask); +extern void iscsi_free_mgmt_task(struct iscsi_conn *conn, + struct iscsi_mgmt_task *mtask); /* * generic helpers */ -extern void iscsi_pool_free(struct iscsi_queue *, void **); -extern int iscsi_pool_init(struct iscsi_queue *, int, void ***, int); +extern void iscsi_pool_free(struct iscsi_pool *); +extern int iscsi_pool_init(struct iscsi_pool *, int, void ***, int); + +/* + * inline functions to deal with padding. + */ +static inline unsigned int +iscsi_padded(unsigned int len) +{ + return (len + ISCSI_PAD_LEN - 1) & ~(ISCSI_PAD_LEN - 1); +} + +static inline unsigned int +iscsi_padding(unsigned int len) +{ + len &= (ISCSI_PAD_LEN - 1); + if (len) + len = ISCSI_PAD_LEN - len; + return len; +} #endif