Skip to content

Commit 73517cf

Browse files
dlechFelipe Balbi
authored andcommitted
usb: gadget: add RNDIS configfs options for class/subclass/protocol
This adds 3 new options to the RNDIS gadget function configs. It allows overriding the default USB interface class/subclass/protocol. The motivation for this is that if you set the values to "ef" (Misc), "04" (RNDIS), "01" (Ethernet) respectively, then the device will be recognized by the rndiscmp.inf file in Windows Vista and newer and will cause Windows to load the correct RNDIS driver without the need for a custom (signed) .inf file. Signed-off-by: David Lechner <[email protected]> Signed-off-by: Felipe Balbi <[email protected]>
1 parent 6cea144 commit 73517cf

File tree

4 files changed

+62
-0
lines changed

4 files changed

+62
-0
lines changed

Documentation/ABI/testing/configfs-usb-gadget-rndis

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,6 @@ Description:
1212
Ethernet over USB link
1313
dev_addr - MAC address of device's end of this
1414
Ethernet over USB link
15+
class - USB interface class, default is 02 (hex)
16+
subclass - USB interface subclass, default is 06 (hex)
17+
protocol - USB interface protocol, default is 00 (hex)

drivers/usb/gadget/function/f_rndis.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -691,6 +691,10 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f)
691691
f->os_desc_table[0].os_desc = &rndis_opts->rndis_os_desc;
692692
}
693693

694+
rndis_iad_descriptor.bFunctionClass = rndis_opts->class;
695+
rndis_iad_descriptor.bFunctionSubClass = rndis_opts->subclass;
696+
rndis_iad_descriptor.bFunctionProtocol = rndis_opts->protocol;
697+
694698
/*
695699
* in drivers/usb/gadget/configfs.c:configfs_composite_bind()
696700
* configurations are bound in sequence with list_for_each_entry,
@@ -866,11 +870,23 @@ USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(rndis);
866870
/* f_rndis_opts_ifname */
867871
USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(rndis);
868872

873+
/* f_rndis_opts_class */
874+
USB_ETHER_CONFIGFS_ITEM_ATTR_U8_RW(rndis, class);
875+
876+
/* f_rndis_opts_subclass */
877+
USB_ETHER_CONFIGFS_ITEM_ATTR_U8_RW(rndis, subclass);
878+
879+
/* f_rndis_opts_protocol */
880+
USB_ETHER_CONFIGFS_ITEM_ATTR_U8_RW(rndis, protocol);
881+
869882
static struct configfs_attribute *rndis_attrs[] = {
870883
&rndis_opts_attr_dev_addr,
871884
&rndis_opts_attr_host_addr,
872885
&rndis_opts_attr_qmult,
873886
&rndis_opts_attr_ifname,
887+
&rndis_opts_attr_class,
888+
&rndis_opts_attr_subclass,
889+
&rndis_opts_attr_protocol,
874890
NULL,
875891
};
876892

@@ -916,6 +932,10 @@ static struct usb_function_instance *rndis_alloc_inst(void)
916932
}
917933
INIT_LIST_HEAD(&opts->rndis_os_desc.ext_prop);
918934

935+
opts->class = rndis_iad_descriptor.bFunctionClass;
936+
opts->subclass = rndis_iad_descriptor.bFunctionSubClass;
937+
opts->protocol = rndis_iad_descriptor.bFunctionProtocol;
938+
919939
descs[0] = &opts->rndis_os_desc;
920940
names[0] = "rndis";
921941
config_group_init_type_name(&opts->func_inst.group, "",

drivers/usb/gadget/function/u_ether_configfs.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,4 +153,39 @@ out: \
153153
\
154154
CONFIGFS_ATTR_RO(_f_##_opts_, ifname)
155155

156+
#define USB_ETHER_CONFIGFS_ITEM_ATTR_U8_RW(_f_, _n_) \
157+
static ssize_t _f_##_opts_##_n_##_show(struct config_item *item,\
158+
char *page) \
159+
{ \
160+
struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \
161+
int ret; \
162+
\
163+
mutex_lock(&opts->lock); \
164+
ret = sprintf(page, "%02x\n", opts->_n_); \
165+
mutex_unlock(&opts->lock); \
166+
\
167+
return ret; \
168+
} \
169+
\
170+
static ssize_t _f_##_opts_##_n_##_store(struct config_item *item,\
171+
const char *page, \
172+
size_t len) \
173+
{ \
174+
struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \
175+
int ret; \
176+
u8 val; \
177+
\
178+
mutex_lock(&opts->lock); \
179+
ret = sscanf(page, "%02hhx", &val); \
180+
if (ret > 0) { \
181+
opts->_n_ = val; \
182+
ret = len; \
183+
} \
184+
mutex_unlock(&opts->lock); \
185+
\
186+
return ret; \
187+
} \
188+
\
189+
CONFIGFS_ATTR(_f_##_opts_, _n_)
190+
156191
#endif /* __U_ETHER_CONFIGFS_H */

drivers/usb/gadget/function/u_rndis.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ struct f_rndis_opts {
2929
struct usb_os_desc rndis_os_desc;
3030
char rndis_ext_compat_id[16];
3131

32+
u8 class;
33+
u8 subclass;
34+
u8 protocol;
35+
3236
/*
3337
* Read/write access to configfs attributes is handled by configfs.
3438
*

0 commit comments

Comments
 (0)