diff options
Diffstat (limited to 'drivers/scsi/sr.c')
-rw-r--r-- | drivers/scsi/sr.c | 35 |
1 files changed, 24 insertions, 11 deletions
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index c61999031141..1fcee16fa36d 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -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| \ @@ -179,21 +177,28 @@ 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; - return 1; /* This will force a flush, if called from - * check_disk_change */ + /* This will force a flush, if called from check_disk_change */ + retval = 1; + goto out; }; retval = cd->device->changed; @@ -203,9 +208,17 @@ static int sr_media_change(struct cdrom_device_info *cdi, int slot) if (retval) { /* check multisession offset etc */ sr_cd_check(cdi); - get_sectorsize(cd); } + +out: + /* Notify userspace, that media has changed. */ + if (retval != cd->previous_state) + sdev_evt_send_simple(cd->device, SDEV_EVT_MEDIA_CHANGE, + GFP_KERNEL); + cd->previous_state = retval; + kfree(sshdr); + return retval; } |