Subject: kern/11425: CD drive does not play last track
To: None <gnats-bugs@gnats.netbsd.org>
From: Julian Coleman <Julian.Coleman@coris.demon.co.uk>
List: netbsd-bugs
Date: 11/05/2000 03:53:17
>Number: 11425
>Category: kern
>Synopsis: CD drive does not play last track
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: kern-bug-people
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Sun Nov 05 03:53:01 PST 2000
>Closed-Date:
>Last-Modified:
>Originator: Julian Coleman
>Release: 1.5_BETA
>Organization:
@home
>Environment:
System: NetBSD orthanc.coris.org.uk 1.5_BETA NetBSD 1.5_BETA (SUN4-300) #2: Sun Oct 29 10:38:14 GMT 2000 root@mariner.coris.org.uk:/usr/obj/sys/arch/sparc/compile/SUN4-300 sparc
>Description:
Trying to play the whole disk (or last track of) an audio CD on :
> cd0 at scsibus0 target 6 lun 0: <SONY, CD-ROM CDU-8012, 3.1e> SCSI2 5/cdrom removable
results in :
> cd0(esp0:6:0): Check Condition on CDB: 0x47 00 00 00 02 20 38 00 0a 00
> SENSE KEY: Illegal Request
> INFO FIELD: 1007312
> ASC/ASCQ: Logical Block Address Out of Range
for the audio CD with contents :
> 1 0:02.32 5:04.20 32 22670 audio
>
> 12 52:11.37 3:50.48 234712 17148 audio
> 170 56:00.10 - 251860 - -
>How-To-Repeat:
Run cdplay with the above Sony drive.
>Fix:
It appears the problem is that cd_play_tracks() plays from the start msf of
the first track to the start msf of the last + 1 track. This drive does not
like that. The fix is to subtract one frame from the end msf :
--- sys/dev/scsipi/cd.c.dist Sat Jun 10 11:14:46 2000
+++ sys/dev/scsipi/cd.c Sun Oct 29 10:29:16 2000
@@ -1286,6 +1286,7 @@
int strack, sindex, etrack, eindex;
{
struct cd_toc toc;
+ union msf_lba emsf;
int error;
if (!etrack)
@@ -1304,12 +1305,31 @@
if (strack < 0)
return (EINVAL);
+ /*
+ * Subtract 1 frame from end location if etrack is the last track,
+ * as some drives will give an error when asked to play this frame.
+ */
+ emsf.msf.minute = toc.entries[etrack].addr.msf.minute;
+ emsf.msf.second = toc.entries[etrack].addr.msf.second;
+ emsf.msf.frame = toc.entries[etrack].addr.msf.frame;
+ if (etrack == toc.header.ending_track) {
+ if (emsf.msf.frame)
+ emsf.msf.frame -= 1;
+ else {
+ emsf.msf.frame = 74;
+ if (emsf.msf.second)
+ emsf.msf.second -= 1;
+ else {
+ emsf.msf.second = 59;
+ if (emsf.msf.minute)
+ emsf.msf.minute -=1;
+ }
+ }
+ }
return (cd_play_msf(cd, toc.entries[strack].addr.msf.minute,
toc.entries[strack].addr.msf.second,
toc.entries[strack].addr.msf.frame,
- toc.entries[etrack].addr.msf.minute,
- toc.entries[etrack].addr.msf.second,
- toc.entries[etrack].addr.msf.frame));
+ emsf.msf.minute, emsf.msf.second, emsf.msf.frame));
}
/*
It may be better to calculate the end msf from the start of the last track
plus the length of that track instead. Above fix also tested on :
> cd1 at scsibus0 target 5 lun 0: <YAMAHA, CRW4416S, 1.0g> SCSI2 5/cdrom removable
> cd0 at scsibus0 target 6 lun 0: <TOSHIBA, XM-4101TASUNSLCD, 1755> SCSI2 5/cdrom removable
>Release-Note:
>Audit-Trail:
>Unformatted: