diff options
author | 2002-05-07 18:29:18 +0000 | |
---|---|---|
committer | 2002-05-07 18:29:18 +0000 | |
commit | 27af6c70e298bf649c0fec687cfb6d2ff678a883 (patch) | |
tree | cf6ac06701a0e4bd2e1317f0e50442f2e320e766 /sys/dev/usb/ugen.c | |
parent | Sync ulpt driver with NetBSD (diff) | |
download | wireguard-openbsd-27af6c70e298bf649c0fec687cfb6d2ff678a883.tar.xz wireguard-openbsd-27af6c70e298bf649c0fec687cfb6d2ff678a883.zip |
Meant to commit only ulpt and committed everything. Most things weren't ready
Diffstat (limited to 'sys/dev/usb/ugen.c')
-rw-r--r-- | sys/dev/usb/ugen.c | 168 |
1 files changed, 76 insertions, 92 deletions
diff --git a/sys/dev/usb/ugen.c b/sys/dev/usb/ugen.c index 6ba08f1ab6e..ab1996330d9 100644 --- a/sys/dev/usb/ugen.c +++ b/sys/dev/usb/ugen.c @@ -1,5 +1,5 @@ -/* $OpenBSD: ugen.c,v 1.19 2002/05/07 18:08:04 nate Exp $ */ -/* $NetBSD: ugen.c,v 1.58 2002/02/20 20:30:12 christos Exp $ */ +/* $OpenBSD: ugen.c,v 1.20 2002/05/07 18:29:18 nate Exp $ */ +/* $NetBSD: ugen.c,v 1.49 2001/10/24 22:31:04 augustss Exp $ */ /* $FreeBSD: src/sys/dev/usb/ugen.c,v 1.26 1999/11/17 22:33:41 n_hibma Exp $ */ /* @@ -20,8 +20,8 @@ * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. * 4. Neither the name of The NetBSD Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. @@ -150,16 +150,16 @@ Static struct cdevsw ugen_cdevsw = { }; #endif -Static void ugenintr(usbd_xfer_handle xfer, usbd_private_handle addr, +Static void ugenintr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status); Static void ugen_isoc_rintr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status); 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, usb_proc_ptr); +Static int ugen_do_ioctl(struct ugen_softc *, int, u_long, + caddr_t, int, struct proc *); Static int ugen_set_config(struct ugen_softc *sc, int configno); -Static usb_config_descriptor_t *ugen_get_cdesc(struct ugen_softc *sc, +Static usb_config_descriptor_t *ugen_get_cdesc(struct ugen_softc *sc, int index, int *lenp); Static usbd_status ugen_set_interface(struct ugen_softc *, int, int); Static int ugen_get_alt_index(struct ugen_softc *sc, int ifaceidx); @@ -201,7 +201,7 @@ USB_ATTACH(ugen) /* First set configuration index 0, the default one for ugen. */ err = usbd_set_config_index(udev, 0, 0); if (err) { - printf("%s: setting configuration index 0 failed\n", + printf("%s: setting configuration index 0 failed\n", USBDEVNAME(sc->sc_dev)); sc->sc_dying = 1; USB_ATTACH_ERROR_RETURN; @@ -211,7 +211,7 @@ USB_ATTACH(ugen) /* Set up all the local state for this configuration. */ err = ugen_set_config(sc, conf); if (err) { - printf("%s: setting configuration %d failed\n", + printf("%s: setting configuration %d failed\n", USBDEVNAME(sc->sc_dev), conf); sc->sc_dying = 1; USB_ATTACH_ERROR_RETURN; @@ -247,19 +247,6 @@ 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)); - - /* - * We start at 1, not 0, because we don't care whether the - * control endpoint is open or not. It is always present. - */ - for (endptno = 1; endptno < USB_MAX_ENDPOINTS; endptno++) - if (sc->sc_is_open[endptno]) { - DPRINTFN(1, - ("ugen_set_config: %s - endpoint %d is open\n", - USBDEVNAME(sc->sc_dev), endptno)); - return (USBD_IN_USE); - } - /* Avoid setting the current value. */ if (usbd_get_config_descriptor(dev)->bConfigurationValue != configno) { err = usbd_set_config_no(dev, configno, 1); @@ -285,7 +272,7 @@ ugen_set_config(struct ugen_softc *sc, int configno) dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT; sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir]; DPRINTFN(1,("ugen_set_config: endptno %d, endpt=0x%02x" - "(%d,%d), sce=%p\n", + "(%d,%d), sce=%p\n", endptno, endpt, UE_GET_ADDR(endpt), UE_GET_DIR(endpt), sce)); sce->sc = sc; @@ -297,7 +284,7 @@ ugen_set_config(struct ugen_softc *sc, int configno) } int -ugenopen(dev_t dev, int flag, int mode, usb_proc_ptr p) +ugenopen(dev_t dev, int flag, int mode, struct proc *p) { struct ugen_softc *sc; int unit = UGENUNIT(dev); @@ -312,7 +299,7 @@ ugenopen(dev_t dev, int flag, int mode, usb_proc_ptr p) USB_GET_SC_OPEN(ugen, unit, sc); - DPRINTFN(5, ("ugenopen: flag=%d, mode=%d, unit=%d endpt=%d\n", + DPRINTFN(5, ("ugenopen: flag=%d, mode=%d, unit=%d endpt=%d\n", flag, mode, unit, endpt)); if (sc == NULL || sc->sc_dying) @@ -343,7 +330,7 @@ ugenopen(dev_t dev, int flag, int mode, usb_proc_ptr p) sce = &sc->sc_endpoints[endpt][dir]; sce->state = 0; sce->timeout = USBD_NO_TIMEOUT; - DPRINTFN(5, ("ugenopen: sc=%p, endpt=%d, dir=%d, sce=%p\n", + DPRINTFN(5, ("ugenopen: sc=%p, endpt=%d, dir=%d, sce=%p\n", sc, endpt, dir, sce)); edesc = sce->edesc; switch (edesc->bmAttributes & UE_XFERTYPE) { @@ -352,14 +339,14 @@ ugenopen(dev_t dev, int flag, int mode, usb_proc_ptr p) if (isize == 0) /* shouldn't happen */ return (EINVAL); sce->ibuf = malloc(isize, M_USBDEV, M_WAITOK); - DPRINTFN(5, ("ugenopen: intr endpt=%d,isize=%d\n", + DPRINTFN(5, ("ugenopen: intr endpt=%d,isize=%d\n", endpt, isize)); - if (clalloc(&sce->q, UGEN_IBSIZE, 0) == -1) - return (ENOMEM); - err = usbd_open_pipe_intr(sce->iface, - edesc->bEndpointAddress, - USBD_SHORT_XFER_OK, &sce->pipeh, sce, - sce->ibuf, isize, ugenintr, + if (clalloc(&sce->q, UGEN_IBSIZE, 0) == -1) + return (ENOMEM); + err = usbd_open_pipe_intr(sce->iface, + edesc->bEndpointAddress, + USBD_SHORT_XFER_OK, &sce->pipeh, sce, + sce->ibuf, isize, ugenintr, USBD_DEFAULT_INTERVAL); if (err) { free(sce->ibuf, M_USBDEV); @@ -369,7 +356,7 @@ ugenopen(dev_t dev, int flag, int mode, usb_proc_ptr p) DPRINTFN(5, ("ugenopen: interrupt open done\n")); break; case UE_BULK: - err = usbd_open_pipe(sce->iface, + err = usbd_open_pipe(sce->iface, edesc->bEndpointAddress, 0, &sce->pipeh); if (err) return (EIO); @@ -384,7 +371,7 @@ ugenopen(dev_t dev, int flag, int mode, usb_proc_ptr p) M_USBDEV, M_WAITOK); sce->cur = sce->fill = sce->ibuf; sce->limit = sce->ibuf + isize * UGEN_NISOFRAMES; - DPRINTFN(5, ("ugenopen: isoc endpt=%d, isize=%d\n", + DPRINTFN(5, ("ugenopen: isoc endpt=%d, isize=%d\n", endpt, isize)); err = usbd_open_pipe(sce->iface, edesc->bEndpointAddress, 0, &sce->pipeh); @@ -421,7 +408,6 @@ ugenopen(dev_t dev, int flag, int mode, usb_proc_ptr p) usbd_free_xfer(sce->isoreqs[i].xfer); return (ENOMEM); case UE_CONTROL: - sce->timeout = USBD_DEFAULT_TIMEOUT; return (EINVAL); } } @@ -430,7 +416,7 @@ ugenopen(dev_t dev, int flag, int mode, usb_proc_ptr p) } int -ugenclose(dev_t dev, int flag, int mode, usb_proc_ptr p) +ugenclose(dev_t dev, int flag, int mode, struct proc *p) { int endpt = UGENENDPOINT(dev); struct ugen_softc *sc; @@ -462,30 +448,31 @@ ugenclose(dev_t dev, int flag, int mode, usb_proc_ptr p) sce = &sc->sc_endpoints[endpt][dir]; if (sce == NULL || sce->pipeh == NULL) continue; - DPRINTFN(5, ("ugenclose: endpt=%d dir=%d sce=%p\n", + DPRINTFN(5, ("ugenclose: endpt=%d dir=%d sce=%p\n", endpt, dir, sce)); usbd_abort_pipe(sce->pipeh); usbd_close_pipe(sce->pipeh); sce->pipeh = NULL; - switch (sce->edesc->bmAttributes & UE_XFERTYPE) { - case UE_INTERRUPT: - ndflush(&sce->q, sce->q.c_cc); - clfree(&sce->q); - break; - case UE_ISOCHRONOUS: - for (i = 0; i < UGEN_NISOREQS; ++i) - usbd_free_xfer(sce->isoreqs[i].xfer); - - default: - break; + switch (sce->edesc->bmAttributes & UE_XFERTYPE) { + case UE_INTERRUPT: + ndflush(&sce->q, sce->q.c_cc); + clfree(&sce->q); + break; + case UE_ISOCHRONOUS: + for (i = 0; i < UGEN_NISOREQS; ++i) + usbd_free_xfer(sce->isoreqs[i].xfer); + + default: + break; } if (sce->ibuf != NULL) { free(sce->ibuf, M_USBDEV); sce->ibuf = NULL; clfree(&sce->q); + } } sc->sc_is_open[endpt] = 0; @@ -571,8 +558,8 @@ ugen_do_read(struct ugen_softc *sc, int endpt, struct uio *uio, int flag) tn = n; err = usbd_bulk_transfer( xfer, sce->pipeh, - sce->state & UGEN_SHORT_OK ? - USBD_SHORT_XFER_OK : 0, + sce->state & UGEN_SHORT_OK ? + USBD_SHORT_XFER_OK : 0, sce->timeout, buf, &tn, "ugenrb"); if (err) { if (err == USBD_INTERRUPTED) @@ -690,7 +677,7 @@ ugen_do_write(struct ugen_softc *sc, int endpt, struct uio *uio, int flag) if (error) break; DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n)); - err = usbd_bulk_transfer(xfer, sce->pipeh, 0, + err = usbd_bulk_transfer(xfer, sce->pipeh, 0, sce->timeout, buf, &n,"ugenwb"); if (err) { if (err == USBD_INTERRUPTED) @@ -811,15 +798,14 @@ ugenintr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status) if (status != USBD_NORMAL_COMPLETION) { DPRINTF(("ugenintr: status=%d\n", status)); - if (status == USBD_STALLED) - usbd_clear_endpoint_stall_async(sce->pipeh); + usbd_clear_endpoint_stall_async(sce->pipeh); return; } usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL); ibuf = sce->ibuf; - DPRINTFN(5, ("ugenintr: xfer=%p status=%d count=%d\n", + DPRINTFN(5, ("ugenintr: xfer=%p status=%d count=%d\n", xfer, status, count)); DPRINTFN(5, (" data = %02x %02x %02x\n", ibuf[0], ibuf[1], ibuf[2])); @@ -835,7 +821,7 @@ ugenintr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status) } Static void -ugen_isoc_rintr(usbd_xfer_handle xfer, usbd_private_handle addr, +ugen_isoc_rintr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status) { struct isoreq *req = addr; @@ -973,8 +959,7 @@ ugen_get_cdesc(struct ugen_softc *sc, int index, int *lenp) if (lenp) *lenp = len; cdesc = malloc(len, M_TEMP, M_WAITOK); - err = usbd_get_config_desc_full(sc->sc_udev, index, cdesc, - len); + err = usbd_get_config_desc_full(sc->sc_udev, index, cdesc,len); if (err) { free(cdesc, M_TEMP); return (0); @@ -997,7 +982,7 @@ ugen_get_alt_index(struct ugen_softc *sc, int ifaceidx) Static int ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd, - caddr_t addr, int flag, usb_proc_ptr p) + caddr_t addr, int flag, struct proc *p) { struct ugen_endpoint *sce; usbd_status err; @@ -1021,12 +1006,18 @@ ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd, /* All handled in the upper FS layer. */ return (0); case USB_SET_SHORT_XFER: + /* This flag only affects read */ if (endpt == USB_CONTROL_ENDPOINT) return (EINVAL); - /* This flag only affects read */ sce = &sc->sc_endpoints[endpt][IN]; - if (sce == NULL || sce->pipeh == NULL) + if (sce == NULL) return (EINVAL); +#ifdef DIAGNOSTIC + if (sce->pipeh == NULL) { + printf("ugenioctl: USB_SET_SHORT_XFER, no pipe\n"); + return (EIO); + } +#endif if (*(int *)addr) sce->state |= UGEN_SHORT_OK; else @@ -1034,12 +1025,14 @@ ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd, return (0); case USB_SET_TIMEOUT: sce = &sc->sc_endpoints[endpt][IN]; - if (sce == NULL - /* XXX this shouldn't happen, but the distinction between - input and output pipes isn't clear enough. - || sce->pipeh == NULL */ - ) + if (sce == NULL) return (EINVAL); +#ifdef DIAGNOSTIC + if (sce->pipeh == NULL) { + printf("ugenioctl: USB_SET_TIMEOUT, no pipe\n"); + return (EIO); + } +#endif sce->timeout = *(int *)addr; return (0); default: @@ -1065,19 +1058,13 @@ ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd, if (!(flag & FWRITE)) return (EPERM); err = ugen_set_config(sc, *(int *)addr); - switch (err) { - case USBD_NORMAL_COMPLETION: - break; - case USBD_IN_USE: - return (EBUSY); - default: + if (err) return (EIO); - } break; case USB_GET_ALTINTERFACE: ai = (struct usb_alt_interface *)addr; - err = usbd_device2interface_handle(sc->sc_udev, - ai->uai_interface_index, &iface); + err = usbd_device2interface_handle(sc->sc_udev, + ai->uai_interface_index, &iface); if (err) return (EINVAL); idesc = usbd_get_interface_descriptor(iface); @@ -1089,12 +1076,11 @@ ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd, if (!(flag & FWRITE)) return (EPERM); ai = (struct usb_alt_interface *)addr; - err = usbd_device2interface_handle(sc->sc_udev, - ai->uai_interface_index, &iface); + err = usbd_device2interface_handle(sc->sc_udev, + ai->uai_interface_index, &iface); if (err) return (EINVAL); - err = ugen_set_interface(sc, ai->uai_interface_index, - ai->uai_alt_no); + err = ugen_set_interface(sc, ai->uai_interface_index, ai->uai_alt_no); if (err) return (EINVAL); break; @@ -1108,8 +1094,7 @@ ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd, free(cdesc, M_TEMP); return (EINVAL); } - ai->uai_alt_no = usbd_get_no_alts(cdesc, - idesc->bInterfaceNumber); + ai->uai_alt_no = usbd_get_no_alts(cdesc, idesc->bInterfaceNumber); free(cdesc, M_TEMP); break; case USB_GET_DEVICE_DESC: @@ -1152,7 +1137,7 @@ ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd, alt = ugen_get_alt_index(sc, ed->ued_interface_index); else alt = ed->ued_alt_index; - edesc = usbd_find_edesc(cdesc, ed->ued_interface_index, + edesc = usbd_find_edesc(cdesc, ed->ued_interface_index, alt, ed->ued_endpoint_index); if (edesc == NULL) { free(cdesc, M_TEMP); @@ -1187,7 +1172,7 @@ ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd, } case USB_GET_STRING_DESC: si = (struct usb_string_desc *)addr; - err = usbd_get_string_desc(sc->sc_udev, si->usd_string_index, + err = usbd_get_string_desc(sc->sc_udev, si->usd_string_index, si->usd_language_id, &si->usd_desc); if (err) return (EINVAL); @@ -1224,7 +1209,7 @@ ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd, uio.uio_offset = 0; uio.uio_segflg = UIO_USERSPACE; uio.uio_rw = - ur->ucr_request.bmRequestType & UT_READ ? + ur->ucr_request.bmRequestType & UT_READ ? UIO_READ : UIO_WRITE; uio.uio_procp = p; ptr = malloc(len, M_TEMP, M_WAITOK); @@ -1234,9 +1219,8 @@ ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd, goto ret; } } - sce = &sc->sc_endpoints[endpt][IN]; - err = usbd_do_request_flags(sc->sc_udev, &ur->ucr_request, - ptr, ur->ucr_flags, &ur->ucr_actlen, sce->timeout); + err = usbd_do_request_flags(sc->sc_udev, &ur->ucr_request, + ptr, ur->ucr_flags, &ur->ucr_actlen); if (err) { error = EIO; goto ret; @@ -1264,7 +1248,7 @@ ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd, } int -ugenioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, usb_proc_ptr p) +ugenioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p) { int endpt = UGENENDPOINT(dev); struct ugen_softc *sc; @@ -1280,7 +1264,7 @@ ugenioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, usb_proc_ptr p) } int -ugenpoll(dev_t dev, int events, usb_proc_ptr p) +ugenpoll(dev_t dev, int events, struct proc *p) { struct ugen_softc *sc; struct ugen_endpoint *sce; @@ -1325,12 +1309,12 @@ ugenpoll(dev_t dev, int events, usb_proc_ptr p) } break; case UE_BULK: - /* + /* * We have no easy way of determining if a read will * yield any data or a write will happen. * Pretend they will. */ - revents |= events & + revents |= events & (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM); break; default: |