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