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 | |
| 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')
| -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) |
