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:
commit
8448f0119a
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue