[SCSI] iscsi_tcp: make padbuf non-static
[safe/jmp/linux-2.6] / include / scsi / libiscsi.h
index 8a6271c..7360e19 100644 (file)
 #include <linux/workqueue.h>
 #include <scsi/iscsi_proto.h>
 #include <scsi/iscsi_if.h>
+#include <scsi/scsi_transport_iscsi.h>
 
 struct scsi_transport_template;
+struct scsi_host_template;
 struct scsi_device;
 struct Scsi_Host;
 struct scsi_cmnd;
@@ -41,6 +43,7 @@ struct iscsi_cls_session;
 struct iscsi_cls_conn;
 struct iscsi_session;
 struct iscsi_nopin;
+struct device;
 
 /* #define DEBUG_SCSI */
 #ifdef DEBUG_SCSI
@@ -50,9 +53,7 @@ struct iscsi_nopin;
 #endif
 
 #define ISCSI_DEF_XMIT_CMDS_MAX        128     /* must be power of 2 */
-#define ISCSI_MGMT_CMDS_MAX    16      /* must be power of 2 */
-
-#define ISCSI_MGMT_ITT_OFFSET  0xa00
+#define ISCSI_MGMT_CMDS_MAX    15
 
 #define ISCSI_DEF_CMD_PER_LUN          32
 #define ISCSI_MAX_CMD_PER_LUN          128
@@ -70,9 +71,12 @@ enum {
 /* Connection suspend "bit" */
 #define ISCSI_SUSPEND_BIT              1
 
-#define ISCSI_ITT_MASK                 (0xfff)
+#define ISCSI_ITT_MASK                 0x1fff
+#define ISCSI_TOTAL_CMDS_MAX           4096
+/* this must be a power of two greater than ISCSI_MGMT_CMDS_MAX */
+#define ISCSI_TOTAL_CMDS_MIN           16
 #define ISCSI_AGE_SHIFT                        28
-#define ISCSI_AGE_MASK                 (0xf << ISCSI_AGE_SHIFT)
+#define ISCSI_AGE_MASK                 0xf
 
 #define ISCSI_ADDRESS_BUF_LEN          64
 
@@ -83,18 +87,6 @@ enum {
        ISCSI_DIGEST_SIZE = sizeof(__u32),
 };
 
-struct iscsi_mgmt_task {
-       /*
-        * Becuae LLDs allocate their hdr differently, this is a pointer to
-        * that storage. It must be setup at session creation time.
-        */
-       struct iscsi_hdr        *hdr;
-       char                    *data;          /* mgmt payload */
-       unsigned                data_count;     /* counts data to be sent */
-       uint32_t                itt;            /* this ITT */
-       void                    *dd_data;       /* driver/transport data */
-       struct list_head        running;
-};
 
 enum {
        ISCSI_TASK_COMPLETED,
@@ -102,23 +94,38 @@ enum {
        ISCSI_TASK_RUNNING,
 };
 
-struct iscsi_cmd_task {
+struct iscsi_r2t_info {
+       __be32                  ttt;            /* copied from R2T */
+       __be32                  exp_statsn;     /* copied from R2T */
+       uint32_t                data_length;    /* copied from R2T */
+       uint32_t                data_offset;    /* copied from R2T */
+       int                     data_count;     /* DATA-Out payload progress */
+       int                     datasn;
+       /* LLDs should set/update these values */
+       int                     sent;           /* R2T sequence progress */
+};
+
+struct iscsi_task {
        /*
         * 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;
+       struct iscsi_hdr        *hdr;
        unsigned short          hdr_max;
        unsigned short          hdr_len;        /* accumulated size of hdr used */
+       /* copied values in case we need to send tmfs */
+       itt_t                   hdr_itt;
+       __be32                  cmdsn;
+       uint8_t                 lun[8];
+
        int                     itt;            /* this ITT */
 
-       uint32_t                unsol_datasn;
        unsigned                imm_count;      /* imm-data (bytes)   */
-       unsigned                unsol_count;    /* unsolicited (bytes)*/
        /* offset in unsolicited stream (bytes); */
-       unsigned                unsol_offset;
-       unsigned                data_count;     /* remaining Data-Out */
+       struct iscsi_r2t_info   unsol_r2t;
+       char                    *data;          /* mgmt payload */
+       unsigned                data_count;
        struct scsi_cmnd        *sc;            /* associated SCSI cmd*/
        struct iscsi_conn       *conn;          /* used connection    */
 
@@ -129,9 +136,14 @@ struct iscsi_cmd_task {
        void                    *dd_data;       /* driver/transport data */
 };
 
-static inline void* iscsi_next_hdr(struct iscsi_cmd_task *ctask)
+static inline int iscsi_task_has_unsol_data(struct iscsi_task *task)
 {
-       return (void*)ctask->hdr + ctask->hdr_len;
+       return task->unsol_r2t.data_length > task->unsol_r2t.sent;
+}
+
+static inline void* iscsi_next_hdr(struct iscsi_task *task)
+{
+       return (void*)task->hdr + task->hdr_len;
 }
 
 /* Connection's states */
@@ -147,11 +159,6 @@ struct iscsi_conn {
        void                    *dd_data;       /* iscsi_transport data */
        struct iscsi_session    *session;       /* parent session */
        /*
-        * LLDs should set this lock. It protects the transport recv
-        * code
-        */
-       rwlock_t                *recv_lock;
-       /*
         * conn_stop() flag: stop to recover, stop to terminate
         */
         int                    stop_stage;
@@ -160,7 +167,7 @@ struct iscsi_conn {
        unsigned long           last_ping;
        int                     ping_timeout;
        int                     recv_timeout;
-       struct iscsi_mgmt_task  *ping_mtask;
+       struct iscsi_task       *ping_task;
 
        /* iSCSI connection-wide sequencing */
        uint32_t                exp_statsn;
@@ -176,9 +183,8 @@ struct iscsi_conn {
         * should always fit in this buffer
         */
        char                    *data;
-       struct iscsi_mgmt_task  *login_mtask;   /* mtask used for login/text */
-       struct iscsi_mgmt_task  *mtask;         /* xmit mtask in progress */
-       struct iscsi_cmd_task   *ctask;         /* xmit ctask in progress */
+       struct iscsi_task       *login_task;    /* mtask used for login/text */
+       struct iscsi_task       *task;          /* xmit task in progress */
 
        /* xmit */
        struct list_head        mgmtqueue;      /* mgmt (control) xmit queue */
@@ -280,6 +286,8 @@ struct iscsi_session {
        char                    *password;
        char                    *password_in;
        char                    *targetname;
+       char                    *ifacename;
+       char                    *initiatorname;
        /* control data */
        struct iscsi_transport  *tt;
        struct Scsi_Host        *host;
@@ -293,12 +301,15 @@ struct iscsi_session {
        int                     state;          /* session state           */
        int                     age;            /* counts session re-opens */
 
+       int                     scsi_cmds_max;  /* max scsi commands */
        int                     cmds_max;       /* size of cmds array */
-       struct iscsi_cmd_task   **cmds;         /* Original Cmds arr */
+       struct iscsi_task       **cmds;         /* Original Cmds arr */
        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_pool       mgmtpool;       /* Mgmt PDU's pool */
+};
+
+enum {
+       ISCSI_HOST_SETUP,
+       ISCSI_HOST_REMOVED,
 };
 
 struct iscsi_host {
@@ -309,6 +320,12 @@ struct iscsi_host {
        /* local address */
        int                     local_port;
        char                    local_address[ISCSI_ADDRESS_BUF_LEN];
+
+       wait_queue_head_t       session_removal_wq;
+       /* protects sessions and state */
+       spinlock_t              lock;
+       int                     num_sessions;
+       int                     state;
 };
 
 /*
@@ -316,29 +333,34 @@ struct iscsi_host {
  */
 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_target_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 *));
 
-
 /*
  * iSCSI host helpers.
  */
+#define iscsi_host_priv(_shost) \
+       (shost_priv(_shost) + sizeof(struct iscsi_host))
+
 extern int iscsi_host_set_param(struct Scsi_Host *shost,
                                enum iscsi_host_param param, char *buf,
                                int buflen);
 extern int iscsi_host_get_param(struct Scsi_Host *shost,
                                enum iscsi_host_param param, char *buf);
-extern void iscsi_host_setup(struct Scsi_Host *shost, uint16_t qdepth);
-extern void iscsi_host_teardown(struct Scsi_Host *shost);
+extern int iscsi_host_add(struct Scsi_Host *shost, struct device *pdev);
+extern struct Scsi_Host *iscsi_host_alloc(struct scsi_host_template *sht,
+                                         int dd_data_size, uint16_t qdepth);
+extern void iscsi_host_remove(struct Scsi_Host *shost);
+extern void iscsi_host_free(struct Scsi_Host *shost);
 
 /*
  * session management
  */
 extern struct iscsi_cls_session *
 iscsi_session_setup(struct iscsi_transport *, struct Scsi_Host *shost,
-                   uint16_t, int, int, uint32_t);
+                   uint16_t, int, uint32_t, unsigned int);
 extern void iscsi_session_teardown(struct iscsi_cls_session *);
 extern void iscsi_session_recovery_timedout(struct iscsi_cls_session *);
 extern int iscsi_set_param(struct iscsi_cls_conn *cls_conn,
@@ -353,34 +375,41 @@ extern int iscsi_session_get_param(struct iscsi_cls_session *cls_session,
  * connection management
  */
 extern struct iscsi_cls_conn *iscsi_conn_setup(struct iscsi_cls_session *,
-                                              uint32_t);
+                                              int, uint32_t);
 extern void iscsi_conn_teardown(struct iscsi_cls_conn *);
 extern int iscsi_conn_start(struct iscsi_cls_conn *);
 extern void iscsi_conn_stop(struct iscsi_cls_conn *, int);
 extern int iscsi_conn_bind(struct iscsi_cls_session *, struct iscsi_cls_conn *,
                           int);
 extern void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err);
+extern void iscsi_session_failure(struct iscsi_cls_session *cls_session,
+                                 enum iscsi_err err);
 extern int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn,
                                enum iscsi_param param, char *buf);
+extern void iscsi_suspend_tx(struct iscsi_conn *conn);
 
 #define iscsi_conn_printk(prefix, _c, fmt, a...) \
-       iscsi_cls_conn_printk(prefix, _c->cls_conn, fmt, ##a)
+       iscsi_cls_conn_printk(prefix, ((struct iscsi_conn *)_c)->cls_conn, \
+                             fmt, ##a)
 
 /*
  * pdu and task processing
  */
 extern void iscsi_update_cmdsn(struct iscsi_session *, struct iscsi_nopin *);
-extern void iscsi_prep_unsolicit_data_pdu(struct iscsi_cmd_task *,
-                                       struct iscsi_data *hdr);
+extern void iscsi_prep_data_out_pdu(struct iscsi_task *task,
+                                   struct iscsi_r2t_info *r2t,
+                                   struct iscsi_data *hdr);
 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_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);
+extern int __iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *,
+                               char *, int);
+extern int iscsi_verify_itt(struct iscsi_conn *, itt_t);
+extern struct iscsi_task *iscsi_itt_to_ctask(struct iscsi_conn *, itt_t);
+extern void iscsi_requeue_task(struct iscsi_task *task);
+extern void iscsi_put_task(struct iscsi_task *task);
+extern void __iscsi_get_task(struct iscsi_task *task);
 
 /*
  * generic helpers