scsi_dh_alua: separate out alua_stpg()
authorHannes Reinecke <hare@suse.de>
Fri, 19 Feb 2016 08:16:59 +0000 (09:16 +0100)
committerMartin K. Petersen <martin.petersen@oracle.com>
Wed, 24 Feb 2016 02:27:02 +0000 (21:27 -0500)
Separate out SET TARGET PORT GROUP functionality into a separate
function alua_stpg().

Reviewed-by: Bart Van Assche <bart.vanassche@sandisk.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/device_handler/scsi_dh_alua.c

index df71e85..136bc76 100644 (file)
@@ -578,6 +578,65 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, int wait_
        return err;
 }
 
+/*
+ * alua_stpg - Issue a SET TARGET PORT GROUP command
+ *
+ * Issue a SET TARGET PORT GROUP command and evaluate the
+ * response. Returns SCSI_DH_RETRY if the target port group
+ * state is found to be in 'transitioning'.
+ * If SCSI_DH_OK is returned the passed-in 'fn' function
+ * this function will take care of executing 'fn'.
+ * Otherwise 'fn' should be executed by the caller with the
+ * returned error code.
+ */
+static unsigned alua_stpg(struct scsi_device *sdev, struct alua_dh_data *h,
+                         activate_complete fn, void *data)
+{
+       int err = SCSI_DH_OK;
+       int stpg = 0;
+
+       if (!(h->tpgs & TPGS_MODE_EXPLICIT))
+               /* Only implicit ALUA supported */
+               goto out;
+
+       switch (h->state) {
+       case TPGS_STATE_NONOPTIMIZED:
+               stpg = 1;
+               if ((h->flags & ALUA_OPTIMIZE_STPG) &&
+                   !h->pref &&
+                   (h->tpgs & TPGS_MODE_IMPLICIT))
+                       stpg = 0;
+               break;
+       case TPGS_STATE_STANDBY:
+       case TPGS_STATE_UNAVAILABLE:
+               stpg = 1;
+               break;
+       case TPGS_STATE_OFFLINE:
+               err = SCSI_DH_IO;
+               break;
+       case TPGS_STATE_TRANSITIONING:
+               err = SCSI_DH_RETRY;
+               break;
+       default:
+               break;
+       }
+
+       if (stpg) {
+               h->callback_fn = fn;
+               h->callback_data = data;
+               err = submit_stpg(h);
+               if (err != SCSI_DH_OK)
+                       h->callback_fn = h->callback_data = NULL;
+               else
+                       fn = NULL;
+       }
+out:
+       if (fn)
+               fn(data, err);
+
+       return err;
+}
+
 /*
  * alua_initialize - Initialize ALUA state
  * @sdev: the device to be initialized
@@ -655,7 +714,6 @@ static int alua_activate(struct scsi_device *sdev,
 {
        struct alua_dh_data *h = sdev->handler_data;
        int err = SCSI_DH_OK;
-       int stpg = 0;
 
        err = alua_rtpg(sdev, h, 1);
        if (err != SCSI_DH_OK)
@@ -664,41 +722,10 @@ static int alua_activate(struct scsi_device *sdev,
        if (optimize_stpg)
                h->flags |= ALUA_OPTIMIZE_STPG;
 
-       if (h->tpgs & TPGS_MODE_EXPLICIT) {
-               switch (h->state) {
-               case TPGS_STATE_NONOPTIMIZED:
-                       stpg = 1;
-                       if ((h->flags & ALUA_OPTIMIZE_STPG) &&
-                           (!h->pref) &&
-                           (h->tpgs & TPGS_MODE_IMPLICIT))
-                               stpg = 0;
-                       break;
-               case TPGS_STATE_STANDBY:
-               case TPGS_STATE_UNAVAILABLE:
-                       stpg = 1;
-                       break;
-               case TPGS_STATE_OFFLINE:
-                       err = SCSI_DH_IO;
-                       break;
-               case TPGS_STATE_TRANSITIONING:
-                       err = SCSI_DH_RETRY;
-                       break;
-               default:
-                       break;
-               }
-       }
-
-       if (stpg) {
-               h->callback_fn = fn;
-               h->callback_data = data;
-               err = submit_stpg(h);
-               if (err == SCSI_DH_OK)
-                       return 0;
-               h->callback_fn = h->callback_data = NULL;
-       }
+       err = alua_stpg(sdev, h, fn, data);
 
 out:
-       if (fn)
+       if (err != SCSI_DH_OK && fn)
                fn(data, err);
        return 0;
 }