diff options
author | n_hibma <n_hibma@FreeBSD.org> | 1999-11-17 22:33:51 +0000 |
---|---|---|
committer | n_hibma <n_hibma@FreeBSD.org> | 1999-11-17 22:33:51 +0000 |
commit | aeb2d2626b24c89dbb68adb9caebd10bbe02dd43 (patch) | |
tree | 4ffabed555c86f3e004db50f4d745f46d25b77c9 /sys/dev/usb/ugen.c | |
parent | a586d3a066b64caa068a9a83440201f39e4d6677 (diff) | |
download | FreeBSD-src-aeb2d2626b24c89dbb68adb9caebd10bbe02dd43.zip FreeBSD-src-aeb2d2626b24c89dbb68adb9caebd10bbe02dd43.tar.gz |
Synchronisation with NetBSD as of 1999/11/16:
Cleaning up the code:
- Declare many functions static
- Change variable names to make them more self explanatory
- Change usbd_request_handle -> usbd_xfer_handle
- Syntactical changes
- Remove some unused code
- Other KNF changes
Interrupt context handling
- Change delay to usbd_delay_ms were possible (takes polling mode into
account)
- Change detection mechanism for interrupt context
Add support for pre-allocation DMA-able memory by device driver
Add preliminary support for isochronous to the UHCI driver (not for OHCI
yet).
usb.c, uhci.c, ohci.c
- Initial attempt at detachable USB host controllers
- Handle the use_polling flag with a lttle more care and only set it if
we are cold booting.
usb.c, uhci.c ohci.c, usbdi.c usbdi_util.c usb_subr.c
- Make sure an aborted pipe is marked as not running.
- Start queued request in the right order.
- Insert some more DIAGNOSTIC sanity checks.
- Remove (almost) unused definitions USBD_XFER_OUT and USBD_XFER_IN.
usb.c, usb_subr.c
- Add an event mechanism so that a userland process can watch devices
come and go.
ohci.c
- Handle the case when a USB transfer is so long that it crosses two
page (4K) boundaries. OHCI cannot do that with a single TD so we make
a chain.
ulpt.c
- Use a bigger buffer when transferring data.
- Pre-allocate the DMA buffer. This makes the driver slightly more
efficient.
- Comment out the GET_DEVICE_ID code, because for some unknown reason it
causes printing to fail sometimes.
usb.h
- Add a macro to extract the isoc type.
- Add a macro to check whether the routine has been entered after splusb
and if not, complain.
usbdi.c
- Fix a glitch in dequeueing and aborting requests on interrupt pipes.
- Add a flag in the request to determine if the data copying is done by
the driver or the usbdi layer.
Diffstat (limited to 'sys/dev/usb/ugen.c')
-rw-r--r-- | sys/dev/usb/ugen.c | 338 |
1 files changed, 175 insertions, 163 deletions
diff --git a/sys/dev/usb/ugen.c b/sys/dev/usb/ugen.c index 2d433d4..5c39160 100644 --- a/sys/dev/usb/ugen.c +++ b/sys/dev/usb/ugen.c @@ -1,4 +1,4 @@ -/* $NetBSD: ugen.c,v 1.23 1999/09/09 12:26:44 augustss Exp $ */ +/* $NetBSD: ugen.c,v 1.27 1999/10/28 12:08:38 augustss Exp $ */ /* $FreeBSD$ */ /* @@ -97,7 +97,7 @@ struct ugen_softc { USBBASEDEVICE sc_dev; /* base device */ usbd_device_handle sc_udev; - char sc_is_open[USB_MAX_ENDPOINTS][2]; + char sc_is_open[USB_MAX_ENDPOINTS]; struct ugen_endpoint sc_endpoints[USB_MAX_ENDPOINTS][2]; #define OUT 0 #define IN 1 @@ -136,18 +136,18 @@ static struct cdevsw ugen_cdevsw = { }; #endif -void ugenintr __P((usbd_request_handle reqh, usbd_private_handle addr, - usbd_status status)); +static void ugenintr __P((usbd_xfer_handle xfer, usbd_private_handle addr, + usbd_status status)); -int ugen_do_read __P((struct ugen_softc *, int, struct uio *, int)); -int ugen_do_write __P((struct ugen_softc *, int, struct uio *, int)); -int ugen_do_ioctl __P((struct ugen_softc *, int, u_long, - caddr_t, int, struct proc *)); -int ugen_set_config __P((struct ugen_softc *sc, int configno)); -usb_config_descriptor_t *ugen_get_cdesc __P((struct ugen_softc *sc, int index, - int *lenp)); -usbd_status ugen_set_interface __P((struct ugen_softc *, int, int)); -int ugen_get_alt_index __P((struct ugen_softc *sc, int ifaceidx)); +static int ugen_do_read __P((struct ugen_softc *, int, struct uio *, int)); +static int ugen_do_write __P((struct ugen_softc *, int, struct uio *, int)); +static int ugen_do_ioctl __P((struct ugen_softc *, int, u_long, + caddr_t, int, struct proc *)); +static int ugen_set_config __P((struct ugen_softc *sc, int configno)); +static usb_config_descriptor_t *ugen_get_cdesc __P((struct ugen_softc *sc, + int index, int *lenp)); +static usbd_status ugen_set_interface __P((struct ugen_softc *, int, int)); +static int ugen_get_alt_index __P((struct ugen_softc *sc, int ifaceidx)); #define UGENUNIT(n) ((minor(n) >> 4) & 0xf) #define UGENENDPOINT(n) (minor(n) & 0xf) @@ -169,7 +169,7 @@ USB_ATTACH(ugen) { USB_ATTACH_START(ugen, sc, uaa); char devinfo[1024]; - usbd_status r; + usbd_status err; int conf; usbd_devinfo(uaa->device, 0, devinfo); @@ -178,8 +178,8 @@ USB_ATTACH(ugen) sc->sc_udev = uaa->device; conf = 1; /* XXX should not hard code 1 */ - r = ugen_set_config(sc, conf); - if (r != USBD_NORMAL_COMPLETION) { + err = ugen_set_config(sc, conf); + if (err) { printf("%s: setting configuration %d failed\n", USBDEVNAME(sc->sc_dev), conf); sc->sc_dying = 1; @@ -195,10 +195,11 @@ USB_ATTACH(ugen) } } #endif + USB_ATTACH_SUCCESS_RETURN; } -int +static int ugen_set_config(sc, configno) struct ugen_softc *sc; int configno; @@ -209,30 +210,30 @@ ugen_set_config(sc, configno) struct ugen_endpoint *sce; u_int8_t niface, nendpt; int ifaceno, endptno, endpt; - usbd_status r; + usbd_status err; int dir; DPRINTFN(1,("ugen_set_config: %s to configno %d, sc=%p\n", USBDEVNAME(sc->sc_dev), configno, sc)); if (usbd_get_config_descriptor(dev)->bConfigurationValue != configno) { /* Avoid setting the current value. */ - r = usbd_set_config_no(dev, configno, 0); - if (r != USBD_NORMAL_COMPLETION) - return (r); + err = usbd_set_config_no(dev, configno, 0); + if (err) + return (err); } - r = usbd_interface_count(dev, &niface); - if (r != USBD_NORMAL_COMPLETION) - return (r); + err = usbd_interface_count(dev, &niface); + if (err) + return (err); memset(sc->sc_endpoints, 0, sizeof sc->sc_endpoints); for (ifaceno = 0; ifaceno < niface; ifaceno++) { DPRINTFN(1,("ugen_set_config: ifaceno %d\n", ifaceno)); - r = usbd_device2interface_handle(dev, ifaceno, &iface); - if (r != USBD_NORMAL_COMPLETION) - return (r); - r = usbd_endpoint_count(iface, &nendpt); - if (r != USBD_NORMAL_COMPLETION) - return (r); + err = usbd_device2interface_handle(dev, ifaceno, &iface); + if (err) + return (err); + err = usbd_endpoint_count(iface, &nendpt); + if (err) + return (err); for (endptno = 0; endptno < nendpt; endptno++) { ed = usbd_interface2endpoint_descriptor(iface,endptno); endpt = ed->bEndpointAddress; @@ -257,29 +258,31 @@ ugenopen(dev, flag, mode, p) int mode; struct proc *p; { + struct ugen_softc *sc; int unit = UGENUNIT(dev); int endpt = UGENENDPOINT(dev); usb_endpoint_descriptor_t *edesc; struct ugen_endpoint *sce; int dir, isize; - usbd_status r; + usbd_status err; USB_GET_SC_OPEN(ugen, unit, sc); + DPRINTFN(5, ("ugenopen: flag=%d, mode=%d, unit=%d endpt=%d\n", flag, mode, unit, endpt)); - if (!sc || sc->sc_dying) + if (sc == NULL || sc->sc_dying) return (ENXIO); + if (sc->sc_is_open[endpt]) + return (EBUSY); + if (endpt == USB_CONTROL_ENDPOINT) { - sc->sc_is_open[USB_CONTROL_ENDPOINT][IN] = 1; + sc->sc_is_open[USB_CONTROL_ENDPOINT] = 1; return (0); } /* Make sure there are pipes for all directions. */ for (dir = OUT; dir <= IN; dir++) { - if (sc->sc_is_open[endpt][dir]) - return (EBUSY); - if (flag & (dir == OUT ? FWRITE : FREAD)) { sce = &sc->sc_endpoints[endpt][dir]; if (sce == 0 || sce->edesc == 0) @@ -298,8 +301,6 @@ ugenopen(dev, flag, mode, p) DPRINTFN(5, ("ugenopen: sc=%p, endpt=%d, dir=%d, sce=%p\n", sc, endpt, dir, sce)); edesc = sce->edesc; - if (!edesc) - return (ENXIO); switch (edesc->bmAttributes & UE_XFERTYPE) { case UE_INTERRUPT: isize = UGETW(edesc->wMaxPacketSize); @@ -308,40 +309,31 @@ ugenopen(dev, flag, mode, p) sce->ibuf = malloc(isize, M_USBDEV, M_WAITOK); DPRINTFN(5, ("ugenopen: intr endpt=%d,isize=%d\n", endpt, isize)); -#if defined(__NetBSD__) || defined(__OpenBSD__) - if (clalloc(&sce->q, UGEN_IBSIZE, 0) == -1) - return (ENOMEM); -#elif defined(__FreeBSD__) - clist_alloc_cblocks(&sce->q, UGEN_IBSIZE, 0); -#endif - r = usbd_open_pipe_intr(sce->iface, + 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 (r != USBD_NORMAL_COMPLETION) { + if (err) { free(sce->ibuf, M_USBDEV); -#if defined(__NetBSD__) || defined(__OpenBSD__) clfree(&sce->q); -#elif defined(__FreeBSD__) - clist_free_cblocks(&sce->q); -#endif return (EIO); } DPRINTFN(5, ("ugenopen: interrupt open done\n")); break; case UE_BULK: - r = usbd_open_pipe(sce->iface, - edesc->bEndpointAddress, 0, - &sce->pipeh); - if (r != USBD_NORMAL_COMPLETION) + err = usbd_open_pipe(sce->iface, + edesc->bEndpointAddress, 0, &sce->pipeh); + if (err) return (EIO); break; case UE_CONTROL: case UE_ISOCHRONOUS: return (EINVAL); } - sc->sc_is_open[endpt][dir] = 1; } + sc->sc_is_open[endpt] = 1; return (0); } @@ -352,16 +344,18 @@ ugenclose(dev, flag, mode, p) int mode; struct proc *p; { - USB_GET_SC(ugen, UGENUNIT(dev), sc); int endpt = UGENENDPOINT(dev); + struct ugen_softc *sc; struct ugen_endpoint *sce; int dir; + USB_GET_SC(ugen, UGENUNIT(dev), sc); + DPRINTFN(5, ("ugenclose: flag=%d, mode=%d, unit=%d, endpt=%d\n", flag, mode, UGENUNIT(dev), endpt)); #ifdef DIAGNOSTIC - if (!sc->sc_is_open[endpt][IN] || !sc->sc_is_open[endpt][OUT] ) { + if (!sc->sc_is_open[endpt]) { printf("ugenclose: not open\n"); return (EINVAL); } @@ -369,7 +363,7 @@ ugenclose(dev, flag, mode, p) if (endpt == USB_CONTROL_ENDPOINT) { DPRINTFN(5, ("ugenclose: close control\n")); - sc->sc_is_open[USB_CONTROL_ENDPOINT][IN] = 0; + sc->sc_is_open[endpt] = 0; return (0); } @@ -377,31 +371,28 @@ ugenclose(dev, flag, mode, p) if (!(flag & (dir == OUT ? FWRITE : FREAD))) continue; sce = &sc->sc_endpoints[endpt][dir]; - if (!sce || !sce->pipeh) + if (sce == NULL || sce->pipeh == NULL) continue; 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 = 0; + sce->pipeh = NULL; - if (sce->ibuf) { + if (sce->ibuf != NULL) { free(sce->ibuf, M_USBDEV); - sce->ibuf = 0; -#if defined(__NetBSD__) || defined(__OpenBSD__) + sce->ibuf = NULL; clfree(&sce->q); -#elif defined(__FreeBSD__) - clist_free_cblocks(&sce->q); -#endif + } - sc->sc_is_open[endpt][dir] = 0; } + sc->sc_is_open[endpt] = 0; return (0); } -int +static int ugen_do_read(sc, endpt, uio, flag) struct ugen_softc *sc; int endpt; @@ -411,8 +402,8 @@ ugen_do_read(sc, endpt, uio, flag) struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][IN]; u_int32_t n, tn; char buf[UGEN_BBSIZE]; - usbd_request_handle reqh; - usbd_status r; + usbd_xfer_handle xfer; + usbd_status err; int s; int error = 0; u_char buffer[UGEN_CHUNK]; @@ -420,15 +411,19 @@ ugen_do_read(sc, endpt, uio, flag) #ifdef __NetBSD__ DPRINTFN(5, ("ugenread: %d:%d\n", sc->sc_dev.dv_unit, endpt)); #endif + if (sc->sc_dying) return (EIO); + if (endpt == USB_CONTROL_ENDPOINT) + return (ENODEV); + #ifdef DIAGNOSTIC - if (!sce->edesc) { + if (sce->edesc == NULL) { printf("ugenread: no edesc\n"); return (EIO); } - if (!sce->pipeh) { + if (sce->pipeh == NULL) { printf("ugenread: no pipe\n"); return (EIO); } @@ -473,21 +468,21 @@ ugen_do_read(sc, endpt, uio, flag) } break; case UE_BULK: - reqh = usbd_alloc_request(sc->sc_udev); - if (reqh == 0) + xfer = usbd_alloc_request(sc->sc_udev); + if (xfer == 0) return (ENOMEM); while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) { DPRINTFN(1, ("ugenread: start transfer %d bytes\n",n)); tn = n; - r = usbd_bulk_transfer( - reqh, sce->pipeh, + err = usbd_bulk_transfer( + xfer, sce->pipeh, sce->state & UGEN_SHORT_OK ? USBD_SHORT_XFER_OK : 0, sce->timeout, buf, &tn, "ugenrb"); - if (r != USBD_NORMAL_COMPLETION) { - if (r == USBD_INTERRUPTED) + if (err) { + if (err == USBD_INTERRUPTED) error = EINTR; - else if (r == USBD_TIMEOUT) + else if (err == USBD_TIMEOUT) error = ETIMEDOUT; else error = EIO; @@ -498,7 +493,7 @@ ugen_do_read(sc, endpt, uio, flag) if (error || tn < n) break; } - usbd_free_request(reqh); + usbd_free_request(xfer); break; default: return (ENXIO); @@ -512,10 +507,12 @@ ugenread(dev, uio, flag) struct uio *uio; int flag; { - USB_GET_SC(ugen, UGENUNIT(dev), sc); int endpt = UGENENDPOINT(dev); + struct ugen_softc *sc; int error; + USB_GET_SC(ugen, UGENUNIT(dev), sc); + sc->sc_refcnt++; error = ugen_do_read(sc, endpt, uio, flag); if (--sc->sc_refcnt < 0) @@ -523,7 +520,7 @@ ugenread(dev, uio, flag) return (error); } -int +static int ugen_do_write(sc, endpt, uio, flag) struct ugen_softc *sc; int endpt; @@ -534,45 +531,49 @@ ugen_do_write(sc, endpt, uio, flag) u_int32_t n; int error = 0; char buf[UGEN_BBSIZE]; - usbd_request_handle reqh; - usbd_status r; + usbd_xfer_handle xfer; + usbd_status err; + + DPRINTFN(5, ("%s: ugenwrite: %d\n", USBDEVNAME(sc->sc_dev), endpt)); if (sc->sc_dying) return (EIO); + if (endpt == USB_CONTROL_ENDPOINT) + return (ENODEV); + #ifdef DIAGNOSTIC - if (!sce->edesc) { + if (sce->edesc == NULL) { printf("ugenwrite: no edesc\n"); return (EIO); } - if (!sce->pipeh) { + if (sce->pipeh == NULL) { printf("ugenwrite: no pipe\n"); return (EIO); } #endif - DPRINTF(("ugenwrite\n")); switch (sce->edesc->bmAttributes & UE_XFERTYPE) { case UE_BULK: - reqh = usbd_alloc_request(sc->sc_udev); - if (reqh == 0) + xfer = usbd_alloc_request(sc->sc_udev); + if (xfer == 0) return (EIO); while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) { error = uiomove(buf, n, uio); if (error) break; DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n)); - r = usbd_bulk_transfer(reqh, sce->pipeh, 0, - sce->timeout, buf, &n,"ugenwb"); - if (r != USBD_NORMAL_COMPLETION) { - if (r == USBD_INTERRUPTED) + err = usbd_bulk_transfer(xfer, sce->pipeh, 0, + sce->timeout, buf, &n,"ugenwb"); + if (err) { + if (err == USBD_INTERRUPTED) error = EINTR; else error = EIO; break; } } - usbd_free_request(reqh); + usbd_free_request(xfer); break; default: return (ENXIO); @@ -586,10 +587,12 @@ ugenwrite(dev, uio, flag) struct uio *uio; int flag; { - USB_GET_SC(ugen, UGENUNIT(dev), sc); int endpt = UGENENDPOINT(dev); + struct ugen_softc *sc; int error; + USB_GET_SC(ugen, UGENUNIT(dev), sc); + sc->sc_refcnt++; error = ugen_do_write(sc, endpt, uio, flag); if (--sc->sc_refcnt < 0) @@ -597,7 +600,6 @@ ugenwrite(dev, uio, flag) return (error); } - #if defined(__NetBSD__) || defined(__OpenBSD__) int ugen_activate(self, act) @@ -669,9 +671,9 @@ USB_DETACH(ugen) return (0); } -void -ugenintr(reqh, addr, status) - usbd_request_handle reqh; +static void +ugenintr(xfer, addr, status) + usbd_xfer_handle xfer; usbd_private_handle addr; usbd_status status; { @@ -689,11 +691,11 @@ ugenintr(reqh, addr, status) return; } - usbd_get_request_status(reqh, 0, 0, &count, 0); + usbd_get_request_status(xfer, 0, 0, &count, 0); ibuf = sce->ibuf; - DPRINTFN(5, ("ugenintr: reqh=%p status=%d count=%d\n", - reqh, status, count)); + 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])); @@ -707,32 +709,32 @@ ugenintr(reqh, addr, status) selwakeup(&sce->rsel); } -usbd_status +static usbd_status ugen_set_interface(sc, ifaceidx, altno) struct ugen_softc *sc; int ifaceidx, altno; { usbd_interface_handle iface; usb_endpoint_descriptor_t *ed; - usbd_status r; + usbd_status err; struct ugen_endpoint *sce; u_int8_t niface, nendpt, endptno, endpt; int dir; DPRINTFN(15, ("ugen_set_interface %d %d\n", ifaceidx, altno)); - r = usbd_interface_count(sc->sc_udev, &niface); - if (r != USBD_NORMAL_COMPLETION) - return (r); + err = usbd_interface_count(sc->sc_udev, &niface); + if (err) + return (err); if (ifaceidx < 0 || ifaceidx >= niface) return (USBD_INVAL); - r = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface); - if (r != USBD_NORMAL_COMPLETION) - return (r); - r = usbd_endpoint_count(iface, &nendpt); - if (r != USBD_NORMAL_COMPLETION) - return (r); + err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface); + if (err) + return (err); + err = usbd_endpoint_count(iface, &nendpt); + if (err) + return (err); for (endptno = 0; endptno < nendpt; endptno++) { ed = usbd_interface2endpoint_descriptor(iface,endptno); endpt = ed->bEndpointAddress; @@ -744,13 +746,13 @@ ugen_set_interface(sc, ifaceidx, altno) } /* change setting */ - r = usbd_set_interface(iface, altno); - if (r != USBD_NORMAL_COMPLETION) - return (r); + err = usbd_set_interface(iface, altno); + if (err) + return (err); - r = usbd_endpoint_count(iface, &nendpt); - if (r != USBD_NORMAL_COMPLETION) - return (r); + err = usbd_endpoint_count(iface, &nendpt); + if (err) + return (err); for (endptno = 0; endptno < nendpt; endptno++) { ed = usbd_interface2endpoint_descriptor(iface,endptno); endpt = ed->bEndpointAddress; @@ -764,7 +766,7 @@ ugen_set_interface(sc, ifaceidx, altno) } /* Retrieve a complete descriptor for a certain device and index. */ -usb_config_descriptor_t * +static usb_config_descriptor_t * ugen_get_cdesc(sc, index, lenp) struct ugen_softc *sc; int index; @@ -772,7 +774,7 @@ ugen_get_cdesc(sc, index, lenp) { usb_config_descriptor_t *cdesc, *tdesc, cdescr; int len; - usbd_status r; + usbd_status err; if (index == USB_CURRENT_CONFIG_INDEX) { tdesc = usbd_get_config_descriptor(sc->sc_udev); @@ -783,16 +785,16 @@ ugen_get_cdesc(sc, index, lenp) memcpy(cdesc, tdesc, len); DPRINTFN(5,("ugen_get_cdesc: current, len=%d\n", len)); } else { - r = usbd_get_config_desc(sc->sc_udev, index, &cdescr); - if (r != USBD_NORMAL_COMPLETION) + err = usbd_get_config_desc(sc->sc_udev, index, &cdescr); + if (err) return (0); len = UGETW(cdescr.wTotalLength); DPRINTFN(5,("ugen_get_cdesc: index=%d, len=%d\n", index, len)); if (lenp) *lenp = len; cdesc = malloc(len, M_TEMP, M_WAITOK); - r = usbd_get_config_desc_full(sc->sc_udev, index, cdesc, len); - if (r != USBD_NORMAL_COMPLETION) { + err = usbd_get_config_desc_full(sc->sc_udev, index, cdesc, len); + if (err) { free(cdesc, M_TEMP); return (0); } @@ -800,21 +802,21 @@ ugen_get_cdesc(sc, index, lenp) return (cdesc); } -int +static int ugen_get_alt_index(sc, ifaceidx) struct ugen_softc *sc; int ifaceidx; { usbd_interface_handle iface; - usbd_status r; + usbd_status err; - r = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface); - if (r != USBD_NORMAL_COMPLETION) + err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface); + if (err) return (-1); return (usbd_get_interface_altindex(iface)); } -int +static int ugen_do_ioctl(sc, endpt, cmd, addr, flag, p) struct ugen_softc *sc; int endpt; @@ -824,7 +826,7 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p) struct proc *p; { struct ugen_endpoint *sce; - usbd_status r; + usbd_status err; usbd_interface_handle iface; struct usb_config_desc *cd; usb_config_descriptor_t *cdesc; @@ -849,8 +851,10 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p) if (endpt == USB_CONTROL_ENDPOINT) return (EINVAL); sce = &sc->sc_endpoints[endpt][IN]; + if (sce == NULL) + return (EINVAL); #ifdef DIAGNOSTIC - if (!sce->pipeh) { + if (sce->pipeh == NULL) { printf("ugenioctl: USB_SET_SHORT_XFER, no pipe\n"); return (EIO); } @@ -862,8 +866,10 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p) return (0); case USB_SET_TIMEOUT: sce = &sc->sc_endpoints[endpt][IN]; + if (sce == NULL) + return (EINVAL); #ifdef DIAGNOSTIC - if (!sce->pipeh) { + if (sce->pipeh == NULL) { printf("ugenioctl: USB_SET_TIMEOUT, no pipe\n"); return (EIO); } @@ -884,26 +890,26 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p) break; #endif case USB_GET_CONFIG: - r = usbd_get_config(sc->sc_udev, &conf); - if (r != USBD_NORMAL_COMPLETION) + err = usbd_get_config(sc->sc_udev, &conf); + if (err) return (EIO); *(int *)addr = conf; break; case USB_SET_CONFIG: if (!(flag & FWRITE)) return (EPERM); - r = ugen_set_config(sc, *(int *)addr); - if (r != USBD_NORMAL_COMPLETION) + err = ugen_set_config(sc, *(int *)addr); + if (err) return (EIO); break; case USB_GET_ALTINTERFACE: ai = (struct usb_alt_interface *)addr; - r = usbd_device2interface_handle(sc->sc_udev, - ai->interface_index, &iface); - if (r != USBD_NORMAL_COMPLETION) + err = usbd_device2interface_handle(sc->sc_udev, + ai->interface_index, &iface); + if (err) return (EINVAL); idesc = usbd_get_interface_descriptor(iface); - if (!idesc) + if (idesc == NULL) return (EIO); ai->alt_no = idesc->bAlternateSetting; break; @@ -911,21 +917,21 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p) if (!(flag & FWRITE)) return (EPERM); ai = (struct usb_alt_interface *)addr; - r = usbd_device2interface_handle(sc->sc_udev, - ai->interface_index, &iface); - if (r != USBD_NORMAL_COMPLETION) + err = usbd_device2interface_handle(sc->sc_udev, + ai->interface_index, &iface); + if (err) return (EINVAL); - r = ugen_set_interface(sc, ai->interface_index, ai->alt_no); - if (r != USBD_NORMAL_COMPLETION) + err = ugen_set_interface(sc, ai->interface_index, ai->alt_no); + if (err) return (EINVAL); break; case USB_GET_NO_ALT: ai = (struct usb_alt_interface *)addr; cdesc = ugen_get_cdesc(sc, ai->config_index, 0); - if (!cdesc) + if (cdesc == NULL) return (EINVAL); idesc = usbd_find_idesc(cdesc, ai->interface_index, 0); - if (!idesc) { + if (idesc == NULL) { free(cdesc, M_TEMP); return (EINVAL); } @@ -939,7 +945,7 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p) case USB_GET_CONFIG_DESC: cd = (struct usb_config_desc *)addr; cdesc = ugen_get_cdesc(sc, cd->config_index, 0); - if (!cdesc) + if (cdesc == NULL) return (EINVAL); cd->desc = *cdesc; free(cdesc, M_TEMP); @@ -947,7 +953,7 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p) case USB_GET_INTERFACE_DESC: id = (struct usb_interface_desc *)addr; cdesc = ugen_get_cdesc(sc, id->config_index, 0); - if (!cdesc) + if (cdesc == NULL) return (EINVAL); if (id->config_index == USB_CURRENT_CONFIG_INDEX && id->alt_index == USB_CURRENT_ALT_INDEX) @@ -955,7 +961,7 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p) else alt = id->alt_index; idesc = usbd_find_idesc(cdesc, id->interface_index, alt); - if (!idesc) { + if (idesc == NULL) { free(cdesc, M_TEMP); return (EINVAL); } @@ -965,7 +971,7 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p) case USB_GET_ENDPOINT_DESC: ed = (struct usb_endpoint_desc *)addr; cdesc = ugen_get_cdesc(sc, ed->config_index, 0); - if (!cdesc) + if (cdesc == NULL) return (EINVAL); if (ed->config_index == USB_CURRENT_CONFIG_INDEX && ed->alt_index == USB_CURRENT_ALT_INDEX) @@ -974,7 +980,7 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p) alt = ed->alt_index; edesc = usbd_find_edesc(cdesc, ed->interface_index, alt, ed->endpoint_index); - if (!edesc) { + if (edesc == NULL) { free(cdesc, M_TEMP); return (EINVAL); } @@ -1011,9 +1017,9 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p) } case USB_GET_STRING_DESC: si = (struct usb_string_desc *)addr; - r = usbd_get_string_desc(sc->sc_udev, si->string_index, - si->language_id, &si->desc); - if (r != USBD_NORMAL_COMPLETION) + err = usbd_get_string_desc(sc->sc_udev, si->string_index, + si->language_id, &si->desc); + if (err) return (EINVAL); break; case USB_DO_REQUEST: @@ -1023,7 +1029,7 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p) struct iovec iov; struct uio uio; void *ptr = 0; - usbd_status r; + usbd_status err; int error = 0; if (!(flag & FWRITE)) @@ -1058,9 +1064,9 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p) goto ret; } } - r = usbd_do_request_flags(sc->sc_udev, &ur->request, - ptr, ur->flags, &ur->actlen); - if (r != USBD_NORMAL_COMPLETION) { + err = usbd_do_request_flags(sc->sc_udev, &ur->request, + ptr, ur->flags, &ur->actlen); + if (err) { error = EIO; goto ret; } @@ -1078,7 +1084,7 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p) } case USB_GET_DEVICEINFO: usbd_fill_deviceinfo(sc->sc_udev, - (struct usb_device_info *)addr); + (struct usb_device_info *)addr); break; default: return (EINVAL); @@ -1094,10 +1100,12 @@ ugenioctl(dev, cmd, addr, flag, p) int flag; struct proc *p; { - USB_GET_SC(ugen, UGENUNIT(dev), sc); int endpt = UGENENDPOINT(dev); + struct ugen_softc *sc; int error; + 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) @@ -1111,16 +1119,20 @@ ugenpoll(dev, events, p) int events; struct proc *p; { - USB_GET_SC(ugen, UGENUNIT(dev), sc); + struct ugen_softc *sc; struct ugen_endpoint *sce; int revents = 0; int s; + USB_GET_SC(ugen, UGENUNIT(dev), sc); + if (sc->sc_dying) return (EIO); /* XXX always IN */ sce = &sc->sc_endpoints[UGENENDPOINT(dev)][IN]; + if (sce == NULL) + return (EINVAL); #ifdef DIAGNOSTIC if (!sce->edesc) { printf("ugenwrite: no edesc\n"); |