diff options
Diffstat (limited to 'hw/ide.c')
-rw-r--r-- | hw/ide.c | 38 |
1 files changed, 25 insertions, 13 deletions
@@ -418,6 +418,7 @@ typedef struct IDEState { /* ATAPI specific */ uint8_t sense_key; uint8_t asc; + uint8_t cdrom_changed; int packet_transfer_size; int elementary_transfer_size; int io_buffer_index; @@ -1660,9 +1661,10 @@ static void ide_atapi_cmd(IDEState *s) } switch(s->io_buffer[0]) { case GPCMD_TEST_UNIT_READY: - if (bdrv_is_inserted(s->bs)) { + if (bdrv_is_inserted(s->bs) && !s->cdrom_changed) { ide_atapi_cmd_ok(s); } else { + s->cdrom_changed = 0; ide_atapi_cmd_error(s, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT); } @@ -2122,7 +2124,7 @@ static void cdrom_change_cb(void *opaque) s->sense_key = SENSE_UNIT_ATTENTION; s->asc = ASC_MEDIUM_MAY_HAVE_CHANGED; - + s->cdrom_changed = 1; ide_set_irq(s); } @@ -2890,7 +2892,7 @@ static void ide_save(QEMUFile* f, IDEState *s) } /* load per IDE drive data */ -static void ide_load(QEMUFile* f, IDEState *s) +static void ide_load(QEMUFile* f, IDEState *s, int version_id) { s->mult_sectors=qemu_get_be32(f); s->identify_set=qemu_get_be32(f); @@ -2914,6 +2916,13 @@ static void ide_load(QEMUFile* f, IDEState *s) qemu_get_8s(f, &s->sense_key); qemu_get_8s(f, &s->asc); + if (version_id == 3) { + qemu_get_8s(f, &s->cdrom_changed); + } else { + if (s->sense_key == SENSE_UNIT_ATTENTION && + s->asc == ASC_MEDIUM_MAY_HAVE_CHANGED) + s->cdrom_changed = 1; + } /* XXX: if a transfer is pending, we do not save it yet */ } @@ -3235,7 +3244,7 @@ static int pci_ide_load(QEMUFile* f, void *opaque, int version_id) PCIIDEState *d = opaque; int ret, i; - if (version_id != 2) + if (version_id != 2 && version_id != 3) return -EINVAL; ret = pci_device_load(&d->dev, f); if (ret < 0) @@ -3265,7 +3274,7 @@ static int pci_ide_load(QEMUFile* f, void *opaque, int version_id) /* per IDE drive data */ for(i = 0; i < 4; i++) { - ide_load(f, &d->ide_if[i]); + ide_load(f, &d->ide_if[i], version_id); } return 0; } @@ -3355,7 +3364,7 @@ void pci_cmd646_ide_init(PCIBus *bus, BlockDriverState **hd_table, ide_init2(&d->ide_if[0], hd_table[0], hd_table[1], irq[0]); ide_init2(&d->ide_if[2], hd_table[2], hd_table[3], irq[1]); - register_savevm("ide", 0, 2, pci_ide_save, pci_ide_load, d); + register_savevm("ide", 0, 3, pci_ide_save, pci_ide_load, d); qemu_register_reset(cmd646_reset, d); cmd646_reset(d); } @@ -3414,7 +3423,7 @@ void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn, if (hd_table[i]) hd_table[i]->private = &d->dev; - register_savevm("ide", 0, 2, pci_ide_save, pci_ide_load, d); + register_savevm("ide", 0, 3, pci_ide_save, pci_ide_load, d); } /* hd_table must contain 4 block drivers */ @@ -3450,7 +3459,7 @@ void pci_piix4_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn, ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6); ide_init_ioport(&d->ide_if[2], 0x170, 0x376); - register_savevm("ide", 0, 2, pci_ide_save, pci_ide_load, d); + register_savevm("ide", 0, 3, pci_ide_save, pci_ide_load, d); } #if defined(TARGET_PPC) @@ -3738,7 +3747,7 @@ static int pmac_ide_load(QEMUFile *f, void *opaque, int version_id) uint8_t drive1_selected; unsigned int i; - if (version_id != 1) + if (version_id != 1 && version_id != 3) return -EINVAL; /* per IDE interface data */ @@ -3748,7 +3757,7 @@ static int pmac_ide_load(QEMUFile *f, void *opaque, int version_id) /* per IDE drive data */ for(i = 0; i < 2; i++) { - ide_load(f, &s[i]); + ide_load(f, &s[i], version_id); } return 0; } @@ -3779,7 +3788,7 @@ int pmac_ide_init (BlockDriverState **hd_table, qemu_irq irq, pmac_ide_memory = cpu_register_io_memory(pmac_ide_read, pmac_ide_write, d); - register_savevm("ide", 0, 1, pmac_ide_save, pmac_ide_load, d); + register_savevm("ide", 0, 3, pmac_ide_save, pmac_ide_load, d); qemu_register_reset(pmac_ide_reset, d); pmac_ide_reset(d); @@ -4172,6 +4181,9 @@ static int md_load(QEMUFile *f, void *opaque, int version_id) int i; uint8_t drive1_selected; + if (version_id != 0 && version_id != 3) + return -EINVAL; + qemu_get_8s(f, &s->opt); qemu_get_8s(f, &s->stat); qemu_get_8s(f, &s->pins); @@ -4185,7 +4197,7 @@ static int md_load(QEMUFile *f, void *opaque, int version_id) s->ide->cur_drive = &s->ide[(drive1_selected != 0)]; for (i = 0; i < 2; i ++) - ide_load(f, &s->ide[i]); + ide_load(f, &s->ide[i], version_id); return 0; } @@ -4416,7 +4428,7 @@ PCMCIACardState *dscm1xxxx_init(BlockDriverState *bdrv) md->ide->mdata_size = METADATA_SIZE; md->ide->mdata_storage = (uint8_t *) qemu_mallocz(METADATA_SIZE); - register_savevm("microdrive", -1, 0, md_save, md_load, md); + register_savevm("microdrive", -1, 3, md_save, md_load, md); return &md->card; } |