svn commit: r279402 - head/sys/dev/gpio

Luiz Otavio O Souza loos at FreeBSD.org
Sat Feb 28 20:02:44 UTC 2015


Author: loos
Date: Sat Feb 28 20:02:41 2015
New Revision: 279402
URL: https://svnweb.freebsd.org/changeset/base/279402

Log:
  Rename and move gpiobus_alloc_ivars() and gpiobus_free_ivars() so they can
  be used on non FDT systems.
  
  This prevents access to uninitialized memory on drivers that try to access
  pin flags on non FDT systems.

Modified:
  head/sys/dev/gpio/gpiobus.c
  head/sys/dev/gpio/gpiobusvar.h
  head/sys/dev/gpio/ofw_gpiobus.c

Modified: head/sys/dev/gpio/gpiobus.c
==============================================================================
--- head/sys/dev/gpio/gpiobus.c	Sat Feb 28 19:57:22 2015	(r279401)
+++ head/sys/dev/gpio/gpiobus.c	Sat Feb 28 20:02:41 2015	(r279402)
@@ -195,6 +195,39 @@ gpiobus_init_softc(device_t dev)
 	return (0);
 }
 
+int
+gpiobus_alloc_ivars(struct gpiobus_ivar *devi)
+{
+
+	/* Allocate pins and flags memory. */
+	devi->pins = malloc(sizeof(uint32_t) * devi->npins, M_DEVBUF,
+	    M_NOWAIT | M_ZERO);
+	if (devi->pins == NULL)
+		return (ENOMEM);
+	devi->flags = malloc(sizeof(uint32_t) * devi->npins, M_DEVBUF,
+	    M_NOWAIT | M_ZERO);
+	if (devi->flags == NULL) {
+		free(devi->pins, M_DEVBUF);
+		return (ENOMEM);
+	}
+
+	return (0);
+}
+
+void
+gpiobus_free_ivars(struct gpiobus_ivar *devi)
+{
+
+	if (devi->flags) {
+		free(devi->flags, M_DEVBUF);
+		devi->flags = NULL;
+	}
+	if (devi->pins) {
+		free(devi->pins, M_DEVBUF);
+		devi->pins = NULL;
+	}
+}
+
 static int
 gpiobus_parse_pins(struct gpiobus_softc *sc, device_t child, int mask)
 {
@@ -206,29 +239,23 @@ gpiobus_parse_pins(struct gpiobus_softc 
 		if (mask & (1 << i))
 			npins++;
 	}
-
 	if (npins == 0) {
 		device_printf(child, "empty pin mask\n");
 		return (EINVAL);
 	}
-
 	devi->npins = npins;
-	devi->pins = malloc(sizeof(uint32_t) * devi->npins, M_DEVBUF, 
-	    M_NOWAIT | M_ZERO);
-
-	if (!devi->pins)
-		return (ENOMEM);
-
+	if (gpiobus_alloc_ivars(devi) != 0) {
+		device_printf(child, "cannot allocate device ivars\n");
+		return (EINVAL);
+	}
 	npins = 0;
 	for (i = 0; i < 32; i++) {
-
 		if ((mask & (1 << i)) == 0)
 			continue;
-
 		if (i >= sc->sc_npins) {
 			device_printf(child, 
 			    "invalid pin %d, max: %d\n", i, sc->sc_npins - 1);
-			free(devi->pins, M_DEVBUF);
+			gpiobus_free_ivars(devi);
 			return (EINVAL);
 		}
 
@@ -239,7 +266,7 @@ gpiobus_parse_pins(struct gpiobus_softc 
 		if (sc->sc_pins_mapped[i]) {
 			device_printf(child, 
 			    "warning: pin %d is already mapped\n", i);
-			free(devi->pins, M_DEVBUF);
+			gpiobus_free_ivars(devi);
 			return (EINVAL);
 		}
 		sc->sc_pins_mapped[i] = 1;
@@ -299,10 +326,7 @@ gpiobus_detach(device_t dev)
 	for (i = 0; i < ndevs; i++) {
 		device_delete_child(dev, devlist[i]);
 		devi = GPIOBUS_IVAR(devlist[i]);
-		if (devi->pins) {
-			free(devi->pins, M_DEVBUF);
-			devi->pins = NULL;
-		}
+		gpiobus_free_ivars(devi);
 	}
 	free(devlist, M_TEMP);
 

Modified: head/sys/dev/gpio/gpiobusvar.h
==============================================================================
--- head/sys/dev/gpio/gpiobusvar.h	Sat Feb 28 19:57:22 2015	(r279401)
+++ head/sys/dev/gpio/gpiobusvar.h	Sat Feb 28 20:02:41 2015	(r279402)
@@ -100,6 +100,8 @@ int gpio_check_flags(uint32_t, uint32_t)
 device_t gpiobus_attach_bus(device_t);
 int gpiobus_detach_bus(device_t);
 int gpiobus_init_softc(device_t);
+int gpiobus_alloc_ivars(struct gpiobus_ivar *);
+void gpiobus_free_ivars(struct gpiobus_ivar *);
 
 extern driver_t gpiobus_driver;
 

Modified: head/sys/dev/gpio/ofw_gpiobus.c
==============================================================================
--- head/sys/dev/gpio/ofw_gpiobus.c	Sat Feb 28 19:57:22 2015	(r279401)
+++ head/sys/dev/gpio/ofw_gpiobus.c	Sat Feb 28 20:02:41 2015	(r279402)
@@ -70,33 +70,6 @@ ofw_gpiobus_add_fdt_child(device_t bus, 
 }
 
 static int
-ofw_gpiobus_alloc_ivars(struct gpiobus_ivar *dinfo)
-{
-
-	/* Allocate pins and flags memory. */
-	dinfo->pins = malloc(sizeof(uint32_t) * dinfo->npins, M_DEVBUF,
-	    M_NOWAIT | M_ZERO);
-	if (dinfo->pins == NULL)
-		return (ENOMEM);
-	dinfo->flags = malloc(sizeof(uint32_t) * dinfo->npins, M_DEVBUF,
-	    M_NOWAIT | M_ZERO);
-	if (dinfo->flags == NULL) {
-		free(dinfo->pins, M_DEVBUF);
-		return (ENOMEM);
-	}
-
-	return (0);
-}
-
-static void
-ofw_gpiobus_free_ivars(struct gpiobus_ivar *dinfo)
-{
-
-	free(dinfo->flags, M_DEVBUF);
-	free(dinfo->pins, M_DEVBUF);
-}
-
-static int
 ofw_gpiobus_parse_gpios(struct gpiobus_softc *sc, struct gpiobus_ivar *dinfo,
 	phandle_t child)
 {
@@ -152,7 +125,7 @@ ofw_gpiobus_parse_gpios(struct gpiobus_s
 	}
 
 	/* Allocate the child resources. */
-	if (ofw_gpiobus_alloc_ivars(dinfo) != 0) {
+	if (gpiobus_alloc_ivars(dinfo) != 0) {
 		free(gpios, M_DEVBUF);
 		return (ENOMEM);
 	}
@@ -172,7 +145,7 @@ ofw_gpiobus_parse_gpios(struct gpiobus_s
 		/* Read gpio-cells property for this GPIO controller. */
 		if (OF_getencprop(gpio, "#gpio-cells", &cells,
 		    sizeof(cells)) < 0) {
-			ofw_gpiobus_free_ivars(dinfo);
+			gpiobus_free_ivars(dinfo);
 			free(gpios, M_DEVBUF);
 			return (EINVAL);
 		}
@@ -180,7 +153,7 @@ ofw_gpiobus_parse_gpios(struct gpiobus_s
 		/* Get the GPIO pin number and flags. */
 		if (gpio_map_gpios(sc->sc_dev, child, gpio, cells,
 		    &gpios[i + 1], &dinfo->pins[j], &dinfo->flags[j]) != 0) {
-			ofw_gpiobus_free_ivars(dinfo);
+			gpiobus_free_ivars(dinfo);
 			free(gpios, M_DEVBUF);
 			return (EINVAL);
 		}
@@ -190,7 +163,7 @@ ofw_gpiobus_parse_gpios(struct gpiobus_s
 			device_printf(sc->sc_busdev,
 			    "invalid pin %d, max: %d\n",
 			    dinfo->pins[j], sc->sc_npins - 1);
-			ofw_gpiobus_free_ivars(dinfo);
+			gpiobus_free_ivars(dinfo);
 			free(gpios, M_DEVBUF);
 			return (EINVAL);
 		}
@@ -202,7 +175,7 @@ ofw_gpiobus_parse_gpios(struct gpiobus_s
 			device_printf(sc->sc_busdev,
 			    "warning: pin %d is already mapped\n",
 			    dinfo->pins[j]);
-			ofw_gpiobus_free_ivars(dinfo);
+			gpiobus_free_ivars(dinfo);
 			free(gpios, M_DEVBUF);
 			return (EINVAL);
 		}


More information about the svn-src-head mailing list