Subject: kern/4092: ioctl CDIOCPLAYTRACKS does not work correctly
To: None <gnats-bugs@gnats.netbsd.org>
From: None <t-nkyma@tcp-ip.or.jp>
List: netbsd-bugs
Date: 09/07/1997 01:53:22
>Number:         4092
>Category:       kern
>Synopsis:       ioctl CDIOCPLAYTRACKS does not work correctly
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Sat Sep  6 10:05:00 1997
>Last-Modified:
>Originator:     Takeshi Nakayama
>Organization:
		Tokai Communication Platform for Inter Person
>Release:        NetBSD-current [Sep 4 1997]
>Environment:
System: NetBSD lethe 1.2G NetBSD 1.2G (LETHE) #14: Sat Sep 6 21:04:42 JST 1997
takeshi@lethe:/var/src/sys/arch/i386/compile/LETHE i386


>Description:
	
New scsipi cd driver uses the PLAY command instead of the PLAY_TRACK
command in CDIOCPLAYTRACKS. (for lack of PLAY_TRACK command in ATAPI?)
The PLAY command plays audio CD specifying a start block and a block
size, but a block size easily overflows since the width is 16 bit
(65535 blocks correspond about 14 minutes).

Therefore, over 65536 block size track or tracks can not play all
blocks (the playing stops at (block size) % 65536 block).

>How-To-Repeat:

If I play the next audio CD from track 1 to track 10 using
CDIOCPLAYTRACKS, the playing stops in about 7 minutes.
((227362 % 65536) / 75 / 60 = 6.83...)

track     start  duration   block  length   type
-------------------------------------------------
    1   0:02.00   5:15.22       0   23497  audio
      :
      :
   10  44:19.17   6:16.20  199292   28070  audio
  170  50:33.37         -  227362       -      -

>Fix:

Like the following patch, we avoid a overflow problem if
cd_play_tracks() uses cd_play_msf() instead of cd_play().

I have only SCSI CDROM, I do not know how about in ATAPI CDROM....

*** src/sys/dev/scsipi/cd.c	Wed Aug 27 20:41:45 1997
--- obj/sys/dev/scsipi/cd.c	Sat Sep  6 21:02:20 1997
*************** cd_play_tracks(cd, strack, sindex, etrac
*** 1019,1026 ****
  	if (strack < 0)
  		return EINVAL;
  
! 	return cd_play(cd, toc.entries[strack].addr.lba,
! 		toc.entries[etrack].addr.lba - toc.entries[strack].addr.lba);
  }
  
  /*
--- 1019,1030 ----
  	if (strack < 0)
  		return EINVAL;
  
! 	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);
  }
  
  /*
*************** cd_load_toc(cd, toc)
*** 1134,1140 ****
      struct cd_softc *cd;
  	struct cd_toc *toc;
  {
! 	int i, ntracks, len, error;
  
  	if ((error = cd_read_toc(cd, 0, 0, toc, sizeof(toc->header))) != 0)
  		return error;
--- 1138,1144 ----
      struct cd_softc *cd;
  	struct cd_toc *toc;
  {
! 	int ntracks, len, error;
  
  	if ((error = cd_read_toc(cd, 0, 0, toc, sizeof(toc->header))) != 0)
  		return error;
*************** cd_load_toc(cd, toc)
*** 1143,1153 ****
  	len = (ntracks+1)*sizeof(struct cd_toc_entry) + sizeof(toc->header);
  	if ((error = cd_read_toc(cd, CD_MSF_FORMAT, 0, toc, len)) != 0)
  		return error;
- 	for (i = 0; i <= ntracks; i++) {
- 		toc->entries[i].addr.lba = msf2lba(toc->entries[i].addr.msf.minute,
- 			toc->entries[i].addr.msf.second,
- 			toc->entries[i].addr.msf.frame);
- 	}
  	return 0;
  }
  
--- 1147,1152 ----
>Audit-Trail:
>Unformatted: