提交 210ba1d1 编写于 作者: J James Bottomley

[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: NJames Bottomley <James.Bottomley@HansenPartnership.com>
上级 32e8ae36
...@@ -67,8 +67,6 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_WORM); ...@@ -67,8 +67,6 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_WORM);
#define SR_DISKS 256 #define SR_DISKS 256
#define MAX_RETRIES 3
#define SR_TIMEOUT (30 * HZ)
#define SR_CAPABILITIES \ #define SR_CAPABILITIES \
(CDC_CLOSE_TRAY|CDC_OPEN_TRAY|CDC_LOCK|CDC_SELECT_SPEED| \ (CDC_CLOSE_TRAY|CDC_OPEN_TRAY|CDC_LOCK|CDC_SELECT_SPEED| \
CDC_SELECT_DISC|CDC_MULTI_SESSION|CDC_MCN|CDC_MEDIA_CHANGED| \ CDC_SELECT_DISC|CDC_MULTI_SESSION|CDC_MCN|CDC_MEDIA_CHANGED| \
......
...@@ -20,6 +20,9 @@ ...@@ -20,6 +20,9 @@
#include <linux/genhd.h> #include <linux/genhd.h>
#include <linux/kref.h> #include <linux/kref.h>
#define MAX_RETRIES 3
#define SR_TIMEOUT (30 * HZ)
struct scsi_device; struct scsi_device;
/* The CDROM is fairly slow, so we need a little extra time */ /* The CDROM is fairly slow, so we need a little extra time */
......
...@@ -275,18 +275,6 @@ int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc) ...@@ -275,18 +275,6 @@ int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc)
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
/* interface to cdrom.c */ /* 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) int sr_tray_move(struct cdrom_device_info *cdi, int pos)
{ {
Scsi_CD *cd = cdi->handle; Scsi_CD *cd = cdi->handle;
...@@ -310,14 +298,46 @@ int sr_lock_door(struct cdrom_device_info *cdi, int lock) ...@@ -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) 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) { if (CDSL_CURRENT != slot) {
/* we have no changer support */ /* we have no changer support */
return -EINVAL; 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;
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; 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_TRAY_OPEN;
return CDS_DRIVE_NOT_READY;
} }
int sr_disk_status(struct cdrom_device_info *cdi) int sr_disk_status(struct cdrom_device_info *cdi)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册