static int xen_pcibk_disable_msix(struct xen_pcibk_device *pdev, struct pci_dev *dev, struct xen_pci_op *op) { if (unlikely(verbose_request)) printk(KERN_DEBUG DRV_NAME ": %s: disable MSI-X\n", pci_name(dev)); if (dev->msix_enabled) { struct xen_pcibk_dev_data *dev_data; pci_disable_msix(dev); dev_data = pci_get_drvdata(dev); if (dev_data) dev_data->ack_intr = 1; } /* * SR-IOV devices (which don't have any legacy IRQ) have * an undefined IRQ value of zero. */ op->value = dev->irq ? xen_pirq_from_irq(dev->irq) : 0; if (unlikely(verbose_request)) printk(KERN_DEBUG DRV_NAME ": %s: MSI-X: %d\n", pci_name(dev), op->value); return 0; }
static int xen_pcibk_enable_msi(struct xen_pcibk_device *pdev, struct pci_dev *dev, struct xen_pci_op *op) { struct xen_pcibk_dev_data *dev_data; int otherend = pdev->xdev->otherend_id; int status; if (unlikely(verbose_request)) printk(KERN_DEBUG DRV_NAME ": %s: enable MSI\n", pci_name(dev)); status = pci_enable_msi(dev); if (status) { printk(KERN_ERR "error enable msi for guest %x status %x\n", otherend, status); op->value = 0; return XEN_PCI_ERR_op_failed; } /* The value the guest needs is actually the IDT vector, not the * the local domain's IRQ number. */ op->value = dev->irq ? xen_pirq_from_irq(dev->irq) : 0; if (unlikely(verbose_request)) printk(KERN_DEBUG DRV_NAME ": %s: MSI: %d\n", pci_name(dev), op->value); dev_data = pci_get_drvdata(dev); if (dev_data) dev_data->ack_intr = 0; return 0; }
static int xen_pcibk_enable_msix(struct xen_pcibk_device *pdev, struct pci_dev *dev, struct xen_pci_op *op) { struct xen_pcibk_dev_data *dev_data; int i, result; struct msix_entry *entries; if (unlikely(verbose_request)) printk(KERN_DEBUG DRV_NAME ": %s: enable MSI-X\n", pci_name(dev)); if (op->value > SH_INFO_MAX_VEC) return -EINVAL; entries = kmalloc(op->value * sizeof(*entries), GFP_KERNEL); if (entries == NULL) return -ENOMEM; for (i = 0; i < op->value; i++) { entries[i].entry = op->msix_entries[i].entry; entries[i].vector = op->msix_entries[i].vector; } result = pci_enable_msix(dev, entries, op->value); if (result == 0) { for (i = 0; i < op->value; i++) { op->msix_entries[i].entry = entries[i].entry; if (entries[i].vector) op->msix_entries[i].vector = xen_pirq_from_irq(entries[i].vector); if (unlikely(verbose_request)) printk(KERN_DEBUG DRV_NAME ": %s: " \ "MSI-X[%d]: %d\n", pci_name(dev), i, op->msix_entries[i].vector); } } else { printk(KERN_WARNING DRV_NAME ": %s: failed to enable MSI-X: err %d!\n", pci_name(dev), result); } kfree(entries); op->value = result; dev_data = pci_get_drvdata(dev); if (dev_data) dev_data->ack_intr = 0; return result; }
static int xen_pcibk_disable_msi(struct xen_pcibk_device *pdev, struct pci_dev *dev, struct xen_pci_op *op) { struct xen_pcibk_dev_data *dev_data; if (unlikely(verbose_request)) printk(KERN_DEBUG DRV_NAME ": %s: disable MSI\n", pci_name(dev)); pci_disable_msi(dev); op->value = dev->irq ? xen_pirq_from_irq(dev->irq) : 0; if (unlikely(verbose_request)) printk(KERN_DEBUG DRV_NAME ": %s: MSI: %d\n", pci_name(dev), op->value); dev_data = pci_get_drvdata(dev); if (dev_data) dev_data->ack_intr = 1; return 0; }
static int xen_pcibk_enable_msix(struct xen_pcibk_device *pdev, struct pci_dev *dev, struct xen_pci_op *op) { struct xen_pcibk_dev_data *dev_data; int i, result; struct msix_entry *entries; u16 cmd; if (unlikely(verbose_request)) printk(KERN_DEBUG DRV_NAME ": %s: enable MSI-X\n", pci_name(dev)); if (op->value > SH_INFO_MAX_VEC) return -EINVAL; if (dev->msix_enabled) return -EALREADY; /* * PCI_COMMAND_MEMORY must be enabled, otherwise we may not be able * to access the BARs where the MSI-X entries reside. */ pci_read_config_word(dev, PCI_COMMAND, &cmd); if (dev->msi_enabled || !(cmd & PCI_COMMAND_MEMORY)) return -ENXIO; entries = kmalloc(op->value * sizeof(*entries), GFP_KERNEL); if (entries == NULL) return -ENOMEM; for (i = 0; i < op->value; i++) { entries[i].entry = op->msix_entries[i].entry; entries[i].vector = op->msix_entries[i].vector; } result = pci_enable_msix(dev, entries, op->value); if (result == 0) { for (i = 0; i < op->value; i++) { op->msix_entries[i].entry = entries[i].entry; if (entries[i].vector) op->msix_entries[i].vector = xen_pirq_from_irq(entries[i].vector); if (unlikely(verbose_request)) printk(KERN_DEBUG DRV_NAME ": %s: " \ "MSI-X[%d]: %d\n", pci_name(dev), i, op->msix_entries[i].vector); } } else pr_warn_ratelimited(DRV_NAME ": %s: error enabling MSI-X for guest %u: err %d!\n", pci_name(dev), pdev->xdev->otherend_id, result); kfree(entries); op->value = result; dev_data = pci_get_drvdata(dev); if (dev_data) dev_data->ack_intr = 0; return result > 0 ? 0 : result; }