> This actually breaks my machine. malloc() is saying allocation too > large. OF_getproplen will return -1 on that. Is it possible that > len is treated as uint64_t as it is an int and sizeof is effectively > uint64_t?
Ah, yes; size_t is unsigned and wider than int on 64-bit platforms, therefore int is converted to unsigned for the comparison. Casting sizeof to int will do. > Might be easier to have a check like: > > if (sc->sc_channels == NULL) > return level < sc->sc_nlevels ? level : sc->sc_nlevels - 1; > > Then you don't need to indent the whole block. Makes the diff smaller > and a bit easier to understand? Sure; what about this new version, then? Index: pwmbl.c =================================================================== RCS file: /OpenBSD/src/sys/dev/fdt/pwmbl.c,v retrieving revision 1.6 diff -u -p -r1.6 pwmbl.c --- pwmbl.c 24 Oct 2021 17:52:26 -0000 1.6 +++ pwmbl.c 11 Nov 2022 06:46:41 -0000 @@ -35,7 +35,7 @@ struct pwmbl_softc { struct device sc_dev; uint32_t *sc_pwm; int sc_pwm_len; - uint32_t *sc_levels; + uint32_t *sc_levels; /* NULL if simple ramp */ int sc_nlevels; uint32_t sc_max_level; uint32_t sc_def_level; @@ -73,7 +73,7 @@ pwmbl_attach(struct device *parent, stru struct pwmbl_softc *sc = (struct pwmbl_softc *)self; struct fdt_attach_args *faa = aux; uint32_t *gpios; - int i, len; + int len; len = OF_getproplen(faa->fa_node, "pwms"); if (len < 0) { @@ -95,7 +95,7 @@ pwmbl_attach(struct device *parent, stru } len = OF_getproplen(faa->fa_node, "brightness-levels"); - if (len > 0) { + if (len >= (int)sizeof(uint32_t)) { sc->sc_levels = malloc(len, M_DEVBUF, M_WAITOK); OF_getpropintarray(faa->fa_node, "brightness-levels", sc->sc_levels, len); @@ -107,13 +107,9 @@ pwmbl_attach(struct device *parent, stru sc->sc_def_level = sc->sc_nlevels - 1; sc->sc_def_level = sc->sc_levels[sc->sc_def_level]; } else { + /* No levels, assume a simple 0..255 ramp. */ sc->sc_nlevels = 256; - sc->sc_levels = mallocarray(sc->sc_nlevels, - sizeof(uint32_t), M_DEVBUF, M_WAITOK); - for (i = 0; i < sc->sc_nlevels; i++) - sc->sc_levels[i] = i; - sc->sc_max_level = sc->sc_levels[sc->sc_nlevels - 1]; - sc->sc_def_level = sc->sc_levels[sc->sc_nlevels - 1]; + sc->sc_max_level = sc->sc_def_level = sc->sc_nlevels - 1; } printf("\n"); @@ -143,6 +139,9 @@ pwmbl_find_brightness(struct pwmbl_softc { uint32_t mid; int i; + + if (sc->sc_levels == NULL) + return level < sc->sc_nlevels ? level : sc->sc_nlevels - 1; for (i = 0; i < sc->sc_nlevels - 1; i++) { mid = (sc->sc_levels[i] + sc->sc_levels[i + 1]) / 2;