From: "Pascal Terjan" <pterjan@gmail.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] Patch to see all tracks on CDROM
Date: Thu, 5 Oct 2006 20:15:12 +0200 [thread overview]
Message-ID: <e8ca35370610051115m6dac99fdob3c2be607554c14a@mail.gmail.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 536 bytes --]
Hello,
Here is a dirty patch to see all tracks of a CD-ROM as I need it. It
basically reads TOC in the cdrom_read_toc function.
The patch only works for Linux (but adding support for other OS should
not be difficult)
What would be needed is to have a BlockDriverState parameter for
cdrom_read_toc in order to avoid exporting the list and searching for
a CDROM inside it.
Another nice thing would be to handle .toc/.bin but that would need
adding a field somewhere to keep the .toc filename.
BTW, why does -snapshot apply to cdrom ?
[-- Attachment #2: qemu-cdrom-multi_track.patch --]
[-- Type: text/x-patch, Size: 5210 bytes --]
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 5 Oct 2006 18:00:31 -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) {
+ 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 5 Oct 2006 18:00:31 -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
next reply other threads:[~2006-10-05 18:15 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-10-05 18:15 Pascal Terjan [this message]
2006-10-11 16:14 ` [Qemu-devel] Re: Patch to see all tracks on CDROM Pascal Terjan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=e8ca35370610051115m6dac99fdob3c2be607554c14a@mail.gmail.com \
--to=pterjan@gmail.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).