Commit 7f837a26 authored by Bjorn Helgaas's avatar Bjorn Helgaas
Browse files

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
parents 63e6f0df 61ae7f86
Loading
Loading
Loading
Loading
+131 −13
Original line number Diff line number Diff line
@@ -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");