diff options
author | James Bottomley <James.Bottomley@SteelEye.com> | 2007-12-02 18:10:40 +0100 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-01-12 01:22:50 +0100 |
commit | 001aac257cf8adbe90cdcba6e07f8d12dfc8fa6b (patch) | |
tree | 0eb6294049245e05f47fdb76e3f878c78c015d88 /drivers/scsi/sr.c | |
parent | [SCSI] BUG_ON() impossible condition in sg list counting (diff) | |
download | linux-001aac257cf8adbe90cdcba6e07f8d12dfc8fa6b.tar.xz linux-001aac257cf8adbe90cdcba6e07f8d12dfc8fa6b.zip |
[SCSI] sd,sr: add early detection of medium not present
The current scsi_test_unit_ready() is updated to return sense code
information (in struct scsi_sense_hdr). The sd and sr drivers are
changed to interpret the sense code return asc 0x3a as no media and
adjust the device status accordingly.
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/sr.c')
-rw-r--r-- | drivers/scsi/sr.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 7702681d93f9..896be4ab285d 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -179,18 +179,24 @@ static int sr_media_change(struct cdrom_device_info *cdi, int slot) { struct scsi_cd *cd = cdi->handle; int retval; + struct scsi_sense_hdr *sshdr; if (CDSL_CURRENT != slot) { /* no changer support */ return -EINVAL; } - retval = scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES); - if (retval) { - /* Unable to test, unit probably not ready. This usually - * means there is no disc in the drive. Mark as changed, - * and we will figure it out later once the drive is - * available again. */ + sshdr = kzalloc(sizeof(*sshdr), GFP_KERNEL); + retval = scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, + sshdr); + if (retval || (scsi_sense_valid(sshdr) && + /* 0x3a is medium not present */ + sshdr->asc == 0x3a)) { + /* Media not present or unable to test, unit probably not + * ready. This usually means there is no disc in the drive. + * Mark as changed, and we will figure it out later once + * the drive is available again. + */ cd->device->changed = 1; /* This will force a flush, if called from check_disk_change */ retval = 1; @@ -213,6 +219,7 @@ out: sdev_evt_send_simple(cd->device, SDEV_EVT_MEDIA_CHANGE, GFP_KERNEL); cd->previous_state = retval; + kfree(sshdr); return retval; } |