usb: gadget: get rid of USB_GADGET_DUALSPEED and USB_GADGET_SUPERSPEED
Subsystems (4)
A message that is not in the archive (sent off-list or not yet received): [email protected]
PATCH 1/1 usb: gadget: get rid of USB_GADGET_DUALSPEED and USB_GADGET_SUPERSPEED
From: Michal Nazarewicz <[email protected]>
This commit removes the use of USB_GADGET_DUALSPEED and USB_GADGET_SUPERSPEED Kconfig options. Those were selected by UDC drivers which supported respective speeds.
However, since kernel now allows multiple UDC drivers to be compiled, the options in question may no longer reflect the state of all gadgets.
For instance, if one driver that supports dual speed is selected and another that does not, the USB_GADGE_DUALSPEED will be set "for both".
This commit replaces all the #ifdefs by a run-time checks made by calling gadget_is_dualspeed().
--- drivers/usb/gadget/Kconfig | 30 ------------------- drivers/usb/gadget/composite.c | 9 +----- drivers/usb/gadget/file_storage.c | 4 -- drivers/usb/gadget/inode.c | 18 ++--------- drivers/usb/gadget/printer.c | 59 ++++++++++-------------------------- drivers/usb/gadget/u_ether.c | 7 ---- 6 files changed, 21 insertions(+), 106 deletions(-)
Please note that because I'm currently lacking hardware to test it (and PandaBoard seem out of stock everywhere), the code is compile-tested only.
It is applied on top of next-20110817.
drivers/usb/gadget/Kconfig +0 -30
@@ -133,7 +133,6 @@ config USB_AT91 config USB_ATMEL_USBA tristate "Atmel USBA" - select USB_GADGET_DUALSPEED depends on AVR32 || ARCH_AT91CAP9 || ARCH_AT91SAM9RL || ARCH_AT91SAM9G45 help USBA is the integrated high-speed USB Device controller on
@@ -142,7 +141,6 @@ config USB_ATMEL_USBA config USB_FSL_USB2 tristate "Freescale Highspeed USB DR Peripheral Controller" depends on FSL_SOC || ARCH_MXC - select USB_GADGET_DUALSPEED select USB_FSL_MPH_DR_OF if OF help Some of Freescale PowerPC processors have a High Speed
@@ -158,7 +156,6 @@ config USB_FSL_USB2 config USB_FUSB300 tristate "Faraday FUSB300 USB Peripheral Controller" depends on !PHYS_ADDR_T_64BIT - select USB_GADGET_DUALSPEED help Faraday usb device controller FUSB300 driver
@@ -206,7 +203,6 @@ config USB_PXA25X_SMALL config USB_R8A66597 tristate "Renesas R8A66597 USB Peripheral Controller" - select USB_GADGET_DUALSPEED help R8A66597 is a discrete USB host and peripheral controller chip that supports both full and high speed USB 2.0 data transfers.
@@ -220,7 +216,6 @@ config USB_RENESAS_USBHS_UDC tristate 'Renesas USBHS controller' depends on SUPERH || ARCH_SHMOBILE depends on USB_RENESAS_USBHS - select USB_GADGET_DUALSPEED help Renesas USBHS is a discrete USB host and peripheral controller chip that supports both full and high speed USB 2.0 data transfers.
@@ -249,7 +244,6 @@ config USB_S3C_HSOTG tristate "S3C HS/OtG USB Device controller" depends on S3C_DEV_USB_HSOTG select USB_GADGET_S3C_HSOTG_PIO - select USB_GADGET_DUALSPEED help The Samsung S3C64XX USB2.0 high-speed gadget controller integrated into the S3C64XX series SoC.
@@ -287,7 +281,6 @@ config USB_S3C2410_DEBUG config USB_S3C_HSUDC tristate "S3C2416, S3C2443 and S3C2450 USB Device Controller" depends on ARCH_S3C2410 - select USB_GADGET_DUALSPEED help Samsung's S3C2416, S3C2443 and S3C2450 is an ARM9 based SoC integrated with dual speed USB 2.0 device controller. It has
@@ -298,7 +291,6 @@ config USB_S3C_HSUDC config USB_PXA_U2O tristate "PXA9xx Processor USB2.0 controller" depends on ARCH_MMP - select USB_GADGET_DUALSPEED help PXA9xx Processor series include a high speed USB2.0 device controller, which support high speed and full speed USB peripheral.
@@ -311,14 +303,12 @@ config USB_PXA_U2O config USB_GADGET_MUSB_HDRC tristate "Inventra HDRC USB Peripheral (TI, ADI, ...)" depends on USB_MUSB_HDRC - select USB_GADGET_DUALSPEED help This OTG-capable silicon IP is used in dual designs including the TI DaVinci, OMAP 243x, OMAP 343x, TUSB 6010, and ADI Blackfin config USB_M66592 tristate "Renesas M66592 USB Peripheral Controller" - select USB_GADGET_DUALSPEED help M66592 is a discrete USB peripheral controller chip that supports both full and high speed USB 2.0 data transfers.
@@ -335,7 +325,6 @@ config USB_M66592 config USB_AMD5536UDC tristate "AMD5536 UDC" depends on PCI - select USB_GADGET_DUALSPEED help The AMD5536 UDC is part of the AMD Geode CS5536, an x86 southbridge. It is a USB Highspeed DMA capable USB device controller. Beside ep0
@@ -363,7 +352,6 @@ config USB_FSL_QE config USB_CI13XXX_PCI tristate "MIPS USB CI13xxx PCI UDC" depends on PCI - select USB_GADGET_DUALSPEED help MIPS USB IP core family device controller Currently it only supports IP part number CI13412
@@ -374,7 +362,6 @@ config USB_CI13XXX_PCI config USB_NET2272 tristate "PLX NET2272" - select USB_GADGET_DUALSPEED help PLX NET2272 is a USB peripheral controller which supports both full and high speed USB 2.0 data transfers.
@@ -398,7 +385,6 @@ config USB_NET2272_DMA config USB_NET2280 tristate "NetChip 228x" depends on PCI - select USB_GADGET_DUALSPEED help NetChip 2280 / 2282 is a PCI based USB peripheral controller which supports both full and high speed USB 2.0 data transfers.
@@ -429,7 +415,6 @@ config USB_LANGWELL tristate "Intel Langwell USB Device Controller" depends on PCI depends on !PHYS_ADDR_T_64BIT - select USB_GADGET_DUALSPEED help Intel Langwell USB Device Controller is a High-Speed USB On-The-Go device controller.
@@ -444,7 +429,6 @@ config USB_LANGWELL config USB_EG20T tristate "Intel EG20T PCH/OKI SEMICONDUCTOR ML7213 IOH UDC" depends on PCI - select USB_GADGET_DUALSPEED help This is a USB device driver for EG20T PCH. EG20T PCH is the platform controller hub that is used in Intel's
@@ -466,7 +450,6 @@ config USB_EG20T config USB_CI13XXX_MSM tristate "MIPS USB CI13xxx for MSM" depends on ARCH_MSM - select USB_GADGET_DUALSPEED select USB_MSM_OTG help MSM SoC has chipidea USB controller. This driver uses
@@ -487,8 +470,6 @@ config USB_CI13XXX_MSM config USB_DUMMY_HCD tristate "Dummy HCD (DEVELOPMENT)" depends on USB=y || (USB=m && USB_GADGET=m) - select USB_GADGET_DUALSPEED - select USB_GADGET_SUPERSPEED help This host controller driver emulates USB, looping all data transfer requests back to a USB "gadget driver" in the same host. The host
@@ -513,17 +494,6 @@ config USB_DUMMY_HCD endchoice -# Selected by UDC drivers that support high-speed operation. -config USB_GADGET_DUALSPEED - bool - depends on USB_GADGET - -# Selected by UDC drivers that support super-speed opperation -config USB_GADGET_SUPERSPEED - bool - depends on USB_GADGET - depends on USB_GADGET_DUALSPEED - # # USB Gadget Drivers #
drivers/usb/gadget/composite.c +1 -8
@@ -1559,12 +1559,6 @@ composite_resume(struct usb_gadget *gadget)/*-------------------------------------------------------------------------*/ static struct usb_gadget_driver composite_driver = { -#ifdef CONFIG_USB_GADGET_SUPERSPEED - .speed =USB_SPEED_SUPER , -#else - .speed =USB_SPEED_HIGH , -#endif - .unbind = composite_unbind, .setup = composite_setup,
@@ -1609,8 +1603,7 @@ int usb_composite_probe(struct usb_composite_driver *driver, driver->iProduct = driver->name; composite_driver.function = (char *) driver->name; composite_driver.driver.name = driver->name; - composite_driver.speed =min ((u8 )composite_driver.speed, - (u8 )driver->max_speed); + composite_driver.speed =min (USB_SPEED_SUPER , driver->max_speed); composite = driver; composite_gadget_bind = bind;
drivers/usb/gadget/file_storage.c +0 -4
@@ -3562,11 +3562,7 @@ static void fsg_resume(struct usb_gadget *gadget)/*-------------------------------------------------------------------------*/ static struct usb_gadget_driver fsg_driver = { -#ifdef CONFIG_USB_GADGET_DUALSPEED .speed =USB_SPEED_HIGH , -#else - .speed =USB_SPEED_FULL , -#endif .function = (char *) fsg_string_product, .unbind = fsg_unbind, .disconnect = fsg_disconnect,
drivers/usb/gadget/inode.c +3 -15
@@ -837,7 +837,6 @@ ep_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)if (value ==0 ) data->state =STATE_EP_ENABLED ;break ; -#ifdef CONFIG_USB_GADGET_DUALSPEED case USB_SPEED_HIGH :/* fails if caller didn't provide that descriptor... */ ep->desc = &data->hs_desc;
@@ -845,7 +844,6 @@ ep_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)if (value ==0 ) data->state =STATE_EP_ENABLED ;break ; -#endif default :DBG (data->dev,"unconnected, %s init abandoned\n" , data->name);
@@ -1015,9 +1013,8 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr)if (dev->current_config) {unsigned power; -if (gadget_is_dualspeed (dev->gadget) - && (dev->gadget->speed - ==USB_SPEED_HIGH )) +if (gadget_is_dualspeed (dev->gadget) && + (dev->gadget->speed ==USB_SPEED_HIGH )) power = dev->hs_config->bMaxPower;else power = dev->config->bMaxPower;
@@ -1331,7 +1328,6 @@ static const struct file_operations ep0_io_operations = {* Unrecognized ep0 requests may be handled in user space. */ -#ifdef CONFIG_USB_GADGET_DUALSPEED static void make_qualifier (struct dev_data *dev) {struct usb_qualifier_descriptor qual;
@@ -1354,10 +1350,8 @@ static void make_qualifier (struct dev_data *dev)memcpy (dev->rbuf, &qual,sizeof qual); } -#endif -static int -config_buf (struct dev_data *dev,u8 type,unsigned index) +static int config_buf (struct dev_data *dev,u8 type,unsigned index) {int len;int hs =0 ;
@@ -1434,7 +1428,6 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) dev->dev->bMaxPacketSize0 = dev->gadget->ep0->maxpacket; req->buf = dev->dev;break ; -#ifdef CONFIG_USB_GADGET_DUALSPEED case USB_DT_DEVICE_QUALIFIER :if (!dev->hs_config)break ;
@@ -1444,7 +1437,6 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)break ;case USB_DT_OTHER_SPEED_CONFIG :// FALLTHROUGH -#endif case USB_DT_CONFIG : value = config_buf (dev, w_value >> 8,
@@ -1773,11 +1765,7 @@ gadgetfs_suspend (struct usb_gadget *gadget) }static struct usb_gadget_driver gadgetfs_driver = { -#ifdef CONFIG_USB_GADGET_DUALSPEED .speed =USB_SPEED_HIGH , -#else - .speed =USB_SPEED_FULL , -#endif .function = (char *) driver_desc, .unbind = gadgetfs_unbind, .setup = gadgetfs_setup,
drivers/usb/gadget/printer.c +17 -42
139 lines not on this page · raw message
drivers/usb/gadget/u_ether.c +0 -7
@@ -92,17 +92,10 @@ struct eth_dev {#define DEFAULT_QLEN 2/* double buffering by default */ - -#ifdef CONFIG_USB_GADGET_DUALSPEED -static unsigned qmult =5 ;module_param (qmult, uint,S_IRUGO |S_IWUSR );MODULE_PARM_DESC (qmult,"queue length multiplier at high/super speed" ); -#else /* full speed (low speed doesn't do bulk) */ -#define qmult 1 -#endif -/* for dual-speed hardware, use deeper queues at high/super speed */ static inline int qlen (struct usb_gadget *gadget) {
Signature · 1 line
1.7.3.1
Quoted 19 lines · Michal Nazarewicz
From: Michal Nazarewicz <[email protected]>
This commit removes the use of
USB_GADGET_DUALSPEEDandUSB_GADGET_SUPERSPEEDKconfigoptions. Those were selected by UDC drivers which supported respective speeds.However, since kernel now allows multiple UDC drivers to be compiled, the options in question may no longer reflect the state of all gadgets.
For instance, if one driver that supports dual speed is selected and another that does not, the
USB_GADGE_DUALSPEEDwill be set "for both".This commit replaces all the #ifdefs by a run-time checks made by calling
gadget_is_dualspeed().
drivers/usb/gadget/composite.c int usb_composite_probe(struct usb_composite_driver *driver, · line 1606
Quoted 6 lines
drivers/usb/gadget/composite.c +1
-2@@ -1609,8 +1603,7 @@ int usb_composite_probe(struct usb_composite_driver *driver, driver->iProduct = driver->name; composite_driver.function = (char *) driver->name; composite_driver.driver.name = driver->name; - composite_driver.speed =min ((u8 )composite_driver.speed, - (u8 )driver->max_speed); + composite_driver.speed =min (USB_SPEED_SUPER , driver->max_speed);
I wonder if the min is needed here at all. It doesn't seem to be doing any good.
Quoted 4 lines
drivers/usb/gadget/file_storage.c +0
-0@@ -3562,11 +3562,7 @@ static void fsg_resume(struct usb_gadget *gadget)/*-------------------------------------------------------------------------*/
drivers/usb/gadget/file_storage.c static void fsg_resume(struct usb_gadget *gadget) · line 3568
Quoted 10 lines
drivers/usb/gadget/file_storage.c +0
-4static struct usb_gadget_driver fsg_driver = { -#ifdef CONFIG_USB_GADGET_DUALSPEED .speed =USB_SPEED_HIGH , -#else - .speed =USB_SPEED_FULL , -#endif .function = (char *) fsg_string_product, .unbind = fsg_unbind, .disconnect = fsg_disconnect,
You mustn't remove the .speed field entirely. Set it to USB_SPEED_HIGH. The same goes for the other drivers below.
Quoted 7 lines
drivers/usb/gadget/inode.c +0
-0@@ -1015,9 +1013,8 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr)if (dev->current_config) {
drivers/usb/gadget/inode.c ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) · line 1020
Quoted 10 lines
drivers/usb/gadget/inode.c +2
-3unsigned power; -if (gadget_is_dualspeed (dev->gadget) - && (dev->gadget->speed - ==USB_SPEED_HIGH )) +if (gadget_is_dualspeed (dev->gadget) && + (dev->gadget->speed ==USB_SPEED_HIGH )) power = dev->hs_config->bMaxPower;else power = dev->config->bMaxPower;
Please don't mix functional changes with cosmetic whitespace changes.
Alan Stern
Quoted 9 lines · Michal Nazarewicz
Quoted 8 lines
drivers/usb/gadget/composite.c +1
-2@@ -1609,8 +1603,7 @@ int usb_composite_probe(struct usb_composite_driver *driver, driver->iProduct = driver->name; composite_driver.function = (char *) driver->name; composite_driver.driver.name = driver->name; - composite_driver.speed =min ((u8 )composite_driver.speed, - (u8 )driver->max_speed); + composite_driver.speed =min (USB_SPEED_SUPER , driver->max_speed);
Quoted 2 lines · Alan Stern
I wonder if the min is needed here at all. It doesn't seem to be doing any good.
Do you mean just doing “composite_driver.speed = driver->max_speed”?
Quoted 5 lines
Quoted 5 lines
drivers/usb/gadget/file_storage.c +0
-0@@ -3562,11 +3562,7 @@ static void fsg_resume(struct usb_gadget *gadget)/*-------------------------------------------------------------------------*/
Quoted 12 lines
drivers/usb/gadget/file_storage.c static void fsg_resume(struct usb_gadget *gadget) · line 3568
Quoted 9 lines
drivers/usb/gadget/file_storage.c +0
-4static struct usb_gadget_driver fsg_driver = { -#ifdef CONFIG_USB_GADGET_DUALSPEED .speed =USB_SPEED_HIGH , -#else - .speed =USB_SPEED_FULL , -#endif .function = (char *) fsg_string_product, .unbind = fsg_unbind, .disconnect = fsg_disconnect,You mustn't remove the .speed field entirely. Set it to
USB_SPEED_HIGH. The same goes for the other drivers below.
Please note that the field is not in fact removed.
I've removed it in composite_driver only but that's because it is later set in usb_composite_probe() (ie. see hunk above).
Quoted 10 lines
Quoted 10 lines
drivers/usb/gadget/inode.c +0
-0@@ -1015,9 +1013,8 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr)if (dev->current_config) {unsigned power;
Quoted 10 lines
Quoted 8 lines
drivers/usb/gadget/inode.c +2
-3-if (gadget_is_dualspeed (dev->gadget) - && (dev->gadget->speed - ==USB_SPEED_HIGH )) +if (gadget_is_dualspeed (dev->gadget) && + (dev->gadget->speed ==USB_SPEED_HIGH )) power = dev->hs_config->bMaxPower;else power =
dev->config->bMaxPower;Please don't mix functional changes with cosmetic whitespace changes.
Will fix.
Signature · 4 lines
Best regards, _ _ .o. | Liege of Serenely Enlightened Majesty of o' \,=./ `o ..o | Computer Science, Michal "mina86" Nazarewicz (o o) ooo +-----<email/xmpp: [email protected]>-----ooO--(_)--Ooo--
Quoted 12 lines · Michal Nazarewicz
Quoted 9 lines · Michal Nazarewicz
drivers/usb/gadget/composite.c int usb_composite_probe(struct · line 1607
Quoted 8 lines
drivers/usb/gadget/composite.c +1
-2@@ -1609,8 +1603,7 @@ int usb_composite_probe(struct usb_composite_driver *driver, driver->iProduct = driver->name; composite_driver.function = (char *) driver->name; composite_driver.driver.name = driver->name; - composite_driver.speed =min ((u8 )composite_driver.speed, - (u8 )driver->max_speed); + composite_driver.speed =min (USB_SPEED_SUPER , driver->max_speed);On Wed, 17 Aug 2011 16:20:15 +0200, Alan Stern <[email protected]> wrote:
Quoted 4 lines
Quoted 2 lines
I wonder if the min is needed here at all. It doesn't seem to be doing any good.
Do you mean just doing “composite_driver.speed = driver->max_speed”?
Yes. After all, there aren't any usb_device_speed values larger than USB_SPEED_SUPER.
Quoted 18 lines
Quoted 5 lines
Quoted 5 lines
drivers/usb/gadget/file_storage.c +0
-0@@ -3562,11 +3562,7 @@ static void fsg_resume(struct usb_gadget *gadget)/*-------------------------------------------------------------------------*/ Quoted 12 lines
drivers/usb/gadget/file_storage.c static void fsg_resume(struct usb_gadget *gadget) · line 3568
Quoted 9 lines
drivers/usb/gadget/file_storage.c +0
-4static struct usb_gadget_driver fsg_driver = { -#ifdef CONFIG_USB_GADGET_DUALSPEED .speed =USB_SPEED_HIGH , -#else - .speed =USB_SPEED_FULL , -#endif .function = (char *) fsg_string_product, .unbind = fsg_unbind, .disconnect = fsg_disconnect,You mustn't remove the .speed field entirely. Set it to
USB_SPEED_HIGH. The same goes for the other drivers below.
Quoted 1 line
Please note that the field is not in fact removed.
No, but you removed its initializer and as a result, it will be set to 0 whereas it should be set to USB_SPEED_HIGH.
Alan Stern
Quoted 15 lines
Quoted 12 lines
Quoted 9 lines · Michal Nazarewicz
Quoted 8 lines
drivers/usb/gadget/composite.c +1
-2@@ -1609,8 +1603,7 @@ int usb_composite_probe(struct usb_composite_driver *driver, driver->iProduct = driver->name; composite_driver.function = (char *) driver->name; composite_driver.driver.name = driver->name; - composite_driver.speed =min ((u8 )composite_driver.speed, - (u8 )driver->max_speed); + composite_driver.speed =min (USB_SPEED_SUPER , driver->max_speed);Quoted 1 line · Alan Stern
I wonder if the min is needed here at all. It doesn't seem to be doing any good.
Quoted 1 line · Michal Nazarewicz
Do you mean just doing “composite_driver.speed = driver->max_speed”?
Quoted 2 lines · Alan Stern
Yes. After all, there aren't any
usb_device_speedvalues larger thanUSB_SPEED_SUPER.
Will fix.
Quoted 16 lines
Quoted 15 lines
Quoted 15 lines
drivers/usb/gadget/file_storage.c static void fsg_resume(struct usb_gadget · line 3567
Quoted 13 lines
drivers/usb/gadget/file_storage.c +0
-4@@ -3562,11 +3562,7 @@ static void fsg_resume(struct usb_gadget *gadget)static struct usb_gadget_driver fsg_driver = { -#ifdef CONFIG_USB_GADGET_DUALSPEED .speed =USB_SPEED_HIGH , -#else - .speed =USB_SPEED_FULL , -#endif .function = (char *) fsg_string_product, .unbind = fsg_unbind, .disconnect = fsg_disconnect,You mustn't remove the .speed field entirely. Set it to
USB_SPEED_HIGH.
Quoted 4 lines
Quoted 1 line
Please note that the field is not in fact removed.
No, but you removed its initializer and as a result, it will be set to 0 whereas it should be set to
USB_SPEED_HIGH.
The initializer is still there. ;) Only the “#” lines and the initializer in the “#else” part are removed.
Signature · 4 lines
Best regards, _ _ .o. | Liege of Serenely Enlightened Majesty of o' \,=./ `o ..o | Computer Science, Michal "mina86" Nazarewicz (o o) ooo +-----<email/xmpp: [email protected]>-----ooO--(_)--Ooo--
Quoted 17 lines · Michal Nazarewicz
Quoted 16 lines
Quoted 16 lines
Quoted 16 lines
drivers/usb/gadget/file_storage.c static void fsg_resume(struct usb_gadget · line 3567
Quoted 13 lines
drivers/usb/gadget/file_storage.c +0
-4@@ -3562,11 +3562,7 @@ static void fsg_resume(struct usb_gadget *gadget)static struct usb_gadget_driver fsg_driver = { -#ifdef CONFIG_USB_GADGET_DUALSPEED .speed =USB_SPEED_HIGH , -#else - .speed =USB_SPEED_FULL , -#endif .function = (char *) fsg_string_product, .unbind = fsg_unbind, .disconnect = fsg_disconnect,You mustn't remove the .speed field entirely. Set it to
USB_SPEED_HIGH.
Quoted 7 lines
Quoted 4 lines
Quoted 1 line
Please note that the field is not in fact removed.
No, but you removed its initializer and as a result, it will be set to 0 whereas it should be set to
USB_SPEED_HIGH.The initializer is still there. ;) Only the “#” lines and the initializer in the “#else” part are removed.
I must be going selectively blind. Never mind...
Alan Stern
Hello.
Quoted 18 lines · Michal Nazarewicz
From: Michal Nazarewicz <[email protected]>
This commit removes the use of
USB_GADGET_DUALSPEEDandUSB_GADGET_SUPERSPEEDKconfigoptions. Those were selected by UDC drivers which supported respective speeds.However, since kernel now allows multiple UDC drivers to be compiled, the options in question may no longer reflect the state of all gadgets.
For instance, if one driver that supports dual speed is selected and another that does not, the
USB_GADGE_DUALSPEEDwill be set "for both".This commit replaces all the #ifdefs by a run-time checks made by calling
gadget_is_dualspeed().Signed-off-by Michal Nazarewicz <[email protected]>
[...]
Quoted 4 lines
drivers/usb/gadget/inode.c +0
-0
[...]
drivers/usb/gadget/inode.c ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) · line 1017
Quoted 9 lines
drivers/usb/gadget/inode.c +2
-3@@ -1015,9 +1013,8 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr)if (dev->current_config) {unsigned power; -if (gadget_is_dualspeed (dev->gadget) - && (dev->gadget->speed - ==USB_SPEED_HIGH )) +if (gadget_is_dualspeed (dev->gadget) && + (dev->gadget->speed ==USB_SPEED_HIGH ))
As Alan noted, this is quite unrelated white space change.
Quoted 5 lines
drivers/usb/gadget/inode.c +0
-0power = dev->hs_config->bMaxPower; else power = dev->config->bMaxPower;@@ -1354,10 +1350,8 @@ static void make_qualifier (struct dev_data *dev)
drivers/usb/gadget/inode.c static void make_qualifier (struct dev_data *dev) · line 1357
Quoted 10 lines
drivers/usb/gadget/inode.c +1
-3memcpy (dev->rbuf, &qual,sizeof qual); } -#endif -static int -config_buf (struct dev_data *dev,u8 type,unsigned index) +static int config_buf (struct dev_data *dev,u8 type,unsigned index) {int len;int hs =0 ;
WARNING: space prohibited between function name and open parenthesis '(' #291: FILE: drivers/usb/gadget/inode.c:1354:
+static int config_buf (struct dev_data *dev, u8 type, unsigned index)
total: 0 errors, 1 warnings, 400 lines checked
patches/usb-gadget-get-rid-of-USB_GADGET_DUALSPEED-and-USB_GADGET_SUPERSPEED.patch has style problems, please review.
If any of these errors are false positives, please report them to the maintainer, see CHECKPATCH in MAINTAINERS.
WBR, Sergei
Quoted 11 lines
Quoted 10 lines · Michal Nazarewicz
drivers/usb/gadget/inode.c +1
-2@@ -1354,10 +1350,8 @@ static void make_qualifier (struct dev_data *dev)memcpy (dev->rbuf, &qual,sizeof qual); } -#endif -static int -config_buf (struct dev_data *dev,u8 type,unsigned index) +static int config_buf (struct dev_data *dev,u8 type,unsigned index) {int len;int hs =0 ;
Quoted 3 lines · Sergei Shtylyov
WARNING: space prohibited between function name and open parenthesis '(' #291: FILE:
drivers/usb/gadget/inode.c:1354:
+static intconfig_buf(structdev_data*dev, u8 type, unsigned index)
This is actually also an unrelated white-space change so I'll just remove this change.
Signature · 4 lines
Best regards, _ _ .o. | Liege of Serenely Enlightened Majesty of o' \,=./ `o ..o | Computer Science, Michal "mina86" Nazarewicz (o o) ooo +-----<email/xmpp: [email protected]>-----ooO--(_)--Ooo--
PATCH v2 1/1 usb: gadget: get rid of USB_GADGET_DUALSPEED and USB_GADGET_SUPERSPEED
In reply to a message not in the archiveFrom: Michal Nazarewicz <[email protected]>
This commit removes the use of USB_GADGET_DUALSPEED and USB_GADGET_SUPERSPEED Kconfig options. Those were selected by UDC drivers which supported respective speeds.
However, since kernel now allows multiple UDC drivers to be compiled, the options in question may no longer reflect the state of all gadgets.
For instance, if one driver that supports dual speed is selected and another that does not, the USB_GADGE_DUALSPEED will be set "for both".
This commit replaces all the #ifdefs by a run-time checks made by calling gadget_is_dualspeed().
--- drivers/usb/gadget/Kconfig | 30 ------------------------- drivers/usb/gadget/composite.c | 9 +------- drivers/usb/gadget/file_storage.c | 4 --- drivers/usb/gadget/inode.c | 10 -------- drivers/usb/gadget/printer.c | 43 ++++++------------------------------- drivers/usb/gadget/u_ether.c | 7 ------ 6 files changed, 8 insertions(+), 95 deletions(-)
Like before, this has been only compile-tested (make allmodconfig bzImage modules on x86_64).
Compared to v1:
* Removed unrelated whitespace changes
* Removed the use of min() in usb_composite_probe()
drivers/usb/gadget/Kconfig +0 -30
@@ -133,7 +133,6 @@ config USB_AT91 config USB_ATMEL_USBA tristate "Atmel USBA" - select USB_GADGET_DUALSPEED depends on AVR32 || ARCH_AT91CAP9 || ARCH_AT91SAM9RL || ARCH_AT91SAM9G45 help USBA is the integrated high-speed USB Device controller on
@@ -142,7 +141,6 @@ config USB_ATMEL_USBA config USB_FSL_USB2 tristate "Freescale Highspeed USB DR Peripheral Controller" depends on FSL_SOC || ARCH_MXC - select USB_GADGET_DUALSPEED select USB_FSL_MPH_DR_OF if OF help Some of Freescale PowerPC processors have a High Speed
@@ -158,7 +156,6 @@ config USB_FSL_USB2 config USB_FUSB300 tristate "Faraday FUSB300 USB Peripheral Controller" depends on !PHYS_ADDR_T_64BIT - select USB_GADGET_DUALSPEED help Faraday usb device controller FUSB300 driver
@@ -206,7 +203,6 @@ config USB_PXA25X_SMALL config USB_R8A66597 tristate "Renesas R8A66597 USB Peripheral Controller" - select USB_GADGET_DUALSPEED help R8A66597 is a discrete USB host and peripheral controller chip that supports both full and high speed USB 2.0 data transfers.
@@ -220,7 +216,6 @@ config USB_RENESAS_USBHS_UDC tristate 'Renesas USBHS controller' depends on SUPERH || ARCH_SHMOBILE depends on USB_RENESAS_USBHS - select USB_GADGET_DUALSPEED help Renesas USBHS is a discrete USB host and peripheral controller chip that supports both full and high speed USB 2.0 data transfers.
@@ -249,7 +244,6 @@ config USB_S3C_HSOTG tristate "S3C HS/OtG USB Device controller" depends on S3C_DEV_USB_HSOTG select USB_GADGET_S3C_HSOTG_PIO - select USB_GADGET_DUALSPEED help The Samsung S3C64XX USB2.0 high-speed gadget controller integrated into the S3C64XX series SoC.
@@ -287,7 +281,6 @@ config USB_S3C2410_DEBUG config USB_S3C_HSUDC tristate "S3C2416, S3C2443 and S3C2450 USB Device Controller" depends on ARCH_S3C2410 - select USB_GADGET_DUALSPEED help Samsung's S3C2416, S3C2443 and S3C2450 is an ARM9 based SoC integrated with dual speed USB 2.0 device controller. It has
@@ -298,7 +291,6 @@ config USB_S3C_HSUDC config USB_PXA_U2O tristate "PXA9xx Processor USB2.0 controller" depends on ARCH_MMP - select USB_GADGET_DUALSPEED help PXA9xx Processor series include a high speed USB2.0 device controller, which support high speed and full speed USB peripheral.
@@ -311,14 +303,12 @@ config USB_PXA_U2O config USB_GADGET_MUSB_HDRC tristate "Inventra HDRC USB Peripheral (TI, ADI, ...)" depends on USB_MUSB_HDRC - select USB_GADGET_DUALSPEED help This OTG-capable silicon IP is used in dual designs including the TI DaVinci, OMAP 243x, OMAP 343x, TUSB 6010, and ADI Blackfin config USB_M66592 tristate "Renesas M66592 USB Peripheral Controller" - select USB_GADGET_DUALSPEED help M66592 is a discrete USB peripheral controller chip that supports both full and high speed USB 2.0 data transfers.
@@ -335,7 +325,6 @@ config USB_M66592 config USB_AMD5536UDC tristate "AMD5536 UDC" depends on PCI - select USB_GADGET_DUALSPEED help The AMD5536 UDC is part of the AMD Geode CS5536, an x86 southbridge. It is a USB Highspeed DMA capable USB device controller. Beside ep0
@@ -363,7 +352,6 @@ config USB_FSL_QE config USB_CI13XXX_PCI tristate "MIPS USB CI13xxx PCI UDC" depends on PCI - select USB_GADGET_DUALSPEED help MIPS USB IP core family device controller Currently it only supports IP part number CI13412
@@ -374,7 +362,6 @@ config USB_CI13XXX_PCI config USB_NET2272 tristate "PLX NET2272" - select USB_GADGET_DUALSPEED help PLX NET2272 is a USB peripheral controller which supports both full and high speed USB 2.0 data transfers.
@@ -398,7 +385,6 @@ config USB_NET2272_DMA config USB_NET2280 tristate "NetChip 228x" depends on PCI - select USB_GADGET_DUALSPEED help NetChip 2280 / 2282 is a PCI based USB peripheral controller which supports both full and high speed USB 2.0 data transfers.
@@ -429,7 +415,6 @@ config USB_LANGWELL tristate "Intel Langwell USB Device Controller" depends on PCI depends on !PHYS_ADDR_T_64BIT - select USB_GADGET_DUALSPEED help Intel Langwell USB Device Controller is a High-Speed USB On-The-Go device controller.
@@ -444,7 +429,6 @@ config USB_LANGWELL config USB_EG20T tristate "Intel EG20T PCH/OKI SEMICONDUCTOR ML7213 IOH UDC" depends on PCI - select USB_GADGET_DUALSPEED help This is a USB device driver for EG20T PCH. EG20T PCH is the platform controller hub that is used in Intel's
@@ -466,7 +450,6 @@ config USB_EG20T config USB_CI13XXX_MSM tristate "MIPS USB CI13xxx for MSM" depends on ARCH_MSM - select USB_GADGET_DUALSPEED select USB_MSM_OTG help MSM SoC has chipidea USB controller. This driver uses
@@ -487,8 +470,6 @@ config USB_CI13XXX_MSM config USB_DUMMY_HCD tristate "Dummy HCD (DEVELOPMENT)" depends on USB=y || (USB=m && USB_GADGET=m) - select USB_GADGET_DUALSPEED - select USB_GADGET_SUPERSPEED help This host controller driver emulates USB, looping all data transfer requests back to a USB "gadget driver" in the same host. The host
@@ -513,17 +494,6 @@ config USB_DUMMY_HCD endchoice -# Selected by UDC drivers that support high-speed operation. -config USB_GADGET_DUALSPEED - bool - depends on USB_GADGET - -# Selected by UDC drivers that support super-speed opperation -config USB_GADGET_SUPERSPEED - bool - depends on USB_GADGET - depends on USB_GADGET_DUALSPEED - # # USB Gadget Drivers #
drivers/usb/gadget/composite.c +1 -8
@@ -1559,12 +1559,6 @@ composite_resume(struct usb_gadget *gadget)/*-------------------------------------------------------------------------*/ static struct usb_gadget_driver composite_driver = { -#ifdef CONFIG_USB_GADGET_SUPERSPEED - .speed =USB_SPEED_SUPER , -#else - .speed =USB_SPEED_HIGH , -#endif - .unbind = composite_unbind, .setup = composite_setup,
@@ -1609,8 +1603,7 @@ int usb_composite_probe(struct usb_composite_driver *driver, driver->iProduct = driver->name; composite_driver.function = (char *) driver->name; composite_driver.driver.name = driver->name; - composite_driver.speed =min ((u8 )composite_driver.speed, - (u8 )driver->max_speed); + composite_driver.speed = driver->max_speed; composite = driver; composite_gadget_bind = bind;
drivers/usb/gadget/file_storage.c +0 -4
@@ -3562,11 +3562,7 @@ static void fsg_resume(struct usb_gadget *gadget)/*-------------------------------------------------------------------------*/ static struct usb_gadget_driver fsg_driver = { -#ifdef CONFIG_USB_GADGET_DUALSPEED .speed =USB_SPEED_HIGH , -#else - .speed =USB_SPEED_FULL , -#endif .function = (char *) fsg_string_product, .unbind = fsg_unbind, .disconnect = fsg_disconnect,
drivers/usb/gadget/inode.c +0 -10
@@ -837,7 +837,6 @@ ep_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)if (value ==0 ) data->state =STATE_EP_ENABLED ;break ; -#ifdef CONFIG_USB_GADGET_DUALSPEED case USB_SPEED_HIGH :/* fails if caller didn't provide that descriptor... */ ep->desc = &data->hs_desc;
@@ -845,7 +844,6 @@ ep_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)if (value ==0 ) data->state =STATE_EP_ENABLED ;break ; -#endif default :DBG (data->dev,"unconnected, %s init abandoned\n" , data->name);
@@ -1331,7 +1329,6 @@ static const struct file_operations ep0_io_operations = {* Unrecognized ep0 requests may be handled in user space. */ -#ifdef CONFIG_USB_GADGET_DUALSPEED static void make_qualifier (struct dev_data *dev) {struct usb_qualifier_descriptor qual;
@@ -1354,7 +1351,6 @@ static void make_qualifier (struct dev_data *dev)memcpy (dev->rbuf, &qual,sizeof qual); } -#endif static int config_buf (struct dev_data *dev,u8 type,unsigned index)
@@ -1434,7 +1430,6 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) dev->dev->bMaxPacketSize0 = dev->gadget->ep0->maxpacket; req->buf = dev->dev;break ; -#ifdef CONFIG_USB_GADGET_DUALSPEED case USB_DT_DEVICE_QUALIFIER :if (!dev->hs_config)break ;
@@ -1444,7 +1439,6 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)break ;case USB_DT_OTHER_SPEED_CONFIG :// FALLTHROUGH -#endif case USB_DT_CONFIG : value = config_buf (dev, w_value >> 8,
@@ -1773,11 +1767,7 @@ gadgetfs_suspend (struct usb_gadget *gadget) }static struct usb_gadget_driver gadgetfs_driver = { -#ifdef CONFIG_USB_GADGET_DUALSPEED .speed =USB_SPEED_HIGH , -#else - .speed =USB_SPEED_FULL , -#endif .function = (char *) driver_desc, .unbind = gadgetfs_unbind, .setup = gadgetfs_setup,
drivers/usb/gadget/printer.c +7 -36
109 lines not on this page · raw message
drivers/usb/gadget/u_ether.c +0 -7
@@ -92,17 +92,10 @@ struct eth_dev {#define DEFAULT_QLEN 2/* double buffering by default */ - -#ifdef CONFIG_USB_GADGET_DUALSPEED -static unsigned qmult =5 ;module_param (qmult, uint,S_IRUGO |S_IWUSR );MODULE_PARM_DESC (qmult,"queue length multiplier at high/super speed" ); -#else /* full speed (low speed doesn't do bulk) */ -#define qmult 1 -#endif -/* for dual-speed hardware, use deeper queues at high/super speed */ static inline int qlen (struct usb_gadget *gadget) {
Signature · 1 line
1.7.3.1
Quoted 34 lines · Michal Nazarewicz
From: Michal Nazarewicz <[email protected]>
This commit removes the use of
USB_GADGET_DUALSPEEDandUSB_GADGET_SUPERSPEEDKconfigoptions. Those were selected by UDC drivers which supported respective speeds.However, since kernel now allows multiple UDC drivers to be compiled, the options in question may no longer reflect the state of all gadgets.
For instance, if one driver that supports dual speed is selected and another that does not, the
USB_GADGE_DUALSPEEDwill be set "for both".This commit replaces all the #ifdefs by a run-time checks made by calling
gadget_is_dualspeed().drivers/usb/gadget/composite.c +0
-6@@ -1559,12 +1559,6 @@ composite_resume(struct usb_gadget *gadget)/*-------------------------------------------------------------------------*/ static struct usb_gadget_driver composite_driver = { -#ifdef CONFIG_USB_GADGET_SUPERSPEED - .speed =USB_SPEED_SUPER , -#else - .speed =USB_SPEED_HIGH , -#endif - .unbind = composite_unbind, .setup = composite_setup,
drivers/usb/gadget/composite.c int usb_composite_probe(struct usb_composite_driver *driver, · line 1608
Quoted 8 lines
drivers/usb/gadget/composite.c +1
-2@@ -1609,8 +1603,7 @@ int usb_composite_probe(struct usb_composite_driver *driver, driver->iProduct = driver->name; composite_driver.function = (char *) driver->name; composite_driver.driver.name = driver->name; - composite_driver.speed =min ((u8 )composite_driver.speed, - (u8 )driver->max_speed); + composite_driver.speed = driver->max_speed; composite = driver; composite_gadget_bind = bind;
I see what's going on here. Your original patch was wrong and then my correction was wrong as well.
This line has to remain the way it was (although those (u8) typecasts don't seem to be necessary). Above, you have to initialize composite_driver.speed to an appropriate value, probably USB_SPEED_SUPER.
What you didn't realize in your original patch is that usb_composite_probe() gets called more than once. Each time it is called, it has to adjust composite_driver.speed.
Alan Stern
Quoted 26 lines · Michal Nazarewicz
Quoted 25 lines
drivers/usb/gadget/composite.c +1
-8@@ -1559,12 +1559,6 @@ composite_resume(struct usb_gadget *gadget)/*-------------------------------------------------------------------------*/ static struct usb_gadget_driver composite_driver = { -#ifdef CONFIG_USB_GADGET_SUPERSPEED - .speed =USB_SPEED_SUPER , -#else - .speed =USB_SPEED_HIGH , -#endif - .unbind = composite_unbind, .setup = composite_setup,@@ -1609,8 +1603,7 @@ int usb_composite_probe(struct usb_composite_driver *driver, driver->iProduct = driver->name; composite_driver.function = (char *) driver->name; composite_driver.driver.name = driver->name; - composite_driver.speed =min ((u8 )composite_driver.speed, - (u8 )driver->max_speed); + composite_driver.speed = driver->max_speed; composite = driver; composite_gadget_bind = bind;
Quoted 11 lines · Alan Stern
I see what's going on here. Your original patch was wrong and then my correction was wrong as well.
This line has to remain the way it was (although those (u8) typecasts don't seem to be necessary). Above, you have to initialize composite_driver.speed to an appropriate value, probably
USB_SPEED_SUPER.What you didn't realize in your original patch is that
usb_composite_probe()gets called more than once. Each time it is called, it has to adjust composite_driver.speed.
That's sneaky of composite.c... But is it desired behaviour? I cannot came up with a situation where that's what we want. I would imagine that usb_composite_probe() should assume the same speed for given usb_composite_driver regardless if some other slower usb_composite_driver was loaded.
Signature · 4 lines
Best regards, _ _ .o. | Liege of Serenely Enlightened Majesty of o' \,=./ `o ..o | Computer Science, Michal "mina86" Nazarewicz (o o) ooo +-----<email/xmpp: [email protected]>-----ooO--(_)--Ooo--
Quoted 10 lines · Michal Nazarewicz
Quoted 8 lines · Alan Stern
I see what's going on here. Your original patch was wrong and then my correction was wrong as well.
This line has to remain the way it was (although those (u8) typecasts don't seem to be necessary). Above, you have to initialize composite_driver.speed to an appropriate value, probably
USB_SPEED_SUPER.
Quoted 5 lines
Quoted 3 lines
What you didn't realize in your original patch is that
usb_composite_probe()gets called more than once. Each time it is called, it has to adjust composite_driver.speed.That's sneaky of
composite.c... But is it desired behaviour?
Yes, it is.
Quoted 5 lines
I cannot
came up with a situation where that's what we want. I would imagine thatusb_composite_probe()should assume the same speed for givenusb_composite_driverregardless if some other slowerusb_composite_driverwas loaded.
The speed being calculated isn't the speed of the usb_composite_driver; it's the speed of the usb_gadget_driver. The gadget itself cannot be allowed to run faster than its internal drivers can handle.
For example, if you have a composite gadget where one of the function drivers can handle SuperSpeed and the other can't go beyond high speed, the overall gadget must never run faster than high speed.
Alan Stern
Quoted 26 lines · Alan Stern
Quoted 10 lines · Michal Nazarewicz
Quoted 8 lines · Alan Stern
I see what's going on here. Your original patch was wrong and then my correction was wrong as well.
This line has to remain the way it was (although those (u8) typecasts don't seem to be necessary). Above, you have to initialize composite_driver.speed to an appropriate value, probably
USB_SPEED_SUPER.Quoted 5 lines
Quoted 3 lines
What you didn't realize in your original patch is that
usb_composite_probe()gets called more than once. Each time it is called, it has to adjust composite_driver.speed.That's sneaky of
composite.c... But is it desired behaviour?Yes, it is.
Quoted 5 lines
I cannot
came up with a situation where that's what we want. I would imagine thatusb_composite_probe()should assume the same speed for givenusb_composite_driverregardless if some other slowerusb_composite_driverwas loaded.
Quoted 3 lines
The speed being calculated isn't the speed of the
usb_composite_driver; it's the speed of theusb_gadget_driver. The gadget itself cannot be allowed to run faster than its internal drivers can handle.
Yeah, that's why you set usb_gadget_driver's speed to the speed declared in usb_composite_driver.
For the most part, usb_composite_probe() is called only once in module's init function. As far as I know, only g_ffs calls it several times. So in all cases expect for g_ffs, composite_driver.speed = min(composite_driver.speed, driver->max_speed) should have the same effect as composite_driver.speed = driver->max_speed.
Quoted 3 lines
For example, if you have a composite gadget where one of the function drivers can handle SuperSpeed and the other can't go beyond high speed, the overall gadget must never run faster than high speed.
Shouldn't that be dealt in usb_add_function()? I cannot see any code that would do that here atm though.
Signature · 4 lines
Best regards, _ _ .o. | Liege of Serenely Enlightened Majesty of o' \,=./ `o ..o | Computer Science, Michal "mina86" Nazarewicz (o o) ooo +-----<email/xmpp: [email protected]>-----ooO--(_)--Ooo--
Quoted 7 lines · Michal Nazarewicz
For the most part,
usb_composite_probe()is called only once in module's init function. As far as I know, onlyg_ffscalls it several times. So in all cases expect forg_ffs, composite_driver.speed = min(composite_driver.speed,driver->max_speed) should have the same effect as composite_driver.speed =driver->max_speed.
Quoted 6 lines
Quoted 3 lines
For example, if you have a composite gadget where one of the function drivers can handle SuperSpeed and the other can't go beyond high speed, the overall gadget must never run faster than high speed.
Shouldn't that be dealt in
usb_add_function()? I cannot see any code that would do that here atm though.
Maybe you're right. But isn't that too late? The UDC driver has to know the gadget driver's limitations before it can connect to the host.
Alan Stern
Quoted 11 lines · Alan Stern
Quoted 9 lines · Michal Nazarewicz
For the most part,
usb_composite_probe()is called only once in module's init function. As far as I know, onlyg_ffscalls it several times. So in all cases expect forg_ffs, composite_driver.speed = min(composite_driver.speed,driver->max_speed) should have the same effect as composite_driver.speed =driver->max_speed.Quoted 2 lines
For example, if you have a composite gadget where one of the function drivers can handle SuperSpeed and the other can't go beyond high
Quoted 7 lines
Quoted 4 lines
speed,
Quoted 1 line
the overall gadget must never run faster than high speed.
Shouldn't that be dealt in
usb_add_function()? I cannot see any code that would do that here atm though.Maybe you're right. But isn't that too late? The UDC driver has to know the gadget driver's limitations before it can connect to the host.
usb_add_function() is called before usb_composite_probe() which only then calls usb_gadget_probe_driver().
What's more, if I understand it correctly, comment in usb_add_function() says that we support all the speeds usb_composite_driver structure claims we do but then return different sets of functions depending on speed. Ie. if a function is only full speed and host requests high speed, configuration will lack that function. The comment in question is:
/* We allow configurations that don't work at both speeds.
* If we run into a lowspeed Linux system, treat it the same
* as full speed ... it's the function drivers that will need
* to avoid bulk and ISO transfers. */
usb_add_function() then proceeds to set config->fullspeed, config->highspeed and config->superspeed depending on what descriptors function provides.
Those are later used in config_desc() where it iterates over all configurations checking which have functions supporting given speed:
list_for_each_entry(c, &cdev->configs, list) {
switch (speed) {
case USB_SPEED_SUPER: if (!c->superspeed) continue; break;
case USB_SPEED_HIGH: if (!c->highspeed) continue; break;
default: if (!c->fullspeed) continue;
}
if (w_value == 0)
return config_buf(c, speed, cdev->req->buf, type);
w_value--;
}config_buf() at the same time, iterates over all functions and skips the ones that do not provide descriptors for given speed:
list_for_each_entry(f, &config->functions, list) {
switch (speed) {
case USB_SPEED_SUPER: descriptors = f->ss_descriptors; break;
case USB_SPEED_HIGH: descriptors = f->hs_descriptors; break;
default: descriptors = f->descriptors;
}
if (!descriptors)
continue;
[...]
}So I think that your suggestion to use composite_driver.speed = driver->max_speed was by all means correct.
Signature · 4 lines
Best regards, _ _ .o. | Liege of Serenely Enlightened Majesty of o' \,=./ `o ..o | Computer Science, Michal "mina86" Nazarewicz (o o) ooo +-----<email/xmpp: [email protected]>-----ooO--(_)--Ooo--
Quoted 10 lines · Michal Nazarewicz
usb_add_function()is called beforeusb_composite_probe()which only then callsusb_gadget_probe_driver().What's more, if I understand it correctly, comment in
usb_add_function()says that we support all the speedsusb_composite_driverstructure claims we do but then return different sets of functions depending on speed. Ie. if a function is only full speed and host requests high speed, configuration
will lack that function. The comment in question is:
Quoted 8 lines
/* We allow configurations that don't work at both speeds.
* If we run into a lowspeed Linux system, treat it the same
* as full speed ... it's the function drivers that will need
* to avoid bulk and ISO transfers. */
usb_add_function()then proceeds to setconfig->fullspeed,config->highspeed
andconfig->superspeeddepending on what descriptors function provides.
Have you misinterpreted that comment? To me, it seems to be saying that the gadget should allow connections that are slower than the maximum supported speed. But that's not what I'm talking about -- I'm suggesting that the gadget needs to avoid running faster than the maximum supported speed.
Quoted 29 lines
Those are later used in
config_desc()where it iterates over all configurations checking which have functions supporting given speed:list_for_each_entry(c, &cdev->configs, list) { switch (speed) { case USB_SPEED_SUPER: if (!c->superspeed) continue; break; case USB_SPEED_HIGH: if (!c->highspeed) continue; break; default: if (!c->fullspeed) continue; } if (w_value == 0) return config_buf(c, speed, cdev->req->buf, type); w_value--; }
config_buf()at the same time, iterates over all functions and skips the ones
that do not provide descriptors for given speed:list_for_each_entry(f, &config->functions, list) { switch (speed) { case USB_SPEED_SUPER: descriptors = f->ss_descriptors; break; case USB_SPEED_HIGH: descriptors = f->hs_descriptors; break; default: descriptors = f->descriptors; } if (!descriptors) continue; [...] }
Quoted 2 lines
So I think that your suggestion to use composite_driver.speed =
driver->max_speedwas by all means correct.
Okay, that line was probably all right, but it seems that something else needs to be changed. In a composite gadget, if none of the function drivers support SuperSpeed then we don't want composite_driver.speed to be set to USB_SPEED_SUPER. It would be foolish to allow the UDC to connect at a speed which would make the gadget useless.
Alan Stern
Quoted 17 lines · Michal Nazarewicz
Quoted 16 lines
usb_add_function()is called beforeusb_composite_probe()which only then callsusb_gadget_probe_driver().What's more, if I understand it correctly, comment in
usb_add_function()
says that we support all the speedsusb_composite_driverstructure claims we do but then return different sets of functions depending
on speed. Ie. if a function is only full speed and host requests
high speed, configuration will lack that function. The comment in
question is:/* We allow configurations that don't work at both speeds.
* If we run into a lowspeed Linux system, treat it the same
* as full speed ... it's the function drivers that will need
* to avoid bulk and ISO transfers. */
usb_add_function()then proceeds to setconfig->fullspeed,config->highspeedandconfig->superspeeddepending on what descriptors function provides.
Quoted 1 line · Alan Stern
Have you misinterpreted that comment?
Might be. ;)
[...]
Quoted 9 lines
Quoted 2 lines
So I think that your suggestion to use composite_driver.speed =
driver->max_speedwas by all means correct.Okay, that line was probably all right, but it seems that something else needs to be changed. In a composite gadget, if none of the function drivers support SuperSpeed then we don't want composite_driver.speed to be set to
USB_SPEED_SUPER. It would be foolish to allow the UDC to connect at a speed which would make the gadget useless.
My understanding is that that's the purpose of driver->max_speed. Composite gadget's author is supposed to set it to the maximum speed he intends his gadget to run with.
This have some consequences of course: driver->max_speed may be set to super speed where no function actually supports super speed so if host chooses this speed we will return no configuration (which I don't know if it's even legal).
At the same time, author may consciously decide to set driver->max_speed to some value that not all functions support aware that depending on speed host chooses, different functions will be available.
The best composite layer can do, is try to check whether there is at least one configuration supporting the speed driver->max_speed declares and if not, decrease it or return with error.
Signature · 4 lines
Best regards, _ _ .o. | Liege of Serenely Enlightened Majesty of o' \,=./ `o ..o | Computer Science, Michal "mina86" Nazarewicz (o o) ooo +-----<email/xmpp: [email protected]>-----ooO--(_)--Ooo--
Quoted 6 lines · Alan Stern
Okay, that line was probably all right, but it seems that something else needs to be changed. In a composite gadget, if none of the function drivers support SuperSpeed then we don't want composite_driver.speed to be set to
USB_SPEED_SUPER. It would be foolish to allow the UDC to connect at a speed which would make the gadget useless.
OK, so it seems I was misunderstanding your comment all along, but that was nothing a good night sleep couldn't fix. :P
So, what you are saying is that when passed to the UDC driver (ie. by calling usb_gadget_probe_driver()) the usb_gadget_driver structure must have speed no higher then what the UDC supports, right? And in that case, it's not composite specific but affects all the gadgets.
In that case, I think that usb_gadget_probe_driver() itself needs to be changed since prior to this function we don't know which gadget the gadget driver will be bound to. Ie. something as follows could be added somewhere there:
driver->speed = min(driver->speed, udc->gadget->speed)
Does that sound like it makes sense?
At this point though, gadget drivers need to be aware that usb_gadget_probe_driver() may change the speed field. It should not be a problem since, as far as I can tell, all gadgets expect for g_ffs call usb_gadget_probe_driver() only once and in case of g_ffs this can be solved at composite level.
Signature · 4 lines
Best regards, _ _ .o. | Liege of Serenely Enlightened Majesty of o' \,=./ `o ..o | Computer Science, Michal "mina86" Nazarewicz (o o) ooo +-----<email/xmpp: [email protected]>-----ooO--(_)--Ooo--
Quoted 23 lines · Michal Nazarewicz
Quoted 6 lines · Alan Stern
Okay, that line was probably all right, but it seems that something else needs to be changed. In a composite gadget, if none of the function drivers support SuperSpeed then we don't want composite_driver.speed to be set to
USB_SPEED_SUPER. It would be foolish to allow the UDC to connect at a speed which would make the gadget useless.OK, so it seems I was misunderstanding your comment all along, but that was nothing a good night sleep couldn't fix. :P
So, what you are saying is that when passed to the UDC driver (ie. by calling
usb_gadget_probe_driver()) theusb_gadget_driverstructure must have speed no higher then what the UDC supports, right? And in that case, it's not composite specific but affects all the gadgets.In that case, I think that
usb_gadget_probe_driver()itself needs to be changed since prior to this function we don't know which gadget the gadget driver will be bound to. Ie. something as follows could be added somewhere there:
driver->speed=min(driver->speed, udc->gadget->speed)
Quoted 7 lines
Does that sound like it makes sense?
At this point though, gadget drivers need to be aware that
usb_gadget_probe_driver()may change the speed field. It should not be a problem since, as far as I can tell, all gadgets expect forg_ffscallusb_gadget_probe_driver()only once and in case ofg_ffsthis can be solved at composite level.
There are three speeds:
- the max speed the UDC supports i.e. HS (no field for that?)
- the max speed the gadget / function driver support i.e. SS (driver->max_speed ?)
- the speed the UDC is connected at the moment i.e. FS. (gadget->speed)
So in this case you have to go down and use FS descriptors. The FS speed is represented by gadget->speed right? So for now we do FS. On the next re-plug the user places OHCI controller with XHCI so you can use HS descriptors now. So changing dirver->speed wouldn't allow you go beyond FS once you to FS right?
Sebastian
Quoted 2 lines · Sebastian Andrzej Siewior
There are three speeds:
- the max speed the UDC supports i.e. HS (no field for that?)
Yep, the field seems to be missing for that one. We have is_dualspeed and comment in gadget_is_superspeed() says about is_superspeed but that does not exist.
Quoted 2 lines
- the max speed the gadget / function driver support i.e. SS (
driver->max_speed?)
Actually “max_speed” is only in usb_composite_driver structure. usb_gadget_driver has only “speed” and it's description says that it is the “highest speed the driver handles.” Because of that description I've assumed that it is UDC driver's responsibility to figure out maximum speed it can use.
Quoted 1 line
- the speed the UDC is connected at the moment i.e. FS. (
gadget->speed)
OK, I see my mistake. I misinterpreted gadget->speed as the max speed gadget supports.
So in the end, it would seem to me that we need to do the following is usb_gadget_probe_direvr() before passing the usb_gadget_driver to the usb_gadegt's bind:
if (driver->speed == USB_SPEED_SUPER && !gadget_is_superspeed(udc->gadget))
driver->speed = USB_SPEED_HIGH; if (driver->speed == USB_SPEED_HIGH && !gadget_is_dualspeed(udc->gadget)) driver->speed = USB_SPEED_FULL;
(Although I'm not sure about USB_SPEED_FULL vs. USB_SPEED_LOW.)
Either than, or make sure that all UDC drivers handle correctly gadgets that declare speed as highest of what the UDC can handle.
At the moment however, gadget_is_superspeed() is implemented using #ifdefs (which I missed before) so we need to add a is_superspeed to usb_gadget structure. Or maybe better yet get rid of is_dualspeed and add max_speed?
Does what I'm writing make sense at all?
Signature · 4 lines
Best regards, _ _ .o. | Liege of Serenely Enlightened Majesty of o' \,=./ `o ..o | Computer Science, Michal "mina86" Nazarewicz (o o) ooo +-----<email/xmpp: [email protected]>-----ooO--(_)--Ooo--
Quoted 8 lines · Michal Nazarewicz
Quoted 2 lines · Sebastian Andrzej Siewior
There are three speeds:
- the max speed the UDC supports i.e. HS (no field for that?)Yep, the field seems to be missing for that one. We have
is_dualspeedand comment ingadget_is_superspeed()says aboutis_superspeedbut that does not exist.
Evidently we need is_superspeed.
Quoted 8 lines
Quoted 2 lines
- the max speed the gadget / function driver support i.e. SS (
driver->max_speed?)Actually “max_speed” is only in
usb_composite_driverstructure.usb_gadget_driverhas only “speed” and it's description says that it is the “highest speed the driver handles.” Because of that description I've assumed that it is UDC driver's responsibility to figure out maximum speed it can use.
Correct.
Quoted 5 lines
Quoted 1 line
- the speed the UDC is connected at the moment i.e. FS. (
gadget->speed)OK, I see my mistake. I misinterpreted
gadget->speedas the max speed gadget supports.
Quoted 8 lines
So in the end, it would seem to me that we need to do the following is
usb_gadget_probe_direvr()before passing theusb_gadget_driverto the usb_gadegt's bind:if (
driver->speed==USB_SPEED_SUPER&& !gadget_is_superspeed(udc->gadget))driver->speed = USB_SPEED_HIGH; if (driver->speed == USB_SPEED_HIGH && !gadget_is_dualspeed(udc->gadget)) driver->speed = USB_SPEED_FULL;
No, the usb_gadget_driver structure is read-only to the UDC driver (except for the .driver field). .speed is the maximum speed supported by the gadget driver -- it doesn't change at runtime. If the driver was written to support speeds up to high speed, then those are the speeds it supports, regardless of the UDC's capabilities.
Maybe if would help if the .speed field in struct usb_gadget_driver was renamed to max_speed.
Quoted 4 lines
(Although I'm not sure about
USB_SPEED_FULLvs.USB_SPEED_LOW.)Either than, or make sure that all UDC drivers handle correctly gadgets that declare speed as highest of what the UDC can handle.
I don't quite understand that sentence. However, it is definitely true that all UDC drivers _must_ avoid connecting at speeds that are faster than the usb_gadget_driver's .speed field.
Quoted 3 lines
At the moment however,
gadget_is_superspeed()is implemented using #ifdefs (which I missed before) so we need to add ais_superspeedtousb_gadgetstructure. Or maybe better yet get rid ofis_dualspeedand addmax_speed?
Either one would be okay. max_speed is simpler, although it would require some work to change the existing usages of is_dualspeed.
Alan Stern
Quoted 12 lines · Michal Nazarewicz
Quoted 11 lines
OK, I see my mistake. I misinterpreted
gadget->speedas the max speed gadget supports.So in the end, it would seem to me that we need to do the following is
usb_gadget_probe_direvr()before passing theusb_gadget_driverto the usb_gadegt's bind:if (
driver->speed==USB_SPEED_SUPER&& !gadget_is_superspeed(udc->gadget))driver->speed = USB_SPEED_HIGH; if (driver->speed == USB_SPEED_HIGH && !gadget_is_dualspeed(udc->gadget)) driver->speed = USB_SPEED_FULL;
Quoted 5 lines · Alan Stern
No, the
usb_gadget_driverstructure is read-only to the UDC driver (except for the .driver field). .speed is the maximum speed supported by the gadget driver -- it doesn't change at runtime. If the driver was written to support speeds up to high speed, then those are the speeds it supports, regardless of the UDC's capabilities.
OK.
Quoted 2 lines
Maybe if would help if the .speed field in struct
usb_gadget_driverwas renamed tomax_speed.
I'll take a look at how much work that would require.
Quoted 8 lines
Quoted 4 lines
(Although I'm not sure about
USB_SPEED_FULLvs.USB_SPEED_LOW.)Either than, or make sure that all UDC drivers handle correctly gadgets that declare speed as highest of what the UDC can handle.
I don't quite understand that sentence. However, it is definitely true that all UDC drivers _must_ avoid connecting at speeds that are faster than the usb_gadget_driver's .speed field.
Yang has brought up an issue that musb_gadget_start() checks if driver->speed equals USB_SPEED_HIGH. This means that if a gadget driver supports super speed it'll set driver->speed to USB_SPEED_SUPER and musb_gadget_start() will complain.
My understanding is that this is a bug in musb driver as it should allow the gadget driver to start but never set super speed.
Quoted 6 lines
Quoted 3 lines
At the moment however,
gadget_is_superspeed()is implemented using #ifdefs (which I missed before) so we need to add ais_superspeedtousb_gadgetstructure. Or maybe better yet get rid ofis_dualspeedand addmax_speed?Either one would be okay.
max_speedis simpler, although it would require some work to change the existing usages ofis_dualspeed.
I'm on it already. ;)
Signature · 4 lines
Best regards, _ _ .o. | Liege of Serenely Enlightened Majesty of o' \,=./ `o ..o | Computer Science, Michal "mina86" Nazarewicz (o o) ooo +-----<email/xmpp: [email protected]>-----ooO--(_)--Ooo--
Quoted 11 lines · Michal Nazarewicz
Quoted 3 lines
I don't quite understand that sentence. However, it is definitely true that all UDC drivers _must_ avoid connecting at speeds that are faster than the usb_gadget_driver's .speed field.
Yang has brought up an issue that
musb_gadget_start()checks ifdriver->speed
equalsUSB_SPEED_HIGH. This means that if a gadget driver supports super speed
it'll setdriver->speedtoUSB_SPEED_SUPERandmusb_gadget_start()will complain.
Quoted 3 lines
My understanding is that this is a bug in musb driver as it should allow the
gadget driver to start but never set super speed.
That's right. It should also allow driver->speed to be USB_SPEED_FULL, in which case it should never connect at high speed (see gmidi.c).
Alan Stern
Quoted 32 lines · Michal Nazarewicz
Quoted 29 lines · Alan Stern
Quoted 11 lines · Michal Nazarewicz
Quoted 8 lines · Alan Stern
I see what's going on here. Your original patch was wrong and then my correction was wrong as well.
This line has to remain the way it was (although those (u8) typecasts don't seem to be necessary). Above, you have to initialize composite_driver.speed to an appropriate value, probably
USB_SPEED_SUPER.Quoted 5 lines
Quoted 3 lines
What you didn't realize in your original patch is that
usb_composite_probe()gets called more than once. Each time it is called, it has to adjust composite_driver.speed.That's sneaky of
composite.c... But is it desired behaviour?Yes, it is.
Quoted 7 lines
I cannot
came up with a situation where that's what we want. I would imagine thatusb_composite_probe()should assume the same speed for givenusb_composite_driverregardless if some other slowerusb_composite_driver
was loaded.
Quoted 6 lines
Quoted 3 lines
The speed being calculated isn't the speed of the
usb_composite_driver; it's the speed of theusb_gadget_driver. The gadget itself cannot be allowed to run faster than its internal drivers can handle.Yeah, that's why you set usb_gadget_driver's speed to the speed declared in
usb_composite_driver.
This is what I means in before reply, musb_gadget_start will check the speed set here. if it != USB_SPEED_HIGH it will return -EINVAL.
Quoted 7 lines
For the most part,
usb_composite_probe()is called only once in module's init function. As far as I know, onlyg_ffscalls it several times. So in all cases expect forg_ffs, composite_driver.speed = min(composite_driver.speed,driver->max_speed) should have the same effect as composite_driver.speed =driver->max_speed.
For original code, ifndef CONFIG_USB_GADGET_SUPERSPEED and max_speed = USB_SPEED_SUPER then the result will be:
composite_driver.speed = min(USB_SPEED_HIGH, USB_SPEED_SUPER)
For patched code, composite_driver.speed = USB_SPEED_SUPER
Quoted 8 lines
Quoted 4 lines
For example, if you have a composite gadget where one of the function drivers can handle SuperSpeed and the other can't go beyond high speed, the overall gadget must never run faster than high speed.
Shouldn't that be dealt in
usb_add_function()? I cannot see any code that would do that here atm though.
Signature · 2 lines
Thanks Yang Ruirui
Quoted 7 lines · Michal Nazarewicz
Quoted 6 lines
For the most part,
usb_composite_probe()is called only once in module's init function. As far as I know, onlyg_ffscalls it several times. So in all cases expect forg_ffs, composite_driver.speed = min(composite_driver.speed,driver->max_speed) should have the same effect as composite_driver.speed =driver->max_speed.
Quoted 5 lines · Yang Rui Rui
For original code, ifndef
CONFIG_USB_GADGET_SUPERSPEEDandmax_speed=USB_SPEED_SUPERthen the result will be:composite_driver.speed =
min(USB_SPEED_HIGH, USB_SPEED_SUPER)For patched code, composite_driver.speed =
USB_SPEED_SUPER
OK, I see your point. This is the issue that we are discussing in another “branch” of the thread. It seems either usb_gadget_driver_probe() should make sure driver->speed is not too high or each UDC need to handle gadgets which support speed higher then the UDC can handle.
Signature · 4 lines
Best regards, _ _ .o. | Liege of Serenely Enlightened Majesty of o' \,=./ `o ..o | Computer Science, Michal "mina86" Nazarewicz (o o) ooo +-----<email/xmpp: [email protected]>-----ooO--(_)--Ooo--
Quoted 10 lines · Michal Nazarewicz
From: Michal Nazarewicz<[email protected]>
This commit removes the use of
USB_GADGET_DUALSPEEDandUSB_GADGET_SUPERSPEEDKconfigoptions. Those were selected by UDC drivers which supported respective speeds.However, since kernel now allows multiple UDC drivers to be compiled, the options in question may no longer reflect the state of all gadgets.
Quoted 6 lines
For instance, if one driver that supports dual speed is selected and another that does not, the
USB_GADGE_DUALSPEEDwill be set "for both".This commit replaces all the #ifdefs by a run-time checks made by calling
gadget_is_dualspeed().
I did not see the include/linux/usb/gadget.h changes, did you have another patch? There's CONFIG_USB_GADGET_DUALSPEED ifdefs in gadget_is_dualspeed function of the gadget.h If so, I will get oops as before.
Quoted 200 lines
--- drivers/usb/gadget/Kconfig | 30 ------------------------- drivers/usb/gadget/composite.c | 9 +------- drivers/usb/gadget/file_storage.c | 4 --- drivers/usb/gadget/inode.c | 10 -------- drivers/usb/gadget/printer.c | 43 ++++++------------------------------- drivers/usb/gadget/u_ether.c | 7 ------ 6 files changed, 8 insertions(+), 95 deletions(-)Like before, this has been only compile-tested (make allmodconfig bzImage modules on
x86_64).Compared to v1:
* Removed unrelated whitespace changes
* Removed the use ofmin()inusb_composite_probe()drivers/usb/gadget/Kconfig +0
-30@@ -133,7 +133,6 @@ config USB_AT91 config USB_ATMEL_USBA tristate "Atmel USBA" - select USB_GADGET_DUALSPEED depends on AVR32 || ARCH_AT91CAP9 || ARCH_AT91SAM9RL || ARCH_AT91SAM9G45 help USBA is the integrated high-speed USB Device controller on@@ -142,7 +141,6 @@ config USB_ATMEL_USBA config USB_FSL_USB2 tristate "Freescale Highspeed USB DR Peripheral Controller" depends on FSL_SOC || ARCH_MXC - select USB_GADGET_DUALSPEED select USB_FSL_MPH_DR_OF if OF help Some of Freescale PowerPC processors have a High Speed@@ -158,7 +156,6 @@ config USB_FSL_USB2 config USB_FUSB300 tristate "Faraday FUSB300 USB Peripheral Controller" depends on !PHYS_ADDR_T_64BIT - select USB_GADGET_DUALSPEED help Faraday usb device controller FUSB300 driver@@ -206,7 +203,6 @@ config USB_PXA25X_SMALL config USB_R8A66597 tristate "Renesas R8A66597 USB Peripheral Controller" - select USB_GADGET_DUALSPEED help R8A66597 is a discrete USB host and peripheral controller chip that supports both full and high speed USB 2.0 data transfers.@@ -220,7 +216,6 @@ config USB_RENESAS_USBHS_UDC tristate 'Renesas USBHS controller' depends on SUPERH || ARCH_SHMOBILE depends on USB_RENESAS_USBHS - select USB_GADGET_DUALSPEED help Renesas USBHS is a discrete USB host and peripheral controller chip that supports both full and high speed USB 2.0 data transfers.@@ -249,7 +244,6 @@ config USB_S3C_HSOTG tristate "S3C HS/OtG USB Device controller" depends on S3C_DEV_USB_HSOTG select USB_GADGET_S3C_HSOTG_PIO - select USB_GADGET_DUALSPEED help The Samsung S3C64XX USB2.0 high-speed gadget controller integrated into the S3C64XX series SoC.@@ -287,7 +281,6 @@ config USB_S3C2410_DEBUG config USB_S3C_HSUDC tristate "S3C2416, S3C2443 and S3C2450 USB Device Controller" depends on ARCH_S3C2410 - select USB_GADGET_DUALSPEED help Samsung's S3C2416, S3C2443 and S3C2450 is an ARM9 based SoC integrated with dual speed USB 2.0 device controller. It has@@ -298,7 +291,6 @@ config USB_S3C_HSUDC config USB_PXA_U2O tristate "PXA9xx Processor USB2.0 controller" depends on ARCH_MMP - select USB_GADGET_DUALSPEED help PXA9xx Processor series include a high speed USB2.0 device controller, which support high speed and full speed USB peripheral.@@ -311,14 +303,12 @@ config USB_PXA_U2O config USB_GADGET_MUSB_HDRC tristate "Inventra HDRC USB Peripheral (TI, ADI, ...)" depends on USB_MUSB_HDRC - select USB_GADGET_DUALSPEED help This OTG-capable silicon IP is used in dual designs including the TI DaVinci, OMAP 243x, OMAP 343x, TUSB 6010, and ADI Blackfin config USB_M66592 tristate "Renesas M66592 USB Peripheral Controller" - select USB_GADGET_DUALSPEED help M66592 is a discrete USB peripheral controller chip that supports both full and high speed USB 2.0 data transfers.@@ -335,7 +325,6 @@ config USB_M66592 config USB_AMD5536UDC tristate "AMD5536 UDC" depends on PCI - select USB_GADGET_DUALSPEED help The AMD5536 UDC is part of the AMD Geode CS5536, an x86 southbridge. It is a USB Highspeed DMA capable USB device controller. Beside ep0@@ -363,7 +352,6 @@ config USB_FSL_QE config USB_CI13XXX_PCI tristate "MIPS USB CI13xxx PCI UDC" depends on PCI - select USB_GADGET_DUALSPEED help MIPS USB IP core family device controller Currently it only supports IP part number CI13412@@ -374,7 +362,6 @@ config USB_CI13XXX_PCI config USB_NET2272 tristate "PLX NET2272" - select USB_GADGET_DUALSPEED help PLX NET2272 is a USB peripheral controller which supports both full and high speed USB 2.0 data transfers.@@ -398,7 +385,6 @@ config USB_NET2272_DMA config USB_NET2280 tristate "NetChip 228x" depends on PCI - select USB_GADGET_DUALSPEED help NetChip 2280 / 2282 is a PCI based USB peripheral controller which supports both full and high speed USB 2.0 data transfers.@@ -429,7 +415,6 @@ config USB_LANGWELL tristate "Intel Langwell USB Device Controller" depends on PCI depends on !PHYS_ADDR_T_64BIT - select USB_GADGET_DUALSPEED help Intel Langwell USB Device Controller is a High-Speed USB On-The-Go device controller.@@ -444,7 +429,6 @@ config USB_LANGWELL config USB_EG20T tristate "Intel EG20T PCH/OKI SEMICONDUCTOR ML7213 IOH UDC" depends on PCI - select USB_GADGET_DUALSPEED help This is a USB device driver for EG20T PCH. EG20T PCH is the platform controller hub that is used in Intel's@@ -466,7 +450,6 @@ config USB_EG20T config USB_CI13XXX_MSM tristate "MIPS USB CI13xxx for MSM" depends on ARCH_MSM - select USB_GADGET_DUALSPEED select USB_MSM_OTG help MSM SoC has chipidea USB controller. This driver uses@@ -487,8 +470,6 @@ config USB_CI13XXX_MSM config USB_DUMMY_HCD tristate "Dummy HCD (DEVELOPMENT)" depends on USB=y || (USB=m&& USB_GADGET=m) - select USB_GADGET_DUALSPEED - select USB_GADGET_SUPERSPEED help This host controller driver emulates USB, looping all data transfer requests back to a USB "gadget driver" in the same host. The host@@ -513,17 +494,6 @@ config USB_DUMMY_HCD endchoice -# Selected by UDC drivers that support high-speed operation. -config USB_GADGET_DUALSPEED - bool - depends on USB_GADGET - -# Selected by UDC drivers that support super-speed opperation -config USB_GADGET_SUPERSPEED - bool - depends on USB_GADGET - depends on USB_GADGET_DUALSPEED - # # USB Gadget Drivers #drivers/usb/gadget/composite.c +0
-6@@ -1559,12 +1559,6 @@ composite_resume(struct usb_gadget *gadget)/*-------------------------------------------------------------------------*/ static struct usb_gadget_driver composite_driver = { -#ifdef CONFIG_USB_GADGET_SUPERSPEED - .speed =USB_SPEED_SUPER , -#else - .speed =USB_SPEED_HIGH , -#endif - .unbind = composite_unbind, .setup = composite_setup,
drivers/usb/gadget/composite.c int usb_composite_probe(struct usb_composite_driver *driver, · line 1606
Quoted 6 lines
drivers/usb/gadget/composite.c +1
-2@@ -1609,8 +1603,7 @@ int usb_composite_probe(struct usb_composite_driver *driver, driver->iProduct = driver->name; composite_driver.function = (char *) driver->name; composite_driver.driver.name = driver->name; - composite_driver.speed =min ((u8 )composite_driver.speed, - (u8 )driver->max_speed); + composite_driver.speed = driver->max_speed;
This does not works, many drivers will check the driver->speed, ie in musg_gadget.c
static int musb_gadget_start(struct usb_gadget *g,
struct usb_gadget_driver *driver)
{
struct musb *musb = gadget_to_musb(g);
unsigned long flags;
int retval = -EINVAL;
if (driver->speed != USB_SPEED_HIGH)
goto err0;[snip]
Quoted 230 lines
composite = driver; composite_gadget_bind = bind;drivers/usb/gadget/file_storage.c +0
-4@@ -3562,11 +3562,7 @@ static void fsg_resume(struct usb_gadget *gadget)/*-------------------------------------------------------------------------*/ static struct usb_gadget_driver fsg_driver = { -#ifdef CONFIG_USB_GADGET_DUALSPEED .speed =USB_SPEED_HIGH , -#else - .speed =USB_SPEED_FULL , -#endif .function = (char *) fsg_string_product, .unbind = fsg_unbind, .disconnect = fsg_disconnect,drivers/usb/gadget/inode.c +0
-10@@ -837,7 +837,6 @@ ep_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)if (value ==0 ) data->state =STATE_EP_ENABLED ;break ; -#ifdef CONFIG_USB_GADGET_DUALSPEED case USB_SPEED_HIGH :/* fails if caller didn't provide that descriptor... */ ep->desc =&data->hs_desc;@@ -845,7 +844,6 @@ ep_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)if (value ==0 ) data->state =STATE_EP_ENABLED ;break ; -#endif default :DBG (data->dev,"unconnected, %s init abandoned\n" , data->name);@@ -1331,7 +1329,6 @@ static const struct file_operations ep0_io_operations = {* Unrecognized ep0 requests may be handled in user space. */ -#ifdef CONFIG_USB_GADGET_DUALSPEED static void make_qualifier (struct dev_data *dev) {struct usb_qualifier_descriptor qual;@@ -1354,7 +1351,6 @@ static void make_qualifier (struct dev_data *dev)memcpy (dev->rbuf,&qual,sizeof qual); } -#endif static int config_buf (struct dev_data *dev,u8 type,unsigned index)@@ -1434,7 +1430,6 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) dev->dev->bMaxPacketSize0 = dev->gadget->ep0->maxpacket; req->buf = dev->dev;break ; -#ifdef CONFIG_USB_GADGET_DUALSPEED case USB_DT_DEVICE_QUALIFIER :if (!dev->hs_config)break ;@@ -1444,7 +1439,6 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)break ;case USB_DT_OTHER_SPEED_CONFIG :// FALLTHROUGH -#endif case USB_DT_CONFIG : value = config_buf (dev, w_value>> 8,@@ -1773,11 +1767,7 @@ gadgetfs_suspend (struct usb_gadget *gadget) }static struct usb_gadget_driver gadgetfs_driver = { -#ifdef CONFIG_USB_GADGET_DUALSPEED .speed =USB_SPEED_HIGH , -#else - .speed =USB_SPEED_FULL , -#endif .function = (char *) driver_desc, .unbind = gadgetfs_unbind, .setup = gadgetfs_setup,drivers/usb/gadget/printer.c +7
-36@@ -164,12 +164,6 @@ module_param(qlen, uint, S_IRUGO|S_IWUSR);#define QLEN qlen -#ifdef CONFIG_USB_GADGET_DUALSPEED -#define DEVSPEED USB_SPEED_HIGH -#else /* full speed (low speed doesn't do bulk) */ -#define DEVSPEED USB_SPEED_FULL -#endif -/*-------------------------------------------------------------------------*/ #define xprintk(d, level, fmt, args...) \@@ -288,8 +282,6 @@ static const struct usb_descriptor_header *fs_printer_function [11] = { NULL }; -#ifdef CONFIG_USB_GADGET_DUALSPEED -/* * usb 2.0 devices need to expose both high speed and full speed * descriptors, unless they only run at full speed. @@ -328,13 +320,6 @@ static const struct usb_descriptor_header *hs_printer_function [11] = {/* maxpacket and other transfer characteristics vary by speed. */ #define ep_desc (g, hs, fs) (((g)->speed == USB_SPEED_HIGH)?(hs):(fs)) -#else - -/* if there's no high speed support, maxpacket doesn't change. */ -#define ep_desc (g, hs, fs) (((void)(g)), (fs)) - -#endif /* !CONFIG_USB_GADGET_DUALSPEED */ -/*-------------------------------------------------------------------------*/ /* descriptors that are built on-demand */ @@ -979,9 +964,7 @@ printer_set_config(struct printer_dev *dev, unsigned number)switch (gadget->speed) {case USB_SPEED_FULL : speed ="full" ;break ; -#ifdef CONFIG_USB_GADGET_DUALSPEED case USB_SPEED_HIGH : speed ="high" ;break ; -#endif default : speed ="?" ;break ; }@@ -998,23 +981,15 @@ config_buf(enum usb_device_speed speed, u8 *buf, u8 type, unsigned index, {int len;const struct usb_descriptor_header **function; -#ifdef CONFIG_USB_GADGET_DUALSPEED int hs = (speed ==USB_SPEED_HIGH ); +if (index>= device_desc.bNumConfigurations) +return -EINVAL ; +if (type ==USB_DT_OTHER_SPEED_CONFIG ) hs = !hs; -if (hs) { - function = hs_printer_function; - }else { - function = fs_printer_function; - } -#else - function = fs_printer_function; -#endif - -if (index>= device_desc.bNumConfigurations) -return -EINVAL ; + function = hs ? hs_printer_function : fs_printer_function;/* for now, don't advertise srp-only devices */ if (!is_otg)@@ -1156,9 +1131,8 @@ printer_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) value =min (wLength, (u16 )sizeof device_desc);memcpy (req->buf,&device_desc, value);break ; -#ifdef CONFIG_USB_GADGET_DUALSPEED case USB_DT_DEVICE_QUALIFIER : -if (!gadget->is_dualspeed) +if (!gadget_is_dualspeed (gadget))break ;/* * assumes ep0 uses the same value for both @@ -1172,10 +1146,9 @@ printer_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)break ;case USB_DT_OTHER_SPEED_CONFIG : -if (!gadget->is_dualspeed) +if (!gadget_is_dualspeed (gadget))break ;/* FALLTHROUGH */ -#endif /* CONFIG_USB_GADGET_DUALSPEED */ case USB_DT_CONFIG : value = config_buf(gadget->speed, req->buf, wValue>> 8,@@ -1460,11 +1433,9 @@ autoconf_fail: goto autoconf_fail; out_ep->driver_data = out_ep;/* claim */ -#ifdef CONFIG_USB_GADGET_DUALSPEED /* assumes that all endpoints are dual-speed */ hs_ep_in_desc.bEndpointAddress = fs_ep_in_desc.bEndpointAddress; hs_ep_out_desc.bEndpointAddress = fs_ep_out_desc.bEndpointAddress; -#endif /* DUALSPEED */ usb_gadget_set_selfpowered (gadget);@@ -1552,7 +1523,7 @@ fail:/*-------------------------------------------------------------------------*/ static struct usb_gadget_driver printer_driver = { - .speed =DEVSPEED , + .speed =USB_SPEED_HIGH , .function = (char *) driver_desc, .unbind = printer_unbind,drivers/usb/gadget/u_ether.c +0
-8@@ -92,17 +92,10 @@ struct eth_dev {#define DEFAULT_QLEN 2/* double buffering by default */ - -#ifdef CONFIG_USB_GADGET_DUALSPEED -static unsigned qmult =5 ;module_param (qmult, uint,S_IRUGO |S_IWUSR );MODULE_PARM_DESC (qmult,"queue length multiplier at high/super speed" ); -#else /* full speed (low speed doesn't do bulk) */ -#define qmult 1 -#endif -/* for dual-speed hardware, use deeper queues at high/super speed */ static inline int qlen (struct usb_gadget *gadget) { --1.7.3.1
Signature · 2 lines
Thanks Yang Ruirui
Quoted 3 lines · Yang Rui Rui
I did not see the
include/linux/usb/gadget.hchanges, did you have another patch? There'sCONFIG_USB_GADGET_DUALSPEEDifdefs ingadget_is_dualspeedfunction of thegadget.hIf so, I will get oops as before.
Thanks, fixed. I did “git add -u” while I was in drivers/usb/gadget so gadget.h did not get added and I've overlooked it. Sorry about that.
Quoted 15 lines · Michal Nazarewicz
Quoted 14 lines
drivers/usb/gadget/composite.c +0
-6@@ -1559,12 +1559,6 @@ composite_resume(struct usb_gadget *gadget)/*-------------------------------------------------------------------------*/ static struct usb_gadget_driver composite_driver = { -#ifdef CONFIG_USB_GADGET_SUPERSPEED - .speed =USB_SPEED_SUPER , -#else - .speed =USB_SPEED_HIGH , -#endif - .unbind = composite_unbind,
Quoted 11 lines
drivers/usb/gadget/composite.c int usb_composite_probe(struct · line 1607
Quoted 9 lines
drivers/usb/gadget/composite.c +1
-2.setup = composite_setup,@@ -1609,8 +1603,7 @@ int usb_composite_probe(struct usb_composite_driver *driver, driver->iProduct = driver->name; composite_driver.function = (char *) driver->name; composite_driver.driver.name = driver->name; - composite_driver.speed =min ((u8 )composite_driver.speed, - (u8 )driver->max_speed); + composite_driver.speed = driver->max_speed;This does not works, many drivers will check the
driver->speed, ie inmusg_gadget.c
Uh? Not sure what you mean here. Note that driver above is not the same structure as driver below. composite_driver is what musb_gadget_start() will get.
Quoted 13 lines
static int musb_gadget_start(struct
usb_gadget*g,
structusb_gadget_driver*driver){ struct musb *musb = gadget_to_musb(g); unsigned long flags; int retval = -EINVAL; if (driver->speed != USB_SPEED_HIGH) goto err0;[snip]
Quoted 2 lines
composite = driver; composite_gadget_bind = bind;
Signature · 4 lines
Best regards, _ _ .o. | Liege of Serenely Enlightened Majesty of o' \,=./ `o ..o | Computer Science, Michal "mina86" Nazarewicz (o o) ooo +-----<email/xmpp: [email protected]>-----ooO--(_)--Ooo--
Quoted 42 lines · Michal Nazarewicz
Quoted 6 lines · Yang Rui Rui
I did not see the
include/linux/usb/gadget.hchanges, did you have another patch?
There's CONFIG_USB_GADGET_DUALSPEED ifdefs ingadget_is_dualspeedfunction of thegadget.h
If so, I will get oops as before.Thanks, fixed. I did “git add -u” while I was in
drivers/usb/gadgetsogadget.hdid not get added and I've overlooked it. Sorry about that.Quoted 17 lines · Michal Nazarewicz
Quoted 16 lines
drivers/usb/gadget/composite.c +0
-6@@ -1559,12 +1559,6 @@ composite_resume(struct usb_gadget *gadget) /*-------------------------------------------------------------------------*/ static struct usb_gadget_driver composite_driver = { -#ifdef CONFIG_USB_GADGET_SUPERSPEED - .speed = USB_SPEED_SUPER, -#else - .speed = USB_SPEED_HIGH, -#endif - .unbind = composite_unbind,Quoted 12 lines
drivers/usb/gadget/composite.c int usb_composite_probe(struct usb_composite_driver · line 1607
Quoted 9 lines
.setup =
composite_setup,drivers/usb/gadget/composite.c +1
-2@@ -1609,8 +1603,7 @@ int usb_composite_probe(struct usb_composite_driver *driver, driver->iProduct = driver->name; composite_driver.function = (char *) driver->name; composite_driver.driver.name = driver->name; - composite_driver.speed = min((u8)composite_driver.speed, - (u8)driver->max_speed); + composite_driver.speed = driver->max_speed;This does not works, many drivers will check the
driver->speed, ie inmusg_gadget.c
Quoted 3 lines
Uh? Not sure what you mean here. Note that driver above is not the same structure as driver below. composite_driver is what
musb_gadget_start()will get.
For example I got -EINVAL in musb_gadget_start in case composite_driver.speed = USB_SPEED_SUPER
the driver param is the composite_driver in composite.c, isn't it?
Quoted 26 lines
Quoted 8 lines
static int
musb_gadget_start(struct usb_gadget *g, struct usb_gadget_driver *driver){
struct musb *musb =gadget_to_musb(g); unsigned long flags;
int retval =-EINVAL;Quoted 6 lines
if (
driver->speed!=USB_SPEED_HIGH)
goto err0;
[snip]Quoted 2 lines
drivers/usb/gadget/composite.c +0
-0composite = driver; composite_gadget_bind = bind;--
Best regards, _ _ .o. | Liege of Serenely Enlightened Majesty of o' \,=./ `o ..o | Computer Science, Michal "mina86" Nazarewicz (o o) ooo +-----<email/xmpp: [email protected]>-----ooO--(_)--Ooo-- --
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Signature · 2 lines
Regards Yang RuiRui
Quoted 35 lines
Quoted 30 lines
Quoted 26 lines · Michal Nazarewicz
Quoted 25 lines
drivers/usb/gadget/composite.c +0
-6@@ -1559,12 +1559,6 @@ composite_resume(struct usb_gadget *gadget)/*-------------------------------------------------------------------------*/ static struct usb_gadget_driver composite_driver = { -#ifdef CONFIG_USB_GADGET_SUPERSPEED - .speed =USB_SPEED_SUPER , -#else - .speed =USB_SPEED_HIGH , -#endif - .unbind = composite_unbind,.setup =
composite_setup,drivers/usb/gadget/composite.c +0
-0@@ -1609,8 +1603,7 @@ int usb_composite_probe(struct
usb_composite_driver
*driver,driver->iProduct = driver->name; composite_driver.function = (char *) driver->name; composite_driver.driver.name = driver->name;drivers/usb/gadget/composite.c +1
-2- composite_driver.speed =min ((u8 )composite_driver.speed, - (u8 )driver->max_speed); + composite_driver.speed = driver->max_speed;Quoted 2 lines · Yang Rui Rui
This does not works, many drivers will check the
driver->speed, ie inmusg_gadget.cQuoted 3 lines · Michal Nazarewicz
Uh? Not sure what you mean here. Note that driver above is not the same structure as driver below.
composite_driveris whatmusb_gadget_start()will get.
Quoted 2 lines · Dave Young
For example I got
-EINVALinmusb_gadget_startin case composite_driver.speed =USB_SPEED_SUPER
For anything other then g_ether and g_zero, the speed should be set to USB_SPEED_HIGH. Unless this is somehow related to what Alan said about this code.
Quoted 1 line
the driver param is the
composite_driverincomposite.c, isn't it?
Yes.
Quoted 13 lines
Quoted 13 lines
Quoted 13 lines
static int musb_gadget_start(struct
usb_gadget*g,
structusb_gadget_driver*driver){ struct musb *musb = gadget_to_musb(g); unsigned long flags; int retval = -EINVAL; if (driver->speed != USB_SPEED_HIGH) goto err0;[snip]
Quoted 2 lines
composite = driver; composite_gadget_bind = bind;
Signature · 4 lines
Best regards, _ _ .o. | Liege of Serenely Enlightened Majesty of o' \,=./ `o ..o | Computer Science, Michal "mina86" Nazarewicz (o o) ooo +-----<email/xmpp: [email protected]>-----ooO--(_)--Ooo--
v3 cover Figuring out speed refactorisation
In reply to Michal NazarewiczFrom: Michal Nazarewicz <[email protected]>
Michal Nazarewicz (4):
usb: Provide usb_device_speed_name() function
Just a little helper.
usb: gadget: replace "is_dualspeed" with "max_speed"
This replaces "is_dualspeed" with "max_speed" so that one can encode in the field whether given UDC is super speed as well.
Without this change, we would have to add a "is_superspeed" field since after removal of USB_GADGET_SUPERSPEED Kconfig option current implementation of gadget_is_superspeed() won't work.
usb: gadget: rename usb_gadget_driver::speed to max_speed
I don't have strong feelings about this patch, but the current name of the usb_gadget_driver::speed field may lead to some confusion.
Changing it to "max_speed" should be apparent that it describes the maximum speed the gadget driver supports.
This comes in pair with usb_gadget::max_speed and usb_composite_driver::max_speed.
usb: gadget: get rid of USB_GADGET_{DUAL,SUPER}SPEED
Removes the USB_GADGET_DUALSPEED and USB_GADGET_SUPERSPEED Kconfig options. In most cases, they were checked just for optimisation (ie. if UDC was not dual speed, gadget drivers could skip some of the logic) so in the end this change was just about deleting #ifdefs.
Making those changes has exposed problems with some UDC drivers, namely:
$ g grep -A3 'max_speed.*[=!]=.*USB_SPEED_HIGH' drivers/usb/gadget/amd5536udc.c: || driver->max_speed != USB_SPEED_HIGH) drivers/usb/gadget/amd5536udc.c- return -EINVAL; drivers/usb/gadget/amd5536udc.c- if (!dev) drivers/usb/gadget/amd5536udc.c- return -ENODEV; -- drivers/usb/gadget/m66592-udc.c: || driver->max_speed != USB_SPEED_HIGH drivers/usb/gadget/m66592-udc.c- || !bind drivers/usb/gadget/m66592-udc.c- || !driver->setup) drivers/usb/gadget/m66592-udc.c- return -EINVAL; -- drivers/usb/gadget/net2272.c: driver->max_speed != USB_SPEED_HIGH) drivers/usb/gadget/net2272.c- return -EINVAL; drivers/usb/gadget/net2272.c- if (!dev) drivers/usb/gadget/net2272.c- return -ENODEV; -- drivers/usb/gadget/net2280.c: || driver->max_speed != USB_SPEED_HIGH drivers/usb/gadget/net2280.c- || !bind || !driver->setup) drivers/usb/gadget/net2280.c- return -EINVAL; drivers/usb/gadget/net2280.c- if (!dev) -- drivers/usb/gadget/r8a66597-udc.c: || driver->max_speed != USB_SPEED_HIGH drivers/usb/gadget/r8a66597-udc.c- || !bind drivers/usb/gadget/r8a66597-udc.c- || !driver->setup) drivers/usb/gadget/r8a66597-udc.c- return -EINVAL;
All those drivers require usb_gadget_driver::max_speed to be set to USB_SPEED_HIGH. This basically means that gmidi (which sets it to USB_SPEED_FULL), g_ether and g_zero (which set it to USB_SPEED_SUPER) won't work with those UDCs:
$ g grep -e '\.max_speed.*=.*USB_SPEED_SUPER' -e '\.max_speed.*=.*USB_SPEED_FULL' dummy_hcd.c: dum->gadget.max_speed = USB_SPEED_SUPER;; ether.c: .max_speed = USB_SPEED_SUPER, gmidi.c: .max_speed = USB_SPEED_FULL, goku_udc.c: dev->gadget.max_speed = USB_SPEED_FULL; omap_udc.c: udc->gadget.max_speed = USB_SPEED_FULL; zero.c: .max_speed = USB_SPEED_SUPER,
So as far as I can tell, UDC drivers for those need to be fixed (but that's probably scope for another patchset). Or am I missing something?
Like before, this has been compile-tested only.
drivers/usb/Makefile | 3 ++ drivers/usb/common.c | 24 +++++++++++++++++ drivers/usb/gadget/Kconfig | 30 ---------------------- drivers/usb/gadget/amd5536udc.c | 4 +- drivers/usb/gadget/atmel_usba_udc.c | 2 +- drivers/usb/gadget/ci13xxx_udc.c | 9 ++++-- drivers/usb/gadget/composite.c | 9 +------ drivers/usb/gadget/dbgp.c | 2 +- drivers/usb/gadget/dummy_hcd.c | 15 +++++------ drivers/usb/gadget/epautoconf.c | 6 ++-- drivers/usb/gadget/file_storage.c | 6 +--- drivers/usb/gadget/fsl_udc_core.c | 2 +- drivers/usb/gadget/fusb300_udc.c | 2 +- drivers/usb/gadget/gmidi.c | 2 +- drivers/usb/gadget/goku_udc.c | 3 +- drivers/usb/gadget/inode.c | 14 +--------- drivers/usb/gadget/langwell_udc.c | 2 +- drivers/usb/gadget/m66592-udc.c | 4 +- drivers/usb/gadget/mv_udc_core.c | 2 +- drivers/usb/gadget/net2272.c | 4 +- drivers/usb/gadget/net2280.c | 4 +- drivers/usb/gadget/omap_udc.c | 1 + drivers/usb/gadget/pch_udc.c | 4 +- drivers/usb/gadget/printer.c | 43 +++++-------------------------- drivers/usb/gadget/r8a66597-udc.c | 4 +- drivers/usb/gadget/s3c-hsotg.c | 2 +- drivers/usb/gadget/s3c-hsudc.c | 2 +- drivers/usb/gadget/u_ether.c | 7 ----- drivers/usb/gadget/udc-core.c | 41 +++++++++++++++--------------- drivers/usb/musb/musb_gadget.c | 2 +- drivers/usb/renesas_usbhs/mod_gadget.c | 2 +- include/linux/usb/ch9.h | 8 ++++++ include/linux/usb/gadget.h | 29 +++++---------------- 33 files changed, 115 insertions(+), 179 deletions(-) create mode 100644 drivers/usb/common.c
Signature · 1 line
1.7.3.1
PATCH v3 1/4 usb: Provide usb_device_speed_name() function
From: Michal Nazarewicz <[email protected]>
In a few places kernel wants to print a human-readable USB device speed name (eg. "high") instead of a raw number (eg. 3). Usually a switch is introduced in those places leading to code repetition. To mitigate this issue, this commit introduces usb_device_speed_name() function, which returns a human-readable name of provided speed.
--- drivers/usb/Makefile | 3 +++ drivers/usb/common.c | 24 ++++++++++++++++++++++++ drivers/usb/gadget/udc-core.c | 19 ++----------------- include/linux/usb/ch9.h | 8 ++++++++ 4 files changed, 37 insertions(+), 17 deletions(-) create mode 100644 drivers/usb/common.c
drivers/usb/Makefile +3 -0
@@ -51,3 +51,6 @@ obj-$(CONFIG_USB_MUSB_HDRC) += musb/ obj-$(CONFIG_USB_RENESAS_USBHS) += renesas_usbhs/ obj-$(CONFIG_USB_OTG_UTILS) += otg/ obj-$(CONFIG_USB_GADGET) += gadget/ + +obj-$(CONFIG_USB) += common.o +obj-$(CONFIG_USB_GADGET) += common.o
drivers/usb/common.c new file +24 -0
@@ -0,0 +1,24 @@ +/* +* Provides code common for host and device side USB. +*/ + +#include <linux/kernel.h> /* for ARRAY_SIZE() */ +#include <linux/module.h> /* for EXPORT_SYMBOL_GPL() */ +#include <linux/usb/ch9.h> + +const char *usb_device_speed_name (enum usb_device_speed speed) +{ +static const char *const names[] = { +"UNKNOWN" , +"low-speed" , +"full-speed" , +"high-speed" , +"wireless" , +"super-speed" , + }; + +if (speed <0 || speed >=ARRAY_SIZE (names)) + speed =USB_SPEED_UNKNOWN ; +return names[speed]; +} +EXPORT_SYMBOL_GPL (usb_device_speed_name);
drivers/usb/gadget/udc-core.c +2 -17
@@ -375,23 +375,8 @@ static ssize_t usb_udc_speed_show(struct device *dev, struct device_attribute *attr, char *buf) { struct usb_udc *udc = container_of(dev, struct usb_udc, dev); -struct usb_gadget *gadget = udc->gadget; - -switch (gadget->speed) { -case USB_SPEED_LOW : -return snprintf (buf,PAGE_SIZE ,"low-speed\n" ); -case USB_SPEED_FULL : -return snprintf (buf,PAGE_SIZE ,"full-speed\n" ); -case USB_SPEED_HIGH : -return snprintf (buf,PAGE_SIZE ,"high-speed\n" ); -case USB_SPEED_WIRELESS : -return snprintf (buf,PAGE_SIZE ,"wireless\n" ); -case USB_SPEED_SUPER : -return snprintf (buf,PAGE_SIZE ,"super-speed\n" ); -case USB_SPEED_UNKNOWN :/* FALLTHROUGH */ -default : -return snprintf (buf,PAGE_SIZE ,"UNKNOWN\n" ); - } +return snprintf (buf,PAGE_SIZE ,"%s\n" , +usb_device_speed_name (udc->gadget->speed)); } static DEVICE_ATTR(speed, S_IRUSR, usb_udc_speed_show, NULL);
include/linux/usb/ch9.h +8 -0
@@ -851,6 +851,14 @@ enum usb_device_speed { USB_SPEED_SUPER, /* usb 3.0 */ }; +/** +* usb_device_speed_name() - Returns human readable-name of the speed. +* @speed: The speed to return human-readable name for. If it's not +* any of the speeds defined in usb_device_speed enum, string for +* USB_SPEED_UNKNOWN will be returned. +*/ +extern const char *usb_device_speed_name (enum usb_device_speed speed); +enum usb_device_state {/* NOTATTACHED isn't in the USB spec, and this state acts * the same as ATTACHED ... but it's clearer this way.
Signature · 1 line
1.7.3.1
Re: [PATCHv3 1/4] usb: Provide usb_device_speed_name() function
Hi,
Quoted 35 lines · Michal Nazarewicz
From: Michal Nazarewicz <[email protected]>
In a few places kernel wants to print a human-readable USB device speed name (eg. "high") instead of a raw number (eg. 3). Usually a switch is introduced in those places leading to code repetition. To mitigate this issue, this commit introduces
usb_device_speed_name()function, which returns a human-readable name of provided speed.Signed-off-by Michal Nazarewicz <[email protected]>--- drivers/usb/Makefile | 3 +++ drivers/usb/common.c | 24 ++++++++++++++++++++++++ drivers/usb/gadget/udc-core.c | 19 ++----------------- include/linux/usb/ch9.h | 8 ++++++++ 4 files changed, 37 insertions(+), 17 deletions(-) create mode 100644 drivers/usb/common.cdrivers/usb/Makefile +3
-0@@ -51,3 +51,6 @@ obj-$(CONFIG_USB_MUSB_HDRC) += musb/ obj-$(CONFIG_USB_RENESAS_USBHS) += renesas_usbhs/ obj-$(CONFIG_USB_OTG_UTILS) += otg/ obj-$(CONFIG_USB_GADGET) += gadget/ + +obj-$(CONFIG_USB) += common.o +obj-$(CONFIG_USB_GADGET) += common.odrivers/usb/common.c new file +0
-0
drivers/usb/common.c line 9
Quoted 9 lines
drivers/usb/common.c new file +9
-0@@ -0,0 +1,24 @@ +/* +* Provides code common for host and device side USB. +*/ + +#include <linux/kernel.h> /* for ARRAY_SIZE() */ +#include <linux/module.h> /* for EXPORT_SYMBOL_GPL() */ +#include <linux/usb/ch9.h> + +const char *usb_device_speed_name (enum usb_device_speed speed)
somehow usb_speed_string() sounds better to me.
drivers/usb/common.c line 21
Quoted 12 lines
drivers/usb/common.c new file +12
-0+{ +static const char *const names[] = { +"UNKNOWN" , +"low-speed" , +"full-speed" , +"high-speed" , +"wireless" , +"super-speed" , + }; + +if (speed <0 || speed >=ARRAY_SIZE (names)) + speed =USB_SPEED_UNKNOWN ;
I generally dislike depending on a particular ordering of enumerations. While's it's highly unlikely that anyone will change that, if someone does change, then it'll take a long time to actually find the bug on the print here :-)
I woud rather use a switch in this case.
Quoted 19 lines
drivers/usb/gadget/udc-core.c +0
-11@@ -375,23 +375,8 @@ static ssize_t usb_udc_speed_show(struct device *dev, struct device_attribute *attr, char *buf) { struct usb_udc *udc = container_of(dev, struct usb_udc, dev); -struct usb_gadget *gadget = udc->gadget; - -switch (gadget->speed) { -case USB_SPEED_LOW : -return snprintf (buf,PAGE_SIZE ,"low-speed\n" ); -case USB_SPEED_FULL : -return snprintf (buf,PAGE_SIZE ,"full-speed\n" ); -case USB_SPEED_HIGH : -return snprintf (buf,PAGE_SIZE ,"high-speed\n" ); -case USB_SPEED_WIRELESS : -return snprintf (buf,PAGE_SIZE ,"wireless\n" );
drivers/usb/gadget/udc-core.c static ssize_t usb_udc_speed_show(struct device *dev, · line 381
Quoted 10 lines
drivers/usb/gadget/udc-core.c +2
-6-case USB_SPEED_SUPER : -return snprintf (buf,PAGE_SIZE ,"super-speed\n" ); -case USB_SPEED_UNKNOWN :/* FALLTHROUGH */ -default : -return snprintf (buf,PAGE_SIZE ,"UNKNOWN\n" ); - } +return snprintf (buf,PAGE_SIZE ,"%s\n" , +usb_device_speed_name (udc->gadget->speed)); } static DEVICE_ATTR(speed, S_IRUSR, usb_udc_speed_show, NULL);
you said 'several locations', but there's only one ? No other driver is using something similar ?
Signature · 1 line
balbi
Re: [PATCHv3 1/4] usb: Provide usb_device_speed_name() function
Quoted 39 lines · Felipe Balbi
Quoted 38 lines · Michal Nazarewicz
From: Michal Nazarewicz <[email protected]>
In a few places kernel wants to print a human-readable USB device speed name (eg. "high") instead of a raw number (eg. 3). Usually a switch is introduced in those places leading to code repetition. To mitigate this issue, this commit introduces
usb_device_speed_name()function, which returns a human-readable name of provided speed.Signed-off-by Michal Nazarewicz <[email protected]>--- drivers/usb/Makefile | 3 +++ drivers/usb/common.c | 24 ++++++++++++++++++++++++ drivers/usb/gadget/udc-core.c | 19 ++----------------- include/linux/usb/ch9.h | 8 ++++++++ 4 files changed, 37 insertions(+), 17 deletions(-) create mode 100644 drivers/usb/common.cdrivers/usb/Makefile +3
-0@@ -51,3 +51,6 @@ obj-$(CONFIG_USB_MUSB_HDRC) += musb/ obj-$(CONFIG_USB_RENESAS_USBHS) += renesas_usbhs/ obj-$(CONFIG_USB_OTG_UTILS) += otg/ obj-$(CONFIG_USB_GADGET) += gadget/ + +obj-$(CONFIG_USB) += common.o +obj-$(CONFIG_USB_GADGET) += common.odrivers/usb/common.c new file +3
-0@@ -0,0 +1,24 @@ +/* +* Provides code common for host and device side USB. +*/
Quoted 8 lines
drivers/usb/common.c line 9
Quoted 6 lines
drivers/usb/common.c new file +6
-0+ +#include <linux/kernel.h> /* for ARRAY_SIZE() */ +#include <linux/module.h> /* for EXPORT_SYMBOL_GPL() */ +#include <linux/usb/ch9.h> + +const char *usb_device_speed_name (enum usb_device_speed speed)somehow
usb_speed_string()sounds better to me.
Done.
Quoted 18 lines
drivers/usb/common.c line 21
Quoted 12 lines
drivers/usb/common.c new file +12
-0+{ +static const char *const names[] = { +"UNKNOWN" , +"low-speed" , +"full-speed" , +"high-speed" , +"wireless" , +"super-speed" , + }; + +if (speed <0 || speed >=ARRAY_SIZE (names)) + speed =USB_SPEED_UNKNOWN ;I generally dislike depending on a particular ordering of enumerations. While's it's highly unlikely that anyone will change that, if someone does change, then it'll take a long time to actually find the bug on the print here :-)
Quoted 1 line
I woud rather use a switch in this case.
Would a C99 initialisation be fine by you?
I, myself, have this aversion to switch as being slower (which is disputable) and too verbose.
Quoted 25 lines
Quoted 25 lines
drivers/usb/gadget/udc-core.c +0
-16@@ -375,23 +375,8 @@ static ssize_t usb_udc_speed_show(struct device *dev, struct device_attribute *attr, char *buf) { struct usb_udc *udc = container_of(dev, struct usb_udc, dev); -struct usb_gadget *gadget = udc->gadget; - -switch (gadget->speed) { -case USB_SPEED_LOW : -return snprintf (buf,PAGE_SIZE ,"low-speed\n" ); -case USB_SPEED_FULL : -return snprintf (buf,PAGE_SIZE ,"full-speed\n" ); -case USB_SPEED_HIGH : -return snprintf (buf,PAGE_SIZE ,"high-speed\n" ); -case USB_SPEED_WIRELESS : -return snprintf (buf,PAGE_SIZE ,"wireless\n" ); -case USB_SPEED_SUPER : -return snprintf (buf,PAGE_SIZE ,"super-speed\n" ); -case USB_SPEED_UNKNOWN :/* FALLTHROUGH */ -default : -return snprintf (buf,PAGE_SIZE ,"UNKNOWN\n" );
Quoted 8 lines
drivers/usb/gadget/udc-core.c static ssize_t usb_udc_speed_show(struct device *dev, · line 381
Quoted 5 lines
drivers/usb/gadget/udc-core.c +2
-1- } +return snprintf (buf,PAGE_SIZE ,"%s\n" , +usb_device_speed_name (udc->gadget->speed)); } static DEVICE_ATTR(speed, S_IRUSR, usb_udc_speed_show, NULL);you said 'several locations', but there's only one ? No other driver is using something similar ?
OK, you caught me on being lazy... ;) Hunted down a few more instances.
Signature · 4 lines
Best regards, _ _ .o. | Liege of Serenely Enlightened Majesty of o' \,=./ `o ..o | Computer Science, Michal "mina86" Nazarewicz (o o) ooo +-----<email/xmpp: [email protected]>-----ooO--(_)--Ooo--
PATCH v3 2/4 usb: gadget: replace "is_dualspeed" with "max_speed"
In reply to Michal NazarewiczFrom: Michal Nazarewicz <[email protected]>
This commit replaces usb_gadget's is_dualspeed field with a max_speed field.
This change is made so that one will be able to check at run-time if given gadget supports super speed.
--- drivers/usb/gadget/amd5536udc.c | 2 +- drivers/usb/gadget/atmel_usba_udc.c | 2 +- drivers/usb/gadget/ci13xxx_udc.c | 7 +++++-- drivers/usb/gadget/dummy_hcd.c | 2 +- drivers/usb/gadget/epautoconf.c | 6 +++--- drivers/usb/gadget/fsl_udc_core.c | 2 +- drivers/usb/gadget/fusb300_udc.c | 2 +- drivers/usb/gadget/goku_udc.c | 1 + drivers/usb/gadget/langwell_udc.c | 2 +- drivers/usb/gadget/m66592-udc.c | 2 +- drivers/usb/gadget/mv_udc_core.c | 2 +- drivers/usb/gadget/net2272.c | 2 +- drivers/usb/gadget/net2280.c | 2 +- drivers/usb/gadget/omap_udc.c | 1 + drivers/usb/gadget/pch_udc.c | 2 +- drivers/usb/gadget/printer.c | 4 ++-- drivers/usb/gadget/r8a66597-udc.c | 2 +- drivers/usb/gadget/s3c-hsotg.c | 2 +- drivers/usb/gadget/s3c-hsudc.c | 2 +- drivers/usb/gadget/udc-core.c | 26 ++++++++++++++++++++------ drivers/usb/musb/musb_gadget.c | 2 +- drivers/usb/renesas_usbhs/mod_gadget.c | 2 +- include/linux/usb/gadget.h | 10 +++++----- 23 files changed, 53 insertions(+), 34 deletions(-)
drivers/usb/gadget/amd5536udc.c +1 -1
@@ -3363,7 +3363,7 @@ static int udc_probe(struct udc *dev)dev_set_name (&dev->gadget.dev,"gadget" ); dev->gadget.dev.release = gadget_release; dev->gadget.name = name; - dev->gadget.is_dualspeed =1 ; + dev->gadget.max_speed =USB_SPEED_HIGH ;/* init registers, interrupts, ... */ startup_registers (dev);
drivers/usb/gadget/atmel_usba_udc.c +1 -1
@@ -1038,7 +1038,7 @@ static struct usba_udc the_udc = { .gadget = { .ops = &usba_udc_ops, .ep_list = LIST_HEAD_INIT(the_udc.gadget.ep_list), - .is_dualspeed = 1, + .max_speed = USB_SPEED_HIGH, .name = "atmel_usba_udc", .dev = { .init_name = "gadget",
drivers/usb/gadget/ci13xxx_udc.c +5 -2
@@ -751,8 +751,11 @@ static ssize_t show_device(struct device *dev, struct device_attribute *attr, n +=scnprintf (buf + n,PAGE_SIZE - n,"speed = %d\n" , gadget->speed); + n +=scnprintf (buf + n,PAGE_SIZE - n,"max_speed = %d\n" , + gadget->max_speed); +/* Provide "is_dualspeed" for backward compatibility. */ n +=scnprintf (buf + n,PAGE_SIZE - n,"is_dualspeed = %d\n" , - gadget->is_dualspeed); +gadget_is_dualspeed (gadget)); n +=scnprintf (buf + n,PAGE_SIZE - n,"is_otg = %d\n" , gadget->is_otg); n += scnprintf(buf + n, PAGE_SIZE - n, "is_a_peripheral = %d\n",
@@ -2866,7 +2869,7 @@ static int udc_probe(struct ci13xxx_udc_driver *driver, struct device *dev, udc->gadget.ops = &usb_gadget_ops; udc->gadget.speed =USB_SPEED_UNKNOWN ; - udc->gadget.is_dualspeed =1 ; + udc->gadget.max_speed =USB_SPEED_HIGH ; udc->gadget.is_otg =0 ; udc->gadget.name = driver->name;
drivers/usb/gadget/dummy_hcd.c +1 -1
@@ -986,7 +986,7 @@ static int dummy_udc_probe (struct platform_device *pdev) dum->gadget.name = gadget_name; dum->gadget.ops = &dummy_ops; - dum->gadget.is_dualspeed =1 ; + dum->gadget.max_speed =USB_SPEED_SUPER ;;dev_set_name (&dum->gadget.dev,"gadget" ); dum->gadget.dev.parent = &pdev->dev;
drivers/usb/gadget/epautoconf.c +3 -3
@@ -162,7 +162,7 @@ ep_matches (switch (type) {case USB_ENDPOINT_XFER_INT :/* INT: limit 64 bytes full speed, 1024 high/super speed */ -if (!gadget->is_dualspeed && max >64 ) +if (!gadget_is_dualspeed (gadget) && max >64 )return 0 ;/* FALLTHROUGH */
@@ -170,12 +170,12 @@ ep_matches (/* ISO: limit 1023 bytes full speed, 1024 high/super speed */ if (ep->maxpacket < max)return 0 ; -if (!gadget->is_dualspeed && max >1023 ) +if (!gadget_is_dualspeed (gadget) && max >1023 )return 0 ;/* BOTH: "high bandwidth" works only at high speed */ if ((desc->wMaxPacketSize &cpu_to_le16 (3 <<11 ))) { -if (!gadget->is_dualspeed) +if (!gadget_is_dualspeed (gadget))return 0 ;/* configure your hardware with enough buffering!! */ }
drivers/usb/gadget/fsl_udc_core.c +1 -1
@@ -2546,7 +2546,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev)/* Setup gadget structure */ udc_controller->gadget.ops = &fsl_gadget_ops; - udc_controller->gadget.is_dualspeed =1 ; + udc_controller->gadget.max_speed =USB_SPEED_HIGH ; udc_controller->gadget.ep0 = &udc_controller->eps[0 ].ep;INIT_LIST_HEAD (&udc_controller->gadget.ep_list); udc_controller->gadget.speed =USB_SPEED_UNKNOWN ;
drivers/usb/gadget/fusb300_udc.c +1 -1
@@ -1473,7 +1473,7 @@ static int __init fusb300_probe(struct platform_device *pdev)dev_set_name (&fusb300->gadget.dev,"gadget" ); - fusb300->gadget.is_dualspeed =1 ; + fusb300->gadget.max_speed =USB_SPEED_HIGH ; fusb300->gadget.dev.parent = &pdev->dev; fusb300->gadget.dev.dma_mask = pdev->dev.dma_mask; fusb300->gadget.dev.release = pdev->dev.release;
drivers/usb/gadget/goku_udc.c +1 -0
@@ -1796,6 +1796,7 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id)spin_lock_init (&dev->lock); dev->pdev = pdev; dev->gadget.ops = &goku_ops; + dev->gadget.max_speed =USB_SPEED_FULL ;/* the "gadget" abstracts/virtualizes the controller */ dev_set_name (&dev->gadget.dev,"gadget" );
drivers/usb/gadget/langwell_udc.c +1 -1
@@ -3320,7 +3320,7 @@ static int langwell_udc_probe(struct pci_dev *pdev, dev->gadget.ep0 = &dev->ep[0 ].ep;/* gadget ep0 */ INIT_LIST_HEAD (&dev->gadget.ep_list);/* ep_list */ dev->gadget.speed =USB_SPEED_UNKNOWN ;/* speed */ - dev->gadget.is_dualspeed =1 ;/* support dual speed */ + dev->gadget.max_speed =USB_SPEED_HIGH ;/* support dual speed */ #ifdef OTG_TRANSCEIVER dev->gadget.is_otg =1 ;/* support otg mode */ #endif
drivers/usb/gadget/m66592-udc.c +1 -1
@@ -1663,7 +1663,7 @@ static int __init m66592_probe(struct platform_device *pdev) m66592->gadget.ops = &m66592_gadget_ops;device_initialize (&m66592->gadget.dev);dev_set_name (&m66592->gadget.dev,"gadget" ); - m66592->gadget.is_dualspeed =1 ; + m66592->gadget.max_speed =USB_SPEED_HIGH ; m66592->gadget.dev.parent = &pdev->dev; m66592->gadget.dev.dma_mask = pdev->dev.dma_mask; m66592->gadget.dev.release = pdev->dev.release;
drivers/usb/gadget/mv_udc_core.c +1 -1
@@ -2061,7 +2061,7 @@ int mv_udc_probe(struct platform_device *dev) udc->gadget.ep0 = &udc->eps[0 ].ep;/* gadget ep0 */ INIT_LIST_HEAD (&udc->gadget.ep_list);/* ep_list */ udc->gadget.speed =USB_SPEED_UNKNOWN ;/* speed */ - udc->gadget.is_dualspeed =1 ;/* support dual speed */ + udc->gadget.max_speed =USB_SPEED_HIGH ;/* support dual speed */ /* the "gadget" abstracts/virtualizes the controller */ dev_set_name (&udc->gadget.dev,"gadget" );
drivers/usb/gadget/net2272.c +1 -1
@@ -2265,7 +2265,7 @@ net2272_probe_init(struct device *dev, unsigned int irq) ret->irq = irq; ret->dev = dev; ret->gadget.ops = &net2272_ops; - ret->gadget.is_dualspeed =1 ; + ret->gadget.max_speed =USB_SPEED_HIGH ;/* the "gadget" abstracts/virtualizes the controller */ dev_set_name (&ret->gadget.dev,"gadget" );
drivers/usb/gadget/net2280.c +1 -1
@@ -2743,7 +2743,7 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id)spin_lock_init (&dev->lock); dev->pdev = pdev; dev->gadget.ops = &net2280_ops; - dev->gadget.is_dualspeed =1 ; + dev->gadget.max_speed =USB_SPEED_HIGH ;/* the "gadget" abstracts/virtualizes the controller */ dev_set_name (&dev->gadget.dev,"gadget" );
drivers/usb/gadget/omap_udc.c +1 -0
@@ -2686,6 +2686,7 @@ omap_udc_setup(struct platform_device *odev, struct otg_transceiver *xceiv)INIT_LIST_HEAD (&udc->gadget.ep_list);INIT_LIST_HEAD (&udc->iso); udc->gadget.speed =USB_SPEED_UNKNOWN ; + udc->gadget.max_speed =USB_SPEED_FULL ; udc->gadget.name = driver_name;device_initialize (&udc->gadget.dev);
drivers/usb/gadget/pch_udc.c +1 -1
@@ -2949,7 +2949,7 @@ static int pch_udc_probe(struct pci_dev *pdev, dev->gadget.dev.dma_mask = pdev->dev.dma_mask; dev->gadget.dev.release = gadget_release; dev->gadget.name =KBUILD_MODNAME ; - dev->gadget.is_dualspeed =1 ; + dev->gadget.max_speed =USB_SPEED_HIGH ; retval =device_register (&dev->gadget.dev);if (retval)
drivers/usb/gadget/printer.c +2 -2
@@ -1158,7 +1158,7 @@ printer_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)break ;#ifdef CONFIG_USB_GADGET_DUALSPEED case USB_DT_DEVICE_QUALIFIER : -if (!gadget->is_dualspeed) +if (!gadget_is_dualspeed (gadget))break ;/* * assumes ep0 uses the same value for both
@@ -1172,7 +1172,7 @@ printer_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)break ;case USB_DT_OTHER_SPEED_CONFIG : -if (!gadget->is_dualspeed) +if (!gadget_is_dualspeed (gadget))break ;/* FALLTHROUGH */ #endif /* CONFIG_USB_GADGET_DUALSPEED */
drivers/usb/gadget/r8a66597-udc.c +1 -1
@@ -1616,7 +1616,7 @@ static int __init r8a66597_probe(struct platform_device *pdev) r8a66597->gadget.ops = &r8a66597_gadget_ops;device_initialize (&r8a66597->gadget.dev);dev_set_name (&r8a66597->gadget.dev,"gadget" ); - r8a66597->gadget.is_dualspeed =1 ; + r8a66597->gadget.max_speed =USB_SPEED_HIGH ; r8a66597->gadget.dev.parent = &pdev->dev; r8a66597->gadget.dev.dma_mask = pdev->dev.dma_mask; r8a66597->gadget.dev.release = pdev->dev.release;
drivers/usb/gadget/s3c-hsotg.c +1 -1
@@ -3368,7 +3368,7 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev)dev_set_name (&hsotg->gadget.dev,"gadget" ); - hsotg->gadget.is_dualspeed =1 ; + hsotg->gadget.max_speed =USB_SPEED_HIGH ; hsotg->gadget.ops = &s3c_hsotg_gadget_ops; hsotg->gadget.name =dev_name (dev);
drivers/usb/gadget/s3c-hsudc.c +1 -1
@@ -1287,7 +1287,7 @@ static int s3c_hsudc_probe(struct platform_device *pdev)device_initialize (&hsudc->gadget.dev);dev_set_name (&hsudc->gadget.dev,"gadget" ); - hsudc->gadget.is_dualspeed =1 ; + hsudc->gadget.max_speed =USB_SPEED_HIGH ; hsudc->gadget.ops = &s3c_hsudc_gadget_ops; hsudc->gadget.name =dev_name (dev); hsudc->gadget.dev.parent = dev;
drivers/usb/gadget/udc-core.c +20 -6
@@ -371,14 +371,28 @@ static ssize_t usb_udc_softconn_store(struct device *dev, } static DEVICE_ATTR(soft_connect, S_IWUSR, NULL, usb_udc_softconn_store); -static ssize_t usb_udc_speed_show (struct device *dev, +#define USB_UDC_SPEED_ATTR (name) \ +ssize_t usb_udc_##name##_show(struct device *dev, \ + struct device_attribute *attr, char *buf) \ +{ \ + struct usb_udc *udc = container_of(dev, struct usb_udc, dev); \ + return snprintf(buf, PAGE_SIZE, "%s\n", \ + usb_device_speed_name(udc->gadget->name)); \ +} \ +static DEVICE_ATTR(name, S_IRUSR, usb_udc_##name##_show, NULL) + +static USB_UDC_SPEED_ATTR (speed); +static USB_UDC_SPEED_ATTR (max_speed); + +/* Provide "is_dualspeed" for backward compatibility. */ +static ssize_t usb_udc_is_dualspeed_show (struct device *dev,struct device_attribute *attr,char *buf) { - struct usb_udc *udc = container_of(dev, struct usb_udc, dev); -return snprintf (buf,PAGE_SIZE ,"%s\n" , -usb_device_speed_name (udc->gadget->speed)); + struct usb_udc *udc = container_of(dev, struct usb_udc, dev); +return snprintf (buf,PAGE_SIZE ,"%d\n" , +gadget_is_dualspeed (udc->gadget)); } -static DEVICE_ATTR(speed, S_IRUSR, usb_udc_speed_show, NULL); +static DEVICE_ATTR(is_dualspeed, S_IRUSR, usb_udc_is_dualspeed_show, NULL);#define USB_UDC_ATTR (name) \ ssize_t usb_udc_##name##_show(struct device *dev, \
@@ -391,7 +405,6 @@ ssize_t usb_udc_##name##_show(struct device *dev, \ } \ static DEVICE_ATTR(name, S_IRUSR, usb_udc_##name##_show, NULL) -static USB_UDC_ATTR (is_dualspeed);static USB_UDC_ATTR (is_otg);static USB_UDC_ATTR (is_a_peripheral);static USB_UDC_ATTR (b_hnp_enable);
@@ -402,6 +415,7 @@ static struct attribute *usb_udc_attrs[] = { &dev_attr_srp.attr, &dev_attr_soft_connect.attr, &dev_attr_speed.attr, + &dev_attr_max_speed.attr, &dev_attr_is_dualspeed.attr, &dev_attr_is_otg.attr,
drivers/usb/musb/musb_gadget.c +1 -1
@@ -1827,7 +1827,7 @@ int __init musb_gadget_setup(struct musb *musb)*/ musb->g.ops = &musb_gadget_operations; - musb->g.is_dualspeed =1 ; + musb->g.max_speed =USB_SPEED_HIGH ; musb->g.speed =USB_SPEED_UNKNOWN ;/* this "gadget" abstracts/virtualizes the controller */
drivers/usb/renesas_usbhs/mod_gadget.c +1 -1
@@ -917,7 +917,7 @@ int __devinit usbhs_mod_gadget_probe(struct usbhs_priv *priv) gpriv->gadget.dev.parent = dev; gpriv->gadget.name ="renesas_usbhs_udc" ; gpriv->gadget.ops = &usbhsg_gadget_ops; - gpriv->gadget.is_dualspeed =1 ; + gpriv->gadget.max_speed =USB_SPEED_HIGH ;INIT_LIST_HEAD (&gpriv->gadget.ep_list);
include/linux/usb/gadget.h +5 -5
@@ -477,8 +477,8 @@ struct usb_gadget_ops {* driver setup() requests * @ep_list: List of other endpoints supported by the device. * @speed: Speed of current connection to USB host. -* @is_dualspeed: True if the controller supports both high and full speed -* operation. If it does, the gadget driver must also support both. +* @max_speed: Maximal speed the UDC can handle. UDC must support this +* and all slower speeds. * @is_otg: True if the USB device port uses a Mini-AB jack, so that the * gadget driver must provide a USB OTG descriptor. * @is_a_peripheral: False unless is_otg, the "A" end of a USB cable
@@ -518,7 +518,7 @@ struct usb_gadget {struct usb_ep *ep0;struct list_head ep_list;/* of usb_ep */ enum usb_device_speed speed; - unsigned is_dualspeed:1; +enum usb_device_speed max_speed; unsigned is_otg:1; unsigned is_a_peripheral:1; unsigned b_hnp_enable:1;
@@ -549,7 +549,7 @@ static inline struct usb_gadget *dev_to_usb_gadget(struct device *dev)static inline int gadget_is_dualspeed (struct usb_gadget *g) {#ifdef CONFIG_USB_GADGET_DUALSPEED -/* runtime test would check "g->is_dualspeed" ... that might be +/* runtime test would check "g->max_speed" ... that might be * useful to work around hardware bugs, but is mostly pointless */ return 1 ;
@@ -567,7 +567,7 @@ static inline int gadget_is_superspeed(struct usb_gadget *g) {#ifdef CONFIG_USB_GADGET_SUPERSPEED /* -* runtime test would check "g->is_superspeed" ... that might be +* runtime test would check "g->max_speed" ... that might be * useful to work around hardware bugs, but is mostly pointless */ return 1 ;
Signature · 1 line
1.7.3.1
Re: [PATCHv3 2/4] usb: gadget: replace "is_dualspeed" with "max_speed"
Hi,
Quoted 7 lines · Michal Nazarewicz
From: Michal Nazarewicz <[email protected]>
This commit replaces usb_gadget's
is_dualspeedfield with amax_speedfield.This change is made so that one will be able to check at run-time if given gadget supports super speed.
IMHO the logic is inverted here. It should start from the function drivers. They should say which USB speeds they support, that would go up to composite layer and composite would call e.g. usb_gadget_set_speed(gadget, maximum_speed);
that function will set gadget->maximum_speed and call into the UDC driver which would write maximum_speed into its internal registers, thus preventing the core from working at speeds unsupported by the gadget driver.
All of this should happen before we even connect to the host, so first all UDCs should have their conversion to udc-core finished and start using udc_start()/udc_stop(). The driver I just sent [1] illustrates what udc_start()/udc_stop() should do.
[1] http://marc.info/?l=linux-usb&m=131376669022473&w=2
<snip>
Quoted 10 lines
drivers/usb/gadget/udc-core.c +1
-1@@ -371,14 +371,28 @@ static ssize_t usb_udc_softconn_store(struct device *dev, } static DEVICE_ATTR(soft_connect, S_IWUSR, NULL, usb_udc_softconn_store); -static ssize_t usb_udc_speed_show(struct device *dev, +#define USB_UDC_SPEED_ATTR (name) \
drivers/usb/gadget/udc-core.c static ssize_t usb_udc_softconn_store(struct device *dev, · line 384
Quoted 10 lines
drivers/usb/gadget/udc-core.c +10
-0+ssize_t usb_udc_##name##_show(struct device *dev, \ + struct device_attribute *attr, char *buf) \ +{ \ + struct usb_udc *udc = container_of(dev, struct usb_udc, dev); \ + return snprintf(buf, PAGE_SIZE, "%s\n", \ + usb_device_speed_name(udc->gadget->name)); \ +} \ +static DEVICE_ATTR(name, S_IRUSR, usb_udc_##name##_show, NULL) + +static USB_UDC_SPEED_ATTR (speed);
how about "current_speed" ?
drivers/usb/gadget/udc-core.c static ssize_t usb_udc_softconn_store(struct device *dev, · line 385
Quoted 1 line
drivers/usb/gadget/udc-core.c +1
-0+static USB_UDC_SPEED_ATTR (max_speed);
in this case, humans will be reading sysfs, so maximum_speed will look nicer, IMHO.
drivers/usb/gadget/udc-core.c static ssize_t usb_udc_softconn_store(struct device *dev, · line 395
Quoted 13 lines
drivers/usb/gadget/udc-core.c +6
-4+/* Provide "is_dualspeed" for backward compatibility. */ +static ssize_t usb_udc_is_dualspeed_show (struct device *dev,struct device_attribute *attr,char *buf) { - struct usb_udc *udc = container_of(dev, struct usb_udc, dev); -return snprintf (buf,PAGE_SIZE ,"%s\n" , -usb_device_speed_name (udc->gadget->speed)); + struct usb_udc *udc = container_of(dev, struct usb_udc, dev); +return snprintf (buf,PAGE_SIZE ,"%d\n" , +gadget_is_dualspeed (udc->gadget)); } -static DEVICE_ATTR(speed, S_IRUSR, usb_udc_speed_show, NULL); +static DEVICE_ATTR(is_dualspeed, S_IRUSR, usb_udc_is_dualspeed_show, NULL);
maybe deprecate this one on feature-removal-schedule ??
Signature · 1 line
balbi
Re: [PATCHv3 2/4] usb: gadget: replace "is_dualspeed" with "max_speed"
Hi,
Sorry, I somehow missed this mail before.
Quoted 6 lines · Michal Nazarewicz
Quoted 5 lines
This commit replaces usb_gadget's
is_dualspeedfield with amax_speedfield.This change is made so that one will be able to check at run-time if given gadget supports super speed.
Quoted 4 lines · Felipe Balbi
IMHO the logic is inverted here. It should start from the function drivers. They should say which USB speeds they support, that would go up to composite layer and composite would call e.g.
usb_gadget_set_speed(gadget, maximum_speed);
This is actually not how composite works at the moment. Currently, a composite gadget can declare a maximum speed of say “high” even if all the functions do not support that speed. Of course when host asks about descriptors for given speed, only functions that support that speed will be returned (and hence only configurations that have at least one function supporting that speed).
Whether the behaviour should be changed is, in my opinion, issue separate from the patchset that I'm sending.
Quoted 10 lines
Quoted 10 lines
drivers/usb/gadget/udc-core.c +0
-0@@ -371,14 +371,28 @@ static ssize_t usb_udc_softconn_store(structdevice *dev, } static DEVICE_ATTR(soft_connect, S_IWUSR, NULL,usb_udc_softconn_store );
Quoted 14 lines
drivers/usb/gadget/udc-core.c static ssize_t usb_udc_softconn_store(struct device *dev, · line 384
Quoted 12 lines
drivers/usb/gadget/udc-core.c +11
-1-static ssize_t usb_udc_speed_show(struct device *dev, +#define USB_UDC_SPEED_ATTR (name) \ +ssize_t usb_udc_##name##_show(struct device *dev, \ + struct device_attribute *attr, char *buf) \ +{ \ + struct usb_udc *udc = container_of(dev, struct usb_udc, dev); \ + return snprintf(buf, PAGE_SIZE, "%s\n", \ + usb_device_speed_name(udc->gadget->name)); \ +} \ +static DEVICE_ATTR(name, S_IRUSR, usb_udc_##name##_show, NULL) + +static USB_UDC_SPEED_ATTR (speed);how about "
current_speed" ?
Is there a big advantage? That would change external interface and I don't see reason to do so. Of course, udc class is quite recent so if you feel we can ignore this issue I can go forward with that change.
Quoted 4 lines
drivers/usb/gadget/udc-core.c static ssize_t usb_udc_softconn_store(struct device *dev, · line 385
Quoted 1 line
drivers/usb/gadget/udc-core.c +1
-0+static USB_UDC_SPEED_ATTR (max_speed);in this case, humans will be reading sysfs, so
maximum_speedwill look nicer, IMHO.
I don't care much. Will change.
Quoted 8 lines
Quoted 8 lines
drivers/usb/gadget/udc-core.c +3
-3+/* Provide "is_dualspeed" for backward compatibility. */ +static ssize_t usb_udc_is_dualspeed_show (struct device *dev,struct device_attribute *attr,char *buf) { - struct usb_udc *udc = container_of(dev, struct usb_udc, dev); -return snprintf (buf,PAGE_SIZE ,"%s\n" , -usb_device_speed_name (udc->gadget->speed)); + struct usb_udc *udc = container_of(dev, struct usb_udc, dev);
Quoted 8 lines
drivers/usb/gadget/udc-core.c static ssize_t usb_udc_softconn_store(struct device *dev,
Quoted 6 lines
drivers/usb/gadget/udc-core.c +3
-1+return snprintf (buf,PAGE_SIZE ,"%d\n" , +gadget_is_dualspeed (udc->gadget)); } -static DEVICE_ATTR(speed, S_IRUSR, usb_udc_speed_show, NULL); +static DEVICE_ATTR(is_dualspeed, S_IRUSR, usb_udc_is_dualspeed_show, NULL);maybe deprecate this one on feature-removal-schedule ??
Sure.
Also, if we decide to change “speed” to “current_speed”, we could just drop this without the announcement.
Signature · 4 lines
Best regards, _ _ .o. | Liege of Serenely Enlightened Majesty of o' \,=./ `o ..o | Computer Science, Michal "mina86" Nazarewicz (o o) ooo +-----<email/xmpp: [email protected]>-----ooO--(_)--Ooo--
Re: [PATCHv3 2/4] usb: gadget: replace "is_dualspeed" with "max_speed"
Hi,
Quoted 1 line · Michal Nazarewicz
Sorry, I somehow missed this mail before.
np
Quoted 7 lines
Quoted 6 lines · Michal Nazarewicz
Quoted 5 lines
This commit replaces usb_gadget's
is_dualspeedfield with amax_speedfield.This change is made so that one will be able to check at run-time if given gadget supports super speed.
Quoted 7 lines
Quoted 4 lines · Felipe Balbi
IMHO the logic is inverted here. It should start from the function drivers. They should say which USB speeds they support, that would go up to composite layer and composite would call e.g.
usb_gadget_set_speed(gadget, maximum_speed);This is actually not how composite works at the moment. Currently,
my suggestion was exactly to change that :-) Speed is something functions support. composite.c shouldn't dictate which speed functions should use, rather composite.c should use the maximum speed which all functions support.
Quoted 8 lines
a composite gadget can declare a maximum speed of say “high” even if all the functions do not support that speed. Of course when host asks about descriptors for given speed, only functions that support that speed will be returned (and hence only configurations that have at least one function supporting that speed).
Whether the behaviour should be changed is, in my opinion, issue separate from the patchset that I'm sending.
I wouldn't say that, actually. Just replacing is_dualspeed with max_speed isn't changing much and if you want to make that part of the code better, why not doing The Right Thing(TM) ?
All of the speed negotiation between composite.c and f_*.c should happen before even connecting to host (before attaching data pullups, enabling IRQs, etc), that's exactly why me and Sebastian have decided (at that time off list) to add udc_start()/udc_stop() methods. One of the reason was that it would be a quite intrusive change to all UDC drivers, second we wanted to give maintainers/authors of those UDC drivers some grace period for the change, third when all UDCs are converted, it allow us to do the speed negotiation before connecting to host.
Quoted 26 lines
Quoted 11 lines
Quoted 11 lines
drivers/usb/gadget/udc-core.c +0
-0@@ -371,14 +371,28 @@ static ssize_t usb_udc_softconn_store(struct device *dev, } static DEVICE_ATTR(soft_connect, S_IWUSR, NULL, usb_udc_softconn_store);Quoted 14 lines
drivers/usb/gadget/udc-core.c static ssize_t usb_udc_softconn_store(struct device *dev, · line 384
Quoted 12 lines
drivers/usb/gadget/udc-core.c +11
-1-static ssize_t usb_udc_speed_show(struct device *dev, +#define USB_UDC_SPEED_ATTR (name) \ +ssize_t usb_udc_##name##_show(struct device *dev, \ + struct device_attribute *attr, char *buf) \ +{ \ + struct usb_udc *udc = container_of(dev, struct usb_udc, dev); \ + return snprintf(buf, PAGE_SIZE, "%s\n", \ + usb_device_speed_name(udc->gadget->name)); \ +} \ +static DEVICE_ATTR(name, S_IRUSR, usb_udc_##name##_show, NULL) + +static USB_UDC_SPEED_ATTR (speed);how about "
current_speed" ?
Quoted 4 lines
Is there a big advantage? That would change external interface and I don't see reason to do so. Of course, udc class is quite recent so if you feel we can
ignore this issue I can go forward with that change.
you already maximum_speed (below) and speed alone looses some extra hint of what kind of information will be there. I think it's better to change this to current_speed and make a symbolic link called 'speed' which we can keep for the next 5 years and remove it in e.g. Linux v5.0
Quoted 17 lines
Quoted 8 lines
Quoted 8 lines
drivers/usb/gadget/udc-core.c +3
-3+/* Provide "is_dualspeed" for backward compatibility. */ +static ssize_t usb_udc_is_dualspeed_show (struct device *dev,struct device_attribute *attr,char *buf) { - struct usb_udc *udc = container_of(dev, struct usb_udc, dev); -return snprintf (buf,PAGE_SIZE ,"%s\n" , -usb_device_speed_name (udc->gadget->speed)); + struct usb_udc *udc = container_of(dev, struct usb_udc, dev);Quoted 8 lines
drivers/usb/gadget/udc-core.c static ssize_t usb_udc_softconn_store(struct device *dev,
Quoted 6 lines
drivers/usb/gadget/udc-core.c +3
-1+return snprintf (buf,PAGE_SIZE ,"%d\n" , +gadget_is_dualspeed (udc->gadget)); } -static DEVICE_ATTR(speed, S_IRUSR, usb_udc_speed_show, NULL); +static DEVICE_ATTR(is_dualspeed, S_IRUSR, usb_udc_is_dualspeed_show, NULL);maybe deprecate this one on feature-removal-schedule ??
Quoted 4 lines
Sure.
Also, if we decide to change “speed” to “current_speed”, we could just drop this without the announcement.
I rather have the announcement. See above that you can make a symbolic link with the name 'speed' for the time being.
Signature · 1 line
balbi
Re: [PATCHv3 2/4] usb: gadget: replace "is_dualspeed" with "max_speed"
Quoted 11 lines · Felipe Balbi
Quoted 6 lines · Felipe Balbi
Quoted 3 lines
IMHO the logic is inverted here. It should start from the function
drivers. They should say which USB speeds they support, that would go up to composite layer and composite would call e.g.usb_gadget_set_speed(gadget, maximum_speed);This is actually not how composite works at the moment. Currently,
my suggestion was exactly to change that :-) Speed is something functions support.
composite.cshouldn't dictate which speed functions should use, rathercomposite.cshould use the maximum speed which all functions support.
Strictly speaking, composite.c does not dictate anything. It just copies
what the composite gadget driver declared as maximum speed.
My understanding was that one could consciously create a composite gadget such that not all of the functions support all of the speeds.
I would suggest leaving everything as is, expect if usb_composite_driver's max_speed is set to USB_SPEED_UNKNOWN in which case composite would iterate over all the functions and figure out the maximum speed that all of the functions support.
Quoted 6 lines
Quoted 6 lines
a composite gadget can declare a maximum speed of say “high” even if all the functions do not support that speed. Of course when host asks about descriptors for given speed, only functions that support that speed will be returned (and hence only configurations that have at least one function supporting that speed).
Quoted 6 lines
Quoted 2 lines
Whether the behaviour should be changed is, in my opinion, issue separate from the patchset that I'm sending.
I wouldn't say that, actually. Just replacing
is_dualspeedwithmax_speedisn't changing much and if you want to make that part of the code better, why not doing The Right Thing(TM) ?
I'm just saying that the main reason for this patchset is to get rid of the USB_GADGET_DUALSPEED and USB_GADGET_SUPERSPEED Kconfig options. So the purpose of changing is_dualspeed with max_speed is to be able to check if gadget is super speed at run-time so that gadget_is_superspeed() can be implemented.
So I would like to just get this done and then figure out what to do with composite.c. How does that sound?
Quoted 2 lines
All of the speed negotiation between
composite.cand f_*.c should happen before even connecting to host
Yep, obviously. The usb_gadget_probe_driver() is called at the very and once all the functions and everything is added so composite.c can do all the analysis it wants and figure out the maximum speed.
Quoted 3 lines
(before attaching data pullups, enabling IRQs, etc), that's exactly why me and Sebastian have decided (at that time off list) to add udc_start()/udc_stop() methods.
I don't really follow why those would be needed...
Quoted 5 lines
One of the reason was that it would be a quite intrusive change to all UDC drivers, second we wanted to give maintainers/authors of those UDC drivers some grace period for the change, third when all UDCs are converted, it allow us to do the speed negotiation before connecting to host.
Again, I don't follow. We can figure out the max_speed before calling usb_gadget_probe_driver() just fine. We don't even have to have UDC to figure that out (ie. gadget driver's max_speed does not change depending on UDC, right?).
Quoted 9 lines
Quoted 4 lines
Quoted 1 line
how about "
current_speed" ?Is there a big advantage? That would change external interface and I don't see reason to do so. Of course, udc class is quite recent so if you feel we can ignore this issue I can go forward with that change.
you already
maximum_speed(below) and speed alone looses some extra hint of what kind of information will be there. I think it's better to change this tocurrent_speedand make a symbolic link called 'speed' which we can keep for the next 5 years and remove it in e.g. Linux v5.0
OK, I'll do that (as soon as I figure out/recall how to make symlinks that is ;) ).
Signature · 4 lines
Best regards, _ _ .o. | Liege of Serenely Enlightened Majesty of o' \,=./ `o ..o | Computer Science, Michal "mina86" Nazarewicz (o o) ooo +-----<email/xmpp: [email protected]>-----ooO--(_)--Ooo--
Re: [PATCHv3 2/4] usb: gadget: replace "is_dualspeed" with "max_speed"
Quoted 2 lines · Michal Nazarewicz
My understanding was that one could consciously create a composite gadget such that not all of the functions support all of the speeds.
That's an important point. If somebody wants to build a composite gadget that includes both midi and storage support, the storage driver would be able to go all the way up to SuperSpeed (or rather, it will once Felipe's patch is finished and merged) but the midi driver would only support full speed. So what speed should the UDC connect at?
In cases like this there's really no way to know. Ultimately the best approach would be to update the midi driver, but that's a long-term sort of thing.
Usually when the kernel can't decide something, it asks the user for help (by allowing the user to specify the speed via a module parameter, for instance). In this case even that wouldn't work, because the gadget's userspace isn't aware of which functions the host's user will want to utilize.
At the moment I don't know the best answer. This is something we should all think about.
Alan Stern
Re: [PATCHv3 2/4] usb: gadget: replace "is_dualspeed" with "max_speed"
Hi,
Quoted 10 lines · Alan Stern
Quoted 2 lines · Michal Nazarewicz
My understanding was that one could consciously create a composite gadget such that not all of the functions support all of the speeds.
That's an important point. If somebody wants to build a composite gadget that includes both midi and storage support, the storage driver would be able to go all the way up to SuperSpeed (or rather, it will once Felipe's patch is finished and merged) but the midi driver would only support full speed. So what speed should the UDC connect at?
if they are both part of the of the same configuration, full speed. Otherwise Audio won't work. If they are part of different configurations, then maximum_speed will be defined by the chosen config, no ?
Quoted 3 lines
In cases like this there's really no way to know. Ultimately the best approach would be to update the midi driver, but that's a long-term sort of thing.
yeah, I agree here.
Quoted 8 lines
Usually when the kernel can't decide something, it asks the user for help (by allowing the user to specify the speed via a module parameter, for instance). In this case even that wouldn't work, because the gadget's userspace isn't aware of which functions the host's user will want to utilize.
At the moment I don't know the best answer. This is something we should all think about.
I stand with the fact that if they are part of the same configuration, there's no way around it, storage will have to come down to full speed. Unless I'm missing something.
Signature · 1 line
balbi
Re: [PATCHv3 2/4] usb: gadget: replace "is_dualspeed" with "max_speed"
Quoted 3 lines · Felipe Balbi
I stand with the fact that if they are part of the same configuration, there's no way around it, storage will have to come down to full speed. Unless I'm missing something.
If you look at config_buf() in composite.c, you'll notice that composite just skips functions that do not support current speed. This means, that if a connection uses high speed but given function can handle only full speed, it won't be included in the descriptors.
config_buf() is called from config_desc() which similarly, iterates over configurations skipping the ones that do not support given speed.
Configuration is defined to support given speed if at least one function that is added to that configuration supports that speed (see usb_add_function()).
This also allows creating functions that support high speed but do not support full speed (which I'm unsure whether it makes sense).
Signature · 4 lines
Best regards, _ _ .o. | Liege of Serenely Enlightened Majesty of o' \,=./ `o ..o | Computer Science, Michal "mina86" Nazarewicz (o o) ooo +-----<email/xmpp: [email protected]>-----ooO--(_)--Ooo--
Re: [PATCHv3 2/4] usb: gadget: replace "is_dualspeed" with "max_speed"
Hi,
Quoted 10 lines · Michal Nazarewicz
Quoted 3 lines · Felipe Balbi
I stand with the fact that if they are part of the same configuration, there's no way around it, storage will have to come down to full speed. Unless I'm missing something.
If you look at
config_buf()incomposite.c, you'll notice that composite just skips functions that do not support current speed. This means, that if a connection uses high speed but given function can handle only full speed, it won't be included in the descriptors.
Quoted 6 lines
config_buf()is called fromconfig_desc()which similarly, iterates over configurations skipping the ones that do not support given speed.Configuration is defined to support given speed if at least one function that is added to that configuration supports that speed (see
usb_add_function()).
I'm trying to think if this is really what we want. This might mean $current_config will be different depending if we connect it to SS, HS or FS hubs. Do we need USB-IF's help here ? I guess I could drop them a mail and ask for some clarification. Don't know how long it would take to get an answer though :-s
Signature · 1 line
balbi
Re: [PATCHv3 2/4] usb: gadget: replace "is_dualspeed" with "max_speed"
Quoted 11 lines · Michal Nazarewicz
Quoted 10 lines
If you look at
config_buf()incomposite.c, you'll notice that composite
just skips functions that do not support current speed. This means, that if a connection uses high speed but given function can handle only full speed, it won't be included in the descriptors.
config_buf()is called fromconfig_desc()which similarly, iterates over configurations skipping the ones that do not support given speed.Configuration is defined to support given speed if at least one function that is added to that configuration supports that speed (see
usb_add_function()).
Quoted 3 lines · Felipe Balbi
I'm trying to think if this is really what we want. This might mean $current_config will be different depending if we connect it to SS, HS or FS hubs.
What do you mean by $current_config? The bConfigurationValue will be the same for "the same" configuration regardless of speed but different configurations may be available for different speeds and "the same" configuration in various speeds might have different functions.
So just for the sake of having something concrete, let's say we have:
Configuration #1 with
function A supporting FS and HS and
function B supporting FS only.
Configuration #2 with
function B supporting FS only.
Configuration #3 with
function A supporting FS and HS and
function C supporting HS only (dunno if that makes sense).
When connected to FS hub, we will return the following:
Configuration #1: A, B
Configuration #2: B
Configuration #3: A
When connect to HS hub, we will return the following:
Configuration #1: A
Configuration #3: A, C
And similarly to bConfigurationValue, the interface IDs may have holes in them.
Whether that's what we want, I don't know... But if I understand composite.c correctly, that's how it is implemented now.
Signature · 4 lines
Best regards, _ _ .o. | Liege of Serenely Enlightened Majesty of o' \,=./ `o ..o | Computer Science, Michal "mina86" Nazarewicz (o o) ooo +-----<email/xmpp: [email protected]>-----ooO--(_)--Ooo--
Re: [PATCHv3 2/4] usb: gadget: replace "is_dualspeed" with "max_speed"
Hi,
Quoted 14 lines · Michal Nazarewicz
Quoted 7 lines · Michal Nazarewicz
Quoted 6 lines
If you look at
config_buf()incomposite.c, you'll notice that composite just skips functions that do not support current speed. This means, that if a connection uses high speed but given function can handle only
full speed, it won't be included in the descriptors.Quoted 6 lines
Quoted 6 lines
config_buf()is called fromconfig_desc()which similarly, iterates over configurations skipping the ones that do not support given speed.Configuration is defined to support given speed if at least one function that is added to that configuration supports that speed (see
usb_add_function()).
Quoted 6 lines
Quoted 3 lines · Felipe Balbi
I'm trying to think if this is really what we want. This might mean $current_config will be different depending if we connect it to SS, HS or FS hubs.
What do you mean by $current_config? The bConfigurationValue will be
the currently chosen configuration.
Quoted 8 lines
the same for "the same" configuration regardless of speed but different configurations may be available for different speeds and "the same" configuration in various speeds might have different functions.
So just for the sake of having something concrete, let's say we have:
Configuration #1 with
function A supporting FS and HS and
my question is what happens with the HS support on function A (descriptors, endpoints, etc) when you connect it to a HS hub or to a FS hub.
Quoted 9 lines
function B supporting FS only.
Configuration #2 with
function B supporting FS only.
Configuration #3 with
function A supporting FS and HS and
function C supporting HS only (dunno if that makes sense).When connected to FS hub, we will return the following:
Quoted 7 lines
Configuration #1: A, B
Configuration #2: B
Configuration #3: AWhen connect to HS hub, we will return the following:
Configuration #1: A
See, I'm not sure this is allowed by USB spec. But I could be wrong. (I mean having a function disappear)
Signature · 1 line
balbi
Re: [PATCHv3 2/4] usb: gadget: replace "is_dualspeed" with "max_speed"
Quoted 7 lines
Quoted 4 lines · Felipe Balbi
Quoted 3 lines
I'm trying to think if this is really what we want. This might mean $current_config will be different depending if we connect it to SS, HS or FS hubs.
Quoted 1 line · Michal Nazarewicz
What do you mean by $current_config? The bConfigurationValue will be
Quoted 1 line · Felipe Balbi
the currently chosen configuration.
So yes, it potentially ma be different depending on the speed.
Quoted 4 lines
Quoted 4 lines
the same for "the same" configuration regardless of speed but different configurations may be available for different speeds and "the same" configuration in various speeds might have different functions.
Quoted 8 lines
Quoted 4 lines
So just for the sake of having something concrete, let's say we have:
Configuration #1 with
function A supporting FS and HS andmy question is what happens with the HS support on function A (descriptors, endpoints, etc) when you connect it to a HS hub or to a FS hub.
When you connect it to HS hub you get it's HS descriptors (and FS descriptors if you request “other speed descriptors”). When you connect it to FS hub you get it's FS descriptors.
Quoted 13 lines
Quoted 13 lines
function B supporting FS only.
Configuration #2 with
function B supporting FS only.
Configuration #3 with
function A supporting FS and HS and
function C supporting HS only (dunno if that makes sense).When connected to FS hub, we will return the following:
Configuration #1: A, B
Configuration #2: B
Configuration #3: A
Quoted 6 lines
Quoted 3 lines
When connect to HS hub, we will return the following:
Configuration #1: A
See, I'm not sure this is allowed by USB spec. But I could be wrong. (I mean having a function disappear)
I'm hardly an expert so I cannot address that concern.
Signature · 4 lines
Best regards, _ _ .o. | Liege of Serenely Enlightened Majesty of o' \,=./ `o ..o | Computer Science, Michal "mina86" Nazarewicz (o o) ooo +-----<email/xmpp: [email protected]>-----ooO--(_)--Ooo--
Re: [PATCHv3 2/4] usb: gadget: replace "is_dualspeed" with "max_speed"
In reply to Felipe BalbiQuoted 14 lines · Felipe Balbi
Hi,
Quoted 10 lines · Alan Stern
Quoted 2 lines · Michal Nazarewicz
My understanding was that one could consciously create a composite gadget such that not all of the functions support all of the speeds.
That's an important point. If somebody wants to build a composite gadget that includes both midi and storage support, the storage driver would be able to go all the way up to SuperSpeed (or rather, it will once Felipe's patch is finished and merged) but the midi driver would only support full speed. So what speed should the UDC connect at?
Quoted 4 lines
if they are both part of the of the same configuration, full speed. Otherwise Audio won't work. If they are part of different configurations, then
maximum_speedwill be defined by the chosen config, no ?
No. The speed has to be chosen first, when the gadget connects to the host. The config isn't chosen until later, after the host retrieves the various descriptors and decides among them.
Quoted 12 lines
Quoted 3 lines
In cases like this there's really no way to know. Ultimately the best approach would be to update the midi driver, but that's a long-term sort of thing.
yeah, I agree here.
Quoted 6 lines
Usually when the kernel can't decide something, it asks the user for help (by allowing the user to specify the speed via a module parameter, for instance). In this case even that wouldn't work, because the gadget's userspace isn't aware of which functions the host's user will want to utilize.
Quoted 6 lines
Quoted 2 lines
At the moment I don't know the best answer. This is something we should all think about.
I stand with the fact that if they are part of the same configuration, there's no way around it, storage will have to come down to full speed. Unless I'm missing something.
What if they are in different configurations?
Alan Stern
Re: [PATCHv3 2/4] usb: gadget: replace "is_dualspeed" with "max_speed"
Hi,
Quoted 8 lines · Alan Stern
Quoted 4 lines
if they are both part of the of the same configuration, full speed. Otherwise Audio won't work. If they are part of different configurations, then
maximum_speedwill be defined by the chosen config, no ?No. The speed has to be chosen first, when the gadget connects to the host. The config isn't chosen until later, after the host retrieves the various descriptors and decides among them.
true
Quoted 5 lines
Quoted 3 lines
I stand with the fact that if they are part of the same configuration, there's no way around it, storage will have to come down to full speed. Unless I'm missing something.
What if they are in different configurations?
then you use the fastest speed between both configurations?
Signature · 1 line
balbi
Re: [PATCHv3 2/4] usb: gadget: replace "is_dualspeed" with "max_speed"
Quoted 14 lines · Felipe Balbi
Hi,
Quoted 8 lines · Alan Stern
Quoted 4 lines
if they are both part of the of the same configuration, full speed. Otherwise Audio won't work. If they are part of different configurations, then
maximum_speedwill be defined by the chosen config, no ?No. The speed has to be chosen first, when the gadget connects to the host. The config isn't chosen until later, after the host retrieves the various descriptors and decides among them.
true
Quoted 7 lines
Quoted 5 lines
Quoted 3 lines
I stand with the fact that if they are part of the same configuration, there's no way around it, storage will have to come down to full speed. Unless I'm missing something.
What if they are in different configurations?
then you use the fastest speed between both configurations?
I simply don't know. It's a difficult problem.
For the time being, perhaps the best answer is to use the _lowest_ max_speed value among all the function drivers. It's the simplest answer and most likely to be correct most of the time.
If anybody ever does want to put together a composite gadget that runs faster than full speed but still provides a midi function ... well, they'll just have to update the midi gadget driver.
(Actually that's a bogus example. It turns out that gmidi.c doesn't support the composite framework. Oh well.)
Alan Stern
Re: [PATCHv3 2/4] usb: gadget: replace "is_dualspeed" with "max_speed"
Quoted 3 lines · Alan Stern
For the time being, perhaps the best answer is to use the _lowest_
max_speedvalue among all the function drivers. It's the simplest answer and most likely to be correct most of the time.
In theory, one could create a composite function with only SS/HS descriptors. So it would work for SS/HS but not for FS. I'm not saying that it would make sense (or that it's not a bug) but that adds to the discussion.
Signature · 4 lines
Best regards, _ _ .o. | Liege of Serenely Enlightened Majesty of o' \,=./ `o ..o | Computer Science, Michal "mina86" Nazarewicz (o o) ooo +-----<email/xmpp: [email protected]>-----ooO--(_)--Ooo--
Re: [PATCHv3 2/4] usb: gadget: replace "is_dualspeed" with "max_speed"
Quoted 8 lines · Michal Nazarewicz
Quoted 3 lines · Alan Stern
For the time being, perhaps the best answer is to use the _lowest_
max_speedvalue among all the function drivers. It's the simplest answer and most likely to be correct most of the time.In theory, one could create a composite function with only SS/HS descriptors.
The only reason for doing that would be if the function was incapable of carrying out its duties when running at full speed (insufficient bandwidth, for example). Something like this is discussed briefly in section 9.2.6.6 of the USB-2 spec.
Quoted 3 lines
So it would work for SS/HS but not for FS. I'm not
saying that it would make sense (or that it's not a bug) but that adds to the discussion.
If somebody writes a composite gadget containing two functions, one of which supports only full speed and the other only high speed, they'll get what they deserve. :-)
Still, maybe I was wrong. Maybe it would be better to use the fastest speed supported by at least one of the function drivers. The user can always force a SuperSpeed-capable device to run at high speed by using a USB-2 cable to plug it in. I'm not sure whether the user could force such a device to run at full speed, however.
Alan Stern
Re: [PATCHv3 2/4] usb: gadget: replace "is_dualspeed" with "max_speed"
Hi,
Quoted 24 lines · Alan Stern
Quoted 8 lines · Michal Nazarewicz
Quoted 3 lines · Alan Stern
For the time being, perhaps the best answer is to use the _lowest_
max_speedvalue among all the function drivers. It's the simplest answer and most likely to be correct most of the time.In theory, one could create a composite function with only SS/HS descriptors.
The only reason for doing that would be if the function was incapable of carrying out its duties when running at full speed (insufficient bandwidth, for example). Something like this is discussed briefly in section 9.2.6.6 of the USB-2 spec.
Quoted 3 lines
So it would work for SS/HS but not for FS. I'm not
saying that it would make sense (or that it's not a bug) but that adds to the discussion.If somebody writes a composite gadget containing two functions, one of which supports only full speed and the other only high speed, they'll get what they deserve. :-)
Quoted 5 lines
Still, maybe I was wrong. Maybe it would be better to use the fastest speed supported by at least one of the function drivers. The user can always force a SuperSpeed-capable device to run at high speed by using a USB-2 cable to plug it in. I'm not sure whether the user could force such a device to run at full speed, however.
plug it behind a full speed hub, like those that usually come on USB keyboards.
Signature · 1 line
balbi
Re: [PATCHv3 2/4] usb: gadget: replace "is_dualspeed" with "max_speed"
In reply to Alan SternQuoted 5 lines · Alan Stern
Still, maybe I was wrong. Maybe it would be better to use the fastest speed supported by at least one of the function drivers. The user can always force a SuperSpeed-capable device to run at high speed by using a USB-2 cable to plug it in. I'm not sure whether the user could force such a device to run at full speed, however.
I'm actually wondering whether we really need to worry about it. composite_driver has the “max_speed” field and I would just leave it as composite driver's author responsibility to put correct value there.
One thing that could be worth doing is iterate over all the configurations and figure out if at least one supports the speed declared by “max_speed” and if not, lower it.
Like I've said before, as additional functionality, composite.c could check if it's USB_SPEED_UNKWONW in which case it would look for the lowest speed that all the functions support.
Such configuration would allow composite driver authors set the speed to USB_SPEED_SUPER when they mean “choose maximum speed at least one function supports” and to “USB_SPEED_UNKWONW” when they mean “choose maximum speed all the functions support”.
Does that make sense?
Signature · 4 lines
Best regards, _ _ .o. | Liege of Serenely Enlightened Majesty of o' \,=./ `o ..o | Computer Science, Michal "mina86" Nazarewicz (o o) ooo +-----<email/xmpp: [email protected]>-----ooO--(_)--Ooo--
Re: [PATCHv3 2/4] usb: gadget: replace "is_dualspeed" with "max_speed"
Quoted 8 lines · Michal Nazarewicz
Quoted 5 lines · Alan Stern
Still, maybe I was wrong. Maybe it would be better to use the fastest speed supported by at least one of the function drivers. The user can always force a SuperSpeed-capable device to run at high speed by using a USB-2 cable to plug it in. I'm not sure whether the user could force such a device to run at full speed, however.
Quoted 7 lines
I'm actually wondering whether we really need to worry about it.
composite_driverhas the “max_speed” field and I would just leave it as composite driver's author responsibility to put correct value there.One thing that could be worth doing is iterate over all the configurations and figure out if at least one supports the speed declared by “max_speed” and if not, lower it.
That's the same as what I said: Use the highest speed supported by any function driver. There really isn't any point in allowing connections faster than that. And as Felipe pointed out, the user always has the capability to force the connection to be slower, by using the right sorts of cables and hubs.
Quoted 10 lines
Like I've said before, as additional functionality,
composite.ccould check if it'sUSB_SPEED_UNKWONWin which case it would look for the lowest speed that all the functions support.Such configuration would allow composite driver authors set the speed to
USB_SPEED_SUPERwhen they mean “choose maximum speed at least one function supports” and to “USB_SPEED_UNKWONW” when they mean “choose maximum speed all the functions support”.Does that make sense?
It's reasonable. Just be sure to document it properly; otherwise nobody will understand or remember it!
Alan Stern
Re: [PATCHv3 2/4] usb: gadget: replace "is_dualspeed" with "max_speed"
Quoted 7 lines · Michal Nazarewicz
Quoted 6 lines
I'm actually wondering whether we really need to worry about it.
composite_driverhas the “max_speed” field and I would just leave it as composite driver's author responsibility to put correct value there.One thing that could be worth doing is iterate over all the configurations and figure out if at least one supports the speed declared by “max_speed” and if not, lower it.
Quoted 2 lines · Alan Stern
That's the same as what I said: Use the highest speed supported by any function driver.
Right.
Quoted 5 lines
Quoted 2 lines
Like I've said before, as additional functionality,
composite.ccould
check if it'sUSB_SPEED_UNKWONWin which case it would look for the lowest speed that all the functions support.It's reasonable. Just be sure to document it properly; otherwise nobody will understand or remember it!
I've found where my reasoning was faulty. The usb_gadget_driver's max_speed is set before all the functions get added so composite.c has no way to figure those things in advance. That's why we need to relay on usb_composite_driver's max_speed be set to a proper value.
Signature · 4 lines
Best regards, _ _ .o. | Liege of Serenely Enlightened Majesty of o' \,=./ `o ..o | Computer Science, Michal "mina86" Nazarewicz (o o) ooo +-----<email/xmpp: [email protected]>-----ooO--(_)--Ooo--
Re: [PATCHv3 2/4] usb: gadget: replace "is_dualspeed" with "max_speed"
Quoted 4 lines · Michal Nazarewicz
I've found where my reasoning was faulty. The usb_gadget_driver's
max_speedis set before all the functions get added socomposite.chas no way to figure those things in advance. That's why we need to relay on usb_composite_driver'smax_speedbe set to a proper value.
This is what Felipe was complaining about earlier. We shouldn't set max_speed or allow the UDC to connect to the host until all the functions have been added.
Alan Stern
Re: [PATCHv3 2/4] usb: gadget: replace "is_dualspeed" with "max_speed"
Quoted 10 lines · Alan Stern
Quoted 4 lines · Michal Nazarewicz
I've found where my reasoning was faulty. The usb_gadget_driver's
max_speedis set before all the functions get added socomposite.chas no way to figure those things in advance. That's why we need to relay on usb_composite_driver'smax_speedbe set to a proper value.This is what Felipe was complaining about earlier. We shouldn't set
max_speedor allow the UDC to connect to the host until all the functions have been added.
We're not doing the latter. The functions are added in bind callback so (hopefully) UDC will first run the bind callback and then try connecting to host.
And the former would be fixed if we allowed gadget driver to set max_speed in bind callback rather then prior to calling usb_gadget_probe_driver().
Signature · 4 lines
Best regards, _ _ .o. | Liege of Serenely Enlightened Majesty of o' \,=./ `o ..o | Computer Science, Michal "mina86" Nazarewicz (o o) ooo +-----<email/xmpp: [email protected]>-----ooO--(_)--Ooo--
Re: [PATCHv3 2/4] usb: gadget: replace "is_dualspeed" with "max_speed"
Hi,
Quoted 14 lines · Michal Nazarewicz
Quoted 10 lines · Alan Stern
Quoted 4 lines · Michal Nazarewicz
I've found where my reasoning was faulty. The usb_gadget_driver's
max_speedis set before all the functions get added socomposite.chas no way to figure those things in advance. That's why we need to relay on usb_composite_driver'smax_speedbe set to a proper value.This is what Felipe was complaining about earlier. We shouldn't set
max_speedor allow the UDC to connect to the host until all the functions have been added.
Quoted 6 lines
We're not doing the latter. The functions are added in bind callback so (hopefully) UDC will first run the bind callback and then try connecting to host.
And the former would be fixed if we allowed gadget driver to set
max_speedin bind callback rather then prior to callingusb_gadget_probe_driver().
there's one catch. As of today, we always start UDCs with data pullups connected, which means that we could connect to a host even before a gadget driver is loaded. My point in moving to udc_start/udc_stop is that the above would be take care of. See udc-core.c:
int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
int (*bind)(struct usb_gadget *))
{
....
if (udc_is_newstyle(udc)) {
ret = bind(udc->gadget);
if (ret)
goto err1;
ret = usb_gadget_udc_start(udc->gadget, driver);
if (ret) {
driver->unbind(udc->gadget);
goto err1;
}
usb_gadget_connect(udc->gadget);
} else {
ret = usb_gadget_start(udc->gadget, driver, bind);
if (ret)
goto err1;
}
...
}If all UDCs are converted to udc_start()/udc_stop() we get the guarantee that they will only conect to host after gadget driver is fully loaded for free. We can also, finally, properly use the usb_function_deactivate/usb_function_activate properly. So for each registered function, composite.c calls usb_function_deactivate() and function is _required_ to call usb_function_activate when it's ready (for f_obex.c that would be when userland OBEX stack has opened /dev/ttyGS*, for g_mass_storage that would be on function bind(), and so on).
Then, when on gadget driver's bind() we can take this kind of spee decision and pass that on to UDC driver.
Signature · 1 line
balbi
Re: [PATCHv3 2/4] usb: gadget: replace "is_dualspeed" with "max_speed"
Quoted 4 lines · Felipe Balbi
there's one catch. As of today, we always start UDCs with data pullups connected, which means that we could connect to a host even before a gadget driver is loaded. My point in moving to udc_start/udc_stop is that the above would be take care of. See
udc-core.c: [...]
Honestly I'm not quite sure why udc_start/udc_stop is needed here. Even without those the UDC driver can start with all hw disabled and turn it on only after the gadget driver's bind callback finishes.
Quoted 8 lines
If all UDCs are converted to udc_start()/udc_stop() we get the guarantee that they will only conect to host after gadget driver is fully loaded for free.
We can also, finally, properly use the usb_function_deactivate/
usb_function_activateproperly. So for each registered function,composite.ccallsusb_function_deactivate()and function is _required_ to callusb_function_activatewhen it's ready.
I'm not really sure why that would be beneficial. Also, it would still require disconnect-connect cycle if some function decides to (de)activate itself while gadget is connected.
Quoted 2 lines
Then, when on gadget driver's
bind()we can take this kind of speed decision and pass that on to UDC driver.
So can we leave things as they are for now and wait for UDCs to be converted and once this is done, do all kinds of magic we want in copomiset's bind callback?
Signature · 4 lines
Best regards, _ _ .o. | Liege of Serenely Enlightened Majesty of o' \,=./ `o ..o | Computer Science, Michal "mina86" Nazarewicz (o o) ooo +-----<email/xmpp: [email protected]>-----ooO--(_)--Ooo--
Re: [PATCHv3 2/4] usb: gadget: replace "is_dualspeed" with "max_speed"
Hi,
Quoted 23 lines · Michal Nazarewicz
Quoted 4 lines · Felipe Balbi
there's one catch. As of today, we always start UDCs with data pullups connected, which means that we could connect to a host even before a gadget driver is loaded. My point in moving to udc_start/udc_stop is that the above would be take care of. See
udc-core.c: [...]Honestly I'm not quite sure why udc_start/udc_stop is needed here. Even without those the UDC driver can start with all hw disabled and turn it on only after the gadget driver's bind callback finishes.
Quoted 8 lines
If all UDCs are converted to udc_start()/udc_stop() we get the guarantee that they will only conect to host after gadget driver is fully loaded for free.
We can also, finally, properly use the usb_function_deactivate/
usb_function_activateproperly. So for each registered function,composite.ccallsusb_function_deactivate()and function is _required_ to callusb_function_activatewhen it's ready.I'm not really sure why that would be beneficial. Also, it would still require disconnect-connect cycle if some function decides to (de)activate itself while gadget is connected.
Quoted 7 lines
Quoted 2 lines
Then, when on gadget driver's
bind()we can take this kind of speed decision and pass that on to UDC driver.So can we leave things as they are for now and wait for UDCs to be converted
and once this is done, do all kinds of magic we want in copomiset's bind callback?
sure.
Signature · 1 line
balbi
Re: [PATCHv3 2/4] usb: gadget: replace "is_dualspeed" with "max_speed"
In reply to Alan SternQuoted 33 lines · Alan Stern
Quoted 8 lines · Michal Nazarewicz
Quoted 5 lines · Alan Stern
Still, maybe I was wrong. Maybe it would be better to use the fastest speed supported by at least one of the function drivers. The user can always force a SuperSpeed-capable device to run at high speed by using a USB-2 cable to plug it in. I'm not sure whether the user could force such a device to run at full speed, however.
Quoted 7 lines
I'm actually wondering whether we really need to worry about it.
composite_driverhas the “max_speed” field and I would just leave it as composite driver's author responsibility to put correct value there.One thing that could be worth doing is iterate over all the configurations and figure out if at least one supports the speed declared by “max_speed” and if not, lower it.
That's the same as what I said: Use the highest speed supported by any function driver. There really isn't any point in allowing connections faster than that. And as Felipe pointed out, the user always has the capability to force the connection to be slower, by using the right sorts of cables and hubs.
Quoted 9 lines
Like I've said before, as additional functionality,
composite.ccould check if it'sUSB_SPEED_UNKWONWin which case it would look for the lowest speed that all the functions support.Such configuration would allow composite driver authors set the speed to
USB_SPEED_SUPERwhen they mean “choose maximum speed at least one function supports” and to “USB_SPEED_UNKWONW” when they mean “choose maximum speed all the functions support”.
Quoted 4 lines
Quoted 1 line
Does that make sense?
It's reasonable. Just be sure to document it properly; otherwise nobody will understand or remember it!
good point. I agree with this approach.
Signature · 1 line
balbi
Re: [PATCHv3 2/4] usb: gadget: replace "is_dualspeed" with "max_speed"
In reply to Michal NazarewiczHi,
Quoted 10 lines · Michal Nazarewicz
Quoted 8 lines · Felipe Balbi
Quoted 7 lines · Felipe Balbi
Quoted 4 lines
IMHO the logic is inverted here. It should start from the function drivers. They should say which USB speeds they support, that would go up to composite layer and composite would call e.g.
usb_gadget_set_speed(gadget, maximum_speed);This is actually not how composite works at the moment. Currently,
Quoted 7 lines
Quoted 4 lines
my suggestion was exactly to change that :-) Speed is something functions support.
composite.cshouldn't dictate which speed functions should use, rathercomposite.cshould use the maximum speed which all functions support.Strictly speaking,
composite.cdoes not dictate anything. It just copies
what the composite gadget driver declared as maximum speed.
true.
Quoted 2 lines
My understanding was that one could consciously create a composite gadget such that not all of the functions support all of the speeds.
of course, but if he puts FS function and SS function on the same configuration, SS function will have to come down to FS, no ?
Quoted 9 lines
Quoted 9 lines
Quoted 8 lines
a composite gadget can declare a maximum speed of say “high” even if all the functions do not support that speed. Of course when host asks about descriptors for given speed, only functions that support that speed will be returned (and hence only configurations that have at least one function supporting that speed).
Whether the behaviour should be changed is, in my opinion, issue separate from the patchset that I'm sending.
Quoted 6 lines
Quoted 3 lines
I wouldn't say that, actually. Just replacing
is_dualspeedwithmax_speedisn't changing much and if you want to make that part of the code better, why not doing The Right Thing(TM) ?I'm just saying that the main reason for this patchset is to get rid of the
USB_GADGET_DUALSPEEDandUSB_GADGET_SUPERSPEEDKconfigoptions. So
yes, but for removing USB_GADGET_DUALSPEED there's no requirement, per se, to remove is_dualspeed, am I right ? I could be missing something.
Quoted 3 lines
the purpose of changing
is_dualspeedwithmax_speedis to be able to check if gadget is super speed at run-time so thatgadget_is_superspeed()can be implemented.
I understand. It does sound better than adding is_superspeed flag.
Quoted 2 lines
So I would like to just get this done and then figure out what to do with
composite.c. How does that sound?
When you put it that way, I guess I must agree ;-)
Quoted 7 lines
Quoted 2 lines
All of the speed negotiation between
composite.cand f_*.c should happen before even connecting to hostYep, obviously. The
usb_gadget_probe_driver()is called at the very and once all the functions and everything is added socomposite.ccan do all the analysis it wants and figure out the maximum speed.
Quoted 5 lines
Quoted 3 lines
(before attaching data pullups, enabling IRQs, etc), that's exactly why me and Sebastian have decided (at that time off list) to add udc_start()/udc_stop() methods.
I don't really follow why those would be needed...
Ok, I guess I need to give the full picture here, my bad.
Let's say you have a SuperSpeed controller, but you know that this particular gadget driver can only support fullspeed, so why do you need to go through RX detection, HS chirp sequence and whatnot if you can decide the maximum_speed before kickstarting the UDC's state machine ?
most controllers (or at least the ones I have seen) have ways to set the maximum_speed we are going to support. As of today, we always, blindly, set the maximum supported by the controller, but that can change overtime.
This might (and I never tested) mean we would be saving a few uA in the sense that unused HW blocks wouldn't even be powered up (at the least the more recent cores have quite a fine grain control over what powers up and what doesn't).
Quoted 10 lines
Quoted 5 lines
One of the reason was that it would be a quite intrusive change to all UDC drivers, second we wanted to give maintainers/authors of those UDC drivers some grace period for the change, third when all UDCs are converted, it allow us to do the speed negotiation before connecting to host.
Again, I don't follow. We can figure out the
max_speedbefore callingusb_gadget_probe_driver()just fine. We don't even have to have UDC to figure that out (ie. gadget driver'smax_speeddoes not change depending on UDC, right?).
it doesn't change depending on UDC, but UDC can take certain decisions depending on the maximum_speed current gadget driver supports ;-)
Quoted 7 lines
Quoted 4 lines
you already
maximum_speed(below) and speed alone looses some extra hint of what kind of information will be there. I think it's better to change this tocurrent_speedand make a symbolic link called 'speed' which we can keep for the next 5 years and remove it in e.g. Linux v5.0OK, I'll do that (as soon as I figure out/recall how to make symlinks that is ;) ).
yeah, I would have to go through the same re-education ;-)
(please add a note on feature-removal-schedule too)
Signature · 1 line
balbi
Re: [PATCHv3 2/4] usb: gadget: replace "is_dualspeed" with "max_speed"
Quoted 13 lines
Quoted 2 lines · Felipe Balbi
Quoted 1 line
All of the speed negotiation between
composite.cand f_*.c should happen before even connecting to hostQuoted 9 lines · Michal Nazarewicz
Yep, obviously. The
usb_gadget_probe_driver()is called at the very and once all the functions and everything is added socomposite.ccan do all the analysis it wants and figure out the maximum speed.Quoted 3 lines
(before attaching data pullups, enabling IRQs, etc), that's exactly why me and Sebastian have decided (at that time off list) to add udc_start()/udc_stop() methods.
I don't really follow why those would be needed...
Quoted 6 lines · Felipe Balbi
Ok, I guess I need to give the full picture here, my bad.
Let's say you have a SuperSpeed controller, but you know that this particular gadget driver can only support fullspeed, so why do you need to go through RX detection, HS chirp sequence and whatnot if you can decide the
maximum_speedbefore kickstarting the UDC's state machine ?
But isn't that what's happening right now? The gadget_driver structure has a speed field which is set to the maximum speed the gadget driver can handle. Only after this is set, usb_gadget_probe_driver() is called so at this point a SS UDC can figure out whether it needs to turn pieces needed for SS support or not.
Quoted 8 lines
Quoted 6 lines
Quoted 4 lines
you already
maximum_speed(below) and speed alone looses some extra hint of what kind of information will be there. I think it's better to change this tocurrent_speedand make a symbolic link called 'speed' which we can keep for the next 5 years and remove it in e.g. Linux v5.0OK, I'll do that (as soon as I figure out/recall how to make symlinks that is ;) ).
yeah, I would have to go through the same re-education ;-)
Adding another attribute with the same show function seems easy, but that's probably not elegant. ;)
Quoted 1 line
(please add a note on feature-removal-schedule too)
Yep!
Signature · 4 lines
Best regards, _ _ .o. | Liege of Serenely Enlightened Majesty of o' \,=./ `o ..o | Computer Science, Michal "mina86" Nazarewicz (o o) ooo +-----<email/xmpp: [email protected]>-----ooO--(_)--Ooo--
PATCH v3 3/4 usb: gadget: rename usb_gadget_driver::speed to max_speed
In reply to Michal NazarewiczFrom: Michal Nazarewicz <[email protected]>
This commit renames the “speed” field of the usb_gadget_driver
structure to “max_speed”. This is so that to make it more apparent that the field represents the maximum speed gadget driver can support.
This also make the field look more like fields with the same name in usb_gadget and usb_composite_driver structures. All of those represent the *maximal* speed given entity supports.
After this commit, there are the following fields in various structures:
* usb_gadget::speed - the current connection speed,
* usb_gadget::max_speed - maximal speed UDC supports,
* usb_gadget_driver::max_speed - maximal speed gadget driver supports, and
* usb_composite_driver::max_speed - maximal speed composite gadget supports.
--- drivers/usb/gadget/amd5536udc.c | 2 +- drivers/usb/gadget/ci13xxx_udc.c | 2 +- drivers/usb/gadget/composite.c | 8 ++++---- drivers/usb/gadget/dbgp.c | 2 +- drivers/usb/gadget/dummy_hcd.c | 13 ++++++------- drivers/usb/gadget/file_storage.c | 4 ++-- drivers/usb/gadget/gmidi.c | 2 +- drivers/usb/gadget/goku_udc.c | 2 +- drivers/usb/gadget/inode.c | 6 +++--- drivers/usb/gadget/m66592-udc.c | 2 +- drivers/usb/gadget/net2272.c | 2 +- drivers/usb/gadget/net2280.c | 2 +- drivers/usb/gadget/pch_udc.c | 2 +- drivers/usb/gadget/printer.c | 2 +- drivers/usb/gadget/r8a66597-udc.c | 2 +- include/linux/usb/gadget.h | 4 ++-- 16 files changed, 28 insertions(+), 29 deletions(-)
drivers/usb/gadget/amd5536udc.c +1 -1
@@ -1968,7 +1968,7 @@ static int amd5536_start(struct usb_gadget_driver *driver,u32 tmp;if (!driver || !bind || !driver->setup - || driver->speed !=USB_SPEED_HIGH ) + || driver->max_speed !=USB_SPEED_HIGH )return -EINVAL ;if (!dev)return -ENODEV ;
drivers/usb/gadget/ci13xxx_udc.c +1 -1
@@ -798,7 +798,7 @@ static ssize_t show_driver(struct device *dev, struct device_attribute *attr, n +=scnprintf (buf + n,PAGE_SIZE - n,"function = %s\n" , (driver->function ? driver->function :"" )); n +=scnprintf (buf + n,PAGE_SIZE - n,"max speed = %d\n" , - driver->speed); + driver->max_speed);return n; }
drivers/usb/gadget/composite.c +4 -4
@@ -1560,9 +1560,9 @@ composite_resume(struct usb_gadget *gadget)static struct usb_gadget_driver composite_driver = { #ifdef CONFIG_USB_GADGET_SUPERSPEED - .speed =USB_SPEED_SUPER , + .max_speed =USB_SPEED_SUPER , #else - .speed =USB_SPEED_HIGH , + .max_speed =USB_SPEED_HIGH , #endif .unbind = composite_unbind,
@@ -1609,8 +1609,8 @@ int usb_composite_probe(struct usb_composite_driver *driver, driver->iProduct = driver->name; composite_driver.function = (char *) driver->name; composite_driver.driver.name = driver->name; - composite_driver.speed =min ((u8 )composite_driver.speed, - (u8 )driver->max_speed); + composite_driver.max_speed =min ((u8 )composite_driver.max_speed, + (u8 )driver->max_speed); composite = driver; composite_gadget_bind = bind;
drivers/usb/gadget/dbgp.c +1 -1
@@ -405,7 +405,7 @@ fail:static struct usb_gadget_driver dbgp_driver = { .function ="dbgp" , - .speed =USB_SPEED_HIGH , + .max_speed =USB_SPEED_HIGH , .unbind = dbgp_unbind, .setup = dbgp_setup, .disconnect = dbgp_disconnect,
drivers/usb/gadget/dummy_hcd.c +6 -7
@@ -832,19 +832,18 @@ static int dummy_pullup (struct usb_gadget *_gadget, int value)if (value && dum->driver) {if (mod_data.is_super_speed) - dum->gadget.speed = dum->driver->speed; + dum->gadget.speed = dum->driver->max_speed;else if (mod_data.is_high_speed) dum->gadget.speed =min_t (u8,USB_SPEED_HIGH , - dum->driver->speed); + dum->driver->max_speed);else dum->gadget.speed =USB_SPEED_FULL ;dummy_udc_udpate_ep0 (dum); -if (dum->gadget.speed < dum->driver->speed) +if (dum->gadget.speed < dum->driver->max_speed)dev_dbg (udc_dev (dum),"This device can perform faster" -" if you connect it to a %s port...\n" , - (dum->driver->speed ==USB_SPEED_SUPER ? -"SuperSpeed" :"HighSpeed" )); +" if you connect it to a %s port...\n" , +usb_device_speed_name (dum->driver->max_speed)); } dum_hcd =gadget_to_dummy_hcd (_gadget);
@@ -907,7 +906,7 @@ static int dummy_udc_start(struct usb_gadget *g,struct dummy_hcd *dum_hcd =gadget_to_dummy_hcd (g);struct dummy *dum = dum_hcd->dum; -if (driver->speed ==USB_SPEED_UNKNOWN ) +if (driver->max_speed ==USB_SPEED_UNKNOWN )return -EINVAL ;/*
drivers/usb/gadget/file_storage.c +2 -2
@@ -3563,9 +3563,9 @@ static void fsg_resume(struct usb_gadget *gadget)static struct usb_gadget_driver fsg_driver = { #ifdef CONFIG_USB_GADGET_DUALSPEED - .speed =USB_SPEED_HIGH , + .max_speed =USB_SPEED_HIGH , #else - .speed =USB_SPEED_FULL , + .max_speed =USB_SPEED_FULL , #endif .function = (char *) fsg_string_product, .unbind = fsg_unbind,
drivers/usb/gadget/gmidi.c +1 -1
@@ -1292,7 +1292,7 @@ static void gmidi_resume(struct usb_gadget *gadget)static struct usb_gadget_driver gmidi_driver = { - .speed =USB_SPEED_FULL , + .max_speed =USB_SPEED_FULL , .function = (char *)longname, .unbind = gmidi_unbind,
drivers/usb/gadget/goku_udc.c +1 -1
@@ -1357,7 +1357,7 @@ static int goku_start(struct usb_gadget_driver *driver,int retval;if (!driver - || driver->speed <USB_SPEED_FULL + || driver->max_speed <USB_SPEED_FULL || !bind || !driver->disconnect || !driver->setup)
drivers/usb/gadget/inode.c +3 -3
@@ -1774,9 +1774,9 @@ gadgetfs_suspend (struct usb_gadget *gadget)static struct usb_gadget_driver gadgetfs_driver = { #ifdef CONFIG_USB_GADGET_DUALSPEED - .speed =USB_SPEED_HIGH , + .max_speed =USB_SPEED_HIGH , #else - .speed =USB_SPEED_FULL , + .max_speed =USB_SPEED_FULL , #endif .function = (char *) driver_desc, .unbind = gadgetfs_unbind,
@@ -1800,7 +1800,7 @@ static int gadgetfs_probe (struct usb_gadget *gadget) }static struct usb_gadget_driver probe_driver = { - .speed =USB_SPEED_HIGH , + .max_speed =USB_SPEED_HIGH , .unbind = gadgetfs_nop, .setup = (void *)gadgetfs_nop, .disconnect = gadgetfs_nop,
drivers/usb/gadget/m66592-udc.c +1 -1
@@ -1482,7 +1482,7 @@ static int m66592_start(struct usb_gadget_driver *driver,int retval;if (!driver - || driver->speed !=USB_SPEED_HIGH + || driver->max_speed !=USB_SPEED_HIGH || !bind || !driver->setup)return -EINVAL ;
drivers/usb/gadget/net2272.c +1 -1
@@ -1461,7 +1461,7 @@ static int net2272_start(struct usb_gadget_driver *driver,unsigned i;if (!driver || !bind || !driver->unbind || !driver->setup || - driver->speed !=USB_SPEED_HIGH ) + driver->max_speed !=USB_SPEED_HIGH )return -EINVAL ;if (!dev)return -ENODEV ;
drivers/usb/gadget/net2280.c +1 -1
@@ -1892,7 +1892,7 @@ static int net2280_start(struct usb_gadget_driver *driver,* "must not be used in normal operation" */ if (!driver - || driver->speed !=USB_SPEED_HIGH + || driver->max_speed !=USB_SPEED_HIGH || !bind || !driver->setup)return -EINVAL ;if (!dev)
drivers/usb/gadget/pch_udc.c +1 -1
@@ -2701,7 +2701,7 @@ static int pch_udc_start(struct usb_gadget_driver *driver,struct pch_udc_dev *dev = pch_udc;int retval; -if (!driver || (driver->speed ==USB_SPEED_UNKNOWN ) || !bind || +if (!driver || (driver->max_speed ==USB_SPEED_UNKNOWN ) || !bind || !driver->setup || !driver->unbind || !driver->disconnect) {dev_err (&dev->pdev->dev,"%s: invalid driver parameter\n" , __func__);
drivers/usb/gadget/printer.c +1 -1
@@ -1552,7 +1552,7 @@ fail:/*-------------------------------------------------------------------------*/ static struct usb_gadget_driver printer_driver = { - .speed =DEVSPEED , + .max_speed =DEVSPEED , .function = (char *) driver_desc, .unbind = printer_unbind,
drivers/usb/gadget/r8a66597-udc.c +1 -1
@@ -1442,7 +1442,7 @@ static int r8a66597_start(struct usb_gadget_driver *driver,int retval;if (!driver - || driver->speed !=USB_SPEED_HIGH + || driver->max_speed !=USB_SPEED_HIGH || !bind || !driver->setup)return -EINVAL ;
include/linux/usb/gadget.h +2 -2
@@ -760,7 +760,7 @@ static inline int usb_gadget_disconnect(struct usb_gadget *gadget)/** * struct usb_gadget_driver - driver for usb 'slave' devices * @function: String describing the gadget's function -* @speed: Highest speed the driver handles. +* @max_speed: Highest speed the driver handles. * @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
@@ -824,7 +824,7 @@ static inline int usb_gadget_disconnect(struct usb_gadget *gadget)*/ struct usb_gadget_driver {char *function; -enum usb_device_speed speed; +enum usb_device_speed max_speed;void (*unbind)(struct usb_gadget *);int (*setup)(struct usb_gadget *,const struct usb_ctrlrequest *);
Signature · 1 line
1.7.3.1
Re: [PATCHv3 3/4] usb: gadget: rename usb_gadget_driver::speed to max_speed
Quoted 7 lines · Michal Nazarewicz
From: Michal Nazarewicz <[email protected]>
This commit renames the “speed” field of the
usb_gadget_driver
structure to “max_speed”. This is so that to make it more apparent that the field represents the maximum speed gadget driver can support.
Quoted 8 lines
This also make the field look more like fields with the same name in
usb_gadgetandusb_composite_driverstructures. All of those represent the *maximal* speed given entity supports.After this commit, there are the following fields in various structures:
*usb_gadget::speed- the current connection speed,
*usb_gadget::max_speed- maximal speed UDC supports,
this will be handled inside the UDC itself, so why do you need to expose it ?
Quoted 56 lines
*
usb_gadget_driver::max_speed- maximal speed gadget driver supports, and
*usb_composite_driver::max_speed- maximal speed composite gadget supports.Signed-off-by Michal Nazarewicz <[email protected]>--- drivers/usb/gadget/amd5536udc.c | 2 +- drivers/usb/gadget/ci13xxx_udc.c | 2 +- drivers/usb/gadget/composite.c | 8 ++++---- drivers/usb/gadget/dbgp.c | 2 +- drivers/usb/gadget/dummy_hcd.c | 13 ++++++------- drivers/usb/gadget/file_storage.c | 4 ++-- drivers/usb/gadget/gmidi.c | 2 +- drivers/usb/gadget/goku_udc.c | 2 +- drivers/usb/gadget/inode.c | 6 +++--- drivers/usb/gadget/m66592-udc.c | 2 +- drivers/usb/gadget/net2272.c | 2 +- drivers/usb/gadget/net2280.c | 2 +- drivers/usb/gadget/pch_udc.c | 2 +- drivers/usb/gadget/printer.c | 2 +- drivers/usb/gadget/r8a66597-udc.c | 2 +- include/linux/usb/gadget.h | 4 ++-- 16 files changed, 28 insertions(+), 29 deletions(-)drivers/usb/gadget/amd5536udc.c +1
-1@@ -1968,7 +1968,7 @@ static int amd5536_start(struct usb_gadget_driver *driver,u32 tmp;if (!driver || !bind || !driver->setup - || driver->speed !=USB_SPEED_HIGH ) + || driver->max_speed !=USB_SPEED_HIGH )return -EINVAL ;if (!dev)return -ENODEV ;drivers/usb/gadget/ci13xxx_udc.c +1
-1@@ -798,7 +798,7 @@ static ssize_t show_driver(struct device *dev, struct device_attribute *attr, n +=scnprintf (buf + n,PAGE_SIZE - n,"function = %s\n" , (driver->function ? driver->function :"" )); n +=scnprintf (buf + n,PAGE_SIZE - n,"max speed = %d\n" , - driver->speed); + driver->max_speed);return n; }drivers/usb/gadget/composite.c +0
-0
drivers/usb/gadget/composite.c composite_resume(struct usb_gadget *gadget) · line 1565
Quoted 8 lines
drivers/usb/gadget/composite.c +2
-2@@ -1560,9 +1560,9 @@ composite_resume(struct usb_gadget *gadget)static struct usb_gadget_driver composite_driver = { #ifdef CONFIG_USB_GADGET_SUPERSPEED - .speed =USB_SPEED_SUPER , + .max_speed =USB_SPEED_SUPER , #else - .speed = USB_SPEED_HIGH, + .max_speed = USB_SPEED_HIGH,
by doing this based on what the function drivers tell you, you could drop this ifdeferry.
Signature · 1 line
balbi
Re: [PATCHv3 3/4] usb: gadget: rename usb_gadget_driver::speed to max_speed
Quoted 12 lines · Felipe Balbi
Quoted 11 lines · Michal Nazarewicz
From: Michal Nazarewicz <[email protected]>
This commit renames the “speed” field of the
usb_gadget_driver
structure to “max_speed”. This is so that to make it more apparent that the field represents the maximum speed gadget driver can support.This also make the field look more like fields with the same name in
usb_gadgetandusb_composite_driverstructures. All of those represent the *maximal* speed given entity supports.
Quoted 7 lines
Quoted 4 lines
After this commit, there are the following fields in various structures:
*usb_gadget::speed- the current connection speed,
*usb_gadget::max_speed- maximal speed UDC supports,this will be handled inside the UDC itself, so why do you need to expose it ?
I wondered about this too. It turns out that sometimes the gadget driver really does need to know about the maximum speed supported by the UDC hardware and driver.
For example, suppose the gadget driver and the UDC both support high speed, but the gadget is currently plugged into a USB-1.1 controller and therefore running only at full speed. Then the gadget driver has to respond to the Get-Device-Qualifier and Get-Other-Speed-Config requests by sending the appropriate descriptors. But if the UDC doesn't support high speed operation then the gadget driver has to respond to those requests with a STALL.
Alan Stern
Re: [PATCHv3 3/4] usb: gadget: rename usb_gadget_driver::speed to max_speed
Hi,
Quoted 26 lines · Alan Stern
Quoted 12 lines · Felipe Balbi
Quoted 11 lines · Michal Nazarewicz
From: Michal Nazarewicz <[email protected]>
This commit renames the “speed” field of the
usb_gadget_driver
structure to “max_speed”. This is so that to make it more apparent that the field represents the maximum speed gadget driver can support.This also make the field look more like fields with the same name in
usb_gadgetandusb_composite_driverstructures. All of those represent the *maximal* speed given entity supports.Quoted 7 lines
Quoted 4 lines
After this commit, there are the following fields in various structures:
*usb_gadget::speed- the current connection speed,
*usb_gadget::max_speed- maximal speed UDC supports,this will be handled inside the UDC itself, so why do you need to expose it ?
I wondered about this too. It turns out that sometimes the gadget driver really does need to know about the maximum speed supported by the UDC hardware and driver.
Quoted 7 lines
For example, suppose the gadget driver and the UDC both support high speed, but the gadget is currently plugged into a USB-1.1 controller and therefore running only at full speed. Then the gadget driver has to respond to the Get-Device-Qualifier and Get-Other-Speed-Config requests by sending the appropriate descriptors. But if the UDC doesn't support high speed operation then the gadget driver has to respond to those requests with a STALL.
aa, good point :-)
Signature · 1 line
balbi
PATCH v3 4/4 usb: gadget: get rid of USB_GADGET_{DUAL,SUPER}SPEED
In reply to Michal NazarewiczFrom: Michal Nazarewicz <[email protected]>
This commit removes USB_GADGET_DUALSPEED and USB_GADGET_SUPERSPEED Kconfig options. Since now kernel allows many UDC drivers to be compiled, those options may turn to no longer be valid. For instance, if someone decides to build UDC that supports super speed and UDC that supports high speed only, the latter will be "assumed" to support super speed since USB_GADGET_SUPERSPEED will be selected by the former.
The test of whether CONFIG_USB_GADGET_*SPEED was defined was just an optimisation which removed otherwise dead code (ie. if UDC is not dual speed, there is no need to handle cases that can happen if speed is high). This commit removes those checks.
--- drivers/usb/gadget/Kconfig | 30 ---------------------------- drivers/usb/gadget/composite.c | 9 +------- drivers/usb/gadget/dummy_hcd.c | 2 +- drivers/usb/gadget/file_storage.c | 4 --- drivers/usb/gadget/inode.c | 10 --------- drivers/usb/gadget/printer.c | 39 ++++-------------------------------- drivers/usb/gadget/u_ether.c | 7 ------ include/linux/usb/gadget.h | 19 +---------------- 8 files changed, 9 insertions(+), 111 deletions(-)
drivers/usb/gadget/Kconfig +0 -30
@@ -133,7 +133,6 @@ config USB_AT91 config USB_ATMEL_USBA tristate "Atmel USBA" - select USB_GADGET_DUALSPEED depends on AVR32 || ARCH_AT91CAP9 || ARCH_AT91SAM9RL || ARCH_AT91SAM9G45 help USBA is the integrated high-speed USB Device controller on
@@ -142,7 +141,6 @@ config USB_ATMEL_USBA config USB_FSL_USB2 tristate "Freescale Highspeed USB DR Peripheral Controller" depends on FSL_SOC || ARCH_MXC - select USB_GADGET_DUALSPEED select USB_FSL_MPH_DR_OF if OF help Some of Freescale PowerPC processors have a High Speed
@@ -158,7 +156,6 @@ config USB_FSL_USB2 config USB_FUSB300 tristate "Faraday FUSB300 USB Peripheral Controller" depends on !PHYS_ADDR_T_64BIT - select USB_GADGET_DUALSPEED help Faraday usb device controller FUSB300 driver
@@ -206,7 +203,6 @@ config USB_PXA25X_SMALL config USB_R8A66597 tristate "Renesas R8A66597 USB Peripheral Controller" - select USB_GADGET_DUALSPEED help R8A66597 is a discrete USB host and peripheral controller chip that supports both full and high speed USB 2.0 data transfers.
@@ -220,7 +216,6 @@ config USB_RENESAS_USBHS_UDC tristate 'Renesas USBHS controller' depends on SUPERH || ARCH_SHMOBILE depends on USB_RENESAS_USBHS - select USB_GADGET_DUALSPEED help Renesas USBHS is a discrete USB host and peripheral controller chip that supports both full and high speed USB 2.0 data transfers.
@@ -249,7 +244,6 @@ config USB_S3C_HSOTG tristate "S3C HS/OtG USB Device controller" depends on S3C_DEV_USB_HSOTG select USB_GADGET_S3C_HSOTG_PIO - select USB_GADGET_DUALSPEED help The Samsung S3C64XX USB2.0 high-speed gadget controller integrated into the S3C64XX series SoC.
@@ -287,7 +281,6 @@ config USB_S3C2410_DEBUG config USB_S3C_HSUDC tristate "S3C2416, S3C2443 and S3C2450 USB Device Controller" depends on ARCH_S3C2410 - select USB_GADGET_DUALSPEED help Samsung's S3C2416, S3C2443 and S3C2450 is an ARM9 based SoC integrated with dual speed USB 2.0 device controller. It has
@@ -298,7 +291,6 @@ config USB_S3C_HSUDC config USB_PXA_U2O tristate "PXA9xx Processor USB2.0 controller" depends on ARCH_MMP - select USB_GADGET_DUALSPEED help PXA9xx Processor series include a high speed USB2.0 device controller, which support high speed and full speed USB peripheral.
@@ -311,14 +303,12 @@ config USB_PXA_U2O config USB_GADGET_MUSB_HDRC tristate "Inventra HDRC USB Peripheral (TI, ADI, ...)" depends on USB_MUSB_HDRC - select USB_GADGET_DUALSPEED help This OTG-capable silicon IP is used in dual designs including the TI DaVinci, OMAP 243x, OMAP 343x, TUSB 6010, and ADI Blackfin config USB_M66592 tristate "Renesas M66592 USB Peripheral Controller" - select USB_GADGET_DUALSPEED help M66592 is a discrete USB peripheral controller chip that supports both full and high speed USB 2.0 data transfers.
@@ -335,7 +325,6 @@ config USB_M66592 config USB_AMD5536UDC tristate "AMD5536 UDC" depends on PCI - select USB_GADGET_DUALSPEED help The AMD5536 UDC is part of the AMD Geode CS5536, an x86 southbridge. It is a USB Highspeed DMA capable USB device controller. Beside ep0
@@ -363,7 +352,6 @@ config USB_FSL_QE config USB_CI13XXX_PCI tristate "MIPS USB CI13xxx PCI UDC" depends on PCI - select USB_GADGET_DUALSPEED help MIPS USB IP core family device controller Currently it only supports IP part number CI13412
@@ -374,7 +362,6 @@ config USB_CI13XXX_PCI config USB_NET2272 tristate "PLX NET2272" - select USB_GADGET_DUALSPEED help PLX NET2272 is a USB peripheral controller which supports both full and high speed USB 2.0 data transfers.
@@ -398,7 +385,6 @@ config USB_NET2272_DMA config USB_NET2280 tristate "NetChip 228x" depends on PCI - select USB_GADGET_DUALSPEED help NetChip 2280 / 2282 is a PCI based USB peripheral controller which supports both full and high speed USB 2.0 data transfers.
@@ -429,7 +415,6 @@ config USB_LANGWELL tristate "Intel Langwell USB Device Controller" depends on PCI depends on !PHYS_ADDR_T_64BIT - select USB_GADGET_DUALSPEED help Intel Langwell USB Device Controller is a High-Speed USB On-The-Go device controller.
@@ -444,7 +429,6 @@ config USB_LANGWELL config USB_EG20T tristate "Intel EG20T PCH/OKI SEMICONDUCTOR ML7213 IOH UDC" depends on PCI - select USB_GADGET_DUALSPEED help This is a USB device driver for EG20T PCH. EG20T PCH is the platform controller hub that is used in Intel's
@@ -466,7 +450,6 @@ config USB_EG20T config USB_CI13XXX_MSM tristate "MIPS USB CI13xxx for MSM" depends on ARCH_MSM - select USB_GADGET_DUALSPEED select USB_MSM_OTG help MSM SoC has chipidea USB controller. This driver uses
@@ -487,8 +470,6 @@ config USB_CI13XXX_MSM config USB_DUMMY_HCD tristate "Dummy HCD (DEVELOPMENT)" depends on USB=y || (USB=m && USB_GADGET=m) - select USB_GADGET_DUALSPEED - select USB_GADGET_SUPERSPEED help This host controller driver emulates USB, looping all data transfer requests back to a USB "gadget driver" in the same host. The host
@@ -513,17 +494,6 @@ config USB_DUMMY_HCD endchoice -# Selected by UDC drivers that support high-speed operation. -config USB_GADGET_DUALSPEED - bool - depends on USB_GADGET - -# Selected by UDC drivers that support super-speed opperation -config USB_GADGET_SUPERSPEED - bool - depends on USB_GADGET - depends on USB_GADGET_DUALSPEED - # # USB Gadget Drivers #
drivers/usb/gadget/composite.c +1 -8
@@ -1559,12 +1559,6 @@ composite_resume(struct usb_gadget *gadget)/*-------------------------------------------------------------------------*/ static struct usb_gadget_driver composite_driver = { -#ifdef CONFIG_USB_GADGET_SUPERSPEED - .max_speed =USB_SPEED_SUPER , -#else - .max_speed =USB_SPEED_HIGH , -#endif - .unbind = composite_unbind, .setup = composite_setup,
@@ -1609,8 +1603,7 @@ int usb_composite_probe(struct usb_composite_driver *driver, driver->iProduct = driver->name; composite_driver.function = (char *) driver->name; composite_driver.driver.name = driver->name; - composite_driver.max_speed =min ((u8 )composite_driver.max_speed, - (u8 )driver->max_speed); + composite_driver.max_speed = driver->max_speed; composite = driver; composite_gadget_bind = bind;
drivers/usb/gadget/dummy_hcd.c +1 -1
@@ -985,7 +985,7 @@ static int dummy_udc_probe (struct platform_device *pdev) dum->gadget.name = gadget_name; dum->gadget.ops = &dummy_ops; - dum->gadget.max_speed =USB_SPEED_SUPER ;; + dum->gadget.max_speed =USB_SPEED_SUPER ;dev_set_name (&dum->gadget.dev,"gadget" ); dum->gadget.dev.parent = &pdev->dev;
drivers/usb/gadget/file_storage.c +0 -4
@@ -3562,11 +3562,7 @@ static void fsg_resume(struct usb_gadget *gadget)/*-------------------------------------------------------------------------*/ static struct usb_gadget_driver fsg_driver = { -#ifdef CONFIG_USB_GADGET_DUALSPEED .max_speed =USB_SPEED_HIGH , -#else - .max_speed =USB_SPEED_FULL , -#endif .function = (char *) fsg_string_product, .unbind = fsg_unbind, .disconnect = fsg_disconnect,
drivers/usb/gadget/inode.c +0 -10
@@ -837,7 +837,6 @@ ep_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)if (value ==0 ) data->state =STATE_EP_ENABLED ;break ; -#ifdef CONFIG_USB_GADGET_DUALSPEED case USB_SPEED_HIGH :/* fails if caller didn't provide that descriptor... */ ep->desc = &data->hs_desc;
@@ -845,7 +844,6 @@ ep_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)if (value ==0 ) data->state =STATE_EP_ENABLED ;break ; -#endif default :DBG (data->dev,"unconnected, %s init abandoned\n" , data->name);
@@ -1331,7 +1329,6 @@ static const struct file_operations ep0_io_operations = {* Unrecognized ep0 requests may be handled in user space. */ -#ifdef CONFIG_USB_GADGET_DUALSPEED static void make_qualifier (struct dev_data *dev) {struct usb_qualifier_descriptor qual;
@@ -1354,7 +1351,6 @@ static void make_qualifier (struct dev_data *dev)memcpy (dev->rbuf, &qual,sizeof qual); } -#endif static int config_buf (struct dev_data *dev,u8 type,unsigned index)
@@ -1434,7 +1430,6 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) dev->dev->bMaxPacketSize0 = dev->gadget->ep0->maxpacket; req->buf = dev->dev;break ; -#ifdef CONFIG_USB_GADGET_DUALSPEED case USB_DT_DEVICE_QUALIFIER :if (!dev->hs_config)break ;
@@ -1444,7 +1439,6 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)break ;case USB_DT_OTHER_SPEED_CONFIG :// FALLTHROUGH -#endif case USB_DT_CONFIG : value = config_buf (dev, w_value >> 8,
@@ -1773,11 +1767,7 @@ gadgetfs_suspend (struct usb_gadget *gadget) }static struct usb_gadget_driver gadgetfs_driver = { -#ifdef CONFIG_USB_GADGET_DUALSPEED .max_speed =USB_SPEED_HIGH , -#else - .max_speed =USB_SPEED_FULL , -#endif .function = (char *) driver_desc, .unbind = gadgetfs_unbind, .setup = gadgetfs_setup,
drivers/usb/gadget/printer.c +5 -34
@@ -164,12 +164,6 @@ module_param(qlen, uint, S_IRUGO|S_IWUSR);#define QLEN qlen -#ifdef CONFIG_USB_GADGET_DUALSPEED -#define DEVSPEED USB_SPEED_HIGH -#else /* full speed (low speed doesn't do bulk) */ -#define DEVSPEED USB_SPEED_FULL -#endif -/*-------------------------------------------------------------------------*/ #define xprintk(d, level, fmt, args...) \
@@ -288,8 +282,6 @@ static const struct usb_descriptor_header *fs_printer_function [11] = { NULL }; -#ifdef CONFIG_USB_GADGET_DUALSPEED -/* * usb 2.0 devices need to expose both high speed and full speed * descriptors, unless they only run at full speed.
@@ -328,13 +320,6 @@ static const struct usb_descriptor_header *hs_printer_function [11] = {/* maxpacket and other transfer characteristics vary by speed. */ #define ep_desc (g, hs, fs) (((g)->speed == USB_SPEED_HIGH)?(hs):(fs)) -#else - -/* if there's no high speed support, maxpacket doesn't change. */ -#define ep_desc (g, hs, fs) (((void)(g)), (fs)) - -#endif /* !CONFIG_USB_GADGET_DUALSPEED */ -/*-------------------------------------------------------------------------*/ /* descriptors that are built on-demand */
@@ -979,9 +964,7 @@ printer_set_config(struct printer_dev *dev, unsigned number)switch (gadget->speed) {case USB_SPEED_FULL : speed ="full" ;break ; -#ifdef CONFIG_USB_GADGET_DUALSPEED case USB_SPEED_HIGH : speed ="high" ;break ; -#endif default : speed ="?" ;break ; }
@@ -998,23 +981,15 @@ config_buf(enum usb_device_speed speed, u8 *buf, u8 type, unsigned index, {int len;const struct usb_descriptor_header **function; -#ifdef CONFIG_USB_GADGET_DUALSPEED int hs = (speed ==USB_SPEED_HIGH ); +if (index >= device_desc.bNumConfigurations) +return -EINVAL ; +if (type ==USB_DT_OTHER_SPEED_CONFIG ) hs = !hs; -if (hs) { - function = hs_printer_function; - }else { - function = fs_printer_function; - } -#else - function = fs_printer_function; -#endif - -if (index >= device_desc.bNumConfigurations) -return -EINVAL ; + function = hs ? hs_printer_function : fs_printer_function;/* for now, don't advertise srp-only devices */ if (!is_otg)
@@ -1156,7 +1131,6 @@ printer_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) value =min (wLength, (u16 )sizeof device_desc);memcpy (req->buf, &device_desc, value);break ; -#ifdef CONFIG_USB_GADGET_DUALSPEED case USB_DT_DEVICE_QUALIFIER :if (!gadget_is_dualspeed (gadget))break ;
@@ -1175,7 +1149,6 @@ printer_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)if (!gadget_is_dualspeed (gadget))break ;/* FALLTHROUGH */ -#endif /* CONFIG_USB_GADGET_DUALSPEED */ case USB_DT_CONFIG : value = config_buf(gadget->speed, req->buf, wValue >> 8,
@@ -1460,11 +1433,9 @@ autoconf_fail: goto autoconf_fail; out_ep->driver_data = out_ep;/* claim */ -#ifdef CONFIG_USB_GADGET_DUALSPEED /* assumes that all endpoints are dual-speed */ hs_ep_in_desc.bEndpointAddress = fs_ep_in_desc.bEndpointAddress; hs_ep_out_desc.bEndpointAddress = fs_ep_out_desc.bEndpointAddress; -#endif /* DUALSPEED */ usb_gadget_set_selfpowered (gadget);
@@ -1552,7 +1523,7 @@ fail:/*-------------------------------------------------------------------------*/ static struct usb_gadget_driver printer_driver = { - .max_speed =DEVSPEED , + .max_speed =USB_SPEED_HIGH , .function = (char *) driver_desc, .unbind = printer_unbind,
drivers/usb/gadget/u_ether.c +0 -7
@@ -92,17 +92,10 @@ struct eth_dev {#define DEFAULT_QLEN 2/* double buffering by default */ - -#ifdef CONFIG_USB_GADGET_DUALSPEED -static unsigned qmult =5 ;module_param (qmult, uint,S_IRUGO |S_IWUSR );MODULE_PARM_DESC (qmult,"queue length multiplier at high/super speed" ); -#else /* full speed (low speed doesn't do bulk) */ -#define qmult 1 -#endif -/* for dual-speed hardware, use deeper queues at high/super speed */ static inline int qlen (struct usb_gadget *gadget) {
include/linux/usb/gadget.h +2 -17
@@ -548,14 +548,7 @@ static inline struct usb_gadget *dev_to_usb_gadget(struct device *dev)*/ static inline int gadget_is_dualspeed (struct usb_gadget *g) { -#ifdef CONFIG_USB_GADGET_DUALSPEED -/* runtime test would check "g->max_speed" ... that might be -* useful to work around hardware bugs, but is mostly pointless -*/ -return 1 ; -#else -return 0 ; -#endif +return g->max_speed >=USB_SPEED_HIGH ; }/**
@@ -565,15 +558,7 @@ static inline int gadget_is_dualspeed(struct usb_gadget *g)*/ static inline int gadget_is_superspeed (struct usb_gadget *g) { -#ifdef CONFIG_USB_GADGET_SUPERSPEED -/* -* runtime test would check "g->max_speed" ... that might be -* useful to work around hardware bugs, but is mostly pointless -*/ -return 1 ; -#else -return 0 ; -#endif +return g->max_speed >=USB_SPEED_SUPER ; }/**
Signature · 1 line
1.7.3.1
Re: [PATCHv3 4/4] usb: gadget: get rid of USB_GADGET_{DUAL,SUPER}SPEED
Quoted 16 lines · Michal Nazarewicz
From: Michal Nazarewicz <[email protected]>
This commit removes
USB_GADGET_DUALSPEEDandUSB_GADGET_SUPERSPEEDKconfigoptions. Since now kernel allows many UDC drivers to be compiled, those options may turn to no longer be valid. For instance, if someone decides to build UDC that supports super speed and UDC that supports high speed only, the latter will be "assumed" to support super speed sinceUSB_GADGET_SUPERSPEEDwill be selected by the former.The test of whether CONFIG_USB_GADGET_*SPEED was defined was just an optimisation which removed otherwise dead code (ie. if UDC is not dual speed, there is no need to handle cases that can happen if speed is high). This commit removes those checks.
Signed-off-by Michal Nazarewicz <[email protected]>
...
drivers/usb/gadget/dummy_hcd.c static int dummy_udc_probe (struct platform_device *pdev) · line 988
Quoted 8 lines
drivers/usb/gadget/dummy_hcd.c +1
-1@@ -985,7 +985,7 @@ static int dummy_udc_probe (struct platform_device *pdev) dum->gadget.name = gadget_name; dum->gadget.ops = &dummy_ops; - dum->gadget.max_speed =USB_SPEED_SUPER ;; + dum->gadget.max_speed =USB_SPEED_SUPER ;
You might as well get this right in patch 2/4. Then this hunk wouldn't be needed.
Quoted 2 lines
drivers/usb/gadget/inode.c +0
-0
...
drivers/usb/gadget/inode.c gadgetfs_suspend (struct usb_gadget *gadget) · line 1780
Quoted 9 lines
drivers/usb/gadget/inode.c +0
-4@@ -1773,11 +1767,7 @@ gadgetfs_suspend (struct usb_gadget *gadget) }static struct usb_gadget_driver gadgetfs_driver = { -#ifdef CONFIG_USB_GADGET_DUALSPEED .max_speed =USB_SPEED_HIGH , -#else - .max_speed =USB_SPEED_FULL , -#endif
I'm not sure that a static definition is correct here. The actual max_speed depends on what descriptors the userspace program sends. Take a look at the ep_config() routine.
Alan Stern
Re: [PATCHv3 4/4] usb: gadget: get rid of USB_GADGET_{DUAL,SUPER}SPEED
Quoted 10 lines · Michal Nazarewicz
Quoted 9 lines
drivers/usb/gadget/dummy_hcd.c +1
-1@@ -985,7 +985,7 @@ static int dummy_udc_probe (struct platform_device *pdev) dum->gadget.name = gadget_name; dum->gadget.ops = &dummy_ops; - dum->gadget.max_speed =USB_SPEED_SUPER ;; + dum->gadget.max_speed =USB_SPEED_SUPER ;
Quoted 2 lines · Alan Stern
You might as well get this right in patch 2/4. Then this hunk wouldn't be needed.
Sorry about that, I've fixuped the wrong commit
Quoted 6 lines
Quoted 2 lines
drivers/usb/gadget/inode.c +0
-0...
Quoted 3 lines
drivers/usb/gadget/inode.c +0
-0@@ -1773,11 +1767,7 @@ gadgetfs_suspend (struct usb_gadget *gadget) }
Quoted 10 lines
drivers/usb/gadget/inode.c gadgetfs_suspend (struct usb_gadget *gadget) · line 1780
Quoted 6 lines
drivers/usb/gadget/inode.c +0
-4static struct usb_gadget_driver gadgetfs_driver = { -#ifdef CONFIG_USB_GADGET_DUALSPEED .max_speed =USB_SPEED_HIGH , -#else - .max_speed =USB_SPEED_FULL , -#endifI'm not sure that a static definition is correct here. The actual
max_speeddepends on what descriptors the userspace program sends. Take a look at theep_config()routine.
Good catch. I've changed it to:
if (dev->hs_config)
gadgetfs_driver.max_speed = USB_SPEED_HIGH; else gadgetfs_driver.max_speed = USB_SPEED_FULL;
just before usb_gadget_probe_driver(), which should do the trick.
Signature · 4 lines
Best regards, _ _ .o. | Liege of Serenely Enlightened Majesty of o' \,=./ `o ..o | Computer Science, Michal "mina86" Nazarewicz (o o) ooo +-----<email/xmpp: [email protected]>-----ooO--(_)--Ooo--
Re: [PATCHv3 4/4] usb: gadget: get rid of USB_GADGET_{DUAL,SUPER}SPEED
Quoted 17 lines · Michal Nazarewicz
Quoted 6 lines
Quoted 2 lines
drivers/usb/gadget/inode.c +0
-0...
Quoted 3 lines
drivers/usb/gadget/inode.c +0
-0@@ -1773,11 +1767,7 @@ gadgetfs_suspend (struct usb_gadget *gadget) }Quoted 10 lines
drivers/usb/gadget/inode.c gadgetfs_suspend (struct usb_gadget *gadget) · line 1780
Quoted 6 lines
drivers/usb/gadget/inode.c +0
-4static struct usb_gadget_driver gadgetfs_driver = { -#ifdef CONFIG_USB_GADGET_DUALSPEED .max_speed =USB_SPEED_HIGH , -#else - .max_speed =USB_SPEED_FULL , -#endifI'm not sure that a static definition is correct here. The actual
max_speeddepends on what descriptors the userspace program sends. Take a look at theep_config()routine.
Quoted 8 lines
Good catch. I've changed it to:
if (
dev->hs_config)gadgetfs_driver.max_speed = USB_SPEED_HIGH; else gadgetfs_driver.max_speed = USB_SPEED_FULL;just before
usb_gadget_probe_driver(), which should do the trick.
Yes, that sounds like the right thing to do.
Alan Stern