Problem: x86 systems could not survive a few system_resets.
Clear most of IDE state when reset. Implement the missing reset handlers.
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
PCIIDEState *d = opaque;
unsigned int i;
- for (i = 0; i < 2; i++)
- ide_dma_cancel(&d->bmdma[i]);
+ for (i = 0; i < 2; i++) {
+ ide_bus_reset(&d->bus[i]);
+ ide_dma_reset(&d->bmdma[i]);
+ }
}
/* CMD646 PCI IDE controller */
s->io_buffer[3] = 0xff;
}
-void ide_reset(IDEState *s)
+static void ide_reset(IDEState *s)
{
- IDEBus *bus = s->bus;
-
+#ifdef DEBUG_IDE
+ printf("ide: reset\n");
+#endif
if (s->is_cf)
s->mult_sectors = 0;
else
s->mult_sectors = MAX_MULT_SECTORS;
- bus->unit = s->unit;
+ /* ide regs */
+ s->feature = 0;
+ s->error = 0;
+ s->nsector = 0;
+ s->sector = 0;
+ s->lcyl = 0;
+ s->hcyl = 0;
+
+ /* lba48 */
+ s->hob_feature = 0;
+ s->hob_sector = 0;
+ s->hob_nsector = 0;
+ s->hob_lcyl = 0;
+ s->hob_hcyl = 0;
+
s->select = 0xa0;
s->status = READY_STAT | SEEK_STAT;
+
+ s->lba48 = 0;
+
+ /* ATAPI specific */
+ s->sense_key = 0;
+ s->asc = 0;
+ s->cdrom_changed = 0;
+ s->packet_transfer_size = 0;
+ s->elementary_transfer_size = 0;
+ s->io_buffer_index = 0;
+ s->cd_sector_size = 0;
+ s->atapi_dma = 0;
+ /* ATA DMA state */
+ s->io_buffer_size = 0;
+ s->req_nb_sectors = 0;
+
ide_set_signature(s);
/* init the transfer handler so that 0xffff is returned on data
accesses */
s->media_changed = 0;
}
+void ide_bus_reset(IDEBus *bus)
+{
+ bus->unit = 0;
+ bus->cmd = 0;
+ ide_reset(&bus->ifs[0]);
+ ide_reset(&bus->ifs[1]);
+ ide_clear_hob(bus);
+}
+
void ide_init_drive(IDEState *s, DriveInfo *dinfo)
{
int cylinders, heads, secs;
}
}
+void ide_dma_reset(BMDMAState *bm)
+{
+#ifdef DEBUG_IDE
+ printf("ide: dma_reset\n");
+#endif
+ ide_dma_cancel(bm);
+ bm->cmd = 0;
+ bm->status = 0;
+ bm->addr = 0;
+ bm->cur_addr = 0;
+ bm->cur_prd_last = 0;
+ bm->cur_prd_addr = 0;
+ bm->cur_prd_len = 0;
+ bm->sector_num = 0;
+ bm->nsector = 0;
+}
#define VMSTATE_IDE_DRIVES(_field, _state) \
VMSTATE_STRUCT_ARRAY(_field, _state, 2, 3, vmstate_ide_drive, IDEState)
-void ide_reset(IDEState *s);
+void ide_bus_reset(IDEBus *bus);
int64_t ide_get_sector(IDEState *s);
void ide_set_sector(IDEState *s, int64_t sector_num);
void ide_dma_cancel(BMDMAState *bm);
void ide_dma_restart_cb(void *opaque, int running, int reason);
void ide_dma_error(IDEState *s);
+void ide_dma_reset(BMDMAState *bm);
void ide_atapi_cmd_ok(IDEState *s);
void ide_atapi_cmd_error(IDEState *s, int sense_key, int asc);
qemu_irq irq;
} ISAIDEState;
+static void isa_ide_reset(DeviceState *d)
+{
+ ISAIDEState *s = container_of(d, ISAIDEState, dev.qdev);
+
+ ide_bus_reset(&s->bus);
+}
+
static const VMStateDescription vmstate_ide_isa = {
.name = "isa-ide",
.version_id = 3,
.qdev.name = "isa-ide",
.qdev.size = sizeof(ISAIDEState),
.init = isa_ide_initfn,
+ .qdev.reset = isa_ide_reset,
.qdev.props = (Property[]) {
DEFINE_PROP_HEX32("iobase", ISAIDEState, iobase, 0x1f0),
DEFINE_PROP_HEX32("iobase2", ISAIDEState, iobase2, 0x3f6),
{
MACIOIDEState *d = opaque;
- ide_reset(d->bus.ifs +0);
- ide_reset(d->bus.ifs +1);
+ ide_bus_reset(&d->bus);
}
/* hd_table must contain 4 block drivers */
s->pins = 0;
s->cycle = 0;
s->ctrl = 0;
- ide_reset(s->bus.ifs);
+ ide_bus_reset(&s->bus);
}
static uint8_t md_attr_read(void *opaque, uint32_t at)
int shift;
} MMIOState;
+static void mmio_ide_reset(void *opaque)
+{
+ MMIOState *s = opaque;
+
+ ide_bus_reset(&s->bus);
+}
+
static uint32_t mmio_ide_read (void *opaque, target_phys_addr_t addr)
{
MMIOState *s = opaque;
cpu_register_physical_memory(membase, 16 << shift, mem1);
cpu_register_physical_memory(membase2, 2 << shift, mem2);
vmstate_register(0, &vmstate_ide_mmio, s);
+ qemu_register_reset(mmio_ide_reset, s);
}
uint8_t *pci_conf = d->dev.config;
int i;
- for (i = 0; i < 2; i++)
- ide_dma_cancel(&d->bmdma[i]);
+ for (i = 0; i < 2; i++) {
+ ide_bus_reset(&d->bus[i]);
+ ide_dma_reset(&d->bmdma[i]);
+ }
pci_conf[0x04] = 0x00;
pci_conf[0x05] = 0x00;