提交 61d9d6b0 编写于 作者: S Stefan Hajnoczi 提交者: Kevin Wolf

ide: Register vm change state handler once only

We register the vm change state handler in a PCI BAR map() function.
This function can be called multiple times throughout the lifetime of a
PCI IDE device.  This results in duplicate vm change state handlers
being register, none of which are ever unregistered.

Instead, register the vm change state handler in the device's init
function once and for all.

piix tested, cmd646 and via not tested.
Signed-off-by: NStefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: NKevin Wolf <kwolf@redhat.com>
上级 ad717139
......@@ -167,10 +167,6 @@ static void bmdma_map(PCIDevice *pci_dev, int region_num,
for(i = 0;i < 2; i++) {
BMDMAState *bm = &d->bmdma[i];
bmdma_init(&d->bus[i], bm);
bm->bus = d->bus+i;
qemu_add_vm_change_state_handler(d->bus[i].dma->ops->restart_cb,
&bm->dma);
if (i == 0) {
register_ioport_write(addr, 4, 1, bmdma_writeb_0, d);
......@@ -228,6 +224,7 @@ static int pci_cmd646_ide_initfn(PCIDevice *dev)
PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev);
uint8_t *pci_conf = d->dev.config;
qemu_irq *irq;
int i;
pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_CMD);
pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_CMD_646);
......@@ -253,10 +250,15 @@ static int pci_cmd646_ide_initfn(PCIDevice *dev)
pci_conf[PCI_INTERRUPT_PIN] = 0x01; // interrupt on pin 1
irq = qemu_allocate_irqs(cmd646_set_irq, d, 2);
ide_bus_new(&d->bus[0], &d->dev.qdev, 0);
ide_bus_new(&d->bus[1], &d->dev.qdev, 1);
ide_init2(&d->bus[0], irq[0]);
ide_init2(&d->bus[1], irq[1]);
for (i = 0; i < 2; i++) {
ide_bus_new(&d->bus[i], &d->dev.qdev, i);
ide_init2(&d->bus[i], irq[i]);
bmdma_init(&d->bus[i], &d->bmdma[i]);
bm->bus = &d->bus[i];
qemu_add_vm_change_state_handler(d->bus[i].dma->ops->restart_cb,
&d->bmdma[i]->dma);
}
vmstate_register(&dev->qdev, 0, &vmstate_ide_pci, d);
qemu_register_reset(cmd646_reset, d);
......
......@@ -76,10 +76,6 @@ static void bmdma_map(PCIDevice *pci_dev, int region_num,
for(i = 0;i < 2; i++) {
BMDMAState *bm = &d->bmdma[i];
bmdma_init(&d->bus[i], bm);
bm->bus = d->bus+i;
qemu_add_vm_change_state_handler(d->bus[i].dma->ops->restart_cb,
&bm->dma);
register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm);
......@@ -112,6 +108,29 @@ static void piix3_reset(void *opaque)
pci_conf[0x20] = 0x01; /* BMIBA: 20-23h */
}
static void pci_piix_init_ports(PCIIDEState *d) {
int i;
struct {
int iobase;
int iobase2;
int isairq;
} port_info[] = {
{0x1f0, 0x3f6, 14},
{0x170, 0x376, 15},
};
for (i = 0; i < 2; i++) {
ide_bus_new(&d->bus[i], &d->dev.qdev, i);
ide_init_ioport(&d->bus[i], port_info[i].iobase, port_info[i].iobase2);
ide_init2(&d->bus[i], isa_reserve_irq(port_info[i].isairq));
bmdma_init(&d->bus[i], &d->bmdma[i]);
d->bmdma[i].bus = &d->bus[i];
qemu_add_vm_change_state_handler(d->bus[i].dma->ops->restart_cb,
&d->bmdma[i].dma);
}
}
static int pci_piix_ide_initfn(PCIIDEState *d)
{
uint8_t *pci_conf = d->dev.config;
......@@ -125,13 +144,8 @@ static int pci_piix_ide_initfn(PCIIDEState *d)
vmstate_register(&d->dev.qdev, 0, &vmstate_ide_pci, d);
ide_bus_new(&d->bus[0], &d->dev.qdev, 0);
ide_bus_new(&d->bus[1], &d->dev.qdev, 1);
ide_init_ioport(&d->bus[0], 0x1f0, 0x3f6);
ide_init_ioport(&d->bus[1], 0x170, 0x376);
pci_piix_init_ports(d);
ide_init2(&d->bus[0], isa_reserve_irq(14));
ide_init2(&d->bus[1], isa_reserve_irq(15));
return 0;
}
......
......@@ -78,10 +78,6 @@ static void bmdma_map(PCIDevice *pci_dev, int region_num,
for(i = 0;i < 2; i++) {
BMDMAState *bm = &d->bmdma[i];
bmdma_init(&d->bus[i], bm);
bm->bus = d->bus+i;
qemu_add_vm_change_state_handler(d->bus[i].dma->ops->restart_cb,
&bm->dma);
register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm);
......@@ -135,6 +131,29 @@ static void via_reset(void *opaque)
pci_set_long(pci_conf + 0xc0, 0x00020001);
}
static void vt82c686b_init_ports(PCIIDEState *d) {
int i;
struct {
int iobase;
int iobase2;
int isairq;
} port_info[] = {
{0x1f0, 0x3f6, 14},
{0x170, 0x376, 15},
};
for (i = 0; i < 2; i++) {
ide_bus_new(&d->bus[i], &d->dev.qdev, i);
ide_init_ioport(&d->bus[i], port_info[i].iobase, port_info[i].iobase2);
ide_init2(&d->bus[i], isa_reserve_irq(port_info[i].isairq));
bmdma_init(&d->bus[i], &d->bmdma[i]);
d->bmdma[i].bus = &d->bus[i];
qemu_add_vm_change_state_handler(d->bus[i].dma->ops->restart_cb,
&d->bmdma[i]->dma);
}
}
/* via ide func */
static int vt82c686b_ide_initfn(PCIDevice *dev)
{
......@@ -154,12 +173,7 @@ static int vt82c686b_ide_initfn(PCIDevice *dev)
vmstate_register(&dev->qdev, 0, &vmstate_ide_pci, d);
ide_bus_new(&d->bus[0], &d->dev.qdev, 0);
ide_bus_new(&d->bus[1], &d->dev.qdev, 1);
ide_init2(&d->bus[0], isa_reserve_irq(14));
ide_init2(&d->bus[1], isa_reserve_irq(15));
ide_init_ioport(&d->bus[0], 0x1f0, 0x3f6);
ide_init_ioport(&d->bus[1], 0x170, 0x376);
vt82c686b_init_ports(d);
return 0;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册