aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@HansenPartnership.com>2008-01-05 11:39:51 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-01-11 19:29:17 -0500
commit210ba1d1724f5c4ed87a2ab1a21ca861a915f734 (patch)
tree4b25acf59b91e2be49faf34507f3d9eeebff76a0 /drivers
parent32e8ae36b8f80372015b88b63c4358a376c9af0f (diff)
[SCSI] sr: update to follow tray status correctly
Based on an original patch from: David Martin <tasio@tasio.net> When trying to get the drive status via ioctl CDROM_DRIVE_STATUS, with no disk it gives CDS_TRAY_OPEN even if the tray is closed. ioctl works as expected with ide-cd driver. Gentoo bug report: http://bugs.gentoo.org/show_bug.cgi?id=196879 Cc: Maarten Bressers <mbres@gentoo.org> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/sr.c2
-rw-r--r--drivers/scsi/sr.h3
-rw-r--r--drivers/scsi/sr_ioctl.c48
3 files changed, 37 insertions, 16 deletions
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index 896be4ab285d..1fcee16fa36d 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -67,8 +67,6 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_WORM);
67 67
68#define SR_DISKS 256 68#define SR_DISKS 256
69 69
70#define MAX_RETRIES 3
71#define SR_TIMEOUT (30 * HZ)
72#define SR_CAPABILITIES \ 70#define SR_CAPABILITIES \
73 (CDC_CLOSE_TRAY|CDC_OPEN_TRAY|CDC_LOCK|CDC_SELECT_SPEED| \ 71 (CDC_CLOSE_TRAY|CDC_OPEN_TRAY|CDC_LOCK|CDC_SELECT_SPEED| \
74 CDC_SELECT_DISC|CDC_MULTI_SESSION|CDC_MCN|CDC_MEDIA_CHANGED| \ 72 CDC_SELECT_DISC|CDC_MULTI_SESSION|CDC_MCN|CDC_MEDIA_CHANGED| \
diff --git a/drivers/scsi/sr.h b/drivers/scsi/sr.h
index 0d04e2878c9d..81fbc0b78a52 100644
--- a/drivers/scsi/sr.h
+++ b/drivers/scsi/sr.h
@@ -20,6 +20,9 @@
20#include <linux/genhd.h> 20#include <linux/genhd.h>
21#include <linux/kref.h> 21#include <linux/kref.h>
22 22
23#define MAX_RETRIES 3
24#define SR_TIMEOUT (30 * HZ)
25
23struct scsi_device; 26struct scsi_device;
24 27
25/* The CDROM is fairly slow, so we need a little extra time */ 28/* The CDROM is fairly slow, so we need a little extra time */
diff --git a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c
index e1589f91706a..d5cebff1d646 100644
--- a/drivers/scsi/sr_ioctl.c
+++ b/drivers/scsi/sr_ioctl.c
@@ -275,18 +275,6 @@ int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc)
275/* ---------------------------------------------------------------------- */ 275/* ---------------------------------------------------------------------- */
276/* interface to cdrom.c */ 276/* interface to cdrom.c */
277 277
278static int test_unit_ready(Scsi_CD *cd)
279{
280 struct packet_command cgc;
281
282 memset(&cgc, 0, sizeof(struct packet_command));
283 cgc.cmd[0] = GPCMD_TEST_UNIT_READY;
284 cgc.quiet = 1;
285 cgc.data_direction = DMA_NONE;
286 cgc.timeout = IOCTL_TIMEOUT;
287 return sr_do_ioctl(cd, &cgc);
288}
289
290int sr_tray_move(struct cdrom_device_info *cdi, int pos) 278int sr_tray_move(struct cdrom_device_info *cdi, int pos)
291{ 279{
292 Scsi_CD *cd = cdi->handle; 280 Scsi_CD *cd = cdi->handle;
@@ -310,14 +298,46 @@ int sr_lock_door(struct cdrom_device_info *cdi, int lock)
310 298
311int sr_drive_status(struct cdrom_device_info *cdi, int slot) 299int sr_drive_status(struct cdrom_device_info *cdi, int slot)
312{ 300{
301 struct scsi_cd *cd = cdi->handle;
302 struct scsi_sense_hdr sshdr;
303 struct media_event_desc med;
304
313 if (CDSL_CURRENT != slot) { 305 if (CDSL_CURRENT != slot) {
314 /* we have no changer support */ 306 /* we have no changer support */
315 return -EINVAL; 307 return -EINVAL;
316 } 308 }
317 if (0 == test_unit_ready(cdi->handle)) 309 if (0 == scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES,
310 &sshdr))
318 return CDS_DISC_OK; 311 return CDS_DISC_OK;
319 312
320 return CDS_TRAY_OPEN; 313 if (!cdrom_get_media_event(cdi, &med)) {
314 if (med.media_present)
315 return CDS_DISC_OK;
316 else if (med.door_open)
317 return CDS_TRAY_OPEN;
318 else
319 return CDS_NO_DISC;
320 }
321
322 /*
323 * 0x04 is format in progress .. but there must be a disc present!
324 */
325 if (sshdr.sense_key == NOT_READY && sshdr.asc == 0x04)
326 return CDS_DISC_OK;
327
328 /*
329 * If not using Mt Fuji extended media tray reports,
330 * just return TRAY_OPEN since ATAPI doesn't provide
331 * any other way to detect this...
332 */
333 if (scsi_sense_valid(&sshdr) &&
334 /* 0x3a is medium not present */
335 sshdr.asc == 0x3a)
336 return CDS_NO_DISC;
337 else
338 return CDS_TRAY_OPEN;
339
340 return CDS_DRIVE_NOT_READY;
321} 341}
322 342
323int sr_disk_status(struct cdrom_device_info *cdi) 343int sr_disk_status(struct cdrom_device_info *cdi)