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
[EMAIL PROTECTED]
//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.0Thu 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);
staticvoidcdprevent(struct cam_periph *periph, int action);
staticint cdsize(dev_t dev, u_int32_t *size);
+ staticint cdfirsttrackisdata(struct cam_periph *periph);
staticint 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