forked from Minki/linux
VMCI: dma dg: register dummy IRQ handlers for DMA datagrams
Register dummy interrupt handlers for DMA datagrams in preparation for DMA datagram receive operations. Reviewed-by: Vishnu Dasa <vdasa@vmware.com> Signed-off-by: Jorgen Hansen <jhansen@vmware.com> Link: https://lore.kernel.org/r/20220207102725.2742-6-jhansen@vmware.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
8cb520bea1
commit
cc68f2177f
@ -414,6 +414,9 @@ static irqreturn_t vmci_interrupt(int irq, void *_dev)
|
|||||||
icr &= ~VMCI_ICR_NOTIFICATION;
|
icr &= ~VMCI_ICR_NOTIFICATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (icr & VMCI_ICR_DMA_DATAGRAM)
|
||||||
|
icr &= ~VMCI_ICR_DMA_DATAGRAM;
|
||||||
|
|
||||||
if (icr != 0)
|
if (icr != 0)
|
||||||
dev_warn(dev->dev,
|
dev_warn(dev->dev,
|
||||||
"Ignoring unknown interrupt cause (%d)\n",
|
"Ignoring unknown interrupt cause (%d)\n",
|
||||||
@ -438,6 +441,16 @@ static irqreturn_t vmci_interrupt_bm(int irq, void *_dev)
|
|||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Interrupt handler for MSI-X interrupt vector VMCI_INTR_DMA_DATAGRAM,
|
||||||
|
* which is for the completion of a DMA datagram send or receive operation.
|
||||||
|
* Will only get called if we are using MSI-X with exclusive vectors.
|
||||||
|
*/
|
||||||
|
static irqreturn_t vmci_interrupt_dma_datagram(int irq, void *_dev)
|
||||||
|
{
|
||||||
|
return IRQ_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Most of the initialization at module load time is done here.
|
* Most of the initialization at module load time is done here.
|
||||||
*/
|
*/
|
||||||
@ -447,6 +460,7 @@ static int vmci_guest_probe_device(struct pci_dev *pdev,
|
|||||||
struct vmci_guest_device *vmci_dev;
|
struct vmci_guest_device *vmci_dev;
|
||||||
void __iomem *iobase = NULL;
|
void __iomem *iobase = NULL;
|
||||||
void __iomem *mmio_base = NULL;
|
void __iomem *mmio_base = NULL;
|
||||||
|
unsigned int num_irq_vectors;
|
||||||
unsigned int capabilities;
|
unsigned int capabilities;
|
||||||
unsigned int caps_in_use;
|
unsigned int caps_in_use;
|
||||||
unsigned long cmd;
|
unsigned long cmd;
|
||||||
@ -627,8 +641,12 @@ static int vmci_guest_probe_device(struct pci_dev *pdev,
|
|||||||
* Enable interrupts. Try MSI-X first, then MSI, and then fallback on
|
* Enable interrupts. Try MSI-X first, then MSI, and then fallback on
|
||||||
* legacy interrupts.
|
* legacy interrupts.
|
||||||
*/
|
*/
|
||||||
error = pci_alloc_irq_vectors(pdev, VMCI_MAX_INTRS, VMCI_MAX_INTRS,
|
if (vmci_dev->mmio_base != NULL)
|
||||||
PCI_IRQ_MSIX);
|
num_irq_vectors = VMCI_MAX_INTRS;
|
||||||
|
else
|
||||||
|
num_irq_vectors = VMCI_MAX_INTRS_NOTIFICATION;
|
||||||
|
error = pci_alloc_irq_vectors(pdev, num_irq_vectors, num_irq_vectors,
|
||||||
|
PCI_IRQ_MSIX);
|
||||||
if (error < 0) {
|
if (error < 0) {
|
||||||
error = pci_alloc_irq_vectors(pdev, 1, 1,
|
error = pci_alloc_irq_vectors(pdev, 1, 1,
|
||||||
PCI_IRQ_MSIX | PCI_IRQ_MSI | PCI_IRQ_LEGACY);
|
PCI_IRQ_MSIX | PCI_IRQ_MSI | PCI_IRQ_LEGACY);
|
||||||
@ -666,6 +684,17 @@ static int vmci_guest_probe_device(struct pci_dev *pdev,
|
|||||||
pci_irq_vector(pdev, 1), error);
|
pci_irq_vector(pdev, 1), error);
|
||||||
goto err_free_irq;
|
goto err_free_irq;
|
||||||
}
|
}
|
||||||
|
if (caps_in_use & VMCI_CAPS_DMA_DATAGRAM) {
|
||||||
|
error = request_irq(pci_irq_vector(pdev, 2),
|
||||||
|
vmci_interrupt_dma_datagram,
|
||||||
|
0, KBUILD_MODNAME, vmci_dev);
|
||||||
|
if (error) {
|
||||||
|
dev_err(&pdev->dev,
|
||||||
|
"Failed to allocate irq %u: %d\n",
|
||||||
|
pci_irq_vector(pdev, 2), error);
|
||||||
|
goto err_free_bm_irq;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_dbg(&pdev->dev, "Registered device\n");
|
dev_dbg(&pdev->dev, "Registered device\n");
|
||||||
@ -676,6 +705,8 @@ static int vmci_guest_probe_device(struct pci_dev *pdev,
|
|||||||
cmd = VMCI_IMR_DATAGRAM;
|
cmd = VMCI_IMR_DATAGRAM;
|
||||||
if (caps_in_use & VMCI_CAPS_NOTIFICATIONS)
|
if (caps_in_use & VMCI_CAPS_NOTIFICATIONS)
|
||||||
cmd |= VMCI_IMR_NOTIFICATION;
|
cmd |= VMCI_IMR_NOTIFICATION;
|
||||||
|
if (caps_in_use & VMCI_CAPS_DMA_DATAGRAM)
|
||||||
|
cmd |= VMCI_IMR_DMA_DATAGRAM;
|
||||||
vmci_write_reg(vmci_dev, cmd, VMCI_IMR_ADDR);
|
vmci_write_reg(vmci_dev, cmd, VMCI_IMR_ADDR);
|
||||||
|
|
||||||
/* Enable interrupts. */
|
/* Enable interrupts. */
|
||||||
@ -686,6 +717,8 @@ static int vmci_guest_probe_device(struct pci_dev *pdev,
|
|||||||
vmci_call_vsock_callback(false);
|
vmci_call_vsock_callback(false);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err_free_bm_irq:
|
||||||
|
free_irq(pci_irq_vector(pdev, 1), vmci_dev);
|
||||||
err_free_irq:
|
err_free_irq:
|
||||||
free_irq(pci_irq_vector(pdev, 0), vmci_dev);
|
free_irq(pci_irq_vector(pdev, 0), vmci_dev);
|
||||||
tasklet_kill(&vmci_dev->datagram_tasklet);
|
tasklet_kill(&vmci_dev->datagram_tasklet);
|
||||||
@ -751,8 +784,11 @@ static void vmci_guest_remove_device(struct pci_dev *pdev)
|
|||||||
* MSI-X, we might have multiple vectors, each with their own
|
* MSI-X, we might have multiple vectors, each with their own
|
||||||
* IRQ, which we must free too.
|
* IRQ, which we must free too.
|
||||||
*/
|
*/
|
||||||
if (vmci_dev->exclusive_vectors)
|
if (vmci_dev->exclusive_vectors) {
|
||||||
free_irq(pci_irq_vector(pdev, 1), vmci_dev);
|
free_irq(pci_irq_vector(pdev, 1), vmci_dev);
|
||||||
|
if (vmci_dev->mmio_base != NULL)
|
||||||
|
free_irq(pci_irq_vector(pdev, 2), vmci_dev);
|
||||||
|
}
|
||||||
free_irq(pci_irq_vector(pdev, 0), vmci_dev);
|
free_irq(pci_irq_vector(pdev, 0), vmci_dev);
|
||||||
pci_free_irq_vectors(pdev);
|
pci_free_irq_vectors(pdev);
|
||||||
|
|
||||||
|
@ -45,13 +45,22 @@
|
|||||||
/* Interrupt Cause register bits. */
|
/* Interrupt Cause register bits. */
|
||||||
#define VMCI_ICR_DATAGRAM BIT(0)
|
#define VMCI_ICR_DATAGRAM BIT(0)
|
||||||
#define VMCI_ICR_NOTIFICATION BIT(1)
|
#define VMCI_ICR_NOTIFICATION BIT(1)
|
||||||
|
#define VMCI_ICR_DMA_DATAGRAM BIT(2)
|
||||||
|
|
||||||
/* Interrupt Mask register bits. */
|
/* Interrupt Mask register bits. */
|
||||||
#define VMCI_IMR_DATAGRAM BIT(0)
|
#define VMCI_IMR_DATAGRAM BIT(0)
|
||||||
#define VMCI_IMR_NOTIFICATION BIT(1)
|
#define VMCI_IMR_NOTIFICATION BIT(1)
|
||||||
|
#define VMCI_IMR_DMA_DATAGRAM BIT(2)
|
||||||
|
|
||||||
/* Maximum MSI/MSI-X interrupt vectors in the device. */
|
/*
|
||||||
#define VMCI_MAX_INTRS 2
|
* Maximum MSI/MSI-X interrupt vectors in the device.
|
||||||
|
* If VMCI_CAPS_DMA_DATAGRAM is supported by the device,
|
||||||
|
* VMCI_MAX_INTRS_DMA_DATAGRAM vectors are available,
|
||||||
|
* otherwise only VMCI_MAX_INTRS_NOTIFICATION.
|
||||||
|
*/
|
||||||
|
#define VMCI_MAX_INTRS_NOTIFICATION 2
|
||||||
|
#define VMCI_MAX_INTRS_DMA_DATAGRAM 3
|
||||||
|
#define VMCI_MAX_INTRS VMCI_MAX_INTRS_DMA_DATAGRAM
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Supported interrupt vectors. There is one for each ICR value above,
|
* Supported interrupt vectors. There is one for each ICR value above,
|
||||||
@ -60,6 +69,7 @@
|
|||||||
enum {
|
enum {
|
||||||
VMCI_INTR_DATAGRAM = 0,
|
VMCI_INTR_DATAGRAM = 0,
|
||||||
VMCI_INTR_NOTIFICATION = 1,
|
VMCI_INTR_NOTIFICATION = 1,
|
||||||
|
VMCI_INTR_DMA_DATAGRAM = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user