misc: pci_endpoint_test: Avoid using module parameter to determine irqtype
authorKishon Vijay Abraham I <kishon@ti.com>
Tue, 17 Mar 2020 10:01:54 +0000 (15:31 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 8 Apr 2020 07:08:41 +0000 (09:08 +0200)
commit b2ba9225e0313b1de631a44b7b48c109032bffec upstream.

commit e03327122e2c ("pci_endpoint_test: Add 2 ioctl commands")
uses module parameter 'irqtype' in pci_endpoint_test_set_irq()
to check if IRQ vectors of a particular type (MSI or MSI-X or
LEGACY) is already allocated. However with multi-function devices,
'irqtype' will not correctly reflect the IRQ type of the PCI device.

Fix it here by adding 'irqtype' for each PCI device to show the
IRQ type of a particular PCI device.

Fixes: e03327122e2c ("pci_endpoint_test: Add 2 ioctl commands")
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: stable@vger.kernel.org # v4.19+
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/misc/pci_endpoint_test.c

index be144b4..1154f04 100644 (file)
@@ -98,6 +98,7 @@ struct pci_endpoint_test {
        struct completion irq_raised;
        int             last_irq;
        int             num_irqs;
+       int             irq_type;
        /* mutex to protect the ioctls */
        struct mutex    mutex;
        struct miscdevice miscdev;
@@ -157,6 +158,7 @@ static void pci_endpoint_test_free_irq_vectors(struct pci_endpoint_test *test)
        struct pci_dev *pdev = test->pdev;
 
        pci_free_irq_vectors(pdev);
+       test->irq_type = IRQ_TYPE_UNDEFINED;
 }
 
 static bool pci_endpoint_test_alloc_irq_vectors(struct pci_endpoint_test *test,
@@ -191,6 +193,8 @@ static bool pci_endpoint_test_alloc_irq_vectors(struct pci_endpoint_test *test,
                irq = 0;
                res = false;
        }
+
+       test->irq_type = type;
        test->num_irqs = irq;
 
        return res;
@@ -330,6 +334,7 @@ static bool pci_endpoint_test_copy(struct pci_endpoint_test *test, size_t size)
        dma_addr_t orig_dst_phys_addr;
        size_t offset;
        size_t alignment = test->alignment;
+       int irq_type = test->irq_type;
        u32 src_crc32;
        u32 dst_crc32;
 
@@ -426,6 +431,7 @@ static bool pci_endpoint_test_write(struct pci_endpoint_test *test, size_t size)
        dma_addr_t orig_phys_addr;
        size_t offset;
        size_t alignment = test->alignment;
+       int irq_type = test->irq_type;
        u32 crc32;
 
        if (size > SIZE_MAX - alignment)
@@ -494,6 +500,7 @@ static bool pci_endpoint_test_read(struct pci_endpoint_test *test, size_t size)
        dma_addr_t orig_phys_addr;
        size_t offset;
        size_t alignment = test->alignment;
+       int irq_type = test->irq_type;
        u32 crc32;
 
        if (size > SIZE_MAX - alignment)
@@ -555,7 +562,7 @@ static bool pci_endpoint_test_set_irq(struct pci_endpoint_test *test,
                return false;
        }
 
-       if (irq_type == req_irq_type)
+       if (test->irq_type == req_irq_type)
                return true;
 
        pci_endpoint_test_release_irq(test);
@@ -567,12 +574,10 @@ static bool pci_endpoint_test_set_irq(struct pci_endpoint_test *test,
        if (!pci_endpoint_test_request_irq(test))
                goto err;
 
-       irq_type = req_irq_type;
        return true;
 
 err:
        pci_endpoint_test_free_irq_vectors(test);
-       irq_type = IRQ_TYPE_UNDEFINED;
        return false;
 }
 
@@ -652,6 +657,7 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
        test->test_reg_bar = 0;
        test->alignment = 0;
        test->pdev = pdev;
+       test->irq_type = IRQ_TYPE_UNDEFINED;
 
        if (no_msi)
                irq_type = IRQ_TYPE_LEGACY;