Date: Thu, 27 Jun 2013 08:47:06 +0200 From: Hans Petter Selasky <hps@bitfrost.no> To: Oleksandr Tymoshenko <gonzo@bluezbox.com> Cc: arm@freebsd.org, usb@freebsd.org Subject: Re: Beaglebone USB driver (Mentor Graphics OTG) Message-ID: <51CBDFEA.7050203@bitfrost.no> In-Reply-To: <0927BB4C-6917-408D-B102-AB98F72314B6@bluezbox.com> References: <51608AA4.2020804@bluezbox.com> <51611A7B.2010105@bitfrost.no> <0927BB4C-6917-408D-B102-AB98F72314B6@bluezbox.com>
next in thread | previous in thread | raw e-mail | index | archive | help
On 06/27/13 02:53, Oleksandr Tymoshenko wrote: > > On 2013-04-07, at 12:04 AM, Hans Petter Selasky <hps@bitfrost.no> 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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?51CBDFEA.7050203>