Module Name:    src
Committed By:   brad
Date:           Wed Apr 27 23:15:30 UTC 2022

Modified Files:
        src/sys/dev/gpio: gpio.c

Log Message:
I have been using this for a while and forgot to commit it.  This add
a number of KERNEL_LOCK() calls and at the very least prevents gpioiic
from panicing the system.  This may be a fix for kern/56438.


To generate a diff of this commit:
cvs rdiff -u -r1.70 -r1.71 src/sys/dev/gpio/gpio.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/gpio/gpio.c
diff -u src/sys/dev/gpio/gpio.c:1.70 src/sys/dev/gpio/gpio.c:1.71
--- src/sys/dev/gpio/gpio.c:1.70	Thu Mar 31 19:30:16 2022
+++ src/sys/dev/gpio/gpio.c	Wed Apr 27 23:15:30 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: gpio.c,v 1.70 2022/03/31 19:30:16 pgoyette Exp $ */
+/* $NetBSD: gpio.c,v 1.71 2022/04/27 23:15:30 brad Exp $ */
 /*	$OpenBSD: gpio.c,v 1.6 2006/01/14 12:33:49 grange Exp $	*/
 
 /*
@@ -23,7 +23,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: gpio.c,v 1.70 2022/03/31 19:30:16 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gpio.c,v 1.71 2022/04/27 23:15:30 brad Exp $");
 
 /*
  * General Purpose Input/Output framework.
@@ -181,12 +181,14 @@ gpio_childdetached(device_t self, device
 	if (error)
 		return;
 
+	KERNEL_LOCK(1, NULL);
 	LIST_FOREACH(gdev, &sc->sc_devs, sc_next)
 		if (gdev->sc_dev == child) {
 			LIST_REMOVE(gdev, sc_next);
 			kmem_free(gdev, sizeof(struct gpio_dev));
 			break;
 		}
+	KERNEL_UNLOCK_ONE(NULL);
 
 	mutex_enter(&sc->sc_mtx);
 	sc->sc_attach_busy = 0;
@@ -199,8 +201,10 @@ static int
 gpio_rescan(device_t self, const char *ifattr, const int *locators)
 {
 
+	KERNEL_LOCK(1, NULL);
 	config_search(self, NULL,
 	    CFARGS(.search = gpio_search));
+	KERNEL_UNLOCK_ONE(NULL);
 
 	return 0;
 }
@@ -882,6 +886,7 @@ gpio_ioctl(struct gpio_softc *sc, u_long
 		locs[GPIOCF_MASK] = ga.ga_mask;
 		locs[GPIOCF_FLAG] = ga.ga_flags;
 
+		KERNEL_LOCK(1, NULL);
 		cf = config_search(sc->sc_dev, &ga,
 		    CFARGS(.locators = locs));
 		if (cf != NULL) {
@@ -902,6 +907,8 @@ gpio_ioctl(struct gpio_softc *sc, u_long
 #endif
 		} else
 			error = EINVAL;
+		KERNEL_UNLOCK_ONE(NULL);
+
 		mutex_enter(&sc->sc_mtx);
 		sc->sc_attach_busy = 0;
 		cv_signal(&sc->sc_attach);
@@ -1139,6 +1146,7 @@ gpio_ioctl_oapi(struct gpio_softc *sc, u
 		if (error)
 			return EBUSY;
 
+		KERNEL_LOCK(1, NULL);
 		attach = data;
 		LIST_FOREACH(gdev, &sc->sc_devs, sc_next) {
 			if (strcmp(device_xname(gdev->sc_dev),
@@ -1148,11 +1156,15 @@ gpio_ioctl_oapi(struct gpio_softc *sc, u
 				cv_signal(&sc->sc_attach);
 				mutex_exit(&sc->sc_mtx);
 
-				if (config_detach(gdev->sc_dev, 0) == 0)
+				if (config_detach(gdev->sc_dev, 0) == 0) {
+					KERNEL_UNLOCK_ONE(NULL);
 					return 0;
+				}
 				break;
 			}
 		}
+		KERNEL_UNLOCK_ONE(NULL);
+
 		if (gdev == NULL) {
 			mutex_enter(&sc->sc_mtx);
 			sc->sc_attach_busy = 0;

Reply via email to