aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/xen/xen-pciback/conf_space_header.c
diff options
context:
space:
mode:
authorKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2011-07-19 18:56:39 -0400
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2011-07-19 20:58:31 -0400
commit0513fe9e5b54e47e37217ea078dd870e3825e02d (patch)
treebec70fca92b64ea535539fc243b746c3a1ab7fd3 /drivers/xen/xen-pciback/conf_space_header.c
parentxen/pciback: Disable MSI/MSI-X when reseting a device (diff)
downloadlinux-dev-0513fe9e5b54e47e37217ea078dd870e3825e02d.tar.xz
linux-dev-0513fe9e5b54e47e37217ea078dd870e3825e02d.zip
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.c6
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)) {