Re: functionfs on dwc3, xhci host: endpoint cannot be used in both directions ?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sun, 15 Jan 2017 12:11:08 +0100, Greg KH <greg@xxxxxxxxx> wrote:
> What are you doing on the host to talk to these endpoints?

https://github.com/vpelletier/python-functionfs/tree/master/functionfs/tests

device.py is the device half and host.py the host part, of course.

The committed tests only request and test 2 endpoints.

In a nutshell:
- device declares one interface with 2 (3 in my modified version)
  endpoints, listens/writes to the functionfs-exposed files and
  discards buffer content. Note that descriptors pushed to functionfs
  cannot request a specific endpoint, they get remapped by the kernel
  (which is just fine if the remapping leads to a functional device).
- host does a few EP0 tests, then triggers usb transfers (with whatever
  in the buffer)

Currently, host just assumes IN and OUT are on endpoint 1, which is
what f_fs (and surrounding gadget machinery) actually does (here with
the OUT/IN/IN configuration):

(host)$ lsusb -vd 1d6b:0104
Bus 001 Device 040: ID 1d6b:0104 Linux Foundation Multifunction Composite Gadget
Couldn't open device, some information will be missing
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.10
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0        64
  idVendor           0x1d6b Linux Foundation
  idProduct          0x0104 Multifunction Composite Gadget
  bcdDevice            4.10
  iManufacturer           1
  iProduct                2
  iSerial                 3
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           39
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          4
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              500mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           3
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass      0
      bInterfaceProtocol      0
      iInterface              5
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x01  EP 1 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0

(device)/sys/kernel/debug/dwc3.1.auto# for EP in ep*; do echo -ne "$EP\t"; cat $EP/transfer_type; done
ep0in   control
ep0out  control
ep10in  --
ep10out --
ep11in  --
ep11out --
ep12in  --
ep12out --
ep13in  --
ep13out --
ep14in  --
ep14out --
ep15in  --
ep15out --
ep1in   bulk
ep1out  bulk
ep2in   bulk
ep2out  --
ep3in   --
ep3out  --
ep4in   --
ep4out  --
ep5in   --
ep5out  --
ep6in   --
ep6out  --
ep7in   --
ep7out  --
ep8in   --
ep8out  --
ep9in   --
ep9out  --
(device)/sys/kernel/debug/dwc3.1.auto# diff -ru ep1in ep1out
diff -ru ep1in/descriptor_fetch_queue ep1out/descriptor_fetch_queue
--- ep1in/descriptor_fetch_queue        2017-01-15 09:50:26.497903702 +0000
+++ ep1out/descriptor_fetch_queue       2017-01-15 09:50:26.507903702 +0000
@@ -1 +1 @@
-0
+32
diff -ru ep1in/rx_fifo_queue ep1out/rx_fifo_queue
--- ep1in/rx_fifo_queue 2017-01-15 09:50:26.497903702 +0000
+++ ep1out/rx_fifo_queue        2017-01-15 09:50:26.507903702 +0000
@@ -1 +1 @@
-54
+50
diff -ru ep1in/trb_ring ep1out/trb_ring
--- ep1in/trb_ring      2017-01-15 09:50:26.497903702 +0000
+++ ep1out/trb_ring     2017-01-15 09:50:26.507903702 +0000
@@ -4,7 +4,7 @@
 --------------------------------------------------

 buffer_addr,size,type,ioc,isp_imi,csp,chn,lst,hwo
-0000000034510000,65536,normal,1,0,0,0,0,1
+00000000344e0000,65536,normal,1,0,1,0,0,1
 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
@@ -259,4 +259,4 @@
 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
-000000003448d000,0,link,0,0,0,0,0,1
+0000000036ab1000,0,link,0,0,0,0,0,1
diff -ru ep1in/tx_request_queue ep1out/tx_request_queue
--- ep1in/tx_request_queue      2017-01-15 09:50:26.497903702 +0000
+++ ep1out/tx_request_queue     2017-01-15 09:50:26.507903702 +0000
@@ -1 +1 @@
-0
+32

> An endpoint can not work in both directions, that's not how USB
> endpoints work at all.  I think you are confusing the hardware with your
> configuration :)

I do agree that I have never noticed in the wild a device using a
non-zero endpoint (4 LSb) in both directions (1 MSb) - and maybe there
is no host OS support anywhere.

On the spec level though, I am less sure. Quoting the USB (v2) spec:

§5.3.1 Device Endpoints:

  Each endpoint has a device-determined direction of data flow. The
  combination of the device address, endpoint number, and direction
  allows each endpoint to be uniquely referenced. Each endpoint is a
  simplex connection that supports data flow in one direction: either
  input (from device to host) or output (from host to device).

The direction is part of the unique identifier, not only the endpoint
number. But this alone does not rule-out an EP0-only need.

§5.3.1.2 Non-endpoint Zero Requirements:

  Full-speed devices can have additional endpoints only limited
  by the protocol definition (i.e., a maximum of 15 additional input
  endpoints and 15 additional output endpoints).

Endpoint address being the low 4 bits, 30+2 (EP0 being bidirectional)
needs a 5th bit.

There is also figure "9-8 Example of Feedback Endpoint Relationships"
in "§9.6.6 Endpoint", which I must admit I never quite understood, but
which shows all 30 endpoints enabled, EP1IN serving as a feedback for
EP1OUT, EP2OUT for EP2IN, etc. Or is it something specific to
isochronous (on the topic of the number of valid active endpoints, not
the feedback mechanism) ?

There is also the fact that dwc3 exposes 30 + 2 endpoints in debugfs
with an apparently separate handling of both direction (which I expect
would not be there if the UDC hardware did not support it), and not 15
+ 2 with a direction info on each.

So there is either a bug in the HCI side, or in the UDC side:
- either the HCI should support bidirectional-ish endpoints (same
  4 LSb, different 1 MSb). Would this limitation be a hardware one ?
- or the UDC endpoint auto-allocation mechanism must skip an endpoint
  when it is already used in the other direction

Regards,
-- 
Vincent Pelletier
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux