From 2af643776b942d1ce16966c74ec1bef014aac32a Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 20 Sep 2011 16:10:05 +0200 Subject: [PATCH 13/13] ide: link BMDMA and IDEState at device creation. RH-Author: Paolo Bonzini Message-id: <1316535005-26089-1-git-send-email-pbonzini@redhat.com> Patchwork-id: 33005 O-Subject: [RHEL 6.2 KVM PATCH] ide: link BMDMA and IDEState at device creation. Bugzilla: 739480 RH-Acked-by: Kevin Wolf RH-Acked-by: Alex Williamson RH-Acked-by: Christoph Hellwig Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=739480 Upstream status: 61d9d6b0 Brew build: https://brewweb.devel.redhat.com/taskinfo?taskID=3646955 We attach the BMDMA to the IDE bus in a PCI BAR map() function. This does not work correctly when the error status subsection has to be sent. Instead, do once-only work in the device's init function. These are the PIIX parts of upstream commit 61d9d6b0. The others did not compile in the version that was pushed upstream, so I just stripped them. This is a regression caused by the fix for bug 698537 (upstream def93791). QE only reproduced the bug in 1/60 chances, but the segfault accessing bm->bus relates very well to this patch, and this one was already upstream when Kevin fixed the bug there. Hence sanity tested only (boot+migrate), but please review and ack. --- hw/ide/piix.c | 33 +++++++++++++++++++++++---------- 1 files changed, 23 insertions(+), 10 deletions(-) Signed-off-by: Michal Novotny --- hw/ide/piix.c | 33 +++++++++++++++++++++++---------- 1 files changed, 23 insertions(+), 10 deletions(-) diff --git a/hw/ide/piix.c b/hw/ide/piix.c index fd48d5d..5224ae0 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]; - d->bus[i].bmdma = bm; - bm->bus = d->bus+i; - qemu_add_vm_change_state_handler(ide_dma_restart_cb, bm); - register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm); register_ioport_write(addr + 1, 3, 1, bmdma_writeb, bm); @@ -95,6 +91,28 @@ static void bmdma_map(PCIDevice *pci_dev, int region_num, } } +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)); + + d->bus[i].bmdma = &d->bmdma[i]; + d->bmdma[i].bus = &d->bus[i]; + qemu_add_vm_change_state_handler(ide_dma_restart_cb, &d->bmdma[i]); + } +} + static void piix3_reset(void *opaque) { PCIIDEState *d = opaque; @@ -126,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; } -- 1.7.4.4