Commit 38582a62ecd337de4212004c7d4844899dc57890
1 parent
d6a451dd4d
Exists in
master
and in
7 other branches
[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>
Showing 3 changed files with 29 additions and 24 deletions Side-by-side Diff
drivers/scsi/sr.c
... | ... | @@ -163,6 +163,29 @@ |
163 | 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 | 190 | * This function checks to see if the media has been changed in the |
168 | 191 | * CDROM drive. It is possible that we have already sensed a change, |
... | ... | @@ -185,8 +208,7 @@ |
185 | 208 | } |
186 | 209 | |
187 | 210 | sshdr = kzalloc(sizeof(*sshdr), GFP_KERNEL); |
188 | - retval = scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, | |
189 | - sshdr); | |
211 | + retval = sr_test_unit_ready(cd->device, sshdr); | |
190 | 212 | if (retval || (scsi_sense_valid(sshdr) && |
191 | 213 | /* 0x3a is medium not present */ |
192 | 214 | sshdr->asc == 0x3a)) { |
193 | 215 | |
... | ... | @@ -733,10 +755,8 @@ |
733 | 755 | { |
734 | 756 | unsigned char *buffer; |
735 | 757 | struct scsi_mode_data data; |
736 | - unsigned char cmd[MAX_COMMAND_SIZE]; | |
737 | 758 | struct scsi_sense_hdr sshdr; |
738 | - unsigned int the_result; | |
739 | - int retries, rc, n; | |
759 | + int rc, n; | |
740 | 760 | |
741 | 761 | static const char *loadmech[] = |
742 | 762 | { |
... | ... | @@ -758,23 +778,8 @@ |
758 | 778 | return; |
759 | 779 | } |
760 | 780 | |
761 | - /* issue TEST_UNIT_READY until the initial startup UNIT_ATTENTION | |
762 | - * conditions are gone, or a timeout happens | |
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))); | |
781 | + /* eat unit attentions */ | |
782 | + sr_test_unit_ready(cd->device, &sshdr); | |
778 | 783 | |
779 | 784 | /* ask for mode page 0x2a */ |
780 | 785 | rc = scsi_mode_sense(cd->device, 0, 0x2a, buffer, 128, |
drivers/scsi/sr.h
drivers/scsi/sr_ioctl.c
... | ... | @@ -306,8 +306,7 @@ |
306 | 306 | /* we have no changer support */ |
307 | 307 | return -EINVAL; |
308 | 308 | } |
309 | - if (0 == scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, | |
310 | - &sshdr)) | |
309 | + if (0 == sr_test_unit_ready(cd->device, &sshdr)) | |
311 | 310 | return CDS_DISC_OK; |
312 | 311 | |
313 | 312 | if (!cdrom_get_media_event(cdi, &med)) { |