Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 2 Nov 2000 21:10:34 -0700
From:      "Kenneth D. Merry" <ken@kdm.org>
To:        Akinori MUSHA <knu@idaemons.org>
Cc:        cvs-committers@FreeBSD.org, cvs-all@FreeBSD.org, current@FreeBSD.org
Subject:   Re: cvs commit: src/sys/kern subr_diskslice.c src/sys/sys diskslice.h         src/sys/cam/scsi scsi_cd.c
Message-ID:  <20001102211034.A13063@panzer.kdm.org>
In-Reply-To: <86pukh8oqd.wl@archon.local.idaemons.org>; from knu@idaemons.org on Tue, Oct 31, 2000 at 04:16:26PM %2B0900
References:  <200010300703.XAA12639@freefall.freebsd.org> <86pukh8oqd.wl@archon.local.idaemons.org>

next in thread | previous in thread | raw e-mail | index | archive | help

--X1bOJ3K7DJ5YkBrT
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Tue, Oct 31, 2000 at 16:16:26 +0900, Akinori MUSHA wrote:
> At Sun, 29 Oct 2000 23:03:02 -0800 (PST),
> Kenneth Merry wrote:
> > ken         2000/10/29 23:03:02 PST
> > 
> >   Modified files:
> >     sys/kern             subr_diskslice.c 
> >     sys/sys              diskslice.h 
> >     sys/cam/scsi         scsi_cd.c 
> >   Log:
> >   Write support for the cd(4) driver.
> 
> I get the following messages when I hit "cdcontrol -f /dev/cd0 play"
> against a music CD:
> 
> Oct 31 16:06:40 archon /boot/kernel/kernel: (cd0:ahc0:0:2:0): READ(10). CDB: 28 0 0 0 0 1 0 0 1 0 
> Oct 31 16:06:40 archon /boot/kernel/kernel: (cd0:ahc0:0:2:0): ILLEGAL REQUEST asc:64,0
> Oct 31 16:06:40 archon /boot/kernel/kernel: (cd0:ahc0:0:2:0): Illegal mode for this track
> Oct 31 16:06:40 archon /boot/kernel/kernel: (cd0:ahc0:0:2:0): cddone: got error 0x16 back
> 
> Though the music goes just fine.

I've got a patch, see if this fixes the problem.

Ken
-- 
Kenneth Merry
ken@kdm.org

--X1bOJ3K7DJ5YkBrT
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="scsi_cd.c.writefix.20001102.new"

==== //depot/FreeBSD-ken/src/sys/cam/scsi/scsi_cd.c#13 - /a/ken/perforce/FreeBSD-ken/src/sys/cam/scsi/scsi_cd.c ====
*** /tmp/tmp.13048.0	Thu Nov  2 21:07:47 2000
--- /a/ken/perforce/FreeBSD-ken/src/sys/cam/scsi/scsi_cd.c	Thu Nov  2 21:05:02 2000
***************
*** 207,212 ****
--- 207,213 ----
  				u_int32_t sense_flags);
  static	void		cdprevent(struct cam_periph *periph, int action);
  static	int		cdsize(dev_t dev, u_int32_t *size);
+ static	int		cdfirsttrackisdata(struct cam_periph *periph);
  static	int		cdreadtoc(struct cam_periph *periph, u_int32_t mode, 
  				  u_int32_t start, struct cd_toc_entry *data, 
  				  u_int32_t len);
***************
*** 920,925 ****
--- 921,937 ----
  	}
  
  	/*
+ 	 * If we get a non-zero return, revert back to not reading the
+ 	 * label off the disk.  The first track is likely audio, which
+ 	 * won't have a disklabel.
+ 	 */
+ 	if ((error = cdfirsttrackisdata(periph)) != 0) {
+ 		softc->disk.d_dsflags &= ~DSO_COMPATLABEL;
+ 		softc->disk.d_dsflags |= DSO_NOLABELS;
+ 		error = 0;
+ 	}
+ 
+ 	/*
  	 * Build prototype label for whole disk.
  	 * Should take information about different data tracks from the
  	 * TOC and put it in the partition table.
***************
*** 993,998 ****
--- 1005,1017 ----
  		cdprevent(periph, PR_ALLOW);
  
  	/*
+ 	 * Unconditionally set the dsopen() flags back to their default
+ 	 * state.
+ 	 */
+ 	softc->disk.d_dsflags &= ~DSO_NOLABELS;
+ 	softc->disk.d_dsflags |= DSO_COMPATLABEL;
+ 
+ 	/*
  	 * Since we're closing this CD, mark the blocksize as unavailable.
  	 * It will be marked as available whence the CD is opened again.
  	 */
***************
*** 2540,2545 ****
--- 2559,2638 ----
  
  	return (error);
  
+ }
+ 
+ /*
+  * The idea here is to try to figure out whether the first track is data or
+  * audio.  If it is data, we can at least attempt to read a disklabel off
+  * the first sector of the disk.  If it is audio, there won't be a
+  * disklabel.
+  *
+  * This routine returns 0 if the first track is data, and non-zero if there
+  * is an error or the first track is audio.  (If either non-zero case, we
+  * should not attempt to read the disklabel.)
+  */
+ static int
+ cdfirsttrackisdata(struct cam_periph *periph)
+ {
+ 	struct cdtocdata {
+ 		struct ioc_toc_header header;
+ 		struct cd_toc_entry entries[100];
+ 	};
+ 	struct cd_softc *softc;
+ 	struct ioc_toc_header *th;
+ 	struct cdtocdata *data;
+ 	int num_entries, i;
+ 	int error, first_track_audio;
+ 
+ 	error = 0;
+ 	first_track_audio = -1;
+ 
+ 	softc = (struct cd_softc *)periph->softc;
+ 
+ 	data = malloc(sizeof(struct cdtocdata), M_TEMP, M_WAITOK);
+ 
+ 	th = &data->header;
+ 	error = cdreadtoc(periph, 0, 0, (struct cd_toc_entry *)data,
+ 			  sizeof(*data));
+ 
+ 	if (error)
+ 		goto bailout;
+ 
+ 	if (softc->quirks & CD_Q_BCD_TRACKS) {
+ 		/* we are going to have to convert the BCD
+ 		 * encoding on the cd to what is expected
+ 		 */
+ 		th->starting_track =
+ 		    bcd2bin(th->starting_track);
+ 		th->ending_track = bcd2bin(th->ending_track);
+ 	}
+ 	th->len = scsi_2btoul((u_int8_t *)&th->len);
+ 
+ 	if ((th->len - 2) > 0)
+ 		num_entries = (th->len - 2) / sizeof(struct cd_toc_entry);
+ 	else
+ 		num_entries = 0;
+ 
+ 	for (i = 0; i < num_entries; i++) {
+ 		if (data->entries[i].track == th->starting_track) {
+ 			if (data->entries[i].control & 0x4)
+ 				first_track_audio = 0;
+ 			else
+ 				first_track_audio = 1;
+ 			break;
+ 		}
+ 	}
+ 
+ 	if (first_track_audio == -1)
+ 		error = ENOENT;
+ 	else if (first_track_audio == 1)
+ 		error = EINVAL;
+ 	else
+ 		error = 0;
+ bailout:
+ 	free(data, M_TEMP);
+ 
+ 	return(error);
  }
  
  static int

--X1bOJ3K7DJ5YkBrT--


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe cvs-all" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20001102211034.A13063>