analogdevicesinc / libiio

A cross platform library for interfacing with local and remote Linux IIO devices
http://analogdevicesinc.github.io/libiio/
GNU Lesser General Public License v2.1
487 stars 316 forks source link

IIOD USB3.0 SuperSpeed doesn’t work #132

Closed mhennerich closed 6 years ago

mhennerich commented 6 years ago

IIOD USB3.0 SuperSpeed doesn’t work:

The kernel dmesg warning on the remote during USB device enumeration:

[3126244.604486] usb 2-2: new SuperSpeed USB device number 2 using xhci_hcd
[3126244.621087] usb 2-2: No SuperSpeed endpoint companion for config 1  interface 0 altsetting 0 ep 129: using minimum values
[3126244.621095] usb 2-2: No SuperSpeed endpoint companion for config 1  interface 0 altsetting 0 ep 1: using minimum values
[3126244.621100] usb 2-2: No SuperSpeed endpoint companion for config 1  interface 0 altsetting 0 ep 130: using minimum values
[3126244.621103] usb 2-2: No SuperSpeed endpoint companion for config 1  interface 0 altsetting 0 ep 2: using minimum values
[3126244.621107] usb 2-2: No SuperSpeed endpoint companion for config 1  interface 0 altsetting 0 ep 131: using minimum values
[3126244.621110] usb 2-2: No SuperSpeed endpoint companion for config 1  interface 0 altsetting 0 ep 3: using minimum values
[3126244.621362] usb 2-2: New USB device found, idVendor=0456, idProduct=b671
[3126244.621367] usb 2-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[3126244.621372] usb 2-2: Product: Generic USB IIOD
[3126244.621377] usb 2-2: Manufacturer: Analog Devices Inc.
[3126244.621382] usb 2-2: SerialNumber: 00000000
[3126244.623553] cdc_acm 2-2:1.1: ttyACM0: USB ACM device
[3126436.299983] usb 2-2: USB disconnect, device number 2
[3126436.300322] cdc_acm 2-2:1.1: failed to set dtr/rts

Context Scan Works:

michael@mhenneri-D04:~/devel/git/linux-private$ iio_info -s
Library version: 0.11 (git tag: 69bc7cb)
Compiled with backends: local xml ip usb
Available contexts:
    0: Local devices [local:]
    1: 0456:b671 (Analog Devices Inc. Generic USB IIOD), serial=00000000 [usb:1.40.0]

However create IIO context fails with –EPIPE:

michael@mhenneri-D04:~/devel/git/linux-private$ iio_info -u usb:1.40.0
Library version: 0.11 (git tag: 69bc7cb)
Compiled with backends: local xml ip usb
Unable to create IIO context: Broken pipe
michael@mhenneri-D04:~/devel/git/linux-private$ 

The kernel warning on the remote host is due to the fact that IIOD usbd doesn't initialize the SuperSpeed Endpoint Companion descriptors. See here:

Tested on Xilinx MPSoC ZCU102:

mhennerich commented 6 years ago

Some updates:

I created Pull Request #134 which fixes the kernel warnings. I think this one is good to merge.

But it doesn't fix the USB issues seen on the MPSoC ZCU102 using the DWC3 controller. On the first call to libusb_get_string_descriptor_ascii() to fetch the dev_desc.iManufacturer it would return LIBUSB_ERROR_PIPE. Which is then causing the "Unable to create IIO context: Broken pipe" error.

This error can we workaround by simply trying it again. And very consistently it succeeds the second time.

diff --git a/usb.c b/usb.c
index ae84edc..7a19e4e 100644
--- a/usb.c
+++ b/usb.c
@@ -728,17 +728,17 @@ static int usb_populate_context_attrs(struct iio_context *ctx,

        for (i = 0; i < ARRAY_SIZE(attrs); i++) {
                if (attrs[i].idx) {
-                       if (i == 0)
                        ret = libusb_get_string_descriptor_ascii(hdl,
                                        attrs[i].idx, (unsigned char *) buffer,
                                        sizeof(buffer));

-                       ret = libusb_get_string_descriptor_ascii(hdl,
-                                                                attrs[i].idx, (unsigned char *) buffer,
-                                                                sizeof(buffer));
-
-                       if (ret < 0)
-                               return -(int) libusb_to_errno(ret);
+                       if (ret < 0) {
+                               ret = libusb_get_string_descriptor_ascii(hdl,
+                                               attrs[i].idx, (unsigned char *) buffer,
+                                               sizeof(buffer));
+                               if (ret < 0)
+                                       return -(int) libusb_to_errno(ret);
+                       }

                        ret = iio_context_add_attr(ctx, attrs[i].attr, buffer);
                        if (ret < 0)

Then next problem is then that submit transfer may return LIBUSB_TRANSFER_TIMED_OUT. And now it get's really weird:

@@ -812,9 +812,6 @@ struct iio_context * usb_create_context(unsigned int bus,
                        usb_dev = dev;

                        ret = libusb_open(usb_dev, &hdl);
-
+                       libusb_reset_device(hdl);
+                       sleep(0.1);
                        /*
                         * Workaround for libusb on Windows >= 8.1. A device
                         * might appear twice in the list with one device being

Resetting the device will resolve these issues as well.

The next thing I tried was to replace the DWC3 driver sources on our 4.9 kernel from a 4.14 upstream. With some minor mods - I was able to make it work.

With this driver the USB device reset is no longer required - but the libusb_get_string_descriptor_ascii() still occasionally fails the first time.

I then tried to measure streaming performance - with Buffer sizes below 1M Samples. We get around 80MBytes/s.

If you increase above 1M Samples - you experience a sudden death Which also brought down the entire USB on my Intel Desktop. (Now reboot a PC without Keyboard and Mouse ....)

root@analog:~# [  135.615218] DMA: Out of SW-IOMMU space for 1048576 bytes at device fe200000.dwc3
[  135.622522] Kernel panic - not syncing: DMA: Random memory could be DMA read
[  135.622522] 
[  135.631032] CPU: 1 PID: 4166 Comm: iiod Tainted: G        W       4.9.0-12448-g3de21d3-dirty #439
[  135.639882] Hardware name: ZynqMP ZCU102 Rev1.0 (DT)
[  135.644829] Call trace:
[  135.647269] [<ffffff8008087f9c>] dump_backtrace+0x0/0x1a4
[  135.652644] [<ffffff8008088154>] show_stack+0x14/0x1c
[  135.657680] [<ffffff80083d30ac>] dump_stack+0x8c/0xac
[  135.662714] [<ffffff800812b308>] panic+0x124/0x26c
[  135.667486] [<ffffff80083fc3bc>] swiotlb_map_page+0x170/0x19c
[  135.673217] [<ffffff80080932c8>] __swiotlb_map_page+0x20/0x7c
[  135.678946] [<ffffff80085f1560>] usb_gadget_map_request_by_dev+0xfc/0x1c8
[  135.685715] [<ffffff80085cc710>] __dwc3_gadget_kick_transfer+0x1c0/0x390
[  135.692398] [<ffffff80085ccaf4>] dwc3_gadget_ep_queue+0xe8/0x1bc
[  135.698387] [<ffffff80085f1368>] usb_ep_queue+0x24/0x58
[  135.703596] [<ffffff80085f9a94>] ffs_epfile_io+0x49c/0x550
[  135.709063] [<ffffff80085f9bdc>] ffs_epfile_write_iter+0x94/0x144
[  135.715142] [<ffffff80081cb964>] aio_write+0xbc/0x150
[  135.720175] [<ffffff80081cc9d4>] do_io_submit+0x4e0/0x5b0
[  135.725557] [<ffffff80081d1e8c>] compat_SyS_io_submit+0x110/0x134
[  135.731632] [<ffffff8008082ef0>] el0_svc_naked+0x24/0x28
[  135.736925] SMP: stopping secondary CPUs
[  135.740927] Kernel Offset: disabled
[  135.744320] Memory Limit: none
[  135.747362] ---[ end Kernel panic - not syncing: DMA: Random memory could be DMA read
[  135.747362] 
pcercuei commented 6 years ago

80 MiB/s sounds really good. I would think these errors are in the kernel, maybe ask for help on the LKML?

mhennerich commented 6 years ago

Just for those who are interested. USB3.0 support with the dwc3 controller in the 4.9 kernel was mostly fixed on this linux brach: https://github.com/analogdevicesinc/linux/tree/zynqmp-usb-dwc3-fixes

mhennerich commented 6 years ago

With this being said - I think we can close this issue since it is clearly not an libIIO issue.