Stupid bug, here is one working when not using -snapshot
Index: hw/cdrom.c
===================================================================
RCS file: /sources/qemu/qemu/hw/cdrom.c,v
retrieving revision 1.1
diff -u -r1.1 cdrom.c
--- hw/cdrom.c	25 May 2006 23:58:51 -0000	1.1
+++ hw/cdrom.c	11 Oct 2006 16:11:13 -0000
@@ -26,6 +26,14 @@
    here.  */
 
 #include <vl.h>
+#include "block_int.h"
+
+#if defined(__linux__)
+#include <sys/ioctl.h>
+#include <linux/cdrom.h>
+#endif
+
+extern BlockDriverState *bdrv_first;
 
 static void lba_to_msf(uint8_t *buf, int lba)
 {
@@ -39,45 +47,125 @@
 /* XXX: check this */
 int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track)
 {
-    uint8_t *q;
-    int len;
-    
-    if (start_track > 1 && start_track != 0xaa)
-        return -1;
-    q = buf + 2;
-    *q++ = 1; /* first session */
-    *q++ = 1; /* last session */
-    if (start_track <= 1) {
-        *q++ = 0; /* reserved */
-        *q++ = 0x14; /* ADR, control */
-        *q++ = 1;    /* track number */
-        *q++ = 0; /* reserved */
-        if (msf) {
-            *q++ = 0; /* reserved */
-            lba_to_msf(q, 0);
-            q += 3;
-        } else {
-            /* sector 0 */
-            cpu_to_be32wu((uint32_t *)q, 0);
-            q += 4;
-        }
+  uint8_t *q;
+  int len;
+  int i;
+  char * filename = NULL;
+
+  /* Find the device filename */
+  BlockDriverState *bs;
+
+  for (bs = bdrv_first; bs != NULL; bs = bs->next) {
+    if(bs->type == BDRV_TYPE_CDROM) {
+      /* Looks like -snapshot also applies to CD */
+      if(bs->backing_file[0]) {
+	filename = bs->backing_file;
+      } else {
+	filename = bs->filename;
+      }
     }
-    /* lead out track */
-    *q++ = 0; /* reserved */
-    *q++ = 0x16; /* ADR, control */
-    *q++ = 0xaa; /* track number */
-    *q++ = 0; /* reserved */
+  }
+
+  int fd = 0;
+#if defined(__linux__)
+  fd = open(filename, O_RDONLY);
+  if(fd<0) {
+    return -1;
+  }
+#endif
+
+  struct cdrom_tochdr tochdr;
+#if defined(__linux__)
+  if (ioctl(fd, CDROMREADTOCHDR, &tochdr)) {
+    /* If we have a file and not a real CD-ROM, revert to old behaviour */
+    /*FIXME We should rather check bs->drv */
+    close(fd);
+    fd = 0;
+#else
+  {
+#endif
+    tochdr.cdth_trk0 = 1;
+    tochdr.cdth_trk1 = 1;
+     
+  }
+
+  if ((start_track > tochdr.cdth_trk1) && (start_track != 0xaa)) {
+    if (fd)
+      close(fd);
+    return -1;
+  }
+  
+  if (start_track < tochdr.cdth_trk0)
+    start_track = tochdr.cdth_trk0;
+  
+  q = buf + 2;
+  *q++ = tochdr.cdth_trk0; /* first session */
+  *q++ = tochdr.cdth_trk1; /* last session */
+  
+  for (i = start_track; i <= tochdr.cdth_trk1; i++) {
+    struct cdrom_tocentry tocentry;
+
+#if defined(__linux__)
+    tocentry.cdte_format = (msf) ? CDROM_MSF : CDROM_LBA;
+    tocentry.cdte_track = i;
+    if (fd) {
+      if (ioctl(fd, CDROMREADTOCENTRY, &tocentry)) {
+	perror("cdrom: read_toc: READTOCENTRY lead-out failed");
+	close(fd);
+	return -1;
+      }
+    } else {
+#else
+    {
+#endif
+      tocentry.cdte_adr = 0;
+      tocentry.cdte_ctrl = 0x14;
+      if (msf) {
+	tocentry.cdte_addr.msf.minute = 0;
+	tocentry.cdte_addr.msf.second = 2;
+	tocentry.cdte_addr.msf.frame = 0;
+      } else {
+	tocentry.cdte_addr.lba = 0;
+      }
+    }
+      
+    *q++ = 0; // Reserved
+    *q++ = (tocentry.cdte_adr << 4) | tocentry.cdte_ctrl ; // ADR, control
+    *q++ = i; // Track number
+    *q++ = 0; // Reserved
+    
+    // Start address
     if (msf) {
-        *q++ = 0; /* reserved */
-        lba_to_msf(q, nb_sectors);
-        q += 3;
+      *q++ = 0; // reserved
+      *q++ = tocentry.cdte_addr.msf.minute;
+      *q++ = tocentry.cdte_addr.msf.second;
+      *q++ = tocentry.cdte_addr.msf.frame;
     } else {
-        cpu_to_be32wu((uint32_t *)q, nb_sectors);
-        q += 4;
+      *q++ = (((unsigned)tocentry.cdte_addr.lba) >> 24) & 0xff;
+      *q++ = (((unsigned)tocentry.cdte_addr.lba) >> 16) & 0xff;
+      *q++ = (((unsigned)tocentry.cdte_addr.lba) >> 8) & 0xff;
+      *q++ = (((unsigned)tocentry.cdte_addr.lba) >> 0) & 0xff;
     }
-    len = q - buf;
-    cpu_to_be16wu((uint16_t *)buf, len - 2);
-    return len;
+  }
+
+  /* lead out track */
+  *q++ = 0; /* reserved */
+  *q++ = 0x16; /* ADR, control */
+  *q++ = 0xaa; /* track number */
+  *q++ = 0; /* reserved */
+  if (msf) {
+    *q++ = 0; /* reserved */
+    lba_to_msf(q, nb_sectors);
+    q += 3;
+  } else {
+    cpu_to_be32wu((uint32_t *)q, nb_sectors);
+    q += 4;
+  }
+  len = q - buf;
+  cpu_to_be16wu((uint16_t *)buf, len - 2);
+  if (fd)
+    close(fd);
+  return len;
 }
 
 /* mostly same info as PearPc */
@@ -152,5 +240,3 @@
     cpu_to_be16wu((uint16_t *)buf, len - 2);
     return len;
 }
-
-
Index: block.c
===================================================================
RCS file: /sources/qemu/qemu/block.c,v
retrieving revision 1.37
diff -u -r1.37 block.c
--- block.c	24 Aug 2006 19:53:37 -0000	1.37
+++ block.c	11 Oct 2006 16:11:14 -0000
@@ -53,7 +53,7 @@
 static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
                          const uint8_t *buf, int nb_sectors);
 
-static BlockDriverState *bdrv_first;
+BlockDriverState *bdrv_first;
 static BlockDriver *first_drv;
 
 #ifdef _WIN32
_______________________________________________
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel

Reply via email to