[PATCH V4] misc: pci_endpoint_test: simplify endpoint test read and write operations

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Li Chen <lchen@xxxxxxxxxxxxx>

Introduce pci_endpoint_epf_transfer_data to simplify
read and write operations.

Signed-off-by: Li Chen <lchen@xxxxxxxxxxxxx>
---
Changes in V2:
fix WARNING: line length of 108 exceeds 100 columns
#128: FILE: drivers/misc/pci_endpoint_test.c:243:
Changes in V3:
This patch context doesn't change but resend with my Zoho mail account in that previous
company mail will contain un-removeable proprietary messages.
Changes in V4:
Add "From:" to the first line of the message body.

drivers/misc/pci_endpoint_test.c | 289 ++++++++++++-------------------
1 file changed, 109 insertions(+), 180 deletions(-)

diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c
index 2ed7e3aaff3a8..b6b0b19b251b3 100644
--- a/drivers/misc/pci_endpoint_test.c
+++ b/drivers/misc/pci_endpoint_test.c
@@ -103,6 +103,11 @@ enum pci_barno {
    BAR_5,
};

+enum operation {
+    EPF_READ,
+    EPF_WRITE,
+};
+
struct pci_endpoint_test {
    struct pci_dev    *pdev;
    void __iomem    *base;
@@ -142,6 +147,108 @@ static inline u32 pci_endpoint_test_bar_readl(struct pci_endpoint_test *test,
{
    return readl(test->bar[bar] + offset);
}
+static bool pci_endpoint_test_transfer_data(struct pci_endpoint_test *test,
+                unsigned long arg, const enum operation operation)
+{
+    struct pci_endpoint_test_xfer_param param;
+    bool ret = false;
+    u32 flags = 0;
+    bool use_dma;
+    void *addr;
+    dma_addr_t phys_addr;
+    struct pci_dev *pdev = test->pdev;
+    struct device *dev = &pdev->dev;
+    void *orig_addr;
+    dma_addr_t orig_phys_addr;
+    size_t offset;
+    size_t alignment = test->alignment;
+    int irq_type = test->irq_type;
+    size_t size;
+    int err;
+
+    err = copy_from_user(&param, (void __user *)arg, sizeof(param));
+    if (err != 0) {
+        dev_err(dev, "Failed to get transfer param\n");
+        return false;
+    }
+
+    size = param.size;
+    if (size > SIZE_MAX - alignment)
+        goto err;
+
+    use_dma = !!(param.flags & PCITEST_FLAGS_USE_DMA);
+    if (use_dma)
+        flags |= FLAG_USE_DMA;
+
+    if (irq_type < IRQ_TYPE_LEGACY || irq_type > IRQ_TYPE_MSIX) {
+        dev_err(dev, "Invalid IRQ type option\n");
+        goto err;
+    }
+
+    orig_addr = kzalloc(size + alignment, GFP_KERNEL);
+    if (!orig_addr)
+        goto err;
+
+    get_random_bytes(orig_addr, size + alignment);
+
+    orig_phys_addr = dma_map_single(dev, orig_addr, size + alignment,
+                    operation == EPF_WRITE ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
+    if (dma_mapping_error(dev, orig_phys_addr)) {
+        dev_err(dev, "failed to map source buffer address\n");
+        goto err_phys_addr;
+    }
+
+    if (alignment && !IS_ALIGNED(orig_phys_addr, alignment)) {
+        phys_addr = PTR_ALIGN(orig_phys_addr, alignment);
+        offset = phys_addr - orig_phys_addr;
+        addr = orig_addr + offset;
+    } else {
+        phys_addr = orig_phys_addr;
+        addr = orig_addr;
+    }
+
+    if (operation == EPF_WRITE) {
+
+        pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_CHECKSUM,
+                 crc32_le(~0, addr, size));
+
+        pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_LOWER_SRC_ADDR,
+                                lower_32_bits(phys_addr));
+        pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_UPPER_SRC_ADDR,
+                                upper_32_bits(phys_addr));
+    } else {
+        pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_LOWER_DST_ADDR,
+                                lower_32_bits(phys_addr));
+        pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_UPPER_DST_ADDR,
+                                upper_32_bits(phys_addr));
+    }
+
+    pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE, size);
+    pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_FLAGS, flags);
+    pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE, irq_type);
+    pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);
+
+    // if we ask rc to write to ep, then ep should do read operation, and vice versa.
+    pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
+                 operation == EPF_WRITE ? COMMAND_READ : COMMAND_WRITE);
+
+    wait_for_completion(&test->irq_raised);
+
+    dma_unmap_single(dev, orig_phys_addr, size + alignment,
+                     operation == EPF_WRITE ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
+
+    if (operation == WRITE)
+        ret = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_STATUS) & STATUS_READ_SUCCESS;
+    else
+        ret = crc32_le(~0, addr, size) ==
+            pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_CHECKSUM);
+
+err_phys_addr:
+    kfree(orig_addr);
+
+err:
+    return ret;
+}

static inline void pci_endpoint_test_bar_writel(struct pci_endpoint_test *test,
                        int bar, u32 offset, u32 value)
@@ -473,191 +580,13 @@ static bool pci_endpoint_test_copy(struct pci_endpoint_test *test,
static bool pci_endpoint_test_write(struct pci_endpoint_test *test,
                 unsigned long arg)
{
-    struct pci_endpoint_test_xfer_param param;
-    bool ret = false;
-    u32 flags = 0;
-    bool use_dma;
-    u32 reg;
-    void *addr;
-    dma_addr_t phys_addr;
-    struct pci_dev *pdev = test->pdev;
-    struct device *dev = &pdev->dev;
-    void *orig_addr;
-    dma_addr_t orig_phys_addr;
-    size_t offset;
-    size_t alignment = test->alignment;
-    int irq_type = test->irq_type;
-    size_t size;
-    u32 crc32;
-    int err;
-
-    err = copy_from_user(&param, (void __user *)arg, sizeof(param));
-    if (err != 0) {
-        dev_err(dev, "Failed to get transfer param\n");
-        return false;
-    }
-
-    size = param.size;
-    if (size > SIZE_MAX - alignment)
-        goto err;
-
-    use_dma = !!(param.flags & PCITEST_FLAGS_USE_DMA);
-    if (use_dma)
-        flags |= FLAG_USE_DMA;
-
-    if (irq_type < IRQ_TYPE_LEGACY || irq_type > IRQ_TYPE_MSIX) {
-        dev_err(dev, "Invalid IRQ type option\n");
-        goto err;
-    }
-
-    orig_addr = kzalloc(size + alignment, GFP_KERNEL);
-    if (!orig_addr) {
-        dev_err(dev, "Failed to allocate address\n");
-        ret = false;
-        goto err;
-    }
-
-    get_random_bytes(orig_addr, size + alignment);
-
-    orig_phys_addr = dma_map_single(dev, orig_addr, size + alignment,
-                    DMA_TO_DEVICE);
-    if (dma_mapping_error(dev, orig_phys_addr)) {
-        dev_err(dev, "failed to map source buffer address\n");
-        ret = false;
-        goto err_phys_addr;
-    }
-
-    if (alignment && !IS_ALIGNED(orig_phys_addr, alignment)) {
-        phys_addr = PTR_ALIGN(orig_phys_addr, alignment);
-        offset = phys_addr - orig_phys_addr;
-        addr = orig_addr + offset;
-    } else {
-        phys_addr = orig_phys_addr;
-        addr = orig_addr;
-    }
-
-    crc32 = crc32_le(~0, addr, size);
-    pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_CHECKSUM,
-                 crc32);
-
-    pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_LOWER_SRC_ADDR,
-                 lower_32_bits(phys_addr));
-    pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_UPPER_SRC_ADDR,
-                 upper_32_bits(phys_addr));
-
-    pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE, size);
-
-    pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_FLAGS, flags);
-    pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE, irq_type);
-    pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);
-    pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
-                 COMMAND_READ);
-
-    wait_for_completion(&test->irq_raised);
-
-    reg = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_STATUS);
-    if (reg & STATUS_READ_SUCCESS)
-        ret = true;
-
-    dma_unmap_single(dev, orig_phys_addr, size + alignment,
-             DMA_TO_DEVICE);
-
-err_phys_addr:
-    kfree(orig_addr);
-
-err:
-    return ret;
+    return pci_endpoint_test_transfer_data(test, arg, EPF_WRITE);
}

static bool pci_endpoint_test_read(struct pci_endpoint_test *test,
                 unsigned long arg)
{
-    struct pci_endpoint_test_xfer_param param;
-    bool ret = false;
-    u32 flags = 0;
-    bool use_dma;
-    size_t size;
-    void *addr;
-    dma_addr_t phys_addr;
-    struct pci_dev *pdev = test->pdev;
-    struct device *dev = &pdev->dev;
-    void *orig_addr;
-    dma_addr_t orig_phys_addr;
-    size_t offset;
-    size_t alignment = test->alignment;
-    int irq_type = test->irq_type;
-    u32 crc32;
-    int err;
-
-    err = copy_from_user(&param, (void __user *)arg, sizeof(param));
-    if (err) {
-        dev_err(dev, "Failed to get transfer param\n");
-        return false;
-    }
-
-    size = param.size;
-    if (size > SIZE_MAX - alignment)
-        goto err;
-
-    use_dma = !!(param.flags & PCITEST_FLAGS_USE_DMA);
-    if (use_dma)
-        flags |= FLAG_USE_DMA;
-
-    if (irq_type < IRQ_TYPE_LEGACY || irq_type > IRQ_TYPE_MSIX) {
-        dev_err(dev, "Invalid IRQ type option\n");
-        goto err;
-    }
-
-    orig_addr = kzalloc(size + alignment, GFP_KERNEL);
-    if (!orig_addr) {
-        dev_err(dev, "Failed to allocate destination address\n");
-        ret = false;
-        goto err;
-    }
-
-    orig_phys_addr = dma_map_single(dev, orig_addr, size + alignment,
-                    DMA_FROM_DEVICE);
-    if (dma_mapping_error(dev, orig_phys_addr)) {
-        dev_err(dev, "failed to map source buffer address\n");
-        ret = false;
-        goto err_phys_addr;
-    }
-
-    if (alignment && !IS_ALIGNED(orig_phys_addr, alignment)) {
-        phys_addr = PTR_ALIGN(orig_phys_addr, alignment);
-        offset = phys_addr - orig_phys_addr;
-        addr = orig_addr + offset;
-    } else {
-        phys_addr = orig_phys_addr;
-        addr = orig_addr;
-    }
-
-    pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_LOWER_DST_ADDR,
-                 lower_32_bits(phys_addr));
-    pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_UPPER_DST_ADDR,
-                 upper_32_bits(phys_addr));
-
-    pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE, size);
-
-    pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_FLAGS, flags);
-    pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE, irq_type);
-    pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);
-    pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
-                 COMMAND_WRITE);
-
-    wait_for_completion(&test->irq_raised);
-
-    dma_unmap_single(dev, orig_phys_addr, size + alignment,
-             DMA_FROM_DEVICE);
-
-    crc32 = crc32_le(~0, addr, size);
-    if (crc32 == pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_CHECKSUM))
-        ret = true;
-
-err_phys_addr:
-    kfree(orig_addr);
-err:
-    return ret;
+    return pci_endpoint_test_transfer_data(test, arg, EPF_READ);
}

static bool pci_endpoint_test_clear_irq(struct pci_endpoint_test *test)
--
2.34.1



[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux