blob: f5bdb9e28f2041970fbaa0653ee6d519b309c9fd [file] [log] [blame]
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001#include <linux/configfs.h>
2#include <linux/module.h>
3#include <linux/slab.h>
4#include <linux/device.h>
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +02005#include <linux/nls.h>
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01006#include <linux/usb/composite.h>
7#include <linux/usb/gadget_configfs.h>
Rashika Kheria0009e992013-12-19 15:37:37 +05308#include "configfs.h"
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02009#include "u_f.h"
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +020010#include "u_os_desc.h"
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +010011
Badhri Jagan Sridharan21877382014-12-15 10:44:47 -080012#ifdef CONFIG_USB_CONFIGFS_UEVENT
13#include <linux/platform_device.h>
14#include <linux/kdev_t.h>
15#include <linux/usb/ch9.h>
Badhri Jagan Sridharan21877382014-12-15 10:44:47 -080016
17#ifdef CONFIG_USB_CONFIGFS_F_ACC
18extern int acc_ctrlrequest(struct usb_composite_dev *cdev,
19 const struct usb_ctrlrequest *ctrl);
20void acc_disconnect(void);
21#endif
22static struct class *android_class;
Badhri Jagan Sridharand6b2d772015-03-27 14:15:19 -070023static struct device *android_device;
24static int index;
25
26struct device *create_function_device(char *name)
27{
28 if (android_device && !IS_ERR(android_device))
29 return device_create(android_class, android_device,
30 MKDEV(0, index++), NULL, name);
31 else
32 return ERR_PTR(-EINVAL);
33}
34EXPORT_SYMBOL_GPL(create_function_device);
Badhri Jagan Sridharan21877382014-12-15 10:44:47 -080035#endif
36
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +010037int check_user_usb_string(const char *name,
38 struct usb_gadget_strings *stringtab_dev)
39{
40 unsigned primary_lang;
41 unsigned sub_lang;
42 u16 num;
43 int ret;
44
45 ret = kstrtou16(name, 0, &num);
46 if (ret)
47 return ret;
48
49 primary_lang = num & 0x3ff;
50 sub_lang = num >> 10;
51
52 /* simple sanity check for valid langid */
53 switch (primary_lang) {
54 case 0:
55 case 0x62 ... 0xfe:
56 case 0x100 ... 0x3ff:
57 return -EINVAL;
58 }
59 if (!sub_lang)
60 return -EINVAL;
61
62 stringtab_dev->language = num;
63 return 0;
64}
65
66#define MAX_NAME_LEN 40
67#define MAX_USB_STRING_LANGS 2
68
Li Jun41ce84c2015-07-09 15:18:48 +080069static const struct usb_descriptor_header *otg_desc[2];
70
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +010071struct gadget_info {
72 struct config_group group;
73 struct config_group functions_group;
74 struct config_group configs_group;
75 struct config_group strings_group;
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +020076 struct config_group os_desc_group;
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +010077
78 struct mutex lock;
79 struct usb_gadget_strings *gstrings[MAX_USB_STRING_LANGS + 1];
80 struct list_head string_list;
81 struct list_head available_func;
82
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +010083 struct usb_composite_driver composite;
84 struct usb_composite_dev cdev;
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +020085 bool use_os_desc;
86 char b_vendor_code;
87 char qw_sign[OS_STRING_QW_SIGN_LEN];
Peter Chenaa919ef2019-08-26 15:10:55 -040088 spinlock_t spinlock;
89 bool unbind;
Badhri Jagan Sridharan21877382014-12-15 10:44:47 -080090#ifdef CONFIG_USB_CONFIGFS_UEVENT
91 bool connected;
92 bool sw_connected;
93 struct work_struct work;
94 struct device *dev;
95#endif
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +010096};
97
Christoph Hellwig45b6a732015-10-03 15:32:38 +020098static inline struct gadget_info *to_gadget_info(struct config_item *item)
99{
100 return container_of(to_config_group(item), struct gadget_info, group);
101}
102
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100103struct config_usb_cfg {
104 struct config_group group;
105 struct config_group strings_group;
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100106 struct list_head string_list;
107 struct usb_configuration c;
108 struct list_head func_list;
109 struct usb_gadget_strings *gstrings[MAX_USB_STRING_LANGS + 1];
110};
111
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200112static inline struct config_usb_cfg *to_config_usb_cfg(struct config_item *item)
113{
114 return container_of(to_config_group(item), struct config_usb_cfg,
115 group);
116}
117
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100118struct gadget_strings {
119 struct usb_gadget_strings stringtab_dev;
120 struct usb_string strings[USB_GADGET_FIRST_AVAIL_IDX];
121 char *manufacturer;
122 char *product;
123 char *serialnumber;
124
125 struct config_group group;
126 struct list_head list;
127};
128
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200129struct os_desc {
130 struct config_group group;
131};
132
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100133struct gadget_config_name {
134 struct usb_gadget_strings stringtab_dev;
135 struct usb_string strings;
136 char *configuration;
137
138 struct config_group group;
139 struct list_head list;
140};
141
142static int usb_string_copy(const char *s, char **s_copy)
143{
144 int ret;
145 char *str;
146 char *copy = *s_copy;
147 ret = strlen(s);
148 if (ret > 126)
149 return -EOVERFLOW;
150
151 str = kstrdup(s, GFP_KERNEL);
152 if (!str)
153 return -ENOMEM;
154 if (str[ret - 1] == '\n')
155 str[ret - 1] = '\0';
156 kfree(copy);
157 *s_copy = str;
158 return 0;
159}
160
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100161#define GI_DEVICE_DESC_SIMPLE_R_u8(__name) \
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200162static ssize_t gadget_dev_desc_##__name##_show(struct config_item *item, \
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100163 char *page) \
164{ \
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200165 return sprintf(page, "0x%02x\n", \
166 to_gadget_info(item)->cdev.desc.__name); \
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100167}
168
169#define GI_DEVICE_DESC_SIMPLE_R_u16(__name) \
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200170static ssize_t gadget_dev_desc_##__name##_show(struct config_item *item, \
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100171 char *page) \
172{ \
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200173 return sprintf(page, "0x%04x\n", \
174 le16_to_cpup(&to_gadget_info(item)->cdev.desc.__name)); \
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100175}
176
177
178#define GI_DEVICE_DESC_SIMPLE_W_u8(_name) \
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200179static ssize_t gadget_dev_desc_##_name##_store(struct config_item *item, \
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100180 const char *page, size_t len) \
181{ \
182 u8 val; \
183 int ret; \
184 ret = kstrtou8(page, 0, &val); \
185 if (ret) \
186 return ret; \
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200187 to_gadget_info(item)->cdev.desc._name = val; \
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100188 return len; \
189}
190
191#define GI_DEVICE_DESC_SIMPLE_W_u16(_name) \
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200192static ssize_t gadget_dev_desc_##_name##_store(struct config_item *item, \
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100193 const char *page, size_t len) \
194{ \
195 u16 val; \
196 int ret; \
197 ret = kstrtou16(page, 0, &val); \
198 if (ret) \
199 return ret; \
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200200 to_gadget_info(item)->cdev.desc._name = cpu_to_le16p(&val); \
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100201 return len; \
202}
203
204#define GI_DEVICE_DESC_SIMPLE_RW(_name, _type) \
205 GI_DEVICE_DESC_SIMPLE_R_##_type(_name) \
206 GI_DEVICE_DESC_SIMPLE_W_##_type(_name)
207
208GI_DEVICE_DESC_SIMPLE_R_u16(bcdUSB);
209GI_DEVICE_DESC_SIMPLE_RW(bDeviceClass, u8);
210GI_DEVICE_DESC_SIMPLE_RW(bDeviceSubClass, u8);
211GI_DEVICE_DESC_SIMPLE_RW(bDeviceProtocol, u8);
212GI_DEVICE_DESC_SIMPLE_RW(bMaxPacketSize0, u8);
213GI_DEVICE_DESC_SIMPLE_RW(idVendor, u16);
214GI_DEVICE_DESC_SIMPLE_RW(idProduct, u16);
215GI_DEVICE_DESC_SIMPLE_R_u16(bcdDevice);
216
217static ssize_t is_valid_bcd(u16 bcd_val)
218{
219 if ((bcd_val & 0xf) > 9)
220 return -EINVAL;
221 if (((bcd_val >> 4) & 0xf) > 9)
222 return -EINVAL;
223 if (((bcd_val >> 8) & 0xf) > 9)
224 return -EINVAL;
225 if (((bcd_val >> 12) & 0xf) > 9)
226 return -EINVAL;
227 return 0;
228}
229
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200230static ssize_t gadget_dev_desc_bcdDevice_store(struct config_item *item,
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100231 const char *page, size_t len)
232{
233 u16 bcdDevice;
234 int ret;
235
236 ret = kstrtou16(page, 0, &bcdDevice);
237 if (ret)
238 return ret;
239 ret = is_valid_bcd(bcdDevice);
240 if (ret)
241 return ret;
242
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200243 to_gadget_info(item)->cdev.desc.bcdDevice = cpu_to_le16(bcdDevice);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100244 return len;
245}
246
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200247static ssize_t gadget_dev_desc_bcdUSB_store(struct config_item *item,
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100248 const char *page, size_t len)
249{
250 u16 bcdUSB;
251 int ret;
252
253 ret = kstrtou16(page, 0, &bcdUSB);
254 if (ret)
255 return ret;
256 ret = is_valid_bcd(bcdUSB);
257 if (ret)
258 return ret;
259
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200260 to_gadget_info(item)->cdev.desc.bcdUSB = cpu_to_le16(bcdUSB);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100261 return len;
262}
263
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200264static ssize_t gadget_dev_desc_UDC_show(struct config_item *item, char *page)
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100265{
Ruslan Bilovolafdaadc2015-11-23 09:56:36 +0100266 char *udc_name = to_gadget_info(item)->composite.gadget_driver.udc_name;
267
268 return sprintf(page, "%s\n", udc_name ?: "");
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100269}
270
271static int unregister_gadget(struct gadget_info *gi)
272{
273 int ret;
274
Ruslan Bilovolafdaadc2015-11-23 09:56:36 +0100275 if (!gi->composite.gadget_driver.udc_name)
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100276 return -ENODEV;
277
278 ret = usb_gadget_unregister_driver(&gi->composite.gadget_driver);
279 if (ret)
280 return ret;
Ruslan Bilovolafdaadc2015-11-23 09:56:36 +0100281 kfree(gi->composite.gadget_driver.udc_name);
282 gi->composite.gadget_driver.udc_name = NULL;
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100283 return 0;
284}
285
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200286static ssize_t gadget_dev_desc_UDC_store(struct config_item *item,
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100287 const char *page, size_t len)
288{
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200289 struct gadget_info *gi = to_gadget_info(item);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100290 char *name;
291 int ret;
292
293 name = kstrdup(page, GFP_KERNEL);
294 if (!name)
295 return -ENOMEM;
296 if (name[len - 1] == '\n')
297 name[len - 1] = '\0';
298
299 mutex_lock(&gi->lock);
300
Badhri Jagan Sridharan21877382014-12-15 10:44:47 -0800301 if (!strlen(name) || strcmp(name, "none") == 0) {
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100302 ret = unregister_gadget(gi);
303 if (ret)
304 goto err;
John Keeping59682e72017-02-28 10:55:30 +0000305 kfree(name);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100306 } else {
Ruslan Bilovolafdaadc2015-11-23 09:56:36 +0100307 if (gi->composite.gadget_driver.udc_name) {
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100308 ret = -EBUSY;
309 goto err;
310 }
Ruslan Bilovolafdaadc2015-11-23 09:56:36 +0100311 gi->composite.gadget_driver.udc_name = name;
312 ret = usb_gadget_probe_driver(&gi->composite.gadget_driver);
313 if (ret) {
314 gi->composite.gadget_driver.udc_name = NULL;
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100315 goto err;
Ruslan Bilovolafdaadc2015-11-23 09:56:36 +0100316 }
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100317 }
318 mutex_unlock(&gi->lock);
319 return len;
320err:
321 kfree(name);
322 mutex_unlock(&gi->lock);
323 return ret;
324}
325
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200326CONFIGFS_ATTR(gadget_dev_desc_, bDeviceClass);
327CONFIGFS_ATTR(gadget_dev_desc_, bDeviceSubClass);
328CONFIGFS_ATTR(gadget_dev_desc_, bDeviceProtocol);
329CONFIGFS_ATTR(gadget_dev_desc_, bMaxPacketSize0);
330CONFIGFS_ATTR(gadget_dev_desc_, idVendor);
331CONFIGFS_ATTR(gadget_dev_desc_, idProduct);
332CONFIGFS_ATTR(gadget_dev_desc_, bcdDevice);
333CONFIGFS_ATTR(gadget_dev_desc_, bcdUSB);
334CONFIGFS_ATTR(gadget_dev_desc_, UDC);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100335
336static struct configfs_attribute *gadget_root_attrs[] = {
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200337 &gadget_dev_desc_attr_bDeviceClass,
338 &gadget_dev_desc_attr_bDeviceSubClass,
339 &gadget_dev_desc_attr_bDeviceProtocol,
340 &gadget_dev_desc_attr_bMaxPacketSize0,
341 &gadget_dev_desc_attr_idVendor,
342 &gadget_dev_desc_attr_idProduct,
343 &gadget_dev_desc_attr_bcdDevice,
344 &gadget_dev_desc_attr_bcdUSB,
345 &gadget_dev_desc_attr_UDC,
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100346 NULL,
347};
348
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100349static inline struct gadget_strings *to_gadget_strings(struct config_item *item)
350{
351 return container_of(to_config_group(item), struct gadget_strings,
352 group);
353}
354
355static inline struct gadget_config_name *to_gadget_config_name(
356 struct config_item *item)
357{
358 return container_of(to_config_group(item), struct gadget_config_name,
359 group);
360}
361
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100362static inline struct usb_function_instance *to_usb_function_instance(
363 struct config_item *item)
364{
365 return container_of(to_config_group(item),
366 struct usb_function_instance, group);
367}
368
369static void gadget_info_attr_release(struct config_item *item)
370{
371 struct gadget_info *gi = to_gadget_info(item);
372
373 WARN_ON(!list_empty(&gi->cdev.configs));
374 WARN_ON(!list_empty(&gi->string_list));
375 WARN_ON(!list_empty(&gi->available_func));
376 kfree(gi->composite.gadget_driver.function);
377 kfree(gi);
378}
379
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100380static struct configfs_item_operations gadget_root_item_ops = {
381 .release = gadget_info_attr_release,
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100382};
383
384static void gadget_config_attr_release(struct config_item *item)
385{
386 struct config_usb_cfg *cfg = to_config_usb_cfg(item);
387
388 WARN_ON(!list_empty(&cfg->c.functions));
389 list_del(&cfg->c.list);
390 kfree(cfg->c.label);
391 kfree(cfg);
392}
393
394static int config_usb_cfg_link(
395 struct config_item *usb_cfg_ci,
396 struct config_item *usb_func_ci)
397{
398 struct config_usb_cfg *cfg = to_config_usb_cfg(usb_cfg_ci);
399 struct usb_composite_dev *cdev = cfg->c.cdev;
400 struct gadget_info *gi = container_of(cdev, struct gadget_info, cdev);
401
402 struct config_group *group = to_config_group(usb_func_ci);
403 struct usb_function_instance *fi = container_of(group,
404 struct usb_function_instance, group);
405 struct usb_function_instance *a_fi;
406 struct usb_function *f;
407 int ret;
408
409 mutex_lock(&gi->lock);
410 /*
411 * Make sure this function is from within our _this_ gadget and not
412 * from another gadget or a random directory.
413 * Also a function instance can only be linked once.
414 */
415 list_for_each_entry(a_fi, &gi->available_func, cfs_list) {
416 if (a_fi == fi)
417 break;
418 }
419 if (a_fi != fi) {
420 ret = -EINVAL;
421 goto out;
422 }
423
424 list_for_each_entry(f, &cfg->func_list, list) {
425 if (f->fi == fi) {
426 ret = -EEXIST;
427 goto out;
428 }
429 }
430
431 f = usb_get_function(fi);
432 if (IS_ERR(f)) {
433 ret = PTR_ERR(f);
434 goto out;
435 }
436
437 /* stash the function until we bind it to the gadget */
438 list_add_tail(&f->list, &cfg->func_list);
439 ret = 0;
440out:
441 mutex_unlock(&gi->lock);
442 return ret;
443}
444
445static int config_usb_cfg_unlink(
446 struct config_item *usb_cfg_ci,
447 struct config_item *usb_func_ci)
448{
449 struct config_usb_cfg *cfg = to_config_usb_cfg(usb_cfg_ci);
450 struct usb_composite_dev *cdev = cfg->c.cdev;
451 struct gadget_info *gi = container_of(cdev, struct gadget_info, cdev);
452
453 struct config_group *group = to_config_group(usb_func_ci);
454 struct usb_function_instance *fi = container_of(group,
455 struct usb_function_instance, group);
456 struct usb_function *f;
457
458 /*
459 * ideally I would like to forbid to unlink functions while a gadget is
460 * bound to an UDC. Since this isn't possible at the moment, we simply
461 * force an unbind, the function is available here and then we can
462 * remove the function.
463 */
464 mutex_lock(&gi->lock);
Ruslan Bilovolafdaadc2015-11-23 09:56:36 +0100465 if (gi->composite.gadget_driver.udc_name)
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100466 unregister_gadget(gi);
Ruslan Bilovolafdaadc2015-11-23 09:56:36 +0100467 WARN_ON(gi->composite.gadget_driver.udc_name);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100468
469 list_for_each_entry(f, &cfg->func_list, list) {
470 if (f->fi == fi) {
471 list_del(&f->list);
472 usb_put_function(f);
473 mutex_unlock(&gi->lock);
474 return 0;
475 }
476 }
477 mutex_unlock(&gi->lock);
David Rientjes75bfe232013-04-07 14:11:47 -0700478 WARN(1, "Unable to locate function to unbind\n");
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100479 return 0;
480}
481
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100482static struct configfs_item_operations gadget_config_item_ops = {
483 .release = gadget_config_attr_release,
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100484 .allow_link = config_usb_cfg_link,
485 .drop_link = config_usb_cfg_unlink,
486};
487
488
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200489static ssize_t gadget_config_desc_MaxPower_show(struct config_item *item,
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100490 char *page)
491{
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200492 return sprintf(page, "%u\n", to_config_usb_cfg(item)->c.MaxPower);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100493}
494
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200495static ssize_t gadget_config_desc_MaxPower_store(struct config_item *item,
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100496 const char *page, size_t len)
497{
498 u16 val;
499 int ret;
500 ret = kstrtou16(page, 0, &val);
501 if (ret)
502 return ret;
503 if (DIV_ROUND_UP(val, 8) > 0xff)
504 return -ERANGE;
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200505 to_config_usb_cfg(item)->c.MaxPower = val;
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100506 return len;
507}
508
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200509static ssize_t gadget_config_desc_bmAttributes_show(struct config_item *item,
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100510 char *page)
511{
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200512 return sprintf(page, "0x%02x\n",
513 to_config_usb_cfg(item)->c.bmAttributes);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100514}
515
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200516static ssize_t gadget_config_desc_bmAttributes_store(struct config_item *item,
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100517 const char *page, size_t len)
518{
519 u8 val;
520 int ret;
521 ret = kstrtou8(page, 0, &val);
522 if (ret)
523 return ret;
524 if (!(val & USB_CONFIG_ATT_ONE))
525 return -EINVAL;
526 if (val & ~(USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER |
527 USB_CONFIG_ATT_WAKEUP))
528 return -EINVAL;
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200529 to_config_usb_cfg(item)->c.bmAttributes = val;
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100530 return len;
531}
532
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200533CONFIGFS_ATTR(gadget_config_desc_, MaxPower);
534CONFIGFS_ATTR(gadget_config_desc_, bmAttributes);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100535
536static struct configfs_attribute *gadget_config_attrs[] = {
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200537 &gadget_config_desc_attr_MaxPower,
538 &gadget_config_desc_attr_bmAttributes,
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100539 NULL,
540};
541
542static struct config_item_type gadget_config_type = {
543 .ct_item_ops = &gadget_config_item_ops,
544 .ct_attrs = gadget_config_attrs,
545 .ct_owner = THIS_MODULE,
546};
547
548static struct config_item_type gadget_root_type = {
549 .ct_item_ops = &gadget_root_item_ops,
550 .ct_attrs = gadget_root_attrs,
551 .ct_owner = THIS_MODULE,
552};
553
554static void composite_init_dev(struct usb_composite_dev *cdev)
555{
556 spin_lock_init(&cdev->lock);
557 INIT_LIST_HEAD(&cdev->configs);
558 INIT_LIST_HEAD(&cdev->gstrings);
559}
560
561static struct config_group *function_make(
562 struct config_group *group,
563 const char *name)
564{
565 struct gadget_info *gi;
566 struct usb_function_instance *fi;
567 char buf[MAX_NAME_LEN];
568 char *func_name;
569 char *instance_name;
570 int ret;
571
572 ret = snprintf(buf, MAX_NAME_LEN, "%s", name);
573 if (ret >= MAX_NAME_LEN)
574 return ERR_PTR(-ENAMETOOLONG);
575
576 func_name = buf;
577 instance_name = strchr(func_name, '.');
578 if (!instance_name) {
579 pr_err("Unable to locate . in FUNC.INSTANCE\n");
580 return ERR_PTR(-EINVAL);
581 }
582 *instance_name = '\0';
583 instance_name++;
584
585 fi = usb_get_function_instance(func_name);
586 if (IS_ERR(fi))
Duan Jionga3469412013-09-26 15:55:25 +0800587 return ERR_CAST(fi);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100588
Nicolas Iooss3958b792015-07-17 16:23:45 -0700589 ret = config_item_set_name(&fi->group.cg_item, "%s", name);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100590 if (ret) {
591 usb_put_function_instance(fi);
592 return ERR_PTR(ret);
593 }
Andrzej Pietrasiewicz19338612013-12-03 15:15:21 +0100594 if (fi->set_inst_name) {
595 ret = fi->set_inst_name(fi, instance_name);
596 if (ret) {
597 usb_put_function_instance(fi);
598 return ERR_PTR(ret);
599 }
600 }
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100601
602 gi = container_of(group, struct gadget_info, functions_group);
603
604 mutex_lock(&gi->lock);
605 list_add_tail(&fi->cfs_list, &gi->available_func);
606 mutex_unlock(&gi->lock);
607 return &fi->group;
608}
609
610static void function_drop(
611 struct config_group *group,
612 struct config_item *item)
613{
614 struct usb_function_instance *fi = to_usb_function_instance(item);
615 struct gadget_info *gi;
616
617 gi = container_of(group, struct gadget_info, functions_group);
618
619 mutex_lock(&gi->lock);
620 list_del(&fi->cfs_list);
621 mutex_unlock(&gi->lock);
622 config_item_put(item);
623}
624
625static struct configfs_group_operations functions_ops = {
626 .make_group = &function_make,
627 .drop_item = &function_drop,
628};
629
630static struct config_item_type functions_type = {
631 .ct_group_ops = &functions_ops,
632 .ct_owner = THIS_MODULE,
633};
634
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100635GS_STRINGS_RW(gadget_config_name, configuration);
636
637static struct configfs_attribute *gadget_config_name_langid_attrs[] = {
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200638 &gadget_config_name_attr_configuration,
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100639 NULL,
640};
641
642static void gadget_config_name_attr_release(struct config_item *item)
643{
644 struct gadget_config_name *cn = to_gadget_config_name(item);
645
646 kfree(cn->configuration);
647
648 list_del(&cn->list);
649 kfree(cn);
650}
651
652USB_CONFIG_STRING_RW_OPS(gadget_config_name);
653USB_CONFIG_STRINGS_LANG(gadget_config_name, config_usb_cfg);
654
655static struct config_group *config_desc_make(
656 struct config_group *group,
657 const char *name)
658{
659 struct gadget_info *gi;
660 struct config_usb_cfg *cfg;
661 char buf[MAX_NAME_LEN];
662 char *num_str;
663 u8 num;
664 int ret;
665
666 gi = container_of(group, struct gadget_info, configs_group);
667 ret = snprintf(buf, MAX_NAME_LEN, "%s", name);
668 if (ret >= MAX_NAME_LEN)
669 return ERR_PTR(-ENAMETOOLONG);
670
671 num_str = strchr(buf, '.');
672 if (!num_str) {
673 pr_err("Unable to locate . in name.bConfigurationValue\n");
674 return ERR_PTR(-EINVAL);
675 }
676
677 *num_str = '\0';
678 num_str++;
679
680 if (!strlen(buf))
681 return ERR_PTR(-EINVAL);
682
683 ret = kstrtou8(num_str, 0, &num);
684 if (ret)
685 return ERR_PTR(ret);
686
687 cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
688 if (!cfg)
689 return ERR_PTR(-ENOMEM);
690 cfg->c.label = kstrdup(buf, GFP_KERNEL);
691 if (!cfg->c.label) {
692 ret = -ENOMEM;
693 goto err;
694 }
695 cfg->c.bConfigurationValue = num;
696 cfg->c.MaxPower = CONFIG_USB_GADGET_VBUS_DRAW;
697 cfg->c.bmAttributes = USB_CONFIG_ATT_ONE;
698 INIT_LIST_HEAD(&cfg->string_list);
699 INIT_LIST_HEAD(&cfg->func_list);
700
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100701 config_group_init_type_name(&cfg->group, name,
702 &gadget_config_type);
Christoph Hellwig1ae16022016-02-26 11:02:14 +0100703
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100704 config_group_init_type_name(&cfg->strings_group, "strings",
705 &gadget_config_name_strings_type);
Christoph Hellwig1ae16022016-02-26 11:02:14 +0100706 configfs_add_default_group(&cfg->strings_group, &cfg->group);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100707
708 ret = usb_add_config_only(&gi->cdev, &cfg->c);
709 if (ret)
710 goto err;
711
712 return &cfg->group;
713err:
714 kfree(cfg->c.label);
715 kfree(cfg);
716 return ERR_PTR(ret);
717}
718
719static void config_desc_drop(
720 struct config_group *group,
721 struct config_item *item)
722{
723 config_item_put(item);
724}
725
726static struct configfs_group_operations config_desc_ops = {
727 .make_group = &config_desc_make,
728 .drop_item = &config_desc_drop,
729};
730
731static struct config_item_type config_desc_type = {
732 .ct_group_ops = &config_desc_ops,
733 .ct_owner = THIS_MODULE,
734};
735
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100736GS_STRINGS_RW(gadget_strings, manufacturer);
737GS_STRINGS_RW(gadget_strings, product);
738GS_STRINGS_RW(gadget_strings, serialnumber);
739
740static struct configfs_attribute *gadget_strings_langid_attrs[] = {
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200741 &gadget_strings_attr_manufacturer,
742 &gadget_strings_attr_product,
743 &gadget_strings_attr_serialnumber,
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100744 NULL,
745};
746
747static void gadget_strings_attr_release(struct config_item *item)
748{
749 struct gadget_strings *gs = to_gadget_strings(item);
750
751 kfree(gs->manufacturer);
752 kfree(gs->product);
753 kfree(gs->serialnumber);
754
755 list_del(&gs->list);
756 kfree(gs);
757}
758
759USB_CONFIG_STRING_RW_OPS(gadget_strings);
760USB_CONFIG_STRINGS_LANG(gadget_strings, gadget_info);
761
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200762static inline struct os_desc *to_os_desc(struct config_item *item)
763{
764 return container_of(to_config_group(item), struct os_desc, group);
765}
766
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200767static inline struct gadget_info *os_desc_item_to_gadget_info(
768 struct config_item *item)
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200769{
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200770 return to_gadget_info(to_os_desc(item)->group.cg_item.ci_parent);
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200771}
772
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200773static ssize_t os_desc_use_show(struct config_item *item, char *page)
774{
775 return sprintf(page, "%d",
776 os_desc_item_to_gadget_info(item)->use_os_desc);
777}
778
779static ssize_t os_desc_use_store(struct config_item *item, const char *page,
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200780 size_t len)
781{
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200782 struct gadget_info *gi = os_desc_item_to_gadget_info(item);
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200783 int ret;
784 bool use;
785
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200786 mutex_lock(&gi->lock);
787 ret = strtobool(page, &use);
788 if (!ret) {
789 gi->use_os_desc = use;
790 ret = len;
791 }
792 mutex_unlock(&gi->lock);
793
794 return ret;
795}
796
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200797static ssize_t os_desc_b_vendor_code_show(struct config_item *item, char *page)
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200798{
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200799 return sprintf(page, "%d",
800 os_desc_item_to_gadget_info(item)->b_vendor_code);
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200801}
802
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200803static ssize_t os_desc_b_vendor_code_store(struct config_item *item,
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200804 const char *page, size_t len)
805{
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200806 struct gadget_info *gi = os_desc_item_to_gadget_info(item);
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200807 int ret;
808 u8 b_vendor_code;
809
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200810 mutex_lock(&gi->lock);
811 ret = kstrtou8(page, 0, &b_vendor_code);
812 if (!ret) {
813 gi->b_vendor_code = b_vendor_code;
814 ret = len;
815 }
816 mutex_unlock(&gi->lock);
817
818 return ret;
819}
820
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200821static ssize_t os_desc_qw_sign_show(struct config_item *item, char *page)
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200822{
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200823 struct gadget_info *gi = os_desc_item_to_gadget_info(item);
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200824
825 memcpy(page, gi->qw_sign, OS_STRING_QW_SIGN_LEN);
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200826 return OS_STRING_QW_SIGN_LEN;
827}
828
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200829static ssize_t os_desc_qw_sign_store(struct config_item *item, const char *page,
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200830 size_t len)
831{
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200832 struct gadget_info *gi = os_desc_item_to_gadget_info(item);
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200833 int res, l;
834
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200835 l = min((int)len, OS_STRING_QW_SIGN_LEN >> 1);
836 if (page[l - 1] == '\n')
837 --l;
838
839 mutex_lock(&gi->lock);
840 res = utf8s_to_utf16s(page, l,
841 UTF16_LITTLE_ENDIAN, (wchar_t *) gi->qw_sign,
842 OS_STRING_QW_SIGN_LEN);
843 if (res > 0)
844 res = len;
845 mutex_unlock(&gi->lock);
846
847 return res;
848}
849
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200850CONFIGFS_ATTR(os_desc_, use);
851CONFIGFS_ATTR(os_desc_, b_vendor_code);
852CONFIGFS_ATTR(os_desc_, qw_sign);
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200853
854static struct configfs_attribute *os_desc_attrs[] = {
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200855 &os_desc_attr_use,
856 &os_desc_attr_b_vendor_code,
857 &os_desc_attr_qw_sign,
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200858 NULL,
859};
860
861static void os_desc_attr_release(struct config_item *item)
862{
863 struct os_desc *os_desc = to_os_desc(item);
864 kfree(os_desc);
865}
866
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +0200867static int os_desc_link(struct config_item *os_desc_ci,
868 struct config_item *usb_cfg_ci)
869{
870 struct gadget_info *gi = container_of(to_config_group(os_desc_ci),
871 struct gadget_info, os_desc_group);
872 struct usb_composite_dev *cdev = &gi->cdev;
873 struct config_usb_cfg *c_target =
874 container_of(to_config_group(usb_cfg_ci),
875 struct config_usb_cfg, group);
876 struct usb_configuration *c;
877 int ret;
878
879 mutex_lock(&gi->lock);
880 list_for_each_entry(c, &cdev->configs, list) {
881 if (c == &c_target->c)
882 break;
883 }
884 if (c != &c_target->c) {
885 ret = -EINVAL;
886 goto out;
887 }
888
889 if (cdev->os_desc_config) {
890 ret = -EBUSY;
891 goto out;
892 }
893
894 cdev->os_desc_config = &c_target->c;
895 ret = 0;
896
897out:
898 mutex_unlock(&gi->lock);
899 return ret;
900}
901
902static int os_desc_unlink(struct config_item *os_desc_ci,
903 struct config_item *usb_cfg_ci)
904{
905 struct gadget_info *gi = container_of(to_config_group(os_desc_ci),
906 struct gadget_info, os_desc_group);
907 struct usb_composite_dev *cdev = &gi->cdev;
908
909 mutex_lock(&gi->lock);
Ruslan Bilovolafdaadc2015-11-23 09:56:36 +0100910 if (gi->composite.gadget_driver.udc_name)
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +0200911 unregister_gadget(gi);
912 cdev->os_desc_config = NULL;
Ruslan Bilovolafdaadc2015-11-23 09:56:36 +0100913 WARN_ON(gi->composite.gadget_driver.udc_name);
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +0200914 mutex_unlock(&gi->lock);
915 return 0;
916}
917
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200918static struct configfs_item_operations os_desc_ops = {
919 .release = os_desc_attr_release,
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +0200920 .allow_link = os_desc_link,
921 .drop_link = os_desc_unlink,
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200922};
923
924static struct config_item_type os_desc_type = {
925 .ct_item_ops = &os_desc_ops,
926 .ct_attrs = os_desc_attrs,
927 .ct_owner = THIS_MODULE,
928};
929
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +0200930static inline struct usb_os_desc_ext_prop
931*to_usb_os_desc_ext_prop(struct config_item *item)
932{
933 return container_of(item, struct usb_os_desc_ext_prop, item);
934}
935
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200936static ssize_t ext_prop_type_show(struct config_item *item, char *page)
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +0200937{
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200938 return sprintf(page, "%d", to_usb_os_desc_ext_prop(item)->type);
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +0200939}
940
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200941static ssize_t ext_prop_type_store(struct config_item *item,
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +0200942 const char *page, size_t len)
943{
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200944 struct usb_os_desc_ext_prop *ext_prop = to_usb_os_desc_ext_prop(item);
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +0200945 struct usb_os_desc *desc = to_usb_os_desc(ext_prop->item.ci_parent);
946 u8 type;
947 int ret;
948
949 if (desc->opts_mutex)
950 mutex_lock(desc->opts_mutex);
951 ret = kstrtou8(page, 0, &type);
952 if (ret)
953 goto end;
954 if (type < USB_EXT_PROP_UNICODE || type > USB_EXT_PROP_UNICODE_MULTI) {
955 ret = -EINVAL;
956 goto end;
957 }
958
959 if ((ext_prop->type == USB_EXT_PROP_BINARY ||
960 ext_prop->type == USB_EXT_PROP_LE32 ||
961 ext_prop->type == USB_EXT_PROP_BE32) &&
962 (type == USB_EXT_PROP_UNICODE ||
963 type == USB_EXT_PROP_UNICODE_ENV ||
964 type == USB_EXT_PROP_UNICODE_LINK))
965 ext_prop->data_len <<= 1;
966 else if ((ext_prop->type == USB_EXT_PROP_UNICODE ||
967 ext_prop->type == USB_EXT_PROP_UNICODE_ENV ||
968 ext_prop->type == USB_EXT_PROP_UNICODE_LINK) &&
969 (type == USB_EXT_PROP_BINARY ||
970 type == USB_EXT_PROP_LE32 ||
971 type == USB_EXT_PROP_BE32))
972 ext_prop->data_len >>= 1;
973 ext_prop->type = type;
974 ret = len;
975
976end:
977 if (desc->opts_mutex)
978 mutex_unlock(desc->opts_mutex);
979 return ret;
980}
981
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200982static ssize_t ext_prop_data_show(struct config_item *item, char *page)
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +0200983{
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200984 struct usb_os_desc_ext_prop *ext_prop = to_usb_os_desc_ext_prop(item);
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +0200985 int len = ext_prop->data_len;
986
987 if (ext_prop->type == USB_EXT_PROP_UNICODE ||
988 ext_prop->type == USB_EXT_PROP_UNICODE_ENV ||
989 ext_prop->type == USB_EXT_PROP_UNICODE_LINK)
990 len >>= 1;
991 memcpy(page, ext_prop->data, len);
992
993 return len;
994}
995
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200996static ssize_t ext_prop_data_store(struct config_item *item,
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +0200997 const char *page, size_t len)
998{
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200999 struct usb_os_desc_ext_prop *ext_prop = to_usb_os_desc_ext_prop(item);
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +02001000 struct usb_os_desc *desc = to_usb_os_desc(ext_prop->item.ci_parent);
1001 char *new_data;
1002 size_t ret_len = len;
1003
1004 if (page[len - 1] == '\n' || page[len - 1] == '\0')
1005 --len;
Benoit Taine58b949e2014-05-26 17:21:20 +02001006 new_data = kmemdup(page, len, GFP_KERNEL);
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +02001007 if (!new_data)
1008 return -ENOMEM;
1009
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +02001010 if (desc->opts_mutex)
1011 mutex_lock(desc->opts_mutex);
1012 kfree(ext_prop->data);
1013 ext_prop->data = new_data;
1014 desc->ext_prop_len -= ext_prop->data_len;
1015 ext_prop->data_len = len;
1016 desc->ext_prop_len += ext_prop->data_len;
1017 if (ext_prop->type == USB_EXT_PROP_UNICODE ||
1018 ext_prop->type == USB_EXT_PROP_UNICODE_ENV ||
1019 ext_prop->type == USB_EXT_PROP_UNICODE_LINK) {
1020 desc->ext_prop_len -= ext_prop->data_len;
1021 ext_prop->data_len <<= 1;
1022 ext_prop->data_len += 2;
1023 desc->ext_prop_len += ext_prop->data_len;
1024 }
1025 if (desc->opts_mutex)
1026 mutex_unlock(desc->opts_mutex);
1027 return ret_len;
1028}
1029
Christoph Hellwig45b6a732015-10-03 15:32:38 +02001030CONFIGFS_ATTR(ext_prop_, type);
1031CONFIGFS_ATTR(ext_prop_, data);
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +02001032
1033static struct configfs_attribute *ext_prop_attrs[] = {
Christoph Hellwig45b6a732015-10-03 15:32:38 +02001034 &ext_prop_attr_type,
1035 &ext_prop_attr_data,
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +02001036 NULL,
1037};
1038
1039static void usb_os_desc_ext_prop_release(struct config_item *item)
1040{
1041 struct usb_os_desc_ext_prop *ext_prop = to_usb_os_desc_ext_prop(item);
1042
1043 kfree(ext_prop); /* frees a whole chunk */
1044}
1045
1046static struct configfs_item_operations ext_prop_ops = {
1047 .release = usb_os_desc_ext_prop_release,
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +02001048};
1049
1050static struct config_item *ext_prop_make(
1051 struct config_group *group,
1052 const char *name)
1053{
1054 struct usb_os_desc_ext_prop *ext_prop;
1055 struct config_item_type *ext_prop_type;
1056 struct usb_os_desc *desc;
1057 char *vlabuf;
1058
1059 vla_group(data_chunk);
1060 vla_item(data_chunk, struct usb_os_desc_ext_prop, ext_prop, 1);
1061 vla_item(data_chunk, struct config_item_type, ext_prop_type, 1);
1062
1063 vlabuf = kzalloc(vla_group_size(data_chunk), GFP_KERNEL);
1064 if (!vlabuf)
1065 return ERR_PTR(-ENOMEM);
1066
1067 ext_prop = vla_ptr(vlabuf, data_chunk, ext_prop);
1068 ext_prop_type = vla_ptr(vlabuf, data_chunk, ext_prop_type);
1069
1070 desc = container_of(group, struct usb_os_desc, group);
1071 ext_prop_type->ct_item_ops = &ext_prop_ops;
1072 ext_prop_type->ct_attrs = ext_prop_attrs;
1073 ext_prop_type->ct_owner = desc->owner;
1074
1075 config_item_init_type_name(&ext_prop->item, name, ext_prop_type);
1076
1077 ext_prop->name = kstrdup(name, GFP_KERNEL);
1078 if (!ext_prop->name) {
1079 kfree(vlabuf);
1080 return ERR_PTR(-ENOMEM);
1081 }
1082 desc->ext_prop_len += 14;
1083 ext_prop->name_len = 2 * strlen(ext_prop->name) + 2;
1084 if (desc->opts_mutex)
1085 mutex_lock(desc->opts_mutex);
1086 desc->ext_prop_len += ext_prop->name_len;
1087 list_add_tail(&ext_prop->entry, &desc->ext_prop);
1088 ++desc->ext_prop_count;
1089 if (desc->opts_mutex)
1090 mutex_unlock(desc->opts_mutex);
1091
1092 return &ext_prop->item;
1093}
1094
1095static void ext_prop_drop(struct config_group *group, struct config_item *item)
1096{
1097 struct usb_os_desc_ext_prop *ext_prop = to_usb_os_desc_ext_prop(item);
1098 struct usb_os_desc *desc = to_usb_os_desc(&group->cg_item);
1099
1100 if (desc->opts_mutex)
1101 mutex_lock(desc->opts_mutex);
1102 list_del(&ext_prop->entry);
1103 --desc->ext_prop_count;
1104 kfree(ext_prop->name);
1105 desc->ext_prop_len -= (ext_prop->name_len + ext_prop->data_len + 14);
1106 if (desc->opts_mutex)
1107 mutex_unlock(desc->opts_mutex);
1108 config_item_put(item);
1109}
1110
1111static struct configfs_group_operations interf_grp_ops = {
1112 .make_item = &ext_prop_make,
1113 .drop_item = &ext_prop_drop,
1114};
1115
Christoph Hellwig45b6a732015-10-03 15:32:38 +02001116static ssize_t interf_grp_compatible_id_show(struct config_item *item,
Andrzej Pietrasiewiczfe00b132014-06-18 14:24:48 +02001117 char *page)
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001118{
Christoph Hellwig45b6a732015-10-03 15:32:38 +02001119 memcpy(page, to_usb_os_desc(item)->ext_compat_id, 8);
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001120 return 8;
1121}
1122
Christoph Hellwig45b6a732015-10-03 15:32:38 +02001123static ssize_t interf_grp_compatible_id_store(struct config_item *item,
Andrzej Pietrasiewiczfe00b132014-06-18 14:24:48 +02001124 const char *page, size_t len)
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001125{
Christoph Hellwig45b6a732015-10-03 15:32:38 +02001126 struct usb_os_desc *desc = to_usb_os_desc(item);
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001127 int l;
1128
1129 l = min_t(int, 8, len);
1130 if (page[l - 1] == '\n')
1131 --l;
1132 if (desc->opts_mutex)
1133 mutex_lock(desc->opts_mutex);
1134 memcpy(desc->ext_compat_id, page, l);
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001135
1136 if (desc->opts_mutex)
1137 mutex_unlock(desc->opts_mutex);
1138
1139 return len;
1140}
1141
Christoph Hellwig45b6a732015-10-03 15:32:38 +02001142static ssize_t interf_grp_sub_compatible_id_show(struct config_item *item,
Andrzej Pietrasiewiczfe00b132014-06-18 14:24:48 +02001143 char *page)
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001144{
Christoph Hellwig45b6a732015-10-03 15:32:38 +02001145 memcpy(page, to_usb_os_desc(item)->ext_compat_id + 8, 8);
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001146 return 8;
1147}
1148
Christoph Hellwig45b6a732015-10-03 15:32:38 +02001149static ssize_t interf_grp_sub_compatible_id_store(struct config_item *item,
Andrzej Pietrasiewiczfe00b132014-06-18 14:24:48 +02001150 const char *page, size_t len)
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001151{
Christoph Hellwig45b6a732015-10-03 15:32:38 +02001152 struct usb_os_desc *desc = to_usb_os_desc(item);
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001153 int l;
1154
1155 l = min_t(int, 8, len);
1156 if (page[l - 1] == '\n')
1157 --l;
1158 if (desc->opts_mutex)
1159 mutex_lock(desc->opts_mutex);
1160 memcpy(desc->ext_compat_id + 8, page, l);
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001161
1162 if (desc->opts_mutex)
1163 mutex_unlock(desc->opts_mutex);
1164
1165 return len;
1166}
1167
Christoph Hellwig45b6a732015-10-03 15:32:38 +02001168CONFIGFS_ATTR(interf_grp_, compatible_id);
1169CONFIGFS_ATTR(interf_grp_, sub_compatible_id);
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001170
1171static struct configfs_attribute *interf_grp_attrs[] = {
Christoph Hellwig45b6a732015-10-03 15:32:38 +02001172 &interf_grp_attr_compatible_id,
1173 &interf_grp_attr_sub_compatible_id,
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001174 NULL
1175};
1176
Andrew Gabbasov3c57f9d2017-09-30 08:54:52 -07001177struct config_group *usb_os_desc_prepare_interf_dir(
1178 struct config_group *parent,
1179 int n_interf,
1180 struct usb_os_desc **desc,
1181 char **names,
1182 struct module *owner)
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001183{
Christoph Hellwig1ae16022016-02-26 11:02:14 +01001184 struct config_group *os_desc_group;
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001185 struct config_item_type *os_desc_type, *interface_type;
1186
1187 vla_group(data_chunk);
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001188 vla_item(data_chunk, struct config_group, os_desc_group, 1);
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001189 vla_item(data_chunk, struct config_item_type, os_desc_type, 1);
1190 vla_item(data_chunk, struct config_item_type, interface_type, 1);
1191
1192 char *vlabuf = kzalloc(vla_group_size(data_chunk), GFP_KERNEL);
1193 if (!vlabuf)
Andrew Gabbasov3c57f9d2017-09-30 08:54:52 -07001194 return ERR_PTR(-ENOMEM);
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001195
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001196 os_desc_group = vla_ptr(vlabuf, data_chunk, os_desc_group);
1197 os_desc_type = vla_ptr(vlabuf, data_chunk, os_desc_type);
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001198 interface_type = vla_ptr(vlabuf, data_chunk, interface_type);
1199
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001200 os_desc_type->ct_owner = owner;
1201 config_group_init_type_name(os_desc_group, "os_desc", os_desc_type);
Christoph Hellwig1ae16022016-02-26 11:02:14 +01001202 configfs_add_default_group(os_desc_group, parent);
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001203
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +02001204 interface_type->ct_group_ops = &interf_grp_ops;
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001205 interface_type->ct_attrs = interf_grp_attrs;
1206 interface_type->ct_owner = owner;
1207
1208 while (n_interf--) {
1209 struct usb_os_desc *d;
1210
1211 d = desc[n_interf];
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +02001212 d->owner = owner;
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001213 config_group_init_type_name(&d->group, "", interface_type);
Andrzej Pietrasiewicz14574b52014-06-18 14:24:49 +02001214 config_item_set_name(&d->group.cg_item, "interface.%s",
1215 names[n_interf]);
Christoph Hellwig1ae16022016-02-26 11:02:14 +01001216 configfs_add_default_group(&d->group, os_desc_group);
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001217 }
1218
Andrew Gabbasov3c57f9d2017-09-30 08:54:52 -07001219 return os_desc_group;
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001220}
1221EXPORT_SYMBOL(usb_os_desc_prepare_interf_dir);
1222
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001223static int configfs_do_nothing(struct usb_composite_dev *cdev)
1224{
David Rientjes75bfe232013-04-07 14:11:47 -07001225 WARN_ON(1);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001226 return -EINVAL;
1227}
1228
1229int composite_dev_prepare(struct usb_composite_driver *composite,
1230 struct usb_composite_dev *dev);
1231
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001232int composite_os_desc_req_prepare(struct usb_composite_dev *cdev,
1233 struct usb_ep *ep0);
1234
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001235static void purge_configs_funcs(struct gadget_info *gi)
1236{
1237 struct usb_configuration *c;
1238
1239 list_for_each_entry(c, &gi->cdev.configs, list) {
1240 struct usb_function *f, *tmp;
1241 struct config_usb_cfg *cfg;
1242
1243 cfg = container_of(c, struct config_usb_cfg, c);
1244
1245 list_for_each_entry_safe(f, tmp, &c->functions, list) {
1246
1247 list_move_tail(&f->list, &cfg->func_list);
1248 if (f->unbind) {
Romain Izardda7b8952016-08-29 12:22:29 +03001249 dev_dbg(&gi->cdev.gadget->dev,
Romain Izarda08f5db2016-07-26 18:21:46 +02001250 "unbind function '%s'/%p\n",
1251 f->name, f);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001252 f->unbind(c, f);
1253 }
1254 }
1255 c->next_interface_id = 0;
Krzysztof Opasiak903124f2015-03-20 15:48:56 +01001256 memset(c->interface, 0, sizeof(c->interface));
John Youn554eead2016-02-05 17:06:35 -08001257 c->superspeed_plus = 0;
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001258 c->superspeed = 0;
1259 c->highspeed = 0;
1260 c->fullspeed = 0;
1261 }
1262}
1263
1264static int configfs_composite_bind(struct usb_gadget *gadget,
1265 struct usb_gadget_driver *gdriver)
1266{
1267 struct usb_composite_driver *composite = to_cdriver(gdriver);
1268 struct gadget_info *gi = container_of(composite,
1269 struct gadget_info, composite);
1270 struct usb_composite_dev *cdev = &gi->cdev;
1271 struct usb_configuration *c;
1272 struct usb_string *s;
1273 unsigned i;
1274 int ret;
1275
1276 /* the gi->lock is hold by the caller */
Peter Chenaa919ef2019-08-26 15:10:55 -04001277 gi->unbind = 0;
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001278 cdev->gadget = gadget;
1279 set_gadget_data(gadget, cdev);
1280 ret = composite_dev_prepare(composite, cdev);
1281 if (ret)
1282 return ret;
1283 /* and now the gadget bind */
1284 ret = -EINVAL;
1285
1286 if (list_empty(&gi->cdev.configs)) {
Peter Chen4d9f8722014-05-05 07:39:34 +08001287 pr_err("Need at least one configuration in %s.\n",
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001288 gi->composite.name);
1289 goto err_comp_cleanup;
1290 }
1291
1292
1293 list_for_each_entry(c, &gi->cdev.configs, list) {
1294 struct config_usb_cfg *cfg;
1295
1296 cfg = container_of(c, struct config_usb_cfg, c);
1297 if (list_empty(&cfg->func_list)) {
Peter Chen4d9f8722014-05-05 07:39:34 +08001298 pr_err("Config %s/%d of %s needs at least one function.\n",
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001299 c->label, c->bConfigurationValue,
1300 gi->composite.name);
1301 goto err_comp_cleanup;
1302 }
1303 }
1304
1305 /* init all strings */
1306 if (!list_empty(&gi->string_list)) {
1307 struct gadget_strings *gs;
1308
1309 i = 0;
1310 list_for_each_entry(gs, &gi->string_list, list) {
1311
1312 gi->gstrings[i] = &gs->stringtab_dev;
1313 gs->stringtab_dev.strings = gs->strings;
1314 gs->strings[USB_GADGET_MANUFACTURER_IDX].s =
1315 gs->manufacturer;
1316 gs->strings[USB_GADGET_PRODUCT_IDX].s = gs->product;
1317 gs->strings[USB_GADGET_SERIAL_IDX].s = gs->serialnumber;
1318 i++;
1319 }
1320 gi->gstrings[i] = NULL;
1321 s = usb_gstrings_attach(&gi->cdev, gi->gstrings,
1322 USB_GADGET_FIRST_AVAIL_IDX);
Wei Yongjunfea77072013-05-07 19:50:31 +08001323 if (IS_ERR(s)) {
1324 ret = PTR_ERR(s);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001325 goto err_comp_cleanup;
Wei Yongjunfea77072013-05-07 19:50:31 +08001326 }
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001327
1328 gi->cdev.desc.iManufacturer = s[USB_GADGET_MANUFACTURER_IDX].id;
1329 gi->cdev.desc.iProduct = s[USB_GADGET_PRODUCT_IDX].id;
1330 gi->cdev.desc.iSerialNumber = s[USB_GADGET_SERIAL_IDX].id;
1331 }
1332
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +02001333 if (gi->use_os_desc) {
1334 cdev->use_os_string = true;
1335 cdev->b_vendor_code = gi->b_vendor_code;
1336 memcpy(cdev->qw_sign, gi->qw_sign, OS_STRING_QW_SIGN_LEN);
1337 }
1338
Li Jun41ce84c2015-07-09 15:18:48 +08001339 if (gadget_is_otg(gadget) && !otg_desc[0]) {
1340 struct usb_descriptor_header *usb_desc;
1341
1342 usb_desc = usb_otg_descriptor_alloc(gadget);
1343 if (!usb_desc) {
1344 ret = -ENOMEM;
1345 goto err_comp_cleanup;
1346 }
1347 usb_otg_descriptor_init(gadget, usb_desc);
1348 otg_desc[0] = usb_desc;
1349 otg_desc[1] = NULL;
1350 }
1351
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001352 /* Go through all configs, attach all functions */
1353 list_for_each_entry(c, &gi->cdev.configs, list) {
1354 struct config_usb_cfg *cfg;
1355 struct usb_function *f;
1356 struct usb_function *tmp;
1357 struct gadget_config_name *cn;
1358
Li Jun41ce84c2015-07-09 15:18:48 +08001359 if (gadget_is_otg(gadget))
1360 c->descriptors = otg_desc;
1361
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001362 cfg = container_of(c, struct config_usb_cfg, c);
1363 if (!list_empty(&cfg->string_list)) {
1364 i = 0;
1365 list_for_each_entry(cn, &cfg->string_list, list) {
1366 cfg->gstrings[i] = &cn->stringtab_dev;
1367 cn->stringtab_dev.strings = &cn->strings;
1368 cn->strings.s = cn->configuration;
1369 i++;
1370 }
1371 cfg->gstrings[i] = NULL;
1372 s = usb_gstrings_attach(&gi->cdev, cfg->gstrings, 1);
Wei Yongjunfea77072013-05-07 19:50:31 +08001373 if (IS_ERR(s)) {
1374 ret = PTR_ERR(s);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001375 goto err_comp_cleanup;
Wei Yongjunfea77072013-05-07 19:50:31 +08001376 }
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001377 c->iConfiguration = s[0].id;
1378 }
1379
1380 list_for_each_entry_safe(f, tmp, &cfg->func_list, list) {
1381 list_del(&f->list);
1382 ret = usb_add_function(c, f);
Andrzej Pietrasiewicz5a68e9b2013-08-08 09:43:28 +02001383 if (ret) {
1384 list_add(&f->list, &cfg->func_list);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001385 goto err_purge_funcs;
Andrzej Pietrasiewicz5a68e9b2013-08-08 09:43:28 +02001386 }
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001387 }
1388 usb_ep_autoconfig_reset(cdev->gadget);
1389 }
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001390 if (cdev->use_os_string) {
1391 ret = composite_os_desc_req_prepare(cdev, gadget->ep0);
1392 if (ret)
1393 goto err_purge_funcs;
1394 }
1395
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001396 usb_ep_autoconfig_reset(cdev->gadget);
1397 return 0;
1398
1399err_purge_funcs:
1400 purge_configs_funcs(gi);
1401err_comp_cleanup:
1402 composite_dev_cleanup(cdev);
1403 return ret;
1404}
1405
Badhri Jagan Sridharan21877382014-12-15 10:44:47 -08001406#ifdef CONFIG_USB_CONFIGFS_UEVENT
1407static void android_work(struct work_struct *data)
1408{
1409 struct gadget_info *gi = container_of(data, struct gadget_info, work);
1410 struct usb_composite_dev *cdev = &gi->cdev;
1411 char *disconnected[2] = { "USB_STATE=DISCONNECTED", NULL };
1412 char *connected[2] = { "USB_STATE=CONNECTED", NULL };
1413 char *configured[2] = { "USB_STATE=CONFIGURED", NULL };
1414 /* 0-connected 1-configured 2-disconnected*/
1415 bool status[3] = { false, false, false };
1416 unsigned long flags;
1417 bool uevent_sent = false;
1418
1419 spin_lock_irqsave(&cdev->lock, flags);
1420 if (cdev->config)
1421 status[1] = true;
1422
1423 if (gi->connected != gi->sw_connected) {
1424 if (gi->connected)
1425 status[0] = true;
1426 else
1427 status[2] = true;
1428 gi->sw_connected = gi->connected;
1429 }
1430 spin_unlock_irqrestore(&cdev->lock, flags);
1431
1432 if (status[0]) {
Badhri Jagan Sridharand6b2d772015-03-27 14:15:19 -07001433 kobject_uevent_env(&android_device->kobj,
1434 KOBJ_CHANGE, connected);
Badhri Jagan Sridharan21877382014-12-15 10:44:47 -08001435 pr_info("%s: sent uevent %s\n", __func__, connected[0]);
1436 uevent_sent = true;
1437 }
1438
1439 if (status[1]) {
Badhri Jagan Sridharand6b2d772015-03-27 14:15:19 -07001440 kobject_uevent_env(&android_device->kobj,
1441 KOBJ_CHANGE, configured);
Badhri Jagan Sridharan21877382014-12-15 10:44:47 -08001442 pr_info("%s: sent uevent %s\n", __func__, configured[0]);
1443 uevent_sent = true;
1444 }
1445
1446 if (status[2]) {
Badhri Jagan Sridharand6b2d772015-03-27 14:15:19 -07001447 kobject_uevent_env(&android_device->kobj,
1448 KOBJ_CHANGE, disconnected);
Badhri Jagan Sridharan21877382014-12-15 10:44:47 -08001449 pr_info("%s: sent uevent %s\n", __func__, disconnected[0]);
1450 uevent_sent = true;
1451 }
1452
1453 if (!uevent_sent) {
1454 pr_info("%s: did not send uevent (%d %d %p)\n", __func__,
1455 gi->connected, gi->sw_connected, cdev->config);
1456 }
1457}
1458#endif
1459
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001460static void configfs_composite_unbind(struct usb_gadget *gadget)
1461{
1462 struct usb_composite_dev *cdev;
1463 struct gadget_info *gi;
Peter Chenaa919ef2019-08-26 15:10:55 -04001464 unsigned long flags;
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001465
1466 /* the gi->lock is hold by the caller */
1467
1468 cdev = get_gadget_data(gadget);
1469 gi = container_of(cdev, struct gadget_info, cdev);
Peter Chenaa919ef2019-08-26 15:10:55 -04001470 spin_lock_irqsave(&gi->spinlock, flags);
1471 gi->unbind = 1;
1472 spin_unlock_irqrestore(&gi->spinlock, flags);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001473
Li Jun41ce84c2015-07-09 15:18:48 +08001474 kfree(otg_desc[0]);
1475 otg_desc[0] = NULL;
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001476 purge_configs_funcs(gi);
1477 composite_dev_cleanup(cdev);
1478 usb_ep_autoconfig_reset(cdev->gadget);
Peter Chenaa919ef2019-08-26 15:10:55 -04001479 spin_lock_irqsave(&gi->spinlock, flags);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001480 cdev->gadget = NULL;
1481 set_gadget_data(gadget, NULL);
Peter Chenaa919ef2019-08-26 15:10:55 -04001482 spin_unlock_irqrestore(&gi->spinlock, flags);
1483}
1484
1485static int configfs_composite_setup(struct usb_gadget *gadget,
1486 const struct usb_ctrlrequest *ctrl)
1487{
1488 struct usb_composite_dev *cdev;
1489 struct gadget_info *gi;
1490 unsigned long flags;
1491 int ret;
1492
1493 cdev = get_gadget_data(gadget);
1494 if (!cdev)
1495 return 0;
1496
1497 gi = container_of(cdev, struct gadget_info, cdev);
1498 spin_lock_irqsave(&gi->spinlock, flags);
1499 cdev = get_gadget_data(gadget);
1500 if (!cdev || gi->unbind) {
1501 spin_unlock_irqrestore(&gi->spinlock, flags);
1502 return 0;
1503 }
1504
1505 ret = composite_setup(gadget, ctrl);
1506 spin_unlock_irqrestore(&gi->spinlock, flags);
1507 return ret;
1508}
1509
1510static void configfs_composite_disconnect(struct usb_gadget *gadget)
1511{
1512 struct usb_composite_dev *cdev;
1513 struct gadget_info *gi;
1514 unsigned long flags;
1515
1516 cdev = get_gadget_data(gadget);
1517 if (!cdev)
1518 return;
1519
1520 gi = container_of(cdev, struct gadget_info, cdev);
1521 spin_lock_irqsave(&gi->spinlock, flags);
1522 cdev = get_gadget_data(gadget);
1523 if (!cdev || gi->unbind) {
1524 spin_unlock_irqrestore(&gi->spinlock, flags);
1525 return;
1526 }
1527
1528 composite_disconnect(gadget);
1529 spin_unlock_irqrestore(&gi->spinlock, flags);
1530}
1531
1532static void configfs_composite_suspend(struct usb_gadget *gadget)
1533{
1534 struct usb_composite_dev *cdev;
1535 struct gadget_info *gi;
1536 unsigned long flags;
1537
1538 cdev = get_gadget_data(gadget);
1539 if (!cdev)
1540 return;
1541
1542 gi = container_of(cdev, struct gadget_info, cdev);
1543 spin_lock_irqsave(&gi->spinlock, flags);
1544 cdev = get_gadget_data(gadget);
1545 if (!cdev || gi->unbind) {
1546 spin_unlock_irqrestore(&gi->spinlock, flags);
1547 return;
1548 }
1549
1550 composite_suspend(gadget);
1551 spin_unlock_irqrestore(&gi->spinlock, flags);
1552}
1553
1554static void configfs_composite_resume(struct usb_gadget *gadget)
1555{
1556 struct usb_composite_dev *cdev;
1557 struct gadget_info *gi;
1558 unsigned long flags;
1559
1560 cdev = get_gadget_data(gadget);
1561 if (!cdev)
1562 return;
1563
1564 gi = container_of(cdev, struct gadget_info, cdev);
1565 spin_lock_irqsave(&gi->spinlock, flags);
1566 cdev = get_gadget_data(gadget);
1567 if (!cdev || gi->unbind) {
1568 spin_unlock_irqrestore(&gi->spinlock, flags);
1569 return;
1570 }
1571
1572 composite_resume(gadget);
1573 spin_unlock_irqrestore(&gi->spinlock, flags);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001574}
1575
Badhri Jagan Sridharan21877382014-12-15 10:44:47 -08001576#ifdef CONFIG_USB_CONFIGFS_UEVENT
1577static int android_setup(struct usb_gadget *gadget,
1578 const struct usb_ctrlrequest *c)
1579{
1580 struct usb_composite_dev *cdev = get_gadget_data(gadget);
1581 unsigned long flags;
1582 struct gadget_info *gi = container_of(cdev, struct gadget_info, cdev);
1583 int value = -EOPNOTSUPP;
1584 struct usb_function_instance *fi;
1585
1586 spin_lock_irqsave(&cdev->lock, flags);
1587 if (!gi->connected) {
1588 gi->connected = 1;
1589 schedule_work(&gi->work);
1590 }
1591 spin_unlock_irqrestore(&cdev->lock, flags);
1592 list_for_each_entry(fi, &gi->available_func, cfs_list) {
1593 if (fi != NULL && fi->f != NULL && fi->f->setup != NULL) {
1594 value = fi->f->setup(fi->f, c);
1595 if (value >= 0)
1596 break;
1597 }
1598 }
1599
1600#ifdef CONFIG_USB_CONFIGFS_F_ACC
1601 if (value < 0)
1602 value = acc_ctrlrequest(cdev, c);
1603#endif
1604
1605 if (value < 0)
1606 value = composite_setup(gadget, c);
1607
1608 spin_lock_irqsave(&cdev->lock, flags);
1609 if (c->bRequest == USB_REQ_SET_CONFIGURATION &&
1610 cdev->config) {
1611 schedule_work(&gi->work);
1612 }
1613 spin_unlock_irqrestore(&cdev->lock, flags);
1614
1615 return value;
1616}
1617
1618static void android_disconnect(struct usb_gadget *gadget)
1619{
1620 struct usb_composite_dev *cdev = get_gadget_data(gadget);
1621 struct gadget_info *gi = container_of(cdev, struct gadget_info, cdev);
1622
Danilo Krummrich6e055352017-08-14 12:45:38 +02001623 /* FIXME: There's a race between usb_gadget_udc_stop() which is likely
1624 * to set the gadget driver to NULL in the udc driver and this drivers
1625 * gadget disconnect fn which likely checks for the gadget driver to
1626 * be a null ptr. It happens that unbind (doing set_gadget_data(NULL))
1627 * is called before the gadget driver is set to NULL and the udc driver
1628 * calls disconnect fn which results in cdev being a null ptr.
1629 */
1630 if (cdev == NULL) {
1631 WARN(1, "%s: gadget driver already disconnected\n", __func__);
1632 return;
1633 }
1634
Badhri Jagan Sridharan21877382014-12-15 10:44:47 -08001635 /* accessory HID support can be active while the
1636 accessory function is not actually enabled,
1637 so we need to inform it when we are disconnected.
1638 */
1639
1640#ifdef CONFIG_USB_CONFIGFS_F_ACC
1641 acc_disconnect();
1642#endif
1643 gi->connected = 0;
1644 schedule_work(&gi->work);
1645 composite_disconnect(gadget);
1646}
1647#endif
1648
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001649static const struct usb_gadget_driver configfs_driver_template = {
1650 .bind = configfs_composite_bind,
1651 .unbind = configfs_composite_unbind,
Badhri Jagan Sridharan21877382014-12-15 10:44:47 -08001652#ifdef CONFIG_USB_CONFIGFS_UEVENT
1653 .setup = android_setup,
Amit Pundir9214c892015-10-06 20:53:27 +05301654 .reset = android_disconnect,
Badhri Jagan Sridharan21877382014-12-15 10:44:47 -08001655 .disconnect = android_disconnect,
1656#else
Peter Chenaa919ef2019-08-26 15:10:55 -04001657 .setup = configfs_composite_setup,
1658 .reset = configfs_composite_disconnect,
1659 .disconnect = configfs_composite_disconnect,
Badhri Jagan Sridharan21877382014-12-15 10:44:47 -08001660#endif
Peter Chenaa919ef2019-08-26 15:10:55 -04001661 .suspend = configfs_composite_suspend,
1662 .resume = configfs_composite_resume,
Andrzej Pietrasiewicz3a571872014-10-08 12:03:36 +02001663
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001664 .max_speed = USB_SPEED_SUPER,
1665 .driver = {
1666 .owner = THIS_MODULE,
1667 .name = "configfs-gadget",
1668 },
Krzysztof Opasiakf1bddbb2016-05-05 10:46:05 +02001669 .match_existing_only = 1,
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001670};
1671
Badhri Jagan Sridharan9150ea12015-07-14 15:46:11 -07001672#ifdef CONFIG_USB_CONFIGFS_UEVENT
1673static ssize_t state_show(struct device *pdev, struct device_attribute *attr,
1674 char *buf)
1675{
1676 struct gadget_info *dev = dev_get_drvdata(pdev);
1677 struct usb_composite_dev *cdev;
1678 char *state = "DISCONNECTED";
1679 unsigned long flags;
1680
1681 if (!dev)
1682 goto out;
1683
1684 cdev = &dev->cdev;
1685
1686 if (!cdev)
1687 goto out;
1688
1689 spin_lock_irqsave(&cdev->lock, flags);
1690 if (cdev->config)
1691 state = "CONFIGURED";
1692 else if (dev->connected)
1693 state = "CONNECTED";
1694 spin_unlock_irqrestore(&cdev->lock, flags);
1695out:
1696 return sprintf(buf, "%s\n", state);
1697}
1698
1699static DEVICE_ATTR(state, S_IRUGO, state_show, NULL);
1700
1701static struct device_attribute *android_usb_attributes[] = {
1702 &dev_attr_state,
1703 NULL
1704};
Badhri Jagan Sridharan560f0132015-08-09 15:12:50 -07001705
1706static int android_device_create(struct gadget_info *gi)
1707{
1708 struct device_attribute **attrs;
1709 struct device_attribute *attr;
1710
1711 INIT_WORK(&gi->work, android_work);
1712 android_device = device_create(android_class, NULL,
1713 MKDEV(0, 0), NULL, "android0");
1714 if (IS_ERR(android_device))
1715 return PTR_ERR(android_device);
1716
1717 dev_set_drvdata(android_device, gi);
1718
1719 attrs = android_usb_attributes;
1720 while ((attr = *attrs++)) {
1721 int err;
1722
1723 err = device_create_file(android_device, attr);
1724 if (err) {
1725 device_destroy(android_device->class,
1726 android_device->devt);
1727 return err;
1728 }
1729 }
1730
1731 return 0;
1732}
1733
1734static void android_device_destroy(void)
1735{
1736 struct device_attribute **attrs;
1737 struct device_attribute *attr;
1738
1739 attrs = android_usb_attributes;
1740 while ((attr = *attrs++))
1741 device_remove_file(android_device, attr);
1742 device_destroy(android_device->class, android_device->devt);
1743}
1744#else
1745static inline int android_device_create(struct gadget_info *gi)
1746{
1747 return 0;
1748}
1749
1750static inline void android_device_destroy(void)
1751{
1752}
Badhri Jagan Sridharan9150ea12015-07-14 15:46:11 -07001753#endif
1754
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001755static struct config_group *gadgets_make(
1756 struct config_group *group,
1757 const char *name)
1758{
1759 struct gadget_info *gi;
1760
1761 gi = kzalloc(sizeof(*gi), GFP_KERNEL);
1762 if (!gi)
1763 return ERR_PTR(-ENOMEM);
1764
Christoph Hellwig1ae16022016-02-26 11:02:14 +01001765 config_group_init_type_name(&gi->group, name, &gadget_root_type);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001766
1767 config_group_init_type_name(&gi->functions_group, "functions",
1768 &functions_type);
Christoph Hellwig1ae16022016-02-26 11:02:14 +01001769 configfs_add_default_group(&gi->functions_group, &gi->group);
1770
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001771 config_group_init_type_name(&gi->configs_group, "configs",
1772 &config_desc_type);
Christoph Hellwig1ae16022016-02-26 11:02:14 +01001773 configfs_add_default_group(&gi->configs_group, &gi->group);
1774
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001775 config_group_init_type_name(&gi->strings_group, "strings",
1776 &gadget_strings_strings_type);
Christoph Hellwig1ae16022016-02-26 11:02:14 +01001777 configfs_add_default_group(&gi->strings_group, &gi->group);
1778
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +02001779 config_group_init_type_name(&gi->os_desc_group, "os_desc",
1780 &os_desc_type);
Christoph Hellwig1ae16022016-02-26 11:02:14 +01001781 configfs_add_default_group(&gi->os_desc_group, &gi->group);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001782
1783 gi->composite.bind = configfs_do_nothing;
1784 gi->composite.unbind = configfs_do_nothing;
1785 gi->composite.suspend = NULL;
1786 gi->composite.resume = NULL;
1787 gi->composite.max_speed = USB_SPEED_SUPER;
1788
Wei Yongjunbe17a732019-10-30 03:40:46 +00001789 spin_lock_init(&gi->spinlock);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001790 mutex_init(&gi->lock);
1791 INIT_LIST_HEAD(&gi->string_list);
1792 INIT_LIST_HEAD(&gi->available_func);
1793
1794 composite_init_dev(&gi->cdev);
1795 gi->cdev.desc.bLength = USB_DT_DEVICE_SIZE;
1796 gi->cdev.desc.bDescriptorType = USB_DT_DEVICE;
1797 gi->cdev.desc.bcdDevice = cpu_to_le16(get_default_bcdDevice());
1798
1799 gi->composite.gadget_driver = configfs_driver_template;
1800
1801 gi->composite.gadget_driver.function = kstrdup(name, GFP_KERNEL);
1802 gi->composite.name = gi->composite.gadget_driver.function;
1803
Badhri Jagan Sridharan560f0132015-08-09 15:12:50 -07001804 if (!gi->composite.gadget_driver.function)
Badhri Jagan Sridharand6b2d772015-03-27 14:15:19 -07001805 goto err;
Badhri Jagan Sridharan9150ea12015-07-14 15:46:11 -07001806
Badhri Jagan Sridharan560f0132015-08-09 15:12:50 -07001807 if (android_device_create(gi) < 0)
1808 goto err;
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001809
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001810 return &gi->group;
Badhri Jagan Sridharan9150ea12015-07-14 15:46:11 -07001811
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001812err:
1813 kfree(gi);
1814 return ERR_PTR(-ENOMEM);
1815}
1816
1817static void gadgets_drop(struct config_group *group, struct config_item *item)
1818{
1819 config_item_put(item);
Badhri Jagan Sridharan560f0132015-08-09 15:12:50 -07001820 android_device_destroy();
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001821}
1822
1823static struct configfs_group_operations gadgets_ops = {
1824 .make_group = &gadgets_make,
1825 .drop_item = &gadgets_drop,
1826};
1827
1828static struct config_item_type gadgets_type = {
1829 .ct_group_ops = &gadgets_ops,
1830 .ct_owner = THIS_MODULE,
1831};
1832
1833static struct configfs_subsystem gadget_subsys = {
1834 .su_group = {
1835 .cg_item = {
1836 .ci_namebuf = "usb_gadget",
1837 .ci_type = &gadgets_type,
1838 },
1839 },
1840 .su_mutex = __MUTEX_INITIALIZER(gadget_subsys.su_mutex),
1841};
1842
Andrzej Pietrasiewicz092a4bd2013-09-26 14:38:15 +02001843void unregister_gadget_item(struct config_item *item)
1844{
1845 struct gadget_info *gi = to_gadget_info(item);
1846
Winter Wangcee51c32016-07-27 10:03:19 +08001847 mutex_lock(&gi->lock);
Andrzej Pietrasiewicz092a4bd2013-09-26 14:38:15 +02001848 unregister_gadget(gi);
Winter Wangcee51c32016-07-27 10:03:19 +08001849 mutex_unlock(&gi->lock);
Andrzej Pietrasiewicz092a4bd2013-09-26 14:38:15 +02001850}
Felipe Balbi0700faa2014-04-01 13:19:32 -05001851EXPORT_SYMBOL_GPL(unregister_gadget_item);
Andrzej Pietrasiewicz092a4bd2013-09-26 14:38:15 +02001852
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001853static int __init gadget_cfs_init(void)
1854{
1855 int ret;
1856
1857 config_group_init(&gadget_subsys.su_group);
1858
1859 ret = configfs_register_subsystem(&gadget_subsys);
Badhri Jagan Sridharan21877382014-12-15 10:44:47 -08001860
1861#ifdef CONFIG_USB_CONFIGFS_UEVENT
1862 android_class = class_create(THIS_MODULE, "android_usb");
1863 if (IS_ERR(android_class))
1864 return PTR_ERR(android_class);
1865#endif
1866
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001867 return ret;
1868}
1869module_init(gadget_cfs_init);
1870
1871static void __exit gadget_cfs_exit(void)
1872{
1873 configfs_unregister_subsystem(&gadget_subsys);
Badhri Jagan Sridharand6b2d772015-03-27 14:15:19 -07001874#ifdef CONFIG_USB_CONFIGFS_UEVENT
1875 if (!IS_ERR(android_class))
1876 class_destroy(android_class);
1877#endif
1878
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001879}
1880module_exit(gadget_cfs_exit);