Il 31/03/2014 20:14, Cole Robinson ha scritto:
irq_state is cleared before pci_device_deassert_intx. But tries to clear all irqs via pci_irq_handler, but that function will exit without taking any action if the requested irq level matches what we already track in irq_state. Since irq_state is 0, pci_device_deassert_intx is basically a no-op. Any interrupts with level=1 will not be cleared, which is the case with the usb tablet after usb_detach.
Thanks for the analysis. It's my bug indeed.
This fixes things for me, but I have no idea if it's the proper fix: diff --git a/hw/pci/pci.c b/hw/pci/pci.c index 8f722dd..1912dfb 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -189,9 +189,9 @@ static void pci_do_device_reset(PCIDevice *dev) { int r; + pci_device_deassert_intx(dev); dev->irq_state = 0; pci_update_irq_status(dev); - pci_device_deassert_intx(dev); /* Clear all writable bits */ pci_word_test_and_clear_mask(dev->config + PCI_COMMAND, pci_get_word(dev->wmask + PCI_COMMAND) |
Yes, the patch is fine. Even better, dev->irq_state = 0 could become an assertion too, and the call to pci_update_irq_status is not necessary at all.
Paolo