aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/target
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2011-11-03 17:50:41 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2011-11-04 04:00:17 -0400
commit617c0e06c1b30b799d8b25f92eefdc1b098cb9f8 (patch)
treec256c38e2bbf9fb1a17cd5d821efca0839060821 /drivers/target
parenteacac00ce5bfde8086cd0615fb53c986f7f970fe (diff)
target: split core_scsi3_emulate_pr
Split core_scsi2_emulate_crh into one routine each for the PERSISTENT_RESERVE_IN and PERSISTENT_RESERVE_OUT side. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target')
-rw-r--r--drivers/target/target_core_pr.c62
-rw-r--r--drivers/target/target_core_pr.h4
-rw-r--r--drivers/target/target_core_transport.c11
3 files changed, 45 insertions, 32 deletions
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c
index 830953a743d6..34403e80b87c 100644
--- a/drivers/target/target_core_pr.c
+++ b/drivers/target/target_core_pr.c
@@ -3734,12 +3734,30 @@ static unsigned long long core_scsi3_extract_reservation_key(unsigned char *cdb)
3734/* 3734/*
3735 * See spc4r17 section 6.14 Table 170 3735 * See spc4r17 section 6.14 Table 170
3736 */ 3736 */
3737static int core_scsi3_emulate_pr_out(struct se_cmd *cmd, unsigned char *cdb) 3737int target_scsi3_emulate_pr_out(struct se_cmd *cmd)
3738{ 3738{
3739 unsigned char *cdb = &cmd->t_task_cdb[0];
3739 unsigned char *buf; 3740 unsigned char *buf;
3740 u64 res_key, sa_res_key; 3741 u64 res_key, sa_res_key;
3741 int sa, scope, type, aptpl; 3742 int sa, scope, type, aptpl;
3742 int spec_i_pt = 0, all_tg_pt = 0, unreg = 0; 3743 int spec_i_pt = 0, all_tg_pt = 0, unreg = 0;
3744
3745 /*
3746 * Following spc2r20 5.5.1 Reservations overview:
3747 *
3748 * If a logical unit has been reserved by any RESERVE command and is
3749 * still reserved by any initiator, all PERSISTENT RESERVE IN and all
3750 * PERSISTENT RESERVE OUT commands shall conflict regardless of
3751 * initiator or service action and shall terminate with a RESERVATION
3752 * CONFLICT status.
3753 */
3754 if (cmd->se_dev->dev_flags & DF_SPC2_RESERVATIONS) {
3755 pr_err("Received PERSISTENT_RESERVE CDB while legacy"
3756 " SPC-2 reservation is held, returning"
3757 " RESERVATION_CONFLICT\n");
3758 return PYX_TRANSPORT_RESERVATION_CONFLICT;
3759 }
3760
3743 /* 3761 /*
3744 * FIXME: A NULL struct se_session pointer means an this is not coming from 3762 * FIXME: A NULL struct se_session pointer means an this is not coming from
3745 * a $FABRIC_MOD's nexus, but from internal passthrough ops. 3763 * a $FABRIC_MOD's nexus, but from internal passthrough ops.
@@ -4185,29 +4203,8 @@ static int core_scsi3_pri_read_full_status(struct se_cmd *cmd)
4185 return 0; 4203 return 0;
4186} 4204}
4187 4205
4188static int core_scsi3_emulate_pr_in(struct se_cmd *cmd, unsigned char *cdb) 4206int target_scsi3_emulate_pr_in(struct se_cmd *cmd)
4189{
4190 switch (cdb[1] & 0x1f) {
4191 case PRI_READ_KEYS:
4192 return core_scsi3_pri_read_keys(cmd);
4193 case PRI_READ_RESERVATION:
4194 return core_scsi3_pri_read_reservation(cmd);
4195 case PRI_REPORT_CAPABILITIES:
4196 return core_scsi3_pri_report_capabilities(cmd);
4197 case PRI_READ_FULL_STATUS:
4198 return core_scsi3_pri_read_full_status(cmd);
4199 default:
4200 pr_err("Unknown PERSISTENT_RESERVE_IN service"
4201 " action: 0x%02x\n", cdb[1] & 0x1f);
4202 return PYX_TRANSPORT_INVALID_CDB_FIELD;
4203 }
4204
4205}
4206
4207int core_scsi3_emulate_pr(struct se_cmd *cmd)
4208{ 4207{
4209 unsigned char *cdb = &cmd->t_task_cdb[0];
4210 struct se_device *dev = cmd->se_dev;
4211 /* 4208 /*
4212 * Following spc2r20 5.5.1 Reservations overview: 4209 * Following spc2r20 5.5.1 Reservations overview:
4213 * 4210 *
@@ -4217,16 +4214,27 @@ int core_scsi3_emulate_pr(struct se_cmd *cmd)
4217 * initiator or service action and shall terminate with a RESERVATION 4214 * initiator or service action and shall terminate with a RESERVATION
4218 * CONFLICT status. 4215 * CONFLICT status.
4219 */ 4216 */
4220 if (dev->dev_flags & DF_SPC2_RESERVATIONS) { 4217 if (cmd->se_dev->dev_flags & DF_SPC2_RESERVATIONS) {
4221 pr_err("Received PERSISTENT_RESERVE CDB while legacy" 4218 pr_err("Received PERSISTENT_RESERVE CDB while legacy"
4222 " SPC-2 reservation is held, returning" 4219 " SPC-2 reservation is held, returning"
4223 " RESERVATION_CONFLICT\n"); 4220 " RESERVATION_CONFLICT\n");
4224 return PYX_TRANSPORT_RESERVATION_CONFLICT; 4221 return PYX_TRANSPORT_RESERVATION_CONFLICT;
4225 } 4222 }
4226 4223
4227 return (cdb[0] == PERSISTENT_RESERVE_OUT) ? 4224 switch (cmd->t_task_cdb[1] & 0x1f) {
4228 core_scsi3_emulate_pr_out(cmd, cdb) : 4225 case PRI_READ_KEYS:
4229 core_scsi3_emulate_pr_in(cmd, cdb); 4226 return core_scsi3_pri_read_keys(cmd);
4227 case PRI_READ_RESERVATION:
4228 return core_scsi3_pri_read_reservation(cmd);
4229 case PRI_REPORT_CAPABILITIES:
4230 return core_scsi3_pri_report_capabilities(cmd);
4231 case PRI_READ_FULL_STATUS:
4232 return core_scsi3_pri_read_full_status(cmd);
4233 default:
4234 pr_err("Unknown PERSISTENT_RESERVE_IN service"
4235 " action: 0x%02x\n", cmd->t_task_cdb[1] & 0x1f);
4236 return PYX_TRANSPORT_INVALID_CDB_FIELD;
4237 }
4230} 4238}
4231 4239
4232static int core_pt_reservation_check(struct se_cmd *cmd, u32 *pr_res_type) 4240static int core_pt_reservation_check(struct se_cmd *cmd, u32 *pr_res_type)
diff --git a/drivers/target/target_core_pr.h b/drivers/target/target_core_pr.h
index 4e94a427e314..c9acb1108124 100644
--- a/drivers/target/target_core_pr.h
+++ b/drivers/target/target_core_pr.h
@@ -62,7 +62,9 @@ extern void core_scsi3_free_all_registrations(struct se_device *);
62extern unsigned char *core_scsi3_pr_dump_type(int); 62extern unsigned char *core_scsi3_pr_dump_type(int);
63extern int core_scsi3_check_cdb_abort_and_preempt(struct list_head *, 63extern int core_scsi3_check_cdb_abort_and_preempt(struct list_head *,
64 struct se_cmd *); 64 struct se_cmd *);
65extern int core_scsi3_emulate_pr(struct se_cmd *); 65
66extern int target_scsi3_emulate_pr_in(struct se_cmd *cmd);
67extern int target_scsi3_emulate_pr_out(struct se_cmd *cmd);
66extern int core_setup_reservations(struct se_device *, int); 68extern int core_setup_reservations(struct se_device *, int);
67 69
68#endif /* TARGET_CORE_PR_H */ 70#endif /* TARGET_CORE_PR_H */
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index f4232934bac5..717f84a9b42b 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -2842,11 +2842,14 @@ static int transport_generic_cmd_sequencer(
2842 cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; 2842 cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
2843 break; 2843 break;
2844 case PERSISTENT_RESERVE_IN: 2844 case PERSISTENT_RESERVE_IN:
2845 if (su_dev->t10_pr.res_type == SPC3_PERSISTENT_RESERVATIONS)
2846 cmd->transport_emulate_cdb = target_scsi3_emulate_pr_in;
2847 size = (cdb[7] << 8) + cdb[8];
2848 cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
2849 break;
2845 case PERSISTENT_RESERVE_OUT: 2850 case PERSISTENT_RESERVE_OUT:
2846 cmd->transport_emulate_cdb = 2851 if (su_dev->t10_pr.res_type == SPC3_PERSISTENT_RESERVATIONS)
2847 (su_dev->t10_pr.res_type == 2852 cmd->transport_emulate_cdb = target_scsi3_emulate_pr_out;
2848 SPC3_PERSISTENT_RESERVATIONS) ?
2849 core_scsi3_emulate_pr : NULL;
2850 size = (cdb[7] << 8) + cdb[8]; 2853 size = (cdb[7] << 8) + cdb[8];
2851 cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; 2854 cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
2852 break; 2855 break;