aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/gadget/f_rndis.c24
-rw-r--r--drivers/usb/gadget/u_rndis.h3
2 files changed, 24 insertions, 3 deletions
diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c
index 139bc9c6f7e0..28d1891f11fa 100644
--- a/drivers/usb/gadget/f_rndis.c
+++ b/drivers/usb/gadget/f_rndis.c
@@ -682,6 +682,15 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f)
682 682
683 rndis_opts = container_of(f->fi, struct f_rndis_opts, func_inst); 683 rndis_opts = container_of(f->fi, struct f_rndis_opts, func_inst);
684 684
685 if (cdev->use_os_string) {
686 f->os_desc_table = kzalloc(sizeof(*f->os_desc_table),
687 GFP_KERNEL);
688 if (!f->os_desc_table)
689 return PTR_ERR(f->os_desc_table);
690 f->os_desc_n = 1;
691 f->os_desc_table[0].os_desc = &rndis_opts->rndis_os_desc;
692 }
693
685 /* 694 /*
686 * in drivers/usb/gadget/configfs.c:configfs_composite_bind() 695 * in drivers/usb/gadget/configfs.c:configfs_composite_bind()
687 * configurations are bound in sequence with list_for_each_entry, 696 * configurations are bound in sequence with list_for_each_entry,
@@ -693,14 +702,16 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f)
693 gether_set_gadget(rndis_opts->net, cdev->gadget); 702 gether_set_gadget(rndis_opts->net, cdev->gadget);
694 status = gether_register_netdev(rndis_opts->net); 703 status = gether_register_netdev(rndis_opts->net);
695 if (status) 704 if (status)
696 return status; 705 goto fail;
697 rndis_opts->bound = true; 706 rndis_opts->bound = true;
698 } 707 }
699 708
700 us = usb_gstrings_attach(cdev, rndis_strings, 709 us = usb_gstrings_attach(cdev, rndis_strings,
701 ARRAY_SIZE(rndis_string_defs)); 710 ARRAY_SIZE(rndis_string_defs));
702 if (IS_ERR(us)) 711 if (IS_ERR(us)) {
703 return PTR_ERR(us); 712 status = PTR_ERR(us);
713 goto fail;
714 }
704 rndis_control_intf.iInterface = us[0].id; 715 rndis_control_intf.iInterface = us[0].id;
705 rndis_data_intf.iInterface = us[1].id; 716 rndis_data_intf.iInterface = us[1].id;
706 rndis_iad_descriptor.iFunction = us[2].id; 717 rndis_iad_descriptor.iFunction = us[2].id;
@@ -802,6 +813,8 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f)
802 return 0; 813 return 0;
803 814
804fail: 815fail:
816 kfree(f->os_desc_table);
817 f->os_desc_n = 0;
805 usb_free_all_descriptors(f); 818 usb_free_all_descriptors(f);
806 819
807 if (rndis->notify_req) { 820 if (rndis->notify_req) {
@@ -892,6 +905,8 @@ static struct usb_function_instance *rndis_alloc_inst(void)
892 opts = kzalloc(sizeof(*opts), GFP_KERNEL); 905 opts = kzalloc(sizeof(*opts), GFP_KERNEL);
893 if (!opts) 906 if (!opts)
894 return ERR_PTR(-ENOMEM); 907 return ERR_PTR(-ENOMEM);
908 opts->rndis_os_desc.ext_compat_id = opts->rndis_ext_compat_id;
909
895 mutex_init(&opts->lock); 910 mutex_init(&opts->lock);
896 opts->func_inst.free_func_inst = rndis_free_inst; 911 opts->func_inst.free_func_inst = rndis_free_inst;
897 opts->net = gether_setup_default(); 912 opts->net = gether_setup_default();
@@ -900,6 +915,7 @@ static struct usb_function_instance *rndis_alloc_inst(void)
900 kfree(opts); 915 kfree(opts);
901 return ERR_CAST(net); 916 return ERR_CAST(net);
902 } 917 }
918 INIT_LIST_HEAD(&opts->rndis_os_desc.ext_prop);
903 919
904 config_group_init_type_name(&opts->func_inst.group, "", 920 config_group_init_type_name(&opts->func_inst.group, "",
905 &rndis_func_type); 921 &rndis_func_type);
@@ -925,6 +941,8 @@ static void rndis_unbind(struct usb_configuration *c, struct usb_function *f)
925{ 941{
926 struct f_rndis *rndis = func_to_rndis(f); 942 struct f_rndis *rndis = func_to_rndis(f);
927 943
944 kfree(f->os_desc_table);
945 f->os_desc_n = 0;
928 usb_free_all_descriptors(f); 946 usb_free_all_descriptors(f);
929 947
930 kfree(rndis->notify_req->buf); 948 kfree(rndis->notify_req->buf);
diff --git a/drivers/usb/gadget/u_rndis.h b/drivers/usb/gadget/u_rndis.h
index 7291b15c9dce..e902aa42a297 100644
--- a/drivers/usb/gadget/u_rndis.h
+++ b/drivers/usb/gadget/u_rndis.h
@@ -26,6 +26,9 @@ struct f_rndis_opts {
26 bool bound; 26 bool bound;
27 bool borrowed_net; 27 bool borrowed_net;
28 28
29 struct usb_os_desc rndis_os_desc;
30 char rndis_ext_compat_id[16];
31
29 /* 32 /*
30 * Read/write access to configfs attributes is handled by configfs. 33 * Read/write access to configfs attributes is handled by configfs.
31 * 34 *