aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@HansenPartnership.com>2008-02-06 14:01:58 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-02-07 19:02:44 -0500
commit38582a62ecd337de4212004c7d4844899dc57890 (patch)
tree44a331ae517ad2307583e3aa3774445c39dc91a8
parentd6a451dd4d7ec805f9a21bb1994ce8ceaecc8fe6 (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>
-rw-r--r--drivers/scsi/sr.c49
-rw-r--r--drivers/scsi/sr.h1
-rw-r--r--drivers/scsi/sr_ioctl.c3
3 files changed, 29 insertions, 24 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 */
168int 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,
diff --git a/drivers/scsi/sr.h b/drivers/scsi/sr.h
index 81fbc0b78a52..1e144dfdbd4b 100644
--- a/drivers/scsi/sr.h
+++ b/drivers/scsi/sr.h
@@ -61,6 +61,7 @@ int sr_select_speed(struct cdrom_device_info *cdi, int speed);
61int sr_audio_ioctl(struct cdrom_device_info *, unsigned int, void *); 61int sr_audio_ioctl(struct cdrom_device_info *, unsigned int, void *);
62 62
63int sr_is_xa(Scsi_CD *); 63int sr_is_xa(Scsi_CD *);
64int sr_test_unit_ready(struct scsi_device *sdev, struct scsi_sense_hdr *sshdr);
64 65
65/* sr_vendor.c */ 66/* sr_vendor.c */
66void sr_vendor_init(Scsi_CD *); 67void sr_vendor_init(Scsi_CD *);
diff --git a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c
index d5cebff1d646..ae87d08df588 100644
--- a/drivers/scsi/sr_ioctl.c
+++ b/drivers/scsi/sr_ioctl.c
@@ -306,8 +306,7 @@ int sr_drive_status(struct cdrom_device_info *cdi, int slot)
306 /* we have no changer support */ 306 /* we have no changer support */
307 return -EINVAL; 307 return -EINVAL;
308 } 308 }
309 if (0 == scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, 309 if (0 == sr_test_unit_ready(cd->device, &sshdr))
310 &sshdr))
311 return CDS_DISC_OK; 310 return CDS_DISC_OK;
312 311
313 if (!cdrom_get_media_event(cdi, &med)) { 312 if (!cdrom_get_media_event(cdi, &med)) {