usb: gadget: remove usb_gadget_controller_number()

The bcdDevice field is defined as
|Device release number in binary-coded decimal
in the USB 2.0 specification. We use this field to distinguish the UDCs
from each other. In theory this could be used on the host side to apply
certain quirks if the "special" UDC in combination with this gadget is
used. This hasn't been done as far as I am aware. In practice it would
be better to fix the UDC driver before shipping since a later release
might not need this quirk anymore.

There are some driver in tree (on the host side) which use the bcdDevice
field to figure out special workarounds for a given firmware revision.
This seems to make sense. Therefore this patch converts all gadgets
(except a few) to use the kernel version instead a random 2 or 3 plus
the UDC number. The few that don't report kernel's version are:
- webcam
  This one reports always a version 0x10 so allow it to do so in future.
- nokia
  This one reports always 0x211. The comment says that this gadget works
  only if the UDC supports altsettings so I added a check for this.
- serial
  This one reports 0x2400 + UDC number. Since the gadget version is 2.4
  this could make sense. Therefore bcdDevice is 0x2400 here.

I also remove various gadget_is_<name> macros which are unused. The
remaining few macros should be moved to feature / bug bitfield.

Acked-by: Michal Nazarewicz <mina86@mina86.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Felipe Balbi <balbi@ti.com>
This commit is contained in:
Sebastian Andrzej Siewior 2012-09-10 09:16:07 +02:00 committed by Felipe Balbi
parent 9c6d196d5a
commit ed9cbda63d
19 changed files with 24 additions and 311 deletions

View File

@ -6,7 +6,7 @@ ccflags-$(CONFIG_USB_GADGET_DEBUG) := -DDEBUG
obj-$(CONFIG_USB_GADGET) += udc-core.o
obj-$(CONFIG_USB_LIBCOMPOSITE) += libcomposite.o
libcomposite-y := usbstring.o config.o epautoconf.o
libcomposite-y += gadget_chips.o composite.o
libcomposite-y += composite.o
obj-$(CONFIG_USB_DUMMY_HCD) += dummy_hcd.o
obj-$(CONFIG_USB_NET2272) += net2272.o
obj-$(CONFIG_USB_NET2280) += net2280.o

View File

@ -148,7 +148,6 @@ static struct usb_configuration acm_ms_config_driver = {
static int __init acm_ms_bind(struct usb_composite_dev *cdev)
{
int gcnum;
struct usb_gadget *gadget = cdev->gadget;
int status;
void *retp;
@ -165,18 +164,6 @@ static int __init acm_ms_bind(struct usb_composite_dev *cdev)
goto fail0;
}
/* set bcdDevice */
gcnum = usb_gadget_controller_number(gadget);
if (gcnum >= 0) {
device_desc.bcdDevice = cpu_to_le16(0x0300 | gcnum);
} else {
WARNING(cdev, "controller '%s' not recognized; trying %s\n",
gadget->name,
acm_ms_config_driver.label);
device_desc.bcdDevice =
cpu_to_le16(0x0300 | 0x0099);
}
/*
* Allocate string descriptor numbers ... note that string
* contents can be overridden by the composite_dev glue.

View File

@ -135,20 +135,8 @@ static struct usb_configuration audio_config_driver = {
static int __init audio_bind(struct usb_composite_dev *cdev)
{
int gcnum;
int status;
gcnum = usb_gadget_controller_number(cdev->gadget);
if (gcnum >= 0)
device_desc.bcdDevice = cpu_to_le16(0x0300 | gcnum);
else {
ERROR(cdev, "controller '%s' not recognized; trying %s\n",
cdev->gadget->name,
audio_config_driver.label);
device_desc.bcdDevice =
__constant_cpu_to_le16(0x0300 | 0x0099);
}
status = usb_string_ids_tab(cdev, strings_dev);
if (status < 0)
goto fail;

View File

@ -143,7 +143,6 @@ static struct usb_configuration cdc_config_driver = {
static int __init cdc_bind(struct usb_composite_dev *cdev)
{
int gcnum;
struct usb_gadget *gadget = cdev->gadget;
int status;
@ -163,21 +162,6 @@ static int __init cdc_bind(struct usb_composite_dev *cdev)
if (status < 0)
goto fail0;
gcnum = usb_gadget_controller_number(gadget);
if (gcnum >= 0)
device_desc.bcdDevice = cpu_to_le16(0x0300 | gcnum);
else {
/* We assume that can_support_ecm() tells the truth;
* but if the controller isn't recognized at all then
* that assumption is a bit more likely to be wrong.
*/
WARNING(cdev, "controller '%s' not recognized; trying %s\n",
gadget->name,
cdc_config_driver.label);
device_desc.bcdDevice =
cpu_to_le16(0x0300 | 0x0099);
}
/* Allocate string descriptor numbers ... note that string
* contents can be overridden by the composite_dev glue.
*/

View File

@ -1389,6 +1389,8 @@ static void update_unchanged_dev_desc(struct usb_device_descriptor *new,
new->idProduct = idProduct;
if (bcdDevice)
new->bcdDevice = bcdDevice;
else
new->bcdDevice = cpu_to_le16(get_default_bcdDevice());
if (iSerialNumber)
new->iSerialNumber = iSerialNumber;
if (iManufacturer)

View File

@ -275,7 +275,6 @@ static struct usb_configuration eth_config_driver = {
static int __init eth_bind(struct usb_composite_dev *cdev)
{
int gcnum;
struct usb_gadget *gadget = cdev->gadget;
int status;
@ -310,22 +309,6 @@ static int __init eth_bind(struct usb_composite_dev *cdev)
device_desc.bNumConfigurations = 2;
}
gcnum = usb_gadget_controller_number(gadget);
if (gcnum >= 0)
device_desc.bcdDevice = cpu_to_le16(0x0300 | gcnum);
else {
/* We assume that can_support_ecm() tells the truth;
* but if the controller isn't recognized at all then
* that assumption is a bit more likely to be wrong.
*/
dev_warn(&gadget->dev,
"controller '%s' not recognized; trying %s\n",
gadget->name,
eth_config_driver.label);
device_desc.bcdDevice =
cpu_to_le16(0x0300 | 0x0099);
}
/* Allocate string descriptor numbers ... note that string
* contents can be overridden by the composite_dev glue.
*/

View File

@ -348,7 +348,6 @@ struct fsg_config {
const char *vendor_name; /* 8 characters or less */
const char *product_name; /* 16 characters or less */
u16 release;
char can_stall;
};
@ -2772,18 +2771,7 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common,
bh->next = common->buffhds;
/* Prepare inquiryString */
if (cfg->release != 0xffff) {
i = cfg->release;
} else {
i = usb_gadget_controller_number(gadget);
if (i >= 0) {
i = 0x0300 + i;
} else {
WARNING(common, "controller '%s' not recognized\n",
gadget->name);
i = 0x0399;
}
}
i = get_default_bcdDevice();
snprintf(common->inquiry_string, sizeof common->inquiry_string,
"%-8s%-16s%04x", cfg->vendor_name ?: "Linux",
/* Assume product name dependent on the first LUN */
@ -3109,7 +3097,6 @@ fsg_config_from_params(struct fsg_config *cfg,
/* Let MSF use defaults */
cfg->vendor_name = 0;
cfg->product_name = 0;
cfg->release = 0xffff;
cfg->ops = NULL;
cfg->private_data = NULL;

View File

@ -251,6 +251,7 @@
#include <linux/freezer.h>
#include <linux/utsname.h>
#include <linux/usb/composite.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
@ -3198,7 +3199,6 @@ static void /* __init_or_exit */ fsg_unbind(struct usb_gadget *gadget)
static int __init check_parameters(struct fsg_dev *fsg)
{
int prot;
int gcnum;
/* Store the default values */
mod_data.transport_type = USB_PR_BULK;
@ -3213,16 +3213,8 @@ static int __init check_parameters(struct fsg_dev *fsg)
if (gadget_is_at91(fsg->gadget))
mod_data.can_stall = 0;
if (mod_data.release == 0xffff) { // Parameter wasn't set
gcnum = usb_gadget_controller_number(fsg->gadget);
if (gcnum >= 0)
mod_data.release = 0x0300 + gcnum;
else {
WARNING(fsg, "controller '%s' not recognized\n",
fsg->gadget->name);
mod_data.release = 0x0399;
}
}
if (mod_data.release == 0xffff)
mod_data.release = get_default_bcdDevice();
prot = simple_strtol(mod_data.protocol_parm, NULL, 0);

View File

@ -1,94 +0,0 @@
/*
* USB device controllers have lots of quirks. Use these macros in
* gadget drivers or other code that needs to deal with them, and which
* autoconfigures instead of using early binding to the hardware.
*
* This SHOULD eventually work like the ARM mach_is_*() stuff, driven by
* some config file that gets updated as new hardware is supported.
* (And avoiding all runtime comparisons in typical one-choice configs!)
*
* NOTE: some of these controller drivers may not be available yet.
* Some are available on 2.4 kernels; several are available, but not
* yet pushed in the 2.6 mainline tree.
*/
#include <linux/usb/gadget.h>
#include <linux/module.h>
#include "gadget_chips.h"
/**
* usb_gadget_controller_number - support bcdDevice id convention
* @gadget: the controller being driven
*
* Return a 2-digit BCD value associated with the peripheral controller,
* suitable for use as part of a bcdDevice value, or a negative error code.
*
* NOTE: this convention is purely optional, and has no meaning in terms of
* any USB specification. If you want to use a different convention in your
* gadget driver firmware -- maybe a more formal revision ID -- feel free.
*
* Hosts see these bcdDevice numbers, and are allowed (but not encouraged!)
* to change their behavior accordingly. For example it might help avoiding
* some chip bug.
*/
int usb_gadget_controller_number(struct usb_gadget *gadget)
{
if (gadget_is_net2280(gadget))
return 0x01;
else if (gadget_is_dummy(gadget))
return 0x02;
else if (gadget_is_pxa(gadget))
return 0x03;
else if (gadget_is_goku(gadget))
return 0x06;
else if (gadget_is_omap(gadget))
return 0x08;
else if (gadget_is_pxa27x(gadget))
return 0x11;
else if (gadget_is_s3c2410(gadget))
return 0x12;
else if (gadget_is_at91(gadget))
return 0x13;
else if (gadget_is_imx(gadget))
return 0x14;
else if (gadget_is_musbhdrc(gadget))
return 0x16;
else if (gadget_is_atmel_usba(gadget))
return 0x18;
else if (gadget_is_fsl_usb2(gadget))
return 0x19;
else if (gadget_is_amd5536udc(gadget))
return 0x20;
else if (gadget_is_m66592(gadget))
return 0x21;
else if (gadget_is_fsl_qe(gadget))
return 0x22;
else if (gadget_is_ci13xxx_pci(gadget))
return 0x23;
else if (gadget_is_langwell(gadget))
return 0x24;
else if (gadget_is_r8a66597(gadget))
return 0x25;
else if (gadget_is_s3c_hsotg(gadget))
return 0x26;
else if (gadget_is_pch(gadget))
return 0x27;
else if (gadget_is_ci13xxx_msm(gadget))
return 0x28;
else if (gadget_is_renesas_usbhs(gadget))
return 0x29;
else if (gadget_is_s3c_hsudc(gadget))
return 0x30;
else if (gadget_is_net2272(gadget))
return 0x31;
else if (gadget_is_dwc3(gadget))
return 0x32;
else if (gadget_is_lpc32xx(gadget))
return 0x33;
else if (gadget_is_bcm63xx(gadget))
return 0x34;
return -ENOENT;
}
EXPORT_SYMBOL_GPL(usb_gadget_controller_number);

View File

@ -27,35 +27,12 @@
* If you have forgotten the alphabetical order let VIM/EMACS
* do that for you.
*/
#define gadget_is_amd5536udc(g) (!strcmp("amd5536udc", (g)->name))
#define gadget_is_at91(g) (!strcmp("at91_udc", (g)->name))
#define gadget_is_atmel_usba(g) (!strcmp("atmel_usba_udc", (g)->name))
#define gadget_is_bcm63xx(g) (!strcmp("bcm63xx_udc", (g)->name))
#define gadget_is_ci13xxx_msm(g) (!strcmp("ci13xxx_msm", (g)->name))
#define gadget_is_ci13xxx_pci(g) (!strcmp("ci13xxx_pci", (g)->name))
#define gadget_is_dummy(g) (!strcmp("dummy_udc", (g)->name))
#define gadget_is_dwc3(g) (!strcmp("dwc3-gadget", (g)->name))
#define gadget_is_fsl_qe(g) (!strcmp("fsl_qe_udc", (g)->name))
#define gadget_is_fsl_usb2(g) (!strcmp("fsl-usb2-udc", (g)->name))
#define gadget_is_goku(g) (!strcmp("goku_udc", (g)->name))
#define gadget_is_imx(g) (!strcmp("imx_udc", (g)->name))
#define gadget_is_langwell(g) (!strcmp("langwell_udc", (g)->name))
#define gadget_is_lpc32xx(g) (!strcmp("lpc32xx_udc", (g)->name))
#define gadget_is_m66592(g) (!strcmp("m66592_udc", (g)->name))
#define gadget_is_musbhdrc(g) (!strcmp("musb-hdrc", (g)->name))
#define gadget_is_net2272(g) (!strcmp("net2272", (g)->name))
#define gadget_is_net2280(g) (!strcmp("net2280", (g)->name))
#define gadget_is_omap(g) (!strcmp("omap_udc", (g)->name))
#define gadget_is_pch(g) (!strcmp("pch_udc", (g)->name))
#define gadget_is_pxa(g) (!strcmp("pxa25x_udc", (g)->name))
#define gadget_is_pxa27x(g) (!strcmp("pxa27x_udc", (g)->name))
#define gadget_is_r8a66597(g) (!strcmp("r8a66597_udc", (g)->name))
#define gadget_is_renesas_usbhs(g) (!strcmp("renesas_usbhs_udc", (g)->name))
#define gadget_is_s3c2410(g) (!strcmp("s3c2410_udc", (g)->name))
#define gadget_is_s3c_hsotg(g) (!strcmp("s3c-hsotg", (g)->name))
#define gadget_is_s3c_hsudc(g) (!strcmp("s3c-hsudc", (g)->name))
int usb_gadget_controller_number(struct usb_gadget *gadget);
/**
* gadget_supports_altsettings - return true if altsettings work

View File

@ -137,8 +137,7 @@ static int __init midi_bind_config(struct usb_configuration *c)
static int __init midi_bind(struct usb_composite_dev *cdev)
{
struct usb_gadget *gadget = cdev->gadget;
int gcnum, status;
int status;
status = usb_string_ids_tab(cdev, strings_dev);
if (status < 0)
@ -147,19 +146,6 @@ static int __init midi_bind(struct usb_composite_dev *cdev)
device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id;
midi_config.iConfiguration = strings_dev[STRING_DESCRIPTION_IDX].id;
gcnum = usb_gadget_controller_number(gadget);
if (gcnum < 0) {
/* gmidi is so simple (no altsettings) that
* it SHOULD NOT have problems with bulk-capable hardware.
* so warn about unrecognized controllers, don't panic.
*/
pr_warning("%s: controller '%s' not recognized\n",
__func__, gadget->name);
device_desc.bcdDevice = cpu_to_le16(0x9999);
} else {
device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum);
}
status = usb_add_config(cdev, &midi_config, midi_bind_config);
if (status < 0)
return status;

View File

@ -143,7 +143,7 @@ static int __init hid_bind(struct usb_composite_dev *cdev)
{
struct usb_gadget *gadget = cdev->gadget;
struct list_head *tmp;
int status, gcnum, funcs = 0;
int status, funcs = 0;
list_for_each(tmp, &hidg_func_list)
funcs++;
@ -156,12 +156,6 @@ static int __init hid_bind(struct usb_composite_dev *cdev)
if (status < 0)
return status;
gcnum = usb_gadget_controller_number(gadget);
if (gcnum >= 0)
device_desc.bcdDevice = cpu_to_le16(0x0300 | gcnum);
else
device_desc.bcdDevice = cpu_to_le16(0x0300 | 0x0099);
/* Allocate string descriptor numbers ... note that string
* contents can be overridden by the composite_dev glue.
*/

View File

@ -247,7 +247,7 @@ static int cdc_config_register(struct usb_composite_dev *cdev)
static int __ref multi_bind(struct usb_composite_dev *cdev)
{
struct usb_gadget *gadget = cdev->gadget;
int status, gcnum;
int status;
if (!can_support_ecm(cdev->gadget)) {
dev_err(&gadget->dev, "controller '%s' not usable\n",
@ -275,15 +275,6 @@ static int __ref multi_bind(struct usb_composite_dev *cdev)
}
}
/* set bcdDevice */
gcnum = usb_gadget_controller_number(gadget);
if (gcnum >= 0) {
device_desc.bcdDevice = cpu_to_le16(0x0300 | gcnum);
} else {
WARNING(cdev, "controller '%s' not recognized\n", gadget->name);
device_desc.bcdDevice = cpu_to_le16(0x0300 | 0x0099);
}
/* allocate string IDs */
status = usb_string_ids_tab(cdev, strings_dev);
if (unlikely(status < 0))

View File

@ -139,7 +139,6 @@ static struct usb_configuration ncm_config_driver = {
static int __init gncm_bind(struct usb_composite_dev *cdev)
{
int gcnum;
struct usb_gadget *gadget = cdev->gadget;
int status;
@ -148,22 +147,6 @@ static int __init gncm_bind(struct usb_composite_dev *cdev)
if (status < 0)
return status;
gcnum = usb_gadget_controller_number(gadget);
if (gcnum >= 0)
device_desc.bcdDevice = cpu_to_le16(0x0300 | gcnum);
else {
/* We assume that can_support_ecm() tells the truth;
* but if the controller isn't recognized at all then
* that assumption is a bit more likely to be wrong.
*/
dev_warn(&gadget->dev,
"controller '%s' not recognized; trying %s\n",
gadget->name,
ncm_config_driver.label);
device_desc.bcdDevice =
cpu_to_le16(0x0300 | 0x0099);
}
/* Allocate string descriptor numbers ... note that string
* contents can be overridden by the composite_dev glue.
*/

View File

@ -84,6 +84,7 @@ static struct usb_device_descriptor device_desc = {
.bDeviceClass = USB_CLASS_COMM,
.idVendor = __constant_cpu_to_le16(NOKIA_VENDOR_ID),
.idProduct = __constant_cpu_to_le16(NOKIA_PRODUCT_ID),
.bcdDevice = cpu_to_le16(NOKIA_VERSION_NUM),
/* .iManufacturer = DYNAMIC */
/* .iProduct = DYNAMIC */
.bNumConfigurations = 1,
@ -145,7 +146,6 @@ static struct usb_configuration nokia_config_100ma_driver = {
static int __init nokia_bind(struct usb_composite_dev *cdev)
{
int gcnum;
struct usb_gadget *gadget = cdev->gadget;
int status;
@ -170,18 +170,8 @@ static int __init nokia_bind(struct usb_composite_dev *cdev)
nokia_config_500ma_driver.iConfiguration = status;
nokia_config_100ma_driver.iConfiguration = status;
/* set up other descriptors */
gcnum = usb_gadget_controller_number(gadget);
if (gcnum >= 0)
device_desc.bcdDevice = cpu_to_le16(NOKIA_VERSION_NUM);
else {
/* this should only work with hw that supports altsettings
* and several endpoints, anything else, panic.
*/
pr_err("nokia_bind: controller '%s' not recognized\n",
gadget->name);
if (!gadget_supports_altsettings(gadget))
goto err_usb;
}
/* finally register the configuration */
status = usb_add_config(cdev, &nokia_config_500ma_driver,

View File

@ -1101,7 +1101,6 @@ static int __init printer_bind_config(struct usb_configuration *c)
struct usb_gadget *gadget = c->cdev->gadget;
struct printer_dev *dev;
int status = -ENOMEM;
int gcnum;
size_t len;
u32 i;
struct usb_request *req;
@ -1143,16 +1142,6 @@ static int __init printer_bind_config(struct usb_configuration *c)
goto fail;
}
gcnum = usb_gadget_controller_number(gadget);
if (gcnum >= 0) {
device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum);
} else {
dev_warn(&gadget->dev, "controller '%s' not recognized\n",
gadget->name);
/* unrecognized, but safe unless bulk is REALLY quirky */
device_desc.bcdDevice =
cpu_to_le16(0xFFFF);
}
if (iPNPstring)
strlcpy(&pnp_string[2], iPNPstring, (sizeof pnp_string)-2);

View File

@ -86,7 +86,7 @@ static struct usb_device_descriptor device_desc = {
/* .bMaxPacketSize0 = f(hardware) */
.idVendor = cpu_to_le16(GS_VENDOR_ID),
/* .idProduct = f(use_acm) */
/* .bcdDevice = f(hardware) */
.bcdDevice = cpu_to_le16(GS_VERSION_NUM << 16),
/* .iManufacturer = DYNAMIC */
/* .iProduct = DYNAMIC */
.bNumConfigurations = 1,
@ -154,8 +154,6 @@ static struct usb_configuration serial_config_driver = {
static int __init gs_bind(struct usb_composite_dev *cdev)
{
int gcnum;
struct usb_gadget *gadget = cdev->gadget;
int status;
status = gserial_setup(cdev->gadget, n_ports);
@ -174,24 +172,6 @@ static int __init gs_bind(struct usb_composite_dev *cdev)
status = strings_dev[STRING_DESCRIPTION_IDX].id;
serial_config_driver.iConfiguration = status;
/* set up other descriptors */
gcnum = usb_gadget_controller_number(gadget);
if (gcnum >= 0)
device_desc.bcdDevice = cpu_to_le16(GS_VERSION_NUM | gcnum);
else {
/* this is so simple (for now, no altsettings) that it
* SHOULD NOT have problems with bulk-capable hardware.
* so warn about unrcognized controllers -- don't panic.
*
* things like configuration and altsetting numbering
* can need hardware-specific attention though.
*/
pr_warning("gs_bind: controller '%s' not recognized\n",
gadget->name);
device_desc.bcdDevice =
cpu_to_le16(GS_VERSION_NUM | 0x0099);
}
if (gadget_is_otg(cdev->gadget)) {
serial_config_driver.descriptors = otg_desc;
serial_config_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;

View File

@ -253,8 +253,6 @@ static void zero_resume(struct usb_composite_dev *cdev)
static int __init zero_bind(struct usb_composite_dev *cdev)
{
int gcnum;
struct usb_gadget *gadget = cdev->gadget;
int status;
/* Allocate string descriptor numbers ... note that string
@ -281,21 +279,6 @@ static int __init zero_bind(struct usb_composite_dev *cdev)
loopback_add(cdev, autoresume != 0);
}
gcnum = usb_gadget_controller_number(gadget);
if (gcnum >= 0)
device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum);
else {
/* gadget zero is so simple (for now, no altsettings) that
* it SHOULD NOT have problems with bulk-capable hardware.
* so just warn about unrcognized controllers -- don't panic.
*
* things like configuration and altsetting numbering
* can need hardware-specific attention though.
*/
pr_warning("%s: controller '%s' not recognized\n",
longname, gadget->name);
device_desc.bcdDevice = cpu_to_le16(0x9999);
}
usb_composite_overwrite_options(cdev, &coverwrite);
INFO(cdev, "%s, version: " DRIVER_VERSION "\n", longname);

View File

@ -34,6 +34,8 @@
* the composite model the host can use both functions at the same time.
*/
#include <linux/bcd.h>
#include <linux/version.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
@ -418,6 +420,15 @@ struct usb_composite_overwrite {
void usb_composite_overwrite_options(struct usb_composite_dev *cdev,
struct usb_composite_overwrite *covr);
static inline u16 get_default_bcdDevice(void)
{
u16 bcdDevice;
bcdDevice = bin2bcd((LINUX_VERSION_CODE >> 16 & 0xff)) << 8;
bcdDevice |= bin2bcd((LINUX_VERSION_CODE >> 8 & 0xff));
return bcdDevice;
}
/* messaging utils */
#define DBG(d, fmt, args...) \
dev_dbg(&(d)->gadget->dev , fmt , ## args)