summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@HansenPartnership.com>2008-01-05 10:39:51 -0600
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-01-11 18:29:17 -0600
commit210ba1d1724f5c4ed87a2ab1a21ca861a915f734 (patch)
tree4b25acf59b91e2be49faf34507f3d9eeebff76a0
parent32e8ae36b8f80372015b88b63c4358a376c9af0f (diff)
downloadlinux-210ba1d1724f5c4ed87a2ab1a21ca861a915f734.tar.bz2
[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>
-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);
#define SR_DISKS 256
-#define MAX_RETRIES 3
-#define SR_TIMEOUT (30 * HZ)
#define SR_CAPABILITIES \
(CDC_CLOSE_TRAY|CDC_OPEN_TRAY|CDC_LOCK|CDC_SELECT_SPEED| \
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 @@
#include <linux/genhd.h>
#include <linux/kref.h>
+#define MAX_RETRIES 3
+#define SR_TIMEOUT (30 * HZ)
+
struct scsi_device;
/* 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)
/* ---------------------------------------------------------------------- */
/* interface to cdrom.c */
-static int test_unit_ready(Scsi_CD *cd)
-{
- struct packet_command cgc;
-
- memset(&cgc, 0, sizeof(struct packet_command));
- cgc.cmd[0] = GPCMD_TEST_UNIT_READY;
- cgc.quiet = 1;
- cgc.data_direction = DMA_NONE;
- cgc.timeout = IOCTL_TIMEOUT;
- return sr_do_ioctl(cd, &cgc);
-}
-
int sr_tray_move(struct cdrom_device_info *cdi, int pos)
{
Scsi_CD *cd = cdi->handle;
@@ -310,14 +298,46 @@ int sr_lock_door(struct cdrom_device_info *cdi, int lock)
int sr_drive_status(struct cdrom_device_info *cdi, int slot)
{
+ struct scsi_cd *cd = cdi->handle;
+ struct scsi_sense_hdr sshdr;
+ struct media_event_desc med;
+
if (CDSL_CURRENT != slot) {
/* we have no changer support */
return -EINVAL;
}
- if (0 == test_unit_ready(cdi->handle))
+ if (0 == scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES,
+ &sshdr))
return CDS_DISC_OK;
- return CDS_TRAY_OPEN;
+ if (!cdrom_get_media_event(cdi, &med)) {
+ if (med.media_present)
+ return CDS_DISC_OK;
+ else if (med.door_open)
+ return CDS_TRAY_OPEN;
+ else
+ return CDS_NO_DISC;
+ }
+
+ /*
+ * 0x04 is format in progress .. but there must be a disc present!
+ */
+ if (sshdr.sense_key == NOT_READY && sshdr.asc == 0x04)
+ return CDS_DISC_OK;
+
+ /*
+ * If not using Mt Fuji extended media tray reports,
+ * just return TRAY_OPEN since ATAPI doesn't provide
+ * any other way to detect this...
+ */
+ if (scsi_sense_valid(&sshdr) &&
+ /* 0x3a is medium not present */
+ sshdr.asc == 0x3a)
+ return CDS_NO_DISC;
+ else
+ return CDS_TRAY_OPEN;
+
+ return CDS_DRIVE_NOT_READY;
}
int sr_disk_status(struct cdrom_device_info *cdi)