Patchwork [1/3] ide: device version property

login
register
mail settings
Submitter Gerd Hoffmann
Date Jan. 14, 2010, 1:44 p.m.
Message ID <1263476654-7222-2-git-send-email-kraxel@redhat.com>
Download mbox | patch
Permalink /patch/42885/
State New
Headers show

Comments

Gerd Hoffmann - Jan. 14, 2010, 1:44 p.m.
This patch adds a new property named 'ver' to ide-drive which allows to
specify the version which the virtual disk/cdrom should report to the
guest.  By default this is the qemu version (i.e. 0.12).  usage:

  -drive if=none,id=disk,file=...
  -device ide-drive,bus=ide.0,unit=0,drive=disk,ver=42

You can also switch the version for all ide drives using:

  -global ide-drive.ver=42

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/ide/core.c     |   19 ++++++++++++-------
 hw/ide/internal.h |    4 +++-
 hw/ide/qdev.c     |    3 ++-
 3 files changed, 17 insertions(+), 9 deletions(-)

Patch

diff --git a/hw/ide/core.c b/hw/ide/core.c
index 76c3820..b6643e8 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -115,7 +115,7 @@  static void ide_identify(IDEState *s)
     put_le16(p + 20, 3); /* XXX: retired, remove ? */
     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 + 23), s->version, 8); /* firmware version */
     padstr((char *)(p + 27), "QEMU HARDDISK", 40); /* model */
 #if MAX_MULT_SECTORS > 1
     put_le16(p + 47, 0x8000 | MAX_MULT_SECTORS);
@@ -186,7 +186,7 @@  static void ide_atapi_identify(IDEState *s)
     put_le16(p + 20, 3); /* buffer type */
     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 + 23), s->version, 8); /* firmware version */
     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
@@ -238,7 +238,7 @@  static void ide_cfata_identify(IDEState *s)
     put_le16(p + 8, s->nb_sectors);		/* Sectors per card */
     padstr((char *)(p + 10), s->drive_serial_str, 20); /* serial number */
     put_le16(p + 22, 0x0004);			/* ECC bytes */
-    padstr((char *) (p + 23), QEMU_VERSION, 8);	/* Firmware Revision */
+    padstr((char *) (p + 23), s->version, 8);	/* Firmware Revision */
     padstr((char *) (p + 27), "QEMU MICRODRIVE", 40);/* Model number */
 #if MAX_MULT_SECTORS > 1
     put_le16(p + 47, 0x8000 | MAX_MULT_SECTORS);
@@ -1591,7 +1591,7 @@  static void ide_atapi_cmd(IDEState *s)
         buf[7] = 0; /* reserved */
         padstr8(buf + 8, 8, "QEMU");
         padstr8(buf + 16, 16, "QEMU DVD-ROM");
-        padstr8(buf + 32, 4, QEMU_VERSION);
+        padstr8(buf + 32, 4, s->version);
         ide_atapi_cmd_reply(s, 36, max_len);
         break;
     case GPCMD_GET_CONFIGURATION:
@@ -2590,7 +2590,7 @@  void ide_bus_reset(IDEBus *bus)
     ide_clear_hob(bus);
 }
 
-void ide_init_drive(IDEState *s, DriveInfo *dinfo)
+void ide_init_drive(IDEState *s, DriveInfo *dinfo, const char *version)
 {
     int cylinders, heads, secs;
     uint64_t nb_sectors;
@@ -2619,6 +2619,11 @@  void ide_init_drive(IDEState *s, DriveInfo *dinfo)
     if (strlen(s->drive_serial_str) == 0)
         snprintf(s->drive_serial_str, sizeof(s->drive_serial_str),
                  "QM%05d", s->drive_serial);
+    if (version) {
+        pstrcpy(s->version, sizeof(s->version), version);
+    } else {
+        pstrcpy(s->version, sizeof(s->version), QEMU_VERSION);
+    }
     ide_reset(s);
 }
 
@@ -2639,9 +2644,9 @@  void ide_init2(IDEBus *bus, DriveInfo *hd0, DriveInfo *hd1,
         s->sector_write_timer = qemu_new_timer(vm_clock,
                                                ide_sector_write_timer_cb, s);
         if (i == 0)
-            ide_init_drive(s, hd0);
+            ide_init_drive(s, hd0, NULL);
         if (i == 1)
-            ide_init_drive(s, hd1);
+            ide_init_drive(s, hd1, NULL);
     }
     bus->irq = irq;
 }
diff --git a/hw/ide/internal.h b/hw/ide/internal.h
index eb5b404..1cc4b55 100644
--- a/hw/ide/internal.h
+++ b/hw/ide/internal.h
@@ -397,6 +397,7 @@  struct IDEState {
     /* set for lba48 access */
     uint8_t lba48;
     BlockDriverState *bs;
+    char version[9];
     /* ATAPI specific */
     uint8_t sense_key;
     uint8_t asc;
@@ -449,6 +450,7 @@  struct IDEDevice {
     DeviceState qdev;
     uint32_t unit;
     DriveInfo *dinfo;
+    char *version;
 };
 
 typedef int (*ide_qdev_initfn)(IDEDevice *dev);
@@ -549,7 +551,7 @@  uint32_t ide_data_readw(void *opaque, uint32_t addr);
 void ide_data_writel(void *opaque, uint32_t addr, uint32_t val);
 uint32_t ide_data_readl(void *opaque, uint32_t addr);
 
-void ide_init_drive(IDEState *s, DriveInfo *dinfo);
+void ide_init_drive(IDEState *s, DriveInfo *dinfo, const char *version);
 void ide_init2(IDEBus *bus, DriveInfo *hd0, DriveInfo *hd1,
                qemu_irq irq);
 void ide_init_ioport(IDEBus *bus, int iobase, int iobase2);
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index 81e7995..0b84a4f 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -99,7 +99,7 @@  typedef struct IDEDrive {
 static int ide_drive_initfn(IDEDevice *dev)
 {
     IDEBus *bus = DO_UPCAST(IDEBus, qbus, dev->qdev.parent_bus);
-    ide_init_drive(bus->ifs + dev->unit, dev->dinfo);
+    ide_init_drive(bus->ifs + dev->unit, dev->dinfo, dev->version);
     return 0;
 }
 
@@ -110,6 +110,7 @@  static IDEDeviceInfo ide_drive_info = {
     .qdev.props = (Property[]) {
         DEFINE_PROP_UINT32("unit", IDEDrive, dev.unit, -1),
         DEFINE_PROP_DRIVE("drive", IDEDrive, dev.dinfo),
+        DEFINE_PROP_STRING("ver",  IDEDrive, dev.version),
         DEFINE_PROP_END_OF_LIST(),
     }
 };