Merge branch 'pci/endpoint/epf-vntb'

- Return -ENOENT (not -1) if pci_epc_get_next_free_bar() fails (Jerome
  Brunet)

- Align MW (memory window) naming with config names (Jerome Brunet)

- Allow BAR assignment via configfs so platforms have flexibility in
  determining BAR usage (Jerome Brunet)

- Drop incorrect '__iomem' annotation on the return value of
  pci_epf_alloc_space(); this also fixes an sparse warning (Manivannan
  Sadhasivam)

* pci/endpoint/epf-vntb:
  PCI: endpoint: pci-epf-vntb: Fix the incorrect usage of __iomem attribute
  PCI: endpoint: pci-epf-vntb: Allow BAR assignment via configfs
  PCI: endpoint: pci-epf-vntb: Align MW naming with config names
  PCI: endpoint: pci-epf-vntb: Return -ENOENT if pci_epc_get_next_free_bar() fails
This commit is contained in:
Bjorn Helgaas 2025-07-31 16:11:46 -05:00
commit 7f837a2648

View file

@ -70,9 +70,11 @@ static struct workqueue_struct *kpcintb_workqueue;
enum epf_ntb_bar {
BAR_CONFIG,
BAR_DB,
BAR_MW0,
BAR_MW1,
BAR_MW2,
BAR_MW3,
BAR_MW4,
VNTB_BAR_NUM,
};
/*
@ -132,7 +134,7 @@ struct epf_ntb {
bool linkup;
u32 spad_size;
enum pci_barno epf_ntb_bar[6];
enum pci_barno epf_ntb_bar[VNTB_BAR_NUM];
struct epf_ntb_ctrl *reg;
@ -510,7 +512,7 @@ static int epf_ntb_db_bar_init(struct epf_ntb *ntb)
struct device *dev = &ntb->epf->dev;
int ret;
struct pci_epf_bar *epf_bar;
void __iomem *mw_addr;
void *mw_addr;
enum pci_barno barno;
size_t size = sizeof(u32) * ntb->db_count;
@ -576,7 +578,7 @@ static int epf_ntb_mw_bar_init(struct epf_ntb *ntb)
for (i = 0; i < ntb->num_mws; i++) {
size = ntb->mws_size[i];
barno = ntb->epf_ntb_bar[BAR_MW0 + i];
barno = ntb->epf_ntb_bar[BAR_MW1 + i];
ntb->epf->bar[barno].barno = barno;
ntb->epf->bar[barno].size = size;
@ -629,7 +631,7 @@ static void epf_ntb_mw_bar_clear(struct epf_ntb *ntb, int num_mws)
int i;
for (i = 0; i < num_mws; i++) {
barno = ntb->epf_ntb_bar[BAR_MW0 + i];
barno = ntb->epf_ntb_bar[BAR_MW1 + i];
pci_epc_clear_bar(ntb->epf->epc,
ntb->epf->func_no,
ntb->epf->vfunc_no,
@ -654,6 +656,63 @@ static void epf_ntb_epc_destroy(struct epf_ntb *ntb)
pci_epc_put(ntb->epf->epc);
}
/**
* epf_ntb_is_bar_used() - Check if a bar is used in the ntb configuration
* @ntb: NTB device that facilitates communication between HOST and VHOST
* @barno: Checked bar number
*
* Returns: true if used, false if free.
*/
static bool epf_ntb_is_bar_used(struct epf_ntb *ntb,
enum pci_barno barno)
{
int i;
for (i = 0; i < VNTB_BAR_NUM; i++) {
if (ntb->epf_ntb_bar[i] == barno)
return true;
}
return false;
}
/**
* epf_ntb_find_bar() - Assign BAR number when no configuration is provided
* @ntb: NTB device that facilitates communication between HOST and VHOST
* @epc_features: The features provided by the EPC specific to this EPF
* @bar: NTB BAR index
* @barno: Bar start index
*
* When the BAR configuration was not provided through the userspace
* configuration, automatically assign BAR as it has been historically
* done by this endpoint function.
*
* Returns: the BAR number found, if any. -1 otherwise
*/
static int epf_ntb_find_bar(struct epf_ntb *ntb,
const struct pci_epc_features *epc_features,
enum epf_ntb_bar bar,
enum pci_barno barno)
{
while (ntb->epf_ntb_bar[bar] < 0) {
barno = pci_epc_get_next_free_bar(epc_features, barno);
if (barno < 0)
break; /* No more BAR available */
/*
* Verify if the BAR found is not already assigned
* through the provided configuration
*/
if (!epf_ntb_is_bar_used(ntb, barno))
ntb->epf_ntb_bar[bar] = barno;
barno += 1;
}
return barno;
}
/**
* epf_ntb_init_epc_bar() - Identify BARs to be used for each of the NTB
* constructs (scratchpad region, doorbell, memorywindow)
@ -676,23 +735,21 @@ static int epf_ntb_init_epc_bar(struct epf_ntb *ntb)
epc_features = pci_epc_get_features(ntb->epf->epc, ntb->epf->func_no, ntb->epf->vfunc_no);
/* These are required BARs which are mandatory for NTB functionality */
for (bar = BAR_CONFIG; bar <= BAR_MW0; bar++, barno++) {
barno = pci_epc_get_next_free_bar(epc_features, barno);
for (bar = BAR_CONFIG; bar <= BAR_MW1; bar++) {
barno = epf_ntb_find_bar(ntb, epc_features, bar, barno);
if (barno < 0) {
dev_err(dev, "Fail to get NTB function BAR\n");
return barno;
return -ENOENT;
}
ntb->epf_ntb_bar[bar] = barno;
}
/* These are optional BARs which don't impact NTB functionality */
for (bar = BAR_MW1, i = 1; i < num_mws; bar++, barno++, i++) {
barno = pci_epc_get_next_free_bar(epc_features, barno);
for (bar = BAR_MW1, i = 1; i < num_mws; bar++, i++) {
barno = epf_ntb_find_bar(ntb, epc_features, bar, barno);
if (barno < 0) {
ntb->num_mws = i;
dev_dbg(dev, "BAR not available for > MW%d\n", i + 1);
}
ntb->epf_ntb_bar[bar] = barno;
}
return 0;
@ -860,6 +917,37 @@ static ssize_t epf_ntb_##_name##_store(struct config_item *item, \
return len; \
}
#define EPF_NTB_BAR_R(_name, _id) \
static ssize_t epf_ntb_##_name##_show(struct config_item *item, \
char *page) \
{ \
struct config_group *group = to_config_group(item); \
struct epf_ntb *ntb = to_epf_ntb(group); \
\
return sprintf(page, "%d\n", ntb->epf_ntb_bar[_id]); \
}
#define EPF_NTB_BAR_W(_name, _id) \
static ssize_t epf_ntb_##_name##_store(struct config_item *item, \
const char *page, size_t len) \
{ \
struct config_group *group = to_config_group(item); \
struct epf_ntb *ntb = to_epf_ntb(group); \
int val; \
int ret; \
\
ret = kstrtoint(page, 0, &val); \
if (ret) \
return ret; \
\
if (val < NO_BAR || val > BAR_5) \
return -EINVAL; \
\
ntb->epf_ntb_bar[_id] = val; \
\
return len; \
}
static ssize_t epf_ntb_num_mws_store(struct config_item *item,
const char *page, size_t len)
{
@ -899,6 +987,18 @@ EPF_NTB_MW_R(mw3)
EPF_NTB_MW_W(mw3)
EPF_NTB_MW_R(mw4)
EPF_NTB_MW_W(mw4)
EPF_NTB_BAR_R(ctrl_bar, BAR_CONFIG)
EPF_NTB_BAR_W(ctrl_bar, BAR_CONFIG)
EPF_NTB_BAR_R(db_bar, BAR_DB)
EPF_NTB_BAR_W(db_bar, BAR_DB)
EPF_NTB_BAR_R(mw1_bar, BAR_MW1)
EPF_NTB_BAR_W(mw1_bar, BAR_MW1)
EPF_NTB_BAR_R(mw2_bar, BAR_MW2)
EPF_NTB_BAR_W(mw2_bar, BAR_MW2)
EPF_NTB_BAR_R(mw3_bar, BAR_MW3)
EPF_NTB_BAR_W(mw3_bar, BAR_MW3)
EPF_NTB_BAR_R(mw4_bar, BAR_MW4)
EPF_NTB_BAR_W(mw4_bar, BAR_MW4)
CONFIGFS_ATTR(epf_ntb_, spad_count);
CONFIGFS_ATTR(epf_ntb_, db_count);
@ -910,6 +1010,12 @@ CONFIGFS_ATTR(epf_ntb_, mw4);
CONFIGFS_ATTR(epf_ntb_, vbus_number);
CONFIGFS_ATTR(epf_ntb_, vntb_pid);
CONFIGFS_ATTR(epf_ntb_, vntb_vid);
CONFIGFS_ATTR(epf_ntb_, ctrl_bar);
CONFIGFS_ATTR(epf_ntb_, db_bar);
CONFIGFS_ATTR(epf_ntb_, mw1_bar);
CONFIGFS_ATTR(epf_ntb_, mw2_bar);
CONFIGFS_ATTR(epf_ntb_, mw3_bar);
CONFIGFS_ATTR(epf_ntb_, mw4_bar);
static struct configfs_attribute *epf_ntb_attrs[] = {
&epf_ntb_attr_spad_count,
@ -922,6 +1028,12 @@ static struct configfs_attribute *epf_ntb_attrs[] = {
&epf_ntb_attr_vbus_number,
&epf_ntb_attr_vntb_pid,
&epf_ntb_attr_vntb_vid,
&epf_ntb_attr_ctrl_bar,
&epf_ntb_attr_db_bar,
&epf_ntb_attr_mw1_bar,
&epf_ntb_attr_mw2_bar,
&epf_ntb_attr_mw3_bar,
&epf_ntb_attr_mw4_bar,
NULL,
};
@ -1048,7 +1160,7 @@ static int vntb_epf_mw_set_trans(struct ntb_dev *ndev, int pidx, int idx,
struct device *dev;
dev = &ntb->ntb.dev;
barno = ntb->epf_ntb_bar[BAR_MW0 + idx];
barno = ntb->epf_ntb_bar[BAR_MW1 + idx];
epf_bar = &ntb->epf->bar[barno];
epf_bar->phys_addr = addr;
epf_bar->barno = barno;
@ -1379,6 +1491,7 @@ static int epf_ntb_probe(struct pci_epf *epf,
{
struct epf_ntb *ntb;
struct device *dev;
int i;
dev = &epf->dev;
@ -1389,6 +1502,11 @@ static int epf_ntb_probe(struct pci_epf *epf,
epf->header = &epf_ntb_header;
ntb->epf = epf;
ntb->vbus_number = 0xff;
/* Initially, no bar is assigned */
for (i = 0; i < VNTB_BAR_NUM; i++)
ntb->epf_ntb_bar[i] = NO_BAR;
epf_set_drvdata(epf, ntb);
dev_info(dev, "pci-ep epf driver loaded\n");