ср, 15 янв. 2020 г. в 22:15, Martin Pieuchot <[email protected]>: > > On 15/01/20(Wed) 20:26, Vadim Zhukov wrote: > > I have a diff or two for that, will send when I'll come home. > > After discussing the issue with Peter Stuge, we figured out that > the free should happen *after* calling config_detach() for the child > device (video(4)). > > When video(4) is detached it will call: > > vdevgone()->videoclose()->uvideo_close() > > this last function will sleep until all I/O are finished or cancelled as > part of usbd_pipe_close(9). > > Diff below should fix the issue.
Looks good; works here on amd64 with 2 different uvideo(4) devices, including broken one. > Index: dev/video.c > =================================================================== > RCS file: /cvs/src/sys/dev/video.c,v > retrieving revision 1.42 > diff -u -p -r1.42 video.c > --- dev/video.c 6 Oct 2019 17:13:10 -0000 1.42 > +++ dev/video.c 15 Jan 2020 19:11:20 -0000 > @@ -463,9 +463,6 @@ videodetach(struct device *self, int fla > struct video_softc *sc = (struct video_softc *)self; > int maj, mn; > > - if (sc->sc_fbuffer != NULL) > - free(sc->sc_fbuffer, M_DEVBUF, sc->sc_fbufferlen); > - > /* locate the major number */ > for (maj = 0; maj < nchrdev; maj++) > if (cdevsw[maj].d_open == videoopen) > @@ -474,6 +471,8 @@ videodetach(struct device *self, int fla > /* Nuke the vnodes for any open instances (calls close). */ > mn = self->dv_unit; > vdevgone(maj, mn, mn, VCHR); > + > + free(sc->sc_fbuffer, M_DEVBUF, sc->sc_fbufferlen); > > return (0); > } > Index: dev/usb/uvideo.c > =================================================================== > RCS file: /cvs/src/sys/dev/usb/uvideo.c,v > retrieving revision 1.205 > diff -u -p -r1.205 uvideo.c > --- dev/usb/uvideo.c 14 Oct 2019 09:20:48 -0000 1.205 > +++ dev/usb/uvideo.c 15 Jan 2020 19:09:48 -0000 > @@ -644,10 +644,10 @@ uvideo_detach(struct device *self, int f > /* Wait for outstanding requests to complete */ > usbd_delay_ms(sc->sc_udev, UVIDEO_NFRAMES_MAX); > > - uvideo_vs_free_frame(sc); > - > if (sc->sc_videodev != NULL) > rv = config_detach(sc->sc_videodev, flags); > + > + uvideo_vs_free_frame(sc); > > return (rv); > } -- WBR, Vadim Zhukov
