mirror of
https://github.com/torvalds/linux.git
synced 2026-05-30 18:13:41 +02:00
Merge branch 'pci/endpoint-test'
- Clear pci-epf-test dma_chan_rx, not dma_chan_tx, after freeing dma_chan_rx (Mohamed Khalfella) - Correct the DMA MEMCPY test so it doesn't fail if the Endpoint supports both DMA_PRIVATE and DMA_MEMCPY (Manivannan Sadhasivam) - Add pci-epf-test and pci_endpoint_test support for capabilities (Niklas Cassel) - Add Endpoint test for consecutive BARs (Niklas Cassel) - Remove redundant comparison from Endpoint BAR test because a > 1MB BAR can always be exactly covered by iterating with a 1MB buffer (Hans Zhang) - Correct the PCI Endpoint test IOCTL return value (Manivannan Sadhasivam) - Move PCI Endpoint tests from tools/pci to Kselftests (Manivannan Sadhasivam) - Convert PCI Endpoint tests to the Kselftest framework (Manivannan Sadhasivam) * pci/endpoint-test: selftests: pci_endpoint: Migrate to Kselftest framework selftests: Move PCI Endpoint tests from tools/pci to Kselftests misc: pci_endpoint_test: Fix IOCTL return value misc: pci_endpoint_test: Remove redundant 'remainder' test misc: pci_endpoint_test: Add consecutive BAR test misc: pci_endpoint_test: Add support for capabilities PCI: endpoint: pci-epf-test: Add support for capabilities PCI: endpoint: pci-epf-test: Fix check for DMA MEMCPY test PCI: endpoint: pci-epf-test: Set dma_chan_rx pointer to NULL on error
This commit is contained in:
commit
e321b10b83
|
|
@ -81,8 +81,8 @@ device, the following commands can be used::
|
|||
|
||||
# echo 0x104c > functions/pci_epf_test/func1/vendorid
|
||||
# echo 0xb500 > functions/pci_epf_test/func1/deviceid
|
||||
# echo 16 > functions/pci_epf_test/func1/msi_interrupts
|
||||
# echo 8 > functions/pci_epf_test/func1/msix_interrupts
|
||||
# echo 32 > functions/pci_epf_test/func1/msi_interrupts
|
||||
# echo 2048 > functions/pci_epf_test/func1/msix_interrupts
|
||||
|
||||
|
||||
Binding pci-epf-test Device to EP Controller
|
||||
|
|
@ -123,113 +123,83 @@ above::
|
|||
Using Endpoint Test function Device
|
||||
-----------------------------------
|
||||
|
||||
pcitest.sh added in tools/pci/ can be used to run all the default PCI endpoint
|
||||
tests. To compile this tool the following commands should be used::
|
||||
Kselftest added in tools/testing/selftests/pci_endpoint can be used to run all
|
||||
the default PCI endpoint tests. To build the Kselftest for PCI endpoint
|
||||
subsystem, the following commands should be used::
|
||||
|
||||
# cd <kernel-dir>
|
||||
# make -C tools/pci
|
||||
# make -C tools/testing/selftests/pci_endpoint
|
||||
|
||||
or if you desire to compile and install in your system::
|
||||
|
||||
# cd <kernel-dir>
|
||||
# make -C tools/pci install
|
||||
# make -C tools/testing/selftests/pci_endpoint INSTALL_PATH=/usr/bin install
|
||||
|
||||
The tool and script will be located in <rootfs>/usr/bin/
|
||||
The test will be located in <rootfs>/usr/bin/
|
||||
|
||||
|
||||
pcitest.sh Output
|
||||
~~~~~~~~~~~~~~~~~
|
||||
Kselftest Output
|
||||
~~~~~~~~~~~~~~~~
|
||||
::
|
||||
|
||||
# pcitest.sh
|
||||
BAR tests
|
||||
# pci_endpoint_test
|
||||
TAP version 13
|
||||
1..16
|
||||
# Starting 16 tests from 9 test cases.
|
||||
# RUN pci_ep_bar.BAR0.BAR_TEST ...
|
||||
# OK pci_ep_bar.BAR0.BAR_TEST
|
||||
ok 1 pci_ep_bar.BAR0.BAR_TEST
|
||||
# RUN pci_ep_bar.BAR1.BAR_TEST ...
|
||||
# OK pci_ep_bar.BAR1.BAR_TEST
|
||||
ok 2 pci_ep_bar.BAR1.BAR_TEST
|
||||
# RUN pci_ep_bar.BAR2.BAR_TEST ...
|
||||
# OK pci_ep_bar.BAR2.BAR_TEST
|
||||
ok 3 pci_ep_bar.BAR2.BAR_TEST
|
||||
# RUN pci_ep_bar.BAR3.BAR_TEST ...
|
||||
# OK pci_ep_bar.BAR3.BAR_TEST
|
||||
ok 4 pci_ep_bar.BAR3.BAR_TEST
|
||||
# RUN pci_ep_bar.BAR4.BAR_TEST ...
|
||||
# OK pci_ep_bar.BAR4.BAR_TEST
|
||||
ok 5 pci_ep_bar.BAR4.BAR_TEST
|
||||
# RUN pci_ep_bar.BAR5.BAR_TEST ...
|
||||
# OK pci_ep_bar.BAR5.BAR_TEST
|
||||
ok 6 pci_ep_bar.BAR5.BAR_TEST
|
||||
# RUN pci_ep_basic.CONSECUTIVE_BAR_TEST ...
|
||||
# OK pci_ep_basic.CONSECUTIVE_BAR_TEST
|
||||
ok 7 pci_ep_basic.CONSECUTIVE_BAR_TEST
|
||||
# RUN pci_ep_basic.LEGACY_IRQ_TEST ...
|
||||
# OK pci_ep_basic.LEGACY_IRQ_TEST
|
||||
ok 8 pci_ep_basic.LEGACY_IRQ_TEST
|
||||
# RUN pci_ep_basic.MSI_TEST ...
|
||||
# OK pci_ep_basic.MSI_TEST
|
||||
ok 9 pci_ep_basic.MSI_TEST
|
||||
# RUN pci_ep_basic.MSIX_TEST ...
|
||||
# OK pci_ep_basic.MSIX_TEST
|
||||
ok 10 pci_ep_basic.MSIX_TEST
|
||||
# RUN pci_ep_data_transfer.memcpy.READ_TEST ...
|
||||
# OK pci_ep_data_transfer.memcpy.READ_TEST
|
||||
ok 11 pci_ep_data_transfer.memcpy.READ_TEST
|
||||
# RUN pci_ep_data_transfer.memcpy.WRITE_TEST ...
|
||||
# OK pci_ep_data_transfer.memcpy.WRITE_TEST
|
||||
ok 12 pci_ep_data_transfer.memcpy.WRITE_TEST
|
||||
# RUN pci_ep_data_transfer.memcpy.COPY_TEST ...
|
||||
# OK pci_ep_data_transfer.memcpy.COPY_TEST
|
||||
ok 13 pci_ep_data_transfer.memcpy.COPY_TEST
|
||||
# RUN pci_ep_data_transfer.dma.READ_TEST ...
|
||||
# OK pci_ep_data_transfer.dma.READ_TEST
|
||||
ok 14 pci_ep_data_transfer.dma.READ_TEST
|
||||
# RUN pci_ep_data_transfer.dma.WRITE_TEST ...
|
||||
# OK pci_ep_data_transfer.dma.WRITE_TEST
|
||||
ok 15 pci_ep_data_transfer.dma.WRITE_TEST
|
||||
# RUN pci_ep_data_transfer.dma.COPY_TEST ...
|
||||
# OK pci_ep_data_transfer.dma.COPY_TEST
|
||||
ok 16 pci_ep_data_transfer.dma.COPY_TEST
|
||||
# PASSED: 16 / 16 tests passed.
|
||||
# Totals: pass:16 fail:0 xfail:0 xpass:0 skip:0 error:0
|
||||
|
||||
BAR0: OKAY
|
||||
BAR1: OKAY
|
||||
BAR2: OKAY
|
||||
BAR3: OKAY
|
||||
BAR4: NOT OKAY
|
||||
BAR5: NOT OKAY
|
||||
|
||||
Interrupt tests
|
||||
Testcase 16 (pci_ep_data_transfer.dma.COPY_TEST) will fail for most of the DMA
|
||||
capable endpoint controllers due to the absence of the MEMCPY over DMA. For such
|
||||
controllers, it is advisable to skip this testcase using this
|
||||
command::
|
||||
|
||||
SET IRQ TYPE TO LEGACY: OKAY
|
||||
LEGACY IRQ: NOT OKAY
|
||||
SET IRQ TYPE TO MSI: OKAY
|
||||
MSI1: OKAY
|
||||
MSI2: OKAY
|
||||
MSI3: OKAY
|
||||
MSI4: OKAY
|
||||
MSI5: OKAY
|
||||
MSI6: OKAY
|
||||
MSI7: OKAY
|
||||
MSI8: OKAY
|
||||
MSI9: OKAY
|
||||
MSI10: OKAY
|
||||
MSI11: OKAY
|
||||
MSI12: OKAY
|
||||
MSI13: OKAY
|
||||
MSI14: OKAY
|
||||
MSI15: OKAY
|
||||
MSI16: OKAY
|
||||
MSI17: NOT OKAY
|
||||
MSI18: NOT OKAY
|
||||
MSI19: NOT OKAY
|
||||
MSI20: NOT OKAY
|
||||
MSI21: NOT OKAY
|
||||
MSI22: NOT OKAY
|
||||
MSI23: NOT OKAY
|
||||
MSI24: NOT OKAY
|
||||
MSI25: NOT OKAY
|
||||
MSI26: NOT OKAY
|
||||
MSI27: NOT OKAY
|
||||
MSI28: NOT OKAY
|
||||
MSI29: NOT OKAY
|
||||
MSI30: NOT OKAY
|
||||
MSI31: NOT OKAY
|
||||
MSI32: NOT OKAY
|
||||
SET IRQ TYPE TO MSI-X: OKAY
|
||||
MSI-X1: OKAY
|
||||
MSI-X2: OKAY
|
||||
MSI-X3: OKAY
|
||||
MSI-X4: OKAY
|
||||
MSI-X5: OKAY
|
||||
MSI-X6: OKAY
|
||||
MSI-X7: OKAY
|
||||
MSI-X8: OKAY
|
||||
MSI-X9: NOT OKAY
|
||||
MSI-X10: NOT OKAY
|
||||
MSI-X11: NOT OKAY
|
||||
MSI-X12: NOT OKAY
|
||||
MSI-X13: NOT OKAY
|
||||
MSI-X14: NOT OKAY
|
||||
MSI-X15: NOT OKAY
|
||||
MSI-X16: NOT OKAY
|
||||
[...]
|
||||
MSI-X2047: NOT OKAY
|
||||
MSI-X2048: NOT OKAY
|
||||
|
||||
Read Tests
|
||||
|
||||
SET IRQ TYPE TO MSI: OKAY
|
||||
READ ( 1 bytes): OKAY
|
||||
READ ( 1024 bytes): OKAY
|
||||
READ ( 1025 bytes): OKAY
|
||||
READ (1024000 bytes): OKAY
|
||||
READ (1024001 bytes): OKAY
|
||||
|
||||
Write Tests
|
||||
|
||||
WRITE ( 1 bytes): OKAY
|
||||
WRITE ( 1024 bytes): OKAY
|
||||
WRITE ( 1025 bytes): OKAY
|
||||
WRITE (1024000 bytes): OKAY
|
||||
WRITE (1024001 bytes): OKAY
|
||||
|
||||
Copy Tests
|
||||
|
||||
COPY ( 1 bytes): OKAY
|
||||
COPY ( 1024 bytes): OKAY
|
||||
COPY ( 1025 bytes): OKAY
|
||||
COPY (1024000 bytes): OKAY
|
||||
COPY (1024001 bytes): OKAY
|
||||
# pci_endpoint_test -f pci_ep_bar -f pci_ep_basic -v memcpy -T COPY_TEST -v dma
|
||||
|
|
|
|||
|
|
@ -18003,7 +18003,7 @@ F: Documentation/PCI/endpoint/*
|
|||
F: Documentation/misc-devices/pci-endpoint-test.rst
|
||||
F: drivers/misc/pci_endpoint_test.c
|
||||
F: drivers/pci/endpoint/
|
||||
F: tools/pci/
|
||||
F: tools/testing/selftests/pci_endpoint/
|
||||
|
||||
PCI ENHANCED ERROR HANDLING (EEH) FOR POWERPC
|
||||
M: Mahesh J Salgaonkar <mahesh@linux.ibm.com>
|
||||
|
|
|
|||
|
|
@ -69,6 +69,9 @@
|
|||
#define PCI_ENDPOINT_TEST_FLAGS 0x2c
|
||||
#define FLAG_USE_DMA BIT(0)
|
||||
|
||||
#define PCI_ENDPOINT_TEST_CAPS 0x30
|
||||
#define CAP_UNALIGNED_ACCESS BIT(0)
|
||||
|
||||
#define PCI_DEVICE_ID_TI_AM654 0xb00c
|
||||
#define PCI_DEVICE_ID_TI_J7200 0xb00f
|
||||
#define PCI_DEVICE_ID_TI_AM64 0xb010
|
||||
|
|
@ -166,43 +169,47 @@ static void pci_endpoint_test_free_irq_vectors(struct pci_endpoint_test *test)
|
|||
test->irq_type = IRQ_TYPE_UNDEFINED;
|
||||
}
|
||||
|
||||
static bool pci_endpoint_test_alloc_irq_vectors(struct pci_endpoint_test *test,
|
||||
static int pci_endpoint_test_alloc_irq_vectors(struct pci_endpoint_test *test,
|
||||
int type)
|
||||
{
|
||||
int irq = -1;
|
||||
int irq;
|
||||
struct pci_dev *pdev = test->pdev;
|
||||
struct device *dev = &pdev->dev;
|
||||
bool res = true;
|
||||
|
||||
switch (type) {
|
||||
case IRQ_TYPE_INTX:
|
||||
irq = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_INTX);
|
||||
if (irq < 0)
|
||||
if (irq < 0) {
|
||||
dev_err(dev, "Failed to get Legacy interrupt\n");
|
||||
return irq;
|
||||
}
|
||||
|
||||
break;
|
||||
case IRQ_TYPE_MSI:
|
||||
irq = pci_alloc_irq_vectors(pdev, 1, 32, PCI_IRQ_MSI);
|
||||
if (irq < 0)
|
||||
if (irq < 0) {
|
||||
dev_err(dev, "Failed to get MSI interrupts\n");
|
||||
return irq;
|
||||
}
|
||||
|
||||
break;
|
||||
case IRQ_TYPE_MSIX:
|
||||
irq = pci_alloc_irq_vectors(pdev, 1, 2048, PCI_IRQ_MSIX);
|
||||
if (irq < 0)
|
||||
if (irq < 0) {
|
||||
dev_err(dev, "Failed to get MSI-X interrupts\n");
|
||||
return irq;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
dev_err(dev, "Invalid IRQ type selected\n");
|
||||
}
|
||||
|
||||
if (irq < 0) {
|
||||
irq = 0;
|
||||
res = false;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
test->irq_type = type;
|
||||
test->num_irqs = irq;
|
||||
|
||||
return res;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pci_endpoint_test_release_irq(struct pci_endpoint_test *test)
|
||||
|
|
@ -217,22 +224,22 @@ static void pci_endpoint_test_release_irq(struct pci_endpoint_test *test)
|
|||
test->num_irqs = 0;
|
||||
}
|
||||
|
||||
static bool pci_endpoint_test_request_irq(struct pci_endpoint_test *test)
|
||||
static int pci_endpoint_test_request_irq(struct pci_endpoint_test *test)
|
||||
{
|
||||
int i;
|
||||
int err;
|
||||
int ret;
|
||||
struct pci_dev *pdev = test->pdev;
|
||||
struct device *dev = &pdev->dev;
|
||||
|
||||
for (i = 0; i < test->num_irqs; i++) {
|
||||
err = devm_request_irq(dev, pci_irq_vector(pdev, i),
|
||||
ret = devm_request_irq(dev, pci_irq_vector(pdev, i),
|
||||
pci_endpoint_test_irqhandler,
|
||||
IRQF_SHARED, test->name, test);
|
||||
if (err)
|
||||
if (ret)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return true;
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
switch (irq_type) {
|
||||
|
|
@ -252,7 +259,7 @@ static bool pci_endpoint_test_request_irq(struct pci_endpoint_test *test)
|
|||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const u32 bar_test_pattern[] = {
|
||||
|
|
@ -277,16 +284,16 @@ static int pci_endpoint_test_bar_memcmp(struct pci_endpoint_test *test,
|
|||
return memcmp(write_buf, read_buf, size);
|
||||
}
|
||||
|
||||
static bool pci_endpoint_test_bar(struct pci_endpoint_test *test,
|
||||
static int pci_endpoint_test_bar(struct pci_endpoint_test *test,
|
||||
enum pci_barno barno)
|
||||
{
|
||||
int j, bar_size, buf_size, iters, remain;
|
||||
int j, bar_size, buf_size, iters;
|
||||
void *write_buf __free(kfree) = NULL;
|
||||
void *read_buf __free(kfree) = NULL;
|
||||
struct pci_dev *pdev = test->pdev;
|
||||
|
||||
if (!test->bar[barno])
|
||||
return false;
|
||||
return -ENOMEM;
|
||||
|
||||
bar_size = pci_resource_len(pdev, barno);
|
||||
|
||||
|
|
@ -301,28 +308,105 @@ static bool pci_endpoint_test_bar(struct pci_endpoint_test *test,
|
|||
|
||||
write_buf = kmalloc(buf_size, GFP_KERNEL);
|
||||
if (!write_buf)
|
||||
return false;
|
||||
return -ENOMEM;
|
||||
|
||||
read_buf = kmalloc(buf_size, GFP_KERNEL);
|
||||
if (!read_buf)
|
||||
return false;
|
||||
return -ENOMEM;
|
||||
|
||||
iters = bar_size / buf_size;
|
||||
for (j = 0; j < iters; j++)
|
||||
if (pci_endpoint_test_bar_memcmp(test, barno, buf_size * j,
|
||||
write_buf, read_buf, buf_size))
|
||||
return false;
|
||||
return -EIO;
|
||||
|
||||
remain = bar_size % buf_size;
|
||||
if (remain)
|
||||
if (pci_endpoint_test_bar_memcmp(test, barno, buf_size * iters,
|
||||
write_buf, read_buf, remain))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool pci_endpoint_test_intx_irq(struct pci_endpoint_test *test)
|
||||
static u32 bar_test_pattern_with_offset(enum pci_barno barno, int offset)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
/* Keep the BAR pattern in the top byte. */
|
||||
val = bar_test_pattern[barno] & 0xff000000;
|
||||
/* Store the (partial) offset in the remaining bytes. */
|
||||
val |= offset & 0x00ffffff;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static void pci_endpoint_test_bars_write_bar(struct pci_endpoint_test *test,
|
||||
enum pci_barno barno)
|
||||
{
|
||||
struct pci_dev *pdev = test->pdev;
|
||||
int j, size;
|
||||
|
||||
size = pci_resource_len(pdev, barno);
|
||||
|
||||
if (barno == test->test_reg_bar)
|
||||
size = 0x4;
|
||||
|
||||
for (j = 0; j < size; j += 4)
|
||||
writel_relaxed(bar_test_pattern_with_offset(barno, j),
|
||||
test->bar[barno] + j);
|
||||
}
|
||||
|
||||
static int pci_endpoint_test_bars_read_bar(struct pci_endpoint_test *test,
|
||||
enum pci_barno barno)
|
||||
{
|
||||
struct pci_dev *pdev = test->pdev;
|
||||
struct device *dev = &pdev->dev;
|
||||
int j, size;
|
||||
u32 val;
|
||||
|
||||
size = pci_resource_len(pdev, barno);
|
||||
|
||||
if (barno == test->test_reg_bar)
|
||||
size = 0x4;
|
||||
|
||||
for (j = 0; j < size; j += 4) {
|
||||
u32 expected = bar_test_pattern_with_offset(barno, j);
|
||||
|
||||
val = readl_relaxed(test->bar[barno] + j);
|
||||
if (val != expected) {
|
||||
dev_err(dev,
|
||||
"BAR%d incorrect data at offset: %#x, got: %#x expected: %#x\n",
|
||||
barno, j, val, expected);
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pci_endpoint_test_bars(struct pci_endpoint_test *test)
|
||||
{
|
||||
enum pci_barno bar;
|
||||
bool ret;
|
||||
|
||||
/* Write all BARs in order (without reading). */
|
||||
for (bar = 0; bar < PCI_STD_NUM_BARS; bar++)
|
||||
if (test->bar[bar])
|
||||
pci_endpoint_test_bars_write_bar(test, bar);
|
||||
|
||||
/*
|
||||
* Read all BARs in order (without writing).
|
||||
* If there is an address translation issue on the EP, writing one BAR
|
||||
* might have overwritten another BAR. Ensure that this is not the case.
|
||||
* (Reading back the BAR directly after writing can not detect this.)
|
||||
*/
|
||||
for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) {
|
||||
if (test->bar[bar]) {
|
||||
ret = pci_endpoint_test_bars_read_bar(test, bar);
|
||||
if (!ret)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pci_endpoint_test_intx_irq(struct pci_endpoint_test *test)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
|
|
@ -334,16 +418,17 @@ static bool pci_endpoint_test_intx_irq(struct pci_endpoint_test *test)
|
|||
val = wait_for_completion_timeout(&test->irq_raised,
|
||||
msecs_to_jiffies(1000));
|
||||
if (!val)
|
||||
return false;
|
||||
return -ETIMEDOUT;
|
||||
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool pci_endpoint_test_msi_irq(struct pci_endpoint_test *test,
|
||||
static int pci_endpoint_test_msi_irq(struct pci_endpoint_test *test,
|
||||
u16 msi_num, bool msix)
|
||||
{
|
||||
u32 val;
|
||||
struct pci_dev *pdev = test->pdev;
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE,
|
||||
msix ? IRQ_TYPE_MSIX : IRQ_TYPE_MSI);
|
||||
|
|
@ -354,9 +439,16 @@ static bool pci_endpoint_test_msi_irq(struct pci_endpoint_test *test,
|
|||
val = wait_for_completion_timeout(&test->irq_raised,
|
||||
msecs_to_jiffies(1000));
|
||||
if (!val)
|
||||
return false;
|
||||
return -ETIMEDOUT;
|
||||
|
||||
return pci_irq_vector(pdev, msi_num - 1) == test->last_irq;
|
||||
ret = pci_irq_vector(pdev, msi_num - 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (ret != test->last_irq)
|
||||
return -EIO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pci_endpoint_test_validate_xfer_params(struct device *dev,
|
||||
|
|
@ -375,11 +467,10 @@ static int pci_endpoint_test_validate_xfer_params(struct device *dev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool pci_endpoint_test_copy(struct pci_endpoint_test *test,
|
||||
static int pci_endpoint_test_copy(struct pci_endpoint_test *test,
|
||||
unsigned long arg)
|
||||
{
|
||||
struct pci_endpoint_test_xfer_param param;
|
||||
bool ret = false;
|
||||
void *src_addr;
|
||||
void *dst_addr;
|
||||
u32 flags = 0;
|
||||
|
|
@ -398,17 +489,17 @@ static bool pci_endpoint_test_copy(struct pci_endpoint_test *test,
|
|||
int irq_type = test->irq_type;
|
||||
u32 src_crc32;
|
||||
u32 dst_crc32;
|
||||
int err;
|
||||
int ret;
|
||||
|
||||
err = copy_from_user(¶m, (void __user *)arg, sizeof(param));
|
||||
if (err) {
|
||||
ret = copy_from_user(¶m, (void __user *)arg, sizeof(param));
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to get transfer param\n");
|
||||
return false;
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
err = pci_endpoint_test_validate_xfer_params(dev, ¶m, alignment);
|
||||
if (err)
|
||||
return false;
|
||||
ret = pci_endpoint_test_validate_xfer_params(dev, ¶m, alignment);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
size = param.size;
|
||||
|
||||
|
|
@ -418,22 +509,21 @@ static bool pci_endpoint_test_copy(struct pci_endpoint_test *test,
|
|||
|
||||
if (irq_type < IRQ_TYPE_INTX || irq_type > IRQ_TYPE_MSIX) {
|
||||
dev_err(dev, "Invalid IRQ type option\n");
|
||||
goto err;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
orig_src_addr = kzalloc(size + alignment, GFP_KERNEL);
|
||||
if (!orig_src_addr) {
|
||||
dev_err(dev, "Failed to allocate source buffer\n");
|
||||
ret = false;
|
||||
goto err;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
get_random_bytes(orig_src_addr, size + alignment);
|
||||
orig_src_phys_addr = dma_map_single(dev, orig_src_addr,
|
||||
size + alignment, DMA_TO_DEVICE);
|
||||
if (dma_mapping_error(dev, orig_src_phys_addr)) {
|
||||
ret = dma_mapping_error(dev, orig_src_phys_addr);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to map source buffer address\n");
|
||||
ret = false;
|
||||
goto err_src_phys_addr;
|
||||
}
|
||||
|
||||
|
|
@ -457,15 +547,15 @@ static bool pci_endpoint_test_copy(struct pci_endpoint_test *test,
|
|||
orig_dst_addr = kzalloc(size + alignment, GFP_KERNEL);
|
||||
if (!orig_dst_addr) {
|
||||
dev_err(dev, "Failed to allocate destination address\n");
|
||||
ret = false;
|
||||
ret = -ENOMEM;
|
||||
goto err_dst_addr;
|
||||
}
|
||||
|
||||
orig_dst_phys_addr = dma_map_single(dev, orig_dst_addr,
|
||||
size + alignment, DMA_FROM_DEVICE);
|
||||
if (dma_mapping_error(dev, orig_dst_phys_addr)) {
|
||||
ret = dma_mapping_error(dev, orig_dst_phys_addr);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to map destination buffer address\n");
|
||||
ret = false;
|
||||
goto err_dst_phys_addr;
|
||||
}
|
||||
|
||||
|
|
@ -498,8 +588,8 @@ static bool pci_endpoint_test_copy(struct pci_endpoint_test *test,
|
|||
DMA_FROM_DEVICE);
|
||||
|
||||
dst_crc32 = crc32_le(~0, dst_addr, size);
|
||||
if (dst_crc32 == src_crc32)
|
||||
ret = true;
|
||||
if (dst_crc32 != src_crc32)
|
||||
ret = -EIO;
|
||||
|
||||
err_dst_phys_addr:
|
||||
kfree(orig_dst_addr);
|
||||
|
|
@ -510,16 +600,13 @@ static bool pci_endpoint_test_copy(struct pci_endpoint_test *test,
|
|||
|
||||
err_src_phys_addr:
|
||||
kfree(orig_src_addr);
|
||||
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool pci_endpoint_test_write(struct pci_endpoint_test *test,
|
||||
static int 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;
|
||||
|
|
@ -534,17 +621,17 @@ static bool pci_endpoint_test_write(struct pci_endpoint_test *test,
|
|||
int irq_type = test->irq_type;
|
||||
size_t size;
|
||||
u32 crc32;
|
||||
int err;
|
||||
int ret;
|
||||
|
||||
err = copy_from_user(¶m, (void __user *)arg, sizeof(param));
|
||||
if (err != 0) {
|
||||
ret = copy_from_user(¶m, (void __user *)arg, sizeof(param));
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to get transfer param\n");
|
||||
return false;
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
err = pci_endpoint_test_validate_xfer_params(dev, ¶m, alignment);
|
||||
if (err)
|
||||
return false;
|
||||
ret = pci_endpoint_test_validate_xfer_params(dev, ¶m, alignment);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
size = param.size;
|
||||
|
||||
|
|
@ -554,23 +641,22 @@ static bool pci_endpoint_test_write(struct pci_endpoint_test *test,
|
|||
|
||||
if (irq_type < IRQ_TYPE_INTX || irq_type > IRQ_TYPE_MSIX) {
|
||||
dev_err(dev, "Invalid IRQ type option\n");
|
||||
goto err;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
orig_addr = kzalloc(size + alignment, GFP_KERNEL);
|
||||
if (!orig_addr) {
|
||||
dev_err(dev, "Failed to allocate address\n");
|
||||
ret = false;
|
||||
goto err;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
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)) {
|
||||
ret = dma_mapping_error(dev, orig_phys_addr);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to map source buffer address\n");
|
||||
ret = false;
|
||||
goto err_phys_addr;
|
||||
}
|
||||
|
||||
|
|
@ -603,24 +689,21 @@ static bool pci_endpoint_test_write(struct pci_endpoint_test *test,
|
|||
wait_for_completion(&test->irq_raised);
|
||||
|
||||
reg = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_STATUS);
|
||||
if (reg & STATUS_READ_SUCCESS)
|
||||
ret = true;
|
||||
if (!(reg & STATUS_READ_SUCCESS))
|
||||
ret = -EIO;
|
||||
|
||||
dma_unmap_single(dev, orig_phys_addr, size + alignment,
|
||||
DMA_TO_DEVICE);
|
||||
|
||||
err_phys_addr:
|
||||
kfree(orig_addr);
|
||||
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool pci_endpoint_test_read(struct pci_endpoint_test *test,
|
||||
static int 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;
|
||||
|
|
@ -634,17 +717,17 @@ static bool pci_endpoint_test_read(struct pci_endpoint_test *test,
|
|||
size_t alignment = test->alignment;
|
||||
int irq_type = test->irq_type;
|
||||
u32 crc32;
|
||||
int err;
|
||||
int ret;
|
||||
|
||||
err = copy_from_user(¶m, (void __user *)arg, sizeof(param));
|
||||
if (err) {
|
||||
ret = copy_from_user(¶m, (void __user *)arg, sizeof(param));
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to get transfer param\n");
|
||||
return false;
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
err = pci_endpoint_test_validate_xfer_params(dev, ¶m, alignment);
|
||||
if (err)
|
||||
return false;
|
||||
ret = pci_endpoint_test_validate_xfer_params(dev, ¶m, alignment);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
size = param.size;
|
||||
|
||||
|
|
@ -654,21 +737,20 @@ static bool pci_endpoint_test_read(struct pci_endpoint_test *test,
|
|||
|
||||
if (irq_type < IRQ_TYPE_INTX || irq_type > IRQ_TYPE_MSIX) {
|
||||
dev_err(dev, "Invalid IRQ type option\n");
|
||||
goto err;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
orig_addr = kzalloc(size + alignment, GFP_KERNEL);
|
||||
if (!orig_addr) {
|
||||
dev_err(dev, "Failed to allocate destination address\n");
|
||||
ret = false;
|
||||
goto err;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
orig_phys_addr = dma_map_single(dev, orig_addr, size + alignment,
|
||||
DMA_FROM_DEVICE);
|
||||
if (dma_mapping_error(dev, orig_phys_addr)) {
|
||||
ret = dma_mapping_error(dev, orig_phys_addr);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to map source buffer address\n");
|
||||
ret = false;
|
||||
goto err_phys_addr;
|
||||
}
|
||||
|
||||
|
|
@ -700,50 +782,51 @@ static bool pci_endpoint_test_read(struct pci_endpoint_test *test,
|
|||
DMA_FROM_DEVICE);
|
||||
|
||||
crc32 = crc32_le(~0, addr, size);
|
||||
if (crc32 == pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_CHECKSUM))
|
||||
ret = true;
|
||||
if (crc32 != pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_CHECKSUM))
|
||||
ret = -EIO;
|
||||
|
||||
err_phys_addr:
|
||||
kfree(orig_addr);
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool pci_endpoint_test_clear_irq(struct pci_endpoint_test *test)
|
||||
static int pci_endpoint_test_clear_irq(struct pci_endpoint_test *test)
|
||||
{
|
||||
pci_endpoint_test_release_irq(test);
|
||||
pci_endpoint_test_free_irq_vectors(test);
|
||||
return true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool pci_endpoint_test_set_irq(struct pci_endpoint_test *test,
|
||||
static int pci_endpoint_test_set_irq(struct pci_endpoint_test *test,
|
||||
int req_irq_type)
|
||||
{
|
||||
struct pci_dev *pdev = test->pdev;
|
||||
struct device *dev = &pdev->dev;
|
||||
int ret;
|
||||
|
||||
if (req_irq_type < IRQ_TYPE_INTX || req_irq_type > IRQ_TYPE_MSIX) {
|
||||
dev_err(dev, "Invalid IRQ type option\n");
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (test->irq_type == req_irq_type)
|
||||
return true;
|
||||
return 0;
|
||||
|
||||
pci_endpoint_test_release_irq(test);
|
||||
pci_endpoint_test_free_irq_vectors(test);
|
||||
|
||||
if (!pci_endpoint_test_alloc_irq_vectors(test, req_irq_type))
|
||||
goto err;
|
||||
ret = pci_endpoint_test_alloc_irq_vectors(test, req_irq_type);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!pci_endpoint_test_request_irq(test))
|
||||
goto err;
|
||||
ret = pci_endpoint_test_request_irq(test);
|
||||
if (ret) {
|
||||
pci_endpoint_test_free_irq_vectors(test);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
err:
|
||||
pci_endpoint_test_free_irq_vectors(test);
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long pci_endpoint_test_ioctl(struct file *file, unsigned int cmd,
|
||||
|
|
@ -768,6 +851,9 @@ static long pci_endpoint_test_ioctl(struct file *file, unsigned int cmd,
|
|||
goto ret;
|
||||
ret = pci_endpoint_test_bar(test, bar);
|
||||
break;
|
||||
case PCITEST_BARS:
|
||||
ret = pci_endpoint_test_bars(test);
|
||||
break;
|
||||
case PCITEST_INTX_IRQ:
|
||||
ret = pci_endpoint_test_intx_irq(test);
|
||||
break;
|
||||
|
|
@ -805,10 +891,24 @@ static const struct file_operations pci_endpoint_test_fops = {
|
|||
.unlocked_ioctl = pci_endpoint_test_ioctl,
|
||||
};
|
||||
|
||||
static void pci_endpoint_test_get_capabilities(struct pci_endpoint_test *test)
|
||||
{
|
||||
struct pci_dev *pdev = test->pdev;
|
||||
struct device *dev = &pdev->dev;
|
||||
u32 caps;
|
||||
|
||||
caps = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_CAPS);
|
||||
dev_dbg(dev, "PCI_ENDPOINT_TEST_CAPS: %#x\n", caps);
|
||||
|
||||
/* CAP_UNALIGNED_ACCESS is set if the EP can do unaligned access */
|
||||
if (caps & CAP_UNALIGNED_ACCESS)
|
||||
test->alignment = 0;
|
||||
}
|
||||
|
||||
static int pci_endpoint_test_probe(struct pci_dev *pdev,
|
||||
const struct pci_device_id *ent)
|
||||
{
|
||||
int err;
|
||||
int ret;
|
||||
int id;
|
||||
char name[24];
|
||||
enum pci_barno bar;
|
||||
|
|
@ -847,24 +947,23 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
|
|||
|
||||
dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(48));
|
||||
|
||||
err = pci_enable_device(pdev);
|
||||
if (err) {
|
||||
ret = pci_enable_device(pdev);
|
||||
if (ret) {
|
||||
dev_err(dev, "Cannot enable PCI device\n");
|
||||
return err;
|
||||
return ret;
|
||||
}
|
||||
|
||||
err = pci_request_regions(pdev, DRV_MODULE_NAME);
|
||||
if (err) {
|
||||
ret = pci_request_regions(pdev, DRV_MODULE_NAME);
|
||||
if (ret) {
|
||||
dev_err(dev, "Cannot obtain PCI resources\n");
|
||||
goto err_disable_pdev;
|
||||
}
|
||||
|
||||
pci_set_master(pdev);
|
||||
|
||||
if (!pci_endpoint_test_alloc_irq_vectors(test, irq_type)) {
|
||||
err = -EINVAL;
|
||||
ret = pci_endpoint_test_alloc_irq_vectors(test, irq_type);
|
||||
if (ret)
|
||||
goto err_disable_irq;
|
||||
}
|
||||
|
||||
for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) {
|
||||
if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM) {
|
||||
|
|
@ -879,7 +978,7 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
|
|||
|
||||
test->base = test->bar[test_reg_bar];
|
||||
if (!test->base) {
|
||||
err = -ENOMEM;
|
||||
ret = -ENOMEM;
|
||||
dev_err(dev, "Cannot perform PCI test without BAR%d\n",
|
||||
test_reg_bar);
|
||||
goto err_iounmap;
|
||||
|
|
@ -889,7 +988,7 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
|
|||
|
||||
id = ida_alloc(&pci_endpoint_test_ida, GFP_KERNEL);
|
||||
if (id < 0) {
|
||||
err = id;
|
||||
ret = id;
|
||||
dev_err(dev, "Unable to get id\n");
|
||||
goto err_iounmap;
|
||||
}
|
||||
|
|
@ -897,27 +996,28 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
|
|||
snprintf(name, sizeof(name), DRV_MODULE_NAME ".%d", id);
|
||||
test->name = kstrdup(name, GFP_KERNEL);
|
||||
if (!test->name) {
|
||||
err = -ENOMEM;
|
||||
ret = -ENOMEM;
|
||||
goto err_ida_remove;
|
||||
}
|
||||
|
||||
if (!pci_endpoint_test_request_irq(test)) {
|
||||
err = -EINVAL;
|
||||
ret = pci_endpoint_test_request_irq(test);
|
||||
if (ret)
|
||||
goto err_kfree_test_name;
|
||||
}
|
||||
|
||||
pci_endpoint_test_get_capabilities(test);
|
||||
|
||||
misc_device = &test->miscdev;
|
||||
misc_device->minor = MISC_DYNAMIC_MINOR;
|
||||
misc_device->name = kstrdup(name, GFP_KERNEL);
|
||||
if (!misc_device->name) {
|
||||
err = -ENOMEM;
|
||||
ret = -ENOMEM;
|
||||
goto err_release_irq;
|
||||
}
|
||||
misc_device->parent = &pdev->dev;
|
||||
misc_device->fops = &pci_endpoint_test_fops;
|
||||
|
||||
err = misc_register(misc_device);
|
||||
if (err) {
|
||||
ret = misc_register(misc_device);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to register device\n");
|
||||
goto err_kfree_name;
|
||||
}
|
||||
|
|
@ -949,7 +1049,7 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
|
|||
err_disable_pdev:
|
||||
pci_disable_device(pdev);
|
||||
|
||||
return err;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void pci_endpoint_test_remove(struct pci_dev *pdev)
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@
|
|||
|
||||
#define TIMER_RESOLUTION 1
|
||||
|
||||
#define CAP_UNALIGNED_ACCESS BIT(0)
|
||||
|
||||
static struct workqueue_struct *kpcitest_workqueue;
|
||||
|
||||
struct pci_epf_test {
|
||||
|
|
@ -74,6 +76,7 @@ struct pci_epf_test_reg {
|
|||
u32 irq_type;
|
||||
u32 irq_number;
|
||||
u32 flags;
|
||||
u32 caps;
|
||||
} __packed;
|
||||
|
||||
static struct pci_epf_header test_header = {
|
||||
|
|
@ -251,7 +254,7 @@ static int pci_epf_test_init_dma_chan(struct pci_epf_test *epf_test)
|
|||
|
||||
fail_back_rx:
|
||||
dma_release_channel(epf_test->dma_chan_rx);
|
||||
epf_test->dma_chan_tx = NULL;
|
||||
epf_test->dma_chan_rx = NULL;
|
||||
|
||||
fail_back_tx:
|
||||
dma_cap_zero(mask);
|
||||
|
|
@ -328,8 +331,8 @@ static void pci_epf_test_copy(struct pci_epf_test *epf_test,
|
|||
void *copy_buf = NULL, *buf;
|
||||
|
||||
if (reg->flags & FLAG_USE_DMA) {
|
||||
if (epf_test->dma_private) {
|
||||
dev_err(dev, "Cannot transfer data using DMA\n");
|
||||
if (!dma_has_cap(DMA_MEMCPY, epf_test->dma_chan_tx->device->cap_mask)) {
|
||||
dev_err(dev, "DMA controller doesn't support MEMCPY\n");
|
||||
ret = -EINVAL;
|
||||
goto set_status;
|
||||
}
|
||||
|
|
@ -739,6 +742,20 @@ static void pci_epf_test_clear_bar(struct pci_epf *epf)
|
|||
}
|
||||
}
|
||||
|
||||
static void pci_epf_test_set_capabilities(struct pci_epf *epf)
|
||||
{
|
||||
struct pci_epf_test *epf_test = epf_get_drvdata(epf);
|
||||
enum pci_barno test_reg_bar = epf_test->test_reg_bar;
|
||||
struct pci_epf_test_reg *reg = epf_test->reg[test_reg_bar];
|
||||
struct pci_epc *epc = epf->epc;
|
||||
u32 caps = 0;
|
||||
|
||||
if (epc->ops->align_addr)
|
||||
caps |= CAP_UNALIGNED_ACCESS;
|
||||
|
||||
reg->caps = cpu_to_le32(caps);
|
||||
}
|
||||
|
||||
static int pci_epf_test_epc_init(struct pci_epf *epf)
|
||||
{
|
||||
struct pci_epf_test *epf_test = epf_get_drvdata(epf);
|
||||
|
|
@ -763,6 +780,8 @@ static int pci_epf_test_epc_init(struct pci_epf *epf)
|
|||
}
|
||||
}
|
||||
|
||||
pci_epf_test_set_capabilities(epf);
|
||||
|
||||
ret = pci_epf_test_set_bar(epf);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#define PCITEST_MSIX _IOW('P', 0x7, int)
|
||||
#define PCITEST_SET_IRQTYPE _IOW('P', 0x8, int)
|
||||
#define PCITEST_GET_IRQTYPE _IO('P', 0x9)
|
||||
#define PCITEST_BARS _IO('P', 0xa)
|
||||
#define PCITEST_CLEAR_IRQ _IO('P', 0x10)
|
||||
|
||||
#define PCITEST_FLAGS_USE_DMA 0x00000001
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
pcitest-y += pcitest.o
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
include ../scripts/Makefile.include
|
||||
|
||||
bindir ?= /usr/bin
|
||||
|
||||
ifeq ($(srctree),)
|
||||
srctree := $(patsubst %/,%,$(dir $(CURDIR)))
|
||||
srctree := $(patsubst %/,%,$(dir $(srctree)))
|
||||
endif
|
||||
|
||||
# Do not use make's built-in rules
|
||||
# (this improves performance and avoids hard-to-debug behaviour);
|
||||
MAKEFLAGS += -r
|
||||
|
||||
CFLAGS += -O2 -Wall -g -D_GNU_SOURCE -I$(OUTPUT)include
|
||||
|
||||
ALL_TARGETS := pcitest
|
||||
ALL_PROGRAMS := $(patsubst %,$(OUTPUT)%,$(ALL_TARGETS))
|
||||
|
||||
SCRIPTS := pcitest.sh
|
||||
|
||||
all: $(ALL_PROGRAMS)
|
||||
|
||||
export srctree OUTPUT CC LD CFLAGS
|
||||
include $(srctree)/tools/build/Makefile.include
|
||||
|
||||
#
|
||||
# We need the following to be outside of kernel tree
|
||||
#
|
||||
$(OUTPUT)include/linux/: ../../include/uapi/linux/
|
||||
mkdir -p $(OUTPUT)include/linux/ 2>&1 || true
|
||||
ln -sf $(CURDIR)/../../include/uapi/linux/pcitest.h $@
|
||||
|
||||
prepare: $(OUTPUT)include/linux/
|
||||
|
||||
PCITEST_IN := $(OUTPUT)pcitest-in.o
|
||||
$(PCITEST_IN): prepare FORCE
|
||||
$(Q)$(MAKE) $(build)=pcitest
|
||||
$(OUTPUT)pcitest: $(PCITEST_IN)
|
||||
$(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@
|
||||
|
||||
clean:
|
||||
rm -f $(ALL_PROGRAMS)
|
||||
rm -rf $(OUTPUT)include/
|
||||
find $(or $(OUTPUT),.) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete
|
||||
|
||||
install: $(ALL_PROGRAMS)
|
||||
install -d -m 755 $(DESTDIR)$(bindir); \
|
||||
for program in $(ALL_PROGRAMS); do \
|
||||
install $$program $(DESTDIR)$(bindir); \
|
||||
done; \
|
||||
for script in $(SCRIPTS); do \
|
||||
install $$script $(DESTDIR)$(bindir); \
|
||||
done
|
||||
|
||||
FORCE:
|
||||
|
||||
.PHONY: all install clean FORCE prepare
|
||||
|
|
@ -1,250 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/**
|
||||
* Userspace PCI Endpoint Test Module
|
||||
*
|
||||
* Copyright (C) 2017 Texas Instruments
|
||||
* Author: Kishon Vijay Abraham I <kishon@ti.com>
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <linux/pcitest.h>
|
||||
|
||||
static char *result[] = { "NOT OKAY", "OKAY" };
|
||||
static char *irq[] = { "LEGACY", "MSI", "MSI-X" };
|
||||
|
||||
struct pci_test {
|
||||
char *device;
|
||||
char barnum;
|
||||
bool legacyirq;
|
||||
unsigned int msinum;
|
||||
unsigned int msixnum;
|
||||
int irqtype;
|
||||
bool set_irqtype;
|
||||
bool get_irqtype;
|
||||
bool clear_irq;
|
||||
bool read;
|
||||
bool write;
|
||||
bool copy;
|
||||
unsigned long size;
|
||||
bool use_dma;
|
||||
};
|
||||
|
||||
static int run_test(struct pci_test *test)
|
||||
{
|
||||
struct pci_endpoint_test_xfer_param param = {};
|
||||
int ret = -EINVAL;
|
||||
int fd;
|
||||
|
||||
fd = open(test->device, O_RDWR);
|
||||
if (fd < 0) {
|
||||
perror("can't open PCI Endpoint Test device");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (test->barnum >= 0 && test->barnum <= 5) {
|
||||
ret = ioctl(fd, PCITEST_BAR, test->barnum);
|
||||
fprintf(stdout, "BAR%d:\t\t", test->barnum);
|
||||
if (ret < 0)
|
||||
fprintf(stdout, "TEST FAILED\n");
|
||||
else
|
||||
fprintf(stdout, "%s\n", result[ret]);
|
||||
}
|
||||
|
||||
if (test->set_irqtype) {
|
||||
ret = ioctl(fd, PCITEST_SET_IRQTYPE, test->irqtype);
|
||||
fprintf(stdout, "SET IRQ TYPE TO %s:\t\t", irq[test->irqtype]);
|
||||
if (ret < 0)
|
||||
fprintf(stdout, "FAILED\n");
|
||||
else
|
||||
fprintf(stdout, "%s\n", result[ret]);
|
||||
}
|
||||
|
||||
if (test->get_irqtype) {
|
||||
ret = ioctl(fd, PCITEST_GET_IRQTYPE);
|
||||
fprintf(stdout, "GET IRQ TYPE:\t\t");
|
||||
if (ret < 0)
|
||||
fprintf(stdout, "FAILED\n");
|
||||
else
|
||||
fprintf(stdout, "%s\n", irq[ret]);
|
||||
}
|
||||
|
||||
if (test->clear_irq) {
|
||||
ret = ioctl(fd, PCITEST_CLEAR_IRQ);
|
||||
fprintf(stdout, "CLEAR IRQ:\t\t");
|
||||
if (ret < 0)
|
||||
fprintf(stdout, "FAILED\n");
|
||||
else
|
||||
fprintf(stdout, "%s\n", result[ret]);
|
||||
}
|
||||
|
||||
if (test->legacyirq) {
|
||||
ret = ioctl(fd, PCITEST_LEGACY_IRQ, 0);
|
||||
fprintf(stdout, "LEGACY IRQ:\t");
|
||||
if (ret < 0)
|
||||
fprintf(stdout, "TEST FAILED\n");
|
||||
else
|
||||
fprintf(stdout, "%s\n", result[ret]);
|
||||
}
|
||||
|
||||
if (test->msinum > 0 && test->msinum <= 32) {
|
||||
ret = ioctl(fd, PCITEST_MSI, test->msinum);
|
||||
fprintf(stdout, "MSI%u:\t\t", test->msinum);
|
||||
if (ret < 0)
|
||||
fprintf(stdout, "TEST FAILED\n");
|
||||
else
|
||||
fprintf(stdout, "%s\n", result[ret]);
|
||||
}
|
||||
|
||||
if (test->msixnum > 0 && test->msixnum <= 2048) {
|
||||
ret = ioctl(fd, PCITEST_MSIX, test->msixnum);
|
||||
fprintf(stdout, "MSI-X%u:\t\t", test->msixnum);
|
||||
if (ret < 0)
|
||||
fprintf(stdout, "TEST FAILED\n");
|
||||
else
|
||||
fprintf(stdout, "%s\n", result[ret]);
|
||||
}
|
||||
|
||||
if (test->write) {
|
||||
param.size = test->size;
|
||||
if (test->use_dma)
|
||||
param.flags = PCITEST_FLAGS_USE_DMA;
|
||||
ret = ioctl(fd, PCITEST_WRITE, ¶m);
|
||||
fprintf(stdout, "WRITE (%7lu bytes):\t\t", test->size);
|
||||
if (ret < 0)
|
||||
fprintf(stdout, "TEST FAILED\n");
|
||||
else
|
||||
fprintf(stdout, "%s\n", result[ret]);
|
||||
}
|
||||
|
||||
if (test->read) {
|
||||
param.size = test->size;
|
||||
if (test->use_dma)
|
||||
param.flags = PCITEST_FLAGS_USE_DMA;
|
||||
ret = ioctl(fd, PCITEST_READ, ¶m);
|
||||
fprintf(stdout, "READ (%7lu bytes):\t\t", test->size);
|
||||
if (ret < 0)
|
||||
fprintf(stdout, "TEST FAILED\n");
|
||||
else
|
||||
fprintf(stdout, "%s\n", result[ret]);
|
||||
}
|
||||
|
||||
if (test->copy) {
|
||||
param.size = test->size;
|
||||
if (test->use_dma)
|
||||
param.flags = PCITEST_FLAGS_USE_DMA;
|
||||
ret = ioctl(fd, PCITEST_COPY, ¶m);
|
||||
fprintf(stdout, "COPY (%7lu bytes):\t\t", test->size);
|
||||
if (ret < 0)
|
||||
fprintf(stdout, "TEST FAILED\n");
|
||||
else
|
||||
fprintf(stdout, "%s\n", result[ret]);
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
close(fd);
|
||||
return (ret < 0) ? ret : 1 - ret; /* return 0 if test succeeded */
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int c;
|
||||
struct pci_test *test;
|
||||
|
||||
test = calloc(1, sizeof(*test));
|
||||
if (!test) {
|
||||
perror("Fail to allocate memory for pci_test\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* since '0' is a valid BAR number, initialize it to -1 */
|
||||
test->barnum = -1;
|
||||
|
||||
/* set default size as 100KB */
|
||||
test->size = 0x19000;
|
||||
|
||||
/* set default endpoint device */
|
||||
test->device = "/dev/pci-endpoint-test.0";
|
||||
|
||||
while ((c = getopt(argc, argv, "D:b:m:x:i:deIlhrwcs:")) != EOF)
|
||||
switch (c) {
|
||||
case 'D':
|
||||
test->device = optarg;
|
||||
continue;
|
||||
case 'b':
|
||||
test->barnum = atoi(optarg);
|
||||
if (test->barnum < 0 || test->barnum > 5)
|
||||
goto usage;
|
||||
continue;
|
||||
case 'l':
|
||||
test->legacyirq = true;
|
||||
continue;
|
||||
case 'm':
|
||||
test->msinum = atoi(optarg);
|
||||
if (test->msinum < 1 || test->msinum > 32)
|
||||
goto usage;
|
||||
continue;
|
||||
case 'x':
|
||||
test->msixnum = atoi(optarg);
|
||||
if (test->msixnum < 1 || test->msixnum > 2048)
|
||||
goto usage;
|
||||
continue;
|
||||
case 'i':
|
||||
test->irqtype = atoi(optarg);
|
||||
if (test->irqtype < 0 || test->irqtype > 2)
|
||||
goto usage;
|
||||
test->set_irqtype = true;
|
||||
continue;
|
||||
case 'I':
|
||||
test->get_irqtype = true;
|
||||
continue;
|
||||
case 'r':
|
||||
test->read = true;
|
||||
continue;
|
||||
case 'w':
|
||||
test->write = true;
|
||||
continue;
|
||||
case 'c':
|
||||
test->copy = true;
|
||||
continue;
|
||||
case 'e':
|
||||
test->clear_irq = true;
|
||||
continue;
|
||||
case 's':
|
||||
test->size = strtoul(optarg, NULL, 0);
|
||||
continue;
|
||||
case 'd':
|
||||
test->use_dma = true;
|
||||
continue;
|
||||
case 'h':
|
||||
default:
|
||||
usage:
|
||||
fprintf(stderr,
|
||||
"usage: %s [options]\n"
|
||||
"Options:\n"
|
||||
"\t-D <dev> PCI endpoint test device {default: /dev/pci-endpoint-test.0}\n"
|
||||
"\t-b <bar num> BAR test (bar number between 0..5)\n"
|
||||
"\t-m <msi num> MSI test (msi number between 1..32)\n"
|
||||
"\t-x <msix num> \tMSI-X test (msix number between 1..2048)\n"
|
||||
"\t-i <irq type> \tSet IRQ type (0 - Legacy, 1 - MSI, 2 - MSI-X)\n"
|
||||
"\t-e Clear IRQ\n"
|
||||
"\t-I Get current IRQ type configured\n"
|
||||
"\t-d Use DMA\n"
|
||||
"\t-l Legacy IRQ test\n"
|
||||
"\t-r Read buffer test\n"
|
||||
"\t-w Write buffer test\n"
|
||||
"\t-c Copy buffer test\n"
|
||||
"\t-s <size> Size of buffer {default: 100KB}\n"
|
||||
"\t-h Print this help message\n",
|
||||
argv[0]);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return run_test(test);
|
||||
}
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
#!/bin/sh
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
echo "BAR tests"
|
||||
echo
|
||||
|
||||
bar=0
|
||||
|
||||
while [ $bar -lt 6 ]
|
||||
do
|
||||
pcitest -b $bar
|
||||
bar=`expr $bar + 1`
|
||||
done
|
||||
echo
|
||||
|
||||
echo "Interrupt tests"
|
||||
echo
|
||||
|
||||
pcitest -i 0
|
||||
pcitest -l
|
||||
|
||||
pcitest -i 1
|
||||
msi=1
|
||||
|
||||
while [ $msi -lt 33 ]
|
||||
do
|
||||
pcitest -m $msi
|
||||
msi=`expr $msi + 1`
|
||||
done
|
||||
echo
|
||||
|
||||
pcitest -i 2
|
||||
msix=1
|
||||
|
||||
while [ $msix -lt 2049 ]
|
||||
do
|
||||
pcitest -x $msix
|
||||
msix=`expr $msix + 1`
|
||||
done
|
||||
echo
|
||||
|
||||
echo "Read Tests"
|
||||
echo
|
||||
|
||||
pcitest -i 1
|
||||
|
||||
pcitest -r -s 1
|
||||
pcitest -r -s 1024
|
||||
pcitest -r -s 1025
|
||||
pcitest -r -s 1024000
|
||||
pcitest -r -s 1024001
|
||||
echo
|
||||
|
||||
echo "Write Tests"
|
||||
echo
|
||||
|
||||
pcitest -w -s 1
|
||||
pcitest -w -s 1024
|
||||
pcitest -w -s 1025
|
||||
pcitest -w -s 1024000
|
||||
pcitest -w -s 1024001
|
||||
echo
|
||||
|
||||
echo "Copy Tests"
|
||||
echo
|
||||
|
||||
pcitest -c -s 1
|
||||
pcitest -c -s 1024
|
||||
pcitest -c -s 1025
|
||||
pcitest -c -s 1024000
|
||||
pcitest -c -s 1024001
|
||||
echo
|
||||
|
|
@ -72,6 +72,7 @@ TARGETS += net/packetdrill
|
|||
TARGETS += net/rds
|
||||
TARGETS += net/tcp_ao
|
||||
TARGETS += nsfs
|
||||
TARGETS += pci_endpoint
|
||||
TARGETS += pcie_bwctrl
|
||||
TARGETS += perf_events
|
||||
TARGETS += pidfd
|
||||
|
|
|
|||
2
tools/testing/selftests/pci_endpoint/.gitignore
vendored
Normal file
2
tools/testing/selftests/pci_endpoint/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
pci_endpoint_test
|
||||
7
tools/testing/selftests/pci_endpoint/Makefile
Normal file
7
tools/testing/selftests/pci_endpoint/Makefile
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
CFLAGS += -O2 -Wl,-no-as-needed -Wall $(KHDR_INCLUDES)
|
||||
LDFLAGS += -lrt -lpthread -lm
|
||||
|
||||
TEST_GEN_PROGS = pci_endpoint_test
|
||||
|
||||
include ../lib.mk
|
||||
4
tools/testing/selftests/pci_endpoint/config
Normal file
4
tools/testing/selftests/pci_endpoint/config
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
CONFIG_PCI_ENDPOINT=y
|
||||
CONFIG_PCI_ENDPOINT_CONFIGFS=y
|
||||
CONFIG_PCI_EPF_TEST=m
|
||||
CONFIG_PCI_ENDPOINT_TEST=m
|
||||
221
tools/testing/selftests/pci_endpoint/pci_endpoint_test.c
Normal file
221
tools/testing/selftests/pci_endpoint/pci_endpoint_test.c
Normal file
|
|
@ -0,0 +1,221 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Kselftest for PCI Endpoint Subsystem
|
||||
*
|
||||
* Copyright (c) 2022 Samsung Electronics Co., Ltd.
|
||||
* https://www.samsung.com
|
||||
* Author: Aman Gupta <aman1.gupta@samsung.com>
|
||||
*
|
||||
* Copyright (c) 2024, Linaro Ltd.
|
||||
* Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "../../../../include/uapi/linux/pcitest.h"
|
||||
|
||||
#include "../kselftest_harness.h"
|
||||
|
||||
#define pci_ep_ioctl(cmd, arg) \
|
||||
({ \
|
||||
ret = ioctl(self->fd, cmd, arg); \
|
||||
ret = ret < 0 ? -errno : 0; \
|
||||
})
|
||||
|
||||
static const char *test_device = "/dev/pci-endpoint-test.0";
|
||||
static const unsigned long test_size[5] = { 1, 1024, 1025, 1024000, 1024001 };
|
||||
|
||||
FIXTURE(pci_ep_bar)
|
||||
{
|
||||
int fd;
|
||||
};
|
||||
|
||||
FIXTURE_SETUP(pci_ep_bar)
|
||||
{
|
||||
self->fd = open(test_device, O_RDWR);
|
||||
|
||||
ASSERT_NE(-1, self->fd) TH_LOG("Can't open PCI Endpoint Test device");
|
||||
}
|
||||
|
||||
FIXTURE_TEARDOWN(pci_ep_bar)
|
||||
{
|
||||
close(self->fd);
|
||||
}
|
||||
|
||||
FIXTURE_VARIANT(pci_ep_bar)
|
||||
{
|
||||
int barno;
|
||||
};
|
||||
|
||||
FIXTURE_VARIANT_ADD(pci_ep_bar, BAR0) { .barno = 0 };
|
||||
FIXTURE_VARIANT_ADD(pci_ep_bar, BAR1) { .barno = 1 };
|
||||
FIXTURE_VARIANT_ADD(pci_ep_bar, BAR2) { .barno = 2 };
|
||||
FIXTURE_VARIANT_ADD(pci_ep_bar, BAR3) { .barno = 3 };
|
||||
FIXTURE_VARIANT_ADD(pci_ep_bar, BAR4) { .barno = 4 };
|
||||
FIXTURE_VARIANT_ADD(pci_ep_bar, BAR5) { .barno = 5 };
|
||||
|
||||
TEST_F(pci_ep_bar, BAR_TEST)
|
||||
{
|
||||
int ret;
|
||||
|
||||
pci_ep_ioctl(PCITEST_BAR, variant->barno);
|
||||
EXPECT_FALSE(ret) TH_LOG("Test failed for BAR%d", variant->barno);
|
||||
}
|
||||
|
||||
FIXTURE(pci_ep_basic)
|
||||
{
|
||||
int fd;
|
||||
};
|
||||
|
||||
FIXTURE_SETUP(pci_ep_basic)
|
||||
{
|
||||
self->fd = open(test_device, O_RDWR);
|
||||
|
||||
ASSERT_NE(-1, self->fd) TH_LOG("Can't open PCI Endpoint Test device");
|
||||
}
|
||||
|
||||
FIXTURE_TEARDOWN(pci_ep_basic)
|
||||
{
|
||||
close(self->fd);
|
||||
}
|
||||
|
||||
TEST_F(pci_ep_basic, CONSECUTIVE_BAR_TEST)
|
||||
{
|
||||
int ret;
|
||||
|
||||
pci_ep_ioctl(PCITEST_BARS, 0);
|
||||
EXPECT_FALSE(ret) TH_LOG("Consecutive BAR test failed");
|
||||
}
|
||||
|
||||
TEST_F(pci_ep_basic, LEGACY_IRQ_TEST)
|
||||
{
|
||||
int ret;
|
||||
|
||||
pci_ep_ioctl(PCITEST_SET_IRQTYPE, 0);
|
||||
ASSERT_EQ(0, ret) TH_LOG("Can't set Legacy IRQ type");
|
||||
|
||||
pci_ep_ioctl(PCITEST_LEGACY_IRQ, 0);
|
||||
EXPECT_FALSE(ret) TH_LOG("Test failed for Legacy IRQ");
|
||||
}
|
||||
|
||||
TEST_F(pci_ep_basic, MSI_TEST)
|
||||
{
|
||||
int ret, i;
|
||||
|
||||
pci_ep_ioctl(PCITEST_SET_IRQTYPE, 1);
|
||||
ASSERT_EQ(0, ret) TH_LOG("Can't set MSI IRQ type");
|
||||
|
||||
for (i = 1; i <= 32; i++) {
|
||||
pci_ep_ioctl(PCITEST_MSI, i);
|
||||
EXPECT_FALSE(ret) TH_LOG("Test failed for MSI%d", i);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(pci_ep_basic, MSIX_TEST)
|
||||
{
|
||||
int ret, i;
|
||||
|
||||
pci_ep_ioctl(PCITEST_SET_IRQTYPE, 2);
|
||||
ASSERT_EQ(0, ret) TH_LOG("Can't set MSI-X IRQ type");
|
||||
|
||||
for (i = 1; i <= 2048; i++) {
|
||||
pci_ep_ioctl(PCITEST_MSIX, i);
|
||||
EXPECT_FALSE(ret) TH_LOG("Test failed for MSI-X%d", i);
|
||||
}
|
||||
}
|
||||
|
||||
FIXTURE(pci_ep_data_transfer)
|
||||
{
|
||||
int fd;
|
||||
};
|
||||
|
||||
FIXTURE_SETUP(pci_ep_data_transfer)
|
||||
{
|
||||
self->fd = open(test_device, O_RDWR);
|
||||
|
||||
ASSERT_NE(-1, self->fd) TH_LOG("Can't open PCI Endpoint Test device");
|
||||
}
|
||||
|
||||
FIXTURE_TEARDOWN(pci_ep_data_transfer)
|
||||
{
|
||||
close(self->fd);
|
||||
}
|
||||
|
||||
FIXTURE_VARIANT(pci_ep_data_transfer)
|
||||
{
|
||||
bool use_dma;
|
||||
};
|
||||
|
||||
FIXTURE_VARIANT_ADD(pci_ep_data_transfer, memcpy)
|
||||
{
|
||||
.use_dma = false,
|
||||
};
|
||||
|
||||
FIXTURE_VARIANT_ADD(pci_ep_data_transfer, dma)
|
||||
{
|
||||
.use_dma = true,
|
||||
};
|
||||
|
||||
TEST_F(pci_ep_data_transfer, READ_TEST)
|
||||
{
|
||||
struct pci_endpoint_test_xfer_param param = {};
|
||||
int ret, i;
|
||||
|
||||
if (variant->use_dma)
|
||||
param.flags = PCITEST_FLAGS_USE_DMA;
|
||||
|
||||
pci_ep_ioctl(PCITEST_SET_IRQTYPE, 1);
|
||||
ASSERT_EQ(0, ret) TH_LOG("Can't set MSI IRQ type");
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(test_size); i++) {
|
||||
param.size = test_size[i];
|
||||
pci_ep_ioctl(PCITEST_READ, ¶m);
|
||||
EXPECT_FALSE(ret) TH_LOG("Test failed for size (%ld)",
|
||||
test_size[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(pci_ep_data_transfer, WRITE_TEST)
|
||||
{
|
||||
struct pci_endpoint_test_xfer_param param = {};
|
||||
int ret, i;
|
||||
|
||||
if (variant->use_dma)
|
||||
param.flags = PCITEST_FLAGS_USE_DMA;
|
||||
|
||||
pci_ep_ioctl(PCITEST_SET_IRQTYPE, 1);
|
||||
ASSERT_EQ(0, ret) TH_LOG("Can't set MSI IRQ type");
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(test_size); i++) {
|
||||
param.size = test_size[i];
|
||||
pci_ep_ioctl(PCITEST_WRITE, ¶m);
|
||||
EXPECT_FALSE(ret) TH_LOG("Test failed for size (%ld)",
|
||||
test_size[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(pci_ep_data_transfer, COPY_TEST)
|
||||
{
|
||||
struct pci_endpoint_test_xfer_param param = {};
|
||||
int ret, i;
|
||||
|
||||
if (variant->use_dma)
|
||||
param.flags = PCITEST_FLAGS_USE_DMA;
|
||||
|
||||
pci_ep_ioctl(PCITEST_SET_IRQTYPE, 1);
|
||||
ASSERT_EQ(0, ret) TH_LOG("Can't set MSI IRQ type");
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(test_size); i++) {
|
||||
param.size = test_size[i];
|
||||
pci_ep_ioctl(PCITEST_COPY, ¶m);
|
||||
EXPECT_FALSE(ret) TH_LOG("Test failed for size (%ld)",
|
||||
test_size[i]);
|
||||
}
|
||||
}
|
||||
TEST_HARNESS_MAIN
|
||||
Loading…
Reference in New Issue
Block a user