[SCSI] Update the SCSI state model to allow blocking in the created state
Brian King <brking@linux.vnet.ibm.com> reported that fibre channel
devices can oops during scanning if their ports block (because the
device goes from CREATED -> BLOCK -> RUNNING rather than CREATED ->
BLOCK -> CREATED).
Fix this by adding a new state: CREATED_BLOCK which can only transition
back to CREATED and disallow the CREATED -> BLOCK transition. Now both
the created and blocked states that the mid-layer recognises can include
CREATED_BLOCK.
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index cc46652..b49e725 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -42,9 +42,11 @@
* originate in the mid-layer) */
SDEV_OFFLINE, /* Device offlined (by error handling or
* user request */
- SDEV_BLOCK, /* Device blocked by scsi lld. No scsi
- * commands from user or midlayer should be issued
- * to the scsi lld. */
+ SDEV_BLOCK, /* Device blocked by scsi lld. No
+ * scsi commands from user or midlayer
+ * should be issued to the scsi
+ * lld. */
+ SDEV_CREATED_BLOCK, /* same as above but for created devices */
};
enum scsi_device_event {
@@ -393,11 +395,13 @@
}
static inline int scsi_device_blocked(struct scsi_device *sdev)
{
- return sdev->sdev_state == SDEV_BLOCK;
+ return sdev->sdev_state == SDEV_BLOCK ||
+ sdev->sdev_state == SDEV_CREATED_BLOCK;
}
static inline int scsi_device_created(struct scsi_device *sdev)
{
- return sdev->sdev_state == SDEV_CREATED;
+ return sdev->sdev_state == SDEV_CREATED ||
+ sdev->sdev_state == SDEV_CREATED_BLOCK;
}
/* accessor functions for the SCSI parameters */