Revision c0897e0c

b/hw/ide.h
24 24
                    qemu_irq irq, int shift,
25 25
                    DriveInfo *hd0, DriveInfo *hd1);
26 26

  
27
void ide_get_bs(BlockDriverState *bs[], BusState *qbus);
28

  
27 29
#endif /* HW_IDE_H */
b/hw/ide/qdev.c
88 88
    return DO_UPCAST(IDEDevice, qdev, dev);
89 89
}
90 90

  
91
void ide_get_bs(BlockDriverState *bs[], BusState *qbus)
92
{
93
    IDEBus *bus = DO_UPCAST(IDEBus, qbus, qbus);
94
    bs[0] = bus->master ? bus->master->conf.bs : NULL;
95
    bs[1] = bus->slave  ? bus->slave->conf.bs  : NULL;
96
}
97

  
91 98
/* --------------------------------- */
92 99

  
93 100
typedef struct IDEDrive {
b/hw/pc.c
25 25
#include "pc.h"
26 26
#include "apic.h"
27 27
#include "fdc.h"
28
#include "ide.h"
28 29
#include "pci.h"
29 30
#include "vmware_vga.h"
30 31
#include "monitor.h"
......
275 276
    return set_boot_dev(opaque, boot_device, 0);
276 277
}
277 278

  
278
/* hd_table must contain 4 block drivers */
279
typedef struct pc_cmos_init_late_arg {
280
    ISADevice *rtc_state;
281
    BusState *idebus0, *idebus1;
282
} pc_cmos_init_late_arg;
283

  
284
static void pc_cmos_init_late(void *opaque)
285
{
286
    pc_cmos_init_late_arg *arg = opaque;
287
    ISADevice *s = arg->rtc_state;
288
    int val;
289
    BlockDriverState *hd_table[4];
290
    int i;
291

  
292
    ide_get_bs(hd_table, arg->idebus0);
293
    ide_get_bs(hd_table + 2, arg->idebus1);
294

  
295
    rtc_set_memory(s, 0x12, (hd_table[0] ? 0xf0 : 0) | (hd_table[1] ? 0x0f : 0));
296
    if (hd_table[0])
297
        cmos_init_hd(0x19, 0x1b, hd_table[0], s);
298
    if (hd_table[1])
299
        cmos_init_hd(0x1a, 0x24, hd_table[1], s);
300

  
301
    val = 0;
302
    for (i = 0; i < 4; i++) {
303
        if (hd_table[i]) {
304
            int cylinders, heads, sectors, translation;
305
            /* NOTE: bdrv_get_geometry_hint() returns the physical
306
                geometry.  It is always such that: 1 <= sects <= 63, 1
307
                <= heads <= 16, 1 <= cylinders <= 16383. The BIOS
308
                geometry can be different if a translation is done. */
309
            translation = bdrv_get_translation_hint(hd_table[i]);
310
            if (translation == BIOS_ATA_TRANSLATION_AUTO) {
311
                bdrv_get_geometry_hint(hd_table[i], &cylinders, &heads, &sectors);
312
                if (cylinders <= 1024 && heads <= 16 && sectors <= 63) {
313
                    /* No translation. */
314
                    translation = 0;
315
                } else {
316
                    /* LBA translation. */
317
                    translation = 1;
318
                }
319
            } else {
320
                translation--;
321
            }
322
            val |= translation << (i * 2);
323
        }
324
    }
325
    rtc_set_memory(s, 0x39, val);
326

  
327
    qemu_unregister_reset(pc_cmos_init_late, opaque);
328
}
329

  
279 330
void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,
280
                  const char *boot_device, DriveInfo **hd_table,
331
                  const char *boot_device,
332
                  BusState *idebus0, BusState *idebus1,
281 333
                  FDCtrl *floppy_controller, ISADevice *s)
282 334
{
283 335
    int val;
284 336
    int fd0, fd1, nb;
285
    int i;
337
    static pc_cmos_init_late_arg arg;
286 338

  
287 339
    /* various important CMOS locations needed by PC/Bochs bios */
288 340

  
......
351 403
    rtc_set_memory(s, REG_EQUIPMENT_BYTE, val);
352 404

  
353 405
    /* hard drives */
354

  
355
    rtc_set_memory(s, 0x12, (hd_table[0] ? 0xf0 : 0) | (hd_table[1] ? 0x0f : 0));
356
    if (hd_table[0])
357
        cmos_init_hd(0x19, 0x1b, hd_table[0]->bdrv, s);
358
    if (hd_table[1])
359
        cmos_init_hd(0x1a, 0x24, hd_table[1]->bdrv, s);
360

  
361
    val = 0;
362
    for (i = 0; i < 4; i++) {
363
        if (hd_table[i]) {
364
            int cylinders, heads, sectors, translation;
365
            /* NOTE: bdrv_get_geometry_hint() returns the physical
366
                geometry.  It is always such that: 1 <= sects <= 63, 1
367
                <= heads <= 16, 1 <= cylinders <= 16383. The BIOS
368
                geometry can be different if a translation is done. */
369
            translation = bdrv_get_translation_hint(hd_table[i]->bdrv);
370
            if (translation == BIOS_ATA_TRANSLATION_AUTO) {
371
                bdrv_get_geometry_hint(hd_table[i]->bdrv, &cylinders, &heads, &sectors);
372
                if (cylinders <= 1024 && heads <= 16 && sectors <= 63) {
373
                    /* No translation. */
374
                    translation = 0;
375
                } else {
376
                    /* LBA translation. */
377
                    translation = 1;
378
                }
379
            } else {
380
                translation--;
381
            }
382
            val |= translation << (i * 2);
383
        }
384
    }
385
    rtc_set_memory(s, 0x39, val);
406
    arg.rtc_state = s;
407
    arg.idebus0 = idebus0;
408
    arg.idebus1 = idebus1;
409
    qemu_register_reset(pc_cmos_init_late, &arg);
386 410
}
387 411

  
388 412
static void handle_a20_line_change(void *opaque, int irq, int level)
b/hw/pc.h
104 104
void pc_audio_init (PCIBus *pci_bus, qemu_irq *pic);
105 105
#endif
106 106
void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,
107
                  const char *boot_device, DriveInfo **hd_table,
107
                  const char *boot_device,
108
                  BusState *ide0, BusState *ide1,
108 109
                  FDCtrl *floppy_controller, ISADevice *s);
109 110
void pc_pci_device_init(PCIBus *pci_bus);
110 111

  
b/hw/pc_piix.c
79 79
    IsaIrqState *isa_irq_state;
80 80
    DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
81 81
    FDCtrl *floppy_controller;
82
    BusState *idebus[MAX_IDE_BUS];
82 83
    ISADevice *rtc_state;
83 84

  
84 85
    pc_cpus_init(cpu_model);
......
132 133
    }
133 134

  
134 135
    if (pci_enabled) {
135
        pci_piix3_ide_init(pci_bus, hd, piix3_devfn + 1);
136
        PCIDevice *dev;
137
        dev = pci_piix3_ide_init(pci_bus, hd, piix3_devfn + 1);
138
        idebus[0] = qdev_get_child_bus(&dev->qdev, "ide.0");
139
        idebus[1] = qdev_get_child_bus(&dev->qdev, "ide.1");
136 140
    } else {
137 141
        for(i = 0; i < MAX_IDE_BUS; i++) {
138
            isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i],
139
	                 hd[MAX_IDE_DEVS * i], hd[MAX_IDE_DEVS * i + 1]);
142
            ISADevice *dev;
143
            dev = isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i],
144
                               hd[MAX_IDE_DEVS * i], hd[MAX_IDE_DEVS * i + 1]);
145
            idebus[i] = qdev_get_child_bus(&dev->qdev, "ide.0");
140 146
        }
141 147
    }
142 148

  
143 149
    pc_audio_init(pci_enabled ? pci_bus : NULL, isa_irq);
144 150

  
145
    pc_cmos_init(below_4g_mem_size, above_4g_mem_size, boot_device, hd,
146
                 floppy_controller, rtc_state);
151
    pc_cmos_init(below_4g_mem_size, above_4g_mem_size, boot_device,
152
                 idebus[0], idebus[1], floppy_controller, rtc_state);
147 153

  
148 154
    if (pci_enabled && usb_enabled) {
149 155
        usb_uhci_piix3_init(pci_bus, piix3_devfn + 2);

Also available in: Unified diff