Date: Sat, 28 Feb 2015 20:02:42 +0000 (UTC) From: Luiz Otavio O Souza <loos@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r279402 - head/sys/dev/gpio Message-ID: <201502282002.t1SK2g2A057426@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201502282002.t1SK2g2A057426>