[PATCH 4/5] scsi host / scsi target state model update

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add a SCSI target state model similar to the SCSI device state model.

Signed-off-by: Mike Anderson <andmike@xxxxxxxxxx>
---

 linux-2.6.12-rc6-mm1-andmike/drivers/scsi/scsi_lib.c    |   57 ++++++++++++++++
 linux-2.6.12-rc6-mm1-andmike/drivers/scsi/scsi_scan.c   |    1 
 linux-2.6.12-rc6-mm1-andmike/drivers/scsi/scsi_sysfs.c  |   23 ++++++
 linux-2.6.12-rc6-mm1-andmike/include/scsi/scsi_device.h |   13 +++
 4 files changed, 94 insertions(+)

diff -puN include/scsi/scsi_device.h~tgt_state include/scsi/scsi_device.h
--- linux-2.6.12-rc6-mm1/include/scsi/scsi_device.h~tgt_state	2005-06-16 10:47:35.000000000 -0700
+++ linux-2.6.12-rc6-mm1-andmike/include/scsi/scsi_device.h	2005-06-16 10:47:35.000000000 -0700
@@ -140,6 +140,16 @@ struct scsi_device {
 	to_scsi_device(class_dev->dev)
 
 /*
+ * stgt state:
+ * scsi_lib:scsi_device_set_state().
+ */
+enum scsi_target_state {
+	STGT_RUNNING = 1,	/* Target properly configured */
+	STGT_CANCEL,		/* Beginning to delete Target */
+	STGT_DEL,		/* Target deleted */
+};
+
+/*
  * scsi_target: representation of a scsi target, for now, this is only
  * used for single_lun devices. If no one has active IO to the target,
  * starget_sdev_user is NULL, else it points to the active sdev.
@@ -155,6 +165,7 @@ struct scsi_target {
 				     * scsi_device.id eventually */
 	unsigned long		create:1; /* signal that it needs to be added */
 	void 			*hostdata; /* available to low-level driver */
+	enum scsi_target_state	stgt_state;
 	unsigned long		starget_data[0]; /* for the transport */
 	/* starget_data must be the last element!!!! */
 } __attribute__((aligned(sizeof(unsigned long))));
@@ -233,6 +244,8 @@ extern int scsi_test_unit_ready(struct s
 				int retries);
 extern int scsi_device_set_state(struct scsi_device *sdev,
 				 enum scsi_device_state state);
+extern int scsi_target_set_state(struct scsi_target *,
+				 enum scsi_device_state);
 extern int scsi_device_quiesce(struct scsi_device *sdev);
 extern void scsi_device_resume(struct scsi_device *sdev);
 extern void scsi_target_quiesce(struct scsi_target *);
diff -puN drivers/scsi/scsi_lib.c~tgt_state drivers/scsi/scsi_lib.c
--- linux-2.6.12-rc6-mm1/drivers/scsi/scsi_lib.c~tgt_state	2005-06-16 10:47:35.000000000 -0700
+++ linux-2.6.12-rc6-mm1-andmike/drivers/scsi/scsi_lib.c	2005-06-16 10:47:35.000000000 -0700
@@ -1819,6 +1819,63 @@ scsi_device_set_state(struct scsi_device
 EXPORT_SYMBOL(scsi_device_set_state);
 
 /**
+ *	scsi_target_set_state - Take the given target through the target
+ *		state model.
+ *	@starget: scsi target 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_target_set_state(struct scsi_target *starget, enum scsi_target_state state)
+{
+	enum scsi_target_state oldstate = starget->stgt_state;
+
+	if (state == oldstate)
+		return 0;
+
+	switch (state) {
+	case STGT_RUNNING:
+		/* There are no legal states that come back to
+		 * created.  This is the manually initialised start
+		 * state */
+		goto illegal;
+
+	case STGT_CANCEL:
+		switch (oldstate) {
+		case STGT_RUNNING:
+			break;
+		default:
+			goto illegal;
+		}
+		break;
+
+	case STGT_DEL:
+		switch (oldstate) {
+		case STGT_CANCEL:
+			break;
+		default:
+			goto illegal;
+		}
+		break;
+
+	}
+	starget->stgt_state = state;
+	return 0;
+
+ illegal:
+	SCSI_LOG_ERROR_RECOVERY(1,
+				dev_printk(KERN_ERR, &starget->dev,
+					   "Illegal state transition %s->%s\n",
+					   scsi_target_state_name(oldstate),
+					   scsi_target_state_name(state))
+				);
+	return -EINVAL;
+}
+EXPORT_SYMBOL(scsi_target_set_state);
+
+/**
  *	scsi_device_quiesce - Block user issued commands.
  *	@sdev:	scsi device to quiesce.
  *
diff -puN drivers/scsi/scsi_sysfs.c~tgt_state drivers/scsi/scsi_sysfs.c
--- linux-2.6.12-rc6-mm1/drivers/scsi/scsi_sysfs.c~tgt_state	2005-06-16 10:47:35.000000000 -0700
+++ linux-2.6.12-rc6-mm1-andmike/drivers/scsi/scsi_sysfs.c	2005-06-16 10:47:35.000000000 -0700
@@ -49,6 +49,29 @@ const char *scsi_device_state_name(enum 
 }
 
 static struct {
+	enum scsi_target_state	value;
+	char			*name;
+} stgt_states[] = {
+	{ STGT_RUNNING, "running" },
+	{ STGT_CANCEL, "cancel" },
+	{ STGT_DEL, "deleted" },
+};
+
+const char *scsi_target_state_name(enum scsi_target_state state)
+{
+	int i;
+	char *name = NULL;
+
+	for (i = 0; i < sizeof(stgt_states)/sizeof(stgt_states[0]); i++) {
+		if (stgt_states[i].value == state) {
+			name = stgt_states[i].name;
+			break;
+		}
+	}
+	return name;
+}
+
+static struct {
 	enum scsi_host_state	value;
 	char			*name;
 } shost_states[] = {
diff -puN drivers/scsi/scsi_scan.c~tgt_state drivers/scsi/scsi_scan.c
--- linux-2.6.12-rc6-mm1/drivers/scsi/scsi_scan.c~tgt_state	2005-06-16 10:47:35.000000000 -0700
+++ linux-2.6.12-rc6-mm1-andmike/drivers/scsi/scsi_scan.c	2005-06-16 10:47:35.000000000 -0700
@@ -361,6 +361,7 @@ static struct scsi_target *scsi_alloc_ta
 	if (found_target)
 		goto found;
 
+	starget->stgt_state = STGT_RUNNING;
 	list_add_tail(&starget->siblings, &shost->__targets);
 	spin_unlock_irqrestore(shost->host_lock, flags);
 	/* allocate and add */
_
-
: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux