Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 1 May 2020 09:50:36 +0000 (UTC)
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org
Subject:   svn commit: r360526 - in stable/12/sys/compat/linuxkpi/common: include/linux src
Message-ID:  <202005010950.0419oaNk061265@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: hselasky
Date: Fri May  1 09:50:36 2020
New Revision: 360526
URL: https://svnweb.freebsd.org/changeset/base/360526

Log:
  MFC r360196:
  Factor code in LinuxKPI to allow attach and detach using any BSD device.
  This allows non-LinuxKPI based infiniband device drivers to attach
  correctly to ibcore.
  
  No functional change intended.
  
  Reviewed by:	np @
  Differential Revision:	https://reviews.freebsd.org/D24514
  Sponsored by:	Mellanox Technologies

Modified:
  stable/12/sys/compat/linuxkpi/common/include/linux/pci.h
  stable/12/sys/compat/linuxkpi/common/src/linux_pci.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/compat/linuxkpi/common/include/linux/pci.h
==============================================================================
--- stable/12/sys/compat/linuxkpi/common/include/linux/pci.h	Fri May  1 09:46:27 2020	(r360525)
+++ stable/12/sys/compat/linuxkpi/common/include/linux/pci.h	Fri May  1 09:50:36 2020	(r360526)
@@ -954,4 +954,15 @@ pcie_get_width_cap(struct pci_dev *dev)
 	return (PCIE_LNK_WIDTH_UNKNOWN);
 }
 
+/*
+ * The following functions can be used to attach/detach the LinuxKPI's
+ * PCI device runtime. The pci_driver and pci_device_id pointer is
+ * allowed to be NULL. Other pointers must be all valid.
+ * The pci_dev structure should be zero-initialized before passed
+ * to the linux_pci_attach_device function.
+ */
+extern int linux_pci_attach_device(device_t, struct pci_driver *,
+    const struct pci_device_id *, struct pci_dev *);
+extern int linux_pci_detach_device(struct pci_dev *);
+
 #endif	/* _LINUX_PCI_H_ */

Modified: stable/12/sys/compat/linuxkpi/common/src/linux_pci.c
==============================================================================
--- stable/12/sys/compat/linuxkpi/common/src/linux_pci.c	Fri May  1 09:46:27 2020	(r360525)
+++ stable/12/sys/compat/linuxkpi/common/src/linux_pci.c	Fri May  1 09:50:36 2020	(r360526)
@@ -213,22 +213,33 @@ linux_pci_probe(device_t dev)
 static int
 linux_pci_attach(device_t dev)
 {
+	const struct pci_device_id *id;
+	struct pci_driver *pdrv;
+	struct pci_dev *pdev;
+
+	pdrv = linux_pci_find(dev, &id);
+	pdev = device_get_softc(dev);
+
+	MPASS(pdrv != NULL);
+	MPASS(pdev != NULL);
+
+	return (linux_pci_attach_device(dev, pdrv, id, pdev));
+}
+
+int
+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_dev *pdev;
 	struct pci_devinfo *dinfo;
-	struct pci_driver *pdrv;
-	const struct pci_device_id *id;
 	device_t parent;
 	int error;
 
 	linux_set_current(curthread);
 
-	pdrv = linux_pci_find(dev, &id);
-	pdev = device_get_softc(dev);
-
-	parent = device_get_parent(dev);
-	if (pdrv->isdrm) {
+	if (pdrv != NULL && pdrv->isdrm) {
+		parent = device_get_parent(dev);
 		dinfo = device_get_ivars(parent);
 		device_set_ivars(dev, dinfo);
 	} else {
@@ -270,9 +281,11 @@ linux_pci_attach(device_t dev)
 	list_add(&pdev->links, &pci_devices);
 	spin_unlock(&pci_lock);
 
-	error = pdrv->probe(pdev, id);
-	if (error)
-		goto out_probe;
+	if (pdrv != NULL) {
+		error = pdrv->probe(pdev, id);
+		if (error)
+			goto out_probe;
+	}
 	return (0);
 
 out_probe:
@@ -291,18 +304,30 @@ linux_pci_detach(device_t dev)
 {
 	struct pci_dev *pdev;
 
-	linux_set_current(curthread);
 	pdev = device_get_softc(dev);
 
-	pdev->pdrv->remove(pdev);
+	MPASS(pdev != NULL);
 
+	device_set_desc(dev, NULL);
+
+	return (linux_pci_detach_device(pdev));
+}
+
+int
+linux_pci_detach_device(struct pci_dev *pdev)
+{
+
+	linux_set_current(curthread);
+
+	if (pdev->pdrv != NULL)
+		pdev->pdrv->remove(pdev);
+
 	free(pdev->bus, M_DEVBUF);
 	linux_pdev_dma_uninit(pdev);
 
 	spin_lock(&pci_lock);
 	list_del(&pdev->links);
 	spin_unlock(&pci_lock);
-	device_set_desc(dev, NULL);
 	put_device(&pdev->dev);
 
 	return (0);



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