]> xenbits.xen.org Git - xenclient/ioemu.git/commitdiff
ioemu: emulate No_Soft_Reset in PMCSR
authorIan Jackson <ian.jackson@eu.citrix.com>
Tue, 24 Mar 2009 13:30:10 +0000 (13:30 +0000)
committerIan Jackson <Ian.Jackson@eu.citrix.com>
Tue, 24 Mar 2009 13:30:10 +0000 (13:30 +0000)
When pci_power_mgmt=0, the No_Soft_Reset field in power
management control/status register of a PCI device needs to be
emulated and fixed to 1. This bit indicates that devices
transitioning from D3 to D0 because of PowerState commands do not
perform an internal reset.

Signed-off-by: Kouya Shimura <kouya@jp.fujitsu.com>
hw/pass-through.c

index 0e3d80b9171eb2f24dd0c4f62a836a921f84561a..f23bdbb3093f2347620a5db78616531fbeab976e 100644 (file)
@@ -2868,7 +2868,7 @@ static int pt_pmcsr_reg_read(struct pt_dev *ptdev,
     uint16_t valid_emu_mask = reg->emu_mask;
 
     if (!ptdev->power_mgmt)
-        valid_emu_mask |= PCI_PM_CTRL_STATE_MASK;
+        valid_emu_mask |= PCI_PM_CTRL_STATE_MASK | PCI_PM_CTRL_NO_SOFT_RESET;
 
     valid_emu_mask = valid_emu_mask & valid_mask ;
     *value = PT_MERGE_VALUE(*value, cfg_entry->data, ~valid_emu_mask);
@@ -3152,37 +3152,26 @@ static int pt_pmcsr_reg_write(struct pt_dev *ptdev,
 {
     struct pt_reg_info_tbl *reg = cfg_entry->reg;
     PCIDevice *d = &ptdev->dev;
+    uint16_t emu_mask = reg->emu_mask;
     uint16_t writable_mask = 0;
     uint16_t throughable_mask = 0;
     struct pt_pm_info *pm_state = ptdev->pm_state;
     uint16_t read_val = 0;
 
-    if (!ptdev->power_mgmt) {
-        uint16_t emu_mask = 
-            PCI_PM_CTRL_PME_STATUS | PCI_PM_CTRL_DATA_SCALE_MASK |
-            PCI_PM_CTRL_PME_ENABLE |
-            PCI_PM_CTRL_DATA_SEL_MASK | PCI_PM_CTRL_STATE_MASK;
-        uint16_t ro_mask = PCI_PM_CTRL_DATA_SCALE_MASK;
-
-        /* modify emulate register */
-        writable_mask = emu_mask & ~ro_mask & valid_mask;
-
-        cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask);
-        /* create value for writing to I/O device register */
-        throughable_mask = ~emu_mask & valid_mask;
-        *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask);
-
-        return 0;
-    }
+    if (!ptdev->power_mgmt)
+        emu_mask |= PCI_PM_CTRL_STATE_MASK | PCI_PM_CTRL_NO_SOFT_RESET;
 
     /* modify emulate register */
-    writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;
+    writable_mask = emu_mask & ~reg->ro_mask & valid_mask;
     cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask);
 
     /* create value for writing to I/O device register */
-    throughable_mask = ~reg->emu_mask & valid_mask;
+    throughable_mask = ~emu_mask & valid_mask;
     *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask);
 
+    if (!ptdev->power_mgmt)
+        return 0;
+
     /* set I/O device power state */
     pm_state->cur_state = (dev_value & PCI_PM_CTRL_STATE_MASK);