[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
@ -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 @@
|
|||||||
#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)
|
|||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
/* 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)
|
|||||||
|
|
||||||
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;
|
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)
|
int sr_disk_status(struct cdrom_device_info *cdi)
|
||||||
|
Loading…
Reference in New Issue
Block a user