On 10/31/2013 03:48 PM, Vineet Gupta wrote:
> Hi Chen,
> 
> Many thanks for all your efforts so far.
> 

Since I need provide contribution to Public Open Source, so what I have
done is what I should do. :-)

In fact, I really need improve myself: e.g. how to make negative effect
lowest (e.g. how to let more members pleased with what I have done), how
to improve efficiency (make my waste mail lower) ...


> Most of your patches have already been folded into ARC for 3.13. I will send 
> out
> the patches for some of the cross-arch changes in next development cycle as
> currently I need to finish up a few things for upcoming merge window.
> 

OK, thanks.

> We are actively working on toolchain issues and hopefully the fixes will make 
> it
> into next formal release of tools. Please check back in few weeks.
> 

OK, I will/should focus.

And for gcc issue #27, I shrank the demo source file is about 1K lines
(shrank from 50K lines to 1K lines), although it is still a big file
which can be shrunk more.

And excuse me, I don't know how to past this file on this website, so I
load it as attachment, please check.


Thanks.
-- 
Chen Gang
typedef char __s8;
typedef unsigned char __u8;
typedef short __s16;
typedef unsigned short __u16;
typedef int __s32;
typedef unsigned int __u32;
typedef long long __s64;
typedef unsigned long long __u64;
typedef signed char s8;
typedef unsigned char u8;
typedef signed short s16;
typedef unsigned short u16;
typedef signed int s32;
typedef unsigned int u32;
typedef signed long long s64;
typedef unsigned long long u64;
enum {
 false = 0,
 true = 1
};
typedef struct {
 unsigned long fds_bits[1024 / (8 * sizeof(long))];
} __kernel_fd_set;
typedef void (*__kernel_sighandler_t)(int);
typedef int __kernel_key_t;
typedef int __kernel_mqd_t;
typedef long __kernel_long_t;
typedef unsigned long __kernel_ulong_t;
typedef __kernel_ulong_t __kernel_ino_t;
typedef unsigned int __kernel_mode_t;
typedef int __kernel_pid_t;
typedef int __kernel_ipc_pid_t;
typedef unsigned int __kernel_uid_t;
typedef unsigned int __kernel_gid_t;
typedef __kernel_long_t __kernel_suseconds_t;
typedef int __kernel_daddr_t;
typedef unsigned int __kernel_uid32_t;
typedef unsigned int __kernel_gid32_t;
typedef __kernel_uid_t __kernel_old_uid_t;
typedef __kernel_gid_t __kernel_old_gid_t;
typedef unsigned int __kernel_old_dev_t;
typedef unsigned int __kernel_size_t;
typedef int __kernel_ssize_t;
typedef int __kernel_ptrdiff_t;
typedef struct {
 int val[2];
} __kernel_fsid_t;
typedef __kernel_long_t __kernel_off_t;
typedef long long __kernel_loff_t;
typedef __kernel_long_t __kernel_time_t;
typedef __kernel_long_t __kernel_clock_t;
typedef int __kernel_timer_t;
typedef int __kernel_clockid_t;
typedef char * __kernel_caddr_t;
typedef unsigned short __kernel_uid16_t;
typedef unsigned short __kernel_gid16_t;
typedef __u16 __le16;
typedef __u16 __be16;
typedef __u32 __le32;
typedef __u32 __be32;
typedef __u64 __le64;
typedef __u64 __be64;
typedef __u16 __sum16;
typedef __u32 __wsum;
typedef __u32 __kernel_dev_t;
typedef __kernel_fd_set fd_set;
typedef __kernel_dev_t dev_t;
typedef __kernel_ino_t ino_t;
typedef __kernel_mode_t mode_t;
typedef unsigned short umode_t;
typedef __u32 nlink_t;
typedef __kernel_off_t off_t;
typedef __kernel_pid_t pid_t;
typedef __kernel_daddr_t daddr_t;
typedef __kernel_key_t key_t;
typedef __kernel_suseconds_t suseconds_t;
typedef __kernel_timer_t timer_t;
typedef __kernel_clockid_t clockid_t;
typedef __kernel_mqd_t mqd_t;
typedef _Bool bool;
typedef __kernel_uid32_t uid_t;
typedef __kernel_gid32_t gid_t;
typedef __kernel_uid16_t uid16_t;
typedef __kernel_gid16_t gid16_t;
typedef unsigned long uintptr_t;
typedef __kernel_loff_t loff_t;
typedef __kernel_size_t size_t;
typedef __kernel_ssize_t ssize_t;
typedef __kernel_ptrdiff_t ptrdiff_t;
typedef __kernel_time_t time_t;
typedef __kernel_clock_t clock_t;
typedef __kernel_caddr_t caddr_t;
typedef unsigned char u_char;
typedef unsigned short u_short;
typedef unsigned int u_int;
typedef unsigned long u_long;
typedef unsigned char unchar;
typedef unsigned short ushort;
typedef unsigned int uint;
typedef unsigned long ulong;
typedef __u8 u_int8_t;
typedef __s8 int8_t;
typedef __u16 u_int16_t;
typedef __s16 int16_t;
typedef __u32 u_int32_t;
typedef __s32 int32_t;
typedef __u8 uint8_t;
typedef __u16 uint16_t;
typedef __u32 uint32_t;
typedef __u64 uint64_t;
typedef __u64 u_int64_t;
typedef __s64 int64_t;
typedef u64 sector_t;
typedef u64 blkcnt_t;
typedef u32 dma_addr_t;
typedef unsigned gfp_t;
typedef unsigned fmode_t;
typedef unsigned oom_flags_t;
typedef u32 phys_addr_t;
typedef phys_addr_t resource_size_t;
typedef unsigned long irq_hw_number_t;
typedef struct {
 int counter;
} atomic_t;
struct list_head {
 struct list_head *next, *prev;
};
typedef struct {
 volatile unsigned int slock;
} arch_spinlock_t;
typedef struct raw_spinlock {
 arch_spinlock_t raw_lock;
 unsigned int magic, owner_cpu;
 void *owner;
} raw_spinlock_t;
typedef struct spinlock {
 union {
  struct raw_spinlock rlock;
 };
} spinlock_t;
typedef atomic_t atomic_long_t;
typedef struct __wait_queue wait_queue_t;
typedef int (*wait_queue_func_t)(wait_queue_t *wait, unsigned mode, int flags, 
void *key);

struct __wait_queue {
 unsigned int flags;
 void *private;
 wait_queue_func_t func;
 struct list_head task_list;
};
struct wait_bit_key {
 void *flags;
 int bit_nr;
};
struct wait_bit_queue {
 struct wait_bit_key key;
 wait_queue_t wait;
};
struct __wait_queue_head {
 spinlock_t lock;
 struct list_head task_list;
};
typedef struct __wait_queue_head wait_queue_head_t;
struct mutex {
 atomic_t count;
 spinlock_t wait_lock;
 struct list_head wait_list;
 struct task_struct *owner;
 const char *name;
 void *magic;
};
typedef struct cpumask { unsigned long bits[(((2) + (8 * sizeof(long)) - 1) / 
(8 * sizeof(long)))]; } cpumask_t;
struct completion {
 unsigned int done;
 wait_queue_head_t wait;
};
struct workqueue_struct;
struct work_struct;
typedef void (*work_func_t)(struct work_struct *work);
void delayed_work_timer_fn(unsigned long __data);

enum {
 WORK_STRUCT_PENDING_BIT = 0,
 WORK_STRUCT_DELAYED_BIT = 1,
 WORK_STRUCT_PWQ_BIT = 2,
 WORK_STRUCT_LINKED_BIT = 3,
 WORK_STRUCT_STATIC_BIT = 4,
 WORK_STRUCT_COLOR_SHIFT = 5,
 WORK_STRUCT_COLOR_BITS = 4,
 WORK_STRUCT_PENDING = 1 << WORK_STRUCT_PENDING_BIT,
 WORK_STRUCT_DELAYED = 1 << WORK_STRUCT_DELAYED_BIT,
 WORK_STRUCT_PWQ = 1 << WORK_STRUCT_PWQ_BIT,
 WORK_STRUCT_LINKED = 1 << WORK_STRUCT_LINKED_BIT,
 WORK_STRUCT_STATIC = 1 << WORK_STRUCT_STATIC_BIT,
 WORK_NR_COLORS = (1 << WORK_STRUCT_COLOR_BITS) - 1,
 WORK_NO_COLOR = WORK_NR_COLORS,
 WORK_CPU_UNBOUND = 2,
 WORK_CPU_END = 2 + 1,
 WORK_STRUCT_FLAG_BITS = WORK_STRUCT_COLOR_SHIFT + WORK_STRUCT_COLOR_BITS,
 WORK_OFFQ_FLAG_BASE = WORK_STRUCT_COLOR_SHIFT,
 WORK_OFFQ_CANCELING = (1 << WORK_OFFQ_FLAG_BASE),
 WORK_OFFQ_FLAG_BITS = 1,
 WORK_OFFQ_POOL_SHIFT = WORK_OFFQ_FLAG_BASE + WORK_OFFQ_FLAG_BITS,
 WORK_OFFQ_LEFT = 32 - WORK_OFFQ_POOL_SHIFT,
 WORK_OFFQ_POOL_BITS = WORK_OFFQ_LEFT <= 31 ? WORK_OFFQ_LEFT : 31,
 WORK_OFFQ_POOL_NONE = (1LU << WORK_OFFQ_POOL_BITS) - 1,
 WORK_STRUCT_FLAG_MASK = (1UL << WORK_STRUCT_FLAG_BITS) - 1,
 WORK_STRUCT_WQ_DATA_MASK = ~WORK_STRUCT_FLAG_MASK,
 WORK_STRUCT_NO_POOL = (unsigned long)WORK_OFFQ_POOL_NONE << 
WORK_OFFQ_POOL_SHIFT,
 WORK_BUSY_PENDING = 1 << 0,
 WORK_BUSY_RUNNING = 1 << 1,
 WORKER_DESC_LEN = 24,
};
struct work_struct {
 atomic_long_t data;
 struct list_head entry;
 work_func_t func;
};
struct kref {
 atomic_t refcount;
};
enum dma_data_direction {
 DMA_BIDIRECTIONAL = 0,
 DMA_TO_DEVICE = 1,
 DMA_FROM_DEVICE = 2,
 DMA_NONE = 3,
};
struct semaphore {
 raw_spinlock_t lock;
 unsigned int count;
 struct list_head wait_list;
};
struct config_item {
 char *ci_name;
 char ci_namebuf[20];
 struct kref ci_kref;
 struct list_head ci_entry;
 struct config_item *ci_parent;
 struct config_group *ci_group;
 struct config_item_type *ci_type;
 struct dentry *ci_dentry;
};
struct config_item_type {
 struct module *ct_owner;
 struct configfs_item_operations *ct_item_ops;
 struct configfs_group_operations *ct_group_ops;
 struct configfs_attribute **ct_attrs;
};
struct config_group {
 struct config_item cg_item;
 struct list_head cg_children;
 struct configfs_subsystem *cg_subsys;
 struct config_group **default_groups;
};
struct configfs_attribute {
 const char *ca_name;
 struct module *ca_owner;
 umode_t ca_mode;
};
struct percpu_ida_cpu;
struct percpu_ida {
 unsigned nr_tags;
 struct percpu_ida_cpu *tag_cpu;
 cpumask_t cpus_have_tags;
 struct {
  spinlock_t lock;
  unsigned cpu_last_stolen;
  wait_queue_head_t wait;
  unsigned nr_free;
  unsigned *freelist;
 } __attribute__((__aligned__((1 << 6))));
};
enum hba_flags_table {
 HBA_FLAGS_INTERNAL_USE = 0x01,
 HBA_FLAGS_PSCSI_MODE = 0x02,
};
enum transport_lun_status_table {
 TRANSPORT_LUN_STATUS_FREE = 0,
 TRANSPORT_LUN_STATUS_ACTIVE = 1,
};
enum transport_tpg_type_table {
 TRANSPORT_TPG_TYPE_NORMAL = 0,
 TRANSPORT_TPG_TYPE_DISCOVERY = 1,
};
enum transport_state_table {
 TRANSPORT_NO_STATE = 0,
 TRANSPORT_NEW_CMD = 1,
 TRANSPORT_WRITE_PENDING = 3,
 TRANSPORT_PROCESSING = 5,
 TRANSPORT_COMPLETE = 6,
 TRANSPORT_ISTATE_PROCESSING = 11,
 TRANSPORT_COMPLETE_QF_WP = 18,
 TRANSPORT_COMPLETE_QF_OK = 19,
};
enum se_cmd_flags_table {
 SCF_SUPPORTED_SAM_OPCODE = 0x00000001,
 SCF_TRANSPORT_TASK_SENSE = 0x00000002,
 SCF_EMULATED_TASK_SENSE = 0x00000004,
 SCF_SCSI_DATA_CDB = 0x00000008,
 SCF_SCSI_TMR_CDB = 0x00000010,
 SCF_FUA = 0x00000080,
 SCF_SE_LUN_CMD = 0x00000100,
 SCF_BIDI = 0x00000400,
 SCF_SENT_CHECK_CONDITION = 0x00000800,
 SCF_OVERFLOW_BIT = 0x00001000,
 SCF_UNDERFLOW_BIT = 0x00002000,
 SCF_SENT_DELAYED_TAS = 0x00004000,
 SCF_ALUA_NON_OPTIMIZED = 0x00008000,
 SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC = 0x00020000,
 SCF_ACK_KREF = 0x00040000,
 SCF_COMPARE_AND_WRITE = 0x00080000,
 SCF_COMPARE_AND_WRITE_POST = 0x00100000,
 SCF_CMD_XCOPY_PASSTHROUGH = 0x00200000,
};
enum transport_lunflags_table {
 TRANSPORT_LUNFLAGS_NO_ACCESS = 0x00,
 TRANSPORT_LUNFLAGS_INITIATOR_ACCESS = 0x01,
 TRANSPORT_LUNFLAGS_READ_ONLY = 0x02,
 TRANSPORT_LUNFLAGS_READ_WRITE = 0x04,
};

typedef unsigned sense_reason_t;

enum tcm_sense_reason_table {
 TCM_NO_SENSE = ( sense_reason_t )(0x00),
 TCM_NON_EXISTENT_LUN = ( sense_reason_t )(0x01),
 TCM_UNSUPPORTED_SCSI_OPCODE = ( sense_reason_t )(0x02),
 TCM_INCORRECT_AMOUNT_OF_DATA = ( sense_reason_t )(0x03),
 TCM_UNEXPECTED_UNSOLICITED_DATA = ( sense_reason_t )(0x04),
 TCM_SERVICE_CRC_ERROR = ( sense_reason_t )(0x05),
 TCM_SNACK_REJECTED = ( sense_reason_t )(0x06),
 TCM_SECTOR_COUNT_TOO_MANY = ( sense_reason_t )(0x07),
 TCM_INVALID_CDB_FIELD = ( sense_reason_t )(0x08),
 TCM_INVALID_PARAMETER_LIST = ( sense_reason_t )(0x09),
 TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE = ( sense_reason_t )(0x0a),
 TCM_UNKNOWN_MODE_PAGE = ( sense_reason_t )(0x0b),
 TCM_WRITE_PROTECTED = ( sense_reason_t )(0x0c),
 TCM_CHECK_CONDITION_ABORT_CMD = ( sense_reason_t )(0x0d),
 TCM_CHECK_CONDITION_UNIT_ATTENTION = ( sense_reason_t )(0x0e),
 TCM_CHECK_CONDITION_NOT_READY = ( sense_reason_t )(0x0f),
 TCM_RESERVATION_CONFLICT = ( sense_reason_t )(0x10),
 TCM_ADDRESS_OUT_OF_RANGE = ( sense_reason_t )(0x11),
 TCM_OUT_OF_RESOURCES = ( sense_reason_t )(0x12),
 TCM_PARAMETER_LIST_LENGTH_ERROR = ( sense_reason_t )(0x13),
 TCM_MISCOMPARE_VERIFY = ( sense_reason_t )(0x14),
};
enum target_sc_flags_table {
 TARGET_SCF_BIDI_OP = 0x01,
 TARGET_SCF_ACK_KREF = 0x02,
 TARGET_SCF_UNKNOWN_SIZE = 0x04,
};
enum tcm_tmreq_table {
 TMR_ABORT_TASK = 1,
 TMR_ABORT_TASK_SET = 2,
 TMR_CLEAR_ACA = 3,
 TMR_CLEAR_TASK_SET = 4,
 TMR_LUN_RESET = 5,
 TMR_TARGET_WARM_RESET = 6,
 TMR_TARGET_COLD_RESET = 7,
};
enum tcm_tmrsp_table {
 TMR_FUNCTION_COMPLETE = 1,
 TMR_TASK_DOES_NOT_EXIST = 2,
 TMR_LUN_DOES_NOT_EXIST = 3,
 TMR_TASK_MGMT_FUNCTION_NOT_SUPPORTED = 4,
 TMR_FUNCTION_REJECTED = 5,
};
typedef enum {
 SCSI_INST_INDEX,
 SCSI_DEVICE_INDEX,
 SCSI_AUTH_INTR_INDEX,
 SCSI_INDEX_TYPE_MAX
} scsi_index_t;

struct se_cmd;

struct t10_alua {
 u16 alua_tg_pt_gps_counter;
 u32 alua_tg_pt_gps_count;
 spinlock_t tg_pt_gps_lock;
 struct se_device *t10_dev;
 struct t10_alua_tg_pt_gp *default_tg_pt_gp;
 struct config_group alua_tg_pt_gps_group;
 struct list_head tg_pt_gps_list;
};
struct t10_alua_lu_gp {
 u16 lu_gp_id;
 int lu_gp_valid_id;
 u32 lu_gp_members;
 atomic_t lu_gp_ref_cnt;
 spinlock_t lu_gp_lock;
 struct config_group lu_gp_group;
 struct list_head lu_gp_node;
 struct list_head lu_gp_mem_list;
};
struct t10_alua_lu_gp_member {
 bool lu_gp_assoc;
 atomic_t lu_gp_mem_ref_cnt;
 spinlock_t lu_gp_mem_lock;
 struct t10_alua_lu_gp *lu_gp;
 struct se_device *lu_gp_mem_dev;
 struct list_head lu_gp_mem_list;
};
struct t10_alua_tg_pt_gp {
 u16 tg_pt_gp_id;
 int tg_pt_gp_valid_id;
 int tg_pt_gp_alua_access_status;
 int tg_pt_gp_alua_access_type;
 int tg_pt_gp_nonop_delay_msecs;
 int tg_pt_gp_trans_delay_msecs;
 int tg_pt_gp_implict_trans_secs;
 int tg_pt_gp_pref;
 int tg_pt_gp_write_metadata;
 u32 tg_pt_gp_md_buf_len;
 u32 tg_pt_gp_members;
 atomic_t tg_pt_gp_alua_access_state;
 atomic_t tg_pt_gp_ref_cnt;
 spinlock_t tg_pt_gp_lock;
 struct mutex tg_pt_gp_md_mutex;
 struct se_device *tg_pt_gp_dev;
 struct config_group tg_pt_gp_group;
 struct list_head tg_pt_gp_list;
 struct list_head tg_pt_gp_mem_list;
};
struct t10_alua_tg_pt_gp_member {
 bool tg_pt_gp_assoc;
 atomic_t tg_pt_gp_mem_ref_cnt;
 spinlock_t tg_pt_gp_mem_lock;
 struct t10_alua_tg_pt_gp *tg_pt_gp;
 struct se_port *tg_pt;
 struct list_head tg_pt_gp_mem_list;
};
struct t10_wwn {
 char vendor[8];
 char model[16];
 char revision[4];
 char unit_serial[254];
 spinlock_t t10_vpd_lock;
 struct se_device *t10_dev;
 struct config_group t10_wwn_group;
 struct list_head t10_vpd_list;
};

struct t10_pr_registration {
 char pr_reg_isid[16];
 unsigned char pr_iport[256];
 unsigned char pr_tport[256];
 u16 pr_aptpl_rpti;
 u16 pr_reg_tpgt;
 int pr_reg_all_tg_pt;
 int pr_reg_aptpl;
 int pr_res_holder;
 int pr_res_type;
 int pr_res_scope;
 bool isid_present_at_reg;
 u32 pr_res_mapped_lun;
 u32 pr_aptpl_target_lun;
 u32 pr_res_generation;
 u64 pr_reg_bin_isid;
 u64 pr_res_key;
 atomic_t pr_res_holders;
 struct se_node_acl *pr_reg_nacl;
 struct se_dev_entry *pr_reg_deve;
 struct se_lun *pr_reg_tg_pt_lun;
 struct list_head pr_reg_list;
 struct list_head pr_reg_abort_list;
 struct list_head pr_reg_aptpl_list;
 struct list_head pr_reg_atp_list;
 struct list_head pr_reg_atp_mem_list;
};
struct t10_reservation {
 int pr_all_tg_pt;
 int pr_aptpl_active;
 u32 pr_generation;
 spinlock_t registration_lock;
 spinlock_t aptpl_reg_lock;
 struct se_node_acl *pr_res_holder;
 struct list_head registration_list;
 struct list_head aptpl_reg_list;
};
struct se_tmr_req {
 u8 function;
 u8 response;
 int call_transport;
 u32 ref_task_tag;
 void *fabric_tmr_ptr;
 struct se_cmd *task_cmd;
 struct se_device *tmr_dev;
 struct se_lun *tmr_lun;
 struct list_head tmr_list;
};
struct se_cmd {
 u8 scsi_status;
 u8 scsi_asc;
 u8 scsi_ascq;
 u16 scsi_sense_length;
 int alua_nonop_delay;
 enum dma_data_direction data_direction;
 int sam_task_attr;
 unsigned int map_tag;
 enum transport_state_table t_state;
 unsigned cmd_wait_set:1;
 unsigned unknown_data_length:1;
 u32 se_cmd_flags;
 u32 se_ordered_id;
 u32 data_length;
 u32 residual_count;
 u32 orig_fe_lun;
 u64 pr_res_key;
 void *sense_buffer;
 struct list_head se_delayed_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_lun *se_lun;
 struct se_session *se_sess;
 struct se_tmr_req *se_tmr_req;
 struct list_head se_cmd_list;
 struct completion cmd_wait_comp;
 struct kref cmd_kref;
 struct target_core_fabric_ops *se_tfo;
 sense_reason_t (*execute_cmd)(struct se_cmd *);
 sense_reason_t (*execute_rw)(struct se_cmd *, struct scatterlist *, u32, enum 
dma_data_direction);
 sense_reason_t (*transport_complete_callback)(struct se_cmd *);
 unsigned char *t_task_cdb;
 unsigned char __t_task_cdb[32];
 unsigned long long t_task_lba;
 unsigned int t_task_nolb;
 unsigned int transport_state;
 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 work_struct work;
 struct scatterlist *t_data_sg;
 struct scatterlist *t_data_sg_orig;
 unsigned int t_data_nents;
 unsigned int t_data_nents_orig;
 void *t_data_vmap;
 struct scatterlist *t_bidi_data_sg;
 unsigned int t_bidi_data_nents;
 struct list_head state_list;
 bool state_active;
 struct completion task_stop_comp;
 void *priv;
};
struct se_ua {
 u8 ua_asc;
 u8 ua_ascq;
 struct se_node_acl *ua_nacl;
 struct list_head ua_dev_list;
 struct list_head ua_nacl_list;
};
struct se_node_acl {
 char initiatorname[224];
 bool dynamic_node_acl;
 bool acl_stop:1;
 u32 queue_depth;
 u32 acl_index;
 char acl_tag[64];
 u64 num_cmds;
 u64 read_bytes;
 u64 write_bytes;
 spinlock_t stats_lock;
 atomic_t acl_pr_ref_count;
 struct se_dev_entry **device_list;
 struct se_session *nacl_sess;
 struct se_portal_group *se_tpg;
 spinlock_t device_list_lock;
 spinlock_t nacl_sess_lock;
 struct config_group acl_group;
 struct config_group acl_attrib_group;
 struct config_group acl_auth_group;
 struct config_group acl_param_group;
 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;
 struct completion acl_free_comp;
 struct kref acl_kref;
};
struct se_session {
 unsigned sess_tearing_down:1;
 u64 sess_bin_isid;
 struct se_node_acl *se_node_acl;
 struct se_portal_group *se_tpg;
 void *fabric_sess_ptr;
 struct list_head sess_list;
 struct list_head sess_acl_list;
 struct list_head sess_cmd_list;
 struct list_head sess_wait_list;
 spinlock_t sess_cmd_lock;
 struct kref sess_kref;
 void *sess_cmd_map;
 struct percpu_ida sess_tag_pool;
};
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[224];
 u32 mapped_lun;
 struct se_node_acl *se_lun_nacl;
 struct se_lun *se_lun;
 struct list_head lacl_list;
 struct config_group se_lun_group;
 struct se_ml_stat_grps ml_stat_grps;
};
struct se_dev_entry {
 bool def_pr_registered;
 u32 lun_flags;
 u32 mapped_lun;
 u32 total_cmds;
 u64 pr_res_key;
 u64 creation_time;
 u32 attach_count;
 u64 read_bytes;
 u64 write_bytes;
 atomic_t ua_count;
 atomic_t pr_ref_count;
 struct se_lun_acl *se_lun_acl;
 spinlock_t ua_lock;
 struct se_lun *se_lun;
 struct list_head alua_port_list;
 struct list_head ua_list;
};
struct se_dev_attrib {
 int emulate_model_alias;
 int emulate_dpo;
 int emulate_fua_write;
 int emulate_fua_read;
 int emulate_write_cache;
 int emulate_ua_intlck_ctrl;
 int emulate_tas;
 int emulate_tpu;
 int emulate_tpws;
 int emulate_caw;
 int emulate_3pc;
 int enforce_pr_isids;
 int is_nonrot;
 int emulate_rest_reord;
 u32 hw_block_size;
 u32 block_size;
 u32 hw_max_sectors;
 u32 fabric_max_sectors;
 u32 optimal_sectors;
 u32 hw_queue_depth;
 u32 queue_depth;
 u32 max_unmap_lba_count;
 u32 max_unmap_block_desc_count;
 u32 unmap_granularity;
 u32 unmap_granularity_alignment;
 u32 max_write_same_len;
 struct se_device *da_dev;
 struct config_group da_group;
};
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_device {
 u32 dev_link_magic;
 u16 dev_rpti_counter;
 u32 dev_cur_ordered_id;
 u32 dev_flags;
 u32 dev_port_count;
 u32 queue_depth;
 u64 dev_res_bin_isid;
 u32 dev_index;
 u64 creation_time;
 u32 num_resets;
 u64 num_cmds;
 u64 read_bytes;
 u64 write_bytes;
 spinlock_t stats_lock;
 atomic_t simple_cmds;
 atomic_t dev_ordered_id;
 atomic_t dev_ordered_sync;
 atomic_t dev_qf_count;
 int export_count;
 spinlock_t delayed_cmd_lock;
 spinlock_t execute_task_lock;
 spinlock_t dev_reservation_lock;
 unsigned int dev_reservation_flags;
 spinlock_t se_port_lock;
 spinlock_t se_tmr_lock;
 spinlock_t qf_cmd_lock;
 struct semaphore caw_sem;
 struct se_node_acl *dev_reserved_node_acl;
 struct t10_alua_lu_gp_member *dev_alua_lu_gp_mem;
 struct t10_pr_registration *dev_pr_res_holder;
 struct list_head dev_sep_list;
 struct list_head dev_tmr_list;
 struct workqueue_struct *tmr_wq;
 struct work_struct qf_work_queue;
 struct list_head delayed_cmd_list;
 struct list_head state_list;
 struct list_head qf_cmd_list;
 struct list_head g_dev_node;
 struct se_hba *se_hba;
 struct t10_wwn t10_wwn;
 struct t10_alua t10_alua;
 struct t10_reservation t10_pr;
 struct se_dev_attrib dev_attrib;
 struct config_group dev_group;
 struct config_group dev_pr_group;
 struct se_dev_stat_grps dev_stat_grps;
 unsigned char dev_alias[512];
 unsigned char udev_path[512];
 struct se_subsystem_api *transport;
 struct list_head dev_list;
};
struct se_hba {
 u16 hba_tpgt;
 u32 hba_id;
 u32 hba_flags;
 u32 dev_count;
 u32 hba_index;
 void *hba_ptr;
 struct list_head hba_node;
 spinlock_t device_lock;
 struct config_group hba_group;
 struct mutex hba_access_mutex;
 struct se_subsystem_api *transport;
};
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 {
 u32 lun_link_magic;
 enum transport_lun_status_table lun_status;
 u32 lun_access;
 u32 lun_flags;
 u32 unpacked_lun;
 atomic_t lun_acl_count;
 spinlock_t lun_acl_lock;
 spinlock_t lun_cmd_lock;
 spinlock_t lun_sep_lock;
 struct completion lun_shutdown_comp;
 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_stat_grps port_stat_grps;
};
struct scsi_port_stats {
       u64 cmd_pdus;
       u64 tx_data_octets;
       u64 rx_data_octets;
};
struct se_port {
 u16 sep_rtpi;
 int sep_tg_pt_secondary_stat;
 int sep_tg_pt_secondary_write_md;
 u32 sep_index;
 struct scsi_port_stats sep_stats;
 atomic_t sep_tg_pt_secondary_offline;
 atomic_t sep_tg_pt_ref_cnt;
 spinlock_t sep_alua_lock;
 struct mutex sep_tg_pt_md_mutex;
 struct t10_alua_tg_pt_gp_member *sep_alua_tg_pt_gp_mem;
 struct se_lun *sep_lun;
 struct se_portal_group *sep_tpg;
 struct list_head sep_alua_list;
 struct list_head sep_list;
};
struct se_tpg_np {
 struct se_portal_group *tpg_np_parent;
 struct config_group tpg_np_group;
};
struct se_portal_group {
 enum transport_tpg_type_table se_tpg_type;
 u32 num_node_acls;
 atomic_t tpg_pr_ref_count;
 spinlock_t acl_node_lock;
 spinlock_t session_lock;
 spinlock_t tpg_lun_lock;
 void *se_tpg_fabric_ptr;
 struct list_head se_tpg_node;
 struct list_head acl_node_list;
 struct se_lun **tpg_lun_list;
 struct se_lun tpg_virt_lun0;
 struct list_head tpg_sess_list;
 struct target_core_fabric_ops *se_tpg_tfo;
 struct se_wwn *se_tpg_wwn;
 struct config_group tpg_group;
 struct config_group *tpg_default_groups[7];
 struct config_group tpg_lun_group;
 struct config_group tpg_np_group;
 struct config_group tpg_acl_group;
 struct config_group tpg_attrib_group;
 struct config_group tpg_auth_group;
 struct config_group tpg_param_group;
};
struct se_wwn {
 struct target_fabric_configfs *wwn_tf;
 struct config_group wwn_group;
 struct config_group *wwn_default_groups[2];
 struct config_group fabric_stat_group;
};

void *transport_kmap_data_sg(struct se_cmd *);
void transport_kunmap_data_sg(struct se_cmd *);

struct target_core_fabric_ops {
 struct configfs_subsystem *tf_subsys;
 char *(*get_fabric_name)(void);
 u8 (*get_fabric_proto_ident)(struct se_portal_group *);
 char *(*tpg_get_wwn)(struct se_portal_group *);
 u16 (*tpg_get_tag)(struct se_portal_group *);
 u32 (*tpg_get_default_depth)(struct se_portal_group *);
 u32 (*tpg_get_pr_transport_id)(struct se_portal_group *, struct se_node_acl *, 
struct t10_pr_registration *, int *, unsigned char *);
 u32 (*tpg_get_pr_transport_id_len)(struct se_portal_group *, struct 
se_node_acl *, struct t10_pr_registration *, int *);
 char *(*tpg_parse_pr_out_transport_id)(struct se_portal_group *, const char *, 
u32 *, char **);
 int (*tpg_check_demo_mode)(struct se_portal_group *);
 int (*tpg_check_demo_mode_cache)(struct se_portal_group *);
 int (*tpg_check_demo_mode_write_protect)(struct se_portal_group *);
 int (*tpg_check_prod_mode_write_protect)(struct se_portal_group *);
 int (*tpg_check_demo_mode_login_only)(struct se_portal_group *);
 struct se_node_acl *(*tpg_alloc_fabric_acl)( struct se_portal_group *);
 void (*tpg_release_fabric_acl)(struct se_portal_group *, struct se_node_acl *);
 u32 (*tpg_get_inst_index)(struct se_portal_group *);
 int (*check_stop_free)(struct se_cmd *);
 void (*release_cmd)(struct se_cmd *);
 void (*put_session)(struct se_session *);
 int (*shutdown_session)(struct se_session *);
 void (*close_session)(struct se_session *);
 u32 (*sess_get_index)(struct se_session *);
 u32 (*sess_get_initiator_sid)(struct se_session *, unsigned char *, u32);
 int (*write_pending)(struct se_cmd *);
 int (*write_pending_status)(struct se_cmd *);
 void (*set_default_node_attributes)(struct se_node_acl *);
 u32 (*get_task_tag)(struct se_cmd *);
 int (*get_cmd_state)(struct se_cmd *);
 int (*queue_data_in)(struct se_cmd *);
 int (*queue_status)(struct se_cmd *);
 void (*queue_tm_rsp)(struct se_cmd *);
 struct se_wwn *(*fabric_make_wwn)(struct target_fabric_configfs *, struct 
config_group *, const char *);
 void (*fabric_drop_wwn)(struct se_wwn *);
 struct se_portal_group *(*fabric_make_tpg)(struct se_wwn *, struct 
config_group *, const char *);
 void (*fabric_drop_tpg)(struct se_portal_group *);
 int (*fabric_post_link)(struct se_portal_group *, struct se_lun *);
 void (*fabric_pre_unlink)(struct se_portal_group *, struct se_lun *);
 struct se_tpg_np *(*fabric_make_np)(struct se_portal_group *, struct 
config_group *, const char *);
 void (*fabric_drop_np)(struct se_tpg_np *);
 struct se_node_acl *(*fabric_make_nodeacl)(struct se_portal_group *, struct 
config_group *, const char *);
 void (*fabric_drop_nodeacl)(struct se_node_acl *);
};
struct target_fabric_configfs_template {
 struct config_item_type tfc_discovery_cit;
 struct config_item_type tfc_wwn_cit;
 struct config_item_type tfc_wwn_fabric_stats_cit;
 struct config_item_type tfc_tpg_cit;
 struct config_item_type tfc_tpg_base_cit;
 struct config_item_type tfc_tpg_lun_cit;
 struct config_item_type tfc_tpg_port_cit;
 struct config_item_type tfc_tpg_port_stat_cit;
 struct config_item_type tfc_tpg_np_cit;
 struct config_item_type tfc_tpg_np_base_cit;
 struct config_item_type tfc_tpg_attrib_cit;
 struct config_item_type tfc_tpg_auth_cit;
 struct config_item_type tfc_tpg_param_cit;
 struct config_item_type tfc_tpg_nacl_cit;
 struct config_item_type tfc_tpg_nacl_base_cit;
 struct config_item_type tfc_tpg_nacl_attrib_cit;
 struct config_item_type tfc_tpg_nacl_auth_cit;
 struct config_item_type tfc_tpg_nacl_param_cit;
 struct config_item_type tfc_tpg_nacl_stat_cit;
 struct config_item_type tfc_tpg_mappedlun_cit;
 struct config_item_type tfc_tpg_mappedlun_stat_cit;
};
struct target_fabric_configfs {
 char tf_name[32];
 atomic_t tf_access_cnt;
 struct list_head tf_list;
 struct config_group tf_group;
 struct config_group tf_disc_group;
 struct config_group *tf_default_groups[2];
 struct config_item *tf_fabric;
 struct config_item_type *tf_fabric_cit;
 struct configfs_subsystem *tf_subsys;
 struct module *tf_module;
 struct target_core_fabric_ops tf_ops;
 struct target_fabric_configfs_template tf_cit_tmpl;
};

extern sense_reason_t target_scsi3_emulate_pr_in(struct se_cmd *);

static sense_reason_t core_scsi3_pri_read_keys(struct se_cmd *cmd)
{
 struct se_device *dev = cmd->se_dev;
 struct t10_pr_registration *pr_reg;
 unsigned char *buf;
 u32 add_len = 0, off = 8;

 if (cmd->data_length < 8) {
  printk("\001" "3" "PRIN SA READ_KEYS SCSI Data Length: %u" " too small\n", 
cmd->data_length);
  return TCM_INVALID_CDB_FIELD;
 }

 buf = transport_kmap_data_sg(cmd);
 if (!buf)
  return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;

 buf[0] = ((dev->t10_pr.pr_generation >> 24) & 0xff);
 buf[1] = ((dev->t10_pr.pr_generation >> 16) & 0xff);
 buf[2] = ((dev->t10_pr.pr_generation >> 8) & 0xff);
 buf[3] = (dev->t10_pr.pr_generation & 0xff);

 spin_lock(&dev->t10_pr.registration_lock);
 for (pr_reg = ({ const typeof( ((typeof(*pr_reg) *)0)->pr_reg_list ) *__mptr = 
((&dev->t10_pr.registration_list)->next); (typeof(*pr_reg) *)( (char *)__mptr - 
__builtin_offsetof(typeof(*pr_reg),pr_reg_list) );}); &pr_reg->pr_reg_list != 
(&dev->t10_pr.registration_list); pr_reg = ({ const typeof( ((typeof(*pr_reg) 
*)0)->pr_reg_list ) *__mptr = (pr_reg->pr_reg_list.next); (typeof(*pr_reg) *)( 
(char *)__mptr - __builtin_offsetof(typeof(*pr_reg),pr_reg_list) );}))
 {
  if ((add_len + 8) > (cmd->data_length - 8))
   break;
  buf[off++] = ((pr_reg->pr_res_key >> 56) & 0xff);
  buf[off++] = ((pr_reg->pr_res_key >> 48) & 0xff);
  buf[off++] = ((pr_reg->pr_res_key >> 40) & 0xff);
  buf[off++] = ((pr_reg->pr_res_key >> 32) & 0xff);
  buf[off++] = ((pr_reg->pr_res_key >> 24) & 0xff);
  buf[off++] = ((pr_reg->pr_res_key >> 16) & 0xff);
  buf[off++] = ((pr_reg->pr_res_key >> 8) & 0xff);
  buf[off++] = (pr_reg->pr_res_key & 0xff);
  add_len += 8;
 }
 spin_unlock(&dev->t10_pr.registration_lock);

 buf[4] = ((add_len >> 24) & 0xff);
 buf[5] = ((add_len >> 16) & 0xff);
 buf[6] = ((add_len >> 8) & 0xff);
 buf[7] = (add_len & 0xff);
 transport_kunmap_data_sg(cmd);
 return 0;
}

static sense_reason_t core_scsi3_pri_read_reservation(struct se_cmd *cmd)
{
 struct se_device *dev = cmd->se_dev;
 struct t10_pr_registration *pr_reg;
 unsigned char *buf;
 u64 pr_res_key;
 u32 add_len = 16;

 if (cmd->data_length < 8) {
  printk("\001" "3" "PRIN SA READ_RESERVATIONS SCSI Data Length: %u" " too 
small\n", cmd->data_length)
                                    ;
  return TCM_INVALID_CDB_FIELD;
 }

 buf = transport_kmap_data_sg(cmd);
 if (!buf)
  return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;

 buf[0] = ((dev->t10_pr.pr_generation >> 24) & 0xff);
 buf[1] = ((dev->t10_pr.pr_generation >> 16) & 0xff);
 buf[2] = ((dev->t10_pr.pr_generation >> 8) & 0xff);
 buf[3] = (dev->t10_pr.pr_generation & 0xff);

 spin_lock(&dev->dev_reservation_lock);
 pr_reg = dev->dev_pr_res_holder;
 if (pr_reg) {

  buf[4] = ((add_len >> 24) & 0xff);
  buf[5] = ((add_len >> 16) & 0xff);
  buf[6] = ((add_len >> 8) & 0xff);
  buf[7] = (add_len & 0xff);

  if (cmd->data_length < 22)
   goto err;
  if ((pr_reg->pr_res_type == 0x07) ||
      (pr_reg->pr_res_type == 0x08))
   pr_res_key = 0;
  else
   pr_res_key = pr_reg->pr_res_key;

  buf[8] = ((pr_res_key >> 56) & 0xff);
  buf[9] = ((pr_res_key >> 48) & 0xff);
  buf[10] = ((pr_res_key >> 40) & 0xff);
  buf[11] = ((pr_res_key >> 32) & 0xff);
  buf[12] = ((pr_res_key >> 24) & 0xff);
  buf[13] = ((pr_res_key >> 16) & 0xff);
  buf[14] = ((pr_res_key >> 8) & 0xff);
  buf[15] = (pr_res_key & 0xff);
  buf[21] = (pr_reg->pr_res_scope & 0xf0) |
     (pr_reg->pr_res_type & 0x0f);
 }

err:
 spin_unlock(&dev->dev_reservation_lock);
 transport_kunmap_data_sg(cmd);
 return 0;
}


static sense_reason_t core_scsi3_pri_report_capabilities(struct se_cmd *cmd)
{
 struct se_device *dev = cmd->se_dev;
 struct t10_reservation *pr_tmpl = &dev->t10_pr;
 unsigned char *buf;
 u16 add_len = 8;

 if (cmd->data_length < 6) {
  printk("\001" "3" "PRIN SA REPORT_CAPABILITIES SCSI Data Length:" " %u too 
small\n", cmd->data_length);
  return TCM_INVALID_CDB_FIELD;
 }

 buf = transport_kmap_data_sg(cmd);
 if (!buf)
  return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;

 buf[0] = ((add_len << 8) & 0xff);
 buf[1] = (add_len & 0xff);
 buf[2] |= 0x10;
 buf[2] |= 0x08;
 buf[2] |= 0x04;
 buf[2] |= 0x01;
 buf[3] |= 0x80;
 buf[3] |= 0x10;

 if (pr_tmpl->pr_aptpl_active)
  buf[3] |= 0x01;

 buf[4] |= 0x80;
 buf[4] |= 0x40;
 buf[4] |= 0x20;
 buf[4] |= 0x08;
 buf[4] |= 0x02;
 buf[5] |= 0x01;

 transport_kunmap_data_sg(cmd);
 return 0;
}

static sense_reason_t
core_scsi3_pri_read_full_status(struct se_cmd *cmd)
{
 struct se_device *dev = cmd->se_dev;
 struct se_node_acl *se_nacl;
 struct se_portal_group *se_tpg;
 struct t10_pr_registration *pr_reg, *pr_reg_tmp;
 struct t10_reservation *pr_tmpl = &dev->t10_pr;
 unsigned char *buf;
 u32 add_desc_len = 0, add_len = 0, desc_len, exp_desc_len;
 u32 off = 8;
 int format_code = 0;

 if (cmd->data_length < 8) {
  printk("\001" "3" "PRIN SA READ_FULL_STATUS SCSI Data Length: %u" " too 
small\n", cmd->data_length)
                                    ;
  return TCM_INVALID_CDB_FIELD;
 }

 buf = transport_kmap_data_sg(cmd);
 if (!buf)
  return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;

 buf[0] = ((dev->t10_pr.pr_generation >> 24) & 0xff);
 buf[1] = ((dev->t10_pr.pr_generation >> 16) & 0xff);
 buf[2] = ((dev->t10_pr.pr_generation >> 8) & 0xff);
 buf[3] = (dev->t10_pr.pr_generation & 0xff);

 spin_lock(&pr_tmpl->registration_lock);
 for (pr_reg = ({ const typeof( ((typeof(*pr_reg) *)0)->pr_reg_list ) *__mptr = 
((&pr_tmpl->registration_list)->next); (typeof(*pr_reg) *)( (char *)__mptr - 
__builtin_offsetof(typeof(*pr_reg),pr_reg_list) );}), pr_reg_tmp = ({ const 
typeof( ((typeof(*pr_reg) *)0)->pr_reg_list ) *__mptr = 
(pr_reg->pr_reg_list.next); (typeof(*pr_reg) *)( (char *)__mptr - 
__builtin_offsetof(typeof(*pr_reg),pr_reg_list) );}); &pr_reg->pr_reg_list != 
(&pr_tmpl->registration_list); pr_reg = pr_reg_tmp, pr_reg_tmp = ({ const 
typeof( ((typeof(*pr_reg_tmp) *)0)->pr_reg_list ) *__mptr = 
(pr_reg_tmp->pr_reg_list.next); (typeof(*pr_reg_tmp) *)( (char *)__mptr - 
__builtin_offsetof(typeof(*pr_reg_tmp),pr_reg_list) );}))
                                             {

  se_nacl = pr_reg->pr_reg_nacl;
  se_tpg = pr_reg->pr_reg_nacl->se_tpg;
  add_desc_len = 0;
  atomic_add(1, &pr_reg->pr_res_holders);
  spin_unlock(&pr_tmpl->registration_lock);

  exp_desc_len = se_tpg->se_tpg_tfo->tpg_get_pr_transport_id_len(
    se_tpg, se_nacl, pr_reg, &format_code);

  if ((exp_desc_len + add_len) > cmd->data_length) {
   printk("\001" "4" "SPC-3 PRIN READ_FULL_STATUS ran" " out of buffer: %d\n", 
cmd->data_length)
                                             ;
   spin_lock(&pr_tmpl->registration_lock);
   atomic_sub(1, &pr_reg->pr_res_holders);
   break;
  }


  buf[off++] = ((pr_reg->pr_res_key >> 56) & 0xff);
  buf[off++] = ((pr_reg->pr_res_key >> 48) & 0xff);
  buf[off++] = ((pr_reg->pr_res_key >> 40) & 0xff);
  buf[off++] = ((pr_reg->pr_res_key >> 32) & 0xff);
  buf[off++] = ((pr_reg->pr_res_key >> 24) & 0xff);
  buf[off++] = ((pr_reg->pr_res_key >> 16) & 0xff);
  buf[off++] = ((pr_reg->pr_res_key >> 8) & 0xff);
  buf[off++] = (pr_reg->pr_res_key & 0xff);
  off += 4;

  if (pr_reg->pr_reg_all_tg_pt)
   buf[off] = 0x02;

  if (pr_reg->pr_res_holder) {
   buf[off++] |= 0x01;
   buf[off++] = (pr_reg->pr_res_scope & 0xf0) |
         (pr_reg->pr_res_type & 0x0f);
  } else
   off += 2;

  off += 4;
  if (!pr_reg->pr_reg_all_tg_pt) {
   struct se_port *port = pr_reg->pr_reg_tg_pt_lun->lun_sep;

   buf[off++] = ((port->sep_rtpi >> 8) & 0xff);
   buf[off++] = (port->sep_rtpi & 0xff);
  } else
   off += 2;

  desc_len = se_tpg->se_tpg_tfo->tpg_get_pr_transport_id(se_tpg,
    se_nacl, pr_reg, &format_code, &buf[off+4]);

  spin_lock(&pr_tmpl->registration_lock);
  atomic_sub(1, &pr_reg->pr_res_holders);

  buf[off++] = ((desc_len >> 24) & 0xff);
  buf[off++] = ((desc_len >> 16) & 0xff);
  buf[off++] = ((desc_len >> 8) & 0xff);
  buf[off++] = (desc_len & 0xff);

  add_desc_len = (24 + desc_len);

  off += desc_len;
  add_len += add_desc_len;
 }
 spin_unlock(&pr_tmpl->registration_lock);

 buf[4] = ((add_len >> 24) & 0xff);
 buf[5] = ((add_len >> 16) & 0xff);
 buf[6] = ((add_len >> 8) & 0xff);
 buf[7] = (add_len & 0xff);
 transport_kunmap_data_sg(cmd);
 return 0;
}

sense_reason_t target_scsi3_emulate_pr_in(struct se_cmd *cmd)
{
 sense_reason_t ret;
 if (cmd->se_dev->dev_reservation_flags & 0x00000001) {
  printk("\001" "3" "Received PERSISTENT_RESERVE CDB while legacy" " SPC-2 
reservation is held, returning" " RESERVATION_CONFLICT\n");
  return TCM_RESERVATION_CONFLICT;
 }

 switch (cmd->t_task_cdb[1] & 0x1f) {
 case 0x00:
  ret = core_scsi3_pri_read_keys(cmd);
  break;
 case 0x01:
  ret = core_scsi3_pri_read_reservation(cmd);
  break;
 case 0x02:
  ret = core_scsi3_pri_report_capabilities(cmd);
  break;
 case 0x03:
  ret = core_scsi3_pri_read_full_status(cmd);
  break;
 default:
  printk("\001" "3" "Unknown PERSISTENT_RESERVE_IN service" " action: 
0x%02x\n", cmd->t_task_cdb[1] & 0x1f)
                                                  ;
  return TCM_INVALID_CDB_FIELD;
 }

 if (!ret)
  target_complete_cmd(cmd, 0x00);
 return ret;
}

Reply via email to