The USB 3.2 specification supports dual-lane and different transfer rates. The speed field is not sufficient to describe the device's sublink. Devices operating in SuperSpeed Plus can refer to gen2x1, gen1x2, or gen2x2. The driver may be contrained by a specific sublink attribute. Add max lane count and lane speed mantissa in Gbps in usb_gadget_driver to provide more contrains for function drivers that support SuperSpeed Plus. Update usb_gadget struct to report the max number of lanes support and connected lane count. Also, add lane speed mantissa in Gigabits per second to properly describe the device transfer rate. Signed-off-by: Thinh Nguyen <thinhn@xxxxxxxxxxxx> --- include/linux/usb/composite.h | 4 ++++ include/linux/usb/gadget.h | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index 8675e145ea8b..ed3fb9a53c4a 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -356,6 +356,8 @@ enum { * are predefined. The first entry that may be used is * USB_GADGET_FIRST_AVAIL_IDX * @max_speed: Highest speed the driver supports. + * @max_lane_count: maximum number of lanes the driver supports (SSP only). + * @max_lsm: maximum lane speed mantissa in Gbps the driver supports (SSP only). * @needs_serial: set to 1 if the gadget needs userspace to provide * a serial number. If one is not provided, warning will be printed. * @bind: (REQUIRED) Used to allocate resources that are shared across the @@ -387,6 +389,8 @@ struct usb_composite_driver { const struct usb_device_descriptor *dev; struct usb_gadget_strings **strings; enum usb_device_speed max_speed; + u8 max_lane_count; + u8 max_lsm; unsigned needs_serial:1; int (*bind)(struct usb_composite_dev *cdev); diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index 124462d65eac..cb7531a6f784 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -335,6 +335,10 @@ struct usb_gadget_ops { * @speed: Speed of current connection to USB host. * @max_speed: Maximal speed the UDC can handle. UDC must support this * and all slower speeds. + * @lane_count: number of lanes in use. + * @max_lane_count: maximum number of lanes the UDC can handle. + * @lsm: current connection lane speed mantissa in Gbps + * @max_lsm: maximum lane speed mantissa in Gbps * @state: the state we are now (attached, suspended, configured, etc) * @name: Identifies the controller hardware type. Used in diagnostics * and sometimes configuration. @@ -401,6 +405,10 @@ struct usb_gadget { struct list_head ep_list; /* of usb_ep */ enum usb_device_speed speed; enum usb_device_speed max_speed; + unsigned lane_count; + unsigned max_lane_count; + unsigned lsm; + unsigned max_lsm; enum usb_device_state state; const char *name; struct device dev; @@ -600,6 +608,8 @@ static inline int usb_gadget_activate(struct usb_gadget *gadget) * struct usb_gadget_driver - driver for usb 'slave' devices * @function: String describing the gadget's function * @max_speed: Highest speed the driver handles. + * @max_lane_count: maximum lane count the driver handles (SSP only). + * @max_lsm: maximum lane speed mantissa in Gbps the driver handles (SSP only). * @setup: Invoked for ep0 control requests that aren't handled by * the hardware level driver. Most calls must be handled by * the gadget driver, including descriptor and configuration @@ -672,6 +682,8 @@ static inline int usb_gadget_activate(struct usb_gadget *gadget) struct usb_gadget_driver { char *function; enum usb_device_speed max_speed; + u8 max_lane_count; + u8 max_lsm; int (*bind)(struct usb_gadget *gadget, struct usb_gadget_driver *driver); void (*unbind)(struct usb_gadget *); -- 2.11.0