From owner-svn-src-all@FreeBSD.ORG Fri Mar 14 08:42:31 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id C30581AE; Fri, 14 Mar 2014 08:42:31 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id AF83669D; Fri, 14 Mar 2014 08:42:31 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s2E8gVtZ080595; Fri, 14 Mar 2014 08:42:31 GMT (envelope-from hselasky@svn.freebsd.org) Received: (from hselasky@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s2E8gUTP080588; Fri, 14 Mar 2014 08:42:30 GMT (envelope-from hselasky@svn.freebsd.org) Message-Id: <201403140842.s2E8gUTP080588@svn.freebsd.org> From: Hans Petter Selasky Date: Fri, 14 Mar 2014 08:42:30 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r263159 - in head/sys/dev: sound/usb usb X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Mar 2014 08:42:31 -0000 Author: hselasky Date: Fri Mar 14 08:42:30 2014 New Revision: 263159 URL: http://svnweb.freebsd.org/changeset/base/263159 Log: Workaround for USB MIDI adapters which use non-supported values of wMaxPacketSize for BULK endpoints. MFC after: 1 week Modified: head/sys/dev/sound/usb/uaudio.c head/sys/dev/usb/usb_core.h head/sys/dev/usb/usb_transfer.c head/sys/dev/usb/usbdi.h Modified: head/sys/dev/sound/usb/uaudio.c ============================================================================== --- head/sys/dev/sound/usb/uaudio.c Fri Mar 14 07:58:11 2014 (r263158) +++ head/sys/dev/sound/usb/uaudio.c Fri Mar 14 08:42:30 2014 (r263159) @@ -5674,6 +5674,25 @@ umidi_probe(device_t dev) DPRINTF("error=%s\n", usbd_errstr(error)); goto detach; } + + /* + * Some USB MIDI device makers couldn't resist using + * wMaxPacketSize = 4 for RX and TX BULK endpoints, although + * that size is an unsupported value for FULL speed BULK + * endpoints. The same applies to some HIGH speed MIDI devices + * which are using a wMaxPacketSize different from 512 bytes. + * + * Refer to section 5.8.3 in USB 2.0 PDF: Cite: "All Host + * Controllers are required to have support for 8-, 16-, 32-, + * and 64-byte maximum packet sizes for full-speed bulk + * endpoints and 512 bytes for high-speed bulk endpoints." + */ + if (usbd_xfer_maxp_was_clamped(chan->xfer[UMIDI_TX_TRANSFER])) + chan->single_command = 1; + + if (chan->single_command != 0) + device_printf(dev, "Single command MIDI quirk enabled\n"); + if ((chan->max_cable > UMIDI_CABLES_MAX) || (chan->max_cable == 0)) { chan->max_cable = UMIDI_CABLES_MAX; Modified: head/sys/dev/usb/usb_core.h ============================================================================== --- head/sys/dev/usb/usb_core.h Fri Mar 14 07:58:11 2014 (r263158) +++ head/sys/dev/usb/usb_core.h Fri Mar 14 08:42:30 2014 (r263159) @@ -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 */ }; /* Modified: head/sys/dev/usb/usb_transfer.c ============================================================================== --- head/sys/dev/usb/usb_transfer.c Fri Mar 14 07:58:11 2014 (r263158) +++ head/sys/dev/usb/usb_transfer.c Fri Mar 14 08:42:30 2014 (r263159) @@ -346,6 +346,7 @@ usbd_transfer_setup_sub(struct usb_setup 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 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 } } + /* + * 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 { 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); +} Modified: head/sys/dev/usb/usbdi.h ============================================================================== --- head/sys/dev/usb/usbdi.h Fri Mar 14 07:58:11 2014 (r263158) +++ head/sys/dev/usb/usbdi.h Fri Mar 14 08:42:30 2014 (r263159) @@ -569,6 +569,7 @@ int usbd_xfer_is_stalled(struct usb_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);