blob: f779fdc30a9701b2c54af8ccb2ce14d76c073c8f [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 Sridharan1c3865d2014-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 Sridharan1c3865d2014-12-15 10:44:47 -080016
Ziqi Chenc35ae882017-09-26 18:48:28 +080017#ifdef CONFIG_USB_F_NCM
18#include <function/u_ncm.h>
19#endif
20
Badhri Jagan Sridharan1c3865d2014-12-15 10:44:47 -080021#ifdef CONFIG_USB_CONFIGFS_F_ACC
22extern int acc_ctrlrequest(struct usb_composite_dev *cdev,
23 const struct usb_ctrlrequest *ctrl);
24void acc_disconnect(void);
25#endif
Ziqi Chenc35ae882017-09-26 18:48:28 +080026
Badhri Jagan Sridharan1c3865d2014-12-15 10:44:47 -080027static struct class *android_class;
Badhri Jagan Sridharan2a387e52015-03-27 14:15:19 -070028static struct device *android_device;
29static int index;
Ajay Agarwalfea56da2017-05-30 10:27:23 +053030static int gadget_index;
Badhri Jagan Sridharan2a387e52015-03-27 14:15:19 -070031
32struct device *create_function_device(char *name)
33{
34 if (android_device && !IS_ERR(android_device))
35 return device_create(android_class, android_device,
36 MKDEV(0, index++), NULL, name);
37 else
38 return ERR_PTR(-EINVAL);
39}
40EXPORT_SYMBOL_GPL(create_function_device);
Badhri Jagan Sridharan1c3865d2014-12-15 10:44:47 -080041#endif
42
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +010043int check_user_usb_string(const char *name,
44 struct usb_gadget_strings *stringtab_dev)
45{
46 unsigned primary_lang;
47 unsigned sub_lang;
48 u16 num;
49 int ret;
50
51 ret = kstrtou16(name, 0, &num);
52 if (ret)
53 return ret;
54
55 primary_lang = num & 0x3ff;
56 sub_lang = num >> 10;
57
58 /* simple sanity check for valid langid */
59 switch (primary_lang) {
60 case 0:
61 case 0x62 ... 0xfe:
62 case 0x100 ... 0x3ff:
63 return -EINVAL;
64 }
65 if (!sub_lang)
66 return -EINVAL;
67
68 stringtab_dev->language = num;
69 return 0;
70}
71
72#define MAX_NAME_LEN 40
73#define MAX_USB_STRING_LANGS 2
74
Li Jun41ce84c2015-07-09 15:18:48 +080075static const struct usb_descriptor_header *otg_desc[2];
76
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +010077struct gadget_info {
78 struct config_group group;
79 struct config_group functions_group;
80 struct config_group configs_group;
81 struct config_group strings_group;
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +020082 struct config_group os_desc_group;
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +010083
84 struct mutex lock;
85 struct usb_gadget_strings *gstrings[MAX_USB_STRING_LANGS + 1];
86 struct list_head string_list;
87 struct list_head available_func;
88
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +010089 struct usb_composite_driver composite;
90 struct usb_composite_dev cdev;
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +020091 bool use_os_desc;
Vijayavardhan Vennapusa4ca835b2017-10-30 14:33:51 +053092 bool unbinding;
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +020093 char b_vendor_code;
94 char qw_sign[OS_STRING_QW_SIGN_LEN];
Badhri Jagan Sridharan1c3865d2014-12-15 10:44:47 -080095#ifdef CONFIG_USB_CONFIGFS_UEVENT
96 bool connected;
97 bool sw_connected;
98 struct work_struct work;
99 struct device *dev;
100#endif
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100101};
102
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200103static inline struct gadget_info *to_gadget_info(struct config_item *item)
104{
105 return container_of(to_config_group(item), struct gadget_info, group);
106}
107
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100108struct config_usb_cfg {
109 struct config_group group;
110 struct config_group strings_group;
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100111 struct list_head string_list;
112 struct usb_configuration c;
113 struct list_head func_list;
114 struct usb_gadget_strings *gstrings[MAX_USB_STRING_LANGS + 1];
115};
116
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200117static inline struct config_usb_cfg *to_config_usb_cfg(struct config_item *item)
118{
119 return container_of(to_config_group(item), struct config_usb_cfg,
120 group);
121}
122
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100123struct gadget_strings {
124 struct usb_gadget_strings stringtab_dev;
125 struct usb_string strings[USB_GADGET_FIRST_AVAIL_IDX];
126 char *manufacturer;
127 char *product;
128 char *serialnumber;
129
130 struct config_group group;
131 struct list_head list;
132};
133
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200134struct os_desc {
135 struct config_group group;
136};
137
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100138struct gadget_config_name {
139 struct usb_gadget_strings stringtab_dev;
140 struct usb_string strings;
141 char *configuration;
142
143 struct config_group group;
144 struct list_head list;
145};
146
Jim Lin240e2d02017-01-13 16:07:58 +0800147#define MAX_USB_STRING_LEN 126
148#define MAX_USB_STRING_WITH_NULL_LEN (MAX_USB_STRING_LEN+1)
149
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100150static int usb_string_copy(const char *s, char **s_copy)
151{
152 int ret;
153 char *str;
154 char *copy = *s_copy;
155 ret = strlen(s);
Jim Lin240e2d02017-01-13 16:07:58 +0800156 if (ret > MAX_USB_STRING_LEN)
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100157 return -EOVERFLOW;
158
Jim Lin240e2d02017-01-13 16:07:58 +0800159 if (copy) {
160 str = copy;
161 } else {
162 str = kmalloc(MAX_USB_STRING_WITH_NULL_LEN, GFP_KERNEL);
163 if (!str)
164 return -ENOMEM;
165 }
Manu Gautam7fffcd42017-03-28 11:28:24 +0530166 strlcpy(str, s, MAX_USB_STRING_WITH_NULL_LEN);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100167 if (str[ret - 1] == '\n')
168 str[ret - 1] = '\0';
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100169 *s_copy = str;
170 return 0;
171}
172
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100173#define GI_DEVICE_DESC_SIMPLE_R_u8(__name) \
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200174static ssize_t gadget_dev_desc_##__name##_show(struct config_item *item, \
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100175 char *page) \
176{ \
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200177 return sprintf(page, "0x%02x\n", \
178 to_gadget_info(item)->cdev.desc.__name); \
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100179}
180
181#define GI_DEVICE_DESC_SIMPLE_R_u16(__name) \
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200182static ssize_t gadget_dev_desc_##__name##_show(struct config_item *item, \
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100183 char *page) \
184{ \
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200185 return sprintf(page, "0x%04x\n", \
186 le16_to_cpup(&to_gadget_info(item)->cdev.desc.__name)); \
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100187}
188
189
190#define GI_DEVICE_DESC_SIMPLE_W_u8(_name) \
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200191static ssize_t gadget_dev_desc_##_name##_store(struct config_item *item, \
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100192 const char *page, size_t len) \
193{ \
194 u8 val; \
195 int ret; \
196 ret = kstrtou8(page, 0, &val); \
197 if (ret) \
198 return ret; \
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200199 to_gadget_info(item)->cdev.desc._name = val; \
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100200 return len; \
201}
202
203#define GI_DEVICE_DESC_SIMPLE_W_u16(_name) \
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200204static ssize_t gadget_dev_desc_##_name##_store(struct config_item *item, \
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100205 const char *page, size_t len) \
206{ \
207 u16 val; \
208 int ret; \
209 ret = kstrtou16(page, 0, &val); \
210 if (ret) \
211 return ret; \
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200212 to_gadget_info(item)->cdev.desc._name = cpu_to_le16p(&val); \
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100213 return len; \
214}
215
216#define GI_DEVICE_DESC_SIMPLE_RW(_name, _type) \
217 GI_DEVICE_DESC_SIMPLE_R_##_type(_name) \
218 GI_DEVICE_DESC_SIMPLE_W_##_type(_name)
219
220GI_DEVICE_DESC_SIMPLE_R_u16(bcdUSB);
221GI_DEVICE_DESC_SIMPLE_RW(bDeviceClass, u8);
222GI_DEVICE_DESC_SIMPLE_RW(bDeviceSubClass, u8);
223GI_DEVICE_DESC_SIMPLE_RW(bDeviceProtocol, u8);
224GI_DEVICE_DESC_SIMPLE_RW(bMaxPacketSize0, u8);
225GI_DEVICE_DESC_SIMPLE_RW(idVendor, u16);
226GI_DEVICE_DESC_SIMPLE_RW(idProduct, u16);
227GI_DEVICE_DESC_SIMPLE_R_u16(bcdDevice);
228
229static ssize_t is_valid_bcd(u16 bcd_val)
230{
231 if ((bcd_val & 0xf) > 9)
232 return -EINVAL;
233 if (((bcd_val >> 4) & 0xf) > 9)
234 return -EINVAL;
235 if (((bcd_val >> 8) & 0xf) > 9)
236 return -EINVAL;
237 if (((bcd_val >> 12) & 0xf) > 9)
238 return -EINVAL;
239 return 0;
240}
241
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200242static ssize_t gadget_dev_desc_bcdDevice_store(struct config_item *item,
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100243 const char *page, size_t len)
244{
245 u16 bcdDevice;
246 int ret;
247
248 ret = kstrtou16(page, 0, &bcdDevice);
249 if (ret)
250 return ret;
251 ret = is_valid_bcd(bcdDevice);
252 if (ret)
253 return ret;
254
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200255 to_gadget_info(item)->cdev.desc.bcdDevice = cpu_to_le16(bcdDevice);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100256 return len;
257}
258
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200259static ssize_t gadget_dev_desc_bcdUSB_store(struct config_item *item,
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100260 const char *page, size_t len)
261{
262 u16 bcdUSB;
263 int ret;
264
265 ret = kstrtou16(page, 0, &bcdUSB);
266 if (ret)
267 return ret;
268 ret = is_valid_bcd(bcdUSB);
269 if (ret)
270 return ret;
271
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200272 to_gadget_info(item)->cdev.desc.bcdUSB = cpu_to_le16(bcdUSB);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100273 return len;
274}
275
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200276static ssize_t gadget_dev_desc_UDC_show(struct config_item *item, char *page)
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100277{
Ruslan Bilovolafdaadc2015-11-23 09:56:36 +0100278 char *udc_name = to_gadget_info(item)->composite.gadget_driver.udc_name;
279
280 return sprintf(page, "%s\n", udc_name ?: "");
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100281}
282
283static int unregister_gadget(struct gadget_info *gi)
284{
285 int ret;
286
Ruslan Bilovolafdaadc2015-11-23 09:56:36 +0100287 if (!gi->composite.gadget_driver.udc_name)
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100288 return -ENODEV;
289
Vijayavardhan Vennapusa4ca835b2017-10-30 14:33:51 +0530290 gi->unbinding = true;
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100291 ret = usb_gadget_unregister_driver(&gi->composite.gadget_driver);
292 if (ret)
293 return ret;
Vijayavardhan Vennapusa4ca835b2017-10-30 14:33:51 +0530294
295 gi->unbinding = false;
Ruslan Bilovolafdaadc2015-11-23 09:56:36 +0100296 kfree(gi->composite.gadget_driver.udc_name);
297 gi->composite.gadget_driver.udc_name = NULL;
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100298 return 0;
299}
300
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200301static ssize_t gadget_dev_desc_UDC_store(struct config_item *item,
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100302 const char *page, size_t len)
303{
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200304 struct gadget_info *gi = to_gadget_info(item);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100305 char *name;
306 int ret;
307
308 name = kstrdup(page, GFP_KERNEL);
309 if (!name)
310 return -ENOMEM;
311 if (name[len - 1] == '\n')
312 name[len - 1] = '\0';
313
314 mutex_lock(&gi->lock);
315
Badhri Jagan Sridharan1c3865d2014-12-15 10:44:47 -0800316 if (!strlen(name) || strcmp(name, "none") == 0) {
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100317 ret = unregister_gadget(gi);
318 if (ret)
319 goto err;
John Keeping59682e72017-02-28 10:55:30 +0000320 kfree(name);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100321 } else {
Ruslan Bilovolafdaadc2015-11-23 09:56:36 +0100322 if (gi->composite.gadget_driver.udc_name) {
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100323 ret = -EBUSY;
324 goto err;
325 }
Ruslan Bilovolafdaadc2015-11-23 09:56:36 +0100326 gi->composite.gadget_driver.udc_name = name;
327 ret = usb_gadget_probe_driver(&gi->composite.gadget_driver);
328 if (ret) {
329 gi->composite.gadget_driver.udc_name = NULL;
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100330 goto err;
Ruslan Bilovolafdaadc2015-11-23 09:56:36 +0100331 }
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100332 }
333 mutex_unlock(&gi->lock);
334 return len;
335err:
336 kfree(name);
337 mutex_unlock(&gi->lock);
338 return ret;
339}
340
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200341CONFIGFS_ATTR(gadget_dev_desc_, bDeviceClass);
342CONFIGFS_ATTR(gadget_dev_desc_, bDeviceSubClass);
343CONFIGFS_ATTR(gadget_dev_desc_, bDeviceProtocol);
344CONFIGFS_ATTR(gadget_dev_desc_, bMaxPacketSize0);
345CONFIGFS_ATTR(gadget_dev_desc_, idVendor);
346CONFIGFS_ATTR(gadget_dev_desc_, idProduct);
347CONFIGFS_ATTR(gadget_dev_desc_, bcdDevice);
348CONFIGFS_ATTR(gadget_dev_desc_, bcdUSB);
349CONFIGFS_ATTR(gadget_dev_desc_, UDC);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100350
351static struct configfs_attribute *gadget_root_attrs[] = {
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200352 &gadget_dev_desc_attr_bDeviceClass,
353 &gadget_dev_desc_attr_bDeviceSubClass,
354 &gadget_dev_desc_attr_bDeviceProtocol,
355 &gadget_dev_desc_attr_bMaxPacketSize0,
356 &gadget_dev_desc_attr_idVendor,
357 &gadget_dev_desc_attr_idProduct,
358 &gadget_dev_desc_attr_bcdDevice,
359 &gadget_dev_desc_attr_bcdUSB,
360 &gadget_dev_desc_attr_UDC,
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100361 NULL,
362};
363
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100364static inline struct gadget_strings *to_gadget_strings(struct config_item *item)
365{
366 return container_of(to_config_group(item), struct gadget_strings,
367 group);
368}
369
370static inline struct gadget_config_name *to_gadget_config_name(
371 struct config_item *item)
372{
373 return container_of(to_config_group(item), struct gadget_config_name,
374 group);
375}
376
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100377static inline struct usb_function_instance *to_usb_function_instance(
378 struct config_item *item)
379{
380 return container_of(to_config_group(item),
381 struct usb_function_instance, group);
382}
383
384static void gadget_info_attr_release(struct config_item *item)
385{
386 struct gadget_info *gi = to_gadget_info(item);
387
388 WARN_ON(!list_empty(&gi->cdev.configs));
389 WARN_ON(!list_empty(&gi->string_list));
390 WARN_ON(!list_empty(&gi->available_func));
391 kfree(gi->composite.gadget_driver.function);
392 kfree(gi);
393}
394
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100395static struct configfs_item_operations gadget_root_item_ops = {
396 .release = gadget_info_attr_release,
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100397};
398
399static void gadget_config_attr_release(struct config_item *item)
400{
401 struct config_usb_cfg *cfg = to_config_usb_cfg(item);
402
403 WARN_ON(!list_empty(&cfg->c.functions));
404 list_del(&cfg->c.list);
405 kfree(cfg->c.label);
406 kfree(cfg);
407}
408
409static int config_usb_cfg_link(
410 struct config_item *usb_cfg_ci,
411 struct config_item *usb_func_ci)
412{
413 struct config_usb_cfg *cfg = to_config_usb_cfg(usb_cfg_ci);
414 struct usb_composite_dev *cdev = cfg->c.cdev;
415 struct gadget_info *gi = container_of(cdev, struct gadget_info, cdev);
416
417 struct config_group *group = to_config_group(usb_func_ci);
418 struct usb_function_instance *fi = container_of(group,
419 struct usb_function_instance, group);
420 struct usb_function_instance *a_fi;
421 struct usb_function *f;
422 int ret;
423
424 mutex_lock(&gi->lock);
425 /*
426 * Make sure this function is from within our _this_ gadget and not
427 * from another gadget or a random directory.
428 * Also a function instance can only be linked once.
429 */
430 list_for_each_entry(a_fi, &gi->available_func, cfs_list) {
431 if (a_fi == fi)
432 break;
433 }
434 if (a_fi != fi) {
435 ret = -EINVAL;
436 goto out;
437 }
438
439 list_for_each_entry(f, &cfg->func_list, list) {
440 if (f->fi == fi) {
441 ret = -EEXIST;
442 goto out;
443 }
444 }
445
446 f = usb_get_function(fi);
447 if (IS_ERR(f)) {
448 ret = PTR_ERR(f);
449 goto out;
450 }
451
452 /* stash the function until we bind it to the gadget */
453 list_add_tail(&f->list, &cfg->func_list);
454 ret = 0;
455out:
456 mutex_unlock(&gi->lock);
457 return ret;
458}
459
460static int config_usb_cfg_unlink(
461 struct config_item *usb_cfg_ci,
462 struct config_item *usb_func_ci)
463{
464 struct config_usb_cfg *cfg = to_config_usb_cfg(usb_cfg_ci);
465 struct usb_composite_dev *cdev = cfg->c.cdev;
466 struct gadget_info *gi = container_of(cdev, struct gadget_info, cdev);
467
468 struct config_group *group = to_config_group(usb_func_ci);
469 struct usb_function_instance *fi = container_of(group,
470 struct usb_function_instance, group);
471 struct usb_function *f;
472
473 /*
474 * ideally I would like to forbid to unlink functions while a gadget is
475 * bound to an UDC. Since this isn't possible at the moment, we simply
476 * force an unbind, the function is available here and then we can
477 * remove the function.
478 */
479 mutex_lock(&gi->lock);
Ruslan Bilovolafdaadc2015-11-23 09:56:36 +0100480 if (gi->composite.gadget_driver.udc_name)
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100481 unregister_gadget(gi);
Ruslan Bilovolafdaadc2015-11-23 09:56:36 +0100482 WARN_ON(gi->composite.gadget_driver.udc_name);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100483
484 list_for_each_entry(f, &cfg->func_list, list) {
485 if (f->fi == fi) {
486 list_del(&f->list);
487 usb_put_function(f);
488 mutex_unlock(&gi->lock);
489 return 0;
490 }
491 }
492 mutex_unlock(&gi->lock);
David Rientjes75bfe232013-04-07 14:11:47 -0700493 WARN(1, "Unable to locate function to unbind\n");
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100494 return 0;
495}
496
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100497static struct configfs_item_operations gadget_config_item_ops = {
498 .release = gadget_config_attr_release,
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100499 .allow_link = config_usb_cfg_link,
500 .drop_link = config_usb_cfg_unlink,
501};
502
503
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200504static ssize_t gadget_config_desc_MaxPower_show(struct config_item *item,
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100505 char *page)
506{
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200507 return sprintf(page, "%u\n", to_config_usb_cfg(item)->c.MaxPower);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100508}
509
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200510static ssize_t gadget_config_desc_MaxPower_store(struct config_item *item,
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100511 const char *page, size_t len)
512{
513 u16 val;
514 int ret;
515 ret = kstrtou16(page, 0, &val);
516 if (ret)
517 return ret;
518 if (DIV_ROUND_UP(val, 8) > 0xff)
519 return -ERANGE;
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200520 to_config_usb_cfg(item)->c.MaxPower = val;
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100521 return len;
522}
523
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200524static ssize_t gadget_config_desc_bmAttributes_show(struct config_item *item,
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100525 char *page)
526{
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200527 return sprintf(page, "0x%02x\n",
528 to_config_usb_cfg(item)->c.bmAttributes);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100529}
530
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200531static ssize_t gadget_config_desc_bmAttributes_store(struct config_item *item,
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100532 const char *page, size_t len)
533{
534 u8 val;
535 int ret;
536 ret = kstrtou8(page, 0, &val);
537 if (ret)
538 return ret;
539 if (!(val & USB_CONFIG_ATT_ONE))
540 return -EINVAL;
541 if (val & ~(USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER |
542 USB_CONFIG_ATT_WAKEUP))
543 return -EINVAL;
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200544 to_config_usb_cfg(item)->c.bmAttributes = val;
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100545 return len;
546}
547
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200548CONFIGFS_ATTR(gadget_config_desc_, MaxPower);
549CONFIGFS_ATTR(gadget_config_desc_, bmAttributes);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100550
551static struct configfs_attribute *gadget_config_attrs[] = {
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200552 &gadget_config_desc_attr_MaxPower,
553 &gadget_config_desc_attr_bmAttributes,
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100554 NULL,
555};
556
557static struct config_item_type gadget_config_type = {
558 .ct_item_ops = &gadget_config_item_ops,
559 .ct_attrs = gadget_config_attrs,
560 .ct_owner = THIS_MODULE,
561};
562
563static struct config_item_type gadget_root_type = {
564 .ct_item_ops = &gadget_root_item_ops,
565 .ct_attrs = gadget_root_attrs,
566 .ct_owner = THIS_MODULE,
567};
568
569static void composite_init_dev(struct usb_composite_dev *cdev)
570{
571 spin_lock_init(&cdev->lock);
572 INIT_LIST_HEAD(&cdev->configs);
573 INIT_LIST_HEAD(&cdev->gstrings);
574}
575
576static struct config_group *function_make(
577 struct config_group *group,
578 const char *name)
579{
580 struct gadget_info *gi;
581 struct usb_function_instance *fi;
582 char buf[MAX_NAME_LEN];
583 char *func_name;
584 char *instance_name;
585 int ret;
586
587 ret = snprintf(buf, MAX_NAME_LEN, "%s", name);
588 if (ret >= MAX_NAME_LEN)
589 return ERR_PTR(-ENAMETOOLONG);
590
591 func_name = buf;
592 instance_name = strchr(func_name, '.');
593 if (!instance_name) {
594 pr_err("Unable to locate . in FUNC.INSTANCE\n");
595 return ERR_PTR(-EINVAL);
596 }
597 *instance_name = '\0';
598 instance_name++;
599
600 fi = usb_get_function_instance(func_name);
601 if (IS_ERR(fi))
Duan Jionga3469412013-09-26 15:55:25 +0800602 return ERR_CAST(fi);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100603
Nicolas Iooss3958b792015-07-17 16:23:45 -0700604 ret = config_item_set_name(&fi->group.cg_item, "%s", name);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100605 if (ret) {
606 usb_put_function_instance(fi);
607 return ERR_PTR(ret);
608 }
Andrzej Pietrasiewicz19338612013-12-03 15:15:21 +0100609 if (fi->set_inst_name) {
610 ret = fi->set_inst_name(fi, instance_name);
611 if (ret) {
612 usb_put_function_instance(fi);
613 return ERR_PTR(ret);
614 }
615 }
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100616
617 gi = container_of(group, struct gadget_info, functions_group);
618
619 mutex_lock(&gi->lock);
620 list_add_tail(&fi->cfs_list, &gi->available_func);
621 mutex_unlock(&gi->lock);
622 return &fi->group;
623}
624
625static void function_drop(
626 struct config_group *group,
627 struct config_item *item)
628{
629 struct usb_function_instance *fi = to_usb_function_instance(item);
630 struct gadget_info *gi;
631
632 gi = container_of(group, struct gadget_info, functions_group);
633
634 mutex_lock(&gi->lock);
635 list_del(&fi->cfs_list);
636 mutex_unlock(&gi->lock);
637 config_item_put(item);
638}
639
640static struct configfs_group_operations functions_ops = {
641 .make_group = &function_make,
642 .drop_item = &function_drop,
643};
644
645static struct config_item_type functions_type = {
646 .ct_group_ops = &functions_ops,
647 .ct_owner = THIS_MODULE,
648};
649
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100650GS_STRINGS_RW(gadget_config_name, configuration);
651
652static struct configfs_attribute *gadget_config_name_langid_attrs[] = {
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200653 &gadget_config_name_attr_configuration,
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100654 NULL,
655};
656
657static void gadget_config_name_attr_release(struct config_item *item)
658{
659 struct gadget_config_name *cn = to_gadget_config_name(item);
660
661 kfree(cn->configuration);
662
663 list_del(&cn->list);
664 kfree(cn);
665}
666
667USB_CONFIG_STRING_RW_OPS(gadget_config_name);
668USB_CONFIG_STRINGS_LANG(gadget_config_name, config_usb_cfg);
669
670static struct config_group *config_desc_make(
671 struct config_group *group,
672 const char *name)
673{
674 struct gadget_info *gi;
675 struct config_usb_cfg *cfg;
676 char buf[MAX_NAME_LEN];
677 char *num_str;
678 u8 num;
679 int ret;
680
681 gi = container_of(group, struct gadget_info, configs_group);
682 ret = snprintf(buf, MAX_NAME_LEN, "%s", name);
683 if (ret >= MAX_NAME_LEN)
684 return ERR_PTR(-ENAMETOOLONG);
685
686 num_str = strchr(buf, '.');
687 if (!num_str) {
688 pr_err("Unable to locate . in name.bConfigurationValue\n");
689 return ERR_PTR(-EINVAL);
690 }
691
692 *num_str = '\0';
693 num_str++;
694
695 if (!strlen(buf))
696 return ERR_PTR(-EINVAL);
697
698 ret = kstrtou8(num_str, 0, &num);
699 if (ret)
700 return ERR_PTR(ret);
701
702 cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
703 if (!cfg)
704 return ERR_PTR(-ENOMEM);
705 cfg->c.label = kstrdup(buf, GFP_KERNEL);
706 if (!cfg->c.label) {
707 ret = -ENOMEM;
708 goto err;
709 }
710 cfg->c.bConfigurationValue = num;
711 cfg->c.MaxPower = CONFIG_USB_GADGET_VBUS_DRAW;
712 cfg->c.bmAttributes = USB_CONFIG_ATT_ONE;
713 INIT_LIST_HEAD(&cfg->string_list);
714 INIT_LIST_HEAD(&cfg->func_list);
715
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100716 config_group_init_type_name(&cfg->group, name,
717 &gadget_config_type);
Christoph Hellwig1ae16022016-02-26 11:02:14 +0100718
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100719 config_group_init_type_name(&cfg->strings_group, "strings",
720 &gadget_config_name_strings_type);
Christoph Hellwig1ae16022016-02-26 11:02:14 +0100721 configfs_add_default_group(&cfg->strings_group, &cfg->group);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100722
723 ret = usb_add_config_only(&gi->cdev, &cfg->c);
724 if (ret)
725 goto err;
726
727 return &cfg->group;
728err:
729 kfree(cfg->c.label);
730 kfree(cfg);
731 return ERR_PTR(ret);
732}
733
734static void config_desc_drop(
735 struct config_group *group,
736 struct config_item *item)
737{
738 config_item_put(item);
739}
740
741static struct configfs_group_operations config_desc_ops = {
742 .make_group = &config_desc_make,
743 .drop_item = &config_desc_drop,
744};
745
746static struct config_item_type config_desc_type = {
747 .ct_group_ops = &config_desc_ops,
748 .ct_owner = THIS_MODULE,
749};
750
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100751GS_STRINGS_RW(gadget_strings, manufacturer);
752GS_STRINGS_RW(gadget_strings, product);
753GS_STRINGS_RW(gadget_strings, serialnumber);
754
755static struct configfs_attribute *gadget_strings_langid_attrs[] = {
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200756 &gadget_strings_attr_manufacturer,
757 &gadget_strings_attr_product,
758 &gadget_strings_attr_serialnumber,
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100759 NULL,
760};
761
762static void gadget_strings_attr_release(struct config_item *item)
763{
764 struct gadget_strings *gs = to_gadget_strings(item);
765
766 kfree(gs->manufacturer);
767 kfree(gs->product);
768 kfree(gs->serialnumber);
769
770 list_del(&gs->list);
771 kfree(gs);
772}
773
774USB_CONFIG_STRING_RW_OPS(gadget_strings);
775USB_CONFIG_STRINGS_LANG(gadget_strings, gadget_info);
776
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200777static inline struct os_desc *to_os_desc(struct config_item *item)
778{
779 return container_of(to_config_group(item), struct os_desc, group);
780}
781
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200782static inline struct gadget_info *os_desc_item_to_gadget_info(
783 struct config_item *item)
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200784{
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200785 return to_gadget_info(to_os_desc(item)->group.cg_item.ci_parent);
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200786}
787
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200788static ssize_t os_desc_use_show(struct config_item *item, char *page)
789{
790 return sprintf(page, "%d",
791 os_desc_item_to_gadget_info(item)->use_os_desc);
792}
793
794static ssize_t os_desc_use_store(struct config_item *item, const char *page,
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200795 size_t len)
796{
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200797 struct gadget_info *gi = os_desc_item_to_gadget_info(item);
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200798 int ret;
799 bool use;
800
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200801 mutex_lock(&gi->lock);
802 ret = strtobool(page, &use);
803 if (!ret) {
804 gi->use_os_desc = use;
805 ret = len;
806 }
807 mutex_unlock(&gi->lock);
808
809 return ret;
810}
811
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200812static ssize_t os_desc_b_vendor_code_show(struct config_item *item, char *page)
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200813{
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200814 return sprintf(page, "%d",
815 os_desc_item_to_gadget_info(item)->b_vendor_code);
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200816}
817
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200818static ssize_t os_desc_b_vendor_code_store(struct config_item *item,
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200819 const char *page, size_t len)
820{
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200821 struct gadget_info *gi = os_desc_item_to_gadget_info(item);
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200822 int ret;
823 u8 b_vendor_code;
824
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200825 mutex_lock(&gi->lock);
826 ret = kstrtou8(page, 0, &b_vendor_code);
827 if (!ret) {
828 gi->b_vendor_code = b_vendor_code;
829 ret = len;
830 }
831 mutex_unlock(&gi->lock);
832
833 return ret;
834}
835
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200836static ssize_t os_desc_qw_sign_show(struct config_item *item, char *page)
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200837{
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200838 struct gadget_info *gi = os_desc_item_to_gadget_info(item);
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200839
840 memcpy(page, gi->qw_sign, OS_STRING_QW_SIGN_LEN);
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200841 return OS_STRING_QW_SIGN_LEN;
842}
843
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200844static ssize_t os_desc_qw_sign_store(struct config_item *item, const char *page,
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200845 size_t len)
846{
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200847 struct gadget_info *gi = os_desc_item_to_gadget_info(item);
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200848 int res, l;
849
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200850 l = min((int)len, OS_STRING_QW_SIGN_LEN >> 1);
851 if (page[l - 1] == '\n')
852 --l;
853
854 mutex_lock(&gi->lock);
855 res = utf8s_to_utf16s(page, l,
856 UTF16_LITTLE_ENDIAN, (wchar_t *) gi->qw_sign,
857 OS_STRING_QW_SIGN_LEN);
858 if (res > 0)
859 res = len;
860 mutex_unlock(&gi->lock);
861
862 return res;
863}
864
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200865CONFIGFS_ATTR(os_desc_, use);
866CONFIGFS_ATTR(os_desc_, b_vendor_code);
867CONFIGFS_ATTR(os_desc_, qw_sign);
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200868
869static struct configfs_attribute *os_desc_attrs[] = {
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200870 &os_desc_attr_use,
871 &os_desc_attr_b_vendor_code,
872 &os_desc_attr_qw_sign,
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200873 NULL,
874};
875
876static void os_desc_attr_release(struct config_item *item)
877{
878 struct os_desc *os_desc = to_os_desc(item);
879 kfree(os_desc);
880}
881
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +0200882static int os_desc_link(struct config_item *os_desc_ci,
883 struct config_item *usb_cfg_ci)
884{
885 struct gadget_info *gi = container_of(to_config_group(os_desc_ci),
886 struct gadget_info, os_desc_group);
887 struct usb_composite_dev *cdev = &gi->cdev;
888 struct config_usb_cfg *c_target =
889 container_of(to_config_group(usb_cfg_ci),
890 struct config_usb_cfg, group);
891 struct usb_configuration *c;
892 int ret;
893
894 mutex_lock(&gi->lock);
895 list_for_each_entry(c, &cdev->configs, list) {
896 if (c == &c_target->c)
897 break;
898 }
899 if (c != &c_target->c) {
900 ret = -EINVAL;
901 goto out;
902 }
903
904 if (cdev->os_desc_config) {
905 ret = -EBUSY;
906 goto out;
907 }
908
909 cdev->os_desc_config = &c_target->c;
910 ret = 0;
911
912out:
913 mutex_unlock(&gi->lock);
914 return ret;
915}
916
917static int os_desc_unlink(struct config_item *os_desc_ci,
918 struct config_item *usb_cfg_ci)
919{
920 struct gadget_info *gi = container_of(to_config_group(os_desc_ci),
921 struct gadget_info, os_desc_group);
922 struct usb_composite_dev *cdev = &gi->cdev;
923
924 mutex_lock(&gi->lock);
Ruslan Bilovolafdaadc2015-11-23 09:56:36 +0100925 if (gi->composite.gadget_driver.udc_name)
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +0200926 unregister_gadget(gi);
927 cdev->os_desc_config = NULL;
Ruslan Bilovolafdaadc2015-11-23 09:56:36 +0100928 WARN_ON(gi->composite.gadget_driver.udc_name);
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +0200929 mutex_unlock(&gi->lock);
930 return 0;
931}
932
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200933static struct configfs_item_operations os_desc_ops = {
934 .release = os_desc_attr_release,
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +0200935 .allow_link = os_desc_link,
936 .drop_link = os_desc_unlink,
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200937};
938
939static struct config_item_type os_desc_type = {
940 .ct_item_ops = &os_desc_ops,
941 .ct_attrs = os_desc_attrs,
942 .ct_owner = THIS_MODULE,
943};
944
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +0200945static inline struct usb_os_desc_ext_prop
946*to_usb_os_desc_ext_prop(struct config_item *item)
947{
948 return container_of(item, struct usb_os_desc_ext_prop, item);
949}
950
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200951static ssize_t ext_prop_type_show(struct config_item *item, char *page)
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +0200952{
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200953 return sprintf(page, "%d", to_usb_os_desc_ext_prop(item)->type);
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +0200954}
955
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200956static ssize_t ext_prop_type_store(struct config_item *item,
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +0200957 const char *page, size_t len)
958{
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200959 struct usb_os_desc_ext_prop *ext_prop = to_usb_os_desc_ext_prop(item);
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +0200960 struct usb_os_desc *desc = to_usb_os_desc(ext_prop->item.ci_parent);
961 u8 type;
962 int ret;
963
964 if (desc->opts_mutex)
965 mutex_lock(desc->opts_mutex);
966 ret = kstrtou8(page, 0, &type);
967 if (ret)
968 goto end;
969 if (type < USB_EXT_PROP_UNICODE || type > USB_EXT_PROP_UNICODE_MULTI) {
970 ret = -EINVAL;
971 goto end;
972 }
973
974 if ((ext_prop->type == USB_EXT_PROP_BINARY ||
975 ext_prop->type == USB_EXT_PROP_LE32 ||
976 ext_prop->type == USB_EXT_PROP_BE32) &&
977 (type == USB_EXT_PROP_UNICODE ||
978 type == USB_EXT_PROP_UNICODE_ENV ||
979 type == USB_EXT_PROP_UNICODE_LINK))
980 ext_prop->data_len <<= 1;
981 else if ((ext_prop->type == USB_EXT_PROP_UNICODE ||
982 ext_prop->type == USB_EXT_PROP_UNICODE_ENV ||
983 ext_prop->type == USB_EXT_PROP_UNICODE_LINK) &&
984 (type == USB_EXT_PROP_BINARY ||
985 type == USB_EXT_PROP_LE32 ||
986 type == USB_EXT_PROP_BE32))
987 ext_prop->data_len >>= 1;
988 ext_prop->type = type;
989 ret = len;
990
991end:
992 if (desc->opts_mutex)
993 mutex_unlock(desc->opts_mutex);
994 return ret;
995}
996
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200997static ssize_t ext_prop_data_show(struct config_item *item, char *page)
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +0200998{
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 int len = ext_prop->data_len;
1001
1002 if (ext_prop->type == USB_EXT_PROP_UNICODE ||
1003 ext_prop->type == USB_EXT_PROP_UNICODE_ENV ||
1004 ext_prop->type == USB_EXT_PROP_UNICODE_LINK)
1005 len >>= 1;
1006 memcpy(page, ext_prop->data, len);
1007
1008 return len;
1009}
1010
Christoph Hellwig45b6a732015-10-03 15:32:38 +02001011static ssize_t ext_prop_data_store(struct config_item *item,
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +02001012 const char *page, size_t len)
1013{
Christoph Hellwig45b6a732015-10-03 15:32:38 +02001014 struct usb_os_desc_ext_prop *ext_prop = to_usb_os_desc_ext_prop(item);
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +02001015 struct usb_os_desc *desc = to_usb_os_desc(ext_prop->item.ci_parent);
1016 char *new_data;
1017 size_t ret_len = len;
1018
1019 if (page[len - 1] == '\n' || page[len - 1] == '\0')
1020 --len;
Benoit Taine58b949e2014-05-26 17:21:20 +02001021 new_data = kmemdup(page, len, GFP_KERNEL);
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +02001022 if (!new_data)
1023 return -ENOMEM;
1024
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +02001025 if (desc->opts_mutex)
1026 mutex_lock(desc->opts_mutex);
1027 kfree(ext_prop->data);
1028 ext_prop->data = new_data;
1029 desc->ext_prop_len -= ext_prop->data_len;
1030 ext_prop->data_len = len;
1031 desc->ext_prop_len += ext_prop->data_len;
1032 if (ext_prop->type == USB_EXT_PROP_UNICODE ||
1033 ext_prop->type == USB_EXT_PROP_UNICODE_ENV ||
1034 ext_prop->type == USB_EXT_PROP_UNICODE_LINK) {
1035 desc->ext_prop_len -= ext_prop->data_len;
1036 ext_prop->data_len <<= 1;
1037 ext_prop->data_len += 2;
1038 desc->ext_prop_len += ext_prop->data_len;
1039 }
1040 if (desc->opts_mutex)
1041 mutex_unlock(desc->opts_mutex);
1042 return ret_len;
1043}
1044
Christoph Hellwig45b6a732015-10-03 15:32:38 +02001045CONFIGFS_ATTR(ext_prop_, type);
1046CONFIGFS_ATTR(ext_prop_, data);
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +02001047
1048static struct configfs_attribute *ext_prop_attrs[] = {
Christoph Hellwig45b6a732015-10-03 15:32:38 +02001049 &ext_prop_attr_type,
1050 &ext_prop_attr_data,
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +02001051 NULL,
1052};
1053
1054static void usb_os_desc_ext_prop_release(struct config_item *item)
1055{
1056 struct usb_os_desc_ext_prop *ext_prop = to_usb_os_desc_ext_prop(item);
1057
1058 kfree(ext_prop); /* frees a whole chunk */
1059}
1060
1061static struct configfs_item_operations ext_prop_ops = {
1062 .release = usb_os_desc_ext_prop_release,
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +02001063};
1064
1065static struct config_item *ext_prop_make(
1066 struct config_group *group,
1067 const char *name)
1068{
1069 struct usb_os_desc_ext_prop *ext_prop;
1070 struct config_item_type *ext_prop_type;
1071 struct usb_os_desc *desc;
1072 char *vlabuf;
1073
1074 vla_group(data_chunk);
1075 vla_item(data_chunk, struct usb_os_desc_ext_prop, ext_prop, 1);
1076 vla_item(data_chunk, struct config_item_type, ext_prop_type, 1);
1077
1078 vlabuf = kzalloc(vla_group_size(data_chunk), GFP_KERNEL);
1079 if (!vlabuf)
1080 return ERR_PTR(-ENOMEM);
1081
1082 ext_prop = vla_ptr(vlabuf, data_chunk, ext_prop);
1083 ext_prop_type = vla_ptr(vlabuf, data_chunk, ext_prop_type);
1084
1085 desc = container_of(group, struct usb_os_desc, group);
1086 ext_prop_type->ct_item_ops = &ext_prop_ops;
1087 ext_prop_type->ct_attrs = ext_prop_attrs;
1088 ext_prop_type->ct_owner = desc->owner;
1089
1090 config_item_init_type_name(&ext_prop->item, name, ext_prop_type);
1091
1092 ext_prop->name = kstrdup(name, GFP_KERNEL);
1093 if (!ext_prop->name) {
1094 kfree(vlabuf);
1095 return ERR_PTR(-ENOMEM);
1096 }
1097 desc->ext_prop_len += 14;
1098 ext_prop->name_len = 2 * strlen(ext_prop->name) + 2;
1099 if (desc->opts_mutex)
1100 mutex_lock(desc->opts_mutex);
1101 desc->ext_prop_len += ext_prop->name_len;
1102 list_add_tail(&ext_prop->entry, &desc->ext_prop);
1103 ++desc->ext_prop_count;
1104 if (desc->opts_mutex)
1105 mutex_unlock(desc->opts_mutex);
1106
1107 return &ext_prop->item;
1108}
1109
1110static void ext_prop_drop(struct config_group *group, struct config_item *item)
1111{
1112 struct usb_os_desc_ext_prop *ext_prop = to_usb_os_desc_ext_prop(item);
1113 struct usb_os_desc *desc = to_usb_os_desc(&group->cg_item);
1114
1115 if (desc->opts_mutex)
1116 mutex_lock(desc->opts_mutex);
1117 list_del(&ext_prop->entry);
1118 --desc->ext_prop_count;
1119 kfree(ext_prop->name);
1120 desc->ext_prop_len -= (ext_prop->name_len + ext_prop->data_len + 14);
1121 if (desc->opts_mutex)
1122 mutex_unlock(desc->opts_mutex);
1123 config_item_put(item);
1124}
1125
1126static struct configfs_group_operations interf_grp_ops = {
1127 .make_item = &ext_prop_make,
1128 .drop_item = &ext_prop_drop,
1129};
1130
Christoph Hellwig45b6a732015-10-03 15:32:38 +02001131static ssize_t interf_grp_compatible_id_show(struct config_item *item,
Andrzej Pietrasiewiczfe00b132014-06-18 14:24:48 +02001132 char *page)
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001133{
Christoph Hellwig45b6a732015-10-03 15:32:38 +02001134 memcpy(page, to_usb_os_desc(item)->ext_compat_id, 8);
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001135 return 8;
1136}
1137
Christoph Hellwig45b6a732015-10-03 15:32:38 +02001138static ssize_t interf_grp_compatible_id_store(struct config_item *item,
Andrzej Pietrasiewiczfe00b132014-06-18 14:24:48 +02001139 const char *page, size_t len)
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001140{
Christoph Hellwig45b6a732015-10-03 15:32:38 +02001141 struct usb_os_desc *desc = to_usb_os_desc(item);
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001142 int l;
1143
1144 l = min_t(int, 8, len);
1145 if (page[l - 1] == '\n')
1146 --l;
1147 if (desc->opts_mutex)
1148 mutex_lock(desc->opts_mutex);
1149 memcpy(desc->ext_compat_id, page, l);
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001150
1151 if (desc->opts_mutex)
1152 mutex_unlock(desc->opts_mutex);
1153
1154 return len;
1155}
1156
Christoph Hellwig45b6a732015-10-03 15:32:38 +02001157static ssize_t interf_grp_sub_compatible_id_show(struct config_item *item,
Andrzej Pietrasiewiczfe00b132014-06-18 14:24:48 +02001158 char *page)
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001159{
Christoph Hellwig45b6a732015-10-03 15:32:38 +02001160 memcpy(page, to_usb_os_desc(item)->ext_compat_id + 8, 8);
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001161 return 8;
1162}
1163
Christoph Hellwig45b6a732015-10-03 15:32:38 +02001164static ssize_t interf_grp_sub_compatible_id_store(struct config_item *item,
Andrzej Pietrasiewiczfe00b132014-06-18 14:24:48 +02001165 const char *page, size_t len)
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001166{
Christoph Hellwig45b6a732015-10-03 15:32:38 +02001167 struct usb_os_desc *desc = to_usb_os_desc(item);
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001168 int l;
1169
1170 l = min_t(int, 8, len);
1171 if (page[l - 1] == '\n')
1172 --l;
1173 if (desc->opts_mutex)
1174 mutex_lock(desc->opts_mutex);
1175 memcpy(desc->ext_compat_id + 8, page, l);
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001176
1177 if (desc->opts_mutex)
1178 mutex_unlock(desc->opts_mutex);
1179
1180 return len;
1181}
1182
Christoph Hellwig45b6a732015-10-03 15:32:38 +02001183CONFIGFS_ATTR(interf_grp_, compatible_id);
1184CONFIGFS_ATTR(interf_grp_, sub_compatible_id);
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001185
1186static struct configfs_attribute *interf_grp_attrs[] = {
Christoph Hellwig45b6a732015-10-03 15:32:38 +02001187 &interf_grp_attr_compatible_id,
1188 &interf_grp_attr_sub_compatible_id,
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001189 NULL
1190};
1191
Andrew Gabbasov3c57f9d2017-09-30 08:54:52 -07001192struct config_group *usb_os_desc_prepare_interf_dir(
1193 struct config_group *parent,
1194 int n_interf,
1195 struct usb_os_desc **desc,
1196 char **names,
1197 struct module *owner)
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001198{
Christoph Hellwig1ae16022016-02-26 11:02:14 +01001199 struct config_group *os_desc_group;
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001200 struct config_item_type *os_desc_type, *interface_type;
1201
1202 vla_group(data_chunk);
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001203 vla_item(data_chunk, struct config_group, os_desc_group, 1);
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001204 vla_item(data_chunk, struct config_item_type, os_desc_type, 1);
1205 vla_item(data_chunk, struct config_item_type, interface_type, 1);
1206
1207 char *vlabuf = kzalloc(vla_group_size(data_chunk), GFP_KERNEL);
1208 if (!vlabuf)
Andrew Gabbasov3c57f9d2017-09-30 08:54:52 -07001209 return ERR_PTR(-ENOMEM);
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001210
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001211 os_desc_group = vla_ptr(vlabuf, data_chunk, os_desc_group);
1212 os_desc_type = vla_ptr(vlabuf, data_chunk, os_desc_type);
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001213 interface_type = vla_ptr(vlabuf, data_chunk, interface_type);
1214
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001215 os_desc_type->ct_owner = owner;
1216 config_group_init_type_name(os_desc_group, "os_desc", os_desc_type);
Christoph Hellwig1ae16022016-02-26 11:02:14 +01001217 configfs_add_default_group(os_desc_group, parent);
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001218
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +02001219 interface_type->ct_group_ops = &interf_grp_ops;
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001220 interface_type->ct_attrs = interf_grp_attrs;
1221 interface_type->ct_owner = owner;
1222
1223 while (n_interf--) {
1224 struct usb_os_desc *d;
1225
1226 d = desc[n_interf];
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +02001227 d->owner = owner;
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001228 config_group_init_type_name(&d->group, "", interface_type);
Andrzej Pietrasiewicz14574b52014-06-18 14:24:49 +02001229 config_item_set_name(&d->group.cg_item, "interface.%s",
1230 names[n_interf]);
Christoph Hellwig1ae16022016-02-26 11:02:14 +01001231 configfs_add_default_group(&d->group, os_desc_group);
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001232 }
1233
Andrew Gabbasov3c57f9d2017-09-30 08:54:52 -07001234 return os_desc_group;
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001235}
1236EXPORT_SYMBOL(usb_os_desc_prepare_interf_dir);
1237
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001238static int configfs_do_nothing(struct usb_composite_dev *cdev)
1239{
David Rientjes75bfe232013-04-07 14:11:47 -07001240 WARN_ON(1);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001241 return -EINVAL;
1242}
1243
1244int composite_dev_prepare(struct usb_composite_driver *composite,
1245 struct usb_composite_dev *dev);
1246
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001247int composite_os_desc_req_prepare(struct usb_composite_dev *cdev,
1248 struct usb_ep *ep0);
1249
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001250static void purge_configs_funcs(struct gadget_info *gi)
1251{
1252 struct usb_configuration *c;
1253
1254 list_for_each_entry(c, &gi->cdev.configs, list) {
1255 struct usb_function *f, *tmp;
1256 struct config_usb_cfg *cfg;
1257
1258 cfg = container_of(c, struct config_usb_cfg, c);
1259
1260 list_for_each_entry_safe(f, tmp, &c->functions, list) {
1261
1262 list_move_tail(&f->list, &cfg->func_list);
1263 if (f->unbind) {
Romain Izardda7b8952016-08-29 12:22:29 +03001264 dev_dbg(&gi->cdev.gadget->dev,
Chandana Kishori Chiluveru7f5670a2017-10-28 23:05:45 +05301265 "unbind function '%s'/%pK\n",
Romain Izarda08f5db2016-07-26 18:21:46 +02001266 f->name, f);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001267 f->unbind(c, f);
1268 }
1269 }
1270 c->next_interface_id = 0;
Krzysztof Opasiak903124f2015-03-20 15:48:56 +01001271 memset(c->interface, 0, sizeof(c->interface));
John Youn554eead2016-02-05 17:06:35 -08001272 c->superspeed_plus = 0;
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001273 c->superspeed = 0;
1274 c->highspeed = 0;
1275 c->fullspeed = 0;
1276 }
1277}
1278
1279static int configfs_composite_bind(struct usb_gadget *gadget,
1280 struct usb_gadget_driver *gdriver)
1281{
1282 struct usb_composite_driver *composite = to_cdriver(gdriver);
1283 struct gadget_info *gi = container_of(composite,
1284 struct gadget_info, composite);
1285 struct usb_composite_dev *cdev = &gi->cdev;
1286 struct usb_configuration *c;
1287 struct usb_string *s;
1288 unsigned i;
1289 int ret;
1290
1291 /* the gi->lock is hold by the caller */
1292 cdev->gadget = gadget;
1293 set_gadget_data(gadget, cdev);
1294 ret = composite_dev_prepare(composite, cdev);
1295 if (ret)
1296 return ret;
1297 /* and now the gadget bind */
1298 ret = -EINVAL;
1299
1300 if (list_empty(&gi->cdev.configs)) {
Peter Chen4d9f8722014-05-05 07:39:34 +08001301 pr_err("Need at least one configuration in %s.\n",
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001302 gi->composite.name);
1303 goto err_comp_cleanup;
1304 }
1305
1306
1307 list_for_each_entry(c, &gi->cdev.configs, list) {
1308 struct config_usb_cfg *cfg;
1309
1310 cfg = container_of(c, struct config_usb_cfg, c);
1311 if (list_empty(&cfg->func_list)) {
Peter Chen4d9f8722014-05-05 07:39:34 +08001312 pr_err("Config %s/%d of %s needs at least one function.\n",
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001313 c->label, c->bConfigurationValue,
1314 gi->composite.name);
1315 goto err_comp_cleanup;
1316 }
1317 }
1318
1319 /* init all strings */
1320 if (!list_empty(&gi->string_list)) {
1321 struct gadget_strings *gs;
1322
1323 i = 0;
1324 list_for_each_entry(gs, &gi->string_list, list) {
1325
1326 gi->gstrings[i] = &gs->stringtab_dev;
1327 gs->stringtab_dev.strings = gs->strings;
1328 gs->strings[USB_GADGET_MANUFACTURER_IDX].s =
1329 gs->manufacturer;
1330 gs->strings[USB_GADGET_PRODUCT_IDX].s = gs->product;
1331 gs->strings[USB_GADGET_SERIAL_IDX].s = gs->serialnumber;
1332 i++;
1333 }
1334 gi->gstrings[i] = NULL;
1335 s = usb_gstrings_attach(&gi->cdev, gi->gstrings,
1336 USB_GADGET_FIRST_AVAIL_IDX);
Wei Yongjunfea77072013-05-07 19:50:31 +08001337 if (IS_ERR(s)) {
1338 ret = PTR_ERR(s);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001339 goto err_comp_cleanup;
Wei Yongjunfea77072013-05-07 19:50:31 +08001340 }
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001341
1342 gi->cdev.desc.iManufacturer = s[USB_GADGET_MANUFACTURER_IDX].id;
1343 gi->cdev.desc.iProduct = s[USB_GADGET_PRODUCT_IDX].id;
1344 gi->cdev.desc.iSerialNumber = s[USB_GADGET_SERIAL_IDX].id;
1345 }
1346
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +02001347 if (gi->use_os_desc) {
1348 cdev->use_os_string = true;
1349 cdev->b_vendor_code = gi->b_vendor_code;
1350 memcpy(cdev->qw_sign, gi->qw_sign, OS_STRING_QW_SIGN_LEN);
1351 }
1352
Li Jun41ce84c2015-07-09 15:18:48 +08001353 if (gadget_is_otg(gadget) && !otg_desc[0]) {
1354 struct usb_descriptor_header *usb_desc;
1355
1356 usb_desc = usb_otg_descriptor_alloc(gadget);
1357 if (!usb_desc) {
1358 ret = -ENOMEM;
1359 goto err_comp_cleanup;
1360 }
1361 usb_otg_descriptor_init(gadget, usb_desc);
1362 otg_desc[0] = usb_desc;
1363 otg_desc[1] = NULL;
1364 }
1365
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001366 /* Go through all configs, attach all functions */
1367 list_for_each_entry(c, &gi->cdev.configs, list) {
1368 struct config_usb_cfg *cfg;
1369 struct usb_function *f;
1370 struct usb_function *tmp;
1371 struct gadget_config_name *cn;
1372
Li Jun41ce84c2015-07-09 15:18:48 +08001373 if (gadget_is_otg(gadget))
1374 c->descriptors = otg_desc;
1375
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001376 cfg = container_of(c, struct config_usb_cfg, c);
1377 if (!list_empty(&cfg->string_list)) {
1378 i = 0;
1379 list_for_each_entry(cn, &cfg->string_list, list) {
1380 cfg->gstrings[i] = &cn->stringtab_dev;
1381 cn->stringtab_dev.strings = &cn->strings;
1382 cn->strings.s = cn->configuration;
1383 i++;
1384 }
1385 cfg->gstrings[i] = NULL;
1386 s = usb_gstrings_attach(&gi->cdev, cfg->gstrings, 1);
Wei Yongjunfea77072013-05-07 19:50:31 +08001387 if (IS_ERR(s)) {
1388 ret = PTR_ERR(s);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001389 goto err_comp_cleanup;
Wei Yongjunfea77072013-05-07 19:50:31 +08001390 }
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001391 c->iConfiguration = s[0].id;
1392 }
1393
1394 list_for_each_entry_safe(f, tmp, &cfg->func_list, list) {
1395 list_del(&f->list);
1396 ret = usb_add_function(c, f);
Andrzej Pietrasiewicz5a68e9b2013-08-08 09:43:28 +02001397 if (ret) {
1398 list_add(&f->list, &cfg->func_list);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001399 goto err_purge_funcs;
Andrzej Pietrasiewicz5a68e9b2013-08-08 09:43:28 +02001400 }
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001401 }
1402 usb_ep_autoconfig_reset(cdev->gadget);
1403 }
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001404 if (cdev->use_os_string) {
1405 ret = composite_os_desc_req_prepare(cdev, gadget->ep0);
1406 if (ret)
1407 goto err_purge_funcs;
1408 }
1409
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001410 usb_ep_autoconfig_reset(cdev->gadget);
1411 return 0;
1412
1413err_purge_funcs:
1414 purge_configs_funcs(gi);
1415err_comp_cleanup:
1416 composite_dev_cleanup(cdev);
1417 return ret;
1418}
1419
Badhri Jagan Sridharan1c3865d2014-12-15 10:44:47 -08001420#ifdef CONFIG_USB_CONFIGFS_UEVENT
1421static void android_work(struct work_struct *data)
1422{
1423 struct gadget_info *gi = container_of(data, struct gadget_info, work);
1424 struct usb_composite_dev *cdev = &gi->cdev;
1425 char *disconnected[2] = { "USB_STATE=DISCONNECTED", NULL };
1426 char *connected[2] = { "USB_STATE=CONNECTED", NULL };
1427 char *configured[2] = { "USB_STATE=CONFIGURED", NULL };
1428 /* 0-connected 1-configured 2-disconnected*/
1429 bool status[3] = { false, false, false };
1430 unsigned long flags;
1431 bool uevent_sent = false;
1432
1433 spin_lock_irqsave(&cdev->lock, flags);
1434 if (cdev->config)
1435 status[1] = true;
1436
1437 if (gi->connected != gi->sw_connected) {
1438 if (gi->connected)
1439 status[0] = true;
1440 else
1441 status[2] = true;
1442 gi->sw_connected = gi->connected;
1443 }
1444 spin_unlock_irqrestore(&cdev->lock, flags);
1445
1446 if (status[0]) {
Ajay Agarwalfea56da2017-05-30 10:27:23 +05301447 kobject_uevent_env(&gi->dev->kobj,
Badhri Jagan Sridharan2a387e52015-03-27 14:15:19 -07001448 KOBJ_CHANGE, connected);
Badhri Jagan Sridharan1c3865d2014-12-15 10:44:47 -08001449 pr_info("%s: sent uevent %s\n", __func__, connected[0]);
1450 uevent_sent = true;
1451 }
1452
1453 if (status[1]) {
Ajay Agarwalfea56da2017-05-30 10:27:23 +05301454 kobject_uevent_env(&gi->dev->kobj,
Badhri Jagan Sridharan2a387e52015-03-27 14:15:19 -07001455 KOBJ_CHANGE, configured);
Badhri Jagan Sridharan1c3865d2014-12-15 10:44:47 -08001456 pr_info("%s: sent uevent %s\n", __func__, configured[0]);
1457 uevent_sent = true;
1458 }
1459
1460 if (status[2]) {
Ajay Agarwalfea56da2017-05-30 10:27:23 +05301461 kobject_uevent_env(&gi->dev->kobj,
Badhri Jagan Sridharan2a387e52015-03-27 14:15:19 -07001462 KOBJ_CHANGE, disconnected);
Badhri Jagan Sridharan1c3865d2014-12-15 10:44:47 -08001463 pr_info("%s: sent uevent %s\n", __func__, disconnected[0]);
1464 uevent_sent = true;
1465 }
1466
1467 if (!uevent_sent) {
Chandana Kishori Chiluveru7f5670a2017-10-28 23:05:45 +05301468 pr_info("%s: did not send uevent (%d %d %pK)\n", __func__,
Badhri Jagan Sridharan1c3865d2014-12-15 10:44:47 -08001469 gi->connected, gi->sw_connected, cdev->config);
1470 }
1471}
1472#endif
1473
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001474static void configfs_composite_unbind(struct usb_gadget *gadget)
1475{
1476 struct usb_composite_dev *cdev;
1477 struct gadget_info *gi;
1478
1479 /* the gi->lock is hold by the caller */
1480
1481 cdev = get_gadget_data(gadget);
1482 gi = container_of(cdev, struct gadget_info, cdev);
1483
Li Jun41ce84c2015-07-09 15:18:48 +08001484 kfree(otg_desc[0]);
1485 otg_desc[0] = NULL;
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001486 purge_configs_funcs(gi);
1487 composite_dev_cleanup(cdev);
1488 usb_ep_autoconfig_reset(cdev->gadget);
1489 cdev->gadget = NULL;
1490 set_gadget_data(gadget, NULL);
1491}
1492
Badhri Jagan Sridharan1c3865d2014-12-15 10:44:47 -08001493#ifdef CONFIG_USB_CONFIGFS_UEVENT
1494static int android_setup(struct usb_gadget *gadget,
1495 const struct usb_ctrlrequest *c)
1496{
1497 struct usb_composite_dev *cdev = get_gadget_data(gadget);
1498 unsigned long flags;
1499 struct gadget_info *gi = container_of(cdev, struct gadget_info, cdev);
1500 int value = -EOPNOTSUPP;
1501 struct usb_function_instance *fi;
1502
1503 spin_lock_irqsave(&cdev->lock, flags);
1504 if (!gi->connected) {
1505 gi->connected = 1;
1506 schedule_work(&gi->work);
1507 }
1508 spin_unlock_irqrestore(&cdev->lock, flags);
1509 list_for_each_entry(fi, &gi->available_func, cfs_list) {
1510 if (fi != NULL && fi->f != NULL && fi->f->setup != NULL) {
1511 value = fi->f->setup(fi->f, c);
1512 if (value >= 0)
1513 break;
1514 }
1515 }
1516
Ziqi Chenc35ae882017-09-26 18:48:28 +08001517#ifdef CONFIG_USB_F_NCM
1518 if (value < 0)
1519 value = ncm_ctrlrequest(cdev, c);
1520
1521 /*
1522 * for mirror link command case, if it already been handled,
1523 * do not pass to composite_setup
1524 */
1525 if (value == 0)
1526 return value;
1527#endif
1528
Badhri Jagan Sridharan1c3865d2014-12-15 10:44:47 -08001529#ifdef CONFIG_USB_CONFIGFS_F_ACC
1530 if (value < 0)
1531 value = acc_ctrlrequest(cdev, c);
1532#endif
1533
1534 if (value < 0)
1535 value = composite_setup(gadget, c);
1536
1537 spin_lock_irqsave(&cdev->lock, flags);
1538 if (c->bRequest == USB_REQ_SET_CONFIGURATION &&
1539 cdev->config) {
1540 schedule_work(&gi->work);
1541 }
1542 spin_unlock_irqrestore(&cdev->lock, flags);
1543
1544 return value;
1545}
1546
1547static void android_disconnect(struct usb_gadget *gadget)
1548{
1549 struct usb_composite_dev *cdev = get_gadget_data(gadget);
Hemant Kumarcb0304a2016-11-01 13:00:57 -07001550 struct gadget_info *gi;
1551
1552 if (!cdev) {
1553 pr_err("%s: gadget is not connected\n", __func__);
1554 return;
1555 }
1556
1557 gi = container_of(cdev, struct gadget_info, cdev);
Badhri Jagan Sridharan1c3865d2014-12-15 10:44:47 -08001558
Danilo Krummrich6e055352017-08-14 12:45:38 +02001559 /* FIXME: There's a race between usb_gadget_udc_stop() which is likely
1560 * to set the gadget driver to NULL in the udc driver and this drivers
1561 * gadget disconnect fn which likely checks for the gadget driver to
1562 * be a null ptr. It happens that unbind (doing set_gadget_data(NULL))
1563 * is called before the gadget driver is set to NULL and the udc driver
1564 * calls disconnect fn which results in cdev being a null ptr.
1565 */
1566 if (cdev == NULL) {
1567 WARN(1, "%s: gadget driver already disconnected\n", __func__);
1568 return;
1569 }
1570
Badhri Jagan Sridharan1c3865d2014-12-15 10:44:47 -08001571 /* accessory HID support can be active while the
1572 accessory function is not actually enabled,
1573 so we need to inform it when we are disconnected.
1574 */
1575
1576#ifdef CONFIG_USB_CONFIGFS_F_ACC
1577 acc_disconnect();
1578#endif
1579 gi->connected = 0;
Vijayavardhan Vennapusa4ca835b2017-10-30 14:33:51 +05301580 if (!gi->unbinding)
1581 schedule_work(&gi->work);
Badhri Jagan Sridharan1c3865d2014-12-15 10:44:47 -08001582 composite_disconnect(gadget);
1583}
1584#endif
1585
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001586static const struct usb_gadget_driver configfs_driver_template = {
1587 .bind = configfs_composite_bind,
1588 .unbind = configfs_composite_unbind,
Badhri Jagan Sridharan1c3865d2014-12-15 10:44:47 -08001589#ifdef CONFIG_USB_CONFIGFS_UEVENT
1590 .setup = android_setup,
Amit Pundirc316caf2015-10-06 20:53:27 +05301591 .reset = android_disconnect,
Badhri Jagan Sridharan1c3865d2014-12-15 10:44:47 -08001592 .disconnect = android_disconnect,
1593#else
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001594 .setup = composite_setup,
Peter Chen02f751b2014-09-09 08:56:50 +08001595 .reset = composite_disconnect,
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001596 .disconnect = composite_disconnect,
Badhri Jagan Sridharan1c3865d2014-12-15 10:44:47 -08001597#endif
Andrzej Pietrasiewicz3a571872014-10-08 12:03:36 +02001598 .suspend = composite_suspend,
1599 .resume = composite_resume,
1600
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001601 .max_speed = USB_SPEED_SUPER,
1602 .driver = {
1603 .owner = THIS_MODULE,
1604 .name = "configfs-gadget",
1605 },
Krzysztof Opasiakf1bddbb2016-05-05 10:46:05 +02001606 .match_existing_only = 1,
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001607};
1608
Badhri Jagan Sridharan51af1202015-07-14 15:46:11 -07001609#ifdef CONFIG_USB_CONFIGFS_UEVENT
1610static ssize_t state_show(struct device *pdev, struct device_attribute *attr,
1611 char *buf)
1612{
1613 struct gadget_info *dev = dev_get_drvdata(pdev);
1614 struct usb_composite_dev *cdev;
1615 char *state = "DISCONNECTED";
1616 unsigned long flags;
1617
1618 if (!dev)
1619 goto out;
1620
1621 cdev = &dev->cdev;
1622
1623 if (!cdev)
1624 goto out;
1625
1626 spin_lock_irqsave(&cdev->lock, flags);
1627 if (cdev->config)
1628 state = "CONFIGURED";
1629 else if (dev->connected)
1630 state = "CONNECTED";
1631 spin_unlock_irqrestore(&cdev->lock, flags);
1632out:
1633 return sprintf(buf, "%s\n", state);
1634}
1635
1636static DEVICE_ATTR(state, S_IRUGO, state_show, NULL);
1637
1638static struct device_attribute *android_usb_attributes[] = {
1639 &dev_attr_state,
1640 NULL
1641};
Badhri Jagan Sridharan4b2c8512015-08-09 15:12:50 -07001642
1643static int android_device_create(struct gadget_info *gi)
1644{
1645 struct device_attribute **attrs;
1646 struct device_attribute *attr;
Ajay Agarwalfea56da2017-05-30 10:27:23 +05301647 char str[10];
Badhri Jagan Sridharan4b2c8512015-08-09 15:12:50 -07001648
1649 INIT_WORK(&gi->work, android_work);
Ajay Agarwalfea56da2017-05-30 10:27:23 +05301650 snprintf(str, sizeof(str), "android%d", gadget_index - 1);
1651 pr_debug("Creating android device %s\n", str);
1652 gi->dev = device_create(android_class, NULL,
1653 MKDEV(0, 0), NULL, str);
1654 if (IS_ERR(gi->dev))
1655 return PTR_ERR(gi->dev);
Badhri Jagan Sridharan4b2c8512015-08-09 15:12:50 -07001656
Ajay Agarwalfea56da2017-05-30 10:27:23 +05301657 dev_set_drvdata(gi->dev, gi);
1658 if (gadget_index == 1)
1659 android_device = gi->dev;
Badhri Jagan Sridharan4b2c8512015-08-09 15:12:50 -07001660
1661 attrs = android_usb_attributes;
1662 while ((attr = *attrs++)) {
1663 int err;
1664
Ajay Agarwalfea56da2017-05-30 10:27:23 +05301665 err = device_create_file(gi->dev, attr);
Badhri Jagan Sridharan4b2c8512015-08-09 15:12:50 -07001666 if (err) {
Ajay Agarwalfea56da2017-05-30 10:27:23 +05301667 device_destroy(gi->dev->class,
1668 gi->dev->devt);
Badhri Jagan Sridharan4b2c8512015-08-09 15:12:50 -07001669 return err;
1670 }
1671 }
1672
1673 return 0;
1674}
1675
Ajay Agarwalfea56da2017-05-30 10:27:23 +05301676static void android_device_destroy(struct device *dev)
Badhri Jagan Sridharan4b2c8512015-08-09 15:12:50 -07001677{
1678 struct device_attribute **attrs;
1679 struct device_attribute *attr;
1680
1681 attrs = android_usb_attributes;
1682 while ((attr = *attrs++))
Ajay Agarwalfea56da2017-05-30 10:27:23 +05301683 device_remove_file(dev, attr);
1684 device_destroy(dev->class, dev->devt);
Badhri Jagan Sridharan4b2c8512015-08-09 15:12:50 -07001685}
1686#else
1687static inline int android_device_create(struct gadget_info *gi)
1688{
1689 return 0;
1690}
1691
Ajay Agarwalfea56da2017-05-30 10:27:23 +05301692static inline void android_device_destroy(struct device *dev)
Badhri Jagan Sridharan4b2c8512015-08-09 15:12:50 -07001693{
1694}
Badhri Jagan Sridharan51af1202015-07-14 15:46:11 -07001695#endif
1696
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001697static struct config_group *gadgets_make(
1698 struct config_group *group,
1699 const char *name)
1700{
1701 struct gadget_info *gi;
1702
1703 gi = kzalloc(sizeof(*gi), GFP_KERNEL);
1704 if (!gi)
1705 return ERR_PTR(-ENOMEM);
1706
Christoph Hellwig1ae16022016-02-26 11:02:14 +01001707 config_group_init_type_name(&gi->group, name, &gadget_root_type);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001708
1709 config_group_init_type_name(&gi->functions_group, "functions",
1710 &functions_type);
Christoph Hellwig1ae16022016-02-26 11:02:14 +01001711 configfs_add_default_group(&gi->functions_group, &gi->group);
1712
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001713 config_group_init_type_name(&gi->configs_group, "configs",
1714 &config_desc_type);
Christoph Hellwig1ae16022016-02-26 11:02:14 +01001715 configfs_add_default_group(&gi->configs_group, &gi->group);
1716
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001717 config_group_init_type_name(&gi->strings_group, "strings",
1718 &gadget_strings_strings_type);
Christoph Hellwig1ae16022016-02-26 11:02:14 +01001719 configfs_add_default_group(&gi->strings_group, &gi->group);
1720
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +02001721 config_group_init_type_name(&gi->os_desc_group, "os_desc",
1722 &os_desc_type);
Christoph Hellwig1ae16022016-02-26 11:02:14 +01001723 configfs_add_default_group(&gi->os_desc_group, &gi->group);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001724
1725 gi->composite.bind = configfs_do_nothing;
1726 gi->composite.unbind = configfs_do_nothing;
1727 gi->composite.suspend = NULL;
1728 gi->composite.resume = NULL;
1729 gi->composite.max_speed = USB_SPEED_SUPER;
1730
1731 mutex_init(&gi->lock);
1732 INIT_LIST_HEAD(&gi->string_list);
1733 INIT_LIST_HEAD(&gi->available_func);
1734
1735 composite_init_dev(&gi->cdev);
1736 gi->cdev.desc.bLength = USB_DT_DEVICE_SIZE;
1737 gi->cdev.desc.bDescriptorType = USB_DT_DEVICE;
1738 gi->cdev.desc.bcdDevice = cpu_to_le16(get_default_bcdDevice());
1739
1740 gi->composite.gadget_driver = configfs_driver_template;
1741
1742 gi->composite.gadget_driver.function = kstrdup(name, GFP_KERNEL);
1743 gi->composite.name = gi->composite.gadget_driver.function;
1744
Badhri Jagan Sridharan4b2c8512015-08-09 15:12:50 -07001745 if (!gi->composite.gadget_driver.function)
Badhri Jagan Sridharan2a387e52015-03-27 14:15:19 -07001746 goto err;
Badhri Jagan Sridharan51af1202015-07-14 15:46:11 -07001747
Ajay Agarwalfea56da2017-05-30 10:27:23 +05301748 gadget_index++;
1749 pr_debug("Creating gadget index %d\n", gadget_index);
Badhri Jagan Sridharan4b2c8512015-08-09 15:12:50 -07001750 if (android_device_create(gi) < 0)
1751 goto err;
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001752
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001753 return &gi->group;
Badhri Jagan Sridharan51af1202015-07-14 15:46:11 -07001754
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001755err:
1756 kfree(gi);
1757 return ERR_PTR(-ENOMEM);
1758}
1759
1760static void gadgets_drop(struct config_group *group, struct config_item *item)
1761{
Ajay Agarwalfea56da2017-05-30 10:27:23 +05301762 struct gadget_info *gi;
1763
1764 gi = container_of(to_config_group(item), struct gadget_info, group);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001765 config_item_put(item);
Ajay Agarwalfea56da2017-05-30 10:27:23 +05301766 if (gi->dev) {
1767 android_device_destroy(gi->dev);
1768 gi->dev = NULL;
1769 }
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001770}
1771
1772static struct configfs_group_operations gadgets_ops = {
1773 .make_group = &gadgets_make,
1774 .drop_item = &gadgets_drop,
1775};
1776
1777static struct config_item_type gadgets_type = {
1778 .ct_group_ops = &gadgets_ops,
1779 .ct_owner = THIS_MODULE,
1780};
1781
1782static struct configfs_subsystem gadget_subsys = {
1783 .su_group = {
1784 .cg_item = {
1785 .ci_namebuf = "usb_gadget",
1786 .ci_type = &gadgets_type,
1787 },
1788 },
1789 .su_mutex = __MUTEX_INITIALIZER(gadget_subsys.su_mutex),
1790};
1791
Andrzej Pietrasiewicz092a4bd2013-09-26 14:38:15 +02001792void unregister_gadget_item(struct config_item *item)
1793{
1794 struct gadget_info *gi = to_gadget_info(item);
1795
Winter Wangcee51c32016-07-27 10:03:19 +08001796 mutex_lock(&gi->lock);
Andrzej Pietrasiewicz092a4bd2013-09-26 14:38:15 +02001797 unregister_gadget(gi);
Winter Wangcee51c32016-07-27 10:03:19 +08001798 mutex_unlock(&gi->lock);
Andrzej Pietrasiewicz092a4bd2013-09-26 14:38:15 +02001799}
Felipe Balbi0700faa2014-04-01 13:19:32 -05001800EXPORT_SYMBOL_GPL(unregister_gadget_item);
Andrzej Pietrasiewicz092a4bd2013-09-26 14:38:15 +02001801
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001802static int __init gadget_cfs_init(void)
1803{
1804 int ret;
1805
1806 config_group_init(&gadget_subsys.su_group);
1807
1808 ret = configfs_register_subsystem(&gadget_subsys);
Badhri Jagan Sridharan1c3865d2014-12-15 10:44:47 -08001809
1810#ifdef CONFIG_USB_CONFIGFS_UEVENT
1811 android_class = class_create(THIS_MODULE, "android_usb");
1812 if (IS_ERR(android_class))
1813 return PTR_ERR(android_class);
1814#endif
1815
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001816 return ret;
1817}
1818module_init(gadget_cfs_init);
1819
1820static void __exit gadget_cfs_exit(void)
1821{
1822 configfs_unregister_subsystem(&gadget_subsys);
Badhri Jagan Sridharan2a387e52015-03-27 14:15:19 -07001823#ifdef CONFIG_USB_CONFIGFS_UEVENT
1824 if (!IS_ERR(android_class))
1825 class_destroy(android_class);
1826#endif
1827
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001828}
1829module_exit(gadget_cfs_exit);