lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251023071916.901355-22-den@valinux.co.jp>
Date: Thu, 23 Oct 2025 16:19:12 +0900
From: Koichiro Den <den@...inux.co.jp>
To: ntb@...ts.linux.dev,
	linux-pci@...r.kernel.org,
	dmaengine@...r.kernel.org,
	linux-kernel@...r.kernel.org
Cc: mani@...nel.org,
	kwilczynski@...nel.org,
	kishon@...nel.org,
	bhelgaas@...gle.com,
	corbet@....net,
	vkoul@...nel.org,
	jdmason@...zu.us,
	dave.jiang@...el.com,
	allenbh@...il.com,
	Basavaraj.Natikar@....com,
	Shyam-sundar.S-k@....com,
	kurt.schwemmer@...rosemi.com,
	logang@...tatee.com,
	jingoohan1@...il.com,
	lpieralisi@...nel.org,
	robh@...nel.org,
	jbrunet@...libre.com,
	Frank.Li@....com,
	fancer.lancer@...il.com,
	arnd@...db.de,
	pstanner@...hat.com,
	elfring@...rs.sourceforge.net
Subject: [RFC PATCH 21/25] NTB: Introduce generic interrupt backend abstraction and convert MSI

Refactor interrupt handling into a new ntb_intr_backend abstraction
layer, and migrate the MSI implementation to use it as a backend. This
enables alternate backends such as DW eDMA test interrupts.

No functional changes.

Signed-off-by: Koichiro Den <den@...inux.co.jp>
---
 drivers/ntb/Kconfig             |   5 ++
 drivers/ntb/Makefile            |   5 +-
 drivers/ntb/intr_common.c       |  55 ++++++++++++
 drivers/ntb/msi.c               | 145 ++++++++++++++++++--------------
 drivers/ntb/ntb_transport.c     |  36 ++++----
 drivers/ntb/test/ntb_msi_test.c |  26 +++---
 include/linux/ntb.h             |  85 ++++++++++++-------
 7 files changed, 231 insertions(+), 126 deletions(-)
 create mode 100644 drivers/ntb/intr_common.c

diff --git a/drivers/ntb/Kconfig b/drivers/ntb/Kconfig
index df16c755b4da..2f22f44245b3 100644
--- a/drivers/ntb/Kconfig
+++ b/drivers/ntb/Kconfig
@@ -13,9 +13,13 @@ menuconfig NTB
 
 if NTB
 
+config NTB_INTR_COMMON
+	bool
+
 config NTB_MSI
 	bool "MSI Interrupt Support"
 	depends on PCI_MSI
+	select NTB_INTR_COMMON
 	help
 	 Support using MSI interrupt forwarding instead of (or in addition to)
 	 hardware doorbells. MSI interrupts typically offer lower latency
@@ -24,6 +28,7 @@ config NTB_MSI
 	 in the hardware driver for creating the MSI interrupts.
 
 	 If unsure, say N.
+
 source "drivers/ntb/hw/Kconfig"
 
 source "drivers/ntb/test/Kconfig"
diff --git a/drivers/ntb/Makefile b/drivers/ntb/Makefile
index 3a6fa181ff99..feaa2a77cbf6 100644
--- a/drivers/ntb/Makefile
+++ b/drivers/ntb/Makefile
@@ -2,5 +2,6 @@
 obj-$(CONFIG_NTB) += ntb.o hw/ test/
 obj-$(CONFIG_NTB_TRANSPORT) += ntb_transport.o
 
-ntb-y			:= core.o
-ntb-$(CONFIG_NTB_MSI)	+= msi.o
+ntb-y				:= core.o
+ntb-$(CONFIG_NTB_INTR_COMMON)	+= intr_common.o
+ntb-$(CONFIG_NTB_MSI)		+= msi.o
diff --git a/drivers/ntb/intr_common.c b/drivers/ntb/intr_common.c
new file mode 100644
index 000000000000..e0e296fd3e3c
--- /dev/null
+++ b/drivers/ntb/intr_common.c
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
+
+#include <linux/ntb.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+
+int ntb_intr_init(struct ntb_dev *ntb,
+		  void (*desc_changed)(void *ctx))
+{
+#ifdef CONFIG_NTB_MSI
+	if (ntb->pdev->dev.msi.data) {
+		ntb->intr_backend = ntb_intr_msi_backend();
+		dev_info(&ntb->dev, "NTB interrupt MSI backend selected.\n");
+	}
+#endif
+	if (!ntb->intr_backend)
+		return -ENODEV;
+	return ntb->intr_backend->init(ntb, desc_changed);
+}
+EXPORT_SYMBOL_GPL(ntb_intr_init);
+
+int ntb_intr_setup_mws(struct ntb_dev *ntb)
+{
+	return ntb->intr_backend->setup_mws(ntb);
+}
+EXPORT_SYMBOL_GPL(ntb_intr_setup_mws);
+
+void ntb_intr_clear_mws(struct ntb_dev *ntb)
+{
+	ntb->intr_backend->clear_mws(ntb);
+}
+EXPORT_SYMBOL_GPL(ntb_intr_clear_mws);
+
+int ntb_intr_request_irq(struct ntb_dev *ntb, irq_handler_t h,
+			 const char *name, void *dev_id,
+			 struct ntb_intr_desc *d)
+{
+	return ntb->intr_backend->request_irq(ntb, h, name, dev_id, d);
+}
+EXPORT_SYMBOL_GPL(ntb_intr_request_irq);
+
+void ntb_intr_free_irq(struct ntb_dev *ntb, int irq, void *dev_id,
+		       struct ntb_intr_desc *d)
+{
+	return ntb->intr_backend->free_irq(ntb, irq, dev_id, d);
+}
+EXPORT_SYMBOL_GPL(ntb_intr_free_irq);
+
+int ntb_intr_peer_trigger(struct ntb_dev *ntb, int peer,
+			  struct ntb_intr_desc *d)
+{
+	return ntb->intr_backend->peer_trigger(ntb, peer, d);
+}
+EXPORT_SYMBOL_GPL(ntb_intr_peer_trigger);
diff --git a/drivers/ntb/msi.c b/drivers/ntb/msi.c
index 983725d4eb13..cdc3ff6040c8 100644
--- a/drivers/ntb/msi.c
+++ b/drivers/ntb/msi.c
@@ -28,11 +28,12 @@ struct ntb_msi {
  *
  * Return: Zero on success, otherwise a negative error number.
  */
-int ntb_msi_init(struct ntb_dev *ntb,
-		 void (*desc_changed)(void *ctx))
+static int ntb_msi_init(struct ntb_dev *ntb,
+			void (*desc_changed)(void *ctx))
 {
 	phys_addr_t mw_phys_addr;
 	resource_size_t mw_size;
+	struct ntb_msi *msi;
 	int peer_widx;
 	int peers;
 	int ret;
@@ -42,12 +43,12 @@ int ntb_msi_init(struct ntb_dev *ntb,
 	if (peers <= 0)
 		return -EINVAL;
 
-	ntb->msi = devm_kzalloc(&ntb->dev, struct_size(ntb->msi, peer_mws, peers),
+	msi = devm_kzalloc(&ntb->dev, struct_size(msi, peer_mws, peers),
 				GFP_KERNEL);
-	if (!ntb->msi)
+	if (!msi)
 		return -ENOMEM;
 
-	ntb->msi->desc_changed = desc_changed;
+	msi->desc_changed = desc_changed;
 
 	for (i = 0; i < peers; i++) {
 		peer_widx = ntb_peer_mw_count(ntb) - 1 - i;
@@ -57,26 +58,26 @@ int ntb_msi_init(struct ntb_dev *ntb,
 		if (ret)
 			goto unroll;
 
-		ntb->msi->peer_mws[i] = devm_ioremap(&ntb->dev, mw_phys_addr,
+		msi->peer_mws[i] = devm_ioremap(&ntb->dev, mw_phys_addr,
 						     mw_size);
-		if (!ntb->msi->peer_mws[i]) {
+		if (!msi->peer_mws[i]) {
 			ret = -EFAULT;
 			goto unroll;
 		}
 	}
 
+	ntb->intr_priv = msi;
+
 	return 0;
 
 unroll:
 	for (i = 0; i < peers; i++)
-		if (ntb->msi->peer_mws[i])
-			devm_iounmap(&ntb->dev, ntb->msi->peer_mws[i]);
+		if (msi->peer_mws[i])
+			devm_iounmap(&ntb->dev, msi->peer_mws[i]);
 
-	devm_kfree(&ntb->dev, ntb->msi);
-	ntb->msi = NULL;
+	devm_kfree(&ntb->dev, msi);
 	return ret;
 }
-EXPORT_SYMBOL(ntb_msi_init);
 
 /**
  * ntb_msi_setup_mws() - Initialize the MSI inbound memory windows
@@ -92,7 +93,7 @@ EXPORT_SYMBOL(ntb_msi_init);
  *
  * Return: Zero on success, otherwise a negative error number.
  */
-int ntb_msi_setup_mws(struct ntb_dev *ntb)
+static int ntb_msi_setup_mws(struct ntb_dev *ntb)
 {
 	struct msi_desc *desc;
 	u64 addr;
@@ -100,13 +101,14 @@ int ntb_msi_setup_mws(struct ntb_dev *ntb)
 	resource_size_t addr_align, size_align, offset;
 	resource_size_t mw_size = SZ_32K;
 	resource_size_t mw_min_size = mw_size;
+	struct ntb_msi *msi = ntb->intr_priv;
 	int i;
 	int ret;
 
-	if (!ntb->msi)
+	if (!msi)
 		return -EINVAL;
 
-	if (ntb->msi->base_addr)
+	if (msi->base_addr)
 		return 0;
 
 	scoped_guard (msi_descs_lock, &ntb->pdev->dev) {
@@ -149,8 +151,8 @@ int ntb_msi_setup_mws(struct ntb_dev *ntb)
 			goto error_out;
 	}
 
-	ntb->msi->base_addr = addr;
-	ntb->msi->end_addr = addr + mw_min_size;
+	msi->base_addr = addr;
+	msi->end_addr = addr + mw_min_size;
 
 	return 0;
 
@@ -165,7 +167,6 @@ int ntb_msi_setup_mws(struct ntb_dev *ntb)
 
 	return ret;
 }
-EXPORT_SYMBOL(ntb_msi_setup_mws);
 
 /**
  * ntb_msi_clear_mws() - Clear all inbound memory windows
@@ -173,7 +174,7 @@ EXPORT_SYMBOL(ntb_msi_setup_mws);
  *
  * This function tears down the resources used by ntb_msi_setup_mws().
  */
-void ntb_msi_clear_mws(struct ntb_dev *ntb)
+static void ntb_msi_clear_mws(struct ntb_dev *ntb)
 {
 	int peer;
 	int peer_widx;
@@ -186,33 +187,33 @@ void ntb_msi_clear_mws(struct ntb_dev *ntb)
 		ntb_mw_clear_trans(ntb, peer, peer_widx);
 	}
 }
-EXPORT_SYMBOL(ntb_msi_clear_mws);
 
 struct ntb_msi_devres {
 	struct ntb_dev *ntb;
 	struct msi_desc *entry;
-	struct ntb_msi_desc *msi_desc;
+	struct ntb_intr_desc *intr_desc;
 };
 
 static int ntb_msi_set_desc(struct ntb_dev *ntb, struct msi_desc *entry,
-			    struct ntb_msi_desc *msi_desc, u16 vector_offset)
+			    struct ntb_intr_desc *intr_desc, u16 vector_offset)
 {
+	struct ntb_msi *msi = ntb->intr_priv;
 	u64 addr;
 
 	addr = entry->msg.address_lo +
 		((uint64_t)entry->msg.address_hi << 32);
 
-	if (addr < ntb->msi->base_addr || addr >= ntb->msi->end_addr) {
+	if (addr < msi->base_addr || addr >= msi->end_addr) {
 		dev_warn_once(&ntb->dev,
 			      "IRQ %d: MSI Address not within the memory window (%llx, [%llx %llx])\n",
-			      entry->irq, addr, ntb->msi->base_addr,
-			      ntb->msi->end_addr);
+			      entry->irq, addr, msi->base_addr,
+			      msi->end_addr);
 		return -EFAULT;
 	}
 
-	msi_desc->addr_offset = addr - ntb->msi->base_addr;
-	msi_desc->data = entry->msg.data + vector_offset;
-	msi_desc->vector_offset = vector_offset;
+	intr_desc->addr_offset = addr - msi->base_addr;
+	intr_desc->data = entry->msg.data + vector_offset;
+	intr_desc->vector_offset = vector_offset;
 
 	return 0;
 }
@@ -220,12 +221,13 @@ static int ntb_msi_set_desc(struct ntb_dev *ntb, struct msi_desc *entry,
 static void ntb_msi_write_msg(struct msi_desc *entry, void *data)
 {
 	struct ntb_msi_devres *dr = data;
+	struct ntb_msi *msi = dr->ntb->intr_priv;
 
-	WARN_ON(ntb_msi_set_desc(dr->ntb, entry, dr->msi_desc,
-				 dr->msi_desc->vector_offset));
+	WARN_ON(ntb_msi_set_desc(dr->ntb, entry, dr->intr_desc,
+				 dr->intr_desc->vector_offset));
 
-	if (dr->ntb->msi->desc_changed)
-		dr->ntb->msi->desc_changed(dr->ntb->ctx);
+	if (msi->desc_changed)
+		msi->desc_changed(dr->ntb->ctx);
 }
 
 static void ntbm_msi_callback_release(struct device *dev, void *res)
@@ -237,7 +239,7 @@ static void ntbm_msi_callback_release(struct device *dev, void *res)
 }
 
 static int ntbm_msi_setup_callback(struct ntb_dev *ntb, struct msi_desc *entry,
-				   struct ntb_msi_desc *msi_desc)
+				   struct ntb_intr_desc *intr_desc)
 {
 	struct ntb_msi_devres *dr;
 
@@ -248,7 +250,7 @@ static int ntbm_msi_setup_callback(struct ntb_dev *ntb, struct msi_desc *entry,
 
 	dr->ntb = ntb;
 	dr->entry = entry;
-	dr->msi_desc = msi_desc;
+	dr->intr_desc = intr_desc;
 
 	devres_add(&ntb->dev, dr);
 
@@ -259,14 +261,12 @@ static int ntbm_msi_setup_callback(struct ntb_dev *ntb, struct msi_desc *entry,
 }
 
 /**
- * ntbm_msi_request_threaded_irq() - allocate an MSI interrupt
+ * ntb_msi_request_irq() - allocate an MSI interrupt
  * @ntb:	NTB device context
  * @handler:	Function to be called when the IRQ occurs
- * @thread_fn:  Function to be called in a threaded interrupt context. NULL
- *              for clients which handle everything in @handler
- * @name:    An ascii name for the claiming device, dev_name(dev) if NULL
- * @dev_id:     A cookie passed back to the handler function
- * @msi_desc:	MSI descriptor data which triggers the interrupt
+ * @name:	An ascii name for the claiming device, dev_name(dev) if NULL
+ * @dev_id:	A cookie passed back to the handler function
+ * @intr_desc:	Generic interrupt descriptor
  *
  * This function assigns an interrupt handler to an unused
  * MSI interrupt and returns the descriptor used to trigger
@@ -281,19 +281,15 @@ static int ntbm_msi_setup_callback(struct ntb_dev *ntb, struct msi_desc *entry,
  *
  * Return: IRQ number assigned on success, otherwise a negative error number.
  */
-int ntbm_msi_request_threaded_irq(struct ntb_dev *ntb, irq_handler_t handler,
-				  irq_handler_t thread_fn,
-				  const char *name, void *dev_id,
-				  struct ntb_msi_desc *msi_desc)
+static int ntb_msi_request_irq(struct ntb_dev *ntb, irq_handler_t handler,
+			       const char *name, void *dev_id,
+			       struct ntb_intr_desc *intr_desc)
 {
 	struct device *dev = &ntb->pdev->dev;
 	struct msi_desc *entry;
 	unsigned int virq;
 	int ret, i;
 
-	if (!ntb->msi)
-		return -EINVAL;
-
 	guard(msi_descs_lock)(dev);
 	msi_for_each_desc(entry, dev, MSI_DESC_ASSOCIATED) {
 		for (i = 0; i < entry->nvec_used; i++) {
@@ -301,18 +297,17 @@ int ntbm_msi_request_threaded_irq(struct ntb_dev *ntb, irq_handler_t handler,
 			if (irq_has_action(virq))
 				continue;
 
-			ret = devm_request_threaded_irq(
-					&ntb->dev, virq, handler,
-					thread_fn, 0, name, dev_id);
+			ret = devm_request_irq(&ntb->dev, virq, handler,
+					       0, name, dev_id);
 			if (ret)
 				continue;
 
-			if (ntb_msi_set_desc(ntb, entry, msi_desc, i)) {
+			if (ntb_msi_set_desc(ntb, entry, intr_desc, i)) {
 				devm_free_irq(&ntb->dev, virq, dev_id);
 				continue;
 			}
 
-			ret = ntbm_msi_setup_callback(ntb, entry, msi_desc);
+			ret = ntbm_msi_setup_callback(ntb, entry, intr_desc);
 			if (ret) {
 				devm_free_irq(&ntb->dev, virq, dev_id);
 				return ret;
@@ -322,7 +317,23 @@ int ntbm_msi_request_threaded_irq(struct ntb_dev *ntb, irq_handler_t handler,
 	}
 	return -ENODEV;
 }
-EXPORT_SYMBOL(ntbm_msi_request_threaded_irq);
+
+/**
+ * ntb_msi_free_irq() - free an MSI interrupt
+ * @ntb:	NTB device context
+ * @irq:	IRQ number assigned
+ * @dev_id:	A cookie passed back to the handler function
+ * @desc:	Generic interrupt descriptor
+ *
+ * Free an IRQ assigned by ntb_msi_request_irq().
+ *
+ * Return: void
+ */
+static void ntb_msi_free_irq(struct ntb_dev *ntb, int irq, void *dev_id,
+			     struct ntb_intr_desc *desc)
+{
+	devm_free_irq(&ntb->dev, irq, dev_id);
+}
 
 /**
  * ntb_msi_peer_trigger() - Trigger an interrupt handler on a peer
@@ -336,18 +347,30 @@ EXPORT_SYMBOL(ntbm_msi_request_threaded_irq);
  *
  * Return: Zero on success, otherwise a negative error number.
  */
-int ntb_msi_peer_trigger(struct ntb_dev *ntb, int peer,
-			 struct ntb_msi_desc *desc)
+static int ntb_msi_peer_trigger(struct ntb_dev *ntb, int peer,
+				struct ntb_intr_desc *desc)
 {
+	struct ntb_msi *msi = ntb->intr_priv;
 	int idx;
 
-	if (!ntb->msi)
-		return -EINVAL;
+	idx = desc->addr_offset / sizeof(*msi->peer_mws[peer]);
 
-	idx = desc->addr_offset / sizeof(*ntb->msi->peer_mws[peer]);
-
-	iowrite32(desc->data, &ntb->msi->peer_mws[peer][idx]);
+	iowrite32(desc->data, &msi->peer_mws[peer][idx]);
 
 	return 0;
 }
-EXPORT_SYMBOL(ntb_msi_peer_trigger);
+
+static const struct ntb_intr_backend ntb_intr_backend_msi = {
+	.name = "msi",
+	.init = ntb_msi_init,
+	.setup_mws = ntb_msi_setup_mws,
+	.clear_mws = ntb_msi_clear_mws,
+	.request_irq = ntb_msi_request_irq,
+	.free_irq = ntb_msi_free_irq,
+	.peer_trigger = ntb_msi_peer_trigger,
+};
+
+const struct ntb_intr_backend *ntb_intr_msi_backend(void)
+{
+	return &ntb_intr_backend_msi;
+}
diff --git a/drivers/ntb/ntb_transport.c b/drivers/ntb/ntb_transport.c
index 4695eb5e6831..ff4a149680c5 100644
--- a/drivers/ntb/ntb_transport.c
+++ b/drivers/ntb/ntb_transport.c
@@ -205,8 +205,8 @@ struct ntb_transport_qp {
 
 	bool use_msi;
 	int msi_irq;
-	struct ntb_msi_desc msi_desc;
-	struct ntb_msi_desc peer_msi_desc;
+	struct ntb_intr_desc intr_desc;
+	struct ntb_intr_desc peer_intr_desc;
 };
 
 struct ntb_transport_mw {
@@ -714,16 +714,16 @@ static void ntb_transport_setup_qp_peer_msi(struct ntb_transport_ctx *nt,
 	if (spad >= ntb_spad_count(nt->ndev))
 		return;
 
-	qp->peer_msi_desc.addr_offset =
+	qp->peer_intr_desc.addr_offset =
 		ntb_peer_spad_read(qp->ndev, PIDX, spad);
-	qp->peer_msi_desc.data =
+	qp->peer_intr_desc.data =
 		ntb_peer_spad_read(qp->ndev, PIDX, spad + 1);
 
 	dev_dbg(&qp->ndev->pdev->dev, "QP%d Peer MSI addr=%x data=%x\n",
-		qp_num, qp->peer_msi_desc.addr_offset, qp->peer_msi_desc.data);
+		qp_num, qp->peer_intr_desc.addr_offset, qp->peer_intr_desc.data);
 
-	if (qp->peer_msi_desc.addr_offset == INTR_INVALID_ADDR_OFFSET ||
-	    qp->peer_msi_desc.data == INTR_INVALID_DATA)
+	if (qp->peer_intr_desc.addr_offset == INTR_INVALID_ADDR_OFFSET ||
+	    qp->peer_intr_desc.data == INTR_INVALID_DATA)
 		dev_info(&qp->ndev->pdev->dev,
 			 "Invalid addr_offset or data, falling back to doorbell\n");
 	else {
@@ -756,9 +756,9 @@ static void ntb_transport_setup_qp_msi(struct ntb_transport_ctx *nt,
 	}
 
 	if (!qp->msi_irq) {
-		qp->msi_irq = ntbm_msi_request_irq(qp->ndev, ntb_transport_isr,
+		qp->msi_irq = ntb_intr_request_irq(qp->ndev, ntb_transport_isr,
 						   KBUILD_MODNAME, qp,
-						   &qp->msi_desc);
+						   &qp->intr_desc);
 		if (qp->msi_irq < 0) {
 			dev_warn(&qp->ndev->pdev->dev,
 				 "Unable to allocate MSI interrupt for qp%d\n",
@@ -767,22 +767,22 @@ static void ntb_transport_setup_qp_msi(struct ntb_transport_ctx *nt,
 		}
 	}
 
-	rc = ntb_spad_write(qp->ndev, spad, qp->msi_desc.addr_offset);
+	rc = ntb_spad_write(qp->ndev, spad, qp->intr_desc.addr_offset);
 	if (rc)
 		goto err_free_interrupt;
 
-	rc = ntb_spad_write(qp->ndev, spad + 1, qp->msi_desc.data);
+	rc = ntb_spad_write(qp->ndev, spad + 1, qp->intr_desc.data);
 	if (rc)
 		goto err_free_interrupt;
 
 	dev_dbg(&qp->ndev->pdev->dev, "QP%d MSI %d addr=%x data=%x\n",
-		qp_num, qp->msi_irq, qp->msi_desc.addr_offset,
-		qp->msi_desc.data);
+		qp_num, qp->msi_irq, qp->intr_desc.addr_offset,
+		qp->intr_desc.data);
 
 	return;
 
 err_free_interrupt:
-	devm_free_irq(&nt->ndev->dev, qp->msi_irq, qp);
+	ntb_intr_free_irq(qp->ndev, qp->msi_irq, qp, &qp->intr_desc);
 }
 
 static void ntb_transport_msi_peer_desc_changed(struct ntb_transport_ctx *nt)
@@ -795,7 +795,7 @@ static void ntb_transport_msi_peer_desc_changed(struct ntb_transport_ctx *nt)
 		ntb_transport_setup_qp_peer_msi(nt, i);
 }
 
-static void ntb_transport_msi_desc_changed(void *data)
+static void ntb_transport_intr_desc_changed(void *data)
 {
 	struct ntb_transport_ctx *nt = data;
 	int i;
@@ -1072,7 +1072,7 @@ static void ntb_transport_link_work(struct work_struct *work)
 	/* send the local info, in the opposite order of the way we read it */
 
 	if (nt->use_intr) {
-		rc = ntb_msi_setup_mws(ndev);
+		rc = ntb_intr_setup_mws(ndev);
 		if (rc) {
 			dev_warn(&pdev->dev,
 				 "Failed to register MSI memory window: %d\n",
@@ -1321,7 +1321,7 @@ static int ntb_transport_probe(struct ntb_client *self, struct ntb_dev *ndev)
 	 * we will reserve the last MW for the MSI window.
 	 */
 	if (use_intr && mw_count > 1) {
-		rc = ntb_msi_init(ndev, ntb_transport_msi_desc_changed);
+		rc = ntb_intr_init(ndev, ntb_transport_intr_desc_changed);
 		if (!rc) {
 			mw_count -= 1;
 			nt->use_intr = true;
@@ -1803,7 +1803,7 @@ static void ntb_tx_copy_callback(void *data,
 	iowrite32(entry->flags | DESC_DONE_FLAG, &hdr->flags);
 
 	if (qp->use_msi)
-		ntb_msi_peer_trigger(qp->ndev, PIDX, &qp->peer_msi_desc);
+		ntb_intr_peer_trigger(qp->ndev, PIDX, &qp->peer_intr_desc);
 	else
 		ntb_peer_db_set(qp->ndev, BIT_ULL(qp->qp_num));
 
diff --git a/drivers/ntb/test/ntb_msi_test.c b/drivers/ntb/test/ntb_msi_test.c
index 4e18e08776c9..d037892e752e 100644
--- a/drivers/ntb/test/ntb_msi_test.c
+++ b/drivers/ntb/test/ntb_msi_test.c
@@ -26,7 +26,7 @@ struct ntb_msit_ctx {
 		int irq_num;
 		int occurrences;
 		struct ntb_msit_ctx *nm;
-		struct ntb_msi_desc desc;
+		struct ntb_intr_desc desc;
 	} *isr_ctx;
 
 	struct ntb_msit_peer {
@@ -34,7 +34,7 @@ struct ntb_msit_ctx {
 		int pidx;
 		int num_irqs;
 		struct completion init_comp;
-		struct ntb_msi_desc *msi_desc;
+		struct ntb_intr_desc *intr_desc;
 	} peers[];
 };
 
@@ -62,7 +62,7 @@ static void ntb_msit_setup_work(struct work_struct *work)
 	int ret;
 	uintptr_t i;
 
-	ret = ntb_msi_setup_mws(nm->ntb);
+	ret = ntb_intr_setup_mws(nm->ntb);
 	if (ret) {
 		dev_err(&nm->ntb->dev, "Unable to setup MSI windows: %d\n",
 			ret);
@@ -74,7 +74,7 @@ static void ntb_msit_setup_work(struct work_struct *work)
 		nm->isr_ctx[i].nm = nm;
 
 		if (!nm->isr_ctx[i].irq_num) {
-			irq = ntbm_msi_request_irq(nm->ntb, ntb_msit_isr,
+			irq = ntb_intr_request_irq(nm->ntb, ntb_msit_isr,
 						   KBUILD_MODNAME,
 						   &nm->isr_ctx[i],
 						   &nm->isr_ctx[i].desc);
@@ -131,7 +131,7 @@ static void ntb_msit_link_event(void *ctx)
 static void ntb_msit_copy_peer_desc(struct ntb_msit_ctx *nm, int peer)
 {
 	int i;
-	struct ntb_msi_desc *desc = nm->peers[peer].msi_desc;
+	struct ntb_intr_desc *desc = nm->peers[peer].intr_desc;
 	int irq_count = nm->peers[peer].num_irqs;
 
 	for (i = 0; i < irq_count; i++) {
@@ -149,7 +149,7 @@ static void ntb_msit_copy_peer_desc(struct ntb_msit_ctx *nm, int peer)
 static void ntb_msit_db_event(void *ctx, int vec)
 {
 	struct ntb_msit_ctx *nm = ctx;
-	struct ntb_msi_desc *desc;
+	struct ntb_intr_desc *desc;
 	u64 peer_mask = ntb_db_read(nm->ntb);
 	u32 irq_count;
 	int peer;
@@ -168,8 +168,8 @@ static void ntb_msit_db_event(void *ctx, int vec)
 		if (!desc)
 			continue;
 
-		kfree(nm->peers[peer].msi_desc);
-		nm->peers[peer].msi_desc = desc;
+		kfree(nm->peers[peer].intr_desc);
+		nm->peers[peer].intr_desc = desc;
 		nm->peers[peer].num_irqs = irq_count;
 
 		ntb_msit_copy_peer_desc(nm, peer);
@@ -191,8 +191,8 @@ static int ntb_msit_dbgfs_trigger(void *data, u64 idx)
 	dev_dbg(&peer->nm->ntb->dev, "trigger irq %llu on peer %u\n",
 		idx, peer->pidx);
 
-	return ntb_msi_peer_trigger(peer->nm->ntb, peer->pidx,
-				    &peer->msi_desc[idx]);
+	return ntb_intr_peer_trigger(peer->nm->ntb, peer->pidx,
+				     &peer->intr_desc[idx]);
 }
 
 DEFINE_DEBUGFS_ATTRIBUTE(ntb_msit_trigger_fops, NULL,
@@ -344,7 +344,7 @@ static int ntb_msit_probe(struct ntb_client *client, struct ntb_dev *ntb)
 		return ret;
 	}
 
-	ret = ntb_msi_init(ntb, ntb_msit_desc_changed);
+	ret = ntb_intr_init(ntb, ntb_msit_desc_changed);
 	if (ret) {
 		dev_err(&ntb->dev, "Unable to initialize MSI library: %d\n",
 			ret);
@@ -392,10 +392,10 @@ static void ntb_msit_remove(struct ntb_client *client, struct ntb_dev *ntb)
 
 	ntb_link_disable(ntb);
 	ntb_db_set_mask(ntb, ntb_db_valid_mask(ntb));
-	ntb_msi_clear_mws(ntb);
+	ntb_intr_clear_mws(ntb);
 
 	for (i = 0; i < ntb_peer_port_count(ntb); i++)
-		kfree(nm->peers[i].msi_desc);
+		kfree(nm->peers[i].intr_desc);
 
 	ntb_clear_ctx(ntb);
 	ntb_msit_remove_dbgfs(nm);
diff --git a/include/linux/ntb.h b/include/linux/ntb.h
index 9f819c7383a3..1a88fe45471e 100644
--- a/include/linux/ntb.h
+++ b/include/linux/ntb.h
@@ -63,7 +63,7 @@
 
 struct ntb_client;
 struct ntb_dev;
-struct ntb_msi;
+struct ntb_intr_backend;
 struct pci_dev;
 struct pci_epc;
 
@@ -438,8 +438,9 @@ struct ntb_dev {
 	/* block unregister until device is fully released */
 	struct completion		released;
 
-#ifdef CONFIG_NTB_MSI
-	struct ntb_msi *msi;
+#ifdef CONFIG_NTB_INTR_COMMON
+	void				*intr_priv;
+	const struct ntb_intr_backend	*intr_backend;
 #endif
 };
 #define dev_ntb(__dev) container_of((__dev), struct ntb_dev, dev)
@@ -1659,58 +1660,78 @@ static inline int ntb_peer_highest_mw_idx(struct ntb_dev *ntb, int pidx)
 	return ntb_mw_count(ntb, pidx) - ret - 1;
 }
 
-struct ntb_msi_desc {
+struct ntb_intr_desc {
 	u32 addr_offset;
 	u32 data;
 	u16 vector_offset;
 };
 
-#ifdef CONFIG_NTB_MSI
+struct ntb_intr_backend {
+	const char *name;
+	int (*init)(struct ntb_dev *ntb, void (*desc_changed)(void *ctx));
+	int (*setup_mws)(struct ntb_dev *ntb);
+	void (*clear_mws)(struct ntb_dev *ntb);
+	int (*request_irq)(struct ntb_dev *ntb, irq_handler_t handler,
+			   const char *name, void *dev_id,
+			   struct ntb_intr_desc *desc);
+	void (*free_irq)(struct ntb_dev *ntb, int irq, void *dev_id,
+			 struct ntb_intr_desc *desc);
+	int (*peer_trigger)(struct ntb_dev *ntb, int pidx,
+			    struct ntb_intr_desc *desc);
+	int (*peer_addr)(struct ntb_dev *ntb, int pidx,
+			 const struct ntb_intr_desc *local, phys_addr_t *addr);
+};
+
+#ifdef CONFIG_NTB_INTR_COMMON
 
-int ntb_msi_init(struct ntb_dev *ntb, void (*desc_changed)(void *ctx));
-int ntb_msi_setup_mws(struct ntb_dev *ntb);
-void ntb_msi_clear_mws(struct ntb_dev *ntb);
-int ntbm_msi_request_threaded_irq(struct ntb_dev *ntb, irq_handler_t handler,
-				  irq_handler_t thread_fn,
-				  const char *name, void *dev_id,
-				  struct ntb_msi_desc *msi_desc);
-int ntb_msi_peer_trigger(struct ntb_dev *ntb, int peer,
-			 struct ntb_msi_desc *desc);
+int ntb_intr_init(struct ntb_dev *ntb, void (*desc_changed)(void *ctx));
+int ntb_intr_setup_mws(struct ntb_dev *ntb);
+void ntb_intr_clear_mws(struct ntb_dev *ntb);
+int ntb_intr_request_irq(struct ntb_dev *ntb, irq_handler_t handler,
+			 const char *name, void *dev_id,
+			 struct ntb_intr_desc *intr_desc);
+void ntb_intr_free_irq(struct ntb_dev *ntb, int irq, void *dev_id,
+		       struct ntb_intr_desc *intr_desc);
+int ntb_intr_peer_trigger(struct ntb_dev *ntb, int peer,
+			  struct ntb_intr_desc *desc);
 
-#else /* not CONFIG_NTB_MSI */
+#else /* not CONFIG_NTB_INTR_COMMON */
 
-static inline int ntb_msi_init(struct ntb_dev *ntb,
+static inline int ntb_intr_init(struct ntb_dev *ntb,
 			       void (*desc_changed)(void *ctx))
 {
 	return -EOPNOTSUPP;
 }
-static inline int ntb_msi_setup_mws(struct ntb_dev *ntb)
+static inline int ntb_intr_setup_mws(struct ntb_dev *ntb)
 {
 	return -EOPNOTSUPP;
 }
-static inline void ntb_msi_clear_mws(struct ntb_dev *ntb) {}
-static inline int ntbm_msi_request_threaded_irq(struct ntb_dev *ntb,
-						irq_handler_t handler,
-						irq_handler_t thread_fn,
-						const char *name, void *dev_id,
-						struct ntb_msi_desc *msi_desc)
+static inline void ntb_intr_clear_mws(struct ntb_dev *ntb) {}
+static inline int ntb_intr_request_irq(struct ntb_dev *ntb,
+				       irq_handler_t handler,
+				       const char *name, void *dev_id,
+				       struct ntb_intr_desc *intr_desc)
 {
 	return -EOPNOTSUPP;
 }
-static inline int ntb_msi_peer_trigger(struct ntb_dev *ntb, int peer,
-				       struct ntb_msi_desc *desc)
+static inline void ntb_intr_free_irq(struct ntb_dev *ntb, int irq, void *dev_id,
+				     struct ntb_intr_desc *desc)
+{
+}
+static inline int ntb_intr_peer_trigger(struct ntb_dev *ntb, int peer,
+					struct ntb_intr_desc *desc)
 {
 	return -EOPNOTSUPP;
 }
-#endif /* CONFIG_NTB_MSI */
+#endif /* CONFIG_NTB_INTR_COMMON */
 
-static inline int ntbm_msi_request_irq(struct ntb_dev *ntb,
-				       irq_handler_t handler,
-				       const char *name, void *dev_id,
-				       struct ntb_msi_desc *msi_desc)
+#ifdef CONFIG_NTB_MSI
+extern const struct ntb_intr_backend *ntb_intr_msi_backend(void);
+#else
+static inline const struct ntb_intr_backend *ntb_intr_msi_backend(void)
 {
-	return ntbm_msi_request_threaded_irq(ntb, handler, NULL, name,
-					     dev_id, msi_desc);
+	return NULL;
 }
+#endif /* CONFIG_NTB_MSI */
 
 #endif
-- 
2.48.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ