Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8448f011 authored by Konrad Rzeszutek Wilk's avatar Konrad Rzeszutek Wilk
Browse files

Merge branch 'stable/pcifront-fixes' into stable/irq.cleanup

* stable/pcifront-fixes:
  pci/xen: When free-ing MSI-X/MSI irq->desc also use generic code.
  pci/xen: Cleanup: convert int** to int[]
  pci/xen: Use xen_allocate_pirq_msi instead of xen_allocate_pirq
  xen-pcifront: Sanity check the MSI/MSI-X values
  xen-pcifront: don't use flush_scheduled_work()
parents 8054c363 3d74a539
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -27,16 +27,16 @@ static inline void __init xen_setup_pirqs(void)
 * its own functions.
 */
struct xen_pci_frontend_ops {
	int (*enable_msi)(struct pci_dev *dev, int **vectors);
	int (*enable_msi)(struct pci_dev *dev, int vectors[]);
	void (*disable_msi)(struct pci_dev *dev);
	int (*enable_msix)(struct pci_dev *dev, int **vectors, int nvec);
	int (*enable_msix)(struct pci_dev *dev, int vectors[], int nvec);
	void (*disable_msix)(struct pci_dev *dev);
};

extern struct xen_pci_frontend_ops *xen_pci_frontend;

static inline int xen_pci_frontend_enable_msi(struct pci_dev *dev,
					      int **vectors)
					      int vectors[])
{
	if (xen_pci_frontend && xen_pci_frontend->enable_msi)
		return xen_pci_frontend->enable_msi(dev, vectors);
@@ -48,7 +48,7 @@ static inline void xen_pci_frontend_disable_msi(struct pci_dev *dev)
			xen_pci_frontend->disable_msi(dev);
}
static inline int xen_pci_frontend_enable_msix(struct pci_dev *dev,
					       int **vectors, int nvec)
					       int vectors[], int nvec)
{
	if (xen_pci_frontend && xen_pci_frontend->enable_msix)
		return xen_pci_frontend->enable_msix(dev, vectors, nvec);
+8 −5
Original line number Diff line number Diff line
@@ -150,21 +150,21 @@ static int xen_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
		return -ENOMEM;

	if (type == PCI_CAP_ID_MSIX)
		ret = xen_pci_frontend_enable_msix(dev, &v, nvec);
		ret = xen_pci_frontend_enable_msix(dev, v, nvec);
	else
		ret = xen_pci_frontend_enable_msi(dev, &v);
		ret = xen_pci_frontend_enable_msi(dev, v);
	if (ret)
		goto error;
	i = 0;
	list_for_each_entry(msidesc, &dev->msi_list, list) {
		irq = xen_allocate_pirq(v[i], 0, /* not sharable */
		xen_allocate_pirq_msi(
			(type == PCI_CAP_ID_MSIX) ?
			"pcifront-msi-x" : "pcifront-msi");
			"pcifront-msi-x" : "pcifront-msi",
			&irq, &v[i], XEN_ALLOC_IRQ);
		if (irq < 0) {
			ret = -1;
			goto free;
		}

		ret = set_irq_msi(irq, msidesc);
		if (ret)
			goto error_while;
@@ -193,6 +193,9 @@ static void xen_teardown_msi_irqs(struct pci_dev *dev)
		xen_pci_frontend_disable_msix(dev);
	else
		xen_pci_frontend_disable_msi(dev);

	/* Free the IRQ's and the msidesc using the generic code. */
	default_teardown_msi_irqs(dev);
}

static void xen_teardown_msi_irq(unsigned int irq)
+21 −10
Original line number Diff line number Diff line
@@ -243,7 +243,7 @@ struct pci_ops pcifront_bus_ops = {

#ifdef CONFIG_PCI_MSI
static int pci_frontend_enable_msix(struct pci_dev *dev,
				    int **vector, int nvec)
				    int vector[], int nvec)
{
	int err;
	int i;
@@ -277,18 +277,24 @@ static int pci_frontend_enable_msix(struct pci_dev *dev,
	if (likely(!err)) {
		if (likely(!op.value)) {
			/* we get the result */
			for (i = 0; i < nvec; i++)
				*(*vector+i) = op.msix_entries[i].vector;
			return 0;
			for (i = 0; i < nvec; i++) {
				if (op.msix_entries[i].vector <= 0) {
					dev_warn(&dev->dev, "MSI-X entry %d is invalid: %d!\n",
						i, op.msix_entries[i].vector);
					err = -EINVAL;
					vector[i] = -1;
					continue;
				}
				vector[i] = op.msix_entries[i].vector;
			}
		} else {
			printk(KERN_DEBUG "enable msix get value %x\n",
				op.value);
			return op.value;
		}
	} else {
		dev_err(&dev->dev, "enable msix get err %x\n", err);
		return err;
	}
	return err;
}

static void pci_frontend_disable_msix(struct pci_dev *dev)
@@ -310,7 +316,7 @@ static void pci_frontend_disable_msix(struct pci_dev *dev)
		dev_err(&dev->dev, "pci_disable_msix get err %x\n", err);
}

static int pci_frontend_enable_msi(struct pci_dev *dev, int **vector)
static int pci_frontend_enable_msi(struct pci_dev *dev, int vector[])
{
	int err;
	struct xen_pci_op op = {
@@ -324,7 +330,13 @@ static int pci_frontend_enable_msi(struct pci_dev *dev, int **vector)

	err = do_pci_op(pdev, &op);
	if (likely(!err)) {
		*(*vector) = op.value;
		vector[0] = op.value;
		if (op.value <= 0) {
			dev_warn(&dev->dev, "MSI entry is invalid: %d!\n",
				op.value);
			err = -EINVAL;
			vector[0] = -1;
		}
	} else {
		dev_err(&dev->dev, "pci frontend enable msi failed for dev "
				    "%x:%x\n", op.bus, op.devfn);
@@ -733,8 +745,7 @@ static void free_pdev(struct pcifront_device *pdev)

	pcifront_free_roots(pdev);

	/*For PCIE_AER error handling job*/
	flush_scheduled_work();
	cancel_work_sync(&pdev->op_work);

	if (pdev->irq >= 0)
		unbind_from_irqhandler(pdev->irq, pdev);