summary refs log tree commit diff stats
path: root/hw/pci.c
diff options
context:
space:
mode:
authorIsaku Yamahata <yamahata@valinux.co.jp>2010-06-17 15:15:45 +0900
committerMichael S. Tsirkin <mst@redhat.com>2010-07-11 23:14:19 +0300
commit71ebd6dcf9dc4d733923ba798154aba8893c28ca (patch)
tree71de1b6bdd59a6543c169f6c5c762a0f16c2ba73 /hw/pci.c
parent1ddda5cd364d2f82201830ca69675e17c60ded8e (diff)
downloadfocaccia-qemu-71ebd6dcf9dc4d733923ba798154aba8893c28ca.tar.gz
focaccia-qemu-71ebd6dcf9dc4d733923ba798154aba8893c28ca.zip
pci: fix pci_device_reset
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>
Diffstat (limited to 'hw/pci.c')
-rw-r--r--hw/pci.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/hw/pci.c b/hw/pci.c
index a3c28738c6..645506aa83 100644
--- 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);
 }