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

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
......@@ -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;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment