target: split core_scsi3_emulate_pr
[pandora-kernel.git] / drivers / target / target_core_pr.c
index 830953a..34403e8 100644 (file)
@@ -3734,12 +3734,30 @@ static unsigned long long core_scsi3_extract_reservation_key(unsigned char *cdb)
 /*
  * See spc4r17 section 6.14 Table 170
  */
-static int core_scsi3_emulate_pr_out(struct se_cmd *cmd, unsigned char *cdb)
+int target_scsi3_emulate_pr_out(struct se_cmd *cmd)
 {
+       unsigned char *cdb = &cmd->t_task_cdb[0];
        unsigned char *buf;
        u64 res_key, sa_res_key;
        int sa, scope, type, aptpl;
        int spec_i_pt = 0, all_tg_pt = 0, unreg = 0;
+
+       /*
+        * Following spc2r20 5.5.1 Reservations overview:
+        *
+        * If a logical unit has been reserved by any RESERVE command and is
+        * still reserved by any initiator, all PERSISTENT RESERVE IN and all
+        * PERSISTENT RESERVE OUT commands shall conflict regardless of
+        * initiator or service action and shall terminate with a RESERVATION
+        * CONFLICT status.
+        */
+       if (cmd->se_dev->dev_flags & DF_SPC2_RESERVATIONS) {
+               pr_err("Received PERSISTENT_RESERVE CDB while legacy"
+                       " SPC-2 reservation is held, returning"
+                       " RESERVATION_CONFLICT\n");
+               return PYX_TRANSPORT_RESERVATION_CONFLICT;
+       }
+
        /*
         * FIXME: A NULL struct se_session pointer means an this is not coming from
         * 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)
        return 0;
 }
 
-static int core_scsi3_emulate_pr_in(struct se_cmd *cmd, unsigned char *cdb)
-{
-       switch (cdb[1] & 0x1f) {
-       case PRI_READ_KEYS:
-               return core_scsi3_pri_read_keys(cmd);
-       case PRI_READ_RESERVATION:
-               return core_scsi3_pri_read_reservation(cmd);
-       case PRI_REPORT_CAPABILITIES:
-               return core_scsi3_pri_report_capabilities(cmd);
-       case PRI_READ_FULL_STATUS:
-               return core_scsi3_pri_read_full_status(cmd);
-       default:
-               pr_err("Unknown PERSISTENT_RESERVE_IN service"
-                       " action: 0x%02x\n", cdb[1] & 0x1f);
-               return PYX_TRANSPORT_INVALID_CDB_FIELD;
-       }
-
-}
-
-int core_scsi3_emulate_pr(struct se_cmd *cmd)
+int target_scsi3_emulate_pr_in(struct se_cmd *cmd)
 {
-       unsigned char *cdb = &cmd->t_task_cdb[0];
-       struct se_device *dev = cmd->se_dev;
        /*
         * Following spc2r20 5.5.1 Reservations overview:
         *
@@ -4217,16 +4214,27 @@ int core_scsi3_emulate_pr(struct se_cmd *cmd)
         * initiator or service action and shall terminate with a RESERVATION
         * CONFLICT status.
         */
-       if (dev->dev_flags & DF_SPC2_RESERVATIONS) {
+       if (cmd->se_dev->dev_flags & DF_SPC2_RESERVATIONS) {
                pr_err("Received PERSISTENT_RESERVE CDB while legacy"
                        " SPC-2 reservation is held, returning"
                        " RESERVATION_CONFLICT\n");
                return PYX_TRANSPORT_RESERVATION_CONFLICT;
        }
 
-       return (cdb[0] == PERSISTENT_RESERVE_OUT) ?
-              core_scsi3_emulate_pr_out(cmd, cdb) :
-              core_scsi3_emulate_pr_in(cmd, cdb);
+       switch (cmd->t_task_cdb[1] & 0x1f) {
+       case PRI_READ_KEYS:
+               return core_scsi3_pri_read_keys(cmd);
+       case PRI_READ_RESERVATION:
+               return core_scsi3_pri_read_reservation(cmd);
+       case PRI_REPORT_CAPABILITIES:
+               return core_scsi3_pri_report_capabilities(cmd);
+       case PRI_READ_FULL_STATUS:
+               return core_scsi3_pri_read_full_status(cmd);
+       default:
+               pr_err("Unknown PERSISTENT_RESERVE_IN service"
+                       " action: 0x%02x\n", cmd->t_task_cdb[1] & 0x1f);
+               return PYX_TRANSPORT_INVALID_CDB_FIELD;
+       }
 }
 
 static int core_pt_reservation_check(struct se_cmd *cmd, u32 *pr_res_type)