Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d2e9b4d6 authored by Sarah Sharp's avatar Sarah Sharp Committed by Greg Kroah-Hartman
Browse files

USB: Add USB 3.0 roothub support to USB core.



Add USB 3.0 root hub descriptors.  This is a kludge because I reused the old
USB 2.0 descriptors, instead of using the new USB 3.0 hub descriptors with
endpoint companion descriptors and other descriptors.  I did this because I
wasn't ready to add USB 3.0 hub changes to khubd.  For now, a USB 3.0 roothub
looks like a USB 2.0 roothub, with a higher speed.

USB 3.0 hubs have no transaction translator (TT).

Make USB core debugging handle super speed ports.

Signed-off-by: default avatarSarah Sharp <sarah.a.sharp@linux.intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 6b403b02
Loading
Loading
Loading
Loading
+69 −2
Original line number Diff line number Diff line
@@ -128,6 +128,27 @@ static inline int is_root_hub(struct usb_device *udev)
#define KERNEL_REL	((LINUX_VERSION_CODE >> 16) & 0x0ff)
#define KERNEL_VER	((LINUX_VERSION_CODE >> 8) & 0x0ff)

/* usb 3.0 root hub device descriptor */
static const u8 usb3_rh_dev_descriptor[18] = {
	0x12,       /*  __u8  bLength; */
	0x01,       /*  __u8  bDescriptorType; Device */
	0x00, 0x03, /*  __le16 bcdUSB; v3.0 */

	0x09,	    /*  __u8  bDeviceClass; HUB_CLASSCODE */
	0x00,	    /*  __u8  bDeviceSubClass; */
	0x03,       /*  __u8  bDeviceProtocol; USB 3.0 hub */
	0x09,       /*  __u8  bMaxPacketSize0; 2^9 = 512 Bytes */

	0x6b, 0x1d, /*  __le16 idVendor; Linux Foundation */
	0x02, 0x00, /*  __le16 idProduct; device 0x0002 */
	KERNEL_VER, KERNEL_REL, /*  __le16 bcdDevice */

	0x03,       /*  __u8  iManufacturer; */
	0x02,       /*  __u8  iProduct; */
	0x01,       /*  __u8  iSerialNumber; */
	0x01        /*  __u8  bNumConfigurations; */
};

/* usb 2.0 root hub device descriptor */
static const u8 usb2_rh_dev_descriptor [18] = {
	0x12,       /*  __u8  bLength; */
@@ -273,6 +294,47 @@ static const u8 hs_rh_config_descriptor [] = {
	0x0c        /*  __u8  ep_bInterval; (256ms -- usb 2.0 spec) */
};

static const u8 ss_rh_config_descriptor[] = {
	/* one configuration */
	0x09,       /*  __u8  bLength; */
	0x02,       /*  __u8  bDescriptorType; Configuration */
	0x19, 0x00, /*  __le16 wTotalLength; FIXME */
	0x01,       /*  __u8  bNumInterfaces; (1) */
	0x01,       /*  __u8  bConfigurationValue; */
	0x00,       /*  __u8  iConfiguration; */
	0xc0,       /*  __u8  bmAttributes;
				 Bit 7: must be set,
				     6: Self-powered,
				     5: Remote wakeup,
				     4..0: resvd */
	0x00,       /*  __u8  MaxPower; */

	/* one interface */
	0x09,       /*  __u8  if_bLength; */
	0x04,       /*  __u8  if_bDescriptorType; Interface */
	0x00,       /*  __u8  if_bInterfaceNumber; */
	0x00,       /*  __u8  if_bAlternateSetting; */
	0x01,       /*  __u8  if_bNumEndpoints; */
	0x09,       /*  __u8  if_bInterfaceClass; HUB_CLASSCODE */
	0x00,       /*  __u8  if_bInterfaceSubClass; */
	0x00,       /*  __u8  if_bInterfaceProtocol; */
	0x00,       /*  __u8  if_iInterface; */

	/* one endpoint (status change endpoint) */
	0x07,       /*  __u8  ep_bLength; */
	0x05,       /*  __u8  ep_bDescriptorType; Endpoint */
	0x81,       /*  __u8  ep_bEndpointAddress; IN Endpoint 1 */
	0x03,       /*  __u8  ep_bmAttributes; Interrupt */
		    /* __le16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8)
		     * see hub.c:hub_configure() for details. */
	(USB_MAXCHILDREN + 1 + 7) / 8, 0x00,
	0x0c        /*  __u8  ep_bInterval; (256ms -- usb 2.0 spec) */
	/*
	 * All 3.0 hubs should have an endpoint companion descriptor,
	 * but we're ignoring that for now.  FIXME?
	 */
};

/*-------------------------------------------------------------------------*/

/*
@@ -426,7 +488,9 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
	case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
		switch (wValue & 0xff00) {
		case USB_DT_DEVICE << 8:
			if (hcd->driver->flags & HCD_USB2)
			if (hcd->driver->flags & HCD_USB3)
				bufp = usb3_rh_dev_descriptor;
			else if (hcd->driver->flags & HCD_USB2)
				bufp = usb2_rh_dev_descriptor;
			else if (hcd->driver->flags & HCD_USB11)
				bufp = usb11_rh_dev_descriptor;
@@ -437,7 +501,10 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
				patch_protocol = 1;
			break;
		case USB_DT_CONFIG << 8:
			if (hcd->driver->flags & HCD_USB2) {
			if (hcd->driver->flags & HCD_USB3) {
				bufp = ss_rh_config_descriptor;
				len = sizeof ss_rh_config_descriptor;
			} else if (hcd->driver->flags & HCD_USB2) {
				bufp = hs_rh_config_descriptor;
				len = sizeof hs_rh_config_descriptor;
			} else {
+5 −0
Original line number Diff line number Diff line
@@ -155,6 +155,8 @@ static inline char *portspeed(int portstatus)
    		return "480 Mb/s";
	else if (portstatus & (1 << USB_PORT_FEAT_LOWSPEED))
		return "1.5 Mb/s";
	else if (portstatus & (1 << USB_PORT_FEAT_SUPERSPEED))
		return "5.0 Gb/s";
	else
		return "12 Mb/s";
}
@@ -951,6 +953,9 @@ static int hub_configure(struct usb_hub *hub,
					ret);
			hub->tt.hub = hdev;
			break;
		case 3:
			/* USB 3.0 hubs don't have a TT */
			break;
		default:
			dev_dbg(hub_dev, "Unrecognized hub protocol %d\n",
				hdev->descriptor.bDeviceProtocol);
+3 −0
Original line number Diff line number Diff line
@@ -47,7 +47,10 @@
#define USB_PORT_FEAT_L1		5	/* L1 suspend */
#define USB_PORT_FEAT_POWER		8
#define USB_PORT_FEAT_LOWSPEED		9
/* This value was never in Table 11-17 */
#define USB_PORT_FEAT_HIGHSPEED		10
/* This value is also fake */
#define USB_PORT_FEAT_SUPERSPEED	11
#define USB_PORT_FEAT_C_CONNECTION	16
#define USB_PORT_FEAT_C_ENABLE		17
#define USB_PORT_FEAT_C_SUSPEND		18