diff options
author | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-01-05 11:39:51 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-01-11 19:29:17 -0500 |
commit | 210ba1d1724f5c4ed87a2ab1a21ca861a915f734 (patch) | |
tree | 4b25acf59b91e2be49faf34507f3d9eeebff76a0 /drivers/scsi | |
parent | 32e8ae36b8f80372015b88b63c4358a376c9af0f (diff) |
[SCSI] sr: update to follow tray status correctly
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>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/sr.c | 2 | ||||
-rw-r--r-- | drivers/scsi/sr.h | 3 | ||||
-rw-r--r-- | drivers/scsi/sr_ioctl.c | 48 |
3 files changed, 37 insertions, 16 deletions
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 896be4ab285d..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| \ |
diff --git a/drivers/scsi/sr.h b/drivers/scsi/sr.h index 0d04e2878c9d..81fbc0b78a52 100644 --- a/drivers/scsi/sr.h +++ b/drivers/scsi/sr.h | |||
@@ -20,6 +20,9 @@ | |||
20 | #include <linux/genhd.h> | 20 | #include <linux/genhd.h> |
21 | #include <linux/kref.h> | 21 | #include <linux/kref.h> |
22 | 22 | ||
23 | #define MAX_RETRIES 3 | ||
24 | #define SR_TIMEOUT (30 * HZ) | ||
25 | |||
23 | struct scsi_device; | 26 | struct scsi_device; |
24 | 27 | ||
25 | /* The CDROM is fairly slow, so we need a little extra time */ | 28 | /* The CDROM is fairly slow, so we need a little extra time */ |
diff --git a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c index e1589f91706a..d5cebff1d646 100644 --- a/drivers/scsi/sr_ioctl.c +++ b/drivers/scsi/sr_ioctl.c | |||
@@ -275,18 +275,6 @@ int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc) | |||
275 | /* ---------------------------------------------------------------------- */ | 275 | /* ---------------------------------------------------------------------- */ |
276 | /* interface to cdrom.c */ | 276 | /* interface to cdrom.c */ |
277 | 277 | ||
278 | static int test_unit_ready(Scsi_CD *cd) | ||
279 | { | ||
280 | struct packet_command cgc; | ||
281 | |||
282 | memset(&cgc, 0, sizeof(struct packet_command)); | ||
283 | cgc.cmd[0] = GPCMD_TEST_UNIT_READY; | ||
284 | cgc.quiet = 1; | ||
285 | cgc.data_direction = DMA_NONE; | ||
286 | cgc.timeout = IOCTL_TIMEOUT; | ||
287 | return sr_do_ioctl(cd, &cgc); | ||
288 | } | ||
289 | |||
290 | int sr_tray_move(struct cdrom_device_info *cdi, int pos) | 278 | int sr_tray_move(struct cdrom_device_info *cdi, int pos) |
291 | { | 279 | { |
292 | Scsi_CD *cd = cdi->handle; | 280 | Scsi_CD *cd = cdi->handle; |
@@ -310,14 +298,46 @@ int sr_lock_door(struct cdrom_device_info *cdi, int lock) | |||
310 | 298 | ||
311 | int sr_drive_status(struct cdrom_device_info *cdi, int slot) | 299 | int sr_drive_status(struct cdrom_device_info *cdi, int slot) |
312 | { | 300 | { |
301 | struct scsi_cd *cd = cdi->handle; | ||
302 | struct scsi_sense_hdr sshdr; | ||
303 | struct media_event_desc med; | ||
304 | |||
313 | if (CDSL_CURRENT != slot) { | 305 | if (CDSL_CURRENT != slot) { |
314 | /* we have no changer support */ | 306 | /* we have no changer support */ |
315 | return -EINVAL; | 307 | return -EINVAL; |
316 | } | 308 | } |
317 | if (0 == test_unit_ready(cdi->handle)) | 309 | if (0 == scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, |
310 | &sshdr)) | ||
318 | return CDS_DISC_OK; | 311 | return CDS_DISC_OK; |
319 | 312 | ||
320 | return CDS_TRAY_OPEN; | 313 | if (!cdrom_get_media_event(cdi, &med)) { |
314 | if (med.media_present) | ||
315 | return CDS_DISC_OK; | ||
316 | else if (med.door_open) | ||
317 | return CDS_TRAY_OPEN; | ||
318 | else | ||
319 | return CDS_NO_DISC; | ||
320 | } | ||
321 | |||
322 | /* | ||
323 | * 0x04 is format in progress .. but there must be a disc present! | ||
324 | */ | ||
325 | if (sshdr.sense_key == NOT_READY && sshdr.asc == 0x04) | ||
326 | return CDS_DISC_OK; | ||
327 | |||
328 | /* | ||
329 | * If not using Mt Fuji extended media tray reports, | ||
330 | * just return TRAY_OPEN since ATAPI doesn't provide | ||
331 | * any other way to detect this... | ||
332 | */ | ||
333 | if (scsi_sense_valid(&sshdr) && | ||
334 | /* 0x3a is medium not present */ | ||
335 | sshdr.asc == 0x3a) | ||
336 | return CDS_NO_DISC; | ||
337 | else | ||
338 | return CDS_TRAY_OPEN; | ||
339 | |||
340 | return CDS_DRIVE_NOT_READY; | ||
321 | } | 341 | } |
322 | 342 | ||
323 | int sr_disk_status(struct cdrom_device_info *cdi) | 343 | int sr_disk_status(struct cdrom_device_info *cdi) |