Skip to content

Commit cc28c0e

Browse files
committed
Merge branch 'pci/endpoint-test'
- Fix endpoint BAR testing so the test can skip disabled BARs instead of reporting them as failures (Niklas Cassel) - Verify that pci_endpoint interrupt tests set the correct IRQ type (Kunihiko Hayashi) - Fix interpretation of pci_endpoint_test_bars_read_bar() error returns (Niklas Cassel) - Fix potential string truncation in pci_endpoint_test_probe() (Niklas Cassel) - Increase endpoint test BAR size variable to accommodate BARs larger than INT_MAX (Niklas Cassel) - Release IRQs to avoid leak in pci_endpoint interrupt tests (Kunihiko Hayashi) - Log the correct IRQ type when pci_endpoint IRQ request test fails (Kunihiko Hayashi) - Remove pci_endpoint_test irq_type and no_msi globals; instead use test->irq_type (Kunihiko Hayashi) - Remove unnecessary use of managed IRQ functions in pci_endpoint_test (Kunihiko Hayashi) - Add and use IRQ_TYPE_* defines in pci_endpoint_test (Niklas Cassel) - Add struct pci_epc_features.intx_capable and note that RK3568 and RK3588 can't raise INTx interrupts (Niklas Cassel) - Expose supported IRQ types in CAPS so pci_endpoint_test can set appropriate type (Niklas Cassel) - Add PCITEST_IRQ_TYPE_AUTO to pci_endpoint_test for cases where the IRQ type doesn't matter (Niklas Cassel) * pci/endpoint-test: misc: pci_endpoint_test: Add support for PCITEST_IRQ_TYPE_AUTO PCI: endpoint: pci-epf-test: Expose supported IRQ types in CAPS register PCI: dw-rockchip: Endpoint mode cannot raise INTx interrupts PCI: endpoint: Add intx_capable to epc_features struct selftests: pci_endpoint: Use IRQ_TYPE_* defines from UAPI header misc: pci_endpoint_test: Use IRQ_TYPE_* defines from UAPI header PCI: endpoint: pcitest: Add IRQ_TYPE_* defines to UAPI header misc: pci_endpoint_test: Do not use managed IRQ functions misc: pci_endpoint_test: Remove global 'irq_type' and 'no_msi' misc: pci_endpoint_test: Fix 'irq_type' to convey the correct type misc: pci_endpoint_test: Fix displaying 'irq_type' after 'request_irq' error misc: pci_endpoint_test: Avoid issue of interrupts remaining after request_irq error misc: pci_endpoint_test: Handle BAR sizes larger than INT_MAX misc: pci_endpoint_test: Give disabled BARs a distinct error code misc: pci_endpoint_test: Fix potential truncation in pci_endpoint_test_probe() misc: pci_endpoint_test: Fix pci_endpoint_test_bars_read_bar() error handling selftests: pci_endpoint: Add GET_IRQTYPE checks to each interrupt test selftests: pci_endpoint: Skip disabled BARs
2 parents a113afb + 08818c6 commit cc28c0e

File tree

6 files changed

+113
-70
lines changed

6 files changed

+113
-70
lines changed

drivers/misc/pci_endpoint_test.c

Lines changed: 70 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,6 @@
2828

2929
#define DRV_MODULE_NAME "pci-endpoint-test"
3030

31-
#define IRQ_TYPE_UNDEFINED -1
32-
#define IRQ_TYPE_INTX 0
33-
#define IRQ_TYPE_MSI 1
34-
#define IRQ_TYPE_MSIX 2
35-
3631
#define PCI_ENDPOINT_TEST_MAGIC 0x0
3732

3833
#define PCI_ENDPOINT_TEST_COMMAND 0x4
@@ -71,6 +66,9 @@
7166

7267
#define PCI_ENDPOINT_TEST_CAPS 0x30
7368
#define CAP_UNALIGNED_ACCESS BIT(0)
69+
#define CAP_MSI BIT(1)
70+
#define CAP_MSIX BIT(2)
71+
#define CAP_INTX BIT(3)
7472

7573
#define PCI_DEVICE_ID_TI_AM654 0xb00c
7674
#define PCI_DEVICE_ID_TI_J7200 0xb00f
@@ -96,14 +94,6 @@ static DEFINE_IDA(pci_endpoint_test_ida);
9694
#define to_endpoint_test(priv) container_of((priv), struct pci_endpoint_test, \
9795
miscdev)
9896

99-
static bool no_msi;
100-
module_param(no_msi, bool, 0444);
101-
MODULE_PARM_DESC(no_msi, "Disable MSI interrupt in pci_endpoint_test");
102-
103-
static int irq_type = IRQ_TYPE_MSI;
104-
module_param(irq_type, int, 0444);
105-
MODULE_PARM_DESC(irq_type, "IRQ mode selection in pci_endpoint_test (0 - Legacy, 1 - MSI, 2 - MSI-X)");
106-
10797
enum pci_barno {
10898
BAR_0,
10999
BAR_1,
@@ -126,6 +116,7 @@ struct pci_endpoint_test {
126116
struct miscdevice miscdev;
127117
enum pci_barno test_reg_bar;
128118
size_t alignment;
119+
u32 ep_caps;
129120
const char *name;
130121
};
131122

@@ -166,7 +157,7 @@ static void pci_endpoint_test_free_irq_vectors(struct pci_endpoint_test *test)
166157
struct pci_dev *pdev = test->pdev;
167158

168159
pci_free_irq_vectors(pdev);
169-
test->irq_type = IRQ_TYPE_UNDEFINED;
160+
test->irq_type = PCITEST_IRQ_TYPE_UNDEFINED;
170161
}
171162

172163
static int pci_endpoint_test_alloc_irq_vectors(struct pci_endpoint_test *test,
@@ -177,23 +168,23 @@ static int pci_endpoint_test_alloc_irq_vectors(struct pci_endpoint_test *test,
177168
struct device *dev = &pdev->dev;
178169

179170
switch (type) {
180-
case IRQ_TYPE_INTX:
171+
case PCITEST_IRQ_TYPE_INTX:
181172
irq = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_INTX);
182173
if (irq < 0) {
183174
dev_err(dev, "Failed to get Legacy interrupt\n");
184175
return irq;
185176
}
186177

187178
break;
188-
case IRQ_TYPE_MSI:
179+
case PCITEST_IRQ_TYPE_MSI:
189180
irq = pci_alloc_irq_vectors(pdev, 1, 32, PCI_IRQ_MSI);
190181
if (irq < 0) {
191182
dev_err(dev, "Failed to get MSI interrupts\n");
192183
return irq;
193184
}
194185

195186
break;
196-
case IRQ_TYPE_MSIX:
187+
case PCITEST_IRQ_TYPE_MSIX:
197188
irq = pci_alloc_irq_vectors(pdev, 1, 2048, PCI_IRQ_MSIX);
198189
if (irq < 0) {
199190
dev_err(dev, "Failed to get MSI-X interrupts\n");
@@ -216,10 +207,9 @@ static void pci_endpoint_test_release_irq(struct pci_endpoint_test *test)
216207
{
217208
int i;
218209
struct pci_dev *pdev = test->pdev;
219-
struct device *dev = &pdev->dev;
220210

221211
for (i = 0; i < test->num_irqs; i++)
222-
devm_free_irq(dev, pci_irq_vector(pdev, i), test);
212+
free_irq(pci_irq_vector(pdev, i), test);
223213

224214
test->num_irqs = 0;
225215
}
@@ -232,33 +222,36 @@ static int pci_endpoint_test_request_irq(struct pci_endpoint_test *test)
232222
struct device *dev = &pdev->dev;
233223

234224
for (i = 0; i < test->num_irqs; i++) {
235-
ret = devm_request_irq(dev, pci_irq_vector(pdev, i),
236-
pci_endpoint_test_irqhandler,
237-
IRQF_SHARED, test->name, test);
225+
ret = request_irq(pci_irq_vector(pdev, i),
226+
pci_endpoint_test_irqhandler, IRQF_SHARED,
227+
test->name, test);
238228
if (ret)
239229
goto fail;
240230
}
241231

242232
return 0;
243233

244234
fail:
245-
switch (irq_type) {
246-
case IRQ_TYPE_INTX:
235+
switch (test->irq_type) {
236+
case PCITEST_IRQ_TYPE_INTX:
247237
dev_err(dev, "Failed to request IRQ %d for Legacy\n",
248238
pci_irq_vector(pdev, i));
249239
break;
250-
case IRQ_TYPE_MSI:
240+
case PCITEST_IRQ_TYPE_MSI:
251241
dev_err(dev, "Failed to request IRQ %d for MSI %d\n",
252242
pci_irq_vector(pdev, i),
253243
i + 1);
254244
break;
255-
case IRQ_TYPE_MSIX:
245+
case PCITEST_IRQ_TYPE_MSIX:
256246
dev_err(dev, "Failed to request IRQ %d for MSI-X %d\n",
257247
pci_irq_vector(pdev, i),
258248
i + 1);
259249
break;
260250
}
261251

252+
test->num_irqs = i;
253+
pci_endpoint_test_release_irq(test);
254+
262255
return ret;
263256
}
264257

@@ -272,9 +265,9 @@ static const u32 bar_test_pattern[] = {
272265
};
273266

274267
static int pci_endpoint_test_bar_memcmp(struct pci_endpoint_test *test,
275-
enum pci_barno barno, int offset,
276-
void *write_buf, void *read_buf,
277-
int size)
268+
enum pci_barno barno,
269+
resource_size_t offset, void *write_buf,
270+
void *read_buf, int size)
278271
{
279272
memset(write_buf, bar_test_pattern[barno], size);
280273
memcpy_toio(test->bar[barno] + offset, write_buf, size);
@@ -287,16 +280,19 @@ static int pci_endpoint_test_bar_memcmp(struct pci_endpoint_test *test,
287280
static int pci_endpoint_test_bar(struct pci_endpoint_test *test,
288281
enum pci_barno barno)
289282
{
290-
int j, bar_size, buf_size, iters;
283+
resource_size_t bar_size, offset = 0;
291284
void *write_buf __free(kfree) = NULL;
292285
void *read_buf __free(kfree) = NULL;
293286
struct pci_dev *pdev = test->pdev;
287+
int buf_size;
288+
289+
bar_size = pci_resource_len(pdev, barno);
290+
if (!bar_size)
291+
return -ENODATA;
294292

295293
if (!test->bar[barno])
296294
return -ENOMEM;
297295

298-
bar_size = pci_resource_len(pdev, barno);
299-
300296
if (barno == test->test_reg_bar)
301297
bar_size = 0x4;
302298

@@ -314,11 +310,12 @@ static int pci_endpoint_test_bar(struct pci_endpoint_test *test,
314310
if (!read_buf)
315311
return -ENOMEM;
316312

317-
iters = bar_size / buf_size;
318-
for (j = 0; j < iters; j++)
319-
if (pci_endpoint_test_bar_memcmp(test, barno, buf_size * j,
320-
write_buf, read_buf, buf_size))
313+
while (offset < bar_size) {
314+
if (pci_endpoint_test_bar_memcmp(test, barno, offset, write_buf,
315+
read_buf, buf_size))
321316
return -EIO;
317+
offset += buf_size;
318+
}
322319

323320
return 0;
324321
}
@@ -382,7 +379,7 @@ static int pci_endpoint_test_bars_read_bar(struct pci_endpoint_test *test,
382379
static int pci_endpoint_test_bars(struct pci_endpoint_test *test)
383380
{
384381
enum pci_barno bar;
385-
bool ret;
382+
int ret;
386383

387384
/* Write all BARs in order (without reading). */
388385
for (bar = 0; bar < PCI_STD_NUM_BARS; bar++)
@@ -398,7 +395,7 @@ static int pci_endpoint_test_bars(struct pci_endpoint_test *test)
398395
for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) {
399396
if (test->bar[bar]) {
400397
ret = pci_endpoint_test_bars_read_bar(test, bar);
401-
if (!ret)
398+
if (ret)
402399
return ret;
403400
}
404401
}
@@ -411,7 +408,7 @@ static int pci_endpoint_test_intx_irq(struct pci_endpoint_test *test)
411408
u32 val;
412409

413410
pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE,
414-
IRQ_TYPE_INTX);
411+
PCITEST_IRQ_TYPE_INTX);
415412
pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 0);
416413
pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
417414
COMMAND_RAISE_INTX_IRQ);
@@ -431,7 +428,8 @@ static int pci_endpoint_test_msi_irq(struct pci_endpoint_test *test,
431428
int ret;
432429

433430
pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE,
434-
msix ? IRQ_TYPE_MSIX : IRQ_TYPE_MSI);
431+
msix ? PCITEST_IRQ_TYPE_MSIX :
432+
PCITEST_IRQ_TYPE_MSI);
435433
pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, msi_num);
436434
pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
437435
msix ? COMMAND_RAISE_MSIX_IRQ :
@@ -507,7 +505,8 @@ static int pci_endpoint_test_copy(struct pci_endpoint_test *test,
507505
if (use_dma)
508506
flags |= FLAG_USE_DMA;
509507

510-
if (irq_type < IRQ_TYPE_INTX || irq_type > IRQ_TYPE_MSIX) {
508+
if (irq_type < PCITEST_IRQ_TYPE_INTX ||
509+
irq_type > PCITEST_IRQ_TYPE_MSIX) {
511510
dev_err(dev, "Invalid IRQ type option\n");
512511
return -EINVAL;
513512
}
@@ -639,7 +638,8 @@ static int pci_endpoint_test_write(struct pci_endpoint_test *test,
639638
if (use_dma)
640639
flags |= FLAG_USE_DMA;
641640

642-
if (irq_type < IRQ_TYPE_INTX || irq_type > IRQ_TYPE_MSIX) {
641+
if (irq_type < PCITEST_IRQ_TYPE_INTX ||
642+
irq_type > PCITEST_IRQ_TYPE_MSIX) {
643643
dev_err(dev, "Invalid IRQ type option\n");
644644
return -EINVAL;
645645
}
@@ -735,7 +735,8 @@ static int pci_endpoint_test_read(struct pci_endpoint_test *test,
735735
if (use_dma)
736736
flags |= FLAG_USE_DMA;
737737

738-
if (irq_type < IRQ_TYPE_INTX || irq_type > IRQ_TYPE_MSIX) {
738+
if (irq_type < PCITEST_IRQ_TYPE_INTX ||
739+
irq_type > PCITEST_IRQ_TYPE_MSIX) {
739740
dev_err(dev, "Invalid IRQ type option\n");
740741
return -EINVAL;
741742
}
@@ -805,11 +806,24 @@ static int pci_endpoint_test_set_irq(struct pci_endpoint_test *test,
805806
struct device *dev = &pdev->dev;
806807
int ret;
807808

808-
if (req_irq_type < IRQ_TYPE_INTX || req_irq_type > IRQ_TYPE_MSIX) {
809+
if (req_irq_type < PCITEST_IRQ_TYPE_INTX ||
810+
req_irq_type > PCITEST_IRQ_TYPE_AUTO) {
809811
dev_err(dev, "Invalid IRQ type option\n");
810812
return -EINVAL;
811813
}
812814

815+
if (req_irq_type == PCITEST_IRQ_TYPE_AUTO) {
816+
if (test->ep_caps & CAP_MSI)
817+
req_irq_type = PCITEST_IRQ_TYPE_MSI;
818+
else if (test->ep_caps & CAP_MSIX)
819+
req_irq_type = PCITEST_IRQ_TYPE_MSIX;
820+
else if (test->ep_caps & CAP_INTX)
821+
req_irq_type = PCITEST_IRQ_TYPE_INTX;
822+
else
823+
/* fallback to MSI if no caps defined */
824+
req_irq_type = PCITEST_IRQ_TYPE_MSI;
825+
}
826+
813827
if (test->irq_type == req_irq_type)
814828
return 0;
815829

@@ -874,7 +888,7 @@ static long pci_endpoint_test_ioctl(struct file *file, unsigned int cmd,
874888
ret = pci_endpoint_test_set_irq(test, arg);
875889
break;
876890
case PCITEST_GET_IRQTYPE:
877-
ret = irq_type;
891+
ret = test->irq_type;
878892
break;
879893
case PCITEST_CLEAR_IRQ:
880894
ret = pci_endpoint_test_clear_irq(test);
@@ -895,13 +909,12 @@ static void pci_endpoint_test_get_capabilities(struct pci_endpoint_test *test)
895909
{
896910
struct pci_dev *pdev = test->pdev;
897911
struct device *dev = &pdev->dev;
898-
u32 caps;
899912

900-
caps = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_CAPS);
901-
dev_dbg(dev, "PCI_ENDPOINT_TEST_CAPS: %#x\n", caps);
913+
test->ep_caps = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_CAPS);
914+
dev_dbg(dev, "PCI_ENDPOINT_TEST_CAPS: %#x\n", test->ep_caps);
902915

903916
/* CAP_UNALIGNED_ACCESS is set if the EP can do unaligned access */
904-
if (caps & CAP_UNALIGNED_ACCESS)
917+
if (test->ep_caps & CAP_UNALIGNED_ACCESS)
905918
test->alignment = 0;
906919
}
907920

@@ -910,7 +923,7 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
910923
{
911924
int ret;
912925
int id;
913-
char name[24];
926+
char name[29];
914927
enum pci_barno bar;
915928
void __iomem *base;
916929
struct device *dev = &pdev->dev;
@@ -929,17 +942,14 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
929942
test->test_reg_bar = 0;
930943
test->alignment = 0;
931944
test->pdev = pdev;
932-
test->irq_type = IRQ_TYPE_UNDEFINED;
933-
934-
if (no_msi)
935-
irq_type = IRQ_TYPE_INTX;
945+
test->irq_type = PCITEST_IRQ_TYPE_UNDEFINED;
936946

937947
data = (struct pci_endpoint_test_data *)ent->driver_data;
938948
if (data) {
939949
test_reg_bar = data->test_reg_bar;
940950
test->test_reg_bar = test_reg_bar;
941951
test->alignment = data->alignment;
942-
irq_type = data->irq_type;
952+
test->irq_type = data->irq_type;
943953
}
944954

945955
init_completion(&test->irq_raised);
@@ -961,7 +971,7 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
961971

962972
pci_set_master(pdev);
963973

964-
ret = pci_endpoint_test_alloc_irq_vectors(test, irq_type);
974+
ret = pci_endpoint_test_alloc_irq_vectors(test, test->irq_type);
965975
if (ret)
966976
goto err_disable_irq;
967977

@@ -1083,23 +1093,23 @@ static void pci_endpoint_test_remove(struct pci_dev *pdev)
10831093
static const struct pci_endpoint_test_data default_data = {
10841094
.test_reg_bar = BAR_0,
10851095
.alignment = SZ_4K,
1086-
.irq_type = IRQ_TYPE_MSI,
1096+
.irq_type = PCITEST_IRQ_TYPE_MSI,
10871097
};
10881098

10891099
static const struct pci_endpoint_test_data am654_data = {
10901100
.test_reg_bar = BAR_2,
10911101
.alignment = SZ_64K,
1092-
.irq_type = IRQ_TYPE_MSI,
1102+
.irq_type = PCITEST_IRQ_TYPE_MSI,
10931103
};
10941104

10951105
static const struct pci_endpoint_test_data j721e_data = {
10961106
.alignment = 256,
1097-
.irq_type = IRQ_TYPE_MSI,
1107+
.irq_type = PCITEST_IRQ_TYPE_MSI,
10981108
};
10991109

11001110
static const struct pci_endpoint_test_data rk3588_data = {
11011111
.alignment = SZ_64K,
1102-
.irq_type = IRQ_TYPE_MSI,
1112+
.irq_type = PCITEST_IRQ_TYPE_MSI,
11031113
};
11041114

11051115
/*

drivers/pci/controller/dwc/pcie-dw-rockchip.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,7 @@ static const struct pci_epc_features rockchip_pcie_epc_features_rk3568 = {
272272
.linkup_notifier = true,
273273
.msi_capable = true,
274274
.msix_capable = true,
275+
.intx_capable = false,
275276
.align = SZ_64K,
276277
.bar[BAR_0] = { .type = BAR_RESIZABLE, },
277278
.bar[BAR_1] = { .type = BAR_RESIZABLE, },
@@ -292,6 +293,7 @@ static const struct pci_epc_features rockchip_pcie_epc_features_rk3588 = {
292293
.linkup_notifier = true,
293294
.msi_capable = true,
294295
.msix_capable = true,
296+
.intx_capable = false,
295297
.align = SZ_64K,
296298
.bar[BAR_0] = { .type = BAR_RESIZABLE, },
297299
.bar[BAR_1] = { .type = BAR_RESIZABLE, },

0 commit comments

Comments
 (0)