$NetBSD: patch-an,v 1.7 2006/08/06 10:36:50 wiz Exp $

--- src/input/input_cdda.c.orig	2005-10-08 15:57:42.000000000 +0200
+++ src/input/input_cdda.c
@@ -613,14 +613,20 @@ static int read_cdrom_frames(cdda_input_
   return 0;
 }
 
-#elif defined(__FreeBSD__)
+#elif defined(__FreeBSD__) || defined(__NetBSD__)
 
 #include <sys/cdio.h>
+#include <sys/scsiio.h>
 
 static int read_cdrom_toc(int fd, cdrom_toc *toc) {
 
   struct ioc_toc_header tochdr;
+#if defined(__FreeBSD__)
   struct ioc_read_toc_single_entry tocentry;
+#elif defined(__NetBSD__)
+  struct ioc_read_toc_entry tocentry;
+  struct cd_toc_entry data;
+#endif
   int i;
 
   /* fetch the table of contents */
@@ -646,13 +652,26 @@ static int read_cdrom_toc(int fd, cdrom_
 
     memset(&tocentry, 0, sizeof(tocentry));
 
+#if defined(__FreeBSD__)
     tocentry.track = i;
     tocentry.address_format = CD_MSF_FORMAT;
     if (ioctl(fd, CDIOREADTOCENTRY, &tocentry) == -1) {
       perror("CDIOREADTOCENTRY");
       return -1;
     }
+#elif defined(__NetBSD__)
+    memset(&data, 0, sizeof(data));
+    tocentry.data_len = sizeof(data);
+    tocentry.data = &data;
+    tocentry.starting_track = i;
+    tocentry.address_format = CD_MSF_FORMAT;
+    if (ioctl(fd, CDIOREADTOCENTRYS, &tocentry) == -1) {
+      perror("CDIOREADTOCENTRYS");
+      return -1;
+    }
+#endif
 
+#if defined(__FreeBSD__)
     toc->toc_entries[i-1].track_mode = (tocentry.entry.control & 0x04) ? 1 : 0;
     toc->toc_entries[i-1].first_frame_minute = tocentry.entry.addr.msf.minute;
     toc->toc_entries[i-1].first_frame_second = tocentry.entry.addr.msf.second;
@@ -661,18 +680,41 @@ static int read_cdrom_toc(int fd, cdrom_
       (tocentry.entry.addr.msf.minute * CD_SECONDS_PER_MINUTE * CD_FRAMES_PER_SECOND) +
       (tocentry.entry.addr.msf.second * CD_FRAMES_PER_SECOND) +
        tocentry.entry.addr.msf.frame;
+#elif defined(__NetBSD__)
+    toc->toc_entries[i-1].track_mode = (tocentry.data->control & 0x04) ? 1 : 0;
+    toc->toc_entries[i-1].first_frame_minute = tocentry.data->addr.msf.minute;
+    toc->toc_entries[i-1].first_frame_second = tocentry.data->addr.msf.second;
+    toc->toc_entries[i-1].first_frame_frame = tocentry.data->addr.msf.frame;
+    toc->toc_entries[i-1].first_frame =
+      (tocentry.data->addr.msf.minute * CD_SECONDS_PER_MINUTE * CD_FRAMES_PER_SECOND) +
+      (tocentry.data->addr.msf.second * CD_FRAMES_PER_SECOND) +
+       tocentry.data->addr.msf.frame;
+#endif
   }
 
   /* fetch the leadout as well */
   memset(&tocentry, 0, sizeof(tocentry));
 
+#if defined(__FreeBSD__)
   tocentry.track = CD_LEADOUT_TRACK;
   tocentry.address_format = CD_MSF_FORMAT;
   if (ioctl(fd, CDIOREADTOCENTRY, &tocentry) == -1) {
     perror("CDIOREADTOCENTRY");
     return -1;
   }
+#elif defined(__NetBSD__)
+  memset(&data, 0, sizeof(data));
+  tocentry.data_len = sizeof(data);
+  tocentry.data = &data;
+  tocentry.starting_track = CD_LEADOUT_TRACK;
+  tocentry.address_format = CD_MSF_FORMAT;
+  if (ioctl(fd, CDIOREADTOCENTRYS, &tocentry) == -1) {
+    perror("CDIOREADTOCENTRYS");
+    return -1;
+  }
+#endif
 
+#if defined(__FreeBSD__)
   toc->leadout_track.track_mode = (tocentry.entry.control & 0x04) ? 1 : 0;
   toc->leadout_track.first_frame_minute = tocentry.entry.addr.msf.minute;
   toc->leadout_track.first_frame_second = tocentry.entry.addr.msf.second;
@@ -681,6 +723,16 @@ static int read_cdrom_toc(int fd, cdrom_
     (tocentry.entry.addr.msf.minute * CD_SECONDS_PER_MINUTE * CD_FRAMES_PER_SECOND) +
     (tocentry.entry.addr.msf.second * CD_FRAMES_PER_SECOND) +
      tocentry.entry.addr.msf.frame;
+#elif defined(__NetBSD__)
+  toc->leadout_track.track_mode = (tocentry.data->control & 0x04) ? 1 : 0;
+  toc->leadout_track.first_frame_minute = tocentry.data->addr.msf.minute;
+  toc->leadout_track.first_frame_second = tocentry.data->addr.msf.second;
+  toc->leadout_track.first_frame_frame = tocentry.data->addr.msf.frame;
+  toc->leadout_track.first_frame =
+    (tocentry.data->addr.msf.minute * CD_SECONDS_PER_MINUTE * CD_FRAMES_PER_SECOND) +
+    (tocentry.data->addr.msf.second * CD_FRAMES_PER_SECOND) +
+     tocentry.data->addr.msf.frame;
+#endif
 
   return 0;
 }
@@ -689,12 +741,12 @@ static int read_cdrom_frames(cdda_input_
   unsigned char *data) {
 
   int fd = this_gen->fd;
-#if  __FreeBSD_version < 501106
-  struct ioc_read_audio cdda;
-#endif
 
   while( num_frames ) {
+#if defined(__FreeBSD__)
 #if  __FreeBSD_version < 501106
+    struct ioc_read_audio cdda;
+
     cdda.address_format = CD_MSF_FORMAT;
     cdda.address.msf.minute = frame / CD_SECONDS_PER_MINUTE / CD_FRAMES_PER_SECOND;
     cdda.address.msf.second = (frame / CD_FRAMES_PER_SECOND) % CD_SECONDS_PER_MINUTE;
@@ -712,6 +764,33 @@ static int read_cdrom_frames(cdda_input_
       perror("CDIOCREADAUDIO");
       return -1;
     }
+#elif defined(__NetBSD__)
+    scsireq_t req;
+    int nblocks = 1;
+
+    memset(&req, 0, sizeof(req));
+    req.cmd[0] = 0xbe;
+    req.cmd[1] = 0;
+    req.cmd[2] = (frame >> 24) & 0xff;
+    req.cmd[3] = (frame >> 16) & 0xff;
+    req.cmd[4] = (frame >> 8) & 0xff;
+    req.cmd[5] = (frame >> 0) & 0xff;
+    req.cmd[6] = (nblocks >> 16) & 0xff;
+    req.cmd[7] = (nblocks >> 8) & 0xff;
+    req.cmd[8] = (nblocks >> 0) & 0xff;
+    req.cmd[9] = 0x78;
+    req.cmdlen = 10;
+
+    req.datalen = nblocks * CD_RAW_FRAME_SIZE;
+    req.databuf = data;
+    req.timeout = 10000;
+    req.flags = SCCMD_READ;
+
+    if(ioctl(fd, SCIOCCOMMAND, &req) < 0) {
+      perror("SCIOCCOMMAND");
+      return -1;
+    }
+#endif
     
     data += CD_RAW_FRAME_SIZE;
     frame++;
