diff --git a/hw/ide/internal.h b/hw/ide/internal.h 
index 027029e..b04232c 100644 
--- a/hw/ide/internal.h 
+++ b/hw/ide/internal.h 
@@ -450,6 +450,7 @@ struct IDEBus { 
     IDEState ifs[2]; 
     uint8_t unit; 
     uint8_t cmd; 
+    uint8_t id; 
     qemu_irq irq; 
 }; 
  
diff --git a/hw/ide/piix.c b/hw/ide/piix.c 
index 295a93d..f62aadb 100644 
--- a/hw/ide/piix.c 
+++ b/hw/ide/piix.c 
@@ -136,6 +136,8 @@ static int pci_piix_ide_initfn(PCIIDEState *d) 
     ide_init_ioport(&d->bus[0], 0x1f0, 0x3f6); 
     ide_init_ioport(&d->bus[1], 0x170, 0x376); 
  
+    d->bus[0].id = 0; 
+    d->bus[1].id = 1; 
     ide_init2(&d->bus[0], NULL, NULL, isa_reserve_irq(14)); 
     ide_init2(&d->bus[1], NULL, NULL, isa_reserve_irq(15)); 
     return 0; 
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c 
index b18693d..632eccd 100644 
--- a/hw/ide/qdev.c 
+++ b/hw/ide/qdev.c 
@@ -39,6 +39,7 @@ static int ide_qdev_init(DeviceState *qdev, DeviceInfo *base) 
     IDEDevice *dev = DO_UPCAST(IDEDevice, qdev, qdev); 
     IDEDeviceInfo *info = DO_UPCAST(IDEDeviceInfo, qdev, base); 
     IDEBus *bus = DO_UPCAST(IDEBus, qbus, qdev->parent_bus); 
+    int i; 
  
     if (!dev->conf.dinfo) { 
         fprintf(stderr, "%s: no drive specified\n", qdev->info->name); 
@@ -65,7 +66,13 @@ static int ide_qdev_init(DeviceState *qdev, DeviceInfo *base) 
     default: 
         goto err; 
     } 
-    return info->init(dev); 
+    dev->dinfo->bus = bus->id; 
+    dev->dinfo->unit = dev->unit; 
+    i = info->init(dev); 
+    if (i >= 0) { 
+        machine_ide_finalize(dev->dinfo); 
+    } 
+    return i; 
  
 err: 
     return -1; 
diff --git a/hw/pc.c b/hw/pc.c 
index 69e597f..29f47d4 100644 
--- a/hw/pc.c 
+++ b/hw/pc.c 
@@ -215,6 +215,44 @@ static void cmos_init_hd(int type_ofs, int info_ofs, BlockDriverState *hd) 
     rtc_set_memory(s, info_ofs + 8, sectors); 
 } 
  
+static void set_cmos_hd_data(DriveInfo *dinfo) 
+{ 
+    static int hd_type = 0; 
+    static int hd_trans = 0; 
+    RTCState *s = rtc_state; 
+    int cylinders, heads, sectors, translation; 
+ 
+    if (dinfo->bus == 0) { 
+        if (dinfo->unit == 0) { 
+            hd_type |= 0xf0; 
+            cmos_init_hd(0x19, 0x1b, dinfo->bdrv); 
+        } else { 
+            hd_type |= 0x0f; 
+            cmos_init_hd(0x1a, 0x24, dinfo->bdrv); 
+        } 
+        rtc_set_memory(s, 0x12, hd_type); 
+    } 
+    /* NOTE: bdrv_get_geometry_hint() returns the physical 
+        geometry.  It is always such that: 1 <= sects <= 63, 1 
+        <= heads <= 16, 1 <= cylinders <= 16383. The BIOS 
+        geometry can be different if a translation is done. */ 
+    translation = bdrv_get_translation_hint(dinfo->bdrv); 
+    if (translation == BIOS_ATA_TRANSLATION_AUTO) { 
+        bdrv_get_geometry_hint(dinfo->bdrv, &cylinders, &heads, &sectors); 
+        if (cylinders <= 1024 && heads <= 16 && sectors <= 63) { 
+            /* No translation. */ 
+            translation = 0; 
+        } else { 
+            /* LBA translation. */ 
+            translation = 1; 
+        } 
+    } else { 
+        translation--; 
+    } 
+    hd_trans |= translation << ((dinfo->bus * 4) + (dinfo->unit * 2)); 
+    rtc_set_memory(s, 0x39, hd_trans); 
+} 
+ 
 /* convert boot_device letter to something recognizable by the bios */ 
 static int boot_device2nibble(char boot_device) 
 { 
@@ -338,37 +376,11 @@ static void cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size, 
  
     /* hard drives */ 
  
-    rtc_set_memory(s, 0x12, (hd_table[0] ? 0xf0 : 0) | (hd_table[1] ? 0x0f : 0)); 
-    if (hd_table[0]) 
-        cmos_init_hd(0x19, 0x1b, hd_table[0]->bdrv); 
-    if (hd_table[1]) 
-        cmos_init_hd(0x1a, 0x24, hd_table[1]->bdrv); 
- 
-    val = 0; 
     for (i = 0; i < 4; i++) { 
         if (hd_table[i]) { 
-            int cylinders, heads, sectors, translation; 
-            /* NOTE: bdrv_get_geometry_hint() returns the physical 
-                geometry.  It is always such that: 1 <= sects <= 63, 1 
-                <= heads <= 16, 1 <= cylinders <= 16383. The BIOS 
-                geometry can be different if a translation is done. */ 
-            translation = bdrv_get_translation_hint(hd_table[i]->bdrv); 
-            if (translation == BIOS_ATA_TRANSLATION_AUTO) { 
-                bdrv_get_geometry_hint(hd_table[i]->bdrv, &cylinders, &heads, &sectors); 
-                if (cylinders <= 1024 && heads <= 16 && sectors <= 63) { 
-                    /* No translation. */ 
-                    translation = 0; 
-                } else { 
-                    /* LBA translation. */ 
-                    translation = 1; 
-                } 
-            } else { 
-                translation--; 
-            } 
-            val |= translation << (i * 2); 
+            set_cmos_hd_data(hd_table[i]); 
         } 
     } 
-    rtc_set_memory(s, 0x39, val); 
 } 
  
 void ioport_set_a20(int enable) 
@@ -820,6 +832,8 @@ static void pc_init1(ram_addr_t ram_size, 
     DriveInfo *fd[MAX_FD]; 
     void *fw_cfg; 
  
+    machine_ide_finalize = set_cmos_hd_data; 
+ 
     if (ram_size >= 0xe0000000 ) { 
         above_4g_mem_size = ram_size - 0xe0000000; 
         below_4g_mem_size = 0xe0000000; 
diff --git a/sysemu.h b/sysemu.h 
index d0effa0..564d477 100644 
--- a/sysemu.h 
+++ b/sysemu.h 
@@ -242,5 +242,6 @@ void usb_info(Monitor *mon); 
 void rtc_change_mon_event(struct tm *tm); 
  
 void register_devices(void); 
+extern void (*machine_ide_finalize)(DriveInfo *dinfo); 
  
 #endif 
diff --git a/vl.c b/vl.c 
index ea79ac4..8ab3349 100644 
--- a/vl.c 
+++ b/vl.c 
@@ -228,6 +228,7 @@ int ctrl_grab = 0; 
 unsigned int nb_prom_envs = 0; 
 const char *prom_envs[MAX_PROM_ENVS]; 
 int boot_menu; 
+void (*machine_ide_finalize)(DriveInfo *dinfo); 
  
 int nb_numa_nodes; 
 uint64_t node_mem[MAX_NODES]; 
@@ -275,6 +276,10 @@ static struct { 
     { .driver = "vmware-svga",          .flag = &default_vga       }, 
 }; 
  
+static void default_ide_finalize(DriveInfo *dinfo) 
+{ 
+} 
+ 
 static int default_driver_check(QemuOpts *opts, void *opaque) 
 { 
     const char *driver = qemu_opt_get(opts, "driver"); 
@@ -2624,6 +2629,7 @@ int main(int argc, char **argv, char **envp) 
  
     module_call_init(MODULE_INIT_MACHINE); 
     machine = find_default_machine(); 
+    machine_ide_finalize = default_ide_finalize; 
     cpu_model = NULL; 
     initrd_filename = NULL; 
     ram_size = 0; 
