Skip to content

Commit

Permalink
[SCSI] sr: update to follow tray status correctly
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
James Bottomley authored and James Bottomley committed Jan 12, 2008
1 parent 32e8ae3 commit 210ba1d
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 16 deletions.
2 changes: 0 additions & 2 deletions drivers/scsi/sr.c
Expand Up @@ -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| \
Expand Down
3 changes: 3 additions & 0 deletions drivers/scsi/sr.h
Expand Up @@ -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 */
Expand Down
48 changes: 34 additions & 14 deletions drivers/scsi/sr_ioctl.c
Expand Up @@ -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;
Expand All @@ -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)
Expand Down

0 comments on commit 210ba1d

Please sign in to comment.