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()
This commit is contained in:
Konrad Rzeszutek Wilk 2011-03-10 14:42:11 -05:00
commit 8448f0119a
3 changed files with 33 additions and 19 deletions

View File

@ -27,16 +27,16 @@ static inline void __init xen_setup_pirqs(void)
* its own functions. * its own functions.
*/ */
struct xen_pci_frontend_ops { 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); 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); void (*disable_msix)(struct pci_dev *dev);
}; };
extern struct xen_pci_frontend_ops *xen_pci_frontend; extern struct xen_pci_frontend_ops *xen_pci_frontend;
static inline int xen_pci_frontend_enable_msi(struct pci_dev *dev, 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) if (xen_pci_frontend && xen_pci_frontend->enable_msi)
return xen_pci_frontend->enable_msi(dev, vectors); 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); xen_pci_frontend->disable_msi(dev);
} }
static inline int xen_pci_frontend_enable_msix(struct pci_dev *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) if (xen_pci_frontend && xen_pci_frontend->enable_msix)
return xen_pci_frontend->enable_msix(dev, vectors, nvec); return xen_pci_frontend->enable_msix(dev, vectors, nvec);

View File

@ -150,21 +150,21 @@ static int xen_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
return -ENOMEM; return -ENOMEM;
if (type == PCI_CAP_ID_MSIX) 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 else
ret = xen_pci_frontend_enable_msi(dev, &v); ret = xen_pci_frontend_enable_msi(dev, v);
if (ret) if (ret)
goto error; goto error;
i = 0; i = 0;
list_for_each_entry(msidesc, &dev->msi_list, list) { 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) ? (type == PCI_CAP_ID_MSIX) ?
"pcifront-msi-x" : "pcifront-msi"); "pcifront-msi-x" : "pcifront-msi",
&irq, &v[i], XEN_ALLOC_IRQ);
if (irq < 0) { if (irq < 0) {
ret = -1; ret = -1;
goto free; goto free;
} }
ret = set_irq_msi(irq, msidesc); ret = set_irq_msi(irq, msidesc);
if (ret) if (ret)
goto error_while; goto error_while;
@ -193,6 +193,9 @@ static void xen_teardown_msi_irqs(struct pci_dev *dev)
xen_pci_frontend_disable_msix(dev); xen_pci_frontend_disable_msix(dev);
else else
xen_pci_frontend_disable_msi(dev); 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) static void xen_teardown_msi_irq(unsigned int irq)

View File

@ -243,7 +243,7 @@ struct pci_ops pcifront_bus_ops = {
#ifdef CONFIG_PCI_MSI #ifdef CONFIG_PCI_MSI
static int pci_frontend_enable_msix(struct pci_dev *dev, static int pci_frontend_enable_msix(struct pci_dev *dev,
int **vector, int nvec) int vector[], int nvec)
{ {
int err; int err;
int i; int i;
@ -277,18 +277,24 @@ static int pci_frontend_enable_msix(struct pci_dev *dev,
if (likely(!err)) { if (likely(!err)) {
if (likely(!op.value)) { if (likely(!op.value)) {
/* we get the result */ /* we get the result */
for (i = 0; i < nvec; i++) for (i = 0; i < nvec; i++) {
*(*vector+i) = op.msix_entries[i].vector; if (op.msix_entries[i].vector <= 0) {
return 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 { } else {
printk(KERN_DEBUG "enable msix get value %x\n", printk(KERN_DEBUG "enable msix get value %x\n",
op.value); op.value);
return op.value;
} }
} else { } else {
dev_err(&dev->dev, "enable msix get err %x\n", err); 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) 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); 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; int err;
struct xen_pci_op op = { 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); err = do_pci_op(pdev, &op);
if (likely(!err)) { 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 { } else {
dev_err(&dev->dev, "pci frontend enable msi failed for dev " dev_err(&dev->dev, "pci frontend enable msi failed for dev "
"%x:%x\n", op.bus, op.devfn); "%x:%x\n", op.bus, op.devfn);
@ -733,8 +745,7 @@ static void free_pdev(struct pcifront_device *pdev)
pcifront_free_roots(pdev); pcifront_free_roots(pdev);
/*For PCIE_AER error handling job*/ cancel_work_sync(&pdev->op_work);
flush_scheduled_work();
if (pdev->irq >= 0) if (pdev->irq >= 0)
unbind_from_irqhandler(pdev->irq, pdev); unbind_from_irqhandler(pdev->irq, pdev);