[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>
This commit is contained in:
parent
32e8ae36b8
commit
210ba1d172
3 changed files with 37 additions and 16 deletions
|
@ -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| \
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
||||
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)
|
||||
|
|
Loading…
Reference in a new issue