Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 18 Jul 2021 00:36:47 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: 05cb0d21ed4b - stable/13 - LinuxKPI: add device_reprobe() and device_release_driver()
Message-ID:  <202107180036.16I0alAI049588@gitrepo.freebsd.org>

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

URL: https://cgit.FreeBSD.org/src/commit/?id=05cb0d21ed4bf7ac5a78a62a10b33b222f3762cc

commit 05cb0d21ed4bf7ac5a78a62a10b33b222f3762cc
Author:     Bjoern A. Zeeb <bz@FreeBSD.org>
AuthorDate: 2021-05-28 11:04:34 +0000
Commit:     Bjoern A. Zeeb <bz@FreeBSD.org>
CommitDate: 2021-07-18 00:35:03 +0000

    LinuxKPI: add device_reprobe() and device_release_driver()
    
    Add two new (though untested) functions to linux/device.h which are
    dealing with manually managing the device/driver and are used by
    at least one wireless driver.  We may have to re-fine them in the
    future.
    Move the devres declarations further up so they can be used earlier
    in the file.
    
    Sponsored by:   The FreeBSD Foundation
    Reviewed by:    imp
    Differential Revision: https://reviews.freebsd.org/D30519
    
    (cherry picked from commit 644b4f117634e3b571031026be87429bea0c30dd)
---
 sys/compat/linuxkpi/common/include/linux/device.h | 67 ++++++++++++++++-------
 1 file changed, 47 insertions(+), 20 deletions(-)

diff --git a/sys/compat/linuxkpi/common/include/linux/device.h b/sys/compat/linuxkpi/common/include/linux/device.h
index 4ef35e6abcd3..4bdc3b831e58 100644
--- a/sys/compat/linuxkpi/common/include/linux/device.h
+++ b/sys/compat/linuxkpi/common/include/linux/device.h
@@ -209,6 +209,25 @@ show_class_attr_string(struct class *class,
 		dev_warn(dev, __VA_ARGS__);	\
 } while (0)
 
+/* Public and LinuxKPI internal devres functions. */
+void *lkpi_devres_alloc(void(*release)(struct device *, void *), size_t, gfp_t);
+void lkpi_devres_add(struct device *, void *);
+void lkpi_devres_free(void *);
+void *lkpi_devres_find(struct device *, void(*release)(struct device *, void *),
+    int (*match)(struct device *, void *, void *), void *);
+int lkpi_devres_destroy(struct device *, void(*release)(struct device *, void *),
+    int (*match)(struct device *, void *, void *), void *);
+#define	devres_alloc(_r, _s, _g)	lkpi_devres_alloc(_r, _s, _g)
+#define	devres_add(_d, _p)		lkpi_devres_add(_d, _p)
+#define	devres_free(_p)			lkpi_devres_free(_p)
+#define	devres_find(_d, _rfn, _mfn, _mp) \
+					lkpi_devres_find(_d, _rfn, _mfn, _mp)
+#define	devres_destroy(_d, _rfn, _mfn, _mp) \
+					lkpi_devres_destroy(_d, _rfn, _mfn, _mp)
+void lkpi_devres_release_free_list(struct device *);
+void lkpi_devres_unlink(struct device *, void *);
+void lkpi_devm_kmalloc_release(struct device *, void *);
+
 static inline void *
 dev_get_drvdata(const struct device *dev)
 {
@@ -483,6 +502,34 @@ device_destroy(struct class *class, dev_t devt)
 		device_unregister(device_get_softc(bsddev));
 }
 
+static inline void
+device_release_driver(struct device *dev)
+{
+
+	/* We also need to cleanup LinuxKPI bits. What else? */
+	lkpi_devres_release_free_list(dev);
+	dev_set_drvdata(dev, NULL);
+	/* Do not call dev->release! */
+
+	mtx_lock(&Giant);
+	if (device_is_attached(dev->bsddev))
+		device_detach(dev->bsddev);
+	mtx_unlock(&Giant);
+}
+
+static inline int
+device_reprobe(struct device *dev)
+{
+	int error;
+
+	device_release_driver(dev);
+	mtx_lock(&Giant);
+	error = device_probe_and_attach(dev->bsddev);
+	mtx_unlock(&Giant);
+
+	return (-error);
+}
+
 #define	dev_pm_set_driver_flags(dev, flags) do { \
 } while (0)
 
@@ -566,26 +613,6 @@ char *lkpi_devm_kasprintf(struct device *, gfp_t, const char *, ...);
 #define	devm_kasprintf(_dev, _gfp, _fmt, ...)			\
     lkpi_devm_kasprintf(_dev, _gfp, _fmt, ##__VA_ARGS__)
 
-void *lkpi_devres_alloc(void(*release)(struct device *, void *), size_t, gfp_t);
-void lkpi_devres_add(struct device *, void *);
-void lkpi_devres_free(void *);
-void *lkpi_devres_find(struct device *, void(*release)(struct device *, void *),
-    int (*match)(struct device *, void *, void *), void *);
-int lkpi_devres_destroy(struct device *, void(*release)(struct device *, void *),
-    int (*match)(struct device *, void *, void *), void *);
-#define	devres_alloc(_r, _s, _g)	lkpi_devres_alloc(_r, _s, _g)
-#define	devres_add(_d, _p)		lkpi_devres_add(_d, _p)
-#define	devres_free(_p)			lkpi_devres_free(_p)
-#define	devres_find(_d, _rfn, _mfn, _mp) \
-					lkpi_devres_find(_d, _rfn, _mfn, _mp)
-#define	devres_destroy(_d, _rfn, _mfn, _mp) \
-					lkpi_devres_destroy(_d, _rfn, _mfn, _mp)
-
-/* LinuxKPI internal functions. */
-void lkpi_devres_release_free_list(struct device *);
-void lkpi_devres_unlink(struct device *, void *);
-void lkpi_devm_kmalloc_release(struct device *, void *);
-
 static __inline void *
 devm_kmalloc(struct device *dev, size_t size, gfp_t gfp)
 {



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