aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/sr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/sr.c')
-rw-r--r--drivers/scsi/sr.c35
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
214out:
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