blob: 625e44db5ff30a23f9e2ecd924346fb6d51f18ab [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];
Peter Chenaa919ef2019-08-26 15:10:55 -040095 spinlock_t spinlock;
96 bool unbind;
Badhri Jagan Sridharan1c3865d2014-12-15 10:44:47 -080097#ifdef CONFIG_USB_CONFIGFS_UEVENT
98 bool connected;
99 bool sw_connected;
100 struct work_struct work;
101 struct device *dev;
102#endif
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100103};
104
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200105static inline struct gadget_info *to_gadget_info(struct config_item *item)
106{
107 return container_of(to_config_group(item), struct gadget_info, group);
108}
109
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100110struct config_usb_cfg {
111 struct config_group group;
112 struct config_group strings_group;
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100113 struct list_head string_list;
114 struct usb_configuration c;
115 struct list_head func_list;
116 struct usb_gadget_strings *gstrings[MAX_USB_STRING_LANGS + 1];
117};
118
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200119static inline struct config_usb_cfg *to_config_usb_cfg(struct config_item *item)
120{
121 return container_of(to_config_group(item), struct config_usb_cfg,
122 group);
123}
124
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100125struct gadget_strings {
126 struct usb_gadget_strings stringtab_dev;
127 struct usb_string strings[USB_GADGET_FIRST_AVAIL_IDX];
128 char *manufacturer;
129 char *product;
130 char *serialnumber;
131
132 struct config_group group;
133 struct list_head list;
134};
135
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200136struct os_desc {
137 struct config_group group;
138};
139
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100140struct gadget_config_name {
141 struct usb_gadget_strings stringtab_dev;
142 struct usb_string strings;
143 char *configuration;
144
145 struct config_group group;
146 struct list_head list;
147};
148
Jim Lin240e2d02017-01-13 16:07:58 +0800149#define MAX_USB_STRING_LEN 126
150#define MAX_USB_STRING_WITH_NULL_LEN (MAX_USB_STRING_LEN+1)
151
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100152static int usb_string_copy(const char *s, char **s_copy)
153{
154 int ret;
155 char *str;
156 char *copy = *s_copy;
157 ret = strlen(s);
Jim Lin240e2d02017-01-13 16:07:58 +0800158 if (ret > MAX_USB_STRING_LEN)
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100159 return -EOVERFLOW;
160
Jim Lin240e2d02017-01-13 16:07:58 +0800161 if (copy) {
162 str = copy;
163 } else {
164 str = kmalloc(MAX_USB_STRING_WITH_NULL_LEN, GFP_KERNEL);
165 if (!str)
166 return -ENOMEM;
167 }
Manu Gautam7fffcd42017-03-28 11:28:24 +0530168 strlcpy(str, s, MAX_USB_STRING_WITH_NULL_LEN);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100169 if (str[ret - 1] == '\n')
170 str[ret - 1] = '\0';
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100171 *s_copy = str;
172 return 0;
173}
174
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100175#define GI_DEVICE_DESC_SIMPLE_R_u8(__name) \
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200176static ssize_t gadget_dev_desc_##__name##_show(struct config_item *item, \
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100177 char *page) \
178{ \
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200179 return sprintf(page, "0x%02x\n", \
180 to_gadget_info(item)->cdev.desc.__name); \
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100181}
182
183#define GI_DEVICE_DESC_SIMPLE_R_u16(__name) \
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200184static ssize_t gadget_dev_desc_##__name##_show(struct config_item *item, \
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100185 char *page) \
186{ \
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200187 return sprintf(page, "0x%04x\n", \
188 le16_to_cpup(&to_gadget_info(item)->cdev.desc.__name)); \
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100189}
190
191
192#define GI_DEVICE_DESC_SIMPLE_W_u8(_name) \
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200193static ssize_t gadget_dev_desc_##_name##_store(struct config_item *item, \
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100194 const char *page, size_t len) \
195{ \
196 u8 val; \
197 int ret; \
198 ret = kstrtou8(page, 0, &val); \
199 if (ret) \
200 return ret; \
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200201 to_gadget_info(item)->cdev.desc._name = val; \
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100202 return len; \
203}
204
205#define GI_DEVICE_DESC_SIMPLE_W_u16(_name) \
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200206static ssize_t gadget_dev_desc_##_name##_store(struct config_item *item, \
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100207 const char *page, size_t len) \
208{ \
209 u16 val; \
210 int ret; \
211 ret = kstrtou16(page, 0, &val); \
212 if (ret) \
213 return ret; \
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200214 to_gadget_info(item)->cdev.desc._name = cpu_to_le16p(&val); \
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100215 return len; \
216}
217
218#define GI_DEVICE_DESC_SIMPLE_RW(_name, _type) \
219 GI_DEVICE_DESC_SIMPLE_R_##_type(_name) \
220 GI_DEVICE_DESC_SIMPLE_W_##_type(_name)
221
222GI_DEVICE_DESC_SIMPLE_R_u16(bcdUSB);
223GI_DEVICE_DESC_SIMPLE_RW(bDeviceClass, u8);
224GI_DEVICE_DESC_SIMPLE_RW(bDeviceSubClass, u8);
225GI_DEVICE_DESC_SIMPLE_RW(bDeviceProtocol, u8);
226GI_DEVICE_DESC_SIMPLE_RW(bMaxPacketSize0, u8);
227GI_DEVICE_DESC_SIMPLE_RW(idVendor, u16);
228GI_DEVICE_DESC_SIMPLE_RW(idProduct, u16);
229GI_DEVICE_DESC_SIMPLE_R_u16(bcdDevice);
230
231static ssize_t is_valid_bcd(u16 bcd_val)
232{
233 if ((bcd_val & 0xf) > 9)
234 return -EINVAL;
235 if (((bcd_val >> 4) & 0xf) > 9)
236 return -EINVAL;
237 if (((bcd_val >> 8) & 0xf) > 9)
238 return -EINVAL;
239 if (((bcd_val >> 12) & 0xf) > 9)
240 return -EINVAL;
241 return 0;
242}
243
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200244static ssize_t gadget_dev_desc_bcdDevice_store(struct config_item *item,
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100245 const char *page, size_t len)
246{
247 u16 bcdDevice;
248 int ret;
249
250 ret = kstrtou16(page, 0, &bcdDevice);
251 if (ret)
252 return ret;
253 ret = is_valid_bcd(bcdDevice);
254 if (ret)
255 return ret;
256
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200257 to_gadget_info(item)->cdev.desc.bcdDevice = cpu_to_le16(bcdDevice);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100258 return len;
259}
260
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200261static ssize_t gadget_dev_desc_bcdUSB_store(struct config_item *item,
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100262 const char *page, size_t len)
263{
264 u16 bcdUSB;
265 int ret;
266
267 ret = kstrtou16(page, 0, &bcdUSB);
268 if (ret)
269 return ret;
270 ret = is_valid_bcd(bcdUSB);
271 if (ret)
272 return ret;
273
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200274 to_gadget_info(item)->cdev.desc.bcdUSB = cpu_to_le16(bcdUSB);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100275 return len;
276}
277
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200278static ssize_t gadget_dev_desc_UDC_show(struct config_item *item, char *page)
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100279{
Ruslan Bilovolafdaadc2015-11-23 09:56:36 +0100280 char *udc_name = to_gadget_info(item)->composite.gadget_driver.udc_name;
281
282 return sprintf(page, "%s\n", udc_name ?: "");
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100283}
284
285static int unregister_gadget(struct gadget_info *gi)
286{
287 int ret;
288
Ruslan Bilovolafdaadc2015-11-23 09:56:36 +0100289 if (!gi->composite.gadget_driver.udc_name)
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100290 return -ENODEV;
291
Vijayavardhan Vennapusa4ca835b2017-10-30 14:33:51 +0530292 gi->unbinding = true;
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100293 ret = usb_gadget_unregister_driver(&gi->composite.gadget_driver);
294 if (ret)
295 return ret;
Vijayavardhan Vennapusa4ca835b2017-10-30 14:33:51 +0530296
297 gi->unbinding = false;
Ruslan Bilovolafdaadc2015-11-23 09:56:36 +0100298 kfree(gi->composite.gadget_driver.udc_name);
299 gi->composite.gadget_driver.udc_name = NULL;
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100300 return 0;
301}
302
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200303static ssize_t gadget_dev_desc_UDC_store(struct config_item *item,
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100304 const char *page, size_t len)
305{
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200306 struct gadget_info *gi = to_gadget_info(item);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100307 char *name;
308 int ret;
309
310 name = kstrdup(page, GFP_KERNEL);
311 if (!name)
312 return -ENOMEM;
313 if (name[len - 1] == '\n')
314 name[len - 1] = '\0';
315
316 mutex_lock(&gi->lock);
317
Badhri Jagan Sridharan1c3865d2014-12-15 10:44:47 -0800318 if (!strlen(name) || strcmp(name, "none") == 0) {
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100319 ret = unregister_gadget(gi);
320 if (ret)
321 goto err;
John Keeping59682e72017-02-28 10:55:30 +0000322 kfree(name);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100323 } else {
Ruslan Bilovolafdaadc2015-11-23 09:56:36 +0100324 if (gi->composite.gadget_driver.udc_name) {
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100325 ret = -EBUSY;
326 goto err;
327 }
Ruslan Bilovolafdaadc2015-11-23 09:56:36 +0100328 gi->composite.gadget_driver.udc_name = name;
329 ret = usb_gadget_probe_driver(&gi->composite.gadget_driver);
330 if (ret) {
331 gi->composite.gadget_driver.udc_name = NULL;
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100332 goto err;
Ruslan Bilovolafdaadc2015-11-23 09:56:36 +0100333 }
Chandana Kishori Chiluverub92f1332019-06-11 12:38:42 +0530334 schedule_work(&gi->work);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100335 }
336 mutex_unlock(&gi->lock);
337 return len;
338err:
339 kfree(name);
340 mutex_unlock(&gi->lock);
341 return ret;
342}
343
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200344CONFIGFS_ATTR(gadget_dev_desc_, bDeviceClass);
345CONFIGFS_ATTR(gadget_dev_desc_, bDeviceSubClass);
346CONFIGFS_ATTR(gadget_dev_desc_, bDeviceProtocol);
347CONFIGFS_ATTR(gadget_dev_desc_, bMaxPacketSize0);
348CONFIGFS_ATTR(gadget_dev_desc_, idVendor);
349CONFIGFS_ATTR(gadget_dev_desc_, idProduct);
350CONFIGFS_ATTR(gadget_dev_desc_, bcdDevice);
351CONFIGFS_ATTR(gadget_dev_desc_, bcdUSB);
352CONFIGFS_ATTR(gadget_dev_desc_, UDC);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100353
354static struct configfs_attribute *gadget_root_attrs[] = {
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200355 &gadget_dev_desc_attr_bDeviceClass,
356 &gadget_dev_desc_attr_bDeviceSubClass,
357 &gadget_dev_desc_attr_bDeviceProtocol,
358 &gadget_dev_desc_attr_bMaxPacketSize0,
359 &gadget_dev_desc_attr_idVendor,
360 &gadget_dev_desc_attr_idProduct,
361 &gadget_dev_desc_attr_bcdDevice,
362 &gadget_dev_desc_attr_bcdUSB,
363 &gadget_dev_desc_attr_UDC,
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100364 NULL,
365};
366
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100367static inline struct gadget_strings *to_gadget_strings(struct config_item *item)
368{
369 return container_of(to_config_group(item), struct gadget_strings,
370 group);
371}
372
373static inline struct gadget_config_name *to_gadget_config_name(
374 struct config_item *item)
375{
376 return container_of(to_config_group(item), struct gadget_config_name,
377 group);
378}
379
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100380static inline struct usb_function_instance *to_usb_function_instance(
381 struct config_item *item)
382{
383 return container_of(to_config_group(item),
384 struct usb_function_instance, group);
385}
386
387static void gadget_info_attr_release(struct config_item *item)
388{
389 struct gadget_info *gi = to_gadget_info(item);
390
391 WARN_ON(!list_empty(&gi->cdev.configs));
392 WARN_ON(!list_empty(&gi->string_list));
393 WARN_ON(!list_empty(&gi->available_func));
394 kfree(gi->composite.gadget_driver.function);
395 kfree(gi);
396}
397
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100398static struct configfs_item_operations gadget_root_item_ops = {
399 .release = gadget_info_attr_release,
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100400};
401
402static void gadget_config_attr_release(struct config_item *item)
403{
404 struct config_usb_cfg *cfg = to_config_usb_cfg(item);
405
406 WARN_ON(!list_empty(&cfg->c.functions));
407 list_del(&cfg->c.list);
408 kfree(cfg->c.label);
409 kfree(cfg);
410}
411
412static int config_usb_cfg_link(
413 struct config_item *usb_cfg_ci,
414 struct config_item *usb_func_ci)
415{
416 struct config_usb_cfg *cfg = to_config_usb_cfg(usb_cfg_ci);
417 struct usb_composite_dev *cdev = cfg->c.cdev;
418 struct gadget_info *gi = container_of(cdev, struct gadget_info, cdev);
419
420 struct config_group *group = to_config_group(usb_func_ci);
421 struct usb_function_instance *fi = container_of(group,
422 struct usb_function_instance, group);
423 struct usb_function_instance *a_fi;
424 struct usb_function *f;
425 int ret;
426
427 mutex_lock(&gi->lock);
428 /*
429 * Make sure this function is from within our _this_ gadget and not
430 * from another gadget or a random directory.
431 * Also a function instance can only be linked once.
432 */
433 list_for_each_entry(a_fi, &gi->available_func, cfs_list) {
434 if (a_fi == fi)
435 break;
436 }
437 if (a_fi != fi) {
438 ret = -EINVAL;
439 goto out;
440 }
441
442 list_for_each_entry(f, &cfg->func_list, list) {
443 if (f->fi == fi) {
444 ret = -EEXIST;
445 goto out;
446 }
447 }
448
449 f = usb_get_function(fi);
450 if (IS_ERR(f)) {
451 ret = PTR_ERR(f);
452 goto out;
453 }
454
455 /* stash the function until we bind it to the gadget */
456 list_add_tail(&f->list, &cfg->func_list);
457 ret = 0;
458out:
459 mutex_unlock(&gi->lock);
460 return ret;
461}
462
463static int config_usb_cfg_unlink(
464 struct config_item *usb_cfg_ci,
465 struct config_item *usb_func_ci)
466{
467 struct config_usb_cfg *cfg = to_config_usb_cfg(usb_cfg_ci);
468 struct usb_composite_dev *cdev = cfg->c.cdev;
469 struct gadget_info *gi = container_of(cdev, struct gadget_info, cdev);
470
471 struct config_group *group = to_config_group(usb_func_ci);
472 struct usb_function_instance *fi = container_of(group,
473 struct usb_function_instance, group);
474 struct usb_function *f;
475
476 /*
477 * ideally I would like to forbid to unlink functions while a gadget is
478 * bound to an UDC. Since this isn't possible at the moment, we simply
479 * force an unbind, the function is available here and then we can
480 * remove the function.
481 */
482 mutex_lock(&gi->lock);
Ruslan Bilovolafdaadc2015-11-23 09:56:36 +0100483 if (gi->composite.gadget_driver.udc_name)
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100484 unregister_gadget(gi);
Ruslan Bilovolafdaadc2015-11-23 09:56:36 +0100485 WARN_ON(gi->composite.gadget_driver.udc_name);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100486
487 list_for_each_entry(f, &cfg->func_list, list) {
488 if (f->fi == fi) {
489 list_del(&f->list);
490 usb_put_function(f);
491 mutex_unlock(&gi->lock);
492 return 0;
493 }
494 }
495 mutex_unlock(&gi->lock);
David Rientjes75bfe232013-04-07 14:11:47 -0700496 WARN(1, "Unable to locate function to unbind\n");
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100497 return 0;
498}
499
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100500static struct configfs_item_operations gadget_config_item_ops = {
501 .release = gadget_config_attr_release,
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100502 .allow_link = config_usb_cfg_link,
503 .drop_link = config_usb_cfg_unlink,
504};
505
506
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200507static ssize_t gadget_config_desc_MaxPower_show(struct config_item *item,
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100508 char *page)
509{
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200510 return sprintf(page, "%u\n", to_config_usb_cfg(item)->c.MaxPower);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100511}
512
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200513static ssize_t gadget_config_desc_MaxPower_store(struct config_item *item,
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100514 const char *page, size_t len)
515{
516 u16 val;
517 int ret;
518 ret = kstrtou16(page, 0, &val);
519 if (ret)
520 return ret;
521 if (DIV_ROUND_UP(val, 8) > 0xff)
522 return -ERANGE;
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200523 to_config_usb_cfg(item)->c.MaxPower = val;
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100524 return len;
525}
526
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200527static ssize_t gadget_config_desc_bmAttributes_show(struct config_item *item,
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100528 char *page)
529{
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200530 return sprintf(page, "0x%02x\n",
531 to_config_usb_cfg(item)->c.bmAttributes);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100532}
533
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200534static ssize_t gadget_config_desc_bmAttributes_store(struct config_item *item,
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100535 const char *page, size_t len)
536{
537 u8 val;
538 int ret;
539 ret = kstrtou8(page, 0, &val);
540 if (ret)
541 return ret;
542 if (!(val & USB_CONFIG_ATT_ONE))
543 return -EINVAL;
544 if (val & ~(USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER |
545 USB_CONFIG_ATT_WAKEUP))
546 return -EINVAL;
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200547 to_config_usb_cfg(item)->c.bmAttributes = val;
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100548 return len;
549}
550
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200551CONFIGFS_ATTR(gadget_config_desc_, MaxPower);
552CONFIGFS_ATTR(gadget_config_desc_, bmAttributes);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100553
554static struct configfs_attribute *gadget_config_attrs[] = {
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200555 &gadget_config_desc_attr_MaxPower,
556 &gadget_config_desc_attr_bmAttributes,
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100557 NULL,
558};
559
560static struct config_item_type gadget_config_type = {
561 .ct_item_ops = &gadget_config_item_ops,
562 .ct_attrs = gadget_config_attrs,
563 .ct_owner = THIS_MODULE,
564};
565
566static struct config_item_type gadget_root_type = {
567 .ct_item_ops = &gadget_root_item_ops,
568 .ct_attrs = gadget_root_attrs,
569 .ct_owner = THIS_MODULE,
570};
571
572static void composite_init_dev(struct usb_composite_dev *cdev)
573{
574 spin_lock_init(&cdev->lock);
575 INIT_LIST_HEAD(&cdev->configs);
576 INIT_LIST_HEAD(&cdev->gstrings);
577}
578
579static struct config_group *function_make(
580 struct config_group *group,
581 const char *name)
582{
583 struct gadget_info *gi;
584 struct usb_function_instance *fi;
585 char buf[MAX_NAME_LEN];
586 char *func_name;
587 char *instance_name;
588 int ret;
589
590 ret = snprintf(buf, MAX_NAME_LEN, "%s", name);
591 if (ret >= MAX_NAME_LEN)
592 return ERR_PTR(-ENAMETOOLONG);
593
594 func_name = buf;
595 instance_name = strchr(func_name, '.');
596 if (!instance_name) {
597 pr_err("Unable to locate . in FUNC.INSTANCE\n");
598 return ERR_PTR(-EINVAL);
599 }
600 *instance_name = '\0';
601 instance_name++;
602
603 fi = usb_get_function_instance(func_name);
604 if (IS_ERR(fi))
Duan Jionga3469412013-09-26 15:55:25 +0800605 return ERR_CAST(fi);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100606
Nicolas Iooss3958b792015-07-17 16:23:45 -0700607 ret = config_item_set_name(&fi->group.cg_item, "%s", name);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100608 if (ret) {
609 usb_put_function_instance(fi);
610 return ERR_PTR(ret);
611 }
Andrzej Pietrasiewicz19338612013-12-03 15:15:21 +0100612 if (fi->set_inst_name) {
613 ret = fi->set_inst_name(fi, instance_name);
614 if (ret) {
615 usb_put_function_instance(fi);
616 return ERR_PTR(ret);
617 }
618 }
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100619
620 gi = container_of(group, struct gadget_info, functions_group);
621
622 mutex_lock(&gi->lock);
623 list_add_tail(&fi->cfs_list, &gi->available_func);
624 mutex_unlock(&gi->lock);
625 return &fi->group;
626}
627
628static void function_drop(
629 struct config_group *group,
630 struct config_item *item)
631{
632 struct usb_function_instance *fi = to_usb_function_instance(item);
633 struct gadget_info *gi;
634
635 gi = container_of(group, struct gadget_info, functions_group);
636
637 mutex_lock(&gi->lock);
638 list_del(&fi->cfs_list);
639 mutex_unlock(&gi->lock);
640 config_item_put(item);
641}
642
643static struct configfs_group_operations functions_ops = {
644 .make_group = &function_make,
645 .drop_item = &function_drop,
646};
647
648static struct config_item_type functions_type = {
649 .ct_group_ops = &functions_ops,
650 .ct_owner = THIS_MODULE,
651};
652
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100653GS_STRINGS_RW(gadget_config_name, configuration);
654
655static struct configfs_attribute *gadget_config_name_langid_attrs[] = {
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200656 &gadget_config_name_attr_configuration,
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100657 NULL,
658};
659
660static void gadget_config_name_attr_release(struct config_item *item)
661{
662 struct gadget_config_name *cn = to_gadget_config_name(item);
663
664 kfree(cn->configuration);
665
666 list_del(&cn->list);
667 kfree(cn);
668}
669
670USB_CONFIG_STRING_RW_OPS(gadget_config_name);
671USB_CONFIG_STRINGS_LANG(gadget_config_name, config_usb_cfg);
672
673static struct config_group *config_desc_make(
674 struct config_group *group,
675 const char *name)
676{
677 struct gadget_info *gi;
678 struct config_usb_cfg *cfg;
679 char buf[MAX_NAME_LEN];
680 char *num_str;
681 u8 num;
682 int ret;
683
684 gi = container_of(group, struct gadget_info, configs_group);
685 ret = snprintf(buf, MAX_NAME_LEN, "%s", name);
686 if (ret >= MAX_NAME_LEN)
687 return ERR_PTR(-ENAMETOOLONG);
688
689 num_str = strchr(buf, '.');
690 if (!num_str) {
691 pr_err("Unable to locate . in name.bConfigurationValue\n");
692 return ERR_PTR(-EINVAL);
693 }
694
695 *num_str = '\0';
696 num_str++;
697
698 if (!strlen(buf))
699 return ERR_PTR(-EINVAL);
700
701 ret = kstrtou8(num_str, 0, &num);
702 if (ret)
703 return ERR_PTR(ret);
704
705 cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
706 if (!cfg)
707 return ERR_PTR(-ENOMEM);
708 cfg->c.label = kstrdup(buf, GFP_KERNEL);
709 if (!cfg->c.label) {
710 ret = -ENOMEM;
711 goto err;
712 }
713 cfg->c.bConfigurationValue = num;
714 cfg->c.MaxPower = CONFIG_USB_GADGET_VBUS_DRAW;
715 cfg->c.bmAttributes = USB_CONFIG_ATT_ONE;
716 INIT_LIST_HEAD(&cfg->string_list);
717 INIT_LIST_HEAD(&cfg->func_list);
718
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100719 config_group_init_type_name(&cfg->group, name,
720 &gadget_config_type);
Christoph Hellwig1ae16022016-02-26 11:02:14 +0100721
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100722 config_group_init_type_name(&cfg->strings_group, "strings",
723 &gadget_config_name_strings_type);
Christoph Hellwig1ae16022016-02-26 11:02:14 +0100724 configfs_add_default_group(&cfg->strings_group, &cfg->group);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100725
726 ret = usb_add_config_only(&gi->cdev, &cfg->c);
727 if (ret)
728 goto err;
729
730 return &cfg->group;
731err:
732 kfree(cfg->c.label);
733 kfree(cfg);
734 return ERR_PTR(ret);
735}
736
737static void config_desc_drop(
738 struct config_group *group,
739 struct config_item *item)
740{
741 config_item_put(item);
742}
743
744static struct configfs_group_operations config_desc_ops = {
745 .make_group = &config_desc_make,
746 .drop_item = &config_desc_drop,
747};
748
749static struct config_item_type config_desc_type = {
750 .ct_group_ops = &config_desc_ops,
751 .ct_owner = THIS_MODULE,
752};
753
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100754GS_STRINGS_RW(gadget_strings, manufacturer);
755GS_STRINGS_RW(gadget_strings, product);
756GS_STRINGS_RW(gadget_strings, serialnumber);
757
758static struct configfs_attribute *gadget_strings_langid_attrs[] = {
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200759 &gadget_strings_attr_manufacturer,
760 &gadget_strings_attr_product,
761 &gadget_strings_attr_serialnumber,
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +0100762 NULL,
763};
764
765static void gadget_strings_attr_release(struct config_item *item)
766{
767 struct gadget_strings *gs = to_gadget_strings(item);
768
769 kfree(gs->manufacturer);
770 kfree(gs->product);
771 kfree(gs->serialnumber);
772
773 list_del(&gs->list);
774 kfree(gs);
775}
776
777USB_CONFIG_STRING_RW_OPS(gadget_strings);
778USB_CONFIG_STRINGS_LANG(gadget_strings, gadget_info);
779
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200780static inline struct os_desc *to_os_desc(struct config_item *item)
781{
782 return container_of(to_config_group(item), struct os_desc, group);
783}
784
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200785static inline struct gadget_info *os_desc_item_to_gadget_info(
786 struct config_item *item)
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200787{
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200788 return to_gadget_info(to_os_desc(item)->group.cg_item.ci_parent);
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200789}
790
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200791static ssize_t os_desc_use_show(struct config_item *item, char *page)
792{
793 return sprintf(page, "%d",
794 os_desc_item_to_gadget_info(item)->use_os_desc);
795}
796
797static ssize_t os_desc_use_store(struct config_item *item, const char *page,
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200798 size_t len)
799{
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200800 struct gadget_info *gi = os_desc_item_to_gadget_info(item);
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200801 int ret;
802 bool use;
803
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200804 mutex_lock(&gi->lock);
805 ret = strtobool(page, &use);
806 if (!ret) {
807 gi->use_os_desc = use;
808 ret = len;
809 }
810 mutex_unlock(&gi->lock);
811
812 return ret;
813}
814
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200815static ssize_t os_desc_b_vendor_code_show(struct config_item *item, char *page)
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200816{
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200817 return sprintf(page, "%d",
818 os_desc_item_to_gadget_info(item)->b_vendor_code);
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200819}
820
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200821static ssize_t os_desc_b_vendor_code_store(struct config_item *item,
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200822 const char *page, size_t len)
823{
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200824 struct gadget_info *gi = os_desc_item_to_gadget_info(item);
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200825 int ret;
826 u8 b_vendor_code;
827
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200828 mutex_lock(&gi->lock);
829 ret = kstrtou8(page, 0, &b_vendor_code);
830 if (!ret) {
831 gi->b_vendor_code = b_vendor_code;
832 ret = len;
833 }
834 mutex_unlock(&gi->lock);
835
836 return ret;
837}
838
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200839static ssize_t os_desc_qw_sign_show(struct config_item *item, char *page)
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200840{
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200841 struct gadget_info *gi = os_desc_item_to_gadget_info(item);
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200842
843 memcpy(page, gi->qw_sign, OS_STRING_QW_SIGN_LEN);
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200844 return OS_STRING_QW_SIGN_LEN;
845}
846
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200847static ssize_t os_desc_qw_sign_store(struct config_item *item, const char *page,
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200848 size_t len)
849{
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200850 struct gadget_info *gi = os_desc_item_to_gadget_info(item);
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200851 int res, l;
852
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200853 l = min((int)len, OS_STRING_QW_SIGN_LEN >> 1);
854 if (page[l - 1] == '\n')
855 --l;
856
857 mutex_lock(&gi->lock);
858 res = utf8s_to_utf16s(page, l,
859 UTF16_LITTLE_ENDIAN, (wchar_t *) gi->qw_sign,
860 OS_STRING_QW_SIGN_LEN);
861 if (res > 0)
862 res = len;
863 mutex_unlock(&gi->lock);
864
865 return res;
866}
867
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200868CONFIGFS_ATTR(os_desc_, use);
869CONFIGFS_ATTR(os_desc_, b_vendor_code);
870CONFIGFS_ATTR(os_desc_, qw_sign);
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200871
872static struct configfs_attribute *os_desc_attrs[] = {
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200873 &os_desc_attr_use,
874 &os_desc_attr_b_vendor_code,
875 &os_desc_attr_qw_sign,
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200876 NULL,
877};
878
879static void os_desc_attr_release(struct config_item *item)
880{
881 struct os_desc *os_desc = to_os_desc(item);
882 kfree(os_desc);
883}
884
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +0200885static int os_desc_link(struct config_item *os_desc_ci,
886 struct config_item *usb_cfg_ci)
887{
888 struct gadget_info *gi = container_of(to_config_group(os_desc_ci),
889 struct gadget_info, os_desc_group);
890 struct usb_composite_dev *cdev = &gi->cdev;
891 struct config_usb_cfg *c_target =
892 container_of(to_config_group(usb_cfg_ci),
893 struct config_usb_cfg, group);
894 struct usb_configuration *c;
895 int ret;
896
897 mutex_lock(&gi->lock);
898 list_for_each_entry(c, &cdev->configs, list) {
899 if (c == &c_target->c)
900 break;
901 }
902 if (c != &c_target->c) {
903 ret = -EINVAL;
904 goto out;
905 }
906
907 if (cdev->os_desc_config) {
908 ret = -EBUSY;
909 goto out;
910 }
911
912 cdev->os_desc_config = &c_target->c;
913 ret = 0;
914
915out:
916 mutex_unlock(&gi->lock);
917 return ret;
918}
919
920static int os_desc_unlink(struct config_item *os_desc_ci,
921 struct config_item *usb_cfg_ci)
922{
923 struct gadget_info *gi = container_of(to_config_group(os_desc_ci),
924 struct gadget_info, os_desc_group);
925 struct usb_composite_dev *cdev = &gi->cdev;
926
927 mutex_lock(&gi->lock);
Ruslan Bilovolafdaadc2015-11-23 09:56:36 +0100928 if (gi->composite.gadget_driver.udc_name)
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +0200929 unregister_gadget(gi);
930 cdev->os_desc_config = NULL;
Ruslan Bilovolafdaadc2015-11-23 09:56:36 +0100931 WARN_ON(gi->composite.gadget_driver.udc_name);
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +0200932 mutex_unlock(&gi->lock);
933 return 0;
934}
935
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200936static struct configfs_item_operations os_desc_ops = {
937 .release = os_desc_attr_release,
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +0200938 .allow_link = os_desc_link,
939 .drop_link = os_desc_unlink,
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +0200940};
941
942static struct config_item_type os_desc_type = {
943 .ct_item_ops = &os_desc_ops,
944 .ct_attrs = os_desc_attrs,
945 .ct_owner = THIS_MODULE,
946};
947
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +0200948static inline struct usb_os_desc_ext_prop
949*to_usb_os_desc_ext_prop(struct config_item *item)
950{
951 return container_of(item, struct usb_os_desc_ext_prop, item);
952}
953
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200954static ssize_t ext_prop_type_show(struct config_item *item, char *page)
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +0200955{
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200956 return sprintf(page, "%d", to_usb_os_desc_ext_prop(item)->type);
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +0200957}
958
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200959static ssize_t ext_prop_type_store(struct config_item *item,
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +0200960 const char *page, size_t len)
961{
Christoph Hellwig45b6a732015-10-03 15:32:38 +0200962 struct usb_os_desc_ext_prop *ext_prop = to_usb_os_desc_ext_prop(item);
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +0200963 struct usb_os_desc *desc = to_usb_os_desc(ext_prop->item.ci_parent);
964 u8 type;
965 int ret;
966
967 if (desc->opts_mutex)
968 mutex_lock(desc->opts_mutex);
969 ret = kstrtou8(page, 0, &type);
970 if (ret)
971 goto end;
972 if (type < USB_EXT_PROP_UNICODE || type > USB_EXT_PROP_UNICODE_MULTI) {
973 ret = -EINVAL;
974 goto end;
975 }
976
977 if ((ext_prop->type == USB_EXT_PROP_BINARY ||
978 ext_prop->type == USB_EXT_PROP_LE32 ||
979 ext_prop->type == USB_EXT_PROP_BE32) &&
980 (type == USB_EXT_PROP_UNICODE ||
981 type == USB_EXT_PROP_UNICODE_ENV ||
982 type == USB_EXT_PROP_UNICODE_LINK))
983 ext_prop->data_len <<= 1;
984 else if ((ext_prop->type == USB_EXT_PROP_UNICODE ||
985 ext_prop->type == USB_EXT_PROP_UNICODE_ENV ||
986 ext_prop->type == USB_EXT_PROP_UNICODE_LINK) &&
987 (type == USB_EXT_PROP_BINARY ||
988 type == USB_EXT_PROP_LE32 ||
989 type == USB_EXT_PROP_BE32))
990 ext_prop->data_len >>= 1;
991 ext_prop->type = type;
992 ret = len;
993
994end:
995 if (desc->opts_mutex)
996 mutex_unlock(desc->opts_mutex);
997 return ret;
998}
999
Christoph Hellwig45b6a732015-10-03 15:32:38 +02001000static ssize_t ext_prop_data_show(struct config_item *item, char *page)
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +02001001{
Christoph Hellwig45b6a732015-10-03 15:32:38 +02001002 struct usb_os_desc_ext_prop *ext_prop = to_usb_os_desc_ext_prop(item);
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +02001003 int len = ext_prop->data_len;
1004
1005 if (ext_prop->type == USB_EXT_PROP_UNICODE ||
1006 ext_prop->type == USB_EXT_PROP_UNICODE_ENV ||
1007 ext_prop->type == USB_EXT_PROP_UNICODE_LINK)
1008 len >>= 1;
1009 memcpy(page, ext_prop->data, len);
1010
1011 return len;
1012}
1013
Christoph Hellwig45b6a732015-10-03 15:32:38 +02001014static ssize_t ext_prop_data_store(struct config_item *item,
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +02001015 const char *page, size_t len)
1016{
Christoph Hellwig45b6a732015-10-03 15:32:38 +02001017 struct usb_os_desc_ext_prop *ext_prop = to_usb_os_desc_ext_prop(item);
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +02001018 struct usb_os_desc *desc = to_usb_os_desc(ext_prop->item.ci_parent);
1019 char *new_data;
1020 size_t ret_len = len;
1021
1022 if (page[len - 1] == '\n' || page[len - 1] == '\0')
1023 --len;
Benoit Taine58b949e2014-05-26 17:21:20 +02001024 new_data = kmemdup(page, len, GFP_KERNEL);
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +02001025 if (!new_data)
1026 return -ENOMEM;
1027
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +02001028 if (desc->opts_mutex)
1029 mutex_lock(desc->opts_mutex);
1030 kfree(ext_prop->data);
1031 ext_prop->data = new_data;
1032 desc->ext_prop_len -= ext_prop->data_len;
1033 ext_prop->data_len = len;
1034 desc->ext_prop_len += ext_prop->data_len;
1035 if (ext_prop->type == USB_EXT_PROP_UNICODE ||
1036 ext_prop->type == USB_EXT_PROP_UNICODE_ENV ||
1037 ext_prop->type == USB_EXT_PROP_UNICODE_LINK) {
1038 desc->ext_prop_len -= ext_prop->data_len;
1039 ext_prop->data_len <<= 1;
1040 ext_prop->data_len += 2;
1041 desc->ext_prop_len += ext_prop->data_len;
1042 }
1043 if (desc->opts_mutex)
1044 mutex_unlock(desc->opts_mutex);
1045 return ret_len;
1046}
1047
Christoph Hellwig45b6a732015-10-03 15:32:38 +02001048CONFIGFS_ATTR(ext_prop_, type);
1049CONFIGFS_ATTR(ext_prop_, data);
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +02001050
1051static struct configfs_attribute *ext_prop_attrs[] = {
Christoph Hellwig45b6a732015-10-03 15:32:38 +02001052 &ext_prop_attr_type,
1053 &ext_prop_attr_data,
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +02001054 NULL,
1055};
1056
1057static void usb_os_desc_ext_prop_release(struct config_item *item)
1058{
1059 struct usb_os_desc_ext_prop *ext_prop = to_usb_os_desc_ext_prop(item);
1060
1061 kfree(ext_prop); /* frees a whole chunk */
1062}
1063
1064static struct configfs_item_operations ext_prop_ops = {
1065 .release = usb_os_desc_ext_prop_release,
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +02001066};
1067
1068static struct config_item *ext_prop_make(
1069 struct config_group *group,
1070 const char *name)
1071{
1072 struct usb_os_desc_ext_prop *ext_prop;
1073 struct config_item_type *ext_prop_type;
1074 struct usb_os_desc *desc;
1075 char *vlabuf;
1076
1077 vla_group(data_chunk);
1078 vla_item(data_chunk, struct usb_os_desc_ext_prop, ext_prop, 1);
1079 vla_item(data_chunk, struct config_item_type, ext_prop_type, 1);
1080
1081 vlabuf = kzalloc(vla_group_size(data_chunk), GFP_KERNEL);
1082 if (!vlabuf)
1083 return ERR_PTR(-ENOMEM);
1084
1085 ext_prop = vla_ptr(vlabuf, data_chunk, ext_prop);
1086 ext_prop_type = vla_ptr(vlabuf, data_chunk, ext_prop_type);
1087
1088 desc = container_of(group, struct usb_os_desc, group);
1089 ext_prop_type->ct_item_ops = &ext_prop_ops;
1090 ext_prop_type->ct_attrs = ext_prop_attrs;
1091 ext_prop_type->ct_owner = desc->owner;
1092
1093 config_item_init_type_name(&ext_prop->item, name, ext_prop_type);
1094
1095 ext_prop->name = kstrdup(name, GFP_KERNEL);
1096 if (!ext_prop->name) {
1097 kfree(vlabuf);
1098 return ERR_PTR(-ENOMEM);
1099 }
1100 desc->ext_prop_len += 14;
1101 ext_prop->name_len = 2 * strlen(ext_prop->name) + 2;
1102 if (desc->opts_mutex)
1103 mutex_lock(desc->opts_mutex);
1104 desc->ext_prop_len += ext_prop->name_len;
1105 list_add_tail(&ext_prop->entry, &desc->ext_prop);
1106 ++desc->ext_prop_count;
1107 if (desc->opts_mutex)
1108 mutex_unlock(desc->opts_mutex);
1109
1110 return &ext_prop->item;
1111}
1112
1113static void ext_prop_drop(struct config_group *group, struct config_item *item)
1114{
1115 struct usb_os_desc_ext_prop *ext_prop = to_usb_os_desc_ext_prop(item);
1116 struct usb_os_desc *desc = to_usb_os_desc(&group->cg_item);
1117
1118 if (desc->opts_mutex)
1119 mutex_lock(desc->opts_mutex);
1120 list_del(&ext_prop->entry);
1121 --desc->ext_prop_count;
1122 kfree(ext_prop->name);
1123 desc->ext_prop_len -= (ext_prop->name_len + ext_prop->data_len + 14);
1124 if (desc->opts_mutex)
1125 mutex_unlock(desc->opts_mutex);
1126 config_item_put(item);
1127}
1128
1129static struct configfs_group_operations interf_grp_ops = {
1130 .make_item = &ext_prop_make,
1131 .drop_item = &ext_prop_drop,
1132};
1133
Christoph Hellwig45b6a732015-10-03 15:32:38 +02001134static ssize_t interf_grp_compatible_id_show(struct config_item *item,
Andrzej Pietrasiewiczfe00b132014-06-18 14:24:48 +02001135 char *page)
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001136{
Christoph Hellwig45b6a732015-10-03 15:32:38 +02001137 memcpy(page, to_usb_os_desc(item)->ext_compat_id, 8);
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001138 return 8;
1139}
1140
Christoph Hellwig45b6a732015-10-03 15:32:38 +02001141static ssize_t interf_grp_compatible_id_store(struct config_item *item,
Andrzej Pietrasiewiczfe00b132014-06-18 14:24:48 +02001142 const char *page, size_t len)
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001143{
Christoph Hellwig45b6a732015-10-03 15:32:38 +02001144 struct usb_os_desc *desc = to_usb_os_desc(item);
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001145 int l;
1146
1147 l = min_t(int, 8, len);
1148 if (page[l - 1] == '\n')
1149 --l;
1150 if (desc->opts_mutex)
1151 mutex_lock(desc->opts_mutex);
1152 memcpy(desc->ext_compat_id, page, l);
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001153
1154 if (desc->opts_mutex)
1155 mutex_unlock(desc->opts_mutex);
1156
1157 return len;
1158}
1159
Christoph Hellwig45b6a732015-10-03 15:32:38 +02001160static ssize_t interf_grp_sub_compatible_id_show(struct config_item *item,
Andrzej Pietrasiewiczfe00b132014-06-18 14:24:48 +02001161 char *page)
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001162{
Christoph Hellwig45b6a732015-10-03 15:32:38 +02001163 memcpy(page, to_usb_os_desc(item)->ext_compat_id + 8, 8);
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001164 return 8;
1165}
1166
Christoph Hellwig45b6a732015-10-03 15:32:38 +02001167static ssize_t interf_grp_sub_compatible_id_store(struct config_item *item,
Andrzej Pietrasiewiczfe00b132014-06-18 14:24:48 +02001168 const char *page, size_t len)
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001169{
Christoph Hellwig45b6a732015-10-03 15:32:38 +02001170 struct usb_os_desc *desc = to_usb_os_desc(item);
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001171 int l;
1172
1173 l = min_t(int, 8, len);
1174 if (page[l - 1] == '\n')
1175 --l;
1176 if (desc->opts_mutex)
1177 mutex_lock(desc->opts_mutex);
1178 memcpy(desc->ext_compat_id + 8, page, l);
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001179
1180 if (desc->opts_mutex)
1181 mutex_unlock(desc->opts_mutex);
1182
1183 return len;
1184}
1185
Christoph Hellwig45b6a732015-10-03 15:32:38 +02001186CONFIGFS_ATTR(interf_grp_, compatible_id);
1187CONFIGFS_ATTR(interf_grp_, sub_compatible_id);
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001188
1189static struct configfs_attribute *interf_grp_attrs[] = {
Christoph Hellwig45b6a732015-10-03 15:32:38 +02001190 &interf_grp_attr_compatible_id,
1191 &interf_grp_attr_sub_compatible_id,
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001192 NULL
1193};
1194
Andrew Gabbasov3c57f9d2017-09-30 08:54:52 -07001195struct config_group *usb_os_desc_prepare_interf_dir(
1196 struct config_group *parent,
1197 int n_interf,
1198 struct usb_os_desc **desc,
1199 char **names,
1200 struct module *owner)
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001201{
Christoph Hellwig1ae16022016-02-26 11:02:14 +01001202 struct config_group *os_desc_group;
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001203 struct config_item_type *os_desc_type, *interface_type;
1204
1205 vla_group(data_chunk);
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001206 vla_item(data_chunk, struct config_group, os_desc_group, 1);
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001207 vla_item(data_chunk, struct config_item_type, os_desc_type, 1);
1208 vla_item(data_chunk, struct config_item_type, interface_type, 1);
1209
1210 char *vlabuf = kzalloc(vla_group_size(data_chunk), GFP_KERNEL);
1211 if (!vlabuf)
Andrew Gabbasov3c57f9d2017-09-30 08:54:52 -07001212 return ERR_PTR(-ENOMEM);
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001213
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001214 os_desc_group = vla_ptr(vlabuf, data_chunk, os_desc_group);
1215 os_desc_type = vla_ptr(vlabuf, data_chunk, os_desc_type);
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001216 interface_type = vla_ptr(vlabuf, data_chunk, interface_type);
1217
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001218 os_desc_type->ct_owner = owner;
1219 config_group_init_type_name(os_desc_group, "os_desc", os_desc_type);
Christoph Hellwig1ae16022016-02-26 11:02:14 +01001220 configfs_add_default_group(os_desc_group, parent);
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001221
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +02001222 interface_type->ct_group_ops = &interf_grp_ops;
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001223 interface_type->ct_attrs = interf_grp_attrs;
1224 interface_type->ct_owner = owner;
1225
1226 while (n_interf--) {
1227 struct usb_os_desc *d;
1228
1229 d = desc[n_interf];
Andrzej Pietrasiewicz74194852014-05-08 14:06:28 +02001230 d->owner = owner;
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001231 config_group_init_type_name(&d->group, "", interface_type);
Andrzej Pietrasiewicz14574b52014-06-18 14:24:49 +02001232 config_item_set_name(&d->group.cg_item, "interface.%s",
1233 names[n_interf]);
Christoph Hellwig1ae16022016-02-26 11:02:14 +01001234 configfs_add_default_group(&d->group, os_desc_group);
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001235 }
1236
Andrew Gabbasov3c57f9d2017-09-30 08:54:52 -07001237 return os_desc_group;
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001238}
1239EXPORT_SYMBOL(usb_os_desc_prepare_interf_dir);
1240
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001241static int configfs_do_nothing(struct usb_composite_dev *cdev)
1242{
David Rientjes75bfe232013-04-07 14:11:47 -07001243 WARN_ON(1);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001244 return -EINVAL;
1245}
1246
1247int composite_dev_prepare(struct usb_composite_driver *composite,
1248 struct usb_composite_dev *dev);
1249
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001250int composite_os_desc_req_prepare(struct usb_composite_dev *cdev,
1251 struct usb_ep *ep0);
1252
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001253static void purge_configs_funcs(struct gadget_info *gi)
1254{
1255 struct usb_configuration *c;
1256
1257 list_for_each_entry(c, &gi->cdev.configs, list) {
1258 struct usb_function *f, *tmp;
1259 struct config_usb_cfg *cfg;
1260
1261 cfg = container_of(c, struct config_usb_cfg, c);
1262
Chandana Kishori Chiluverua1bd87c2018-06-18 17:23:18 +05301263 list_for_each_entry_safe_reverse(f, tmp, &c->functions, list) {
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001264
Chandana Kishori Chiluverua1bd87c2018-06-18 17:23:18 +05301265 list_move(&f->list, &cfg->func_list);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001266 if (f->unbind) {
Romain Izardda7b8952016-08-29 12:22:29 +03001267 dev_dbg(&gi->cdev.gadget->dev,
Chandana Kishori Chiluveru7f5670a2017-10-28 23:05:45 +05301268 "unbind function '%s'/%pK\n",
Romain Izarda08f5db2016-07-26 18:21:46 +02001269 f->name, f);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001270 f->unbind(c, f);
1271 }
1272 }
1273 c->next_interface_id = 0;
Krzysztof Opasiak903124f2015-03-20 15:48:56 +01001274 memset(c->interface, 0, sizeof(c->interface));
John Youn554eead2016-02-05 17:06:35 -08001275 c->superspeed_plus = 0;
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001276 c->superspeed = 0;
1277 c->highspeed = 0;
1278 c->fullspeed = 0;
1279 }
1280}
1281
1282static int configfs_composite_bind(struct usb_gadget *gadget,
1283 struct usb_gadget_driver *gdriver)
1284{
1285 struct usb_composite_driver *composite = to_cdriver(gdriver);
1286 struct gadget_info *gi = container_of(composite,
1287 struct gadget_info, composite);
1288 struct usb_composite_dev *cdev = &gi->cdev;
1289 struct usb_configuration *c;
1290 struct usb_string *s;
1291 unsigned i;
1292 int ret;
1293
1294 /* the gi->lock is hold by the caller */
Peter Chenaa919ef2019-08-26 15:10:55 -04001295 gi->unbind = 0;
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001296 cdev->gadget = gadget;
1297 set_gadget_data(gadget, cdev);
1298 ret = composite_dev_prepare(composite, cdev);
1299 if (ret)
1300 return ret;
1301 /* and now the gadget bind */
1302 ret = -EINVAL;
1303
1304 if (list_empty(&gi->cdev.configs)) {
Peter Chen4d9f8722014-05-05 07:39:34 +08001305 pr_err("Need at least one configuration in %s.\n",
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001306 gi->composite.name);
1307 goto err_comp_cleanup;
1308 }
1309
1310
1311 list_for_each_entry(c, &gi->cdev.configs, list) {
1312 struct config_usb_cfg *cfg;
1313
1314 cfg = container_of(c, struct config_usb_cfg, c);
1315 if (list_empty(&cfg->func_list)) {
Peter Chen4d9f8722014-05-05 07:39:34 +08001316 pr_err("Config %s/%d of %s needs at least one function.\n",
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001317 c->label, c->bConfigurationValue,
1318 gi->composite.name);
1319 goto err_comp_cleanup;
1320 }
1321 }
1322
1323 /* init all strings */
1324 if (!list_empty(&gi->string_list)) {
1325 struct gadget_strings *gs;
1326
1327 i = 0;
1328 list_for_each_entry(gs, &gi->string_list, list) {
1329
1330 gi->gstrings[i] = &gs->stringtab_dev;
1331 gs->stringtab_dev.strings = gs->strings;
1332 gs->strings[USB_GADGET_MANUFACTURER_IDX].s =
1333 gs->manufacturer;
1334 gs->strings[USB_GADGET_PRODUCT_IDX].s = gs->product;
1335 gs->strings[USB_GADGET_SERIAL_IDX].s = gs->serialnumber;
1336 i++;
1337 }
1338 gi->gstrings[i] = NULL;
1339 s = usb_gstrings_attach(&gi->cdev, gi->gstrings,
1340 USB_GADGET_FIRST_AVAIL_IDX);
Wei Yongjunfea77072013-05-07 19:50:31 +08001341 if (IS_ERR(s)) {
1342 ret = PTR_ERR(s);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001343 goto err_comp_cleanup;
Wei Yongjunfea77072013-05-07 19:50:31 +08001344 }
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001345
1346 gi->cdev.desc.iManufacturer = s[USB_GADGET_MANUFACTURER_IDX].id;
1347 gi->cdev.desc.iProduct = s[USB_GADGET_PRODUCT_IDX].id;
1348 gi->cdev.desc.iSerialNumber = s[USB_GADGET_SERIAL_IDX].id;
1349 }
1350
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +02001351 if (gi->use_os_desc) {
1352 cdev->use_os_string = true;
1353 cdev->b_vendor_code = gi->b_vendor_code;
1354 memcpy(cdev->qw_sign, gi->qw_sign, OS_STRING_QW_SIGN_LEN);
1355 }
1356
Li Jun41ce84c2015-07-09 15:18:48 +08001357 if (gadget_is_otg(gadget) && !otg_desc[0]) {
1358 struct usb_descriptor_header *usb_desc;
1359
1360 usb_desc = usb_otg_descriptor_alloc(gadget);
1361 if (!usb_desc) {
1362 ret = -ENOMEM;
1363 goto err_comp_cleanup;
1364 }
1365 usb_otg_descriptor_init(gadget, usb_desc);
1366 otg_desc[0] = usb_desc;
1367 otg_desc[1] = NULL;
1368 }
1369
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001370 /* Go through all configs, attach all functions */
1371 list_for_each_entry(c, &gi->cdev.configs, list) {
1372 struct config_usb_cfg *cfg;
1373 struct usb_function *f;
1374 struct usb_function *tmp;
1375 struct gadget_config_name *cn;
1376
Li Jun41ce84c2015-07-09 15:18:48 +08001377 if (gadget_is_otg(gadget))
1378 c->descriptors = otg_desc;
1379
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001380 cfg = container_of(c, struct config_usb_cfg, c);
1381 if (!list_empty(&cfg->string_list)) {
1382 i = 0;
1383 list_for_each_entry(cn, &cfg->string_list, list) {
1384 cfg->gstrings[i] = &cn->stringtab_dev;
1385 cn->stringtab_dev.strings = &cn->strings;
1386 cn->strings.s = cn->configuration;
1387 i++;
1388 }
1389 cfg->gstrings[i] = NULL;
1390 s = usb_gstrings_attach(&gi->cdev, cfg->gstrings, 1);
Wei Yongjunfea77072013-05-07 19:50:31 +08001391 if (IS_ERR(s)) {
1392 ret = PTR_ERR(s);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001393 goto err_comp_cleanup;
Wei Yongjunfea77072013-05-07 19:50:31 +08001394 }
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001395 c->iConfiguration = s[0].id;
1396 }
1397
1398 list_for_each_entry_safe(f, tmp, &cfg->func_list, list) {
1399 list_del(&f->list);
1400 ret = usb_add_function(c, f);
Andrzej Pietrasiewicz5a68e9b2013-08-08 09:43:28 +02001401 if (ret) {
1402 list_add(&f->list, &cfg->func_list);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001403 goto err_purge_funcs;
Andrzej Pietrasiewicz5a68e9b2013-08-08 09:43:28 +02001404 }
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001405 }
1406 usb_ep_autoconfig_reset(cdev->gadget);
1407 }
Andrzej Pietrasiewiczda424312014-05-08 14:06:26 +02001408 if (cdev->use_os_string) {
1409 ret = composite_os_desc_req_prepare(cdev, gadget->ep0);
1410 if (ret)
1411 goto err_purge_funcs;
1412 }
1413
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001414 usb_ep_autoconfig_reset(cdev->gadget);
1415 return 0;
1416
1417err_purge_funcs:
1418 purge_configs_funcs(gi);
1419err_comp_cleanup:
1420 composite_dev_cleanup(cdev);
1421 return ret;
1422}
1423
Badhri Jagan Sridharan1c3865d2014-12-15 10:44:47 -08001424#ifdef CONFIG_USB_CONFIGFS_UEVENT
1425static void android_work(struct work_struct *data)
1426{
1427 struct gadget_info *gi = container_of(data, struct gadget_info, work);
1428 struct usb_composite_dev *cdev = &gi->cdev;
1429 char *disconnected[2] = { "USB_STATE=DISCONNECTED", NULL };
1430 char *connected[2] = { "USB_STATE=CONNECTED", NULL };
1431 char *configured[2] = { "USB_STATE=CONFIGURED", NULL };
1432 /* 0-connected 1-configured 2-disconnected*/
1433 bool status[3] = { false, false, false };
1434 unsigned long flags;
1435 bool uevent_sent = false;
1436
1437 spin_lock_irqsave(&cdev->lock, flags);
1438 if (cdev->config)
1439 status[1] = true;
1440
1441 if (gi->connected != gi->sw_connected) {
1442 if (gi->connected)
1443 status[0] = true;
1444 else
1445 status[2] = true;
1446 gi->sw_connected = gi->connected;
1447 }
1448 spin_unlock_irqrestore(&cdev->lock, flags);
1449
1450 if (status[0]) {
Ajay Agarwalfea56da2017-05-30 10:27:23 +05301451 kobject_uevent_env(&gi->dev->kobj,
Badhri Jagan Sridharan2a387e52015-03-27 14:15:19 -07001452 KOBJ_CHANGE, connected);
Badhri Jagan Sridharan1c3865d2014-12-15 10:44:47 -08001453 pr_info("%s: sent uevent %s\n", __func__, connected[0]);
1454 uevent_sent = true;
1455 }
1456
1457 if (status[1]) {
Ajay Agarwalfea56da2017-05-30 10:27:23 +05301458 kobject_uevent_env(&gi->dev->kobj,
Badhri Jagan Sridharan2a387e52015-03-27 14:15:19 -07001459 KOBJ_CHANGE, configured);
Badhri Jagan Sridharan1c3865d2014-12-15 10:44:47 -08001460 pr_info("%s: sent uevent %s\n", __func__, configured[0]);
1461 uevent_sent = true;
1462 }
1463
1464 if (status[2]) {
Ajay Agarwalfea56da2017-05-30 10:27:23 +05301465 kobject_uevent_env(&gi->dev->kobj,
Badhri Jagan Sridharan2a387e52015-03-27 14:15:19 -07001466 KOBJ_CHANGE, disconnected);
Badhri Jagan Sridharan1c3865d2014-12-15 10:44:47 -08001467 pr_info("%s: sent uevent %s\n", __func__, disconnected[0]);
1468 uevent_sent = true;
1469 }
1470
1471 if (!uevent_sent) {
Chandana Kishori Chiluveru7f5670a2017-10-28 23:05:45 +05301472 pr_info("%s: did not send uevent (%d %d %pK)\n", __func__,
Badhri Jagan Sridharan1c3865d2014-12-15 10:44:47 -08001473 gi->connected, gi->sw_connected, cdev->config);
1474 }
1475}
1476#endif
1477
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001478static void configfs_composite_unbind(struct usb_gadget *gadget)
1479{
1480 struct usb_composite_dev *cdev;
1481 struct gadget_info *gi;
Peter Chenaa919ef2019-08-26 15:10:55 -04001482 unsigned long flags;
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001483
1484 /* the gi->lock is hold by the caller */
1485
1486 cdev = get_gadget_data(gadget);
1487 gi = container_of(cdev, struct gadget_info, cdev);
Peter Chenaa919ef2019-08-26 15:10:55 -04001488 spin_lock_irqsave(&gi->spinlock, flags);
1489 gi->unbind = 1;
1490 spin_unlock_irqrestore(&gi->spinlock, flags);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001491
Li Jun41ce84c2015-07-09 15:18:48 +08001492 kfree(otg_desc[0]);
1493 otg_desc[0] = NULL;
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001494 purge_configs_funcs(gi);
1495 composite_dev_cleanup(cdev);
1496 usb_ep_autoconfig_reset(cdev->gadget);
Peter Chenaa919ef2019-08-26 15:10:55 -04001497 spin_lock_irqsave(&gi->spinlock, flags);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001498 cdev->gadget = NULL;
Vijayavardhan Vennapusa07691fc2020-05-14 08:52:22 +05301499 cdev->deactivations = 0;
1500 gadget->deactivated = false;
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001501 set_gadget_data(gadget, NULL);
Peter Chenaa919ef2019-08-26 15:10:55 -04001502 spin_unlock_irqrestore(&gi->spinlock, flags);
1503}
1504
jianzhou2de43592019-12-09 10:19:45 +08001505#ifndef CONFIG_USB_CONFIGFS_UEVENT
Peter Chenaa919ef2019-08-26 15:10:55 -04001506static int configfs_composite_setup(struct usb_gadget *gadget,
1507 const struct usb_ctrlrequest *ctrl)
1508{
1509 struct usb_composite_dev *cdev;
1510 struct gadget_info *gi;
1511 unsigned long flags;
1512 int ret;
1513
1514 cdev = get_gadget_data(gadget);
1515 if (!cdev)
1516 return 0;
1517
1518 gi = container_of(cdev, struct gadget_info, cdev);
1519 spin_lock_irqsave(&gi->spinlock, flags);
1520 cdev = get_gadget_data(gadget);
1521 if (!cdev || gi->unbind) {
1522 spin_unlock_irqrestore(&gi->spinlock, flags);
1523 return 0;
1524 }
1525
1526 ret = composite_setup(gadget, ctrl);
1527 spin_unlock_irqrestore(&gi->spinlock, flags);
1528 return ret;
1529}
1530
1531static void configfs_composite_disconnect(struct usb_gadget *gadget)
1532{
1533 struct usb_composite_dev *cdev;
1534 struct gadget_info *gi;
1535 unsigned long flags;
1536
1537 cdev = get_gadget_data(gadget);
1538 if (!cdev)
1539 return;
1540
1541 gi = container_of(cdev, struct gadget_info, cdev);
1542 spin_lock_irqsave(&gi->spinlock, flags);
1543 cdev = get_gadget_data(gadget);
1544 if (!cdev || gi->unbind) {
1545 spin_unlock_irqrestore(&gi->spinlock, flags);
1546 return;
1547 }
1548
1549 composite_disconnect(gadget);
1550 spin_unlock_irqrestore(&gi->spinlock, flags);
1551}
jianzhou2de43592019-12-09 10:19:45 +08001552#endif
Peter Chenaa919ef2019-08-26 15:10:55 -04001553
1554static void configfs_composite_suspend(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_suspend(gadget);
1573 spin_unlock_irqrestore(&gi->spinlock, flags);
1574}
1575
1576static void configfs_composite_resume(struct usb_gadget *gadget)
1577{
1578 struct usb_composite_dev *cdev;
1579 struct gadget_info *gi;
1580 unsigned long flags;
1581
1582 cdev = get_gadget_data(gadget);
1583 if (!cdev)
1584 return;
1585
1586 gi = container_of(cdev, struct gadget_info, cdev);
1587 spin_lock_irqsave(&gi->spinlock, flags);
1588 cdev = get_gadget_data(gadget);
1589 if (!cdev || gi->unbind) {
1590 spin_unlock_irqrestore(&gi->spinlock, flags);
1591 return;
1592 }
1593
1594 composite_resume(gadget);
1595 spin_unlock_irqrestore(&gi->spinlock, flags);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001596}
1597
Badhri Jagan Sridharan1c3865d2014-12-15 10:44:47 -08001598#ifdef CONFIG_USB_CONFIGFS_UEVENT
1599static int android_setup(struct usb_gadget *gadget,
1600 const struct usb_ctrlrequest *c)
1601{
1602 struct usb_composite_dev *cdev = get_gadget_data(gadget);
1603 unsigned long flags;
1604 struct gadget_info *gi = container_of(cdev, struct gadget_info, cdev);
1605 int value = -EOPNOTSUPP;
1606 struct usb_function_instance *fi;
1607
1608 spin_lock_irqsave(&cdev->lock, flags);
1609 if (!gi->connected) {
1610 gi->connected = 1;
1611 schedule_work(&gi->work);
1612 }
1613 spin_unlock_irqrestore(&cdev->lock, flags);
1614 list_for_each_entry(fi, &gi->available_func, cfs_list) {
1615 if (fi != NULL && fi->f != NULL && fi->f->setup != NULL) {
1616 value = fi->f->setup(fi->f, c);
1617 if (value >= 0)
1618 break;
1619 }
1620 }
1621
Ziqi Chenc35ae882017-09-26 18:48:28 +08001622#ifdef CONFIG_USB_F_NCM
1623 if (value < 0)
1624 value = ncm_ctrlrequest(cdev, c);
1625
1626 /*
1627 * for mirror link command case, if it already been handled,
1628 * do not pass to composite_setup
1629 */
1630 if (value == 0)
1631 return value;
1632#endif
1633
Badhri Jagan Sridharan1c3865d2014-12-15 10:44:47 -08001634#ifdef CONFIG_USB_CONFIGFS_F_ACC
1635 if (value < 0)
1636 value = acc_ctrlrequest(cdev, c);
1637#endif
1638
1639 if (value < 0)
1640 value = composite_setup(gadget, c);
1641
1642 spin_lock_irqsave(&cdev->lock, flags);
1643 if (c->bRequest == USB_REQ_SET_CONFIGURATION &&
1644 cdev->config) {
1645 schedule_work(&gi->work);
1646 }
1647 spin_unlock_irqrestore(&cdev->lock, flags);
1648
1649 return value;
1650}
1651
1652static void android_disconnect(struct usb_gadget *gadget)
1653{
1654 struct usb_composite_dev *cdev = get_gadget_data(gadget);
Hemant Kumarcb0304a2016-11-01 13:00:57 -07001655 struct gadget_info *gi;
1656
1657 if (!cdev) {
1658 pr_err("%s: gadget is not connected\n", __func__);
1659 return;
1660 }
1661
1662 gi = container_of(cdev, struct gadget_info, cdev);
Badhri Jagan Sridharan1c3865d2014-12-15 10:44:47 -08001663
Danilo Krummrich6e055352017-08-14 12:45:38 +02001664 /* FIXME: There's a race between usb_gadget_udc_stop() which is likely
1665 * to set the gadget driver to NULL in the udc driver and this drivers
1666 * gadget disconnect fn which likely checks for the gadget driver to
1667 * be a null ptr. It happens that unbind (doing set_gadget_data(NULL))
1668 * is called before the gadget driver is set to NULL and the udc driver
1669 * calls disconnect fn which results in cdev being a null ptr.
1670 */
1671 if (cdev == NULL) {
1672 WARN(1, "%s: gadget driver already disconnected\n", __func__);
1673 return;
1674 }
1675
Badhri Jagan Sridharan1c3865d2014-12-15 10:44:47 -08001676 /* accessory HID support can be active while the
1677 accessory function is not actually enabled,
1678 so we need to inform it when we are disconnected.
1679 */
1680
1681#ifdef CONFIG_USB_CONFIGFS_F_ACC
1682 acc_disconnect();
1683#endif
1684 gi->connected = 0;
Vijayavardhan Vennapusa4ca835b2017-10-30 14:33:51 +05301685 if (!gi->unbinding)
1686 schedule_work(&gi->work);
Badhri Jagan Sridharan1c3865d2014-12-15 10:44:47 -08001687 composite_disconnect(gadget);
1688}
1689#endif
1690
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001691static const struct usb_gadget_driver configfs_driver_template = {
1692 .bind = configfs_composite_bind,
1693 .unbind = configfs_composite_unbind,
Badhri Jagan Sridharan1c3865d2014-12-15 10:44:47 -08001694#ifdef CONFIG_USB_CONFIGFS_UEVENT
1695 .setup = android_setup,
Amit Pundirc316caf2015-10-06 20:53:27 +05301696 .reset = android_disconnect,
Badhri Jagan Sridharan1c3865d2014-12-15 10:44:47 -08001697 .disconnect = android_disconnect,
1698#else
Peter Chenaa919ef2019-08-26 15:10:55 -04001699 .setup = configfs_composite_setup,
1700 .reset = configfs_composite_disconnect,
1701 .disconnect = configfs_composite_disconnect,
Badhri Jagan Sridharan1c3865d2014-12-15 10:44:47 -08001702#endif
Peter Chenaa919ef2019-08-26 15:10:55 -04001703 .suspend = configfs_composite_suspend,
1704 .resume = configfs_composite_resume,
Andrzej Pietrasiewicz3a571872014-10-08 12:03:36 +02001705
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001706 .max_speed = USB_SPEED_SUPER,
1707 .driver = {
1708 .owner = THIS_MODULE,
1709 .name = "configfs-gadget",
1710 },
Krzysztof Opasiakf1bddbb2016-05-05 10:46:05 +02001711 .match_existing_only = 1,
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001712};
1713
Badhri Jagan Sridharan51af1202015-07-14 15:46:11 -07001714#ifdef CONFIG_USB_CONFIGFS_UEVENT
1715static ssize_t state_show(struct device *pdev, struct device_attribute *attr,
1716 char *buf)
1717{
1718 struct gadget_info *dev = dev_get_drvdata(pdev);
1719 struct usb_composite_dev *cdev;
1720 char *state = "DISCONNECTED";
1721 unsigned long flags;
1722
1723 if (!dev)
1724 goto out;
1725
1726 cdev = &dev->cdev;
1727
1728 if (!cdev)
1729 goto out;
1730
1731 spin_lock_irqsave(&cdev->lock, flags);
1732 if (cdev->config)
1733 state = "CONFIGURED";
1734 else if (dev->connected)
1735 state = "CONNECTED";
1736 spin_unlock_irqrestore(&cdev->lock, flags);
1737out:
1738 return sprintf(buf, "%s\n", state);
1739}
1740
1741static DEVICE_ATTR(state, S_IRUGO, state_show, NULL);
1742
1743static struct device_attribute *android_usb_attributes[] = {
1744 &dev_attr_state,
1745 NULL
1746};
Badhri Jagan Sridharan4b2c8512015-08-09 15:12:50 -07001747
1748static int android_device_create(struct gadget_info *gi)
1749{
1750 struct device_attribute **attrs;
1751 struct device_attribute *attr;
Ajay Agarwalfea56da2017-05-30 10:27:23 +05301752 char str[10];
Badhri Jagan Sridharan4b2c8512015-08-09 15:12:50 -07001753
1754 INIT_WORK(&gi->work, android_work);
Ajay Agarwalfea56da2017-05-30 10:27:23 +05301755 snprintf(str, sizeof(str), "android%d", gadget_index - 1);
1756 pr_debug("Creating android device %s\n", str);
1757 gi->dev = device_create(android_class, NULL,
1758 MKDEV(0, 0), NULL, str);
1759 if (IS_ERR(gi->dev))
1760 return PTR_ERR(gi->dev);
Badhri Jagan Sridharan4b2c8512015-08-09 15:12:50 -07001761
Ajay Agarwalfea56da2017-05-30 10:27:23 +05301762 dev_set_drvdata(gi->dev, gi);
1763 if (gadget_index == 1)
1764 android_device = gi->dev;
Badhri Jagan Sridharan4b2c8512015-08-09 15:12:50 -07001765
1766 attrs = android_usb_attributes;
1767 while ((attr = *attrs++)) {
1768 int err;
1769
Ajay Agarwalfea56da2017-05-30 10:27:23 +05301770 err = device_create_file(gi->dev, attr);
Badhri Jagan Sridharan4b2c8512015-08-09 15:12:50 -07001771 if (err) {
Ajay Agarwalfea56da2017-05-30 10:27:23 +05301772 device_destroy(gi->dev->class,
1773 gi->dev->devt);
Badhri Jagan Sridharan4b2c8512015-08-09 15:12:50 -07001774 return err;
1775 }
1776 }
1777
1778 return 0;
1779}
1780
Ajay Agarwalfea56da2017-05-30 10:27:23 +05301781static void android_device_destroy(struct device *dev)
Badhri Jagan Sridharan4b2c8512015-08-09 15:12:50 -07001782{
1783 struct device_attribute **attrs;
1784 struct device_attribute *attr;
1785
1786 attrs = android_usb_attributes;
1787 while ((attr = *attrs++))
Ajay Agarwalfea56da2017-05-30 10:27:23 +05301788 device_remove_file(dev, attr);
1789 device_destroy(dev->class, dev->devt);
Badhri Jagan Sridharan4b2c8512015-08-09 15:12:50 -07001790}
1791#else
1792static inline int android_device_create(struct gadget_info *gi)
1793{
1794 return 0;
1795}
1796
Ajay Agarwalfea56da2017-05-30 10:27:23 +05301797static inline void android_device_destroy(struct device *dev)
Badhri Jagan Sridharan4b2c8512015-08-09 15:12:50 -07001798{
1799}
Badhri Jagan Sridharan51af1202015-07-14 15:46:11 -07001800#endif
1801
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001802static struct config_group *gadgets_make(
1803 struct config_group *group,
1804 const char *name)
1805{
1806 struct gadget_info *gi;
1807
1808 gi = kzalloc(sizeof(*gi), GFP_KERNEL);
1809 if (!gi)
1810 return ERR_PTR(-ENOMEM);
1811
Christoph Hellwig1ae16022016-02-26 11:02:14 +01001812 config_group_init_type_name(&gi->group, name, &gadget_root_type);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001813
1814 config_group_init_type_name(&gi->functions_group, "functions",
1815 &functions_type);
Christoph Hellwig1ae16022016-02-26 11:02:14 +01001816 configfs_add_default_group(&gi->functions_group, &gi->group);
1817
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001818 config_group_init_type_name(&gi->configs_group, "configs",
1819 &config_desc_type);
Christoph Hellwig1ae16022016-02-26 11:02:14 +01001820 configfs_add_default_group(&gi->configs_group, &gi->group);
1821
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001822 config_group_init_type_name(&gi->strings_group, "strings",
1823 &gadget_strings_strings_type);
Christoph Hellwig1ae16022016-02-26 11:02:14 +01001824 configfs_add_default_group(&gi->strings_group, &gi->group);
1825
Andrzej Pietrasiewicz87213d32014-05-08 14:06:25 +02001826 config_group_init_type_name(&gi->os_desc_group, "os_desc",
1827 &os_desc_type);
Christoph Hellwig1ae16022016-02-26 11:02:14 +01001828 configfs_add_default_group(&gi->os_desc_group, &gi->group);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001829
1830 gi->composite.bind = configfs_do_nothing;
1831 gi->composite.unbind = configfs_do_nothing;
1832 gi->composite.suspend = NULL;
1833 gi->composite.resume = NULL;
1834 gi->composite.max_speed = USB_SPEED_SUPER;
1835
jianzhou2de43592019-12-09 10:19:45 +08001836 spin_lock_init(&gi->spinlock);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001837 mutex_init(&gi->lock);
1838 INIT_LIST_HEAD(&gi->string_list);
1839 INIT_LIST_HEAD(&gi->available_func);
1840
1841 composite_init_dev(&gi->cdev);
1842 gi->cdev.desc.bLength = USB_DT_DEVICE_SIZE;
1843 gi->cdev.desc.bDescriptorType = USB_DT_DEVICE;
1844 gi->cdev.desc.bcdDevice = cpu_to_le16(get_default_bcdDevice());
1845
1846 gi->composite.gadget_driver = configfs_driver_template;
1847
1848 gi->composite.gadget_driver.function = kstrdup(name, GFP_KERNEL);
1849 gi->composite.name = gi->composite.gadget_driver.function;
1850
Badhri Jagan Sridharan4b2c8512015-08-09 15:12:50 -07001851 if (!gi->composite.gadget_driver.function)
Badhri Jagan Sridharan2a387e52015-03-27 14:15:19 -07001852 goto err;
Badhri Jagan Sridharan51af1202015-07-14 15:46:11 -07001853
Ajay Agarwalfea56da2017-05-30 10:27:23 +05301854 gadget_index++;
1855 pr_debug("Creating gadget index %d\n", gadget_index);
Badhri Jagan Sridharan4b2c8512015-08-09 15:12:50 -07001856 if (android_device_create(gi) < 0)
1857 goto err;
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001858
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001859 return &gi->group;
Badhri Jagan Sridharan51af1202015-07-14 15:46:11 -07001860
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001861err:
1862 kfree(gi);
1863 return ERR_PTR(-ENOMEM);
1864}
1865
1866static void gadgets_drop(struct config_group *group, struct config_item *item)
1867{
Ajay Agarwalfea56da2017-05-30 10:27:23 +05301868 struct gadget_info *gi;
1869
1870 gi = container_of(to_config_group(item), struct gadget_info, group);
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001871 config_item_put(item);
Ajay Agarwalfea56da2017-05-30 10:27:23 +05301872 if (gi->dev) {
1873 android_device_destroy(gi->dev);
1874 gi->dev = NULL;
1875 }
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001876}
1877
1878static struct configfs_group_operations gadgets_ops = {
1879 .make_group = &gadgets_make,
1880 .drop_item = &gadgets_drop,
1881};
1882
1883static struct config_item_type gadgets_type = {
1884 .ct_group_ops = &gadgets_ops,
1885 .ct_owner = THIS_MODULE,
1886};
1887
1888static struct configfs_subsystem gadget_subsys = {
1889 .su_group = {
1890 .cg_item = {
1891 .ci_namebuf = "usb_gadget",
1892 .ci_type = &gadgets_type,
1893 },
1894 },
1895 .su_mutex = __MUTEX_INITIALIZER(gadget_subsys.su_mutex),
1896};
1897
Andrzej Pietrasiewicz092a4bd2013-09-26 14:38:15 +02001898void unregister_gadget_item(struct config_item *item)
1899{
1900 struct gadget_info *gi = to_gadget_info(item);
1901
Winter Wangcee51c32016-07-27 10:03:19 +08001902 mutex_lock(&gi->lock);
Andrzej Pietrasiewicz092a4bd2013-09-26 14:38:15 +02001903 unregister_gadget(gi);
Winter Wangcee51c32016-07-27 10:03:19 +08001904 mutex_unlock(&gi->lock);
Andrzej Pietrasiewicz092a4bd2013-09-26 14:38:15 +02001905}
Felipe Balbi0700faa2014-04-01 13:19:32 -05001906EXPORT_SYMBOL_GPL(unregister_gadget_item);
Andrzej Pietrasiewicz092a4bd2013-09-26 14:38:15 +02001907
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001908static int __init gadget_cfs_init(void)
1909{
1910 int ret;
1911
1912 config_group_init(&gadget_subsys.su_group);
1913
1914 ret = configfs_register_subsystem(&gadget_subsys);
Badhri Jagan Sridharan1c3865d2014-12-15 10:44:47 -08001915
1916#ifdef CONFIG_USB_CONFIGFS_UEVENT
1917 android_class = class_create(THIS_MODULE, "android_usb");
1918 if (IS_ERR(android_class))
1919 return PTR_ERR(android_class);
1920#endif
1921
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001922 return ret;
1923}
1924module_init(gadget_cfs_init);
1925
1926static void __exit gadget_cfs_exit(void)
1927{
1928 configfs_unregister_subsystem(&gadget_subsys);
Badhri Jagan Sridharan2a387e52015-03-27 14:15:19 -07001929#ifdef CONFIG_USB_CONFIGFS_UEVENT
1930 if (!IS_ERR(android_class))
1931 class_destroy(android_class);
1932#endif
1933
Sebastian Andrzej Siewior88af8bb2012-12-23 21:10:24 +01001934}
1935module_exit(gadget_cfs_exit);