Example of using OS Descriptors in a legacy gadget. Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@xxxxxxxxxxx> --- drivers/usb/gadget/ether.c | 58 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 5 deletions(-) diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index c1c113e..2c06f1f 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -24,6 +24,7 @@ #endif #include "u_ether.h" +#include "u_os_desc.h" /* @@ -316,6 +317,11 @@ static struct usb_configuration eth_config_driver = { .bmAttributes = USB_CONFIG_ATT_SELFPOWER, }; +static struct usb_os_desc_ext_prop icon_prop; +static struct usb_os_desc_ext_prop label_prop; +static const char *os_string = "MSFT100"; +static const char *rndis_label = "RNDIS"; + /*-------------------------------------------------------------------------*/ static int __init eth_bind(struct usb_composite_dev *cdev) @@ -324,6 +330,7 @@ static int __init eth_bind(struct usb_composite_dev *cdev) struct f_eem_opts *eem_opts = NULL; struct f_ecm_opts *ecm_opts = NULL; struct f_gether_opts *geth_opts = NULL; + struct f_rndis_opts *rndis_opts = NULL; struct net_device *net; int status; @@ -416,18 +423,53 @@ static int __init eth_bind(struct usb_composite_dev *cdev) device_desc.iManufacturer = strings_dev[USB_GADGET_MANUFACTURER_IDX].id; device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id; + status = usb_add_config(cdev, ð_config_driver, eth_do_config); + if (status < 0) + goto fail1; + /* register our configuration(s); RNDIS first, if it's used */ if (has_rndis()) { + rndis_opts = container_of(fi_rndis, struct f_rndis_opts, + func_inst); + cdev->use_os_string = true; + cdev->b_vendor_code = 0xCA; + status = utf8s_to_utf16s(os_string, strlen(os_string), + UTF16_LITTLE_ENDIAN, (wchar_t *) &cdev->qw_sign[0], + OS_STRING_QW_SIGN_LEN); + if (status < 0) + goto fail1; + + list_add_tail(&icon_prop.entry, + &rndis_opts->rndis_os_desc.ext_prop); + list_add_tail(&label_prop.entry, + &rndis_opts->rndis_os_desc.ext_prop); + + cdev->os_desc_config = &rndis_config_driver; + memcpy(&rndis_opts->rndis_os_desc.ext_compat_id[0], + rndis_label, 5); + + icon_prop.type = USB_EXT_PROP_UNICODE_ENV; + icon_prop.name = "Icons"; + icon_prop.name_len = 2 * strlen(icon_prop.name) + 2; + icon_prop.data = "%SystemRoot%\\system32\\shell32.dll,-233"; + icon_prop.data_len = 2 * strlen(icon_prop.data) + 2; + + label_prop.type = USB_EXT_PROP_UNICODE; + label_prop.name = "Label"; + label_prop.name_len = 2 * strlen(label_prop.name) + 2; + label_prop.data = "XYZ Device"; + label_prop.data_len = 2 * strlen(label_prop.data) + 2; + + rndis_opts->rndis_os_desc.ext_prop_len = + icon_prop.name_len + icon_prop.data_len + 14 + + label_prop.name_len + label_prop.data_len + 14; + rndis_opts->rndis_os_desc.ext_prop_count = 2; status = usb_add_config(cdev, &rndis_config_driver, rndis_do_config); if (status < 0) goto fail1; } - status = usb_add_config(cdev, ð_config_driver, eth_do_config); - if (status < 0) - goto fail1; - usb_composite_overwrite_options(cdev, &coverwrite); dev_info(&gadget->dev, "%s, version: " DRIVER_VERSION "\n", DRIVER_DESC); @@ -435,8 +477,11 @@ static int __init eth_bind(struct usb_composite_dev *cdev) return 0; fail1: - if (has_rndis()) + if (has_rndis()) { + label_prop.data = NULL; + icon_prop.data = NULL; usb_put_function_instance(fi_rndis); + } fail: if (use_eem) usb_put_function_instance(fi_eem); @@ -449,7 +494,10 @@ fail: static int __exit eth_unbind(struct usb_composite_dev *cdev) { + if (has_rndis()) { + label_prop.data = NULL; + icon_prop.data = NULL; usb_put_function(f_rndis); usb_put_function_instance(fi_rndis); } -- 1.8.3.2 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html