git: 105a37cac76b - main - linuxkpi: Add more pci functions needed by DRM

Emmanuel Vadot manu at FreeBSD.org
Tue Jan 12 11:42:58 UTC 2021


The branch main has been updated by manu:

URL: https://cgit.FreeBSD.org/src/commit/?id=105a37cac76b971f7a94409fbdc4f508a7e97fa0

commit 105a37cac76b971f7a94409fbdc4f508a7e97fa0
Author:     Emmanuel Vadot <manu at FreeBSD.org>
AuthorDate: 2020-12-10 16:47:11 +0000
Commit:     Emmanuel Vadot <manu at FreeBSD.org>
CommitDate: 2021-01-12 11:31:00 +0000

    linuxkpi: Add more pci functions needed by DRM
    
     -pci_get_class : This function search for a matching pci device based on
       the class/subclass and returns a newly created pci_dev.
     - pci_{save,restore}_state : This is analogous to ours with the same name
     - pci_is_root_bus : Return true if this is the root bus
     - pci_get_domain_bus_and_slot : This function search for a matching pci
       device based on domain, bus and slot/function concat into a single
       unsigned int (devfn) and returns a newly created pci_dev
     - pci_bus_{read,write}_config* : Read/Write to the config space.
    
    While here add some helper function to alloc and fill the pci_dev struct.
    
    Reviewed by:   hselasky, bz (older version)
    Differential Revision:     https://reviews.freebsd.org/D27550
---
 sys/compat/linuxkpi/common/include/linux/pci.h | 96 ++++++++++++++++++++++++++
 sys/compat/linuxkpi/common/src/linux_pci.c     | 75 +++++++++++++++++---
 sys/dev/mlx4/mlx4_core/mlx4_main.c             |  2 +-
 sys/dev/mlx5/mlx5_core/mlx5_main.c             |  6 +-
 4 files changed, 166 insertions(+), 13 deletions(-)

diff --git a/sys/compat/linuxkpi/common/include/linux/pci.h b/sys/compat/linuxkpi/common/include/linux/pci.h
index 643bc7cc2630..6338f5795f0a 100644
--- a/sys/compat/linuxkpi/common/include/linux/pci.h
+++ b/sys/compat/linuxkpi/common/include/linux/pci.h
@@ -460,6 +460,9 @@ linux_pci_disable_msi(struct pci_dev *pdev)
 	pdev->msi_enabled = false;
 }
 
+#define	pci_free_irq_vectors(pdev) \
+	linux_pci_disable_msi(pdev)
+
 unsigned long	pci_resource_start(struct pci_dev *pdev, int bar);
 unsigned long	pci_resource_len(struct pci_dev *pdev, int bar);
 
@@ -702,6 +705,23 @@ pci_iounmap(struct pci_dev *dev, void *res)
 	}
 }
 
+static inline void
+lkpi_pci_save_state(struct pci_dev *pdev)
+{
+
+	pci_save_state(pdev->dev.bsddev);
+}
+
+static inline void
+lkpi_pci_restore_state(struct pci_dev *pdev)
+{
+
+	pci_restore_state(pdev->dev.bsddev);
+}
+
+#define pci_save_state(dev)	lkpi_pci_save_state(dev)
+#define pci_restore_state(dev)	lkpi_pci_restore_state(dev)
+
 #define DEFINE_PCI_DEVICE_TABLE(_table) \
 	const struct pci_device_id _table[] __devinitdata
 
@@ -1058,4 +1078,80 @@ pci_dev_present(const struct pci_device_id *cur)
 	return (0);
 }
 
+static inline bool
+pci_is_root_bus(struct pci_bus *pbus)
+{
+
+	return (pbus->self == NULL);
+}
+
+struct pci_dev *lkpi_pci_get_domain_bus_and_slot(int domain,
+    unsigned int bus, unsigned int devfn);
+#define	pci_get_domain_bus_and_slot(domain, bus, devfn)	\
+	lkpi_pci_get_domain_bus_and_slot(domain, bus, devfn)
+
+static inline int
+pci_domain_nr(struct pci_bus *pbus)
+{
+
+	return (pci_get_domain(pbus->self->dev.bsddev));
+}
+
+static inline int
+pci_bus_read_config(struct pci_bus *bus, unsigned int devfn,
+                    int pos, uint32_t *val, int len)
+{
+
+	*val = pci_read_config(bus->self->dev.bsddev, pos, len);
+	return (0);
+}
+
+static inline int
+pci_bus_read_config_word(struct pci_bus *bus, unsigned int devfn, int pos, u16 *val)
+{
+	uint32_t tmp;
+	int ret;
+
+	ret = pci_bus_read_config(bus, devfn, pos, &tmp, 2);
+	*val = (u16)tmp;
+	return (ret);
+}
+
+static inline int
+pci_bus_read_config_byte(struct pci_bus *bus, unsigned int devfn, int pos, u8 *val)
+{
+	uint32_t tmp;
+	int ret;
+
+	ret = pci_bus_read_config(bus, devfn, pos, &tmp, 1);
+	*val = (u8)tmp;
+	return (ret);
+}
+
+static inline int
+pci_bus_write_config(struct pci_bus *bus, unsigned int devfn, int pos,
+    uint32_t val, int size)
+{
+
+	pci_write_config(bus->self->dev.bsddev, pos, val, size);
+	return (0);
+}
+
+static inline int
+pci_bus_write_config_byte(struct pci_bus *bus, unsigned int devfn, int pos,
+    uint8_t val)
+{
+	return (pci_bus_write_config(bus, devfn, pos, val, 1));
+}
+
+static inline int
+pci_bus_write_config_word(struct pci_bus *bus, unsigned int devfn, int pos,
+    uint16_t val)
+{
+	return (pci_bus_write_config(bus, devfn, pos, val, 2));
+}
+
+struct pci_dev *lkpi_pci_get_class(unsigned int class, struct pci_dev *from);
+#define	pci_get_class(class, from)	lkpi_pci_get_class(class, from)
+
 #endif	/* _LINUX_PCI_H_ */
diff --git a/sys/compat/linuxkpi/common/src/linux_pci.c b/sys/compat/linuxkpi/common/src/linux_pci.c
index be61c2dba3d2..0e184b64884b 100644
--- a/sys/compat/linuxkpi/common/src/linux_pci.c
+++ b/sys/compat/linuxkpi/common/src/linux_pci.c
@@ -70,6 +70,9 @@ __FBSDID("$FreeBSD$");
 #include "backlight_if.h"
 #include "pcib_if.h"
 
+/* Undef the linux function macro defined in linux/pci.h */
+#undef pci_get_class
+
 static device_probe_t linux_pci_probe;
 static device_attach_t linux_pci_attach;
 static device_detach_t linux_pci_detach;
@@ -210,6 +213,67 @@ linux_pci_find(device_t dev, const struct pci_device_id **idp)
 	return (NULL);
 }
 
+static void
+lkpifill_pci_dev(device_t dev, struct pci_dev *pdev)
+{
+
+	pdev->devfn = PCI_DEVFN(pci_get_slot(dev), pci_get_function(dev));
+	pdev->vendor = pci_get_vendor(dev);
+	pdev->device = pci_get_device(dev);
+	pdev->class = pci_get_class(dev);
+	pdev->revision = pci_get_revid(dev);
+	pdev->dev.bsddev = dev;
+	pdev->bus->self = pdev;
+	pdev->bus->number = pci_get_bus(dev);
+	pdev->bus->domain = pci_get_domain(dev);
+}
+
+static struct pci_dev *
+lkpinew_pci_dev(device_t dev)
+{
+	struct pci_dev *pdev;
+	struct pci_bus *pbus;
+
+	pdev = malloc(sizeof(*pdev), M_DEVBUF, M_WAITOK|M_ZERO);
+	pbus = malloc(sizeof(*pbus), M_DEVBUF, M_WAITOK|M_ZERO);
+	pdev->bus = pbus;
+	lkpifill_pci_dev(dev, pdev);
+	return (pdev);
+}
+
+struct pci_dev *
+lkpi_pci_get_class(unsigned int class, struct pci_dev *from)
+{
+	device_t dev;
+	device_t devfrom = NULL;
+	struct pci_dev *pdev;
+
+	if (from != NULL)
+		devfrom = from->dev.bsddev;
+
+	dev = pci_find_class_from(class >> 16, (class >> 8) & 0xFF, devfrom);
+	if (dev == NULL)
+		return (NULL);
+
+	pdev = lkpinew_pci_dev(dev);
+	return (pdev);
+}
+
+struct pci_dev *
+lkpi_pci_get_domain_bus_and_slot(int domain, unsigned int bus,
+    unsigned int devfn)
+{
+	device_t dev;
+	struct pci_dev *pdev;
+
+	dev = pci_find_dbsf(domain, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+	if (dev == NULL)
+		return (NULL);
+
+	pdev = lkpinew_pci_dev(dev);
+	return (pdev);
+}
+
 static int
 linux_pci_probe(device_t dev)
 {
@@ -245,7 +309,6 @@ linux_pci_attach_device(device_t dev, struct pci_driver *pdrv,
     const struct pci_device_id *id, struct pci_dev *pdev)
 {
 	struct resource_list_entry *rle;
-	struct pci_bus *pbus;
 	struct pci_devinfo *dinfo;
 	device_t parent;
 	uintptr_t rid;
@@ -264,8 +327,9 @@ linux_pci_attach_device(device_t dev, struct pci_driver *pdrv,
 		dinfo = device_get_ivars(dev);
 	}
 
+	pdev->bus = malloc(sizeof(*pdev->bus), M_DEVBUF, M_WAITOK | M_ZERO);
+	lkpifill_pci_dev(dev, pdev);
 	pdev->dev.parent = &linux_root_device;
-	pdev->dev.bsddev = dev;
 	INIT_LIST_HEAD(&pdev->dev.irqents);
 	if (isdrm)
 		PCI_GET_ID(device_get_parent(parent), parent, PCI_ID_RID, &rid);
@@ -276,8 +340,6 @@ linux_pci_attach_device(device_t dev, struct pci_driver *pdrv,
 	pdev->vendor = dinfo->cfg.vendor;
 	pdev->subsystem_vendor = dinfo->cfg.subvendor;
 	pdev->subsystem_device = dinfo->cfg.subdevice;
-	pdev->class = pci_get_class(dev);
-	pdev->revision = pci_get_revid(dev);
 	pdev->pdrv = pdrv;
 	kobject_init(&pdev->dev.kobj, &linux_dev_ktype);
 	kobject_set_name(&pdev->dev.kobj, device_get_nameunit(dev));
@@ -294,11 +356,6 @@ linux_pci_attach_device(device_t dev, struct pci_driver *pdrv,
 		goto out_dma_init;
 
 	TAILQ_INIT(&pdev->mmio);
-	pbus = malloc(sizeof(*pbus), M_DEVBUF, M_WAITOK | M_ZERO);
-	pbus->self = pdev;
-	pbus->number = pci_get_bus(dev);
-	pbus->domain = pci_get_domain(dev);
-	pdev->bus = pbus;
 
 	spin_lock(&pci_lock);
 	list_add(&pdev->links, &pci_devices);
diff --git a/sys/dev/mlx4/mlx4_core/mlx4_main.c b/sys/dev/mlx4/mlx4_core/mlx4_main.c
index ee17418388eb..48cc2fc7d3f6 100644
--- a/sys/dev/mlx4/mlx4_core/mlx4_main.c
+++ b/sys/dev/mlx4/mlx4_core/mlx4_main.c
@@ -3781,7 +3781,7 @@ static int mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
 		return ret;
 	} else {
 		device_set_desc(pdev->dev.bsddev, mlx4_description);
-		pci_save_state(pdev->dev.bsddev);
+		pci_save_state(pdev);
 	}
 
 	snprintf(dev->fw_str, sizeof(dev->fw_str), "%d.%d.%d",
diff --git a/sys/dev/mlx5/mlx5_core/mlx5_main.c b/sys/dev/mlx5/mlx5_core/mlx5_main.c
index 27326d692261..37a55f65683c 100644
--- a/sys/dev/mlx5/mlx5_core/mlx5_main.c
+++ b/sys/dev/mlx5/mlx5_core/mlx5_main.c
@@ -1634,7 +1634,7 @@ static int init_one(struct pci_dev *pdev,
 	}
 #endif
 
-	pci_save_state(bsddev);
+	pci_save_state(pdev);
 	return 0;
 
 clean_health:
@@ -1709,8 +1709,8 @@ static pci_ers_result_t mlx5_pci_slot_reset(struct pci_dev *pdev)
 	}
 	pci_set_master(pdev);
 	pci_set_powerstate(pdev->dev.bsddev, PCI_POWERSTATE_D0);
-	pci_restore_state(pdev->dev.bsddev);
-	pci_save_state(pdev->dev.bsddev);
+	pci_restore_state(pdev);
+	pci_save_state(pdev);
 
 	return err ? PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_RECOVERED;
 }


More information about the dev-commits-src-all mailing list