Skip to content

Commit

Permalink
usb: gadget: f_rndis: OS descriptors support
Browse files Browse the repository at this point in the history
In order for usb functions to expose OS descriptors they
need to be made aware of OS descriptors. This involves
extending the "options" structure and setting up
appropriate associations.

Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
Acked-by: Michal Nazarewicz <mina86@mina86.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
  • Loading branch information
Andrzej Pietrasiewicz authored and Felipe Balbi committed May 14, 2014
1 parent 37a3a53 commit de7a8d2
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 3 deletions.
24 changes: 21 additions & 3 deletions drivers/usb/gadget/f_rndis.c
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,15 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f)

rndis_opts = container_of(f->fi, struct f_rndis_opts, func_inst);

if (cdev->use_os_string) {
f->os_desc_table = kzalloc(sizeof(*f->os_desc_table),
GFP_KERNEL);
if (!f->os_desc_table)
return PTR_ERR(f->os_desc_table);
f->os_desc_n = 1;
f->os_desc_table[0].os_desc = &rndis_opts->rndis_os_desc;
}

/*
* in drivers/usb/gadget/configfs.c:configfs_composite_bind()
* configurations are bound in sequence with list_for_each_entry,
Expand All @@ -693,14 +702,16 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f)
gether_set_gadget(rndis_opts->net, cdev->gadget);
status = gether_register_netdev(rndis_opts->net);
if (status)
return status;
goto fail;
rndis_opts->bound = true;
}

us = usb_gstrings_attach(cdev, rndis_strings,
ARRAY_SIZE(rndis_string_defs));
if (IS_ERR(us))
return PTR_ERR(us);
if (IS_ERR(us)) {
status = PTR_ERR(us);
goto fail;
}
rndis_control_intf.iInterface = us[0].id;
rndis_data_intf.iInterface = us[1].id;
rndis_iad_descriptor.iFunction = us[2].id;
Expand Down Expand Up @@ -802,6 +813,8 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f)
return 0;

fail:
kfree(f->os_desc_table);
f->os_desc_n = 0;
usb_free_all_descriptors(f);

if (rndis->notify_req) {
Expand Down Expand Up @@ -892,6 +905,8 @@ static struct usb_function_instance *rndis_alloc_inst(void)
opts = kzalloc(sizeof(*opts), GFP_KERNEL);
if (!opts)
return ERR_PTR(-ENOMEM);
opts->rndis_os_desc.ext_compat_id = opts->rndis_ext_compat_id;

mutex_init(&opts->lock);
opts->func_inst.free_func_inst = rndis_free_inst;
opts->net = gether_setup_default();
Expand All @@ -900,6 +915,7 @@ static struct usb_function_instance *rndis_alloc_inst(void)
kfree(opts);
return ERR_CAST(net);
}
INIT_LIST_HEAD(&opts->rndis_os_desc.ext_prop);

config_group_init_type_name(&opts->func_inst.group, "",
&rndis_func_type);
Expand All @@ -925,6 +941,8 @@ static void rndis_unbind(struct usb_configuration *c, struct usb_function *f)
{
struct f_rndis *rndis = func_to_rndis(f);

kfree(f->os_desc_table);
f->os_desc_n = 0;
usb_free_all_descriptors(f);

kfree(rndis->notify_req->buf);
Expand Down
3 changes: 3 additions & 0 deletions drivers/usb/gadget/u_rndis.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ struct f_rndis_opts {
bool bound;
bool borrowed_net;

struct usb_os_desc rndis_os_desc;
char rndis_ext_compat_id[16];

/*
* Read/write access to configfs attributes is handled by configfs.
*
Expand Down

0 comments on commit de7a8d2

Please sign in to comment.