Re: [PATCH v3 1/1] USB: core: let USB device know device node

Arnd Bergmann
2016-01-21T22:24:21Z

On Thursday 21 January 2016 10:21:15 Alan Stern wrote:
> On Thu, 21 Jan 2016, Arnd Bergmann wrote:
>
> > On Thursday 21 January 2016 17:48:32 Peter Chen wrote:
> > >
> > > >
> > > > So two hubs at ports 1 and 2 of the USB controller that integrates
> > > > the root hub and shares a device node with it.
> > > >
> > > Ok, so the "reg" is the address for certain root hub (HS or SS), not
> > > the unity address for the whole controller, if it is, do we really
> > > need to add two nodes for one physical port, HS and SS will not be used
> > > at the same time. And if the reg is the same, how can we know
> > > which node is from current recognized device.
> >
> > The "reg" is the address that the parent device uses to talk to the child
> > device. If you know which of the two that child is attached to, then I
> > think you don't need both, but I think we have to use the entire addressing.
> >
> > In Alan's example, there are six HS ports and three SS ports, but as I
> > understand it, there is no guarantee that the numbering between the two
> > is identical, and that the three SS ports always refer to the three HS
> > ports. In particular for devices soldered on-board (rather than connected
> > through a standard plug), I would guess that it is possible to connect
> > them to separate child devices though I have to admit that I do not
> > understand enough of the standard to know for sure.
>
> The spec allows for a lot of flexibility. It even allows for "tier
> mismatches", in which (for example) the SS connection for a particular
> port is routed directly to the root hub while the HS connection for the
> same port is routed through an intermediate hub!
>
> There is only one major constraint: With the exception of hubs, no USB
> device is allowed to use both the SS and the HS buses at the same time.
> A device has to decide on one speed and use only the corresponding bus.
> USB-3 hubs, on the other hand, are required to connect to both buses.
> They appear as two separate logical devices: a SS hub on the SS bus and
> a HS hub on the HS bus.

Ok, thanks for the explanation. This means there is no strict relation
between the SS and HS ports and we have to represent them separately.

I can also see what you explained now on my PC by plugging in a couple
of devices into a hub on a single SS port:

/: Bus 04.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 5000M
|__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/4p, 5000M
|__ Port 1: Dev 4, If 0, Class=Mass Storage, Driver=usb-storage, 5000M
|__ Port 4: Dev 3, If 0, Class=Vendor Specific Class, Driver=ax88179_178a, 5000M
/: Bus 03.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 480M
|__ Port 1: Dev 3, If 0, Class=Hub, Driver=hub/4p, 480M
|__ Port 2: Dev 5, If 0, Class=Wireless, Driver=btusb, 12M
|__ Port 2: Dev 5, If 1, Class=Wireless, Driver=btusb, 12M

In this case, the DT representation would be

usb@... { /* host controller and root hub */
compatible = "xhci-generic";
#address-cells = <1>;
#size-cells = <0>;

hub@1 { /* external hub, superspeed mode class 9/subclass 0/proto 3 */
compatible = "usb2109,0812.591",
"usb2109,0812",
"usb2109,class9.0.3",
"usb2109,class9.0",
"usb2109,class9";
compatible = "usb2109,0812";
#address-cells = <1>;
#size-cells = <0>;
reg = <1>;

communications@4 { /* superspeed ethernet device */
compatible = "usb0b95,1790.100",
"usb0b95,1790",
"usb0b95,class255.255.0",
"usb0b95,class255.255",
"usb0b95,class255",
"usbif0b95,1790.100",
"usbif0b95,1790",
"usbif0b95,class255.255.0",
"usbif0b95,class255.255,
"usbif0b95,class255";
reg = <4>;
};

storage@1 { /* superspeed flash drive */
compatible = "usb1234,5678.600",
"usb1234,5678",
"usbif1234,class8.6.80",
"usbif1234,class8.6",
"usbif1234,class8",
"usbif,class8.6.80",
"usbif,class8.6",
"usbif,class8";
reg = <1>;
};
};

hub@3 { /* same external hub, highspeed mode */
compatible = "usb2109,0812.591",
"usb2109,0812",
"usb2109,class9.0.1",
"usb2109,class9.0",
"usb2109,class9";

#address-cells = <1>;
#size-cells = <0>;
reg = <3>;

wireless@2 { /* bluetooth device */
compatible = "usb0a12,0001.134",
"usb0a12,0001",
"usb0a12,class224.1.1",
"usb0a12,class224.1",
"usb0a12,class224",
"usb0a12,class224.1.1",
"usb0a12,class224.1",
"usb0a12,class224";
#address-cells = <1>;
#size-cells = <0>;
reg = <2>;

wireless@0,0 { /* bluetooth config 0, if 0 */
compatible = "usbif0a12,0001.134.config0.0",
"usbif0a12,0001.config0.0",
"usbif0a12,class224.1.1",
"usbif0a12,class224.1",
"usbif0a12,class224",
"usbif,class224.1.1",
"usbif,class224.1",
"usbif,class224";
reg = <0 0>;
};

wireless@0,1 { /* bluetooth config 0, if 1 */
compatible = "usbif0a12,0001.134.config0.1",
"usbif0a12,0001.config0.1",
"usbif0a12,class224.1.1",
"usbif0a12,class224.1",
"usbif0a12,class224",
"usbif,class224.1.1",
"usbif,class224.1",
"usbif,class224";
reg = <0 0>;
};
};
};
};

In that description, I have included all four kinds of nodes from
the spec: host controller, device (wireless@2), interface (wireless@0.1,
wireless@0.2) and combined (hub@1, hub@3, storage@1, communications@4).

Peter's example only contained hubs in combined nodes, no device or
interface nodes. I wonder if the code is able to parse all four
kinds of nodes though, and if we actually need that.

Do we have a 'struct device' for each interface?

Is it possible to have a hub in an interface of a multifunction device
or are they always single-configuration single-interface devices?

Arnd