Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 23 Feb 2023 19:34:38 GMT
From:      "Bjoern A. Zeeb" <bz@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: 4876c939ce63 - releng/13.2 - LinuxKPI: implement irq_get_msi_desc()
Message-ID:  <202302231934.31NJYcJ3020416@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch releng/13.2 has been updated by bz:

URL: https://cgit.FreeBSD.org/src/commit/?id=4876c939ce63c86fe918e469881cc92ec40cfbee

commit 4876c939ce63c86fe918e469881cc92ec40cfbee
Author:     Bjoern A. Zeeb <bz@FreeBSD.org>
AuthorDate: 2022-11-28 18:27:03 +0000
Commit:     Bjoern A. Zeeb <bz@FreeBSD.org>
CommitDate: 2023-02-23 19:33:09 +0000

    LinuxKPI: implement irq_get_msi_desc()
    
    Add irq_get_msi_desc() as a wrapper around a PCI function which will
    allocate a single cached value (see comment on struct) for the
    msi_desc requested if it doesn't exist yet and handle freeing it
    when the PCI device goes away.  We take the values from the ivars of
    the native (FreeBSD) device.
    
    While changing struct pci_dev also add the msi_cap field requested by
    a wireless driver.
    
    Reviewed by:    hselasky (earlier version)
    Approved by:    re (cperciva)
    Differential Revision: https://reviews.freebsd.org/D37523
    
    (cherry picked from commit 4b56afaf7bf4fa37bae5b26fd93ee1ff5969c1bb)
    (cherry picked from commit 7d23664b35a2611dc4fea56f7cfd2b99f91626a0)
---
 sys/compat/linuxkpi/common/include/linux/pci.h | 14 ++++++++++++
 sys/compat/linuxkpi/common/src/linux_pci.c     | 31 ++++++++++++++++++++++++++
 2 files changed, 45 insertions(+)

diff --git a/sys/compat/linuxkpi/common/include/linux/pci.h b/sys/compat/linuxkpi/common/include/linux/pci.h
index 8d41e33b0da8..1475a159e0b5 100644
--- a/sys/compat/linuxkpi/common/include/linux/pci.h
+++ b/sys/compat/linuxkpi/common/include/linux/pci.h
@@ -303,6 +303,17 @@ _pci_exit(void)								\
 module_init(_pci_init);							\
 module_exit(_pci_exit)
 
+struct msi_msg {
+	uint32_t			data;
+};
+
+struct msi_desc {
+	struct msi_msg			msg;
+	struct {
+		bool			is_64;
+	} msi_attrib;
+};
+
 /*
  * If we find drivers accessing this from multiple KPIs we may have to
  * refcount objects of this structure.
@@ -338,6 +349,8 @@ struct pci_dev {
 	bool			managed;	/* devres "pcim_*(). */
 	bool			want_iomap_res;
 	bool			msix_enabled;
+	uint8_t			msi_cap;
+	struct msi_desc		*msi_desc;
 };
 
 /* XXX add kassert here on the mmio offset */
@@ -366,6 +379,7 @@ struct resource *_lkpi_pci_iomap(struct pci_dev *pdev, int bar, int mmio_size);
 struct pcim_iomap_devres *lkpi_pcim_iomap_devres_find(struct pci_dev *pdev);
 void lkpi_pcim_iomap_table_release(struct device *, void *);
 struct pci_dev *lkpi_pci_get_device(uint16_t, uint16_t, struct pci_dev *);
+struct msi_desc *lkpi_pci_msi_desc_alloc(int);
 
 static inline bool
 dev_is_pci(struct device *dev)
diff --git a/sys/compat/linuxkpi/common/src/linux_pci.c b/sys/compat/linuxkpi/common/src/linux_pci.c
index 15c5030a33b9..e31ff18b675d 100644
--- a/sys/compat/linuxkpi/common/src/linux_pci.c
+++ b/sys/compat/linuxkpi/common/src/linux_pci.c
@@ -341,6 +341,8 @@ lkpinew_pci_dev_release(struct device *dev)
 	if (pdev->bus->self != pdev)
 		pci_dev_put(pdev->bus->self);
 	free(pdev->bus, M_DEVBUF);
+	if (pdev->msi_desc != NULL)
+		free(pdev->msi_desc, M_DEVBUF);
 	free(pdev, M_DEVBUF);
 }
 
@@ -962,6 +964,35 @@ out:
 	return (-EINVAL);
 }
 
+struct msi_desc *
+lkpi_pci_msi_desc_alloc(int irq)
+{
+	struct device *dev;
+	struct pci_dev *pdev;
+	struct msi_desc *desc;
+	struct pci_devinfo *dinfo;
+	struct pcicfg_msi *msi;
+
+	dev = linux_pci_find_irq_dev(irq);
+	if (dev == NULL)
+		return (NULL);
+
+	pdev = to_pci_dev(dev);
+	if (pdev->msi_desc != NULL)
+		return (pdev->msi_desc);
+
+	dinfo = device_get_ivars(dev->bsddev);
+	msi = &dinfo->cfg.msi;
+
+	desc = malloc(sizeof(*desc), M_DEVBUF, M_WAITOK | M_ZERO);
+
+	desc->msi_attrib.is_64 =
+	   (msi->msi_ctrl & PCIM_MSICTRL_64BIT) ? true : false;
+	desc->msg.data = msi->msi_data;
+
+	return (desc);
+}
+
 CTASSERT(sizeof(dma_addr_t) <= sizeof(uint64_t));
 
 struct linux_dma_obj {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202302231934.31NJYcJ3020416>