From owner-freebsd-usb@freebsd.org Tue Jan 5 08:25:26 2016 Return-Path: Delivered-To: freebsd-usb@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id D7FC7A560F2 for ; Tue, 5 Jan 2016 08:25:26 +0000 (UTC) (envelope-from hps@selasky.org) Received: from mail.turbocat.net (mail.turbocat.net [IPv6:2a01:4f8:d16:4514::2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 7119A115D for ; Tue, 5 Jan 2016 08:25:26 +0000 (UTC) (envelope-from hps@selasky.org) Received: from laptop015.home.selasky.org (unknown [62.141.129.119]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.turbocat.net (Postfix) with ESMTPSA id 3E6621FE022; Tue, 5 Jan 2016 09:25:23 +0100 (CET) Subject: Re: dwc_otg: Problem with directly connected full/low speed devices To: Sebastian Huber , freebsd-usb@freebsd.org References: <568B69FE.5030307@embedded-brains.de> From: Hans Petter Selasky Message-ID: <568B7E74.5080600@selasky.org> Date: Tue, 5 Jan 2016 09:27:32 +0100 User-Agent: Mozilla/5.0 (X11; FreeBSD amd64; rv:38.0) Gecko/20100101 Thunderbird/38.4.0 MIME-Version: 1.0 In-Reply-To: <568B69FE.5030307@embedded-brains.de> Content-Type: multipart/mixed; boundary="------------090207000504090507060103" X-BeenThere: freebsd-usb@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FreeBSD support for USB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 05 Jan 2016 08:25:27 -0000 This is a multi-part message in MIME format. --------------090207000504090507060103 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit On 01/05/16 08:00, Sebastian Huber wrote: > Hello, > > I use an Altera Cyclone V development kit which the dwc_otg driver from > FreeBSD. The device enumeration of full/low speed devices directly > connected to the root hub fails since split transactions are used. If I > connect them via a hub it works fine. I used the following hack to get > them working with a direct connection: > > diff --git a/sys/dev/usb/controller/dwc_otg.c > b/sys/dev/usb/controller/dwc_otg.c > index 2110b94..37cca8e 100644 > --- a/sys/dev/usb/controller/dwc_otg.c > +++ b/sys/dev/usb/controller/dwc_otg.c > @@ -3340,7 +3340,7 @@ dwc_otg_setup_standard_chain(struct usb_xfer *xfer) > case USB_SPEED_FULL: > case USB_SPEED_LOW: > /* check if root HUB port is running High Speed */ > - if (xfer->xroot->udev->parent_hs_hub != NULL) { > + if (xfer->xroot->udev->parent_hs_hub != NULL && > 0) { > hcsplt = HCSPLT_SPLTENA | > (xfer->xroot->udev->hs_port_no << > HCSPLT_PRTADDR_SHIFT) | > > I am not sure how to fix this properly. Is this a specific problem with > the Altera Cyclone V board or is this problem also present on other > boards e.g. RPI2? > Hi, Does the attached patch solve your problem? --HPS --------------090207000504090507060103 Content-Type: text/x-patch; name="dwc_otg.c.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="dwc_otg.c.diff" Index: dwc_otg.c =================================================================== --- dwc_otg.c (revision 293158) +++ dwc_otg.c (working copy) @@ -456,6 +456,18 @@ return (0); } +static uint8_t +dwc_otg_uses_split(struct usb_device *udev) +{ + /* + * When a LOW or FULL speed device is connected directly to + * the USB port we don't use split transactions: + */ + return (udev->speed != USB_SPEED_HIGH && + udev->parent_hs_hub != NULL && + udev->parent_hs_hub->parent_hub != NULL); +} + static void dwc_otg_update_host_frame_interval(struct dwc_otg_softc *sc) { @@ -3329,16 +3341,16 @@ else hcchar |= (td->ep_type << HCCHAR_EPTYPE_SHIFT); - if (usbd_get_speed(xfer->xroot->udev) == USB_SPEED_LOW) - hcchar |= HCCHAR_LSPDDEV; if (UE_GET_DIR(xfer->endpointno) == UE_DIR_IN) hcchar |= HCCHAR_EPDIR_IN; switch (xfer->xroot->udev->speed) { + case USB_SPEED_LOW: + hcchar |= HCCHAR_LSPDDEV; + /* FALLTHROUGH */ case USB_SPEED_FULL: - case USB_SPEED_LOW: /* check if root HUB port is running High Speed */ - if (xfer->xroot->udev->parent_hs_hub != NULL) { + if (dwc_otg_uses_split(xfer->xroot->udev)) { hcsplt = HCSPLT_SPLTENA | (xfer->xroot->udev->hs_port_no << HCSPLT_PRTADDR_SHIFT) | @@ -4160,7 +4172,10 @@ framenum = DSTS_SOFFN_GET(temp); } - if (xfer->xroot->udev->parent_hs_hub != NULL) + /* + * Check if port is doing 8000 or 1000 frames per second: + */ + if (sc->sc_flags.status_high_speed) framenum /= 8; framenum &= DWC_OTG_FRAME_MASK; @@ -4837,7 +4852,7 @@ td = USB_ADD_BYTES(parm->buf, parm->size[0]); /* compute shared bandwidth resource index for TT */ - if (parm->udev->parent_hs_hub != NULL && parm->udev->speed != USB_SPEED_HIGH) { + if (dwc_otg_uses_split(parm->udev)) { if (parm->udev->parent_hs_hub->ddesc.bDeviceProtocol == UDPROTO_HSHUBMTT) td->tt_index = parm->udev->device_index; else --------------090207000504090507060103--