| 1 |
From: James Bottomley <James.Bottomley@HansenPartnership.com>
|
| 2 |
Date: Sat, 5 Jan 2008 16:39:51 +0000 (-0600)
|
| 3 |
Subject: [SCSI] sr: update to follow tray status correctly
|
| 4 |
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=210ba1d1724f5c4ed87a2ab1a21ca861a915f734
|
| 5 |
|
| 6 |
[SCSI] sr: update to follow tray status correctly
|
| 7 |
|
| 8 |
Based on an original patch from: David Martin <tasio@tasio.net>
|
| 9 |
|
| 10 |
When trying to get the drive status via ioctl CDROM_DRIVE_STATUS, with
|
| 11 |
no disk it gives CDS_TRAY_OPEN even if the tray is closed.
|
| 12 |
|
| 13 |
ioctl works as expected with ide-cd driver.
|
| 14 |
|
| 15 |
Gentoo bug report: http://bugs.gentoo.org/show_bug.cgi?id=196879
|
| 16 |
|
| 17 |
Cc: Maarten Bressers <mbres@gentoo.org>
|
| 18 |
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
|
| 19 |
---
|
| 20 |
|
| 21 |
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
|
| 22 |
index 896be4a..1fcee16 100644
|
| 23 |
--- a/drivers/scsi/sr.c
|
| 24 |
+++ b/drivers/scsi/sr.c
|
| 25 |
@@ -67,8 +67,6 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_WORM);
|
| 26 |
|
| 27 |
#define SR_DISKS 256
|
| 28 |
|
| 29 |
-#define MAX_RETRIES 3
|
| 30 |
-#define SR_TIMEOUT (30 * HZ)
|
| 31 |
#define SR_CAPABILITIES \
|
| 32 |
(CDC_CLOSE_TRAY|CDC_OPEN_TRAY|CDC_LOCK|CDC_SELECT_SPEED| \
|
| 33 |
CDC_SELECT_DISC|CDC_MULTI_SESSION|CDC_MCN|CDC_MEDIA_CHANGED| \
|
| 34 |
diff --git a/drivers/scsi/sr.h b/drivers/scsi/sr.h
|
| 35 |
index 0d04e28..81fbc0b 100644
|
| 36 |
--- a/drivers/scsi/sr.h
|
| 37 |
+++ b/drivers/scsi/sr.h
|
| 38 |
@@ -20,6 +20,9 @@
|
| 39 |
#include <linux/genhd.h>
|
| 40 |
#include <linux/kref.h>
|
| 41 |
|
| 42 |
+#define MAX_RETRIES 3
|
| 43 |
+#define SR_TIMEOUT (30 * HZ)
|
| 44 |
+
|
| 45 |
struct scsi_device;
|
| 46 |
|
| 47 |
/* The CDROM is fairly slow, so we need a little extra time */
|
| 48 |
diff --git a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c
|
| 49 |
index e1589f9..d5cebff 100644
|
| 50 |
--- a/drivers/scsi/sr_ioctl.c
|
| 51 |
+++ b/drivers/scsi/sr_ioctl.c
|
| 52 |
@@ -275,18 +275,6 @@ int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc)
|
| 53 |
/* ---------------------------------------------------------------------- */
|
| 54 |
/* interface to cdrom.c */
|
| 55 |
|
| 56 |
-static int test_unit_ready(Scsi_CD *cd)
|
| 57 |
-{
|
| 58 |
- struct packet_command cgc;
|
| 59 |
-
|
| 60 |
- memset(&cgc, 0, sizeof(struct packet_command));
|
| 61 |
- cgc.cmd[0] = GPCMD_TEST_UNIT_READY;
|
| 62 |
- cgc.quiet = 1;
|
| 63 |
- cgc.data_direction = DMA_NONE;
|
| 64 |
- cgc.timeout = IOCTL_TIMEOUT;
|
| 65 |
- return sr_do_ioctl(cd, &cgc);
|
| 66 |
-}
|
| 67 |
-
|
| 68 |
int sr_tray_move(struct cdrom_device_info *cdi, int pos)
|
| 69 |
{
|
| 70 |
Scsi_CD *cd = cdi->handle;
|
| 71 |
@@ -310,14 +298,46 @@ int sr_lock_door(struct cdrom_device_info *cdi, int lock)
|
| 72 |
|
| 73 |
int sr_drive_status(struct cdrom_device_info *cdi, int slot)
|
| 74 |
{
|
| 75 |
+ struct scsi_cd *cd = cdi->handle;
|
| 76 |
+ struct scsi_sense_hdr sshdr;
|
| 77 |
+ struct media_event_desc med;
|
| 78 |
+
|
| 79 |
if (CDSL_CURRENT != slot) {
|
| 80 |
/* we have no changer support */
|
| 81 |
return -EINVAL;
|
| 82 |
}
|
| 83 |
- if (0 == test_unit_ready(cdi->handle))
|
| 84 |
+ if (0 == scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES,
|
| 85 |
+ &sshdr))
|
| 86 |
return CDS_DISC_OK;
|
| 87 |
|
| 88 |
- return CDS_TRAY_OPEN;
|
| 89 |
+ if (!cdrom_get_media_event(cdi, &med)) {
|
| 90 |
+ if (med.media_present)
|
| 91 |
+ return CDS_DISC_OK;
|
| 92 |
+ else if (med.door_open)
|
| 93 |
+ return CDS_TRAY_OPEN;
|
| 94 |
+ else
|
| 95 |
+ return CDS_NO_DISC;
|
| 96 |
+ }
|
| 97 |
+
|
| 98 |
+ /*
|
| 99 |
+ * 0x04 is format in progress .. but there must be a disc present!
|
| 100 |
+ */
|
| 101 |
+ if (sshdr.sense_key == NOT_READY && sshdr.asc == 0x04)
|
| 102 |
+ return CDS_DISC_OK;
|
| 103 |
+
|
| 104 |
+ /*
|
| 105 |
+ * If not using Mt Fuji extended media tray reports,
|
| 106 |
+ * just return TRAY_OPEN since ATAPI doesn't provide
|
| 107 |
+ * any other way to detect this...
|
| 108 |
+ */
|
| 109 |
+ if (scsi_sense_valid(&sshdr) &&
|
| 110 |
+ /* 0x3a is medium not present */
|
| 111 |
+ sshdr.asc == 0x3a)
|
| 112 |
+ return CDS_NO_DISC;
|
| 113 |
+ else
|
| 114 |
+ return CDS_TRAY_OPEN;
|
| 115 |
+
|
| 116 |
+ return CDS_DRIVE_NOT_READY;
|
| 117 |
}
|
| 118 |
|
| 119 |
int sr_disk_status(struct cdrom_device_info *cdi)
|