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); | |||
67 | 67 | ||
68 | #define SR_DISKS 256 | 68 | #define SR_DISKS 256 |
69 | 69 | ||
70 | #define MAX_RETRIES 3 | ||
71 | #define SR_TIMEOUT (30 * HZ) | ||
72 | #define SR_CAPABILITIES \ | 70 | #define SR_CAPABILITIES \ |
73 | (CDC_CLOSE_TRAY|CDC_OPEN_TRAY|CDC_LOCK|CDC_SELECT_SPEED| \ | 71 | (CDC_CLOSE_TRAY|CDC_OPEN_TRAY|CDC_LOCK|CDC_SELECT_SPEED| \ |
74 | CDC_SELECT_DISC|CDC_MULTI_SESSION|CDC_MCN|CDC_MEDIA_CHANGED| \ | 72 | 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) | |||
179 | { | 177 | { |
180 | struct scsi_cd *cd = cdi->handle; | 178 | struct scsi_cd *cd = cdi->handle; |
181 | int retval; | 179 | int retval; |
180 | struct scsi_sense_hdr *sshdr; | ||
182 | 181 | ||
183 | if (CDSL_CURRENT != slot) { | 182 | if (CDSL_CURRENT != slot) { |
184 | /* no changer support */ | 183 | /* no changer support */ |
185 | return -EINVAL; | 184 | return -EINVAL; |
186 | } | 185 | } |
187 | 186 | ||
188 | retval = scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES); | 187 | sshdr = kzalloc(sizeof(*sshdr), GFP_KERNEL); |
189 | if (retval) { | 188 | retval = scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, |
190 | /* Unable to test, unit probably not ready. This usually | 189 | sshdr); |
191 | * means there is no disc in the drive. Mark as changed, | 190 | if (retval || (scsi_sense_valid(sshdr) && |
192 | * and we will figure it out later once the drive is | 191 | /* 0x3a is medium not present */ |
193 | * available again. */ | 192 | sshdr->asc == 0x3a)) { |
193 | /* Media not present or unable to test, unit probably not | ||
194 | * ready. This usually means there is no disc in the drive. | ||
195 | * Mark as changed, and we will figure it out later once | ||
196 | * the drive is available again. | ||
197 | */ | ||
194 | cd->device->changed = 1; | 198 | cd->device->changed = 1; |
195 | return 1; /* This will force a flush, if called from | 199 | /* This will force a flush, if called from check_disk_change */ |
196 | * check_disk_change */ | 200 | retval = 1; |
201 | goto out; | ||
197 | }; | 202 | }; |
198 | 203 | ||
199 | retval = cd->device->changed; | 204 | retval = cd->device->changed; |
@@ -203,9 +208,17 @@ static int sr_media_change(struct cdrom_device_info *cdi, int slot) | |||
203 | if (retval) { | 208 | if (retval) { |
204 | /* check multisession offset etc */ | 209 | /* check multisession offset etc */ |
205 | sr_cd_check(cdi); | 210 | sr_cd_check(cdi); |
206 | |||
207 | get_sectorsize(cd); | 211 | get_sectorsize(cd); |
208 | } | 212 | } |
213 | |||
214 | out: | ||
215 | /* Notify userspace, that media has changed. */ | ||
216 | if (retval != cd->previous_state) | ||
217 | sdev_evt_send_simple(cd->device, SDEV_EVT_MEDIA_CHANGE, | ||
218 | GFP_KERNEL); | ||
219 | cd->previous_state = retval; | ||
220 | kfree(sshdr); | ||
221 | |||
209 | return retval; | 222 | return retval; |
210 | } | 223 | } |
211 | 224 | ||