int pci_piix3_xen_ide_unplug(DeviceState *dev) { PCIIDEState *pci_ide; DriveInfo *di; int i; IDEDevice *idedev; pci_ide = PCI_IDE(dev); for (i = 0; i < 4; i++) { di = drive_get_by_index(IF_IDE, i); if (di != NULL && !di->media_cd) { BlockBackend *blk = blk_by_legacy_dinfo(di); DeviceState *ds = blk_get_attached_dev(blk); if (ds) { blk_detach_dev(blk, ds); } pci_ide->bus[di->bus].ifs[di->unit].blk = NULL; if (!(i % 2)) { idedev = pci_ide->bus[di->bus].master; } else { idedev = pci_ide->bus[di->bus].slave; } idedev->conf.blk = NULL; monitor_remove_blk(blk); blk_unref(blk); } } qdev_reset_all(DEVICE(dev)); return 0; }
static void vt82c686b_ide_exitfn(PCIDevice *dev) { PCIIDEState *d = PCI_IDE(dev); unsigned i; for (i = 0; i < 2; ++i) { memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].extra_io); memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].addr_ioport); } }
static void pci_cmd646_ide_exitfn(PCIDevice *dev) { PCIIDEState *d = PCI_IDE(dev); unsigned i; for (i = 0; i < 2; ++i) { memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].extra_io); memory_region_destroy(&d->bmdma[i].extra_io); memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].addr_ioport); memory_region_destroy(&d->bmdma[i].addr_ioport); memory_region_destroy(&d->cmd646_bar[i].cmd); memory_region_destroy(&d->cmd646_bar[i].data); } memory_region_destroy(&d->bmdma_bar); }
/* via ide func */ static void vt82c686b_ide_realize(PCIDevice *dev, Error **errp) { PCIIDEState *d = PCI_IDE(dev); uint8_t *pci_conf = dev->config; pci_config_set_prog_interface(pci_conf, 0x8a); /* legacy ATA mode */ pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x000000c0); qemu_register_reset(via_reset, d); bmdma_setup_bar(d); pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar); vmstate_register(DEVICE(dev), 0, &vmstate_ide_pci, d); vt82c686b_init_ports(d); }
static void pci_piix_ide_realize(PCIDevice *dev, Error **errp) { PCIIDEState *d = PCI_IDE(dev); uint8_t *pci_conf = dev->config; pci_conf[PCI_CLASS_PROG] = 0x80; // legacy ATA mode qemu_register_reset(piix3_reset, d); bmdma_setup_bar(d); pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar); vmstate_register(DEVICE(dev), 0, &vmstate_ide_pci, d); pci_piix_init_ports(d); }
/* CMD646 PCI IDE controller */ static int pci_cmd646_ide_initfn(PCIDevice *dev) { PCIIDEState *d = PCI_IDE(dev); uint8_t *pci_conf = dev->config; qemu_irq *irq; int i; pci_conf[PCI_CLASS_PROG] = 0x8f; pci_conf[0x51] = 0x04; // enable IDE0 if (d->secondary) { /* XXX: if not enabled, really disable the seconday IDE controller */ pci_conf[0x51] |= 0x08; /* enable IDE1 */ } setup_cmd646_bar(d, 0); setup_cmd646_bar(d, 1); pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd646_bar[0].data); pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd646_bar[0].cmd); pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd646_bar[1].data); pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd646_bar[1].cmd); bmdma_setup_bar(d); pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar); /* TODO: RST# value should be 0 */ pci_conf[PCI_INTERRUPT_PIN] = 0x01; // interrupt on pin 1 irq = qemu_allocate_irqs(cmd646_set_irq, d, 2); for (i = 0; i < 2; i++) { ide_bus_new(&d->bus[i], sizeof(d->bus[i]), DEVICE(dev), i, 2); ide_init2(&d->bus[i], irq[i]); bmdma_init(&d->bus[i], &d->bmdma[i], d); d->bmdma[i].bus = &d->bus[i]; qemu_add_vm_change_state_handler(d->bus[i].dma->ops->restart_cb, &d->bmdma[i].dma); } vmstate_register(DEVICE(dev), 0, &vmstate_ide_pci, d); qemu_register_reset(cmd646_reset, d); return 0; }
static void via_ide_realize(PCIDevice *dev, Error **errp) { PCIIDEState *d = PCI_IDE(dev); uint8_t *pci_conf = dev->config; int i; pci_config_set_prog_interface(pci_conf, 0x8f); /* native PCI ATA mode */ pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x000000c0); dev->wmask[PCI_INTERRUPT_LINE] = 0xf; qemu_register_reset(via_ide_reset, d); memory_region_init_io(&d->data_bar[0], OBJECT(d), &pci_ide_data_le_ops, &d->bus[0], "via-ide0-data", 8); pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->data_bar[0]); memory_region_init_io(&d->cmd_bar[0], OBJECT(d), &pci_ide_cmd_le_ops, &d->bus[0], "via-ide0-cmd", 4); pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_bar[0]); memory_region_init_io(&d->data_bar[1], OBJECT(d), &pci_ide_data_le_ops, &d->bus[1], "via-ide1-data", 8); pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &d->data_bar[1]); memory_region_init_io(&d->cmd_bar[1], OBJECT(d), &pci_ide_cmd_le_ops, &d->bus[1], "via-ide1-cmd", 4); pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_bar[1]); bmdma_setup_bar(d); pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar); vmstate_register(DEVICE(dev), 0, &vmstate_ide_pci, d); for (i = 0; i < 2; i++) { ide_bus_new(&d->bus[i], sizeof(d->bus[i]), DEVICE(d), i, 2); ide_init2(&d->bus[i], qemu_allocate_irq(via_ide_set_irq, d, i)); bmdma_init(&d->bus[i], &d->bmdma[i], d); d->bmdma[i].bus = &d->bus[i]; ide_register_restart_cb(&d->bus[i]); } }
int pci_piix3_xen_ide_unplug(DeviceState *dev) { PCIIDEState *pci_ide; DriveInfo *di; int i = 0; pci_ide = PCI_IDE(dev); for (; i < 3; i++) { di = drive_get_by_index(IF_IDE, i); if (di != NULL && !di->media_cd) { DeviceState *ds = bdrv_get_attached_dev(di->bdrv); if (ds) { bdrv_detach_dev(di->bdrv, ds); } bdrv_close(di->bdrv); pci_ide->bus[di->bus].ifs[di->unit].bs = NULL; drive_del(di); } } qdev_reset_all(DEVICE(dev)); return 0; }