target: Make all control CDBs scatter-gather
[linux-2.6.git] / include / target / target_core_base.h
index b3a62e4..f67ca98 100644 (file)
@@ -9,7 +9,7 @@
 #include <net/sock.h>
 #include <net/tcp.h>
 
-#define TARGET_CORE_MOD_VERSION                "v4.0.0-rc6"
+#define TARGET_CORE_MOD_VERSION                "v4.0.0-rc7-ml"
 #define SHUTDOWN_SIGS  (sigmask(SIGKILL)|sigmask(SIGINT)|sigmask(SIGABRT))
 
 /* Used by transport_generic_allocate_iovecs() */
@@ -22,7 +22,7 @@
  * Note that both include/scsi/scsi_cmnd.h:MAX_COMMAND_SIZE and
  * include/linux/blkdev.h:BLOCK_MAX_CDB as of v2.6.36-rc4 still use
  * 16-byte CDBs by default and require an extra allocation for
- * 32-byte CDBs to becasue of legacy issues.
+ * 32-byte CDBs to because of legacy issues.
  *
  * Within TCM Core there are no such legacy limitiations, so we go ahead
  * use 32-byte CDBs by default and use include/scsi/scsi.h:scsi_command_size()
@@ -98,6 +98,8 @@ enum transport_state_table {
        TRANSPORT_REMOVE        = 14,
        TRANSPORT_FREE          = 15,
        TRANSPORT_NEW_CMD_MAP   = 16,
+       TRANSPORT_FREE_CMD_INTR = 17,
+       TRANSPORT_COMPLETE_QF_WP = 18,
 };
 
 /* Used for struct se_cmd->se_cmd_flags */
@@ -107,27 +109,22 @@ enum se_cmd_flags_table {
        SCF_EMULATED_TASK_SENSE         = 0x00000004,
        SCF_SCSI_DATA_SG_IO_CDB         = 0x00000008,
        SCF_SCSI_CONTROL_SG_IO_CDB      = 0x00000010,
-       SCF_SCSI_CONTROL_NONSG_IO_CDB   = 0x00000020,
        SCF_SCSI_NON_DATA_CDB           = 0x00000040,
        SCF_SCSI_CDB_EXCEPTION          = 0x00000080,
        SCF_SCSI_RESERVATION_CONFLICT   = 0x00000100,
-       SCF_CMD_PASSTHROUGH_NOALLOC     = 0x00000200,
        SCF_SE_CMD_FAILED               = 0x00000400,
        SCF_SE_LUN_CMD                  = 0x00000800,
        SCF_SE_ALLOW_EOO                = 0x00001000,
-       SCF_SE_DISABLE_ONLINE_CHECK     = 0x00002000,
        SCF_SENT_CHECK_CONDITION        = 0x00004000,
        SCF_OVERFLOW_BIT                = 0x00008000,
        SCF_UNDERFLOW_BIT               = 0x00010000,
        SCF_SENT_DELAYED_TAS            = 0x00020000,
        SCF_ALUA_NON_OPTIMIZED          = 0x00040000,
        SCF_DELAYED_CMD_FROM_SAM_ATTR   = 0x00080000,
-       SCF_PASSTHROUGH_SG_TO_MEM       = 0x00100000,
-       SCF_PASSTHROUGH_CONTIG_TO_SG    = 0x00200000,
+       SCF_UNUSED                      = 0x00100000,
        SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC = 0x00400000,
-       SCF_EMULATE_SYNC_CACHE          = 0x00800000,
        SCF_EMULATE_CDB_ASYNC           = 0x01000000,
-       SCF_EMULATE_SYNC_UNMAP          = 0x02000000
+       SCF_EMULATE_QUEUE_FULL          = 0x02000000,
 };
 
 /* struct se_dev_entry->lun_flags and struct se_lun->lun_access */
@@ -204,11 +201,6 @@ typedef enum {
        SCSI_INDEX_TYPE_MAX
 } scsi_index_t;
 
-struct scsi_index_table {
-       spinlock_t      lock;
-       u32             scsi_mib_index[SCSI_INDEX_TYPE_MAX];
-} ____cacheline_aligned;
-
 struct se_cmd;
 
 struct t10_alua {
@@ -234,7 +226,7 @@ struct t10_alua_lu_gp {
        atomic_t lu_gp_ref_cnt;
        spinlock_t lu_gp_lock;
        struct config_group lu_gp_group;
-       struct list_head lu_gp_list;
+       struct list_head lu_gp_node;
        struct list_head lu_gp_mem_list;
 } ____cacheline_aligned;
 
@@ -290,10 +282,10 @@ struct t10_vpd {
 } ____cacheline_aligned;
 
 struct t10_wwn {
-       unsigned char vendor[8];
-       unsigned char model[16];
-       unsigned char revision[4];
-       unsigned char unit_serial[INQUIRY_VPD_SERIAL_LEN];
+       char vendor[8];
+       char model[16];
+       char revision[4];
+       char unit_serial[INQUIRY_VPD_SERIAL_LEN];
        spinlock_t t10_vpd_lock;
        struct se_subsystem_dev *t10_sub_dev;
        struct config_group t10_wwn_group;
@@ -302,7 +294,7 @@ struct t10_wwn {
 
 
 /*
- * Used by TCM Core internally to signal if >= SPC-3 peristent reservations
+ * Used by TCM Core internally to signal if >= SPC-3 persistent reservations
  * emulation is enabled or disabled, or running in with TCM/pSCSI passthrough
  * mode
  */
@@ -365,13 +357,13 @@ struct t10_reservation_ops {
        int (*t10_pr_clear)(struct se_cmd *);
 };
 
-struct t10_reservation_template {
+struct t10_reservation {
        /* Reservation effects all target ports */
        int pr_all_tg_pt;
        /* Activate Persistence across Target Power Loss enabled
         * for SCSI device */
        int pr_aptpl_active;
-       /* Used by struct t10_reservation_template->pr_aptpl_buf_len */
+       /* Used by struct t10_reservation->pr_aptpl_buf_len */
 #define PR_APTPL_BUF_LEN                       8192
        u32 pr_aptpl_buf_len;
        u32 pr_generation;
@@ -396,7 +388,7 @@ struct t10_reservation_template {
 
 struct se_queue_req {
        int                     state;
-       void                    *cmd;
+       struct se_cmd           *cmd;
        struct list_head        qr_list;
 } ____cacheline_aligned;
 
@@ -407,64 +399,10 @@ struct se_queue_obj {
        wait_queue_head_t       thread_wq;
 } ____cacheline_aligned;
 
-/*
- * Used one per struct se_cmd to hold all extra struct se_task
- * metadata.  This structure is setup and allocated in
- * drivers/target/target_core_transport.c:__transport_alloc_se_cmd()
- */
-struct se_transport_task {
-       unsigned char           *t_task_cdb;
-       unsigned char           __t_task_cdb[TCM_MAX_COMMAND_SIZE];
-       unsigned long long      t_task_lba;
-       int                     t_tasks_failed;
-       int                     t_tasks_fua;
-       bool                    t_tasks_bidi;
-       u32                     t_task_cdbs;
-       u32                     t_tasks_check;
-       u32                     t_tasks_no;
-       u32                     t_tasks_sectors;
-       u32                     t_tasks_se_num;
-       u32                     t_tasks_se_bidi_num;
-       u32                     t_tasks_sg_chained_no;
-       atomic_t                t_fe_count;
-       atomic_t                t_se_count;
-       atomic_t                t_task_cdbs_left;
-       atomic_t                t_task_cdbs_ex_left;
-       atomic_t                t_task_cdbs_timeout_left;
-       atomic_t                t_task_cdbs_sent;
-       atomic_t                t_transport_aborted;
-       atomic_t                t_transport_active;
-       atomic_t                t_transport_complete;
-       atomic_t                t_transport_queue_active;
-       atomic_t                t_transport_sent;
-       atomic_t                t_transport_stop;
-       atomic_t                t_transport_timeout;
-       atomic_t                transport_dev_active;
-       atomic_t                transport_lun_active;
-       atomic_t                transport_lun_fe_stop;
-       atomic_t                transport_lun_stop;
-       spinlock_t              t_state_lock;
-       struct completion       t_transport_stop_comp;
-       struct completion       transport_lun_fe_stop_comp;
-       struct completion       transport_lun_stop_comp;
-       struct scatterlist      *t_tasks_sg_chained;
-       struct scatterlist      t_tasks_sg_bounce;
-       void                    *t_task_buf;
-       /*
-        * Used for pre-registered fabric SGL passthrough WRITE and READ
-        * with the special SCF_PASSTHROUGH_CONTIG_TO_SG case for TCM_Loop
-        * and other HW target mode fabric modules.
-        */
-       struct scatterlist      *t_task_pt_sgl;
-       struct list_head        *t_mem_list;
-       /* Used for BIDI READ */
-       struct list_head        *t_mem_bidi_list;
-       struct list_head        t_task_list;
-} ____cacheline_aligned;
-
 struct se_task {
        unsigned char   task_sense;
        struct scatterlist *task_sg;
+       u32             task_sg_num;
        struct scatterlist *task_sg_bidi;
        u8              task_scsi_status;
        u8              task_flags;
@@ -475,8 +413,6 @@ struct se_task {
        u32             task_no;
        u32             task_sectors;
        u32             task_size;
-       u32             task_sg_num;
-       u32             task_sg_offset;
        enum dma_data_direction task_data_direction;
        struct se_cmd *task_se_cmd;
        struct se_device        *se_dev;
@@ -494,9 +430,6 @@ struct se_task {
        struct list_head t_state_list;
 } ____cacheline_aligned;
 
-#define TASK_CMD(task) ((task)->task_se_cmd)
-#define TASK_DEV(task) ((task)->se_dev)
-
 struct se_cmd {
        /* SAM response code being sent to initiator */
        u8                      scsi_status;
@@ -530,9 +463,10 @@ struct se_cmd {
        atomic_t                transport_sent;
        /* Used for sense data */
        void                    *sense_buffer;
-       struct list_head        se_delayed_list;
-       struct list_head        se_ordered_list;
-       struct list_head        se_lun_list;
+       struct list_head        se_delayed_node;
+       struct list_head        se_ordered_node;
+       struct list_head        se_lun_node;
+       struct list_head        se_qf_node;
        struct se_device      *se_dev;
        struct se_dev_entry   *se_deve;
        struct se_device        *se_obj_ptr;
@@ -541,18 +475,60 @@ struct se_cmd {
        /* Only used for internal passthrough and legacy TCM fabric modules */
        struct se_session       *se_sess;
        struct se_tmr_req       *se_tmr_req;
-       /* t_task is setup to t_task_backstore in transport_init_se_cmd() */
-       struct se_transport_task *t_task;
-       struct se_transport_task t_task_backstore;
+       struct list_head        se_queue_node;
        struct target_core_fabric_ops *se_tfo;
        int (*transport_emulate_cdb)(struct se_cmd *);
        void (*transport_split_cdb)(unsigned long long, u32 *, unsigned char *);
        void (*transport_wait_for_tasks)(struct se_cmd *, int, int);
        void (*transport_complete_callback)(struct se_cmd *);
-} ____cacheline_aligned;
+       int (*transport_qf_callback)(struct se_cmd *);
+
+       unsigned char           *t_task_cdb;
+       unsigned char           __t_task_cdb[TCM_MAX_COMMAND_SIZE];
+       unsigned long long      t_task_lba;
+       int                     t_tasks_failed;
+       int                     t_tasks_fua;
+       bool                    t_tasks_bidi;
+       u32                     t_tasks_se_num;
+       u32                     t_tasks_se_bidi_num;
+       u32                     t_tasks_sg_chained_no;
+       atomic_t                t_fe_count;
+       atomic_t                t_se_count;
+       atomic_t                t_task_cdbs_left;
+       atomic_t                t_task_cdbs_ex_left;
+       atomic_t                t_task_cdbs_timeout_left;
+       atomic_t                t_task_cdbs_sent;
+       atomic_t                t_transport_aborted;
+       atomic_t                t_transport_active;
+       atomic_t                t_transport_complete;
+       atomic_t                t_transport_queue_active;
+       atomic_t                t_transport_sent;
+       atomic_t                t_transport_stop;
+       atomic_t                t_transport_timeout;
+       atomic_t                transport_dev_active;
+       atomic_t                transport_lun_active;
+       atomic_t                transport_lun_fe_stop;
+       atomic_t                transport_lun_stop;
+       spinlock_t              t_state_lock;
+       struct completion       t_transport_stop_comp;
+       struct completion       transport_lun_fe_stop_comp;
+       struct completion       transport_lun_stop_comp;
+       struct scatterlist      *t_tasks_sg_chained;
 
-#define T_TASK(cmd)     ((cmd)->t_task)
-#define CMD_TFO(cmd)   ((cmd)->se_tfo)
+       /*
+        * Used for pre-registered fabric SGL passthrough WRITE and READ
+        * with the special SCF_PASSTHROUGH_CONTIG_TO_SG case for TCM_Loop
+        * and other HW target mode fabric modules.
+        */
+       struct scatterlist      *t_task_pt_sgl;
+       u32                     t_task_pt_sgl_num;
+       struct list_head        t_mem_list;
+       /* Used for BIDI READ */
+       struct list_head        t_mem_bidi_list;
+       struct list_head        t_task_list;
+       u32                     t_task_list_num;
+
+} ____cacheline_aligned;
 
 struct se_tmr_req {
        /* Task Management function to be preformed */
@@ -601,7 +577,8 @@ struct se_node_acl {
        struct config_group     acl_attrib_group;
        struct config_group     acl_auth_group;
        struct config_group     acl_param_group;
-       struct config_group     *acl_default_groups[4];
+       struct config_group     acl_fabric_stat_group;
+       struct config_group     *acl_default_groups[5];
        struct list_head        acl_list;
        struct list_head        acl_sess_list;
 } ____cacheline_aligned;
@@ -615,13 +592,16 @@ struct se_session {
        struct list_head        sess_acl_list;
 } ____cacheline_aligned;
 
-#define SE_SESS(cmd)           ((cmd)->se_sess)
-#define SE_NODE_ACL(sess)      ((sess)->se_node_acl)
-
 struct se_device;
 struct se_transform_info;
 struct scatterlist;
 
+struct se_ml_stat_grps {
+       struct config_group     stat_group;
+       struct config_group     scsi_auth_intr_group;
+       struct config_group     scsi_att_intr_port_group;
+};
+
 struct se_lun_acl {
        char                    initiatorname[TRANSPORT_IQN_LEN];
        u32                     mapped_lun;
@@ -629,6 +609,7 @@ struct se_lun_acl {
        struct se_lun           *se_lun;
        struct list_head        lacl_list;
        struct config_group     se_lun_group;
+       struct se_ml_stat_grps  ml_stat_grps;
 }  ____cacheline_aligned;
 
 struct se_dev_entry {
@@ -677,6 +658,7 @@ struct se_dev_attrib {
        int             emulate_reservations;
        int             emulate_alua;
        int             enforce_pr_isids;
+       int             is_nonrot;
        u32             hw_block_size;
        u32             block_size;
        u32             hw_max_sectors;
@@ -693,6 +675,13 @@ struct se_dev_attrib {
        struct config_group da_group;
 } ____cacheline_aligned;
 
+struct se_dev_stat_grps {
+       struct config_group stat_group;
+       struct config_group scsi_dev_group;
+       struct config_group scsi_tgt_dev_group;
+       struct config_group scsi_lu_group;
+};
+
 struct se_subsystem_dev {
 /* Used for struct se_subsystem_dev-->se_dev_alias, must be less than PAGE_SIZE */
 #define SE_DEV_ALIAS_LEN               512
@@ -709,19 +698,17 @@ struct se_subsystem_dev {
        /* T10 Inquiry and VPD WWN Information */
        struct t10_wwn  t10_wwn;
        /* T10 SPC-2 + SPC-3 Reservations */
-       struct t10_reservation_template t10_reservation;
+       struct t10_reservation t10_pr;
        spinlock_t      se_dev_lock;
        void            *se_dev_su_ptr;
-       struct list_head g_se_dev_list;
+       struct list_head se_dev_node;
        struct config_group se_dev_group;
        /* For T10 Reservations */
        struct config_group se_dev_pr_group;
+       /* For target_core_stat.c groups */
+       struct se_dev_stat_grps dev_stat_grps;
 } ____cacheline_aligned;
 
-#define T10_ALUA(su_dev)       (&(su_dev)->t10_alua)
-#define T10_RES(su_dev)                (&(su_dev)->t10_reservation)
-#define T10_PR_OPS(su_dev)     (&(su_dev)->t10_reservation.pr_ops)
-
 struct se_device {
        /* Set to 1 if thread is NOT sleeping on thread_sem */
        u8                      thread_active;
@@ -759,11 +746,11 @@ struct se_device {
        atomic_t                dev_status_thr_count;
        atomic_t                dev_hoq_count;
        atomic_t                dev_ordered_sync;
+       atomic_t                dev_qf_count;
        struct se_obj           dev_obj;
        struct se_obj           dev_access_obj;
        struct se_obj           dev_export_obj;
-       struct se_queue_obj     *dev_queue_obj;
-       struct se_queue_obj     *dev_status_queue_obj;
+       struct se_queue_obj     dev_queue_obj;
        spinlock_t              delayed_cmd_lock;
        spinlock_t              ordered_cmd_lock;
        spinlock_t              execute_task_lock;
@@ -775,6 +762,7 @@ struct se_device {
        spinlock_t              dev_status_thr_lock;
        spinlock_t              se_port_lock;
        spinlock_t              se_tmr_lock;
+       spinlock_t              qf_cmd_lock;
        /* Used for legacy SPC-2 reservationsa */
        struct se_node_acl      *dev_reserved_node_acl;
        /* Used for ALUA Logical Unit Group membership */
@@ -788,10 +776,12 @@ struct se_device {
        struct task_struct      *process_thread;
        pid_t                   process_thread_pid;
        struct task_struct              *dev_mgmt_thread;
+       struct work_struct      qf_work_queue;
        struct list_head        delayed_cmd_list;
        struct list_head        ordered_cmd_list;
        struct list_head        execute_task_list;
        struct list_head        state_task_list;
+       struct list_head        qf_cmd_list;
        /* Pointer to associated SE HBA */
        struct se_hba           *se_hba;
        struct se_subsystem_dev *se_sub_dev;
@@ -803,11 +793,6 @@ struct se_device {
        struct list_head        g_se_dev_list;
 }  ____cacheline_aligned;
 
-#define SE_DEV(cmd)            ((cmd)->se_lun->lun_se_dev)
-#define SU_DEV(dev)            ((dev)->se_sub_dev)
-#define DEV_ATTRIB(dev)                (&(dev)->se_sub_dev->se_dev_attrib)
-#define DEV_T10_WWN(dev)       (&(dev)->se_sub_dev->t10_wwn)
-
 struct se_hba {
        u16                     hba_tpgt;
        u32                     hba_id;
@@ -816,23 +801,23 @@ struct se_hba {
        /* Virtual iSCSI devices attached. */
        u32                     dev_count;
        u32                     hba_index;
-       atomic_t                load_balance_queue;
-       atomic_t                left_queue_depth;
-       /* Maximum queue depth the HBA can handle. */
-       atomic_t                max_queue_depth;
        /* Pointer to transport specific host structure. */
        void                    *hba_ptr;
        /* Linked list for struct se_device */
        struct list_head        hba_dev_list;
-       struct list_head        hba_list;
+       struct list_head        hba_node;
        spinlock_t              device_lock;
-       spinlock_t              hba_queue_lock;
        struct config_group     hba_group;
        struct mutex            hba_access_mutex;
        struct se_subsystem_api *transport;
 }  ____cacheline_aligned;
 
-#define SE_HBA(dev)            ((dev)->se_hba)
+struct se_port_stat_grps {
+       struct config_group stat_group;
+       struct config_group scsi_port_group;
+       struct config_group scsi_tgt_port_group;
+       struct config_group scsi_transport_group;
+};
 
 struct se_lun {
        /* See transport_lun_status_table */
@@ -848,12 +833,11 @@ struct se_lun {
        struct list_head        lun_cmd_list;
        struct list_head        lun_acl_list;
        struct se_device        *lun_se_dev;
+       struct se_port          *lun_sep;
        struct config_group     lun_group;
-       struct se_port  *lun_sep;
+       struct se_port_stat_grps port_stat_grps;
 } ____cacheline_aligned;
 
-#define SE_LUN(cmd)            ((cmd)->se_lun)
-
 struct scsi_port_stats {
        u64     cmd_pdus;
        u64     tx_data_octets;
@@ -900,12 +884,12 @@ struct se_portal_group {
        spinlock_t              tpg_lun_lock;
        /* Pointer to $FABRIC_MOD portal group */
        void                    *se_tpg_fabric_ptr;
-       struct list_head        se_tpg_list;
+       struct list_head        se_tpg_node;
        /* linked list for initiator ACL list */
        struct list_head        acl_node_list;
        struct se_lun           *tpg_lun_list;
        struct se_lun           tpg_virt_lun0;
-       /* List of TCM sessions assoicated wth this TPG */
+       /* List of TCM sessions associated wth this TPG */
        struct list_head        tpg_sess_list;
        /* Pointer to $FABRIC_MOD dependent code */
        struct target_core_fabric_ops *se_tpg_tfo;
@@ -919,35 +903,11 @@ struct se_portal_group {
        struct config_group     tpg_param_group;
 } ____cacheline_aligned;
 
-#define TPG_TFO(se_tpg)        ((se_tpg)->se_tpg_tfo)
-
 struct se_wwn {
        struct target_fabric_configfs *wwn_tf;
        struct config_group     wwn_group;
-} ____cacheline_aligned;
-
-struct se_global {
-       u16                     alua_lu_gps_counter;
-       int                     g_sub_api_initialized;
-       u32                     in_shutdown;
-       u32                     alua_lu_gps_count;
-       u32                     g_hba_id_counter;
-       struct config_group     target_core_hbagroup;
-       struct config_group     alua_group;
-       struct config_group     alua_lu_gps_group;
-       struct list_head        g_lu_gps_list;
-       struct list_head        g_se_tpg_list;
-       struct list_head        g_hba_list;
-       struct list_head        g_se_dev_list;
-       struct se_hba           *g_lun0_hba;
-       struct se_subsystem_dev *g_lun0_su_dev;
-       struct se_device        *g_lun0_dev;
-       struct t10_alua_lu_gp   *default_lu_gp;
-       spinlock_t              g_device_lock;
-       spinlock_t              hba_lock;
-       spinlock_t              se_tpg_lock;
-       spinlock_t              lu_gps_lock;
-       spinlock_t              plugin_class_lock;
+       struct config_group     *wwn_default_groups[2];
+       struct config_group     fabric_stat_group;
 } ____cacheline_aligned;
 
 #endif /* TARGET_CORE_BASE_H */