From owner-freebsd-current Thu Nov 2 20:10:52 2000 Delivered-To: freebsd-current@freebsd.org Received: from panzer.kdm.org (panzer.kdm.org [216.160.178.169]) by hub.freebsd.org (Postfix) with ESMTP id 88D6837B479; Thu, 2 Nov 2000 20:10:39 -0800 (PST) Received: (from ken@localhost) by panzer.kdm.org (8.9.3/8.9.1) id VAA13080; Thu, 2 Nov 2000 21:10:34 -0700 (MST) (envelope-from ken) Date: Thu, 2 Nov 2000 21:10:34 -0700 From: "Kenneth D. Merry" To: Akinori MUSHA 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> References: <200010300703.XAA12639@freefall.freebsd.org> <86pukh8oqd.wl@archon.local.idaemons.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="X1bOJ3K7DJ5YkBrT" Content-Disposition: inline User-Agent: Mutt/1.2i In-Reply-To: <86pukh8oqd.wl@archon.local.idaemons.org>; from knu@idaemons.org on Tue, Oct 31, 2000 at 04:16:26PM +0900 Sender: owner-freebsd-current@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG --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 freebsd-current" in the body of the message