The following patch re-implements the "GET CONFIGURATION" MMC-6 command to
match the published SPEC.
This is a re-write of the original patch series published but including the
feedback received :
http://lists.gnu.org/archive/html/qemu-devel/2007-11/msg00849.html
Important changes from the previous patch :
* Use a 99min CD size as the bigger possible sector count for CD profile
* Don't recalculate the number of sectors
* Use an inline helper function to set the profiles in a cleaner way
* Avoid extra computations from constants while reducing the use of magic
numbers and using defines when possible.
Carlo
---
Index: hw/ide.c
===
RCS file: /sources/qemu/qemu/hw/ide.c,v
retrieving revision 1.79
diff -u -p -r1.79 ide.c
--- hw/ide.c24 Dec 2007 14:33:24 - 1.79
+++ hw/ide.c7 Jan 2008 11:57:43 -
@@ -1,5 +1,5 @@
/*
- * QEMU IDE disk and CD-ROM Emulator
+ * QEMU IDE disk and CD/DVD-ROM Emulator
*
* Copyright (c) 2003 Fabrice Bellard
* Copyright (c) 2006 Openedhand Ltd.
@@ -284,6 +284,44 @@
* of MODE_SENSE_POWER_PAGE */
#define GPMODE_CDROM_PAGE 0x0d
+/* Some generally useful CD-ROM information */
+#define CD_MINS 99 /* max. minutes per CD */
+#define CD_SECS 60 /* seconds per minute */
+#define CD_FRAMES 75 /* frames per second */
+#define CD_FRAMESIZE2048 /* bytes per frame, "cooked" mode */
+#define CD_MAX_BYTES 912384000 /* multiply all of the above */
+#define CD_MAX_SECTORS 1782000 /* divide by 512 */
+
+/* Profile list from MMC-6 revision 1 table 91 */
+#define MMC_PROFILE_NONE0x
+#define MMC_PROFILE_CD_ROM 0x0008
+#define MMC_PROFILE_CD_R0x0009
+#define MMC_PROFILE_CD_RW 0x000A
+#define MMC_PROFILE_DVD_ROM 0x0010
+#define MMC_PROFILE_DVD_R_SR0x0011
+#define MMC_PROFILE_DVD_RAM 0x0012
+#define MMC_PROFILE_DVD_RW_RO 0x0013
+#define MMC_PROFILE_DVD_RW_SR 0x0014
+#define MMC_PROFILE_DVD_R_DL_SR 0x0015
+#define MMC_PROFILE_DVD_R_DL_JR 0x0016
+#define MMC_PROFILE_DVD_RW_DL 0x0017
+#define MMC_PROFILE_DVD_DDR 0x0018
+#define MMC_PROFILE_DVD_PLUS_RW 0x001A
+#define MMC_PROFILE_DVD_PLUS_R 0x001B
+#define MMC_PROFILE_DVD_PLUS_RW_DL 0x002A
+#define MMC_PROFILE_DVD_PLUS_R_DL 0x002B
+#define MMC_PROFILE_BD_ROM 0x0040
+#define MMC_PROFILE_BD_R_SRM0x0041
+#define MMC_PROFILE_BD_R_RRM0x0042
+#define MMC_PROFILE_BD_RE 0x0043
+#define MMC_PROFILE_HDDVD_ROM 0x0050
+#define MMC_PROFILE_HDDVD_R 0x0051
+#define MMC_PROFILE_HDDVD_RAM 0x0052
+#define MMC_PROFILE_HDDVD_RW0x0053
+#define MMC_PROFILE_HDDVD_R_DL 0x0058
+#define MMC_PROFILE_HDDVD_RW_DL 0x005A
+#define MMC_PROFILE_INVALID 0x
+
#define ATAPI_INT_REASON_CD 0x01 /* 0 = data transfer */
#define ATAPI_INT_REASON_IO 0x02 /* 1 = transfer to the host */
#define ATAPI_INT_REASON_REL0x04
@@ -540,7 +578,7 @@ static void ide_atapi_identify(IDEState
put_le16(p + 21, 512); /* cache size in sectors */
put_le16(p + 22, 4); /* ecc bytes */
padstr((char *)(p + 23), QEMU_VERSION, 8); /* firmware version */
-padstr((char *)(p + 27), "QEMU CD-ROM", 40); /* model */
+padstr((char *)(p + 27), "QEMU DVD-ROM", 40); /* model */
put_le16(p + 48, 1); /* dword I/O (XXX: should not be set on CDROM) */
#ifdef USE_DMA_CDROM
put_le16(p + 49, 1 << 9 | 1 << 8); /* DMA and LBA supported */
@@ -1290,6 +1328,22 @@ static void ide_atapi_cmd_read(IDEState
}
}
+static inline uint8_t ide_atapi_set_profile(uint8_t *buf, uint8_t *index,
+uint16_t profile)
+{
+uint8_t *buf_profile = buf + 12; /* start of profiles */
+
+buf_profile += ((*index) * 4); /* start of indexed profile */
+cpu_to_ube16 (buf_profile, profile);
+buf_profile[2] = ((buf_profile[0] == buf[6]) && (buf_profile[1] ==
buf[7]));
+
+/* each profile adds 4 bytes to the response */
+(*index)++;
+buf[11] += 4; /* Additional Length */
+
+return 4;
+}
+
static void ide_atapi_cmd(IDEState *s)
{
const uint8_t *packet;
@@ -1634,13 +1688,13 @@ static void ide_atapi_cmd(IDEState *s)
buf[6] = 0; /* reserved */
buf[7] = 0; /* reserved */
padstr8(buf + 8, 8, "QEMU");
-padstr8(buf + 16, 16, "QEMU CD-ROM");
+padstr8(buf + 16, 16, "QEMU DVD-ROM");
padstr8(buf + 32, 4, QEMU_VERSION);
ide_atapi_cmd_reply(s, 36, max_len);
break;
case GPCMD_GET_CONFIGURATION:
{
-uint64_t total_sectors;
+uint32_t len;
/* only feature 0 is supported */
if (packet[2] !=