>From 57109790e4cb53561f36d73a8efc7b9abd2736a9 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Sat, 8 Mar 2008 18:04:13 +0100 Subject: [PATCH] Implement SDEV_NEW state 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 --- 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