Make gpio(4) release the device reference that device_lookup() takes.

OK?

Index: dev/gpio/gpio.c
===================================================================
RCS file: src/sys/dev/gpio/gpio.c,v
retrieving revision 1.16
diff -u -p -r1.16 gpio.c
--- dev/gpio/gpio.c     6 Apr 2022 18:59:28 -0000       1.16
+++ dev/gpio/gpio.c     10 Apr 2022 14:45:40 -0000
@@ -53,6 +53,7 @@ int   gpio_detach(struct device *, int);
 int    gpio_search(struct device *, void *, void *);
 int    gpio_print(void *, const char *);
 int    gpio_pinbyname(struct gpio_softc *, char *gp_name);
+int    gpio_ioctl(struct gpio_softc *, u_long, caddr_t, int);
 
 const struct cfattach gpio_ca = {
        sizeof (struct gpio_softc),
@@ -249,16 +250,20 @@ int
 gpioopen(dev_t dev, int flag, int mode, struct proc *p)
 {
        struct gpio_softc *sc;
+       int error = 0;
 
        sc = (struct gpio_softc *)device_lookup(&gpio_cd, minor(dev));
        if (sc == NULL)
                return (ENXIO);
 
        if (sc->sc_opened)
-               return (EBUSY);
-       sc->sc_opened = 1;
+               error = EBUSY;
+       else
+               sc->sc_opened = 1;
 
-       return (0);
+       device_unref(&sc->sc_dev);
+
+       return (error);
 }
 
 int
@@ -272,6 +277,8 @@ gpioclose(dev_t dev, int flag, int mode,
 
        sc->sc_opened = 0;
 
+       device_unref(&sc->sc_dev);
+
        return (0);
 }
 
@@ -287,9 +294,8 @@ gpio_pinbyname(struct gpio_softc *sc, ch
 }
 
 int
-gpioioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
+gpio_ioctl(struct gpio_softc *sc, u_long cmd, caddr_t data, int flag)
 {
-       struct gpio_softc *sc;
        gpio_chipset_tag_t gc;
        struct gpio_info *info;
        struct gpio_pin_op *op;
@@ -301,10 +307,6 @@ gpioioctl(dev_t dev, u_long cmd, caddr_t
        struct device *dv;
        int pin, value, flags, npins, found;
 
-       sc = (struct gpio_softc *)device_lookup(&gpio_cd, minor(dev));
-       if (sc == NULL)
-               return (ENXIO);
-
        gc = sc->sc_gc;
 
        switch (cmd) {
@@ -520,4 +522,21 @@ gpioioctl(dev_t dev, u_long cmd, caddr_t
        }
 
        return (0);
+}
+
+int
+gpioioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
+{
+       struct gpio_softc *sc;
+       int error;
+
+       sc = (struct gpio_softc *)device_lookup(&gpio_cd, minor(dev));
+       if (sc == NULL)
+               return (ENXIO);
+
+       error = gpio_ioctl(sc, cmd, data, flag);
+
+       device_unref(&sc->sc_dev);
+
+       return (error);
 }

Reply via email to