[PATCH] Implement SDEV_NEW state

From: Hannes Reinecke
Date: Sat Mar 08 2008 - 12:04:13 EST


When a scsi_device is allocated it's state is set to SDEV_CREATED.
However, we don't have any chance to detect if slave_alloc() has
run successfully or not.
This patch introduces a state SDEV_NEW which is used instead of
SDEV_CREATED upon initial sdev creation. After slave_alloc() has
run successfully the state is changed to SDEV_CREATED.
This allows us to detect later on if we might call slave_destroy()
or not.

Signed-off-by: Hannes Reinecke <hare@xxxxxxx>
---
drivers/scsi/scsi_lib.c | 17 +++++++++++++----
drivers/scsi/scsi_scan.c | 9 ++++++++-
drivers/scsi/scsi_sysfs.c | 1 +
include/scsi/scsi_device.h | 3 ++-
4 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index ba21d97..c398767 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1999,12 +1999,21 @@ scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state)
return 0;

switch (state) {
- case SDEV_CREATED:
+ case SDEV_NEW:
/* There are no legal states that come back to
- * created. This is the manually initialised start
+ * new. This is the manually initialised start
* state */
goto illegal;
-
+
+ case SDEV_CREATED:
+ switch (oldstate) {
+ case SDEV_NEW:
+ break;
+ default:
+ goto illegal;
+ }
+ break;
+
case SDEV_RUNNING:
switch (oldstate) {
case SDEV_CREATED:
@@ -2064,7 +2073,7 @@ scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state)

case SDEV_DEL:
switch (oldstate) {
- case SDEV_CREATED:
+ case SDEV_NEW:
case SDEV_RUNNING:
case SDEV_OFFLINE:
case SDEV_CANCEL:
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 2feab2a..aa632f9 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -253,7 +253,7 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget,
sdev->id = starget->id;
sdev->lun = lun;
sdev->channel = starget->channel;
- sdev->sdev_state = SDEV_CREATED;
+ sdev->sdev_state = SDEV_NEW;
INIT_LIST_HEAD(&sdev->siblings);
INIT_LIST_HEAD(&sdev->same_target_siblings);
INIT_LIST_HEAD(&sdev->cmd_list);
@@ -307,9 +307,16 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget,
*/
if (ret == -ENXIO)
display_failure_msg = 0;
+ /*
+ * sdev remains in SDEV_NEW as the release
+ * function has to know whether slave_alloc()
+ * failed or not.
+ */
goto out_device_destroy;
}
}
+ /* Device is created properly */
+ scsi_device_set_state(sdev, SDEV_CREATED);

return sdev;

diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index 7dc3015..3ec76dd 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -27,6 +27,7 @@ static const struct {
enum scsi_device_state value;
char *name;
} sdev_states[] = {
+ { SDEV_NEW, "new" },
{ SDEV_CREATED, "created" },
{ SDEV_RUNNING, "running" },
{ SDEV_CANCEL, "cancel" },
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index ccc437b..1616b26 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -28,7 +28,8 @@ struct scsi_mode_data {
* scsi_lib:scsi_device_set_state().
*/
enum scsi_device_state {
- SDEV_CREATED = 1, /* device created but not added to sysfs
+ SDEV_NEW = 1, /* device created, slave_alloc has not run */
+ SDEV_CREATED, /* device created but not added to sysfs
* Only internal commands allowed (for inq) */
SDEV_RUNNING, /* device properly configured
* All commands allowed */
--
1.5.3.2


--------------050407030103030004010009
Content-Type: text/x-patch;
name="0006-Rename-__scsi_remove_device-into-scsi_sysfs_remove.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename*0="0006-Rename-__scsi_remove_device-into-scsi_sysfs_remove.patc";
filename*1="h"