Commit f2ecf13a authored by Hannes Reinecke's avatar Hannes Reinecke Committed by Martin K. Petersen
Browse files

scsi_dh_alua: separate out alua_stpg()



Separate out SET TARGET PORT GROUP functionality into a separate
function alua_stpg().

Reviewed-by: default avatarBart Van Assche <bart.vanassche@sandisk.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarHannes Reinecke <hare@suse.de>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent d42ae5f3
Loading
Loading
Loading
Loading
+61 −34
Original line number Diff line number Diff line
@@ -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;
}