Skip to content

Commit cf376b4

Browse files
kishonLorenzo Pieralisi
authored andcommitted
misc: pci_endpoint_test: Add support to get DMA option from userspace
'pcitest' utility now uses '-d' option to allow the user to test DMA. Add support to parse option to use DMA from userspace application. Signed-off-by: Kishon Vijay Abraham I <[email protected]> Signed-off-by: Lorenzo Pieralisi <[email protected]> Tested-by: Alan Mikhak <[email protected]>
1 parent 73c5762 commit cf376b4

File tree

1 file changed

+62
-3
lines changed

1 file changed

+62
-3
lines changed

drivers/misc/pci_endpoint_test.c

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <linux/mutex.h>
1818
#include <linux/random.h>
1919
#include <linux/slab.h>
20+
#include <linux/uaccess.h>
2021
#include <linux/pci.h>
2122
#include <linux/pci_ids.h>
2223

@@ -52,6 +53,7 @@
5253
#define STATUS_SRC_ADDR_INVALID BIT(7)
5354
#define STATUS_DST_ADDR_INVALID BIT(8)
5455

56+
#define PCI_ENDPOINT_TEST_STATUS 0x8
5557
#define PCI_ENDPOINT_TEST_LOWER_SRC_ADDR 0x0c
5658
#define PCI_ENDPOINT_TEST_UPPER_SRC_ADDR 0x10
5759

@@ -64,6 +66,9 @@
6466
#define PCI_ENDPOINT_TEST_IRQ_TYPE 0x24
6567
#define PCI_ENDPOINT_TEST_IRQ_NUMBER 0x28
6668

69+
#define PCI_ENDPOINT_TEST_FLAGS 0x2c
70+
#define FLAG_USE_DMA BIT(0)
71+
6772
#define PCI_DEVICE_ID_TI_AM654 0xb00c
6873

6974
#define is_am654_pci_dev(pdev) \
@@ -315,11 +320,16 @@ static bool pci_endpoint_test_msi_irq(struct pci_endpoint_test *test,
315320
return false;
316321
}
317322

318-
static bool pci_endpoint_test_copy(struct pci_endpoint_test *test, size_t size)
323+
static bool pci_endpoint_test_copy(struct pci_endpoint_test *test,
324+
unsigned long arg)
319325
{
326+
struct pci_endpoint_test_xfer_param param;
320327
bool ret = false;
321328
void *src_addr;
322329
void *dst_addr;
330+
u32 flags = 0;
331+
bool use_dma;
332+
size_t size;
323333
dma_addr_t src_phys_addr;
324334
dma_addr_t dst_phys_addr;
325335
struct pci_dev *pdev = test->pdev;
@@ -332,10 +342,22 @@ static bool pci_endpoint_test_copy(struct pci_endpoint_test *test, size_t size)
332342
size_t alignment = test->alignment;
333343
u32 src_crc32;
334344
u32 dst_crc32;
345+
int err;
346+
347+
err = copy_from_user(&param, (void __user *)arg, sizeof(param));
348+
if (err) {
349+
dev_err(dev, "Failed to get transfer param\n");
350+
return false;
351+
}
335352

353+
size = param.size;
336354
if (size > SIZE_MAX - alignment)
337355
goto err;
338356

357+
use_dma = !!(param.flags & PCITEST_FLAGS_USE_DMA);
358+
if (use_dma)
359+
flags |= FLAG_USE_DMA;
360+
339361
if (irq_type < IRQ_TYPE_LEGACY || irq_type > IRQ_TYPE_MSIX) {
340362
dev_err(dev, "Invalid IRQ type option\n");
341363
goto err;
@@ -406,6 +428,7 @@ static bool pci_endpoint_test_copy(struct pci_endpoint_test *test, size_t size)
406428
pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE,
407429
size);
408430

431+
pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_FLAGS, flags);
409432
pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE, irq_type);
410433
pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);
411434
pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
@@ -434,9 +457,13 @@ static bool pci_endpoint_test_copy(struct pci_endpoint_test *test, size_t size)
434457
return ret;
435458
}
436459

437-
static bool pci_endpoint_test_write(struct pci_endpoint_test *test, size_t size)
460+
static bool pci_endpoint_test_write(struct pci_endpoint_test *test,
461+
unsigned long arg)
438462
{
463+
struct pci_endpoint_test_xfer_param param;
439464
bool ret = false;
465+
u32 flags = 0;
466+
bool use_dma;
440467
u32 reg;
441468
void *addr;
442469
dma_addr_t phys_addr;
@@ -446,11 +473,24 @@ static bool pci_endpoint_test_write(struct pci_endpoint_test *test, size_t size)
446473
dma_addr_t orig_phys_addr;
447474
size_t offset;
448475
size_t alignment = test->alignment;
476+
size_t size;
449477
u32 crc32;
478+
int err;
450479

480+
err = copy_from_user(&param, (void __user *)arg, sizeof(param));
481+
if (err != 0) {
482+
dev_err(dev, "Failed to get transfer param\n");
483+
return false;
484+
}
485+
486+
size = param.size;
451487
if (size > SIZE_MAX - alignment)
452488
goto err;
453489

490+
use_dma = !!(param.flags & PCITEST_FLAGS_USE_DMA);
491+
if (use_dma)
492+
flags |= FLAG_USE_DMA;
493+
454494
if (irq_type < IRQ_TYPE_LEGACY || irq_type > IRQ_TYPE_MSIX) {
455495
dev_err(dev, "Invalid IRQ type option\n");
456496
goto err;
@@ -493,6 +533,7 @@ static bool pci_endpoint_test_write(struct pci_endpoint_test *test, size_t size)
493533

494534
pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE, size);
495535

536+
pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_FLAGS, flags);
496537
pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE, irq_type);
497538
pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);
498539
pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
@@ -514,9 +555,14 @@ static bool pci_endpoint_test_write(struct pci_endpoint_test *test, size_t size)
514555
return ret;
515556
}
516557

517-
static bool pci_endpoint_test_read(struct pci_endpoint_test *test, size_t size)
558+
static bool pci_endpoint_test_read(struct pci_endpoint_test *test,
559+
unsigned long arg)
518560
{
561+
struct pci_endpoint_test_xfer_param param;
519562
bool ret = false;
563+
u32 flags = 0;
564+
bool use_dma;
565+
size_t size;
520566
void *addr;
521567
dma_addr_t phys_addr;
522568
struct pci_dev *pdev = test->pdev;
@@ -526,10 +572,22 @@ static bool pci_endpoint_test_read(struct pci_endpoint_test *test, size_t size)
526572
size_t offset;
527573
size_t alignment = test->alignment;
528574
u32 crc32;
575+
int err;
529576

577+
err = copy_from_user(&param, (void __user *)arg, sizeof(param));
578+
if (err) {
579+
dev_err(dev, "Failed to get transfer param\n");
580+
return false;
581+
}
582+
583+
size = param.size;
530584
if (size > SIZE_MAX - alignment)
531585
goto err;
532586

587+
use_dma = !!(param.flags & PCITEST_FLAGS_USE_DMA);
588+
if (use_dma)
589+
flags |= FLAG_USE_DMA;
590+
533591
if (irq_type < IRQ_TYPE_LEGACY || irq_type > IRQ_TYPE_MSIX) {
534592
dev_err(dev, "Invalid IRQ type option\n");
535593
goto err;
@@ -566,6 +624,7 @@ static bool pci_endpoint_test_read(struct pci_endpoint_test *test, size_t size)
566624

567625
pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE, size);
568626

627+
pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_FLAGS, flags);
569628
pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE, irq_type);
570629
pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);
571630
pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,

0 commit comments

Comments
 (0)