make sure we tear down the devnodes for the endpoints 1 and above

when switching configuration.
This commit is contained in:
Nick Hibma 2000-12-12 10:19:19 +00:00
parent 63bd758be4
commit 040639a0aa
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=69904

View File

@ -155,6 +155,10 @@ Static int ugen_do_read(struct ugen_softc *, int, struct uio *, int);
Static int ugen_do_write(struct ugen_softc *, int, struct uio *, int);
Static int ugen_do_ioctl(struct ugen_softc *, int, u_long,
caddr_t, int, struct proc *);
#if defined(__FreeBSD__)
Static void ugen_make_devnodes(struct ugen_softc *sc);
Static void ugen_destroy_devnodes(struct ugen_softc *sc);
#endif
Static int ugen_set_config(struct ugen_softc *sc, int configno);
Static usb_config_descriptor_t *ugen_get_cdesc(struct ugen_softc *sc,
int index, int *lenp);
@ -191,6 +195,13 @@ USB_ATTACH(ugen)
sc->sc_udev = udev = uaa->device;
#if defined(__FreeBSD__)
/* the main device, ctrl endpoint */
make_dev(&ugen_cdevsw, UGENMINOR(USBDEVUNIT(sc->sc_dev), 0),
UID_ROOT, GID_OPERATOR, 0644, "%s", USBDEVNAME(sc->sc_dev));
#endif
memset(sc->sc_endpoints, 0, sizeof sc->sc_endpoints);
/* First set configuration index 0, the default one for ugen. */
err = usbd_set_config_index(udev, 0, 0);
if (err) {
@ -213,6 +224,63 @@ USB_ATTACH(ugen)
USB_ATTACH_SUCCESS_RETURN;
}
#if defined(__FreeBSD__)
Static void
ugen_make_devnodes(struct ugen_softc *sc)
{
int endptno;
for (endptno = 1; endptno < USB_MAX_ENDPOINTS; endptno++) {
if (sc->sc_endpoints[endptno][IN].sc != NULL ||
sc->sc_endpoints[endptno][OUT].sc != NULL ) {
/* endpt can be 0x81 and 0x01, representing
* endpoint address 0x01 and IN/OUT directions.
* We map both endpts to the same device,
* IN is reading from it, OUT is writing to it.
*
* In the if clause above we check whether one
* of the structs is populated.
*/
make_dev(&ugen_cdevsw,
UGENMINOR(USBDEVUNIT(sc->sc_dev), endptno),
UID_ROOT, GID_OPERATOR, 0644,
"%s.%d",
USBDEVNAME(sc->sc_dev), endptno);
}
}
}
Static void
ugen_destroy_devnodes(struct ugen_softc *sc)
{
int endptno;
dev_t dev;
struct vnode *vp;
/* destroy all devices for the other (existing) endpoints as well */
for (endptno = 1; endptno < USB_MAX_ENDPOINTS; endptno++) {
if (sc->sc_endpoints[endptno][IN].sc != NULL ||
sc->sc_endpoints[endptno][OUT].sc != NULL ) {
/* endpt can be 0x81 and 0x01, representing
* endpoint address 0x01 and IN/OUT directions.
* We map both endpoint addresses to the same device,
* IN is reading from it, OUT is writing to it.
*
* In the if clause above we check whether one
* of the structs is populated.
*/
dev = makedev(UGEN_CDEV_MAJOR,
UGENMINOR(USBDEVUNIT(sc->sc_dev), endptno));
vp = SLIST_FIRST(&dev->si_hlist);
if (vp)
VOP_REVOKE(vp, REVOKEALL);
destroy_dev(dev);
}
}
}
#endif
Static int
ugen_set_config(struct ugen_softc *sc, int configno)
{
@ -228,6 +296,10 @@ ugen_set_config(struct ugen_softc *sc, int configno)
DPRINTFN(1,("ugen_set_config: %s to configno %d, sc=%p\n",
USBDEVNAME(sc->sc_dev), configno, sc));
#if defined(__FreeBSD__)
ugen_destroy_devnodes(sc);
#endif
/* We start at 1, not 0, because we don't care whether the
* control endpoint is open or not. It is always present.
*/
@ -275,30 +347,8 @@ ugen_set_config(struct ugen_softc *sc, int configno)
}
}
#if defined(__FreeBSD__)
/* the main device, ctrl endpoint */
make_dev(&ugen_cdevsw, UGENMINOR(USBDEVUNIT(sc->sc_dev), 0),
UID_ROOT, GID_OPERATOR, 0644, "%s", USBDEVNAME(sc->sc_dev));
for (endptno = 1; endptno < USB_MAX_ENDPOINTS; endptno++) {
if (sc->sc_endpoints[endptno][IN].sc != NULL ||
sc->sc_endpoints[endptno][OUT].sc != NULL ) {
/* endpt can be 0x81 and 0x01, representing
* endpoint address 0x01 and IN/OUT directions.
* We map both endpts to the same device,
* IN is reading from it, OUT is writing to it.
*
* In the if clause above we check whether one
* of the structs is populated.
*/
make_dev(&ugen_cdevsw,
UGENMINOR(USBDEVUNIT(sc->sc_dev), endptno),
UID_ROOT, GID_OPERATOR, 0644,
"%s.%d",
USBDEVNAME(sc->sc_dev), endptno);
}
}
ugen_make_devnodes(sc);
#endif
return (USBD_NORMAL_COMPLETION);
@ -757,7 +807,6 @@ USB_DETACH(ugen)
#if defined(__NetBSD__) || defined(__OpenBSD__)
int maj, mn;
#elif defined(__FreeBSD__)
int endptno;
dev_t dev;
struct vnode *vp;
#endif
@ -804,28 +853,7 @@ USB_DETACH(ugen)
if (vp)
VOP_REVOKE(vp, REVOKEALL);
destroy_dev(dev);
/* destroy all devices for the other (existing) endpoints as well */
for (endptno = 1; endptno < USB_MAX_ENDPOINTS; endptno++) {
if (sc->sc_endpoints[endptno][IN].sc != NULL ||
sc->sc_endpoints[endptno][OUT].sc != NULL ) {
/* endpt can be 0x81 and 0x01, representing
* endpoint address 0x01 and IN/OUT directions.
* We map both endpoint addresses to the same device,
* IN is reading from it, OUT is writing to it.
*
* In the if clause above we check whether one
* of the structs is populated.
*/
dev = makedev(UGEN_CDEV_MAJOR,
UGENMINOR(USBDEVUNIT(sc->sc_dev), endptno));
vp = SLIST_FIRST(&dev->si_hlist);
if (vp)
VOP_REVOKE(vp, REVOKEALL);
destroy_dev(dev);
}
}
ugen_destroy_devnodes(sc);
#endif
return (0);