Example of using OS Descriptors in a legacy gadget.
Signed-off-by: Andrzej Pietrasiewicz <[email protected]>
---
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 [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html