---
drivers/xen/xen-pciback/conf_space.c | 35 ++++++++
drivers/xen/xen-pciback/conf_space.h | 10 +++
.../xen/xen-pciback/conf_space_capability.c | 88 +++++++++++++++++++
drivers/xen/xen-pciback/conf_space_header.c | 19 ++++
drivers/xen/xen-pciback/pci_stub.c | 66 ++++++++++++++
drivers/xen/xen-pciback/pciback.h | 1 +
6 files changed, 219 insertions(+)
@@ -64,6 +64,7 @@ static int command_write(struct pci_dev *dev, int offset, u16 value, void *data)
int err;
u16 val;
struct pci_cmd_info *cmd = data;
+ u16 cap_value;
dev_data = pci_get_drvdata(dev);
if (!pci_is_enabled(dev) && is_enable_cmd(value)) {
@@ -117,6 +118,24 @@ static int command_write(struct pci_dev *dev, int offset, u16 value, void *data)
pci_clear_mwi(dev);
}
+ if (dev_data && dev_data->allow_interrupt_control) {
+ if (!(cmd->val & PCI_COMMAND_INTX_DISABLE) &&
+ (value & PCI_COMMAND_INTX_DISABLE)) {
+ pci_intx(dev, 0);
+ } else if ((cmd->val & PCI_COMMAND_INTX_DISABLE) &&
+ !(value & PCI_COMMAND_INTX_DISABLE)) {
+ /* Do not allow enabling INTx together with MSI or MSI-X. */
+ switch (xen_pcibk_get_interrupt_type(dev)) {
+ case INTERRUPT_TYPE_NONE:
+ case INTERRUPT_TYPE_INTX:
+ pci_intx(dev, 1);
+ break;
+ default:
+ return PCIBIOS_SET_FAILED;
+ }
+ }