aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_scan.c
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@HansenPartnership.com>2008-08-22 17:53:31 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-10-03 12:46:13 -0400
commit6f4267e3bd1211b3d09130e626b0b3d885077610 (patch)
treee9350f919238866c3bcd9c340ffea639a0c5de1d /drivers/scsi/scsi_scan.c
parent0f1d87a2acb8fd1f2ef8af109a785123ddc1a6cb (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.c16
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,
730static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, 730static 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