]> git.proxmox.com Git - qemu.git/commitdiff
pci: fix pci_device_reset
authorIsaku Yamahata <yamahata@valinux.co.jp>
Thu, 17 Jun 2010 06:15:45 +0000 (15:15 +0900)
committerMichael S. Tsirkin <mst@redhat.com>
Sun, 11 Jul 2010 20:14:19 +0000 (23:14 +0300)
Clear interrupt disable bit on reset, according to PCI spec.
Fix pci_device_reset() with 64bit BAR.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
hw/pci.c

index a3c28738c6a71fe8d4d8fb0c2e9b86a5e0bf015c..645506aa836972a72fb1687556bd5815a6d1873a 100644 (file)
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -155,15 +155,24 @@ static void pci_device_reset(PCIDevice *dev)
 
     dev->irq_state = 0;
     pci_update_irq_status(dev);
-    dev->config[PCI_COMMAND] &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
-                                  PCI_COMMAND_MASTER);
+    /* Clear all writeable bits */
+    pci_set_word(dev->config + PCI_COMMAND,
+                 pci_get_word(dev->config + PCI_COMMAND) &
+                 ~pci_get_word(dev->wmask + PCI_COMMAND));
     dev->config[PCI_CACHE_LINE_SIZE] = 0x0;
     dev->config[PCI_INTERRUPT_LINE] = 0x0;
     for (r = 0; r < PCI_NUM_REGIONS; ++r) {
-        if (!dev->io_regions[r].size) {
+        PCIIORegion *region = &dev->io_regions[r];
+        if (!region->size) {
             continue;
         }
-        pci_set_long(dev->config + pci_bar(dev, r), dev->io_regions[r].type);
+
+        if (!(region->type & PCI_BASE_ADDRESS_SPACE_IO) &&
+            region->type & PCI_BASE_ADDRESS_MEM_TYPE_64) {
+            pci_set_quad(dev->config + pci_bar(dev, r), region->type);
+        } else {
+            pci_set_long(dev->config + pci_bar(dev, r), region->type);
+        }
     }
     pci_update_mappings(dev);
 }