Patchwork [U-Boot,6/7] USB: SS: Add support for Super Speed USB interface

login
register
mail settings
Submitter Vivek Gautam
Date March 27, 2013, 9:29 a.m.
Message ID <1364376543-7526-7-git-send-email-gautam.vivek@samsung.com>
Download mbox | patch
Permalink /patch/231633/
State Awaiting Upstream
Delegated to: Marek Vasut
Headers show

Comments

Vivek Gautam - March 27, 2013, 9:29 a.m.
This adds usb framework support for super-speed usb, which will
further facilitate to add stack support for xHCI.

Signed-off-by: Vikas C Sajjan <vikas.sajjan@samsung.com>
Signed-off-by: Vivek Gautam <gautam.vivek@samsung.com>
---
 common/cmd_usb.c     |    6 ++++--
 common/usb.c         |   11 ++++++++---
 common/usb_hub.c     |   10 +++++++---
 common/usb_storage.c |    2 +-
 include/usb.h        |   12 +++++++++++-
 include/usb_defs.h   |   24 +++++++++++++++++++++++-
 6 files changed, 54 insertions(+), 11 deletions(-)
Marek Vasut - March 28, 2013, 2:35 p.m.
Dear Vivek Gautam,

> This adds usb framework support for super-speed usb, which will
> further facilitate to add stack support for xHCI.
> 
> Signed-off-by: Vikas C Sajjan <vikas.sajjan@samsung.com>
> Signed-off-by: Vivek Gautam <gautam.vivek@samsung.com>

[...]

> --- a/include/usb.h
> +++ b/include/usb.h
> @@ -67,6 +67,16 @@ struct devrequest {
>  	unsigned short	length;
>  } __attribute__ ((packed));
> 
> +struct usb_ep_desc {
> +	struct usb_endpoint_descriptor		ep_desc;
> +	/*
> +	 * Super Speed Device will have Super Speed Endpoint
> +	 * Companion Descriptor  (section 9.6.7 of usb 3.0 spec)
> +	 * Revision 1.0 June 6th 2011
> +	 */
> +	struct usb_ss_ep_comp_descriptor	ss_ep_comp;
> +};
> +
>  /* Interface */
>  struct usb_interface {
>  	struct usb_interface_descriptor desc;
> @@ -75,7 +85,7 @@ struct usb_interface {
>  	unsigned char	num_altsetting;
>  	unsigned char	act_altsetting;
> 
> -	struct usb_endpoint_descriptor ep_desc[USB_MAXENDPOINTS];
> +	struct usb_ep_desc ep_desc[USB_MAXENDPOINTS];

Do we really need this struct usb_ep_desc? Can we not just store the 
usb_ss_ep_comp_descriptor here as well?

>  } __attribute__ ((packed));
> 
>  /* Configuration information.. */
> diff --git a/include/usb_defs.h b/include/usb_defs.h
> index 0c78d9d..e2aaef3 100644
> --- a/include/usb_defs.h
> +++ b/include/usb_defs.h
> @@ -203,6 +203,8 @@
>  #define USB_PORT_FEAT_POWER          8
>  #define USB_PORT_FEAT_LOWSPEED       9
>  #define USB_PORT_FEAT_HIGHSPEED      10
> +#define USB_PORT_FEAT_FULLSPEED      11
> +#define USB_PORT_FEAT_SUPERSPEED     12
>  #define USB_PORT_FEAT_C_CONNECTION   16
>  #define USB_PORT_FEAT_C_ENABLE       17
>  #define USB_PORT_FEAT_C_SUSPEND      18
> @@ -218,8 +220,20 @@
>  #define USB_PORT_STAT_POWER         0x0100
>  #define USB_PORT_STAT_LOW_SPEED     0x0200
>  #define USB_PORT_STAT_HIGH_SPEED    0x0400	/* support for EHCI */
> +#define USB_PORT_STAT_FULL_SPEED    0x0800
> +#define USB_PORT_STAT_SUPER_SPEED   0x1000	/* support for XHCI */
>  #define USB_PORT_STAT_SPEED	\
> -	(USB_PORT_STAT_LOW_SPEED | USB_PORT_STAT_HIGH_SPEED)
> +	(USB_PORT_STAT_LOW_SPEED | USB_PORT_STAT_HIGH_SPEED | \
> +	USB_PORT_STAT_FULL_SPEED | USB_PORT_STAT_SUPER_SPEED)
> +
> +/*
> + * Additions to wPortStatus bit field from USB 3.0
> + * See USB 3.0 spec Table 10-10
> + */
> +#define USB_PORT_STAT_LINK_STATE	0x01e0
> +#define USB_SS_PORT_STAT_POWER		0x0200
> +#define USB_SS_PORT_STAT_SPEED		0x1c00
> +#define USB_PORT_STAT_SPEED_5GBPS	0x0000
> 
>  /* wPortChange bits */
>  #define USB_PORT_STAT_C_CONNECTION  0x0001
> @@ -228,6 +242,14 @@
>  #define USB_PORT_STAT_C_OVERCURRENT 0x0008
>  #define USB_PORT_STAT_C_RESET       0x0010
> 
> +/*
> + * Addition to wPortChange bit fields form USB 3.0
> + * See USB 3.0 spec Table 10-11
> + */
> +#define USB_PORT_STAT_C_BH_RESET	0x0020
> +#define USB_PORT_STAT_C_LINK_STATE	0x0040
> +#define USB_PORT_STAT_C_CONFIG_ERROR	0x0080
> +
>  /* wHubCharacteristics (masks) */
>  #define HUB_CHAR_LPSM               0x0003
>  #define HUB_CHAR_COMPOUND           0x0004
Vivek Gautam - April 2, 2013, 9:52 a.m.
Hi Marek,


On Thu, Mar 28, 2013 at 8:05 PM, Marek Vasut <marex@denx.de> wrote:
> Dear Vivek Gautam,
>
>> This adds usb framework support for super-speed usb, which will
>> further facilitate to add stack support for xHCI.
>>
>> Signed-off-by: Vikas C Sajjan <vikas.sajjan@samsung.com>
>> Signed-off-by: Vivek Gautam <gautam.vivek@samsung.com>
>
> [...]
>
>> --- a/include/usb.h
>> +++ b/include/usb.h
>> @@ -67,6 +67,16 @@ struct devrequest {
>>       unsigned short  length;
>>  } __attribute__ ((packed));
>>
>> +struct usb_ep_desc {
>> +     struct usb_endpoint_descriptor          ep_desc;
>> +     /*
>> +      * Super Speed Device will have Super Speed Endpoint
>> +      * Companion Descriptor  (section 9.6.7 of usb 3.0 spec)
>> +      * Revision 1.0 June 6th 2011
>> +      */
>> +     struct usb_ss_ep_comp_descriptor        ss_ep_comp;
>> +};
>> +
>>  /* Interface */
>>  struct usb_interface {
>>       struct usb_interface_descriptor desc;
>> @@ -75,7 +85,7 @@ struct usb_interface {
>>       unsigned char   num_altsetting;
>>       unsigned char   act_altsetting;
>>
>> -     struct usb_endpoint_descriptor ep_desc[USB_MAXENDPOINTS];
>> +     struct usb_ep_desc ep_desc[USB_MAXENDPOINTS];
>
> Do we really need this struct usb_ep_desc? Can we not just store the
> usb_ss_ep_comp_descriptor here as well?

Yea, possibly we can add "usb_ss_ep_comp_descriptor" in
'usb_interface' itself only.
Also quoting USB 3.0 specs:
"SuperSpeed devices shall return Endpoint Companion descriptors
for each of the endpoints in that interface to return additional
information about its endpoint
capabilities. The Endpoint Companion descriptor shall immediately
follow the endpoint descriptor
it is associated with in the configuration information."

Will update this accordingly.

>
>>  } __attribute__ ((packed));
>>
>>  /* Configuration information.. */
>> diff --git a/include/usb_defs.h b/include/usb_defs.h
>> index 0c78d9d..e2aaef3 100644
>> --- a/include/usb_defs.h
>> +++ b/include/usb_defs.h
>> @@ -203,6 +203,8 @@
>>  #define USB_PORT_FEAT_POWER          8
>>  #define USB_PORT_FEAT_LOWSPEED       9
>>  #define USB_PORT_FEAT_HIGHSPEED      10
>> +#define USB_PORT_FEAT_FULLSPEED      11
>> +#define USB_PORT_FEAT_SUPERSPEED     12
>>  #define USB_PORT_FEAT_C_CONNECTION   16
>>  #define USB_PORT_FEAT_C_ENABLE       17
>>  #define USB_PORT_FEAT_C_SUSPEND      18
>> @@ -218,8 +220,20 @@
>>  #define USB_PORT_STAT_POWER         0x0100
>>  #define USB_PORT_STAT_LOW_SPEED     0x0200
>>  #define USB_PORT_STAT_HIGH_SPEED    0x0400   /* support for EHCI */
>> +#define USB_PORT_STAT_FULL_SPEED    0x0800
>> +#define USB_PORT_STAT_SUPER_SPEED   0x1000   /* support for XHCI */
>>  #define USB_PORT_STAT_SPEED  \
>> -     (USB_PORT_STAT_LOW_SPEED | USB_PORT_STAT_HIGH_SPEED)
>> +     (USB_PORT_STAT_LOW_SPEED | USB_PORT_STAT_HIGH_SPEED | \
>> +     USB_PORT_STAT_FULL_SPEED | USB_PORT_STAT_SUPER_SPEED)
>> +
>> +/*
>> + * Additions to wPortStatus bit field from USB 3.0
>> + * See USB 3.0 spec Table 10-10
>> + */
>> +#define USB_PORT_STAT_LINK_STATE     0x01e0
>> +#define USB_SS_PORT_STAT_POWER               0x0200
>> +#define USB_SS_PORT_STAT_SPEED               0x1c00
>> +#define USB_PORT_STAT_SPEED_5GBPS    0x0000
>>
>>  /* wPortChange bits */
>>  #define USB_PORT_STAT_C_CONNECTION  0x0001
>> @@ -228,6 +242,14 @@
>>  #define USB_PORT_STAT_C_OVERCURRENT 0x0008
>>  #define USB_PORT_STAT_C_RESET       0x0010
>>
>> +/*
>> + * Addition to wPortChange bit fields form USB 3.0
>> + * See USB 3.0 spec Table 10-11
>> + */
>> +#define USB_PORT_STAT_C_BH_RESET     0x0020
>> +#define USB_PORT_STAT_C_LINK_STATE   0x0040
>> +#define USB_PORT_STAT_C_CONFIG_ERROR 0x0080
>> +
>>  /* wHubCharacteristics (masks) */
>>  #define HUB_CHAR_LPSM               0x0003
>>  #define HUB_CHAR_COMPOUND           0x0004

Patch

diff --git a/common/cmd_usb.c b/common/cmd_usb.c
index dacdc2d..90c2cf1 100644
--- a/common/cmd_usb.c
+++ b/common/cmd_usb.c
@@ -262,7 +262,7 @@  static void usb_display_config(struct usb_device *dev)
 		ifdesc = &config->if_desc[i];
 		usb_display_if_desc(&ifdesc->desc, dev);
 		for (ii = 0; ii < ifdesc->no_of_ep; ii++) {
-			epdesc = &ifdesc->ep_desc[ii];
+			epdesc = &ifdesc->ep_desc[ii].ep_desc;
 			usb_display_ep_desc(epdesc);
 		}
 	}
@@ -271,7 +271,9 @@  static void usb_display_config(struct usb_device *dev)
 
 static inline char *portspeed(int speed)
 {
-	if (speed == USB_SPEED_HIGH)
+	if (speed == USB_SPEED_SUPER)
+		return "5 Gb/s";
+	else if (speed == USB_SPEED_HIGH)
 		return "480 Mb/s";
 	else if (speed == USB_SPEED_LOW)
 		return "1.5 Mb/s";
diff --git a/common/usb.c b/common/usb.c
index 39fcedd..a5b915e 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -304,7 +304,7 @@  usb_set_maxpacket_ep(struct usb_device *dev, int if_idx, int ep_idx)
 	struct usb_endpoint_descriptor *ep;
 	u16 ep_wMaxPacketSize;
 
-	ep = &dev->config.if_desc[if_idx].ep_desc[ep_idx];
+	ep = &dev->config.if_desc[if_idx].ep_desc[ep_idx].ep_desc;
 
 	b = ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
 	ep_wMaxPacketSize = get_unaligned(&ep->wMaxPacketSize);
@@ -410,14 +410,19 @@  static int usb_parse_config(struct usb_device *dev,
 			ep_wMaxPacketSize = get_unaligned(&dev->config.\
 							if_desc[ifno].\
 							ep_desc[epno].\
-							wMaxPacketSize);
+							ep_desc.wMaxPacketSize);
 			put_unaligned(le16_to_cpu(ep_wMaxPacketSize),
 					&dev->config.\
 					if_desc[ifno].\
 					ep_desc[epno].\
-					wMaxPacketSize);
+					ep_desc.wMaxPacketSize);
 			USB_PRINTF("if %d, ep %d\n", ifno, epno);
 			break;
+		case USB_DT_SS_ENDPOINT_COMP:
+			if_desc = &dev->config.if_desc[ifno];
+			memcpy(&(if_desc->ep_desc[epno].ss_ep_comp),
+				&buffer[index], buffer[index]);
+			break;
 		default:
 			if (head->bLength == 0)
 				return 1;
diff --git a/common/usb_hub.c b/common/usb_hub.c
index 8ba7a0d..9acaede 100644
--- a/common/usb_hub.c
+++ b/common/usb_hub.c
@@ -158,7 +158,9 @@  static struct usb_hub_device *usb_hub_allocate(void)
 
 static inline char *portspeed(int portstatus)
 {
-	if (portstatus & (1 << USB_PORT_FEAT_HIGHSPEED))
+	if (portstatus & (1 << USB_PORT_FEAT_SUPERSPEED))
+		return "5 Gb/s";
+	else if (portstatus & (1 << USB_PORT_FEAT_HIGHSPEED))
 		return "480 Mb/s";
 	else if (portstatus & (1 << USB_PORT_FEAT_LOWSPEED))
 		return "1.5 Mb/s";
@@ -262,7 +264,9 @@  void usb_hub_port_connect_change(struct usb_device *dev, int port)
 	/* Allocate a new device struct for it */
 	usb = usb_alloc_new_device(dev->controller);
 
-	if (portstatus & USB_PORT_STAT_HIGH_SPEED)
+	if (portstatus & USB_PORT_STAT_SUPER_SPEED)
+		usb->speed = USB_SPEED_SUPER;
+	else if (portstatus & USB_PORT_STAT_HIGH_SPEED)
 		usb->speed = USB_SPEED_HIGH;
 	else if (portstatus & USB_PORT_STAT_LOW_SPEED)
 		usb->speed = USB_SPEED_LOW;
@@ -525,7 +529,7 @@  int usb_hub_probe(struct usb_device *dev, int ifnum)
 	/* Multiple endpoints? What kind of mutant ninja-hub is this? */
 	if (iface->desc.bNumEndpoints != 1)
 		return 0;
-	ep = &iface->ep_desc[0];
+	ep = &iface->ep_desc[0].ep_desc;
 	/* Output endpoint? Curiousier and curiousier.. */
 	if (!(ep->bEndpointAddress & USB_DIR_IN))
 		return 0;
diff --git a/common/usb_storage.c b/common/usb_storage.c
index 475c218..c48da43 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -1301,7 +1301,7 @@  int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,
 	 * We will ignore any others.
 	 */
 	for (i = 0; i < iface->desc.bNumEndpoints; i++) {
-		ep_desc = &iface->ep_desc[i];
+		ep_desc = &iface->ep_desc[i].ep_desc;
 		/* is it an BULK endpoint? */
 		if ((ep_desc->bmAttributes &
 		     USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) {
diff --git a/include/usb.h b/include/usb.h
index d79c865..1d832ca 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -67,6 +67,16 @@  struct devrequest {
 	unsigned short	length;
 } __attribute__ ((packed));
 
+struct usb_ep_desc {
+	struct usb_endpoint_descriptor		ep_desc;
+	/*
+	 * Super Speed Device will have Super Speed Endpoint
+	 * Companion Descriptor  (section 9.6.7 of usb 3.0 spec)
+	 * Revision 1.0 June 6th 2011
+	 */
+	struct usb_ss_ep_comp_descriptor	ss_ep_comp;
+};
+
 /* Interface */
 struct usb_interface {
 	struct usb_interface_descriptor desc;
@@ -75,7 +85,7 @@  struct usb_interface {
 	unsigned char	num_altsetting;
 	unsigned char	act_altsetting;
 
-	struct usb_endpoint_descriptor ep_desc[USB_MAXENDPOINTS];
+	struct usb_ep_desc ep_desc[USB_MAXENDPOINTS];
 } __attribute__ ((packed));
 
 /* Configuration information.. */
diff --git a/include/usb_defs.h b/include/usb_defs.h
index 0c78d9d..e2aaef3 100644
--- a/include/usb_defs.h
+++ b/include/usb_defs.h
@@ -203,6 +203,8 @@ 
 #define USB_PORT_FEAT_POWER          8
 #define USB_PORT_FEAT_LOWSPEED       9
 #define USB_PORT_FEAT_HIGHSPEED      10
+#define USB_PORT_FEAT_FULLSPEED      11
+#define USB_PORT_FEAT_SUPERSPEED     12
 #define USB_PORT_FEAT_C_CONNECTION   16
 #define USB_PORT_FEAT_C_ENABLE       17
 #define USB_PORT_FEAT_C_SUSPEND      18
@@ -218,8 +220,20 @@ 
 #define USB_PORT_STAT_POWER         0x0100
 #define USB_PORT_STAT_LOW_SPEED     0x0200
 #define USB_PORT_STAT_HIGH_SPEED    0x0400	/* support for EHCI */
+#define USB_PORT_STAT_FULL_SPEED    0x0800
+#define USB_PORT_STAT_SUPER_SPEED   0x1000	/* support for XHCI */
 #define USB_PORT_STAT_SPEED	\
-	(USB_PORT_STAT_LOW_SPEED | USB_PORT_STAT_HIGH_SPEED)
+	(USB_PORT_STAT_LOW_SPEED | USB_PORT_STAT_HIGH_SPEED | \
+	USB_PORT_STAT_FULL_SPEED | USB_PORT_STAT_SUPER_SPEED)
+
+/*
+ * Additions to wPortStatus bit field from USB 3.0
+ * See USB 3.0 spec Table 10-10
+ */
+#define USB_PORT_STAT_LINK_STATE	0x01e0
+#define USB_SS_PORT_STAT_POWER		0x0200
+#define USB_SS_PORT_STAT_SPEED		0x1c00
+#define USB_PORT_STAT_SPEED_5GBPS	0x0000
 
 /* wPortChange bits */
 #define USB_PORT_STAT_C_CONNECTION  0x0001
@@ -228,6 +242,14 @@ 
 #define USB_PORT_STAT_C_OVERCURRENT 0x0008
 #define USB_PORT_STAT_C_RESET       0x0010
 
+/*
+ * Addition to wPortChange bit fields form USB 3.0
+ * See USB 3.0 spec Table 10-11
+ */
+#define USB_PORT_STAT_C_BH_RESET	0x0020
+#define USB_PORT_STAT_C_LINK_STATE	0x0040
+#define USB_PORT_STAT_C_CONFIG_ERROR	0x0080
+
 /* wHubCharacteristics (masks) */
 #define HUB_CHAR_LPSM               0x0003
 #define HUB_CHAR_COMPOUND           0x0004