Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d3301874 authored by Mike Anderson's avatar Mike Anderson Committed by James Bottomley
Browse files

[SCSI] host state model update: replace old host bitmap state



Migrate the current SCSI host state model to a model like SCSI
device is using.

Signed-off-by: default avatarMike Anderson <andmike@us.ibm.com>

Rejections fixed up and

Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 5dbffcd8
Loading
Loading
Loading
Loading
+82 −6
Original line number Diff line number Diff line
@@ -51,6 +51,82 @@ static struct class shost_class = {
	.release	= scsi_host_cls_release,
};

/**
 *	scsi_host_set_state - Take the given host through the host
 *		state model.
 *	@shost:	scsi host to change the state of.
 *	@state:	state to change to.
 *
 *	Returns zero if unsuccessful or an error if the requested
 *	transition is illegal.
 **/
int scsi_host_set_state(struct Scsi_Host *shost, enum scsi_host_state state)
{
	enum scsi_host_state oldstate = shost->shost_state;

	if (state == oldstate)
		return 0;

	switch (state) {
	case SHOST_CREATED:
		/* There are no legal states that come back to
		 * created.  This is the manually initialised start
		 * state */
		goto illegal;

	case SHOST_RUNNING:
		switch (oldstate) {
		case SHOST_CREATED:
		case SHOST_RECOVERY:
			break;
		default:
			goto illegal;
		}
		break;

	case SHOST_RECOVERY:
		switch (oldstate) {
		case SHOST_RUNNING:
			break;
		default:
			goto illegal;
		}
		break;

	case SHOST_CANCEL:
		switch (oldstate) {
		case SHOST_CREATED:
		case SHOST_RUNNING:
			break;
		default:
			goto illegal;
		}
		break;

	case SHOST_DEL:
		switch (oldstate) {
		case SHOST_CANCEL:
			break;
		default:
			goto illegal;
		}
		break;

	}
	shost->shost_state = state;
	return 0;

 illegal:
	SCSI_LOG_ERROR_RECOVERY(1,
				dev_printk(KERN_ERR, &shost->shost_gendev,
					   "Illegal host state transition"
					   "%s->%s\n",
					   scsi_host_state_name(oldstate),
					   scsi_host_state_name(state)));
	return -EINVAL;
}
EXPORT_SYMBOL(scsi_host_set_state);

/**
 * scsi_host_cancel - cancel outstanding IO to this host
 * @shost:	pointer to struct Scsi_Host
@@ -60,12 +136,11 @@ static void scsi_host_cancel(struct Scsi_Host *shost, int recovery)
{
	struct scsi_device *sdev;

	set_bit(SHOST_CANCEL, &shost->shost_state);
	scsi_host_set_state(shost, SHOST_CANCEL);
	shost_for_each_device(sdev, shost) {
		scsi_device_cancel(sdev, recovery);
	}
	wait_event(shost->host_wait, (!test_bit(SHOST_RECOVERY,
						&shost->shost_state)));
	wait_event(shost->host_wait, (shost->shost_state != SHOST_RECOVERY));
}

/**
@@ -78,7 +153,7 @@ void scsi_remove_host(struct Scsi_Host *shost)
	scsi_host_cancel(shost, 0);
	scsi_proc_host_rm(shost);

	set_bit(SHOST_DEL, &shost->shost_state);
	scsi_host_set_state(shost, SHOST_DEL);

	transport_unregister_device(&shost->shost_gendev);
	class_device_unregister(&shost->shost_classdev);
@@ -115,7 +190,7 @@ int scsi_add_host(struct Scsi_Host *shost, struct device *dev)
	if (error)
		goto out;

	set_bit(SHOST_ADD, &shost->shost_state);
	scsi_host_set_state(shost, SHOST_RUNNING);
	get_device(shost->shost_gendev.parent);

	error = class_device_add(&shost->shost_classdev);
@@ -226,6 +301,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)

	spin_lock_init(&shost->default_lock);
	scsi_assign_lock(shost, &shost->default_lock);
	shost->shost_state = SHOST_CREATED;
	INIT_LIST_HEAD(&shost->__devices);
	INIT_LIST_HEAD(&shost->__targets);
	INIT_LIST_HEAD(&shost->eh_cmd_q);
@@ -382,7 +458,7 @@ EXPORT_SYMBOL(scsi_host_lookup);
 **/
struct Scsi_Host *scsi_host_get(struct Scsi_Host *shost)
{
	if (test_bit(SHOST_DEL, &shost->shost_state) ||
	if ((shost->shost_state == SHOST_DEL) ||
		!get_device(&shost->shost_gendev))
		return NULL;
	return shost;
+1 −1
Original line number Diff line number Diff line
@@ -627,7 +627,7 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
	spin_lock_irqsave(host->host_lock, flags);
	scsi_cmd_get_serial(host, cmd); 

	if (unlikely(test_bit(SHOST_CANCEL, &host->shost_state))) {
	if (unlikely(host->shost_state == SHOST_CANCEL)) {
		cmd->result = (DID_NO_CONNECT << 16);
		scsi_done(cmd);
	} else {
+4 −3
Original line number Diff line number Diff line
@@ -75,7 +75,7 @@ int scsi_eh_scmd_add(struct scsi_cmnd *scmd, int eh_flag)

	scmd->eh_eflags |= eh_flag;
	list_add_tail(&scmd->eh_entry, &shost->eh_cmd_q);
	set_bit(SHOST_RECOVERY, &shost->shost_state);
	scsi_host_set_state(shost, SHOST_RECOVERY);
	shost->host_failed++;
	scsi_eh_wakeup(shost);
	spin_unlock_irqrestore(shost->host_lock, flags);
@@ -197,7 +197,8 @@ int scsi_block_when_processing_errors(struct scsi_device *sdev)
{
	int online;

	wait_event(sdev->host->host_wait, (!test_bit(SHOST_RECOVERY, &sdev->host->shost_state)));
	wait_event(sdev->host->host_wait, (sdev->host->shost_state !=
					   SHOST_RECOVERY));

	online = scsi_device_online(sdev);

@@ -1458,7 +1459,7 @@ static void scsi_restart_operations(struct Scsi_Host *shost)
	SCSI_LOG_ERROR_RECOVERY(3, printk("%s: waking up host to restart\n",
					  __FUNCTION__));

	clear_bit(SHOST_RECOVERY, &shost->shost_state);
	scsi_host_set_state(shost, SHOST_RUNNING);

	wake_up(&shost->host_wait);

+1 −2
Original line number Diff line number Diff line
@@ -475,8 +475,7 @@ int scsi_nonblockable_ioctl(struct scsi_device *sdev, int cmd,
	 * error processing, as long as the device was opened
	 * non-blocking */
	if (filp && filp->f_flags & O_NONBLOCK) {
		if (test_bit(SHOST_RECOVERY,
			     &sdev->host->shost_state))
		if (sdev->host->shost_state == SHOST_RECOVERY)
			return -ENODEV;
	} else if (!scsi_block_when_processing_errors(sdev))
		return -ENODEV;
+2 −2
Original line number Diff line number Diff line
@@ -348,7 +348,7 @@ void scsi_device_unbusy(struct scsi_device *sdev)

	spin_lock_irqsave(shost->host_lock, flags);
	shost->host_busy--;
	if (unlikely(test_bit(SHOST_RECOVERY, &shost->shost_state) &&
	if (unlikely((shost->shost_state == SHOST_RECOVERY) &&
		     shost->host_failed))
		scsi_eh_wakeup(shost);
	spin_unlock(shost->host_lock);
@@ -1207,7 +1207,7 @@ static inline int scsi_host_queue_ready(struct request_queue *q,
				   struct Scsi_Host *shost,
				   struct scsi_device *sdev)
{
	if (test_bit(SHOST_RECOVERY, &shost->shost_state))
	if (shost->shost_state == SHOST_RECOVERY)
		return 0;
	if (shost->host_busy == 0 && shost->host_blocked) {
		/*
Loading