Index: ugen.c =================================================================== RCS file: /repos/projects/mirrored/freebsd/src/sys/dev/usb/ugen.c,v retrieving revision 1.38.2.12 diff -u -r1.38.2.12 ugen.c --- ugen.c 31 Dec 2004 08:15:19 -0000 1.38.2.12 +++ ugen.c 28 Apr 2005 00:15:50 -0000 @@ -573,19 +573,21 @@ return (0); } +#define RBFSIZ 131072 Static int ugen_do_read(struct ugen_softc *sc, int endpt, struct uio *uio, int flag) { struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][IN]; u_int32_t n, tn; - char buf[UGEN_BBSIZE]; + char * buf; usbd_xfer_handle xfer; usbd_status err; int s; int error = 0; u_char buffer[UGEN_CHUNK]; + DPRINTFN(5, ("%s: ugenread: %d\n", USBDEVNAME(sc->sc_dev), endpt)); if (sc->sc_dying) @@ -608,6 +610,8 @@ } #endif + buf = malloc(RBFSIZ, M_TEMP, M_WAITOK); + switch (sce->edesc->bmAttributes & UE_XFERTYPE) { case UE_INTERRUPT: /* Block until activity occurred. */ @@ -615,6 +619,7 @@ while (sce->q.c_cc == 0) { if (flag & IO_NDELAY) { splx(s); + free(buf, M_TEMP); return (EWOULDBLOCK); } sce->state |= UGEN_ASLP; @@ -648,9 +653,11 @@ break; case UE_BULK: xfer = usbd_alloc_xfer(sc->sc_udev); - if (xfer == 0) + if (xfer == 0) { + free(buf, M_TEMP); return (ENOMEM); - while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) { + } + while ((n = min(RBFSIZ, uio->uio_resid)) != 0) { DPRINTFN(1, ("ugenread: start transfer %d bytes\n",n)); tn = n; err = usbd_bulk_transfer( @@ -679,6 +686,7 @@ while (sce->cur == sce->fill) { if (flag & IO_NDELAY) { splx(s); + free(buf, M_TEMP); return (EWOULDBLOCK); } sce->state |= UGEN_ASLP; @@ -714,8 +722,10 @@ default: + free(buf, M_TEMP); return (ENXIO); } + free(buf, M_TEMP); return (error); } Index: usb_port.h =================================================================== RCS file: /repos/projects/mirrored/freebsd/src/sys/dev/usb/usb_port.h,v retrieving revision 1.25.2.8 diff -u -r1.25.2.8 usb_port.h --- usb_port.h 1 Mar 2004 00:07:22 -0000 1.25.2.8 +++ usb_port.h 28 Apr 2005 00:15:50 -0000 @@ -7,7 +7,7 @@ * $NetBSD: usb_port.h,v 1.58 2002/10/01 01:25:26 thorpej Exp $ */ -/* +/*- * Copyright (c) 1998 The NetBSD Foundation, Inc. * All rights reserved. * @@ -134,7 +134,8 @@ #define USB_ATTACH_ERROR_RETURN return #define USB_ATTACH_SUCCESS_RETURN return -#define USB_ATTACH_SETUP printf("\n") +#define USB_ATTACH_SETUP + printf("\n%s: %s\n", USBDEVNAME(sc->sc_dev), devinfo); #define USB_DETACH(dname) \ int __CONCAT(dname,_detach)(struct device *self, int flags) @@ -301,7 +302,8 @@ #define USB_ATTACH_ERROR_RETURN return #define USB_ATTACH_SUCCESS_RETURN return -#define USB_ATTACH_SETUP printf("\n") +#define USB_ATTACH_SETUP + printf("\n%s: %s\n", USBDEVNAME(sc->sc_dev), devinfo); #define USB_DETACH(dname) \ int \ @@ -386,6 +388,7 @@ #define usb_callout_init(h) callout_init(&(h), 0) #define usb_callout(h, t, f, d) callout_reset(&(h), (t), (f), (d)) #define usb_uncallout(h, f, d) callout_stop(&(h)) +#define usb_uncallout_drain(h, f, d) callout_drain(&(h)) #else typedef struct proc *usb_proc_ptr; @@ -417,7 +420,12 @@ #define PWR_RESUME 0 #define PWR_SUSPEND 1 -#define config_detach(dev, flag) device_delete_child(device_get_parent(dev), dev) +#define config_detach(dev, flag) \ + do { \ + device_detach(dev); \ + free(device_get_ivars(dev), M_USB); \ + device_delete_child(device_get_parent(dev), dev); \ + } while (0); typedef struct malloc_type *usb_malloc_type; @@ -470,8 +478,11 @@ #define USB_ATTACH_SUCCESS_RETURN return 0 #define USB_ATTACH_SETUP \ - sc->sc_dev = self; \ - device_set_desc_copy(self, devinfo) + do { \ + sc->sc_dev = self; \ + device_set_desc_copy(self, devinfo); \ + device_printf(self, "%s\n", devinfo); \ + } while (0); #define USB_DETACH(dname) \ Static int \ Index: usb_subr.c =================================================================== RCS file: /repos/projects/mirrored/freebsd/src/sys/dev/usb/usb_subr.c,v retrieving revision 1.23.2.20 diff -u -r1.23.2.20 usb_subr.c --- usb_subr.c 8 Dec 2004 08:52:30 -0000 1.23.2.20 +++ usb_subr.c 28 Apr 2005 00:15:50 -0000 @@ -7,12 +7,13 @@ * $NetBSD: usb_subr.c,v 1.114 2004/06/23 02:30:52 mycroft Exp $ * $NetBSD: usb_subr.c,v 1.115 2004/06/23 05:23:19 mycroft Exp $ * $NetBSD: usb_subr.c,v 1.116 2004/06/23 06:27:54 mycroft Exp $ + * $NetBSD: usb_subr.c,v 1.119 2004/10/23 13:26:33 augustss Exp $ */ #include __FBSDID("$FreeBSD: src/sys/dev/usb/usb_subr.c,v 1.23.2.20 2004/12/08 08:52:30 julian Exp $"); -/* +/*- * Copyright (c) 1998 The NetBSD Foundation, Inc. * All rights reserved. * @@ -49,6 +50,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include "opt_usb.h" + #include #include #include @@ -88,7 +91,6 @@ Static usbd_status usbd_set_config(usbd_device_handle, int); Static void usbd_devinfo_vp(usbd_device_handle, char *, char *, int); -Static char *usbd_get_string(usbd_device_handle, int, char *); Static int usbd_getnewaddr(usbd_bus_handle bus); #if defined(__NetBSD__) Static int usbd_print(void *aux, const char *pnp); @@ -194,51 +196,6 @@ return (USBD_NORMAL_COMPLETION); } -char * -usbd_get_string(usbd_device_handle dev, int si, char *buf) -{ - int swap = dev->quirks->uq_flags & UQ_SWAP_UNICODE; - usb_string_descriptor_t us; - char *s; - int i, n; - u_int16_t c; - usbd_status err; - int size; - - if (si == 0) - return (0); - if (dev->quirks->uq_flags & UQ_NO_STRINGS) - return (0); - if (dev->langid == USBD_NOLANG) { - /* Set up default language */ - err = usbd_get_string_desc(dev, USB_LANGUAGE_TABLE, 0, &us, - &size); - if (err || size < 4) { - dev->langid = 0; /* Well, just pick something then */ - } else { - /* Pick the first language as the default. */ - dev->langid = UGETW(us.bString[0]); - } - } - err = usbd_get_string_desc(dev, si, dev->langid, &us, &size); - if (err) - return (0); - s = buf; - n = size / 2 - 1; - for (i = 0; i < n; i++) { - c = UGETW(us.bString[i]); - /* Convert from Unicode, handle buggy strings. */ - if ((c & 0xff00) == 0) - *s++ = c; - else if ((c & 0x00ff) == 0 && swap) - *s++ = c >> 8; - else - *s++ = '?'; - } - *s++ = 0; - return (buf); -} - Static void usbd_trim_spaces(char *p) { @@ -270,9 +227,15 @@ } if (usedev) { - vendor = usbd_get_string(dev, udd->iManufacturer, v); + if (usbd_get_string(dev, udd->iManufacturer, v)) + vendor = NULL; + else + vendor = v; usbd_trim_spaces(vendor); - product = usbd_get_string(dev, udd->iProduct, p); + if (usbd_get_string(dev, udd->iProduct, p)) + product = NULL; + else + product = p; usbd_trim_spaces(product); if (vendor && !*vendor) vendor = NULL; @@ -864,21 +827,25 @@ int found, i, confi, nifaces; usbd_status err; device_ptr_t dv; + device_ptr_t *tmpdv; usbd_interface_handle ifaces[256]; /* 256 is the absolute max */ #if defined(__FreeBSD__) - /* - * XXX uaa is a static var. Not a problem as it _should_ be used only - * during probe and attach. Should be changed however. - */ - device_t bdev; + /* XXX FreeBSD may leak resources on failure cases -- fixme */ + device_t bdev; + struct usb_attach_arg *uaap; + bdev = device_add_child(parent, NULL, -1); if (!bdev) { - printf("%s: Device creation failed\n", USBDEVNAME(dev->bus->bdev)); - return (USBD_INVAL); + device_printf(parent, "Device creation failed\n"); + return (USBD_INVAL); } - device_set_ivars(bdev, &uaa); device_quiet(bdev); + uaap = malloc(sizeof(uaa), M_USB, M_NOWAIT); + if (uaap == NULL) { + return (USBD_INVAL); + } + device_set_ivars(bdev, uaap); #endif uaa.device = dev; @@ -895,16 +862,25 @@ /* First try with device specific drivers. */ DPRINTF(("usbd_probe_and_attach: trying device specific drivers\n")); + + dev->ifacenums = NULL; + dev->subdevs = malloc(2 * sizeof dv, M_USB, M_NOWAIT); + if (dev->subdevs == NULL) + return (USBD_NOMEM); + dev->subdevs[0] = bdev; + dev->subdevs[1] = 0; + *uaap = uaa; dv = USB_DO_ATTACH(dev, bdev, parent, &uaa, usbd_print, usbd_submatch); if (dv) { - dev->subdevs = malloc(2 * sizeof dv, M_USB, M_NOWAIT); - if (dev->subdevs == NULL) - return (USBD_NOMEM); - dev->subdevs[0] = dv; - dev->subdevs[1] = 0; return (USBD_NORMAL_COMPLETION); } - + /* + * Free subdevs so we can reallocate it larger for the number of + * interfaces + */ + tmpdv = dev->subdevs; + dev->subdevs = NULL; + free(tmpdv, M_USB); DPRINTF(("usbd_probe_and_attach: no device specific driver found\n")); DPRINTF(("usbd_probe_and_attach: looping over %d configurations\n", @@ -923,10 +899,6 @@ printf("%s: port %d, set config at addr %d failed\n", USBDEVPTRNAME(parent), port, addr); #endif -#if defined(__FreeBSD__) - device_delete_child(parent, bdev); -#endif - return (err); } nifaces = dev->cdesc->bNumInterface; @@ -937,9 +909,11 @@ uaa.nifaces = nifaces; dev->subdevs = malloc((nifaces+1) * sizeof dv, M_USB,M_NOWAIT); if (dev->subdevs == NULL) { -#if defined(__FreeBSD__) - device_delete_child(parent, bdev); -#endif + return (USBD_NOMEM); + } + dev->ifacenums = malloc((nifaces) * sizeof(*dev->ifacenums), + M_USB,M_NOWAIT); + if (dev->ifacenums == NULL) { return (USBD_NOMEM); } @@ -949,35 +923,48 @@ continue; /* interface already claimed */ uaa.iface = ifaces[i]; uaa.ifaceno = ifaces[i]->idesc->bInterfaceNumber; + dev->subdevs[found] = bdev; + dev->subdevs[found + 1] = 0; + dev->ifacenums[found] = i; + *uaap = uaa; dv = USB_DO_ATTACH(dev, bdev, parent, &uaa, usbd_print, usbd_submatch); if (dv != NULL) { - dev->subdevs[found++] = dv; - dev->subdevs[found] = 0; ifaces[i] = 0; /* consumed */ + found++; #if defined(__FreeBSD__) /* create another child for the next iface */ bdev = device_add_child(parent, NULL, -1); if (!bdev) { - printf("%s: Device creation failed\n", - USBDEVNAME(dev->bus->bdev)); + device_printf(parent, + "Device add failed\n"); return (USBD_NORMAL_COMPLETION); } - device_set_ivars(bdev, &uaa); + uaap = malloc(sizeof(uaa), M_USB, M_NOWAIT); + if (uaap == NULL) { + return (USBD_NOMEM); + } + device_set_ivars(bdev, uaap); device_quiet(bdev); #endif + } else { + dev->subdevs[found] = 0; } } if (found != 0) { #if defined(__FreeBSD__) - /* remove the last created child again; it is unused */ + /* remove the last created child. It is unused */ device_delete_child(parent, bdev); + /* free(uaap, M_USB); */ /* May be needed? xxx */ #endif return (USBD_NORMAL_COMPLETION); } - free(dev->subdevs, M_USB); - dev->subdevs = 0; + tmpdv = dev->subdevs; + dev->subdevs = NULL; + free(tmpdv, M_USB); + free(dev->ifacenums, M_USB); + dev->ifacenums = NULL; } /* No interfaces were attached in any of the configurations. */ @@ -991,13 +978,15 @@ uaa.usegeneric = 1; uaa.configno = UHUB_UNK_CONFIGURATION; uaa.ifaceno = UHUB_UNK_INTERFACE; + dev->subdevs = malloc(2 * sizeof dv, M_USB, M_NOWAIT); + if (dev->subdevs == 0) { + return (USBD_NOMEM); + } + dev->subdevs[0] = bdev; + dev->subdevs[1] = 0; + *uaap = uaa; dv = USB_DO_ATTACH(dev, bdev, parent, &uaa, usbd_print, usbd_submatch); if (dv != NULL) { - dev->subdevs = malloc(2 * sizeof dv, M_USB, M_NOWAIT); - if (dev->subdevs == 0) - return (USBD_NOMEM); - dev->subdevs[0] = dv; - dev->subdevs[1] = 0; return (USBD_NORMAL_COMPLETION); } @@ -1007,9 +996,6 @@ * fully operational and not harming anyone. */ DPRINTF(("usbd_probe_and_attach: generic attach failed\n")); -#if defined(__FreeBSD__) - device_delete_child(parent, bdev); -#endif return (USBD_NORMAL_COMPLETION); } @@ -1195,7 +1181,7 @@ usbd_status usbd_reload_device_desc(usbd_device_handle dev) { - usbd_status err = USBD_NORMAL_COMPLETION; + usbd_status err = 0; int i; /* Get the full device descriptor. */ @@ -1345,11 +1331,15 @@ di->udi_speed = dev->speed; if (dev->subdevs != NULL) { - for (i = 0; dev->subdevs[i] && - i < USB_MAX_DEVNAMES; i++) { - strncpy(di->udi_devnames[i], USBDEVPTRNAME(dev->subdevs[i]), - USB_MAX_DEVNAMELEN); - di->udi_devnames[i][USB_MAX_DEVNAMELEN-1] = '\0'; + for (i = 0; dev->subdevs[i] && i < USB_MAX_DEVNAMES; i++) { + if (device_is_attached(dev->subdevs[i])) { + strncpy(di->udi_devnames[i], + USBDEVPTRNAME(dev->subdevs[i]), + USB_MAX_DEVNAMELEN - 1); + di->udi_devnames[i][USB_MAX_DEVNAMELEN-1] + = '\0'; + } else + di->udi_devnames[i][0] = 0; } } else { i = 0; @@ -1400,6 +1390,8 @@ free(dev->cdesc, M_USB); if (dev->subdevs != NULL) free(dev->subdevs, M_USB); + if (dev->ifacenums != NULL) + free(dev->ifacenums, M_USB); free(dev, M_USB); } Index: usbdevs.h =================================================================== RCS file: /repos/projects/mirrored/freebsd/src/sys/dev/usb/Attic/usbdevs.h,v retrieving revision 1.32.2.61 diff -u -r1.32.2.61 usbdevs.h --- usbdevs.h 8 Dec 2004 22:15:06 -0000 1.32.2.61 +++ usbdevs.h 28 Apr 2005 00:15:50 -0000 @@ -1,4 +1,4 @@ -/* $FreeBSD: src/sys/dev/usb/usbdevs.h,v 1.32.2.61 2004/12/08 22:15:06 rsm Exp $ */ +/* ??? */ /* * THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. Index: usbdevs_data.h =================================================================== RCS file: /repos/projects/mirrored/freebsd/src/sys/dev/usb/Attic/usbdevs_data.h,v retrieving revision 1.32.2.61 diff -u -r1.32.2.61 usbdevs_data.h --- usbdevs_data.h 8 Dec 2004 22:15:06 -0000 1.32.2.61 +++ usbdevs_data.h 28 Apr 2005 00:15:50 -0000 @@ -1,4 +1,4 @@ -/* $FreeBSD: src/sys/dev/usb/usbdevs_data.h,v 1.32.2.61 2004/12/08 22:15:06 rsm Exp $ */ +/* ??? */ /* * THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. Index: usbdi.c =================================================================== RCS file: /repos/projects/mirrored/freebsd/src/sys/dev/usb/usbdi.c,v retrieving revision 1.34.2.11 diff -u -r1.34.2.11 usbdi.c --- usbdi.c 26 Nov 2004 00:34:20 -0000 1.34.2.11 +++ usbdi.c 28 Apr 2005 00:15:50 -0000 @@ -1,9 +1,9 @@ -/* $NetBSD: usbdi.c,v 1.103 2002/09/27 15:37:38 provos Exp $ */ +/* $NetBSD: usbdi.c,v 1.106 2004/10/24 12:52:40 augustss Exp $ */ #include __FBSDID("$FreeBSD: src/sys/dev/usb/usbdi.c,v 1.34.2.11 2004/11/26 00:34:20 julian Exp $"); -/* +/*- * Copyright (c) 1998 The NetBSD Foundation, Inc. * All rights reserved. * @@ -43,6 +43,7 @@ #include #include #if defined(__NetBSD__) || defined(__OpenBSD__) +#include #include #elif defined(__FreeBSD__) #include @@ -62,6 +63,7 @@ #include #include #include +#include #if defined(__FreeBSD__) #include "usb_if.h" @@ -241,7 +243,7 @@ ipipe->repeat = 1; err = usbd_transfer(xfer); *pipe = ipipe; - if (err != USBD_IN_PROGRESS) + if (err != USBD_IN_PROGRESS && err) goto bad2; return (USBD_NORMAL_COMPLETION); @@ -527,6 +529,12 @@ return (dev->cdesc); } +int +usbd_get_speed(usbd_device_handle dev) +{ + return (dev->speed); +} + usb_interface_descriptor_t * usbd_get_interface_descriptor(usbd_interface_handle iface) { @@ -572,6 +580,12 @@ } usbd_status +usbd_abort_default_pipe(usbd_device_handle dev) +{ + return (usbd_abort_pipe(dev->default_pipe)); +} + +usbd_status usbd_clear_endpoint_stall(usbd_pipe_handle pipe) { usbd_device_handle dev = pipe->device; @@ -779,6 +793,9 @@ { usbd_pipe_handle pipe = xfer->pipe; usb_dma_t *dmap = &xfer->dmabuf; + int sync = xfer->flags & USBD_SYNCHRONOUS; + int erred = xfer->status == USBD_CANCELLED || + xfer->status == USBD_TIMEOUT; int repeat = pipe->repeat; int polling; @@ -863,14 +880,12 @@ pipe->methods->done(xfer); #endif - if ((xfer->flags & USBD_SYNCHRONOUS) && !polling) + if (sync && !polling) wakeup(xfer); if (!repeat) { /* XXX should we stop the queue on all errors? */ - if ((xfer->status == USBD_CANCELLED || - xfer->status == USBD_TIMEOUT) && - pipe->iface != NULL) /* not control pipe */ + if (erred && pipe->iface != NULL) /* not control pipe */ pipe->running = 0; else usbd_start_next(pipe); @@ -1068,7 +1083,7 @@ usbd_setup_default_xfer(xfer, dev, 0, USBD_DEFAULT_TIMEOUT, req, data, UGETW(req->wLength), 0, usbd_do_request_async_cb); err = usbd_transfer(xfer); - if (err != USBD_IN_PROGRESS) { + if (err != USBD_IN_PROGRESS && err) { usbd_free_xfer(xfer); return (err); } @@ -1158,6 +1173,86 @@ return (NULL); } + +void +usb_desc_iter_init(usbd_device_handle dev, usbd_desc_iter_t *iter) +{ + const usb_config_descriptor_t *cd = usbd_get_config_descriptor(dev); + + iter->cur = (const uByte *)cd; + iter->end = (const uByte *)cd + UGETW(cd->wTotalLength); +} + +const usb_descriptor_t * +usb_desc_iter_next(usbd_desc_iter_t *iter) +{ + const usb_descriptor_t *desc; + + if (iter->cur + sizeof(usb_descriptor_t) >= iter->end) { + if (iter->cur != iter->end) + printf("usb_desc_iter_next: bad descriptor\n"); + return NULL; + } + desc = (const usb_descriptor_t *)iter->cur; + if (desc->bLength == 0) { + printf("usb_desc_iter_next: descriptor length = 0\n"); + return NULL; + } + iter->cur += desc->bLength; + if (iter->cur > iter->end) { + printf("usb_desc_iter_next: descriptor length too large\n"); + return NULL; + } + return desc; +} + +usbd_status +usbd_get_string(usbd_device_handle dev, int si, char *buf) +{ + int swap = dev->quirks->uq_flags & UQ_SWAP_UNICODE; + usb_string_descriptor_t us; + char *s; + int i, n; + u_int16_t c; + usbd_status err; + int size; + + buf[0] = '\0'; + if (si == 0) + return (USBD_INVAL); + if (dev->quirks->uq_flags & UQ_NO_STRINGS) + return (USBD_STALLED); + if (dev->langid == USBD_NOLANG) { + /* Set up default language */ + err = usbd_get_string_desc(dev, USB_LANGUAGE_TABLE, 0, &us, + &size); + if (err || size < 4) { + DPRINTFN(-1,("usbd_get_string: getting lang failed, using 0\n")); + dev->langid = 0; /* Well, just pick something then */ + } else { + /* Pick the first language as the default. */ + dev->langid = UGETW(us.bString[0]); + } + } + err = usbd_get_string_desc(dev, si, dev->langid, &us, &size); + if (err) + return (err); + s = buf; + n = size / 2 - 1; + for (i = 0; i < n; i++) { + c = UGETW(us.bString[i]); + /* Convert from Unicode, handle buggy strings. */ + if ((c & 0xff00) == 0) + *s++ = c; + else if ((c & 0x00ff) == 0 && swap) + *s++ = c >> 8; + else + *s++ = '?'; + } + *s++ = 0; + return (USBD_NORMAL_COMPLETION); +} + #if defined(__FreeBSD__) int usbd_driver_load(module_t mod, int what, void *arg) Index: usbdi.h =================================================================== RCS file: /repos/projects/mirrored/freebsd/src/sys/dev/usb/usbdi.h,v retrieving revision 1.21.2.6 diff -u -r1.21.2.6 usbdi.h --- usbdi.h 8 Dec 2004 08:22:05 -0000 1.21.2.6 +++ usbdi.h 28 Apr 2005 00:15:50 -0000 @@ -1,7 +1,7 @@ -/* $NetBSD: usbdi.h,v 1.62 2002/07/11 21:14:35 augustss Exp $ */ -/* $FreeBSD: src/sys/dev/usb/usbdi.h,v 1.21.2.6 2004/12/08 08:22:05 julian Exp $ */ +/* $NetBSD: usbdi.h,v 1.64 2004/10/23 13:26:34 augustss Exp $ */ +/* $FreeBSD: src/sys/dev/usb/usbdi.h,v 1.58 2005/03/25 13:22:58 sobomax Exp $ */ -/* +/*- * Copyright (c) 1998 The NetBSD Foundation, Inc. * All rights reserved. * @@ -38,6 +38,9 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef _USBDI_H_ +#define _USBDI_H_ + typedef struct usbd_bus *usbd_bus_handle; typedef struct usbd_device *usbd_device_handle; typedef struct usbd_interface *usbd_interface_handle; @@ -95,78 +98,75 @@ #define USB_CDEV_MAJOR 108 #endif -usbd_status usbd_open_pipe(usbd_interface_handle iface, u_int8_t address, - u_int8_t flags, usbd_pipe_handle *pipe); -usbd_status usbd_close_pipe(usbd_pipe_handle pipe); -usbd_status usbd_transfer(usbd_xfer_handle req); +usbd_status usbd_open_pipe(usbd_interface_handle, u_int8_t, + u_int8_t, usbd_pipe_handle *); +usbd_status usbd_close_pipe(usbd_pipe_handle); +usbd_status usbd_transfer(usbd_xfer_handle); usbd_xfer_handle usbd_alloc_xfer(usbd_device_handle); -usbd_status usbd_free_xfer(usbd_xfer_handle xfer); -void usbd_setup_xfer(usbd_xfer_handle xfer, usbd_pipe_handle pipe, - usbd_private_handle priv, void *buffer, - u_int32_t length, u_int16_t flags, u_int32_t timeout, +usbd_status usbd_free_xfer(usbd_xfer_handle); +void usbd_setup_xfer(usbd_xfer_handle, usbd_pipe_handle, + usbd_private_handle, void *, + u_int32_t, u_int16_t, u_int32_t, usbd_callback); -void usbd_setup_default_xfer(usbd_xfer_handle xfer, usbd_device_handle dev, - usbd_private_handle priv, u_int32_t timeout, - usb_device_request_t *req, void *buffer, - u_int32_t length, u_int16_t flags, usbd_callback); -void usbd_setup_isoc_xfer(usbd_xfer_handle xfer, usbd_pipe_handle pipe, - usbd_private_handle priv, u_int16_t *frlengths, - u_int32_t nframes, u_int16_t flags, usbd_callback); -void usbd_get_xfer_status(usbd_xfer_handle xfer, usbd_private_handle *priv, - void **buffer, u_int32_t *count, usbd_status *status); +void usbd_setup_default_xfer(usbd_xfer_handle, usbd_device_handle, + usbd_private_handle, u_int32_t, + usb_device_request_t *, void *, + u_int32_t, u_int16_t, usbd_callback); +void usbd_setup_isoc_xfer(usbd_xfer_handle, usbd_pipe_handle, + usbd_private_handle, u_int16_t *, + u_int32_t, u_int16_t, usbd_callback); +void usbd_get_xfer_status(usbd_xfer_handle, usbd_private_handle *, + void **, u_int32_t *, usbd_status *); usb_endpoint_descriptor_t *usbd_interface2endpoint_descriptor - (usbd_interface_handle iface, u_int8_t address); -usbd_status usbd_abort_pipe(usbd_pipe_handle pipe); -usbd_status usbd_clear_endpoint_stall(usbd_pipe_handle pipe); -usbd_status usbd_clear_endpoint_stall_async(usbd_pipe_handle pipe); -void usbd_clear_endpoint_toggle(usbd_pipe_handle pipe); -usbd_status usbd_endpoint_count(usbd_interface_handle dev, u_int8_t *count); -usbd_status usbd_interface_count(usbd_device_handle dev, u_int8_t *count); -void usbd_interface2device_handle(usbd_interface_handle iface, - usbd_device_handle *dev); -usbd_status usbd_device2interface_handle(usbd_device_handle dev, - u_int8_t ifaceno, usbd_interface_handle *iface); + (usbd_interface_handle, u_int8_t); +usbd_status usbd_abort_pipe(usbd_pipe_handle); +usbd_status usbd_abort_default_pipe(usbd_device_handle); +usbd_status usbd_clear_endpoint_stall(usbd_pipe_handle); +usbd_status usbd_clear_endpoint_stall_async(usbd_pipe_handle); +void usbd_clear_endpoint_toggle(usbd_pipe_handle); +usbd_status usbd_endpoint_count(usbd_interface_handle, u_int8_t *); +usbd_status usbd_interface_count(usbd_device_handle, u_int8_t *); +void usbd_interface2device_handle(usbd_interface_handle, + usbd_device_handle *); +usbd_status usbd_device2interface_handle(usbd_device_handle, + u_int8_t, usbd_interface_handle *); usbd_device_handle usbd_pipe2device_handle(usbd_pipe_handle); -void *usbd_alloc_buffer(usbd_xfer_handle xfer, u_int32_t size); -void usbd_free_buffer(usbd_xfer_handle xfer); -void *usbd_get_buffer(usbd_xfer_handle xfer); -usbd_status usbd_sync_transfer(usbd_xfer_handle req); -usbd_status usbd_open_pipe_intr(usbd_interface_handle iface, u_int8_t address, - u_int8_t flags, usbd_pipe_handle *pipe, - usbd_private_handle priv, void *buffer, - u_int32_t length, usbd_callback, int); -usbd_status usbd_do_request(usbd_device_handle pipe, usb_device_request_t *req, - void *data); -usbd_status usbd_do_request_async(usbd_device_handle pipe, - usb_device_request_t *req, void *data); -usbd_status usbd_do_request_flags(usbd_device_handle pipe, - usb_device_request_t *req, - void *data, u_int16_t flags, int*, u_int32_t); -usbd_status usbd_do_request_flags_pipe( - usbd_device_handle dev, usbd_pipe_handle pipe, - usb_device_request_t *req, void *data, u_int16_t flags, int *actlen, - u_int32_t); +void *usbd_alloc_buffer(usbd_xfer_handle, u_int32_t); +void usbd_free_buffer(usbd_xfer_handle); +void *usbd_get_buffer(usbd_xfer_handle); +usbd_status usbd_sync_transfer(usbd_xfer_handle); +usbd_status usbd_open_pipe_intr(usbd_interface_handle, u_int8_t, + u_int8_t, usbd_pipe_handle *, + usbd_private_handle, void *, + u_int32_t, usbd_callback, int); +usbd_status usbd_do_request(usbd_device_handle, usb_device_request_t *, void *); +usbd_status usbd_do_request_async(usbd_device_handle, + usb_device_request_t *, void *); +usbd_status usbd_do_request_flags(usbd_device_handle, usb_device_request_t *, + void *, u_int16_t, int*, u_int32_t); +usbd_status usbd_do_request_flags_pipe(usbd_device_handle, usbd_pipe_handle, + usb_device_request_t *, void *, u_int16_t, int *, u_int32_t); usb_interface_descriptor_t *usbd_get_interface_descriptor - (usbd_interface_handle iface); -usb_config_descriptor_t *usbd_get_config_descriptor(usbd_device_handle dev); -usb_device_descriptor_t *usbd_get_device_descriptor(usbd_device_handle dev); + (usbd_interface_handle); +usb_config_descriptor_t *usbd_get_config_descriptor(usbd_device_handle); +usb_device_descriptor_t *usbd_get_device_descriptor(usbd_device_handle); +int usbd_get_speed(usbd_device_handle); usbd_status usbd_set_interface(usbd_interface_handle, int); int usbd_get_no_alts(usb_config_descriptor_t *, int); -usbd_status usbd_get_interface(usbd_interface_handle iface, u_int8_t *aiface); +usbd_status usbd_get_interface(usbd_interface_handle, u_int8_t *); void usbd_fill_deviceinfo(usbd_device_handle, struct usb_device_info *, int); -int usbd_get_interface_altindex(usbd_interface_handle iface); +int usbd_get_interface_altindex(usbd_interface_handle); -usb_interface_descriptor_t *usbd_find_idesc(usb_config_descriptor_t *cd, - int iindex, int ano); -usb_endpoint_descriptor_t *usbd_find_edesc(usb_config_descriptor_t *cd, - int ifaceidx, int altidx, - int endptidx); +usb_interface_descriptor_t *usbd_find_idesc(usb_config_descriptor_t *, + int, int); +usb_endpoint_descriptor_t *usbd_find_edesc(usb_config_descriptor_t *, + int, int, int); void usbd_dopoll(usbd_interface_handle); -void usbd_set_polling(usbd_device_handle dev, int on); +void usbd_set_polling(usbd_device_handle, int); -const char *usbd_errstr(usbd_status err); +const char *usbd_errstr(usbd_status); void usbd_add_dev_event(int, usbd_device_handle); void usbd_add_drv_event(int, usbd_device_handle, device_ptr_t); @@ -174,12 +174,22 @@ void usbd_devinfo(usbd_device_handle, int, char *); const struct usbd_quirks *usbd_get_quirks(usbd_device_handle); usb_endpoint_descriptor_t *usbd_get_endpoint_descriptor - (usbd_interface_handle iface, u_int8_t address); + (usbd_interface_handle, u_int8_t); usbd_status usbd_reload_device_desc(usbd_device_handle); int usbd_ratecheck(struct timeval *last); +usbd_status usbd_get_string(usbd_device_handle dev, int si, char *buf); + +/* An iterator for descriptors. */ +typedef struct { + const uByte *cur; + const uByte *end; +} usbd_desc_iter_t; +void usb_desc_iter_init(usbd_device_handle dev, usbd_desc_iter_t *iter); +const usb_descriptor_t *usb_desc_iter_next(usbd_desc_iter_t *iter); + /* * The usb_task structs form a queue of things to run in the USB event * thread. Normally this is just device discovery when a connect/disconnect @@ -193,16 +203,16 @@ char onqueue; }; -void usb_add_task(usbd_device_handle dev, struct usb_task *task); -void usb_rem_task(usbd_device_handle dev, struct usb_task *task); +void usb_add_task(usbd_device_handle, struct usb_task *); +void usb_rem_task(usbd_device_handle, struct usb_task *); #define usb_init_task(t, f, a) ((t)->fun = (f), (t)->arg = (a), (t)->onqueue = 0) struct usb_devno { u_int16_t ud_vendor; u_int16_t ud_product; }; -const struct usb_devno *usb_match_device(const struct usb_devno *tbl, - u_int nentries, u_int sz, u_int16_t vendor, u_int16_t product); +const struct usb_devno *usb_match_device(const struct usb_devno *, + u_int, u_int, u_int16_t, u_int16_t); #define usb_lookup(tbl, vendor, product) \ usb_match_device((const struct usb_devno *)(tbl), sizeof (tbl) / sizeof ((tbl)[0]), sizeof ((tbl)[0]), (vendor), (product)) #define USB_PRODUCT_ANY 0xffff @@ -286,3 +296,5 @@ #endif /* USB_USE_SOFTINTR */ #define splhardusb splbio #define IPL_USB IPL_BIO + +#endif /* _USBDI_H_ */ Index: usbdi_util.c =================================================================== RCS file: /repos/projects/mirrored/freebsd/src/sys/dev/usb/usbdi_util.c,v retrieving revision 1.15.2.6 diff -u -r1.15.2.6 usbdi_util.c --- usbdi_util.c 1 Mar 2004 00:07:23 -0000 1.15.2.6 +++ usbdi_util.c 28 Apr 2005 00:15:50 -0000 @@ -1,6 +1,6 @@ -/* $NetBSD: usbdi_util.c,v 1.36 2001/11/13 06:24:57 lukem Exp $ */ +/* $NetBSD: usbdi_util.c,v 1.42 2004/12/03 08:53:40 augustss Exp $ */ -/* +/*- * Copyright (c) 1998 The NetBSD Foundation, Inc. * All rights reserved. * @@ -221,6 +221,25 @@ return (usbd_do_request(dev, &req, 0)); } +usbd_status +usbd_get_protocol(usbd_interface_handle iface, u_int8_t *report) +{ + usb_interface_descriptor_t *id = usbd_get_interface_descriptor(iface); + usbd_device_handle dev; + usb_device_request_t req; + + DPRINTFN(4, ("usbd_get_protocol: iface=%p, endpt=%d\n", + iface, id->bInterfaceNumber)); + if (id == NULL) + return (USBD_IOERROR); + usbd_interface2device_handle(iface, &dev); + req.bmRequestType = UT_READ_CLASS_INTERFACE; + req.bRequest = UR_GET_PROTOCOL; + USETW(req.wValue, 0); + USETW(req.wIndex, id->bInterfaceNumber); + USETW(req.wLength, 1); + return (usbd_do_request(dev, &req, report)); +} usbd_status usbd_set_protocol(usbd_interface_handle iface, int report) @@ -290,8 +309,8 @@ usbd_device_handle dev; usb_device_request_t req; - DPRINTFN(4, ("usbd_set_report: len=%d\n", len)); - if (id == 0) + DPRINTFN(4, ("usbd_get_report: len=%d\n", len)); + if (ifd == NULL) return (USBD_IOERROR); usbd_interface2device_handle(iface, &dev); req.bmRequestType = UT_READ_CLASS_INTERFACE; @@ -345,7 +364,7 @@ char *p, *end; if (idesc == NULL) - return (0); + return (NULL); usbd_interface2device_handle(ifc, &dev); cdesc = usbd_get_config_descriptor(dev); @@ -359,7 +378,7 @@ if (hd->bDescriptorType == UDESC_INTERFACE) break; } - return (0); + return (NULL); } usbd_status @@ -431,7 +450,7 @@ splx(s); return (err); } - error = tsleep(xfer, PZERO | PCATCH, lbl, 0); + error = tsleep((caddr_t)xfer, PZERO | PCATCH, lbl, 0); splx(s); if (error) { DPRINTF(("usbd_bulk_transfer: tsleep=%d\n", error)); @@ -505,3 +524,20 @@ DPRINTF(("usb_detach_wakeup: for %s\n", USBDEVPTRNAME(dv))); wakeup(dv); } + +const usb_descriptor_t * +usb_find_desc(usbd_device_handle dev, int type, int subtype) +{ + usbd_desc_iter_t iter; + const usb_descriptor_t *desc; + + usb_desc_iter_init(dev, &iter); + for (;;) { + desc = usb_desc_iter_next(&iter); + if (!desc || (desc->bDescriptorType == type && + (subtype == USBD_SUBTYPE_ANY || + subtype == desc->bDescriptorSubtype))) + break; + } + return desc; +} Index: usbdi_util.h =================================================================== RCS file: /repos/projects/mirrored/freebsd/src/sys/dev/usb/usbdi_util.h,v retrieving revision 1.9.2.4 diff -u -r1.9.2.4 usbdi_util.h --- usbdi_util.h 8 Dec 2004 07:55:48 -0000 1.9.2.4 +++ usbdi_util.h 28 Apr 2005 00:15:50 -0000 @@ -1,7 +1,7 @@ -/* $NetBSD: usbdi_util.h,v 1.23 2001/10/26 17:58:22 augustss Exp $ */ -/* $FreeBSD: src/sys/dev/usb/usbdi_util.h,v 1.9.2.4 2004/12/08 07:55:48 julian Exp $ */ +/* $NetBSD: usbdi_util.h,v 1.31 2004/12/03 08:53:40 augustss Exp $ */ +/* $FreeBSD$ */ -/* +/*- * Copyright (c) 1998 The NetBSD Foundation, Inc. * All rights reserved. * @@ -54,6 +54,7 @@ usbd_status usbd_clear_port_feature(usbd_device_handle, int, int); usbd_status usbd_get_device_status(usbd_device_handle, usb_status_t *); usbd_status usbd_get_hub_status(usbd_device_handle, usb_hub_status_t *); +usbd_status usbd_get_protocol(usbd_interface_handle dev, u_int8_t *report); usbd_status usbd_set_protocol(usbd_interface_handle dev, int report); usbd_status usbd_get_report_descriptor(usbd_device_handle dev, int ifcno, int size, void *d); @@ -88,3 +89,7 @@ void usb_detach_wait(device_ptr_t); void usb_detach_wakeup(device_ptr_t); +const usb_descriptor_t *usb_find_desc(usbd_device_handle dev, int type, + int subtype); +#define USBD_SUBTYPE_ANY (~0) + Index: usbdivar.h =================================================================== RCS file: /repos/projects/mirrored/freebsd/src/sys/dev/usb/usbdivar.h,v retrieving revision 1.14.2.4 diff -u -r1.14.2.4 usbdivar.h --- usbdivar.h 24 Nov 2004 18:55:46 -0000 1.14.2.4 +++ usbdivar.h 28 Apr 2005 00:15:50 -0000 @@ -1,7 +1,7 @@ /* $NetBSD: usbdivar.h,v 1.70 2002/07/11 21:14:36 augustss Exp $ */ /* $FreeBSD: src/sys/dev/usb/usbdivar.h,v 1.14.2.4 2004/11/24 18:55:46 julian Exp $ */ -/* +/*- * Copyright (c) 1998 The NetBSD Foundation, Inc. * All rights reserved. * @@ -155,6 +155,7 @@ const struct usbd_quirks *quirks; /* device quirks, always set */ struct usbd_hub *hub; /* only if this is a hub */ device_ptr_t *subdevs; /* sub-devices, 0 terminated */ + uint8_t *ifacenums; /* sub-device interfacenumbers */ }; struct usbd_interface {