diff options
author | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-02-06 14:01:58 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-02-07 19:02:44 -0500 |
commit | 38582a62ecd337de4212004c7d4844899dc57890 (patch) | |
tree | 44a331ae517ad2307583e3aa3774445c39dc91a8 /drivers/scsi/sr.c | |
parent | d6a451dd4d7ec805f9a21bb1994ce8ceaecc8fe6 (diff) |
[SCSI] sr: fix test unit ready responses
Commit 210ba1d1724f5c4ed87a2ab1a21ca861a915f734 updated sr.c to use
the scsi_test_unit_ready() function. Unfortunately, this has the
wrong characteristic of eating NOT_READY returns which sr.c relies on
for tray status.
Fix by rolling an internal sr_test_unit_ready() that doesn't do this.
Tested-by: Daniel Drake <dsd@gentoo.org>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/sr.c')
-rw-r--r-- | drivers/scsi/sr.c | 49 |
1 files changed, 27 insertions, 22 deletions
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 50ba49250203..208565bdbe8e 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c | |||
@@ -163,6 +163,29 @@ static void scsi_cd_put(struct scsi_cd *cd) | |||
163 | mutex_unlock(&sr_ref_mutex); | 163 | mutex_unlock(&sr_ref_mutex); |
164 | } | 164 | } |
165 | 165 | ||
166 | /* identical to scsi_test_unit_ready except that it doesn't | ||
167 | * eat the NOT_READY returns for removable media */ | ||
168 | int sr_test_unit_ready(struct scsi_device *sdev, struct scsi_sense_hdr *sshdr) | ||
169 | { | ||
170 | int retries = MAX_RETRIES; | ||
171 | int the_result; | ||
172 | u8 cmd[] = {TEST_UNIT_READY, 0, 0, 0, 0, 0 }; | ||
173 | |||
174 | /* issue TEST_UNIT_READY until the initial startup UNIT_ATTENTION | ||
175 | * conditions are gone, or a timeout happens | ||
176 | */ | ||
177 | do { | ||
178 | the_result = scsi_execute_req(sdev, cmd, DMA_NONE, NULL, | ||
179 | 0, sshdr, SR_TIMEOUT, | ||
180 | retries--); | ||
181 | |||
182 | } while (retries > 0 && | ||
183 | (!scsi_status_is_good(the_result) || | ||
184 | (scsi_sense_valid(sshdr) && | ||
185 | sshdr->sense_key == UNIT_ATTENTION))); | ||
186 | return the_result; | ||
187 | } | ||
188 | |||
166 | /* | 189 | /* |
167 | * This function checks to see if the media has been changed in the | 190 | * This function checks to see if the media has been changed in the |
168 | * CDROM drive. It is possible that we have already sensed a change, | 191 | * CDROM drive. It is possible that we have already sensed a change, |
@@ -185,8 +208,7 @@ static int sr_media_change(struct cdrom_device_info *cdi, int slot) | |||
185 | } | 208 | } |
186 | 209 | ||
187 | sshdr = kzalloc(sizeof(*sshdr), GFP_KERNEL); | 210 | sshdr = kzalloc(sizeof(*sshdr), GFP_KERNEL); |
188 | retval = scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, | 211 | retval = sr_test_unit_ready(cd->device, sshdr); |
189 | sshdr); | ||
190 | if (retval || (scsi_sense_valid(sshdr) && | 212 | if (retval || (scsi_sense_valid(sshdr) && |
191 | /* 0x3a is medium not present */ | 213 | /* 0x3a is medium not present */ |
192 | sshdr->asc == 0x3a)) { | 214 | sshdr->asc == 0x3a)) { |
@@ -733,10 +755,8 @@ static void get_capabilities(struct scsi_cd *cd) | |||
733 | { | 755 | { |
734 | unsigned char *buffer; | 756 | unsigned char *buffer; |
735 | struct scsi_mode_data data; | 757 | struct scsi_mode_data data; |
736 | unsigned char cmd[MAX_COMMAND_SIZE]; | ||
737 | struct scsi_sense_hdr sshdr; | 758 | struct scsi_sense_hdr sshdr; |
738 | unsigned int the_result; | 759 | int rc, n; |
739 | int retries, rc, n; | ||
740 | 760 | ||
741 | static const char *loadmech[] = | 761 | static const char *loadmech[] = |
742 | { | 762 | { |
@@ -758,23 +778,8 @@ static void get_capabilities(struct scsi_cd *cd) | |||
758 | return; | 778 | return; |
759 | } | 779 | } |
760 | 780 | ||
761 | /* issue TEST_UNIT_READY until the initial startup UNIT_ATTENTION | 781 | /* eat unit attentions */ |
762 | * conditions are gone, or a timeout happens | 782 | sr_test_unit_ready(cd->device, &sshdr); |
763 | */ | ||
764 | retries = 0; | ||
765 | do { | ||
766 | memset((void *)cmd, 0, MAX_COMMAND_SIZE); | ||
767 | cmd[0] = TEST_UNIT_READY; | ||
768 | |||
769 | the_result = scsi_execute_req (cd->device, cmd, DMA_NONE, NULL, | ||
770 | 0, &sshdr, SR_TIMEOUT, | ||
771 | MAX_RETRIES); | ||
772 | |||
773 | retries++; | ||
774 | } while (retries < 5 && | ||
775 | (!scsi_status_is_good(the_result) || | ||
776 | (scsi_sense_valid(&sshdr) && | ||
777 | sshdr.sense_key == UNIT_ATTENTION))); | ||
778 | 783 | ||
779 | /* ask for mode page 0x2a */ | 784 | /* ask for mode page 0x2a */ |
780 | rc = scsi_mode_sense(cd->device, 0, 0x2a, buffer, 128, | 785 | rc = scsi_mode_sense(cd->device, 0, 0x2a, buffer, 128, |