diff options
author | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-08-22 17:53:31 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-10-03 12:46:13 -0400 |
commit | 6f4267e3bd1211b3d09130e626b0b3d885077610 (patch) | |
tree | e9350f919238866c3bcd9c340ffea639a0c5de1d /drivers/scsi/scsi_scan.c | |
parent | 0f1d87a2acb8fd1f2ef8af109a785123ddc1a6cb (diff) |
[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>
Diffstat (limited to 'drivers/scsi/scsi_scan.c')
-rw-r--r-- | drivers/scsi/scsi_scan.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 2926baaac31e..334862e26a1b 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c | |||
@@ -730,6 +730,8 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result, | |||
730 | static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, | 730 | static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, |
731 | int *bflags, int async) | 731 | int *bflags, int async) |
732 | { | 732 | { |
733 | int ret; | ||
734 | |||
733 | /* | 735 | /* |
734 | * XXX do not save the inquiry, since it can change underneath us, | 736 | * XXX do not save the inquiry, since it can change underneath us, |
735 | * save just vendor/model/rev. | 737 | * save just vendor/model/rev. |
@@ -885,7 +887,17 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, | |||
885 | 887 | ||
886 | /* set the device running here so that slave configure | 888 | /* set the device running here so that slave configure |
887 | * may do I/O */ | 889 | * may do I/O */ |
888 | scsi_device_set_state(sdev, SDEV_RUNNING); | 890 | ret = scsi_device_set_state(sdev, SDEV_RUNNING); |
891 | if (ret) { | ||
892 | ret = scsi_device_set_state(sdev, SDEV_BLOCK); | ||
893 | |||
894 | if (ret) { | ||
895 | sdev_printk(KERN_ERR, sdev, | ||
896 | "in wrong state %s to complete scan\n", | ||
897 | scsi_device_state_name(sdev->sdev_state)); | ||
898 | return SCSI_SCAN_NO_RESPONSE; | ||
899 | } | ||
900 | } | ||
889 | 901 | ||
890 | if (*bflags & BLIST_MS_192_BYTES_FOR_3F) | 902 | if (*bflags & BLIST_MS_192_BYTES_FOR_3F) |
891 | sdev->use_192_bytes_for_3f = 1; | 903 | sdev->use_192_bytes_for_3f = 1; |
@@ -899,7 +911,7 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, | |||
899 | transport_configure_device(&sdev->sdev_gendev); | 911 | transport_configure_device(&sdev->sdev_gendev); |
900 | 912 | ||
901 | if (sdev->host->hostt->slave_configure) { | 913 | if (sdev->host->hostt->slave_configure) { |
902 | int ret = sdev->host->hostt->slave_configure(sdev); | 914 | ret = sdev->host->hostt->slave_configure(sdev); |
903 | if (ret) { | 915 | if (ret) { |
904 | /* | 916 | /* |
905 | * if LLDD reports slave not present, don't clutter | 917 | * if LLDD reports slave not present, don't clutter |