Re: Beaglebone USB driver (Mentor Graphics OTG)
Hi Oleksandr, Got some time to review the code you committed to HEAD: 1) You need to distinguish between STALL and other errors. This is a bit important, because STALL is a PID and other errors can mean anything. See attached patch. 2) You should not use the NAKTO feature, because USB devices are allowed to NAK forever if they wish to. You should restart a USB transfer seamlessly after NAKTO or should use infinite NAKing. The USB stack has a timeout on the transfers, and will cancel when timeout happens. By feeding these error codes into the USB stack you risk loosing data on mouse/keyboard/modem devices! Upon cancel you need to use that trick I told you (included in the attached patch), else the double reset of the FIFO will crash! Could you clean this up and test a bit. I don't have hardware at hand to test at the moment. Thank you! --HPS diff --git a/sys/dev/usb/controller/musb_otg.c b/sys/dev/usb/controller/musb_otg.c index 5113d7a..bac8dd9 100644 --- a/sys/dev/usb/controller/musb_otg.c +++ b/sys/dev/usb/controller/musb_otg.c @@ -169,6 +169,9 @@ musbotg_channel_alloc(struct musbotg_softc *sc, struct musbotg_td *td) if (sc-sc_channel_mask (1 0)) return (-1); sc-sc_channel_mask |= (1 0); + /* Clear previous status bits */ + MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, 0); + /* Enable interrupts */ musbotg_ep_int_set(sc, ep, 1); return (0); } @@ -176,6 +179,9 @@ musbotg_channel_alloc(struct musbotg_softc *sc, struct musbotg_td *td) for (ch = 1; ch MUSB2_EP_MAX; ch++) { if (!(sc-sc_channel_mask (1 ch))) { sc-sc_channel_mask |= (1 ch); + /* Clear previous status bits */ + MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, 0); + /* Enable interrupts */ musbotg_ep_int_set(sc, ch, 1); return (ch); } @@ -203,6 +209,19 @@ musbotg_channel_free(struct musbotg_softc *sc, struct musbotg_td *td) musbotg_ep_int_set(sc, td-channel, 0); sc-sc_channel_mask = ~(1 td-channel); + /* select endpoint */ + MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, td-channel); + + /* clear NAK limit */ + MUSB2_WRITE_1(sc, MUSB2_REG_TXNAKLIMIT, 0); + + /* + * Set non-existing device address so that any NAK'ing only + * transfers get cancelled! Should wait 250us before using + * channel again. + */ + MUSB2_WRITE_1(sc, MUSB2_REG_TXFADDR(td-channel), MUSB2_RST_ADDR); + td-channel = -1; } @@ -518,13 +537,15 @@ musbotg_host_ctrl_setup_tx(struct musbotg_td *td) return (1); /* Failed */ - if (csr (MUSB2_MASK_CSR0L_RXSTALL | - MUSB2_MASK_CSR0L_ERROR)) - { - /* Clear status bit */ - MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, 0); + if (csr MUSB2_MASK_CSR0L_RXSTALL) { DPRINTFN(1, error bit set, csr=0x%02x\n, csr); - td-error = 1; + td-error_any = 1; + td-error_stall = 1; + return (0); /* complete */ + } else if (csr MUSB2_MASK_CSR0L_ERROR) { + DPRINTFN(1, error bit set, csr=0x%02x\n, csr); + td-error_any = 1; + return (0); /* complete */ } if (csr MUSB2_MASK_CSR0L_NAKTIMO) { @@ -546,10 +567,10 @@ musbotg_host_ctrl_setup_tx(struct musbotg_td *td) csr = ~MUSB2_MASK_CSR0L_NAKTIMO; MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, csr); - td-error = 1; + td-error_any = 1; } - if (td-error) { + if (td-error_any) { musbotg_channel_free(sc, td); return (0); } @@ -636,7 +657,7 @@ musbotg_dev_ctrl_data_rx(struct musbotg_td *td) /* * USB Host Aborted the transfer. */ - td-error = 1; + td-error_any = 1; return (0); /* complete */ } if (!(csr MUSB2_MASK_CSR0L_RXPKTRDY)) { @@ -653,14 +674,14 @@ musbotg_dev_ctrl_data_rx(struct musbotg_td *td) got_short = 1; } else { /* invalid USB packet */ - td-error = 1; + td-error_any = 1; return (0); /* we are complete */ } } /* verify the packet byte count */ if (count td-remainder) { /* invalid USB packet */ - td-error = 1; + td-error_any = 1; return (0); /* we are complete */ } while (count 0) { @@ -769,7 +790,7 @@ musbotg_dev_ctrl_data_tx(struct musbotg_td *td) * The current transfer was aborted * by the USB Host */ - td-error = 1; + td-error_any = 1; return (0); /* complete */ } if (csr MUSB2_MASK_CSR0L_TXPKTRDY) { @@ -911,22 +932,19 @@ musbotg_host_ctrl_data_rx(struct musbotg_td *td) csr = ~MUSB2_MASK_CSR0L_NAKTIMO; MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, csr); - td-error = 1; + td-error_any = 1; XXX; } /* Failed */ - if (csr (MUSB2_MASK_CSR0L_RXSTALL | - MUSB2_MASK_CSR0L_ERROR)) - { - /* Clear status bit */ - MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, 0); + if (csr MUSB2_MASK_CSR0L_RXSTALL) { DPRINTFN(1, error bit set, csr=0x%02x\n, csr); - td-error = 1; - } - - if (td-error) { - musbotg_channel_free(sc, td); - return (0); /* we are complete */ + td-error_any = 1; + td-error_stall = 1; + return (0); /* complete */ + } else if (csr MUSB2_MASK_CSR0L_ERROR) { + DPRINTFN(1, error bit set, csr=0x%02x\n, csr); + td-error_any = 1; + return (0); /* complete */ } if (!(csr
Re: Beaglebone USB driver (Mentor Graphics OTG)
On 2013-07-01, at 9:48 PM, Oleksandr Tymoshenko go...@bluezbox.com wrote: On 2013-06-26, at 11:47 PM, Hans Petter Selasky h...@bitfrost.no wrote: On 06/27/13 02:53, Oleksandr Tymoshenko wrote: On 2013-04-07, at 12:04 AM, Hans Petter Selasky h...@bitfrost.no wrote: On 04/06/13 22:50, Oleksandr Tymoshenko wrote: Hello, .. skipped .. Writing 127 to FADDR breaks driver. It can't even attach device properly. I do not completely understand the scenario behind this requirement. My recollection is: when we cancel IN transaction somehow we should ensure that function that currently handles it does not stuck forever. From what I see it's just impossible. There is internal NAK timer that fails the transaction once it reached configured value (or 3 by default AFAIR). Isn't it enough? I tried unloading active uwrtn driver - it unloads with some delay but as far as I can see from logs delay is not due to USB internal transactions code it must be upper layer. Could you, please, elaborate on the matter? Here is updated version of the patch: http://people.freebsd.org/~gonzo/arm/patches/beaglebone-usb-20130701.diff Besides cosmetic fixes I also synced dev/usb/controller/musb_otg_atmelarm.c to the latest changes of core logic: added required wrappers and some initializations. I do not longer have access to USB analyzer so my debugging abilities is somewhat limited now. Hi Hans, The driver seems to be fairly stable judging from my tests. I'd like to commit it as-is, get more test coverage from users and tighten up loose ends then. What do you think? ___ freebsd-usb@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-usb To unsubscribe, send any mail to freebsd-usb-unsubscr...@freebsd.org
Re: Beaglebone USB driver (Mentor Graphics OTG)
On 2013-06-26, at 11:47 PM, Hans Petter Selasky h...@bitfrost.no wrote: On 06/27/13 02:53, Oleksandr Tymoshenko wrote: On 2013-04-07, at 12:04 AM, Hans Petter Selasky h...@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? I was talking about USB suspend/resume. I do not thin we have working suspend/resume for ARM yet so I don't have reliable way to test it. 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 */ +
Re: Beaglebone USB driver (Mentor Graphics OTG)
On 06/27/13 08:47, Hans Petter Selasky wrote: /* 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! Probably td-channel instead of (0) --HPS ___ freebsd-usb@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-usb To unsubscribe, send any mail to freebsd-usb-unsubscr...@freebsd.org
Re: Beaglebone USB driver (Mentor Graphics OTG)
On 2013-04-07, at 12:04 AM, Hans Petter Selasky h...@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. 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? On the related note: can somebody suggest budget USB protocol analyzer with support for high-speed bus? ___ freebsd-usb@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-usb To unsubscribe, send any mail to freebsd-usb-unsubscr...@freebsd.org
Re: Beaglebone USB driver (Mentor Graphics OTG)
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, Supporting split transactions is required: + + /* SPLIT transaction */ + MUSB2_WRITE_1(sc, MUSB2_REG_RXHADDR(0), 0); + MUSB2_WRITE_1(sc, MUSB2_REG_RXHUBPORT(0), 0); + See EHCI driver: EHCI_QH_SET_HUBA(xfer-xroot-udev-hs_hub_addr) | EHCI_QH_SET_PORT(xfer-xroot-udev-hs_port_no)); This feature should be enabled when: Connected root HUB port is running HIGH speed, and the connected device is LOW or FULL speed. Try connecting a USB keyboard through any high speed USB HUB. --HPS ___ freebsd-usb@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-usb To unsubscribe, send any mail to freebsd-usb-unsubscr...@freebsd.org
Re: Beaglebone USB driver (Mentor Graphics OTG)
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. --HPS ___ freebsd-usb@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-usb To unsubscribe, send any mail to freebsd-usb-unsubscr...@freebsd.org
Re: Beaglebone USB driver (Mentor Graphics OTG)
On 04/07/13 09:04, Hans Petter Selasky wrote: 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, I recommend that cancel works like this: 1) Set invalid device address, like 127. 2) Use DMA delay feature to make a 4ms wait (see XHCI driver for example). 3) Free host channel (final). --HPS ___ freebsd-usb@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-usb To unsubscribe, send any mail to freebsd-usb-unsubscr...@freebsd.org
Beaglebone USB driver (Mentor Graphics OTG)
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 ___ freebsd-usb@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-usb To unsubscribe, send any mail to freebsd-usb-unsubscr...@freebsd.org
Re: Beaglebone USB driver (Mentor Graphics OTG)
On Sat, 06 Apr 2013 13:50:44 -0700 Oleksandr Tymoshenko go...@bluezbox.com 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? Any USB camera (a.k.a. Web Cam) - 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 ___ freebsd-...@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-arm To unsubscribe, send any mail to freebsd-arm-unsubscr...@freebsd.org WBW -- Aleksandr Rybalko r...@freebsd.org ___ freebsd-usb@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-usb To unsubscribe, send any mail to freebsd-usb-unsubscr...@freebsd.org