diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2015-11-12 13:01:12 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2015-11-12 13:01:12 +0100 |
commit | 02279d6272b22e96ca418c5a2dd9d32c46d16ee1 (patch) | |
tree | 5d85f7010c479473520105484ded7f23394304ee /freebsd/sys/dev/usb/usb_request.c | |
parent | Rename kernel space log() to _bsd_log() (diff) | |
download | rtems-libbsd-02279d6272b22e96ca418c5a2dd9d32c46d16ee1.tar.bz2 |
USB: Update to FreeBSD trunk 2015-11-10
Diffstat (limited to 'freebsd/sys/dev/usb/usb_request.c')
-rw-r--r-- | freebsd/sys/dev/usb/usb_request.c | 99 |
1 files changed, 73 insertions, 26 deletions
diff --git a/freebsd/sys/dev/usb/usb_request.c b/freebsd/sys/dev/usb/usb_request.c index 6f9d7b12..39e03c6e 100644 --- a/freebsd/sys/dev/usb/usb_request.c +++ b/freebsd/sys/dev/usb/usb_request.c @@ -28,6 +28,9 @@ * SUCH DAMAGE. */ +#ifdef USB_GLOBAL_INCLUDE_FILE +#include USB_GLOBAL_INCLUDE_FILE +#else #include <sys/stdint.h> #include <sys/stddef.h> #include <rtems/bsd/sys/param.h> @@ -67,15 +70,16 @@ #include <dev/usb/usb_controller.h> #include <dev/usb/usb_bus.h> #include <sys/ctype.h> +#endif /* USB_GLOBAL_INCLUDE_FILE */ static int usb_no_cs_fail; -SYSCTL_INT(_hw_usb, OID_AUTO, no_cs_fail, CTLFLAG_RW, +SYSCTL_INT(_hw_usb, OID_AUTO, no_cs_fail, CTLFLAG_RWTUN, &usb_no_cs_fail, 0, "USB clear stall failures are ignored, if set"); static int usb_full_ddesc; -SYSCTL_INT(_hw_usb, OID_AUTO, full_ddesc, CTLFLAG_RW, +SYSCTL_INT(_hw_usb, OID_AUTO, full_ddesc, CTLFLAG_RWTUN, &usb_full_ddesc, 0, "USB always read complete device descriptor, if set"); #ifdef USB_DEBUG @@ -109,21 +113,21 @@ static struct usb_ctrl_debug usb_ctrl_debug = { .bRequest_value = -1, }; -SYSCTL_INT(_hw_usb, OID_AUTO, ctrl_bus_fail, CTLFLAG_RW, +SYSCTL_INT(_hw_usb, OID_AUTO, ctrl_bus_fail, CTLFLAG_RWTUN, &usb_ctrl_debug.bus_index, 0, "USB controller index to fail"); -SYSCTL_INT(_hw_usb, OID_AUTO, ctrl_dev_fail, CTLFLAG_RW, +SYSCTL_INT(_hw_usb, OID_AUTO, ctrl_dev_fail, CTLFLAG_RWTUN, &usb_ctrl_debug.dev_index, 0, "USB device address to fail"); -SYSCTL_INT(_hw_usb, OID_AUTO, ctrl_ds_fail, CTLFLAG_RW, +SYSCTL_INT(_hw_usb, OID_AUTO, ctrl_ds_fail, CTLFLAG_RWTUN, &usb_ctrl_debug.ds_fail, 0, "USB fail data stage"); -SYSCTL_INT(_hw_usb, OID_AUTO, ctrl_ss_fail, CTLFLAG_RW, +SYSCTL_INT(_hw_usb, OID_AUTO, ctrl_ss_fail, CTLFLAG_RWTUN, &usb_ctrl_debug.ss_fail, 0, "USB fail status stage"); -SYSCTL_INT(_hw_usb, OID_AUTO, ctrl_ds_delay, CTLFLAG_RW, +SYSCTL_INT(_hw_usb, OID_AUTO, ctrl_ds_delay, CTLFLAG_RWTUN, &usb_ctrl_debug.ds_delay, 0, "USB data stage delay in ms"); -SYSCTL_INT(_hw_usb, OID_AUTO, ctrl_ss_delay, CTLFLAG_RW, +SYSCTL_INT(_hw_usb, OID_AUTO, ctrl_ss_delay, CTLFLAG_RWTUN, &usb_ctrl_debug.ss_delay, 0, "USB status stage delay in ms"); -SYSCTL_INT(_hw_usb, OID_AUTO, ctrl_rt_fail, CTLFLAG_RW, +SYSCTL_INT(_hw_usb, OID_AUTO, ctrl_rt_fail, CTLFLAG_RWTUN, &usb_ctrl_debug.bmRequestType_value, 0, "USB bmRequestType to fail"); -SYSCTL_INT(_hw_usb, OID_AUTO, ctrl_rv_fail, CTLFLAG_RW, +SYSCTL_INT(_hw_usb, OID_AUTO, ctrl_rv_fail, CTLFLAG_RWTUN, &usb_ctrl_debug.bRequest_value, 0, "USB bRequest to fail"); /*------------------------------------------------------------------------* @@ -226,6 +230,7 @@ usb_do_clear_stall_callback(struct usb_xfer *xfer, usb_error_t error) struct usb_endpoint *ep; struct usb_endpoint *ep_end; struct usb_endpoint *ep_first; + usb_stream_t x; uint8_t to; udev = xfer->xroot->udev; @@ -253,9 +258,11 @@ tr_transferred: ep->is_stalled = 0; /* some hardware needs a callback to clear the data toggle */ usbd_clear_stall_locked(udev, ep); - /* start up the current or next transfer, if any */ - usb_command_wrapper(&ep->endpoint_q, - ep->endpoint_q.curr); + for (x = 0; x != USB_MAX_EP_STREAMS; x++) { + /* start the current or next transfer, if any */ + usb_command_wrapper(&ep->endpoint_q[x], + ep->endpoint_q[x].curr); + } } ep++; @@ -1265,10 +1272,49 @@ done: } /*------------------------------------------------------------------------* + * usbd_alloc_config_desc + * + * This function is used to allocate a zeroed configuration + * descriptor. + * + * Returns: + * NULL: Failure + * Else: Success + *------------------------------------------------------------------------*/ +void * +usbd_alloc_config_desc(struct usb_device *udev, uint32_t size) +{ + if (size > USB_CONFIG_MAX) { + DPRINTF("Configuration descriptor too big\n"); + return (NULL); + } +#if (USB_HAVE_FIXED_CONFIG == 0) + return (malloc(size, M_USBDEV, M_ZERO | M_WAITOK)); +#else + memset(udev->config_data, 0, sizeof(udev->config_data)); + return (udev->config_data); +#endif +} + +/*------------------------------------------------------------------------* + * usbd_alloc_config_desc + * + * This function is used to free a configuration descriptor. + *------------------------------------------------------------------------*/ +void +usbd_free_config_desc(struct usb_device *udev, void *ptr) +{ +#if (USB_HAVE_FIXED_CONFIG == 0) + free(ptr, M_USBDEV); +#endif +} + +/*------------------------------------------------------------------------* * usbd_req_get_config_desc_full * * This function gets the complete USB configuration descriptor and - * ensures that "wTotalLength" is correct. + * ensures that "wTotalLength" is correct. The returned configuration + * descriptor is freed by calling "usbd_free_config_desc()". * * Returns: * 0: Success @@ -1276,12 +1322,11 @@ done: *------------------------------------------------------------------------*/ usb_error_t usbd_req_get_config_desc_full(struct usb_device *udev, struct mtx *mtx, - struct usb_config_descriptor **ppcd, struct malloc_type *mtype, - uint8_t index) + struct usb_config_descriptor **ppcd, uint8_t index) { struct usb_config_descriptor cd; struct usb_config_descriptor *cdesc; - uint16_t len; + uint32_t len; usb_error_t err; DPRINTFN(4, "index=%d\n", index); @@ -1289,23 +1334,25 @@ usbd_req_get_config_desc_full(struct usb_device *udev, struct mtx *mtx, *ppcd = NULL; err = usbd_req_get_config_desc(udev, mtx, &cd, index); - if (err) { + if (err) return (err); - } + /* get full descriptor */ len = UGETW(cd.wTotalLength); - if (len < sizeof(*cdesc)) { + if (len < (uint32_t)sizeof(*cdesc)) { /* corrupt descriptor */ return (USB_ERR_INVAL); + } else if (len > USB_CONFIG_MAX) { + DPRINTF("Configuration descriptor was truncated\n"); + len = USB_CONFIG_MAX; } - cdesc = malloc(len, mtype, M_WAITOK); - if (cdesc == NULL) { + cdesc = usbd_alloc_config_desc(udev, len); + if (cdesc == NULL) return (USB_ERR_NOMEM); - } err = usbd_req_get_desc(udev, mtx, NULL, cdesc, len, len, 0, UDESC_CONFIG, index, 3); if (err) { - free(cdesc, mtype); + usbd_free_config_desc(udev, cdesc); return (err); } /* make sure that the device is not fooling us: */ @@ -1915,9 +1962,9 @@ usbd_setup_device_desc(struct usb_device *udev, struct mtx *mtx) break; default: - DPRINTF("Minimum MaxPacketSize is large enough " + DPRINTF("Minimum bMaxPacketSize is large enough " "to hold the complete device descriptor or " - "only once MaxPacketSize choice\n"); + "only one bMaxPacketSize choice\n"); /* get the full device descriptor */ err = usbd_req_get_device_desc(udev, mtx, &udev->ddesc); |