From owner-freebsd-usb@FreeBSD.ORG Thu Jun 27 06:46:00 2013 Return-Path: Delivered-To: usb@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id 14F075B9; Thu, 27 Jun 2013 06:46:00 +0000 (UTC) (envelope-from hps@bitfrost.no) Received: from mta.bitpro.no (mta.bitpro.no [92.42.64.202]) by mx1.freebsd.org (Postfix) with ESMTP id A36C41CE8; Thu, 27 Jun 2013 06:45:59 +0000 (UTC) Received: from mail.bitfrost.no (mail.bitfrost.no [46.29.221.36]) by mta.bitpro.no (Postfix) with ESMTP id B23C77A191; Thu, 27 Jun 2013 08:45:58 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bitfrost.no Received: from laptop015.hselasky.homeunix.org (cm-176.74.213.204.customer.telag.net [176.74.213.204]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) (Authenticated sender: hanspetter) by mail.bitfrost.no (Postfix) with ESMTPSA id 4C1552215E; Thu, 27 Jun 2013 08:45:55 +0200 (CEST) Message-ID: <51CBDFEA.7050203@bitfrost.no> Date: Thu, 27 Jun 2013 08:47:06 +0200 From: Hans Petter Selasky Organization: Bitfrost A/S MIME-Version: 1.0 To: Oleksandr Tymoshenko Subject: Re: Beaglebone USB driver (Mentor Graphics OTG) References: <51608AA4.2020804@bluezbox.com> <51611A7B.2010105@bitfrost.no> <0927BB4C-6917-408D-B102-AB98F72314B6@bluezbox.com> In-Reply-To: <0927BB4C-6917-408D-B102-AB98F72314B6@bluezbox.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: arm@freebsd.org, usb@freebsd.org X-BeenThere: freebsd-usb@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: FreeBSD support for USB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 27 Jun 2013 06:46:00 -0000 On 06/27/13 02:53, Oleksandr Tymoshenko wrote: > > On 2013-04-07, at 12:04 AM, Hans Petter Selasky wrote: > >> On 04/06/13 22:50, Oleksandr Tymoshenko wrote: >>> Hello, >>> >>> This is first iteration of Host Mode support for Mentor Graphics >>> OTG USB controller. I tested it by building kernel with USB memory >>> stick mounted as /usr/obj, resulting kernel was bootable and worked fine. >>> I reused some ideas (mostly for channel-management) from >>> DWT OTG driver. >>> >>> Some pieces are still missing: >>> - Support for SPLIT transactions, I don not have high speed hub >>> right now to test it, but implementing it should be really >>> straighforward. >>> - Isochronous transfers. I do not have hardware to test this. Does >>> anybody have any suggestion about simple use case? >>> - Control Data OUT transaction >>> - Wrapper for atmel HW has not ben synced with new core logic requirements >>> yet >>> >>> Please review and test. I tested it only with gcc-built kernel/world. >>> Now when >>> first iteration is finished I'm going to update all my boards to new >>> world order >>> (clang/EABI) and re-test this stuff. >>> >>> Patch: >>> http://people.freebsd.org/~gonzo/arm/patches/beaglebone-musb.diff >> >> Hi, >> >> Looks like you've got the grasp of the USB controller stuff :-) >> >> Some comments: >> >> 1) Use DPRINTFN(-1, ...) instead of printf() for all printf() that are not part of boot dmesg. >> >> + break; >> + default: >> + td->transfer_type = 0; >> + printf("Invalid USB speed: %d\n", speed); >> + break; >> + } >> >> >> 2) You should implement if HOST mode, support for SUSPEND and RESUME. See EHCI driver. Basically what you need is: >> >> a) USB transfers are stopped/paused. I know there is a hack you need if the host transfer cancel hangs, and that is to write a dummy device address and wait for the USB transfer to error out after 250 us max. >> >> b) switch on USB suspend signalling. >> >> >> At resume: >> >> c) do resume signalling, similar to EHCI/UHCI I think. >> >> d) switch on channel tokens. >> >> case UHF_PORT_SUSPEND: >> + if (sc->sc_mode == MUSB2_HOST_MODE) >> + printf("TODO: Set UHF_PORT_SUSPEND\n"); >> + break; >> >> >> >> 3) Make sure that channels are not generating tokens if they are aborted / cancelled / timedout. This can not be verified using a USB mass storage device. Verify this by connecting a USB serial adapter. Try to open/close /dev/cuaU0. Make sure it does not loose any bytes and that channel cancel does not hang forever. > > Hi, > Thanks for review. Took me quite some time to get back > to the driver but here is updated version that addresses some > of the issues you've mentioned: > http://people.freebsd.org/~gonzo/arm/patches/beaglebone-usb-20130626.diff > > It fixes several bugs, adds proper SPLIT transactions support and > suspend/resume signalling. I tested it with urtwn-based WiFi chip, > mass storage device, USB keyboard connected directly and using > high-speed hub. > > Suspend/resume is not 100% complete though. I can use USB serial > port adapter if it's suspended/resumed unconnected. But it stuck if I do > the test while connected. Is it the right way to test it? Which suspend you mean system/resume suspend or USB suspend/resume? You should implement a musb_set_hw_power_sleep() too. This handles system going into suspend. You should probably reset that adapter at this point. static void musb_set_hw_power_sleep(struct usb_bus *bus, uint32_t state) { struct ehci_softc *sc = EHCI_BUS2SC(bus); switch (state) { case USB_HW_POWER_SUSPEND: case USB_HW_POWER_SHUTDOWN: ehci_suspend(sc); break; case USB_HW_POWER_RESUME: ehci_resume(sc); break; default: break; } } If the musb requires that you stop tokens before going in and out of suspend, you need to add functions like this: ehci_device_resume/ehci_device_suspend > > On the related note: can somebody suggest budget USB protocol analyzer > with support for high-speed bus? > http://www.totalphase.com/products/beagle_usb480/ There are more, but I don't have the list right now. You can probably just remove this check. We don't support LOW speed in device mode. - - if ((udev->speed != USB_SPEED_FULL) && - (udev->speed != USB_SPEED_HIGH)) { - /* not supported */ - return; + if (sc->sc_mode != MUSB2_HOST_MODE) { + if ((udev->speed != USB_SPEED_FULL) && + (udev->speed != USB_SPEED_HIGH)) { + /* not supported */ + return; + } } The musbotg_channel_free function is not sufficient! You need to program a non-existing device address like 127 and wait for 2 ms I recommend. The ABORT bits don't work with this controller last time I tried them! You can verify this by loading and unloading the wireless driver. I guess that IN tokens don't stop when you unload the driver. You will see this using an USB analyzer. +#define MUSB2_MAX_DEVICES (USB_MAX_DEVICES - 1) +static void +musbotg_channel_free(struct musbotg_softc *sc, struct musbotg_td *td) +{ + + DPRINTFN(1, "ep_no=%d\n", td->channel); + + if (sc->sc_mode == MUSB2_DEVICE_MODE) + return; + + if (td == NULL) + return; + if (td->channel == -1) + return; + + musbotg_ep_int_set(sc, td->channel, 0); + sc->sc_channel_mask &= ~(1 << td->channel); + td->channel = -1; /* force transfer failure */ MUSB2_WRITE_1(sc, MUSB2_REG_RXFADDR(0), 127); XXX channel should not be re-used until after 2*125us. Can probably use ticks for this! +} The 2ms can be done asynchronosly by implementing this function. See EHCI driver. static void musbotg_get_dma_delay(struct usb_device *udev, uint32_t *pus) { if (host_mode) *pus = 2000; /* microseconds */ else *pus = 0; } --HPS