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.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

Reply via email to