From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from [140.186.70.92] (port=52228 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PTeNF-0001hF-Dz for qemu-devel@nongnu.org; Fri, 17 Dec 2010 12:46:30 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PTeML-00038q-D2 for qemu-devel@nongnu.org; Fri, 17 Dec 2010 12:45:44 -0500 Received: from mx1.redhat.com ([209.132.183.28]:14657) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PTeML-00038b-2L for qemu-devel@nongnu.org; Fri, 17 Dec 2010 12:44:49 -0500 From: Kevin Wolf Date: Fri, 17 Dec 2010 18:44:40 +0100 Message-Id: <1292607893-13461-26-git-send-email-kwolf@redhat.com> In-Reply-To: <1292607893-13461-1-git-send-email-kwolf@redhat.com> References: <1292607893-13461-1-git-send-email-kwolf@redhat.com> Subject: [Qemu-devel] [PATCH 25/38] ide: Register vm change state handler once only List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: anthony@codemonkey.ws Cc: kwolf@redhat.com, qemu-devel@nongnu.org From: Stefan Hajnoczi 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: Stefan Hajnoczi Signed-off-by: Kevin Wolf --- hw/ide/cmd646.c | 18 ++++++++++-------- hw/ide/piix.c | 34 ++++++++++++++++++++++++---------- hw/ide/via.c | 34 ++++++++++++++++++++++++---------- 3 files changed, 58 insertions(+), 28 deletions(-) diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c index e191ee6..89ba836 100644 --- a/hw/ide/cmd646.c +++ b/hw/ide/cmd646.c @@ -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); diff --git a/hw/ide/piix.c b/hw/ide/piix.c index a6b5d92..1cad906 100644 --- a/hw/ide/piix.c +++ b/hw/ide/piix.c @@ -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; } diff --git a/hw/ide/via.c b/hw/ide/via.c index 2603110..5b70bd2 100644 --- a/hw/ide/via.c +++ b/hw/ide/via.c @@ -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; } -- 1.7.2.3