From: peng.fan at nxp.com <peng.fan@nxp.com>
To: u-boot@lists.denx.de
Subject: [PATCH 10/16] usb: gadget: add super speed support
Date: Wed, 16 Sep 2020 21:25:31 +0800 [thread overview]
Message-ID: <20200916132537.8313-11-peng.fan@nxp.com> (raw)
In-Reply-To: <20200916132537.8313-1-peng.fan@nxp.com>
From: Li Jun <jun.li@nxp.com>
This patch is to add usb gadget super speed support in common
driver, including BOS descriptor and select the super speed
descriptor from function driver.
Reviewed-by: Ye Li <ye.li@nxp.com>
Reviewed-by: Peter Chen <peter.chen@nxp.com>
Tested-by: faqiang.zhu <faqiang.zhu@nxp.com>
Signed-off-by: Li Jun <jun.li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
drivers/usb/gadget/composite.c | 85 ++++++++++++++++++++++++----------
include/linux/usb/composite.h | 4 ++
include/linux/usb/gadget.h | 6 +++
3 files changed, 70 insertions(+), 25 deletions(-)
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index b453055838..abb42db6bd 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -88,6 +88,8 @@ int usb_add_function(struct usb_configuration *config,
config->fullspeed = 1;
if (!config->highspeed && function->hs_descriptors)
config->highspeed = 1;
+ if (!config->superspeed && function->ss_descriptors)
+ config->superspeed = 1;
done:
if (value)
@@ -223,7 +225,9 @@ static int config_buf(struct usb_configuration *config,
/* add each function's descriptors */
list_for_each_entry(f, &config->functions, list) {
- if (speed == USB_SPEED_HIGH)
+ if (speed == USB_SPEED_SUPER)
+ descriptors = f->ss_descriptors;
+ else if (speed == USB_SPEED_HIGH)
descriptors = f->hs_descriptors;
else
descriptors = f->descriptors;
@@ -251,7 +255,9 @@ static int config_desc(struct usb_composite_dev *cdev, unsigned w_value)
struct usb_configuration *c;
struct list_head *pos;
- if (gadget_is_dualspeed(gadget)) {
+ if (gadget_is_superspeed(gadget)) {
+ speed = gadget->speed;
+ } else if (gadget_is_dualspeed(gadget)) {
if (gadget->speed == USB_SPEED_HIGH)
hs = 1;
if (type == USB_DT_OTHER_SPEED_CONFIG)
@@ -275,7 +281,10 @@ static int config_desc(struct usb_composite_dev *cdev, unsigned w_value)
continue;
check_config:
- if (speed == USB_SPEED_HIGH) {
+ if (speed == USB_SPEED_SUPER) {
+ if (!c->superspeed)
+ continue;
+ } else if (speed == USB_SPEED_HIGH) {
if (!c->highspeed)
continue;
} else {
@@ -294,8 +303,12 @@ static int count_configs(struct usb_composite_dev *cdev, unsigned type)
struct usb_gadget *gadget = cdev->gadget;
unsigned count = 0;
int hs = 0;
+ int ss = 0;
struct usb_configuration *c;
+ if (gadget->speed == USB_SPEED_SUPER)
+ ss = 1;
+
if (gadget_is_dualspeed(gadget)) {
if (gadget->speed == USB_SPEED_HIGH)
hs = 1;
@@ -304,7 +317,10 @@ static int count_configs(struct usb_composite_dev *cdev, unsigned type)
}
list_for_each_entry(c, &cdev->configs, list) {
/* ignore configs that won't work at this speed */
- if (hs) {
+ if (ss) {
+ if (!c->superspeed)
+ continue;
+ } else if (hs) {
if (!c->highspeed)
continue;
} else {
@@ -388,6 +404,9 @@ static int set_config(struct usb_composite_dev *cdev,
case USB_SPEED_HIGH:
speed = "high";
break;
+ case USB_SPEED_SUPER:
+ speed = "super";
+ break;
default:
speed = "?";
break;
@@ -412,7 +431,9 @@ static int set_config(struct usb_composite_dev *cdev,
* function's setup callback instead of the current
* configuration's setup callback.
*/
- if (gadget->speed == USB_SPEED_HIGH)
+ if (gadget->speed == USB_SPEED_SUPER)
+ descriptors = f->ss_descriptors;
+ else if (gadget->speed == USB_SPEED_HIGH)
descriptors = f->hs_descriptors;
else
descriptors = f->descriptors;
@@ -492,8 +513,9 @@ int usb_add_config(struct usb_composite_dev *cdev,
list_del(&config->list);
config->cdev = NULL;
} else {
- debug("cfg %d/%p speeds:%s%s\n",
+ debug("cfg %d/%p speeds:%s%s%s\n",
config->bConfigurationValue, config,
+ config->superspeed ? " super" : "",
config->highspeed ? " high" : "",
config->fullspeed
? (gadget_is_dualspeed(cdev->gadget)
@@ -751,6 +773,7 @@ static void composite_setup_complete(struct usb_ep *ep, struct usb_request *req)
static int bos_desc(struct usb_composite_dev *cdev)
{
struct usb_ext_cap_descriptor *usb_ext;
+ struct usb_dcd_config_params dcd_config_params;
struct usb_bos_descriptor *bos = cdev->req->buf;
bos->bLength = USB_DT_BOS_SIZE;
@@ -794,9 +817,19 @@ static int bos_desc(struct usb_composite_dev *cdev)
USB_HIGH_SPEED_OPERATION |
USB_5GBPS_OPERATION);
ss_cap->bFunctionalitySupport = USB_LOW_SPEED_OPERATION;
- ss_cap->bU1devExitLat = USB_DEFAULT_U1_DEV_EXIT_LAT;
- ss_cap->bU2DevExitLat =
- cpu_to_le16(USB_DEFAULT_U2_DEV_EXIT_LAT);
+
+ /* Get Controller configuration */
+ if (cdev->gadget->ops->get_config_params) {
+ cdev->gadget->ops->get_config_params(
+ &dcd_config_params);
+ } else {
+ dcd_config_params.bU1devExitLat =
+ USB_DEFAULT_U1_DEV_EXIT_LAT;
+ dcd_config_params.bU2DevExitLat =
+ cpu_to_le16(USB_DEFAULT_U2_DEV_EXIT_LAT);
+ }
+ ss_cap->bU1devExitLat = dcd_config_params.bU1devExitLat;
+ ss_cap->bU2DevExitLat = dcd_config_params.bU2DevExitLat;
}
return le16_to_cpu(bos->wTotalLength);
}
@@ -999,32 +1032,28 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
cdev->desc.bNumConfigurations =
count_configs(cdev, USB_DT_DEVICE);
- /*
- * If the speed is Super speed, then the supported
- * max packet size is 512 and it should be sent as
- * exponent of 2. So, 9(2^9=512) should be filled in
- * bMaxPacketSize0. Also fill USB version as 3.0
- * if speed is Super speed.
- */
- if (cdev->gadget->speed == USB_SPEED_SUPER) {
+ cdev->desc.bMaxPacketSize0 =
+ cdev->gadget->ep0->maxpacket;
+ if (gadget->speed >= USB_SPEED_SUPER) {
+ cdev->desc.bcdUSB = cpu_to_le16(0x0310);
cdev->desc.bMaxPacketSize0 = 9;
- cdev->desc.bcdUSB = cpu_to_le16(0x0300);
} else {
- cdev->desc.bMaxPacketSize0 =
- cdev->gadget->ep0->maxpacket;
+ cdev->desc.bcdUSB = cpu_to_le16(0x0200);
}
value = min(w_length, (u16) sizeof cdev->desc);
memcpy(req->buf, &cdev->desc, value);
break;
case USB_DT_DEVICE_QUALIFIER:
- if (!gadget_is_dualspeed(gadget))
+ if (!gadget_is_dualspeed(gadget) ||
+ gadget->speed >= USB_SPEED_SUPER)
break;
device_qual(cdev);
value = min_t(int, w_length,
sizeof(struct usb_qualifier_descriptor));
break;
case USB_DT_OTHER_SPEED_CONFIG:
- if (!gadget_is_dualspeed(gadget))
+ if (!gadget_is_dualspeed(gadget) ||
+ gadget->speed >= USB_SPEED_SUPER)
break;
case USB_DT_CONFIG:
@@ -1039,10 +1068,16 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
value = min(w_length, (u16) value);
break;
case USB_DT_BOS:
- if (gadget_is_superspeed(cdev->gadget))
+ /*
+ * Super speed connection should support BOS, and
+ * USB compliance test (USB 2.0 Command Verifier)
+ * also issues this request, return for now for
+ * USB 2.0 connection.
+ */
+ if (gadget->speed >= USB_SPEED_SUPER) {
value = bos_desc(cdev);
- if (value >= 0)
value = min(w_length, (u16)value);
+ }
break;
default:
goto unknown;
@@ -1421,7 +1456,7 @@ composite_resume(struct usb_gadget *gadget)
}
static struct usb_gadget_driver composite_driver = {
- .speed = USB_SPEED_HIGH,
+ .speed = USB_SPEED_SUPER,
.bind = composite_bind,
.unbind = composite_unbind,
diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h
index d75a0bc4c4..935e5c0cbb 100644
--- a/include/linux/usb/composite.h
+++ b/include/linux/usb/composite.h
@@ -146,6 +146,7 @@ struct usb_function {
struct usb_gadget_strings **strings;
struct usb_descriptor_header **descriptors;
struct usb_descriptor_header **hs_descriptors;
+ struct usb_descriptor_header **ss_descriptors;
struct usb_configuration *config;
@@ -279,6 +280,7 @@ struct usb_configuration {
u8 next_interface_id;
unsigned highspeed:1;
unsigned fullspeed:1;
+ unsigned superspeed:1;
struct usb_function *interface[MAX_CONFIG_INTERFACES];
};
@@ -292,6 +294,7 @@ int usb_add_config(struct usb_composite_dev *,
* identifiers.
* @strings: tables of strings, keyed by identifiers assigned during bind()
* and language IDs provided in control requests
+ * @max_speed: Highest speed the driver supports.
* @bind: (REQUIRED) Used to allocate resources that are shared across the
* whole device, such as string IDs, and add its configurations using
* @usb_add_config(). This may fail by returning a negative errno
@@ -319,6 +322,7 @@ struct usb_composite_driver {
const char *name;
const struct usb_device_descriptor *dev;
struct usb_gadget_strings **strings;
+ enum usb_device_speed max_speed;
/* REVISIT: bind() functions can be marked __init, which
* makes trouble for section mismatch analysis. See if
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 8d54b91734..7e6d329e54 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -449,6 +449,11 @@ static inline void usb_ep_fifo_flush(struct usb_ep *ep)
/*-------------------------------------------------------------------------*/
+struct usb_dcd_config_params {
+ __u8 bU1devExitLat; /* U1 Device exit Latency */
+ __le16 bU2DevExitLat; /* U2 Device exit Latency */
+};
+
struct usb_gadget;
struct usb_gadget_driver;
@@ -464,6 +469,7 @@ struct usb_gadget_ops {
int (*pullup) (struct usb_gadget *, int is_on);
int (*ioctl)(struct usb_gadget *,
unsigned code, unsigned long param);
+ void (*get_config_params)(struct usb_dcd_config_params *);
int (*udc_start)(struct usb_gadget *,
struct usb_gadget_driver *);
int (*udc_stop)(struct usb_gadget *);
--
2.28.0
next prev parent reply other threads:[~2020-09-16 13:25 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-09-16 13:25 [PATCH 00/16] usb: gadget: update peng.fan at nxp.com
2020-09-16 13:25 ` [PATCH 01/16] usb: gadget: Add ep_config call back to usb_gadget_ops peng.fan at nxp.com
2020-09-16 13:25 ` [PATCH 02/16] usb: gadget: don't change ep name for dwc3 while ep autoconfig peng.fan at nxp.com
2020-09-16 13:25 ` [PATCH 03/16] usb: gadget: OS String support peng.fan at nxp.com
2020-09-16 13:25 ` [PATCH 04/16] usb: gadget: move utf8_to_utf16le to header file peng.fan at nxp.com
2020-09-16 13:25 ` [PATCH 05/16] usb: gadget: OS Feature Descriptors support peng.fan at nxp.com
2020-09-16 13:25 ` [PATCH 06/16] usb: gadget: add WCID support for mfgtool peng.fan at nxp.com
2020-09-16 13:25 ` [PATCH 07/16] usb: gadget: fastboot: add ext properties for WCID peng.fan at nxp.com
2020-09-16 13:25 ` [PATCH 08/16] usb: gadget: set correct usb_configuration for os_desc_config peng.fan at nxp.com
2020-09-16 13:25 ` [PATCH 09/16] usb: gadget: update os_desc_config when add config peng.fan at nxp.com
2020-09-16 13:25 ` peng.fan at nxp.com [this message]
2020-09-16 13:25 ` [PATCH 11/16] usb: fastboot: add super speed support peng.fan at nxp.com
2020-09-16 13:25 ` [PATCH 12/16] usb: gadget: dnl: set dnl to be super speed peng.fan at nxp.com
2020-09-16 13:25 ` [PATCH 13/16] usb: composite: force gadget to be USB2 for HS only function peng.fan at nxp.com
2020-09-16 13:25 ` [PATCH 14/16] usb: udc: ci: update speed handling peng.fan at nxp.com
2020-09-16 13:25 ` [PATCH 15/16] usb: gadget: fastboot: use correct max packet size peng.fan at nxp.com
2020-09-16 13:25 ` [PATCH 16/16] usb: gaget: ci: set ep's desc when enable ep peng.fan at nxp.com
2020-10-10 6:00 ` [PATCH 00/16] usb: gadget: update Peng Fan
2021-01-03 10:32 ` Peng Fan
2021-01-23 12:11 ` Lukasz Majewski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200916132537.8313-11-peng.fan@nxp.com \
--to=peng.fan@nxp.com \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.