[RFC 9/9] usb: gadget: ether: example usage of "OS desriptors"

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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, &eth_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, &eth_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




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux