Date: Thu, 2 Nov 2000 21:18:07 -0700 From: "Kenneth D. Merry" <ken@kdm.org> To: scsi@FreeBSD.ORG Subject: Re: cd(4) write support Message-ID: <20001102211807.A13085@panzer.kdm.org> In-Reply-To: <20001030002505.A37704@panzer.kdm.org>; from ken@kdm.org on Mon, Oct 30, 2000 at 12:25:05AM -0700 References: <20001030002505.A37704@panzer.kdm.org>
next in thread | previous in thread | raw e-mail | index | archive | help
--qDbXVdCdHGoSgWSk Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Mon, Oct 30, 2000 at 00:25:05 -0700, Kenneth D. Merry wrote: > > I've committed a set of patches in -current that provide write support for > randomly writeable CD-type drives. (Mainly DVD-RAM and PD-type drives.) > > The driver should function the same as before with read-only media. > > It is now possible to do things like burn a UFS disklabel and filesystem > on a CD-R, or disklabel and newfs a DVD-RAM disk. As it turns out, there was a problem with audio CD's. In general, you can't issue a standard READ(10) with an audio CD in a drive. (Well, you can on many drives, but it generally requires changing some mode page parameters first.) The disklabel code attempts to do a read on the device to see if there is a disklabel, which causes problems with audio CDs. (Since the mode page wasn't setup beforehand.) The solution is to look at the table of contents, and only attempt to read the disklabel for drives with data tracks at the beginning of the CD. Anyway, a patch is attached that should fix the problems with audio CDs. I'd appreciate it if folks running -current would test this with whatever strange CDs or DVDs you have. I'm especially interested in Video CDs, since I don't have any to test with here. Thanks, Ken -- Kenneth Merry ken@kdm.org --qDbXVdCdHGoSgWSk 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 --qDbXVdCdHGoSgWSk-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-scsi" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20001102211807.A13085>