diff options
author | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2011-07-20 02:56:39 +0400 |
---|---|---|
committer | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2011-07-20 04:58:31 +0400 |
commit | 0513fe9e5b54e47e37217ea078dd870e3825e02d (patch) | |
tree | bec70fca92b64ea535539fc243b746c3a1ab7fd3 /drivers/xen/xen-pciback/conf_space_header.c | |
parent | a2be65fd363831502afdf0babdf48149b3959cde (diff) | |
download | linux-0513fe9e5b54e47e37217ea078dd870e3825e02d.tar.xz |
xen/pciback: Allocate IRQ handler for device that is shared with guest.
If the device that is to be shared with a guest is a level device and
the IRQ is shared with the initial domain we need to take actions.
Mainly we install a dummy IRQ handler that will ACK on the interrupt
line so as to not have the initial domain disable the interrupt line.
This dummy IRQ handler is not enabled when the device MSI/MSI-X lines
are set, nor for edge interrupts. And also not for level interrupts
that are not shared amongst devices. Lastly, if the user passes
to the guest all of the PCI devices on the shared line the we won't
install the dummy handler either.
There is also SysFS instrumentation to check its state and turn
IRQ ACKing on/off if necessary.
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Diffstat (limited to 'drivers/xen/xen-pciback/conf_space_header.c')
-rw-r--r-- | drivers/xen/xen-pciback/conf_space_header.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/drivers/xen/xen-pciback/conf_space_header.c b/drivers/xen/xen-pciback/conf_space_header.c index dcd6dd964e3b..22ad0f560669 100644 --- a/drivers/xen/xen-pciback/conf_space_header.c +++ b/drivers/xen/xen-pciback/conf_space_header.c @@ -39,8 +39,10 @@ static int command_read(struct pci_dev *dev, int offset, u16 *value, void *data) static int command_write(struct pci_dev *dev, int offset, u16 value, void *data) { + struct pciback_dev_data *dev_data; int err; + dev_data = pci_get_drvdata(dev); if (!pci_is_enabled(dev) && is_enable_cmd(value)) { if (unlikely(verbose_request)) printk(KERN_DEBUG "pciback: %s: enable\n", @@ -48,11 +50,15 @@ static int command_write(struct pci_dev *dev, int offset, u16 value, void *data) err = pci_enable_device(dev); if (err) return err; + if (dev_data) + dev_data->enable_intx = 1; } else if (pci_is_enabled(dev) && !is_enable_cmd(value)) { if (unlikely(verbose_request)) printk(KERN_DEBUG "pciback: %s: disable\n", pci_name(dev)); pci_disable_device(dev); + if (dev_data) + dev_data->enable_intx = 0; } if (!dev->is_busmaster && is_master_cmd(value)) { |