return err;
}
+/* delete all emulate register */
+static void pt_config_delete(struct pt_dev *ptdev)
+{
+ struct pt_reg_grp_tbl *reg_grp_entry = NULL;
+ struct pt_reg_tbl *reg_entry = NULL;
+
+ /* free MSI/MSI-X info table */
+ if (ptdev->msix)
+ pt_msix_delete(ptdev);
+ if (ptdev->msi)
+ free(ptdev->msi);
+
+ /* free all register group entry */
+ while ((reg_grp_entry = ptdev->reg_grp_tbl_head.lh_first) != NULL)
+ {
+ /* free all register entry */
+ while ((reg_entry = reg_grp_entry->reg_tbl_head.lh_first) != NULL)
+ {
+ QEMU_LIST_REMOVE(reg_entry, entries);
+ qemu_free(reg_entry);
+ }
+
+ QEMU_LIST_REMOVE(reg_grp_entry, entries);
+ qemu_free(reg_grp_entry);
+ }
+}
+
/* initialize common register value */
static uint32_t pt_common_reg_init(struct pt_dev *ptdev,
struct pt_reg_info_tbl *reg, uint32_t real_offset)
/* Unbind interrupt */
e_device = (assigned_device->dev.devfn >> 3) & 0x1f;
- e_intx = assigned_device->dev.config[0x3d]-1;
+ /* fix virtual interrupt pin to INTA# */
+ e_intx = 0;
machine_irq = pci_dev->irq;
if ( machine_irq != 0 ) {
}
}
+ /* delete all emulated config registers */
+ pt_config_delete(assigned_device);
+
/* unregister real device's MMIO/PIO BARs */
pt_unregister_regions(assigned_device);
(unsigned long)dev->msix->phys_iomem_base);
return 0;
}
+
+void pt_msix_delete(struct pt_dev *dev)
+{
+ /* unmap the MSI-X memory mapped register area */
+ if (dev->msix->phys_iomem_base)
+ {
+ PT_LOG("unmapping physical MSI-X table from %lx\n",
+ (unsigned long)dev->msix->phys_iomem_base);
+ munmap(dev->msix->phys_iomem_base, dev->msix->total_entries * 16);
+ }
+
+ free(dev->msix);
+}