Skip to content

Commit ffcc485

Browse files
floatiousbjorn-helgaas
authored andcommitted
PCI: endpoint: pci-epf-test: Allow overriding default BAR sizes
Add bar{0,1,2,3,4,5}_size attributes in configfs, so that the user is not restricted to run pci-epf-test with the hardcoded BAR size values defined in pci-epf-test.c. This code is shamelessly more or less copy pasted from pci-epf-vntb.c Signed-off-by: Niklas Cassel <cassel@kernel.org> Signed-off-by: Manivannan Sadhasivam <mani@kernel.org> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Tested-by: Koichiro Den <den@valinux.co.jp> Reviewed-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Frank Li <Frank.Li@nxp.com> Link: https://patch.msgid.link/20260130113038.2143947-2-cassel@kernel.org
1 parent c17b904 commit ffcc485

2 files changed

Lines changed: 116 additions & 2 deletions

File tree

Documentation/PCI/endpoint/pci-test-howto.rst

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,25 @@ device, the following commands can be used::
8484
# echo 32 > functions/pci_epf_test/func1/msi_interrupts
8585
# echo 2048 > functions/pci_epf_test/func1/msix_interrupts
8686

87+
By default, pci-epf-test uses the following BAR sizes::
88+
89+
# grep . functions/pci_epf_test/func1/pci_epf_test.0/bar?_size
90+
functions/pci_epf_test/func1/pci_epf_test.0/bar0_size:131072
91+
functions/pci_epf_test/func1/pci_epf_test.0/bar1_size:131072
92+
functions/pci_epf_test/func1/pci_epf_test.0/bar2_size:131072
93+
functions/pci_epf_test/func1/pci_epf_test.0/bar3_size:131072
94+
functions/pci_epf_test/func1/pci_epf_test.0/bar4_size:131072
95+
functions/pci_epf_test/func1/pci_epf_test.0/bar5_size:1048576
96+
97+
The user can override a default value using e.g.::
98+
# echo 1048576 > functions/pci_epf_test/func1/pci_epf_test.0/bar1_size
99+
100+
Overriding the default BAR sizes can only be done before binding the
101+
pci-epf-test device to a PCI endpoint controller driver.
102+
103+
Note: Some endpoint controllers might have fixed-size BARs or reserved BARs;
104+
for such controllers, the corresponding BAR size in configfs will be ignored.
105+
87106

88107
Binding pci-epf-test Device to EP Controller
89108
--------------------------------------------

drivers/pci/endpoint/functions/pci-epf-test.c

Lines changed: 97 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ static struct workqueue_struct *kpcitest_workqueue;
7272
struct pci_epf_test {
7373
void *reg[PCI_STD_NUM_BARS];
7474
struct pci_epf *epf;
75+
struct config_group group;
7576
enum pci_barno test_reg_bar;
7677
size_t msix_table_offset;
7778
struct delayed_work cmd_handler;
@@ -85,6 +86,7 @@ struct pci_epf_test {
8586
bool dma_private;
8687
const struct pci_epc_features *epc_features;
8788
struct pci_epf_bar db_bar;
89+
size_t bar_size[PCI_STD_NUM_BARS];
8890
};
8991

9092
struct pci_epf_test_reg {
@@ -111,7 +113,8 @@ static struct pci_epf_header test_header = {
111113
.interrupt_pin = PCI_INTERRUPT_INTA,
112114
};
113115

114-
static size_t bar_size[] = { 131072, 131072, 131072, 131072, 131072, 1048576 };
116+
/* default BAR sizes, can be overridden by the user using configfs */
117+
static size_t default_bar_size[] = { 131072, 131072, 131072, 131072, 131072, 1048576 };
115118

116119
static void pci_epf_test_dma_callback(void *param)
117120
{
@@ -1240,7 +1243,7 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf)
12401243
if (epc_features->bar[bar].type == BAR_FIXED)
12411244
test_reg_size = epc_features->bar[bar].fixed_size;
12421245
else
1243-
test_reg_size = bar_size[bar];
1246+
test_reg_size = epf_test->bar_size[bar];
12441247

12451248
base = pci_epf_alloc_space(epf, test_reg_size, bar,
12461249
epc_features, PRIMARY_INTERFACE);
@@ -1312,6 +1315,94 @@ static void pci_epf_test_unbind(struct pci_epf *epf)
13121315
pci_epf_test_free_space(epf);
13131316
}
13141317

1318+
#define PCI_EPF_TEST_BAR_SIZE_R(_name, _id) \
1319+
static ssize_t pci_epf_test_##_name##_show(struct config_item *item, \
1320+
char *page) \
1321+
{ \
1322+
struct config_group *group = to_config_group(item); \
1323+
struct pci_epf_test *epf_test = \
1324+
container_of(group, struct pci_epf_test, group); \
1325+
\
1326+
return sysfs_emit(page, "%zu\n", epf_test->bar_size[_id]); \
1327+
}
1328+
1329+
#define PCI_EPF_TEST_BAR_SIZE_W(_name, _id) \
1330+
static ssize_t pci_epf_test_##_name##_store(struct config_item *item, \
1331+
const char *page, \
1332+
size_t len) \
1333+
{ \
1334+
struct config_group *group = to_config_group(item); \
1335+
struct pci_epf_test *epf_test = \
1336+
container_of(group, struct pci_epf_test, group); \
1337+
int val, ret; \
1338+
\
1339+
/* \
1340+
* BAR sizes can only be modified before binding to an EPC, \
1341+
* because pci_epf_test_alloc_space() is called in .bind(). \
1342+
*/ \
1343+
if (epf_test->epf->epc) \
1344+
return -EOPNOTSUPP; \
1345+
\
1346+
ret = kstrtouint(page, 0, &val); \
1347+
if (ret) \
1348+
return ret; \
1349+
\
1350+
if (!is_power_of_2(val)) \
1351+
return -EINVAL; \
1352+
\
1353+
epf_test->bar_size[_id] = val; \
1354+
\
1355+
return len; \
1356+
}
1357+
1358+
PCI_EPF_TEST_BAR_SIZE_R(bar0_size, BAR_0)
1359+
PCI_EPF_TEST_BAR_SIZE_W(bar0_size, BAR_0)
1360+
PCI_EPF_TEST_BAR_SIZE_R(bar1_size, BAR_1)
1361+
PCI_EPF_TEST_BAR_SIZE_W(bar1_size, BAR_1)
1362+
PCI_EPF_TEST_BAR_SIZE_R(bar2_size, BAR_2)
1363+
PCI_EPF_TEST_BAR_SIZE_W(bar2_size, BAR_2)
1364+
PCI_EPF_TEST_BAR_SIZE_R(bar3_size, BAR_3)
1365+
PCI_EPF_TEST_BAR_SIZE_W(bar3_size, BAR_3)
1366+
PCI_EPF_TEST_BAR_SIZE_R(bar4_size, BAR_4)
1367+
PCI_EPF_TEST_BAR_SIZE_W(bar4_size, BAR_4)
1368+
PCI_EPF_TEST_BAR_SIZE_R(bar5_size, BAR_5)
1369+
PCI_EPF_TEST_BAR_SIZE_W(bar5_size, BAR_5)
1370+
1371+
CONFIGFS_ATTR(pci_epf_test_, bar0_size);
1372+
CONFIGFS_ATTR(pci_epf_test_, bar1_size);
1373+
CONFIGFS_ATTR(pci_epf_test_, bar2_size);
1374+
CONFIGFS_ATTR(pci_epf_test_, bar3_size);
1375+
CONFIGFS_ATTR(pci_epf_test_, bar4_size);
1376+
CONFIGFS_ATTR(pci_epf_test_, bar5_size);
1377+
1378+
static struct configfs_attribute *pci_epf_test_attrs[] = {
1379+
&pci_epf_test_attr_bar0_size,
1380+
&pci_epf_test_attr_bar1_size,
1381+
&pci_epf_test_attr_bar2_size,
1382+
&pci_epf_test_attr_bar3_size,
1383+
&pci_epf_test_attr_bar4_size,
1384+
&pci_epf_test_attr_bar5_size,
1385+
NULL,
1386+
};
1387+
1388+
static const struct config_item_type pci_epf_test_group_type = {
1389+
.ct_attrs = pci_epf_test_attrs,
1390+
.ct_owner = THIS_MODULE,
1391+
};
1392+
1393+
static struct config_group *pci_epf_test_add_cfs(struct pci_epf *epf,
1394+
struct config_group *group)
1395+
{
1396+
struct pci_epf_test *epf_test = epf_get_drvdata(epf);
1397+
struct config_group *epf_group = &epf_test->group;
1398+
struct device *dev = &epf->dev;
1399+
1400+
config_group_init_type_name(epf_group, dev_name(dev),
1401+
&pci_epf_test_group_type);
1402+
1403+
return epf_group;
1404+
}
1405+
13151406
static const struct pci_epf_device_id pci_epf_test_ids[] = {
13161407
{
13171408
.name = "pci_epf_test",
@@ -1324,13 +1415,16 @@ static int pci_epf_test_probe(struct pci_epf *epf,
13241415
{
13251416
struct pci_epf_test *epf_test;
13261417
struct device *dev = &epf->dev;
1418+
enum pci_barno bar;
13271419

13281420
epf_test = devm_kzalloc(dev, sizeof(*epf_test), GFP_KERNEL);
13291421
if (!epf_test)
13301422
return -ENOMEM;
13311423

13321424
epf->header = &test_header;
13331425
epf_test->epf = epf;
1426+
for (bar = BAR_0; bar < PCI_STD_NUM_BARS; bar++)
1427+
epf_test->bar_size[bar] = default_bar_size[bar];
13341428

13351429
INIT_DELAYED_WORK(&epf_test->cmd_handler, pci_epf_test_cmd_handler);
13361430

@@ -1343,6 +1437,7 @@ static int pci_epf_test_probe(struct pci_epf *epf,
13431437
static const struct pci_epf_ops ops = {
13441438
.unbind = pci_epf_test_unbind,
13451439
.bind = pci_epf_test_bind,
1440+
.add_cfs = pci_epf_test_add_cfs,
13461441
};
13471442

13481443
static struct pci_epf_driver test_driver = {

0 commit comments

Comments
 (0)