diff options
author | hselasky <hselasky@FreeBSD.org> | 2014-03-14 08:42:30 +0000 |
---|---|---|
committer | hselasky <hselasky@FreeBSD.org> | 2014-03-14 08:42:30 +0000 |
commit | 6bbd5680a4df771c980fdd36dcf78dc9dae915d7 (patch) | |
tree | 8a3b75d06927aee1ad6354b789d7bfa23e6faf3d /sys/dev/usb | |
parent | 7961add611c0111412dc670fa7b7386b3ca135d2 (diff) | |
download | FreeBSD-src-6bbd5680a4df771c980fdd36dcf78dc9dae915d7.zip FreeBSD-src-6bbd5680a4df771c980fdd36dcf78dc9dae915d7.tar.gz |
Workaround for USB MIDI adapters which use non-supported values of
wMaxPacketSize for BULK endpoints.
MFC after: 1 week
Diffstat (limited to 'sys/dev/usb')
-rw-r--r-- | sys/dev/usb/usb_core.h | 2 | ||||
-rw-r--r-- | sys/dev/usb/usb_transfer.c | 23 | ||||
-rw-r--r-- | sys/dev/usb/usbdi.h | 1 |
3 files changed, 26 insertions, 0 deletions
diff --git a/sys/dev/usb/usb_core.h b/sys/dev/usb/usb_core.h index afd74ed..bea7c2c 100644 --- a/sys/dev/usb/usb_core.h +++ b/sys/dev/usb/usb_core.h @@ -114,6 +114,8 @@ struct usb_xfer_flags_int { uint8_t can_cancel_immed:1; /* set if USB transfer can be * cancelled immediately */ uint8_t doing_callback:1; /* set if executing the callback */ + uint8_t maxp_was_clamped:1; /* set if the max packet size + * was outside its allowed range */ }; /* diff --git a/sys/dev/usb/usb_transfer.c b/sys/dev/usb/usb_transfer.c index dccac40..db912bc 100644 --- a/sys/dev/usb/usb_transfer.c +++ b/sys/dev/usb/usb_transfer.c @@ -346,6 +346,7 @@ usbd_transfer_setup_sub(struct usb_setup_params *parm) usb_frcount_t n_frlengths; usb_frcount_t n_frbuffers; usb_frcount_t x; + uint16_t maxp_old; uint8_t type; uint8_t zmps; @@ -433,6 +434,11 @@ usbd_transfer_setup_sub(struct usb_setup_params *parm) if (xfer->max_packet_count > parm->hc_max_packet_count) { xfer->max_packet_count = parm->hc_max_packet_count; } + + /* store max packet size value before filtering */ + + maxp_old = xfer->max_packet_size; + /* filter "wMaxPacketSize" according to HC capabilities */ if ((xfer->max_packet_size > parm->hc_max_packet_size) || @@ -465,6 +471,13 @@ usbd_transfer_setup_sub(struct usb_setup_params *parm) } } + /* + * Check if the max packet size was outside its allowed range + * and clamped to a valid value: + */ + if (maxp_old != xfer->max_packet_size) + xfer->flags_int.maxp_was_clamped = 1; + /* compute "max_frame_size" */ usbd_update_max_frame_size(xfer); @@ -3432,3 +3445,13 @@ usbd_xfer_get_timestamp(struct usb_xfer *xfer) { return (xfer->isoc_time_complete); } + +/* + * The following function returns non-zero if the max packet size + * field was clamped to a valid value. Else it returns zero. + */ +uint8_t +usbd_xfer_maxp_was_clamped(struct usb_xfer *xfer) +{ + return (xfer->flags_int.maxp_was_clamped); +} diff --git a/sys/dev/usb/usbdi.h b/sys/dev/usb/usbdi.h index 099b390..f4c6cf9 100644 --- a/sys/dev/usb/usbdi.h +++ b/sys/dev/usb/usbdi.h @@ -569,6 +569,7 @@ int usbd_xfer_is_stalled(struct usb_xfer *xfer); void usbd_xfer_set_flag(struct usb_xfer *xfer, int flag); void usbd_xfer_clr_flag(struct usb_xfer *xfer, int flag); uint16_t usbd_xfer_get_timestamp(struct usb_xfer *xfer); +uint8_t usbd_xfer_maxp_was_clamped(struct usb_xfer *xfer); void usbd_copy_in(struct usb_page_cache *cache, usb_frlength_t offset, const void *ptr, usb_frlength_t len); |