diff options
author | imp <imp@FreeBSD.org> | 2004-09-09 17:49:53 +0000 |
---|---|---|
committer | imp <imp@FreeBSD.org> | 2004-09-09 17:49:53 +0000 |
commit | fae2456461205b28eed92a2c1e6ab855420a872e (patch) | |
tree | f545b12203f5866753ed346fffd646eb92fb8cb0 /sys/dev | |
parent | ab6f621526c38ded9b2bfc54920e540d547ab919 (diff) | |
download | FreeBSD-src-fae2456461205b28eed92a2c1e6ab855420a872e.zip FreeBSD-src-fae2456461205b28eed92a2c1e6ab855420a872e.tar.gz |
For the moment, back out my back out of green's 1.87 commit. While it
produced better results for a test program I had here, it didn't
substantially change the number of crashes that I saw. Both the old
code and the new code seemed to produce the same crashes from the usb
layer. Since the new code also solves a close() crash, go with it
until the underlying issues wrt devices going away can be addressed.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/usb/ugen.c | 20 |
1 files changed, 9 insertions, 11 deletions
diff --git a/sys/dev/usb/ugen.c b/sys/dev/usb/ugen.c index 760cc6a..4ff006f 100644 --- a/sys/dev/usb/ugen.c +++ b/sys/dev/usb/ugen.c @@ -405,6 +405,7 @@ ugenopen(struct cdev *dev, int flag, int mode, usb_proc_ptr p) if (endpt == USB_CONTROL_ENDPOINT) { sc->sc_is_open[USB_CONTROL_ENDPOINT] = 1; + sc->sc_refcnt++; return (0); } @@ -515,6 +516,7 @@ ugenopen(struct cdev *dev, int flag, int mode, usb_proc_ptr p) } } sc->sc_is_open[endpt] = 1; + sc->sc_refcnt++; return (0); } @@ -542,6 +544,8 @@ ugenclose(struct cdev *dev, int flag, int mode, usb_proc_ptr p) if (endpt == USB_CONTROL_ENDPOINT) { DPRINTFN(5, ("ugenclose: close control\n")); sc->sc_is_open[endpt] = 0; + if (--sc->sc_refcnt == 0) + usb_detach_wakeup(USBDEV(sc->sc_dev)); return (0); } @@ -577,6 +581,8 @@ ugenclose(struct cdev *dev, int flag, int mode, usb_proc_ptr p) } } sc->sc_is_open[endpt] = 0; + if (--sc->sc_refcnt == 0) + usb_detach_wakeup(USBDEV(sc->sc_dev)); return (0); } @@ -733,10 +739,7 @@ ugenread(struct cdev *dev, struct uio *uio, int flag) USB_GET_SC(ugen, UGENUNIT(dev), sc); - sc->sc_refcnt++; error = ugen_do_read(sc, endpt, uio, flag); - if (--sc->sc_refcnt < 0) - usb_detach_wakeup(USBDEV(sc->sc_dev)); return (error); } @@ -833,10 +836,7 @@ ugenwrite(struct cdev *dev, struct uio *uio, int flag) USB_GET_SC(ugen, UGENUNIT(dev), sc); - sc->sc_refcnt++; error = ugen_do_write(sc, endpt, uio, flag); - if (--sc->sc_refcnt < 0) - usb_detach_wakeup(USBDEV(sc->sc_dev)); return (error); } @@ -885,12 +885,13 @@ USB_DETACH(ugen) } s = splusb(); - if (--sc->sc_refcnt >= 0) { + if (sc->sc_refcnt > 0) { /* Wake everyone */ for (i = 0; i < USB_MAX_ENDPOINTS; i++) wakeup(&sc->sc_endpoints[i][IN]); /* Wait for processes to go away. */ - usb_detach_wait(USBDEV(sc->sc_dev)); + while (sc->sc_refcnt > 0) + usb_detach_wait(USBDEV(sc->sc_dev)); } splx(s); @@ -1400,10 +1401,7 @@ ugenioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, usb_proc_ptr p) USB_GET_SC(ugen, UGENUNIT(dev), sc); - sc->sc_refcnt++; error = ugen_do_ioctl(sc, endpt, cmd, addr, flag, p); - if (--sc->sc_refcnt < 0) - usb_detach_wakeup(USBDEV(sc->sc_dev)); return (error); } |