2017-11-03 18:28:30 +08:00
|
|
|
// SPDX-License-Identifier: GPL-2.0
|
2012-12-24 04:10:24 +08:00
|
|
|
#include <linux/configfs.h>
|
|
|
|
#include <linux/module.h>
|
|
|
|
#include <linux/slab.h>
|
|
|
|
#include <linux/device.h>
|
2014-05-08 20:06:25 +08:00
|
|
|
#include <linux/nls.h>
|
2012-12-24 04:10:24 +08:00
|
|
|
#include <linux/usb/composite.h>
|
|
|
|
#include <linux/usb/gadget_configfs.h>
|
2013-12-19 18:07:37 +08:00
|
|
|
#include "configfs.h"
|
2014-05-08 20:06:26 +08:00
|
|
|
#include "u_f.h"
|
2014-05-08 20:06:28 +08:00
|
|
|
#include "u_os_desc.h"
|
2012-12-24 04:10:24 +08:00
|
|
|
|
|
|
|
int check_user_usb_string(const char *name,
|
|
|
|
struct usb_gadget_strings *stringtab_dev)
|
|
|
|
{
|
|
|
|
unsigned primary_lang;
|
|
|
|
unsigned sub_lang;
|
|
|
|
u16 num;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = kstrtou16(name, 0, &num);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
primary_lang = num & 0x3ff;
|
|
|
|
sub_lang = num >> 10;
|
|
|
|
|
|
|
|
/* simple sanity check for valid langid */
|
|
|
|
switch (primary_lang) {
|
|
|
|
case 0:
|
|
|
|
case 0x62 ... 0xfe:
|
|
|
|
case 0x100 ... 0x3ff:
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
if (!sub_lang)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
stringtab_dev->language = num;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define MAX_NAME_LEN 40
|
|
|
|
#define MAX_USB_STRING_LANGS 2
|
|
|
|
|
2015-07-09 15:18:48 +08:00
|
|
|
static const struct usb_descriptor_header *otg_desc[2];
|
|
|
|
|
2012-12-24 04:10:24 +08:00
|
|
|
struct gadget_info {
|
|
|
|
struct config_group group;
|
|
|
|
struct config_group functions_group;
|
|
|
|
struct config_group configs_group;
|
|
|
|
struct config_group strings_group;
|
2014-05-08 20:06:25 +08:00
|
|
|
struct config_group os_desc_group;
|
2012-12-24 04:10:24 +08:00
|
|
|
|
|
|
|
struct mutex lock;
|
|
|
|
struct usb_gadget_strings *gstrings[MAX_USB_STRING_LANGS + 1];
|
|
|
|
struct list_head string_list;
|
|
|
|
struct list_head available_func;
|
|
|
|
|
|
|
|
struct usb_composite_driver composite;
|
|
|
|
struct usb_composite_dev cdev;
|
2014-05-08 20:06:25 +08:00
|
|
|
bool use_os_desc;
|
|
|
|
char b_vendor_code;
|
|
|
|
char qw_sign[OS_STRING_QW_SIGN_LEN];
|
usb: gadget: configfs: fix concurrent issue between composite APIs
We meet several NULL pointer issues if configfs_composite_unbind
and composite_setup (or composite_disconnect) are running together.
These issues occur when do the function switch stress test, the
configfs_compsoite_unbind is called from user mode by
echo "" to /sys/../UDC entry, and meanwhile, the setup interrupt
or disconnect interrupt occurs by hardware. The composite_setup
will get the cdev from get_gadget_data, but configfs_composite_unbind
will set gadget data as NULL, so the NULL pointer issue occurs.
This concurrent is hard to reproduce by native kernel, but can be
reproduced by android kernel.
In this commit, we introduce one spinlock belongs to structure
gadget_info since we can't use the same spinlock in usb_composite_dev
due to exclusive running together between composite_setup and
configfs_composite_unbind. And one bit flag 'unbind' to indicate the
code is at unbind routine, this bit is needed due to we release the
lock at during configfs_composite_unbind sometimes, and composite_setup
may be run at that time.
Several oops:
oops 1:
android_work: sent uevent USB_STATE=CONNECTED
configfs-gadget gadget: super-speed config #1: b
android_work: sent uevent USB_STATE=CONFIGURED
init: Received control message 'start' for 'adbd' from pid: 3515 (system_server)
Unable to handle kernel NULL pointer dereference at virtual address 0000002a
init: Received control message 'stop' for 'adbd' from pid: 3375 (/vendor/bin/hw/android.hardware.usb@1.1-servic)
Mem abort info:
Exception class = DABT (current EL), IL = 32 bits
SET = 0, FnV = 0
EA = 0, S1PTW = 0
Data abort info:
ISV = 0, ISS = 0x00000004
CM = 0, WnR = 0
user pgtable: 4k pages, 48-bit VAs, pgd = ffff8008f1b7f000
[000000000000002a] *pgd=0000000000000000
Internal error: Oops: 96000004 [#1] PREEMPT SMP
Modules linked in:
CPU: 4 PID: 2457 Comm: irq/125-5b11000 Not tainted 4.14.98-07846-g0b40a9b-dirty #16
Hardware name: Freescale i.MX8QM MEK (DT)
task: ffff8008f2a98000 task.stack: ffff00000b7b8000
PC is at composite_setup+0x44/0x1508
LR is at android_setup+0xb8/0x13c
pc : [<ffff0000089ffb3c>] lr : [<ffff000008a032fc>] pstate: 800001c5
sp : ffff00000b7bbb80
x29: ffff00000b7bbb80 x28: ffff8008f2a3c010
x27: 0000000000000001 x26: 0000000000000000 [1232/1897]
audit: audit_lost=25791 audit_rate_limit=5 audit_backlog_limit=64
x25: 00000000ffffffa1 x24: ffff8008f2a3c010
audit: rate limit exceeded
x23: 0000000000000409 x22: ffff000009c8e000
x21: ffff8008f7a8b428 x20: ffff00000afae000
x19: ffff0000089ff000 x18: 0000000000000000
x17: 0000000000000000 x16: ffff0000082b7c9c
x15: 0000000000000000 x14: f1866f5b952aca46
x13: e35502e30d44349c x12: 0000000000000008
x11: 0000000000000008 x10: 0000000000000a30
x9 : ffff00000b7bbd00 x8 : ffff8008f2a98a90
x7 : ffff8008f27a9c90 x6 : 0000000000000001
x5 : 0000000000000000 x4 : 0000000000000001
x3 : 0000000000000000 x2 : 0000000000000006
x1 : ffff0000089ff8d0 x0 : 732a010310b9ed00
X7: 0xffff8008f27a9c10:
9c10 00000002 00000000 00000001 00000000 13110000 ffff0000 00000002 00208040
9c30 00000000 00000000 00000000 00000000 00000000 00000005 00000029 00000000
9c50 00051778 00000001 f27a8e00 ffff8008 00000005 00000000 00000078 00000078
9c70 00000078 00000000 09031d48 ffff0000 00100000 00000000 00400000 00000000
9c90 00000001 00000000 00000000 00000000 00000000 00000000 ffefb1a0 ffff8008
9cb0 f27a9ca8 ffff8008 00000000 00000000 b9d88037 00000173 1618a3eb 00000001
9cd0 870a792a 0000002e 16188fe6 00000001 0000242b 00000000 00000000 00000000
using random self ethernet address
9cf0 019a4646 00000000 000547f3 00000000 ecfd6c33 00000002 00000000
using random host ethernet address
00000000
X8: 0xffff8008f2a98a10:
8a10 00000000 00000000 f7788d00 ffff8008 00000001 00000000 00000000 00000000
8a30 eb218000 ffff8008 f2a98000 ffff8008 f2a98000 ffff8008 09885000 ffff0000
8a50 f34df480 ffff8008 00000000 00000000 f2a98648 ffff8008 09c8e000 ffff0000
8a70 fff2c800 ffff8008 09031d48 ffff0000 0b7bbd00 ffff0000 0b7bbd00 ffff0000
8a90 080861bc ffff0000 00000000 00000000 00000000 00000000 00000000 00000000
8ab0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
8ad0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
8af0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
X21: 0xffff8008f7a8b3a8:
b3a8 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
b3c8 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
b3e8 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
b408 00000000 00000000 00000000 00000000 00000000 00000000 00000001 00000000
b428 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
b448 0053004d 00540046 00300031 00010030 eb07b520 ffff8008 20011201 00000003
b468 e418d109 0104404e 00010302 00000000 eb07b558 ffff8008 eb07b558 ffff8008
b488 f7a8b488 ffff8008 f7a8b488 ffff8008 f7a8b300 ffff8008 00000000 00000000
X24: 0xffff8008f2a3bf90:
bf90 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bfb0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bfd0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bff0 00000000 00000000 00000000 00000000 f76c8010 ffff8008 f76c8010 ffff8008
c010 00000000 00000000 f2a3c018 ffff8008 f2a3c018 ffff8008 08a067dc ffff0000
c030 f2a5a000 ffff8008 091c3650 ffff0000 f716fd18 ffff8008 f716fe30 ffff8008
c050 f2ce4a30 ffff8008 00000000 00000005 00000000 00000000 095d1568 ffff0000
c070 f76c8010 ffff8008 f2ce4b00 ffff8008 095cac68 ffff0000 f2a5a028 ffff8008
X28: 0xffff8008f2a3bf90:
bf90 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bfb0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bfd0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bff0 00000000 00000000 00000000 00000000 f76c8010 ffff8008 f76c8010 ffff8008
c010 00000000 00000000 f2a3c018 ffff8008 f2a3c018 ffff8008 08a067dc ffff0000
c030 f2a5a000 ffff8008 091c3650 ffff0000 f716fd18 ffff8008 f716fe30 ffff8008
c050 f2ce4a30 ffff8008 00000000 00000005 00000000 00000000 095d1568 ffff0000
c070 f76c8010 ffff8008 f2ce4b00 ffff8008 095cac68 ffff0000 f2a5a028 ffff8008
Process irq/125-5b11000 (pid: 2457, stack limit = 0xffff00000b7b8000)
Call trace:
Exception stack(0xffff00000b7bba40 to 0xffff00000b7bbb80)
ba40: 732a010310b9ed00 ffff0000089ff8d0 0000000000000006 0000000000000000
ba60: 0000000000000001 0000000000000000 0000000000000001 ffff8008f27a9c90
ba80: ffff8008f2a98a90 ffff00000b7bbd00 0000000000000a30 0000000000000008
baa0: 0000000000000008 e35502e30d44349c f1866f5b952aca46 0000000000000000
bac0: ffff0000082b7c9c 0000000000000000 0000000000000000 ffff0000089ff000
bae0: ffff00000afae000 ffff8008f7a8b428 ffff000009c8e000 0000000000000409
bb00: ffff8008f2a3c010 00000000ffffffa1 0000000000000000 0000000000000001
bb20: ffff8008f2a3c010 ffff00000b7bbb80 ffff000008a032fc ffff00000b7bbb80
bb40: ffff0000089ffb3c 00000000800001c5 ffff00000b7bbb80 732a010310b9ed00
bb60: ffffffffffffffff ffff0000080f777c ffff00000b7bbb80 ffff0000089ffb3c
[<ffff0000089ffb3c>] composite_setup+0x44/0x1508
[<ffff000008a032fc>] android_setup+0xb8/0x13c
[<ffff0000089bd9a8>] cdns3_ep0_delegate_req+0x44/0x70
[<ffff0000089bdff4>] cdns3_check_ep0_interrupt_proceed+0x33c/0x654
[<ffff0000089bca44>] cdns3_device_thread_irq_handler+0x4b0/0x4bc
[<ffff0000089b77b4>] cdns3_thread_irq+0x48/0x68
[<ffff000008145bf0>] irq_thread_fn+0x28/0x88
[<ffff000008145e38>] irq_thread+0x13c/0x228
[<ffff0000080fed70>] kthread+0x104/0x130
[<ffff000008085064>] ret_from_fork+0x10/0x18
oops2:
composite_disconnect: Calling disconnect on a Gadget that is not connected
android_work: did not send uevent (0 0 (null))
init: Received control message 'stop' for 'adbd' from pid: 3359 (/vendor/bin/hw/android.hardware.usb@1.1-service.imx)
init: Sending signal 9 to service 'adbd' (pid 22343) process group...
------------[ cut here ]------------
audit: audit_lost=180038 audit_rate_limit=5 audit_backlog_limit=64
audit: rate limit exceeded
WARNING: CPU: 0 PID: 3468 at kernel_imx/drivers/usb/gadget/composite.c:2009 composite_disconnect+0x80/0x88
Modules linked in:
CPU: 0 PID: 3468 Comm: HWC-UEvent-Thre Not tainted 4.14.98-07846-g0b40a9b-dirty #16
Hardware name: Freescale i.MX8QM MEK (DT)
task: ffff8008f2349c00 task.stack: ffff00000b0a8000
PC is at composite_disconnect+0x80/0x88
LR is at composite_disconnect+0x80/0x88
pc : [<ffff0000089ff9b0>] lr : [<ffff0000089ff9b0>] pstate: 600001c5
sp : ffff000008003dd0
x29: ffff000008003dd0 x28: ffff8008f2349c00
x27: ffff000009885018 x26: ffff000008004000
Timeout for IPC response!
x25: ffff000009885018 x24: ffff000009c8e280
x23: ffff8008f2d98010 x22: 00000000000001c0
x21: ffff8008f2d98394 x20: ffff8008f2d98010
x19: 0000000000000000 x18: 0000e3956f4f075a
fxos8700 4-001e: i2c block read acc failed
x17: 0000e395735727e8 x16: ffff00000829f4d4
x15: ffffffffffffffff x14: 7463656e6e6f6320
x13: 746f6e2009090920 x12: 7369207461687420
x11: 7465676461472061 x10: 206e6f207463656e
x9 : 6e6f637369642067 x8 : ffff000009c8e280
x7 : ffff0000086ca6cc x6 : ffff000009f15e78
x5 : 0000000000000000 x4 : 0000000000000000
x3 : ffffffffffffffff x2 : c3f28b86000c3900
x1 : c3f28b86000c3900 x0 : 000000000000004e
X20: 0xffff8008f2d97f90:
7f90 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
7fb0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
libprocessgroup: Failed to kill process cgroup uid 0 pid 22343 in 215ms, 1 processes remain
7fd0
Timeout for IPC response!
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
using random self ethernet address
7ff0 00000000 00000000 00000000 00000000 f76c8010 ffff8008 f76c8010 ffff8008
8010 00000100 00000000 f2d98018 ffff8008 f2d98018 ffff8008 08a067dc
using random host ethernet address
ffff0000
8030 f206d800 ffff8008 091c3650 ffff0000 f7957b18 ffff8008 f7957730 ffff8008
8050 f716a630 ffff8008 00000000 00000005 00000000 00000000 095d1568 ffff0000
8070 f76c8010 ffff8008 f716a800 ffff8008 095cac68 ffff0000 f206d828 ffff8008
X21: 0xffff8008f2d98314:
8314 ffff8008 00000000 00000000 00000000 00000000 00000000 00000000 00000000
8334 00000000 00000000 00000000 00000000 00000000 08a04cf4 ffff0000 00000000
8354 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
8374 00000000 00000000 00000000 00001001 00000000 00000000 00000000 00000000
8394 e4bbe4bb 0f230000 ffff0000 0afae000 ffff0000 ae001000 00000000 f206d400
Timeout for IPC response!
83b4 ffff8008 00000000 00000000 f7957b18 ffff8008 f7957718 ffff8008 f7957018
83d4 ffff8008 f7957118 ffff8008 f7957618 ffff8008 f7957818 ffff8008 f7957918
83f4 ffff8008 f7957d18 ffff8008 00000000 00000000 00000000 00000000 00000000
X23: 0xffff8008f2d97f90:
7f90 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
7fb0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
7fd0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
7ff0 00000000 00000000 00000000 00000000 f76c8010 ffff8008 f76c8010 ffff8008
8010 00000100 00000000 f2d98018 ffff8008 f2d98018 ffff8008 08a067dc ffff0000
8030 f206d800 ffff8008 091c3650 ffff0000 f7957b18 ffff8008 f7957730 ffff8008
8050 f716a630 ffff8008 00000000 00000005 00000000 00000000 095d1568 ffff0000
8070 f76c8010 ffff8008 f716a800 ffff8008 095cac68 ffff0000 f206d828 ffff8008
X28: 0xffff8008f2349b80:
9b80 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
9ba0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
9bc0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
9be0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
9c00 00000022 00000000 ffffffff ffffffff 00010001 00000000 00000000 00000000
9c20 0b0a8000 ffff0000 00000002 00404040 00000000 00000000 00000000 00000000
9c40 00000001 00000000 00000001 00000000 001ebd44 00000001 f390b800 ffff8008
9c60 00000000 00000001 00000070 00000070 00000070 00000000 09031d48 ffff0000
Call trace:
Exception stack(0xffff000008003c90 to 0xffff000008003dd0)
3c80: 000000000000004e c3f28b86000c3900
3ca0: c3f28b86000c3900 ffffffffffffffff 0000000000000000 0000000000000000
3cc0: ffff000009f15e78 ffff0000086ca6cc ffff000009c8e280 6e6f637369642067
3ce0: 206e6f207463656e 7465676461472061 7369207461687420 746f6e2009090920
3d00: 7463656e6e6f6320 ffffffffffffffff ffff00000829f4d4 0000e395735727e8
3d20: 0000e3956f4f075a 0000000000000000 ffff8008f2d98010 ffff8008f2d98394
3d40: 00000000000001c0 ffff8008f2d98010 ffff000009c8e280 ffff000009885018
3d60: ffff000008004000 ffff000009885018 ffff8008f2349c00 ffff000008003dd0
3d80: ffff0000089ff9b0 ffff000008003dd0 ffff0000089ff9b0 00000000600001c5
3da0: ffff8008f33f2cd8 0000000000000000 0000ffffffffffff 0000000000000000
init: Received control message 'start' for 'adbd' from pid: 3359 (/vendor/bin/hw/android.hardware.usb@1.1-service.imx)
3dc0: ffff000008003dd0 ffff0000089ff9b0
[<ffff0000089ff9b0>] composite_disconnect+0x80/0x88
[<ffff000008a044d4>] android_disconnect+0x3c/0x68
[<ffff0000089ba9f8>] cdns3_device_irq_handler+0xfc/0x2c8
[<ffff0000089b84c0>] cdns3_irq+0x44/0x94
[<ffff00000814494c>] __handle_irq_event_percpu+0x60/0x24c
[<ffff000008144c0c>] handle_irq_event+0x58/0xc0
[<ffff00000814873c>] handle_fasteoi_irq+0x98/0x180
[<ffff000008143a10>] generic_handle_irq+0x24/0x38
[<ffff000008144170>] __handle_domain_irq+0x60/0xac
[<ffff0000080819c4>] gic_handle_irq+0xd4/0x17c
Signed-off-by: Peter Chen <peter.chen@nxp.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
2019-08-27 03:10:55 +08:00
|
|
|
spinlock_t spinlock;
|
|
|
|
bool unbind;
|
2012-12-24 04:10:24 +08:00
|
|
|
};
|
|
|
|
|
2015-10-03 21:32:38 +08:00
|
|
|
static inline struct gadget_info *to_gadget_info(struct config_item *item)
|
|
|
|
{
|
|
|
|
return container_of(to_config_group(item), struct gadget_info, group);
|
|
|
|
}
|
|
|
|
|
2012-12-24 04:10:24 +08:00
|
|
|
struct config_usb_cfg {
|
|
|
|
struct config_group group;
|
|
|
|
struct config_group strings_group;
|
|
|
|
struct list_head string_list;
|
|
|
|
struct usb_configuration c;
|
|
|
|
struct list_head func_list;
|
|
|
|
struct usb_gadget_strings *gstrings[MAX_USB_STRING_LANGS + 1];
|
|
|
|
};
|
|
|
|
|
2015-10-03 21:32:38 +08:00
|
|
|
static inline struct config_usb_cfg *to_config_usb_cfg(struct config_item *item)
|
|
|
|
{
|
|
|
|
return container_of(to_config_group(item), struct config_usb_cfg,
|
|
|
|
group);
|
|
|
|
}
|
|
|
|
|
2012-12-24 04:10:24 +08:00
|
|
|
struct gadget_strings {
|
|
|
|
struct usb_gadget_strings stringtab_dev;
|
|
|
|
struct usb_string strings[USB_GADGET_FIRST_AVAIL_IDX];
|
|
|
|
char *manufacturer;
|
|
|
|
char *product;
|
|
|
|
char *serialnumber;
|
|
|
|
|
|
|
|
struct config_group group;
|
|
|
|
struct list_head list;
|
|
|
|
};
|
|
|
|
|
2014-05-08 20:06:25 +08:00
|
|
|
struct os_desc {
|
|
|
|
struct config_group group;
|
|
|
|
};
|
|
|
|
|
2012-12-24 04:10:24 +08:00
|
|
|
struct gadget_config_name {
|
|
|
|
struct usb_gadget_strings stringtab_dev;
|
|
|
|
struct usb_string strings;
|
|
|
|
char *configuration;
|
|
|
|
|
|
|
|
struct config_group group;
|
|
|
|
struct list_head list;
|
|
|
|
};
|
|
|
|
|
|
|
|
static int usb_string_copy(const char *s, char **s_copy)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
char *str;
|
|
|
|
char *copy = *s_copy;
|
|
|
|
ret = strlen(s);
|
|
|
|
if (ret > 126)
|
|
|
|
return -EOVERFLOW;
|
|
|
|
|
|
|
|
str = kstrdup(s, GFP_KERNEL);
|
|
|
|
if (!str)
|
|
|
|
return -ENOMEM;
|
|
|
|
if (str[ret - 1] == '\n')
|
|
|
|
str[ret - 1] = '\0';
|
|
|
|
kfree(copy);
|
|
|
|
*s_copy = str;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define GI_DEVICE_DESC_SIMPLE_R_u8(__name) \
|
2015-10-03 21:32:38 +08:00
|
|
|
static ssize_t gadget_dev_desc_##__name##_show(struct config_item *item, \
|
2012-12-24 04:10:24 +08:00
|
|
|
char *page) \
|
|
|
|
{ \
|
2015-10-03 21:32:38 +08:00
|
|
|
return sprintf(page, "0x%02x\n", \
|
|
|
|
to_gadget_info(item)->cdev.desc.__name); \
|
2012-12-24 04:10:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#define GI_DEVICE_DESC_SIMPLE_R_u16(__name) \
|
2015-10-03 21:32:38 +08:00
|
|
|
static ssize_t gadget_dev_desc_##__name##_show(struct config_item *item, \
|
2012-12-24 04:10:24 +08:00
|
|
|
char *page) \
|
|
|
|
{ \
|
2015-10-03 21:32:38 +08:00
|
|
|
return sprintf(page, "0x%04x\n", \
|
|
|
|
le16_to_cpup(&to_gadget_info(item)->cdev.desc.__name)); \
|
2012-12-24 04:10:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#define GI_DEVICE_DESC_SIMPLE_W_u8(_name) \
|
2015-10-03 21:32:38 +08:00
|
|
|
static ssize_t gadget_dev_desc_##_name##_store(struct config_item *item, \
|
2012-12-24 04:10:24 +08:00
|
|
|
const char *page, size_t len) \
|
|
|
|
{ \
|
|
|
|
u8 val; \
|
|
|
|
int ret; \
|
|
|
|
ret = kstrtou8(page, 0, &val); \
|
|
|
|
if (ret) \
|
|
|
|
return ret; \
|
2015-10-03 21:32:38 +08:00
|
|
|
to_gadget_info(item)->cdev.desc._name = val; \
|
2012-12-24 04:10:24 +08:00
|
|
|
return len; \
|
|
|
|
}
|
|
|
|
|
|
|
|
#define GI_DEVICE_DESC_SIMPLE_W_u16(_name) \
|
2015-10-03 21:32:38 +08:00
|
|
|
static ssize_t gadget_dev_desc_##_name##_store(struct config_item *item, \
|
2012-12-24 04:10:24 +08:00
|
|
|
const char *page, size_t len) \
|
|
|
|
{ \
|
|
|
|
u16 val; \
|
|
|
|
int ret; \
|
|
|
|
ret = kstrtou16(page, 0, &val); \
|
|
|
|
if (ret) \
|
|
|
|
return ret; \
|
2015-10-03 21:32:38 +08:00
|
|
|
to_gadget_info(item)->cdev.desc._name = cpu_to_le16p(&val); \
|
2012-12-24 04:10:24 +08:00
|
|
|
return len; \
|
|
|
|
}
|
|
|
|
|
|
|
|
#define GI_DEVICE_DESC_SIMPLE_RW(_name, _type) \
|
|
|
|
GI_DEVICE_DESC_SIMPLE_R_##_type(_name) \
|
|
|
|
GI_DEVICE_DESC_SIMPLE_W_##_type(_name)
|
|
|
|
|
|
|
|
GI_DEVICE_DESC_SIMPLE_R_u16(bcdUSB);
|
|
|
|
GI_DEVICE_DESC_SIMPLE_RW(bDeviceClass, u8);
|
|
|
|
GI_DEVICE_DESC_SIMPLE_RW(bDeviceSubClass, u8);
|
|
|
|
GI_DEVICE_DESC_SIMPLE_RW(bDeviceProtocol, u8);
|
|
|
|
GI_DEVICE_DESC_SIMPLE_RW(bMaxPacketSize0, u8);
|
|
|
|
GI_DEVICE_DESC_SIMPLE_RW(idVendor, u16);
|
|
|
|
GI_DEVICE_DESC_SIMPLE_RW(idProduct, u16);
|
|
|
|
GI_DEVICE_DESC_SIMPLE_R_u16(bcdDevice);
|
|
|
|
|
|
|
|
static ssize_t is_valid_bcd(u16 bcd_val)
|
|
|
|
{
|
|
|
|
if ((bcd_val & 0xf) > 9)
|
|
|
|
return -EINVAL;
|
|
|
|
if (((bcd_val >> 4) & 0xf) > 9)
|
|
|
|
return -EINVAL;
|
|
|
|
if (((bcd_val >> 8) & 0xf) > 9)
|
|
|
|
return -EINVAL;
|
|
|
|
if (((bcd_val >> 12) & 0xf) > 9)
|
|
|
|
return -EINVAL;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-10-03 21:32:38 +08:00
|
|
|
static ssize_t gadget_dev_desc_bcdDevice_store(struct config_item *item,
|
2012-12-24 04:10:24 +08:00
|
|
|
const char *page, size_t len)
|
|
|
|
{
|
|
|
|
u16 bcdDevice;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = kstrtou16(page, 0, &bcdDevice);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
ret = is_valid_bcd(bcdDevice);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
2015-10-03 21:32:38 +08:00
|
|
|
to_gadget_info(item)->cdev.desc.bcdDevice = cpu_to_le16(bcdDevice);
|
2012-12-24 04:10:24 +08:00
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
2015-10-03 21:32:38 +08:00
|
|
|
static ssize_t gadget_dev_desc_bcdUSB_store(struct config_item *item,
|
2012-12-24 04:10:24 +08:00
|
|
|
const char *page, size_t len)
|
|
|
|
{
|
|
|
|
u16 bcdUSB;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = kstrtou16(page, 0, &bcdUSB);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
ret = is_valid_bcd(bcdUSB);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
2015-10-03 21:32:38 +08:00
|
|
|
to_gadget_info(item)->cdev.desc.bcdUSB = cpu_to_le16(bcdUSB);
|
2012-12-24 04:10:24 +08:00
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
2015-10-03 21:32:38 +08:00
|
|
|
static ssize_t gadget_dev_desc_UDC_show(struct config_item *item, char *page)
|
2012-12-24 04:10:24 +08:00
|
|
|
{
|
2015-11-23 16:56:36 +08:00
|
|
|
char *udc_name = to_gadget_info(item)->composite.gadget_driver.udc_name;
|
|
|
|
|
|
|
|
return sprintf(page, "%s\n", udc_name ?: "");
|
2012-12-24 04:10:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static int unregister_gadget(struct gadget_info *gi)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
2015-11-23 16:56:36 +08:00
|
|
|
if (!gi->composite.gadget_driver.udc_name)
|
2012-12-24 04:10:24 +08:00
|
|
|
return -ENODEV;
|
|
|
|
|
|
|
|
ret = usb_gadget_unregister_driver(&gi->composite.gadget_driver);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
2015-11-23 16:56:36 +08:00
|
|
|
kfree(gi->composite.gadget_driver.udc_name);
|
|
|
|
gi->composite.gadget_driver.udc_name = NULL;
|
2012-12-24 04:10:24 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-10-03 21:32:38 +08:00
|
|
|
static ssize_t gadget_dev_desc_UDC_store(struct config_item *item,
|
2012-12-24 04:10:24 +08:00
|
|
|
const char *page, size_t len)
|
|
|
|
{
|
2015-10-03 21:32:38 +08:00
|
|
|
struct gadget_info *gi = to_gadget_info(item);
|
2012-12-24 04:10:24 +08:00
|
|
|
char *name;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
name = kstrdup(page, GFP_KERNEL);
|
|
|
|
if (!name)
|
|
|
|
return -ENOMEM;
|
|
|
|
if (name[len - 1] == '\n')
|
|
|
|
name[len - 1] = '\0';
|
|
|
|
|
|
|
|
mutex_lock(&gi->lock);
|
|
|
|
|
|
|
|
if (!strlen(name)) {
|
|
|
|
ret = unregister_gadget(gi);
|
|
|
|
if (ret)
|
|
|
|
goto err;
|
2017-02-28 18:55:30 +08:00
|
|
|
kfree(name);
|
2012-12-24 04:10:24 +08:00
|
|
|
} else {
|
2015-11-23 16:56:36 +08:00
|
|
|
if (gi->composite.gadget_driver.udc_name) {
|
2012-12-24 04:10:24 +08:00
|
|
|
ret = -EBUSY;
|
|
|
|
goto err;
|
|
|
|
}
|
2015-11-23 16:56:36 +08:00
|
|
|
gi->composite.gadget_driver.udc_name = name;
|
|
|
|
ret = usb_gadget_probe_driver(&gi->composite.gadget_driver);
|
|
|
|
if (ret) {
|
|
|
|
gi->composite.gadget_driver.udc_name = NULL;
|
2012-12-24 04:10:24 +08:00
|
|
|
goto err;
|
2015-11-23 16:56:36 +08:00
|
|
|
}
|
2012-12-24 04:10:24 +08:00
|
|
|
}
|
|
|
|
mutex_unlock(&gi->lock);
|
|
|
|
return len;
|
|
|
|
err:
|
|
|
|
kfree(name);
|
|
|
|
mutex_unlock(&gi->lock);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-10-03 21:32:38 +08:00
|
|
|
CONFIGFS_ATTR(gadget_dev_desc_, bDeviceClass);
|
|
|
|
CONFIGFS_ATTR(gadget_dev_desc_, bDeviceSubClass);
|
|
|
|
CONFIGFS_ATTR(gadget_dev_desc_, bDeviceProtocol);
|
|
|
|
CONFIGFS_ATTR(gadget_dev_desc_, bMaxPacketSize0);
|
|
|
|
CONFIGFS_ATTR(gadget_dev_desc_, idVendor);
|
|
|
|
CONFIGFS_ATTR(gadget_dev_desc_, idProduct);
|
|
|
|
CONFIGFS_ATTR(gadget_dev_desc_, bcdDevice);
|
|
|
|
CONFIGFS_ATTR(gadget_dev_desc_, bcdUSB);
|
|
|
|
CONFIGFS_ATTR(gadget_dev_desc_, UDC);
|
2012-12-24 04:10:24 +08:00
|
|
|
|
|
|
|
static struct configfs_attribute *gadget_root_attrs[] = {
|
2015-10-03 21:32:38 +08:00
|
|
|
&gadget_dev_desc_attr_bDeviceClass,
|
|
|
|
&gadget_dev_desc_attr_bDeviceSubClass,
|
|
|
|
&gadget_dev_desc_attr_bDeviceProtocol,
|
|
|
|
&gadget_dev_desc_attr_bMaxPacketSize0,
|
|
|
|
&gadget_dev_desc_attr_idVendor,
|
|
|
|
&gadget_dev_desc_attr_idProduct,
|
|
|
|
&gadget_dev_desc_attr_bcdDevice,
|
|
|
|
&gadget_dev_desc_attr_bcdUSB,
|
|
|
|
&gadget_dev_desc_attr_UDC,
|
2012-12-24 04:10:24 +08:00
|
|
|
NULL,
|
|
|
|
};
|
|
|
|
|
|
|
|
static inline struct gadget_strings *to_gadget_strings(struct config_item *item)
|
|
|
|
{
|
|
|
|
return container_of(to_config_group(item), struct gadget_strings,
|
|
|
|
group);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline struct gadget_config_name *to_gadget_config_name(
|
|
|
|
struct config_item *item)
|
|
|
|
{
|
|
|
|
return container_of(to_config_group(item), struct gadget_config_name,
|
|
|
|
group);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline struct usb_function_instance *to_usb_function_instance(
|
|
|
|
struct config_item *item)
|
|
|
|
{
|
|
|
|
return container_of(to_config_group(item),
|
|
|
|
struct usb_function_instance, group);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void gadget_info_attr_release(struct config_item *item)
|
|
|
|
{
|
|
|
|
struct gadget_info *gi = to_gadget_info(item);
|
|
|
|
|
|
|
|
WARN_ON(!list_empty(&gi->cdev.configs));
|
|
|
|
WARN_ON(!list_empty(&gi->string_list));
|
|
|
|
WARN_ON(!list_empty(&gi->available_func));
|
|
|
|
kfree(gi->composite.gadget_driver.function);
|
|
|
|
kfree(gi);
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct configfs_item_operations gadget_root_item_ops = {
|
|
|
|
.release = gadget_info_attr_release,
|
|
|
|
};
|
|
|
|
|
|
|
|
static void gadget_config_attr_release(struct config_item *item)
|
|
|
|
{
|
|
|
|
struct config_usb_cfg *cfg = to_config_usb_cfg(item);
|
|
|
|
|
|
|
|
WARN_ON(!list_empty(&cfg->c.functions));
|
|
|
|
list_del(&cfg->c.list);
|
|
|
|
kfree(cfg->c.label);
|
|
|
|
kfree(cfg);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int config_usb_cfg_link(
|
|
|
|
struct config_item *usb_cfg_ci,
|
|
|
|
struct config_item *usb_func_ci)
|
|
|
|
{
|
|
|
|
struct config_usb_cfg *cfg = to_config_usb_cfg(usb_cfg_ci);
|
|
|
|
struct usb_composite_dev *cdev = cfg->c.cdev;
|
|
|
|
struct gadget_info *gi = container_of(cdev, struct gadget_info, cdev);
|
|
|
|
|
|
|
|
struct config_group *group = to_config_group(usb_func_ci);
|
|
|
|
struct usb_function_instance *fi = container_of(group,
|
|
|
|
struct usb_function_instance, group);
|
|
|
|
struct usb_function_instance *a_fi;
|
|
|
|
struct usb_function *f;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
mutex_lock(&gi->lock);
|
|
|
|
/*
|
|
|
|
* Make sure this function is from within our _this_ gadget and not
|
|
|
|
* from another gadget or a random directory.
|
|
|
|
* Also a function instance can only be linked once.
|
|
|
|
*/
|
|
|
|
list_for_each_entry(a_fi, &gi->available_func, cfs_list) {
|
|
|
|
if (a_fi == fi)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (a_fi != fi) {
|
|
|
|
ret = -EINVAL;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
list_for_each_entry(f, &cfg->func_list, list) {
|
|
|
|
if (f->fi == fi) {
|
|
|
|
ret = -EEXIST;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
f = usb_get_function(fi);
|
|
|
|
if (IS_ERR(f)) {
|
|
|
|
ret = PTR_ERR(f);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* stash the function until we bind it to the gadget */
|
|
|
|
list_add_tail(&f->list, &cfg->func_list);
|
|
|
|
ret = 0;
|
|
|
|
out:
|
|
|
|
mutex_unlock(&gi->lock);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2016-11-28 20:22:42 +08:00
|
|
|
static void config_usb_cfg_unlink(
|
2012-12-24 04:10:24 +08:00
|
|
|
struct config_item *usb_cfg_ci,
|
|
|
|
struct config_item *usb_func_ci)
|
|
|
|
{
|
|
|
|
struct config_usb_cfg *cfg = to_config_usb_cfg(usb_cfg_ci);
|
|
|
|
struct usb_composite_dev *cdev = cfg->c.cdev;
|
|
|
|
struct gadget_info *gi = container_of(cdev, struct gadget_info, cdev);
|
|
|
|
|
|
|
|
struct config_group *group = to_config_group(usb_func_ci);
|
|
|
|
struct usb_function_instance *fi = container_of(group,
|
|
|
|
struct usb_function_instance, group);
|
|
|
|
struct usb_function *f;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* ideally I would like to forbid to unlink functions while a gadget is
|
|
|
|
* bound to an UDC. Since this isn't possible at the moment, we simply
|
|
|
|
* force an unbind, the function is available here and then we can
|
|
|
|
* remove the function.
|
|
|
|
*/
|
|
|
|
mutex_lock(&gi->lock);
|
2015-11-23 16:56:36 +08:00
|
|
|
if (gi->composite.gadget_driver.udc_name)
|
2012-12-24 04:10:24 +08:00
|
|
|
unregister_gadget(gi);
|
2015-11-23 16:56:36 +08:00
|
|
|
WARN_ON(gi->composite.gadget_driver.udc_name);
|
2012-12-24 04:10:24 +08:00
|
|
|
|
|
|
|
list_for_each_entry(f, &cfg->func_list, list) {
|
|
|
|
if (f->fi == fi) {
|
|
|
|
list_del(&f->list);
|
|
|
|
usb_put_function(f);
|
|
|
|
mutex_unlock(&gi->lock);
|
2016-11-28 20:22:42 +08:00
|
|
|
return;
|
2012-12-24 04:10:24 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
mutex_unlock(&gi->lock);
|
2013-04-08 05:11:47 +08:00
|
|
|
WARN(1, "Unable to locate function to unbind\n");
|
2012-12-24 04:10:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static struct configfs_item_operations gadget_config_item_ops = {
|
|
|
|
.release = gadget_config_attr_release,
|
|
|
|
.allow_link = config_usb_cfg_link,
|
|
|
|
.drop_link = config_usb_cfg_unlink,
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-10-03 21:32:38 +08:00
|
|
|
static ssize_t gadget_config_desc_MaxPower_show(struct config_item *item,
|
2012-12-24 04:10:24 +08:00
|
|
|
char *page)
|
|
|
|
{
|
2015-10-03 21:32:38 +08:00
|
|
|
return sprintf(page, "%u\n", to_config_usb_cfg(item)->c.MaxPower);
|
2012-12-24 04:10:24 +08:00
|
|
|
}
|
|
|
|
|
2015-10-03 21:32:38 +08:00
|
|
|
static ssize_t gadget_config_desc_MaxPower_store(struct config_item *item,
|
2012-12-24 04:10:24 +08:00
|
|
|
const char *page, size_t len)
|
|
|
|
{
|
|
|
|
u16 val;
|
|
|
|
int ret;
|
|
|
|
ret = kstrtou16(page, 0, &val);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
if (DIV_ROUND_UP(val, 8) > 0xff)
|
|
|
|
return -ERANGE;
|
2015-10-03 21:32:38 +08:00
|
|
|
to_config_usb_cfg(item)->c.MaxPower = val;
|
2012-12-24 04:10:24 +08:00
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
2015-10-03 21:32:38 +08:00
|
|
|
static ssize_t gadget_config_desc_bmAttributes_show(struct config_item *item,
|
2012-12-24 04:10:24 +08:00
|
|
|
char *page)
|
|
|
|
{
|
2015-10-03 21:32:38 +08:00
|
|
|
return sprintf(page, "0x%02x\n",
|
|
|
|
to_config_usb_cfg(item)->c.bmAttributes);
|
2012-12-24 04:10:24 +08:00
|
|
|
}
|
|
|
|
|
2015-10-03 21:32:38 +08:00
|
|
|
static ssize_t gadget_config_desc_bmAttributes_store(struct config_item *item,
|
2012-12-24 04:10:24 +08:00
|
|
|
const char *page, size_t len)
|
|
|
|
{
|
|
|
|
u8 val;
|
|
|
|
int ret;
|
|
|
|
ret = kstrtou8(page, 0, &val);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
if (!(val & USB_CONFIG_ATT_ONE))
|
|
|
|
return -EINVAL;
|
|
|
|
if (val & ~(USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER |
|
|
|
|
USB_CONFIG_ATT_WAKEUP))
|
|
|
|
return -EINVAL;
|
2015-10-03 21:32:38 +08:00
|
|
|
to_config_usb_cfg(item)->c.bmAttributes = val;
|
2012-12-24 04:10:24 +08:00
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
2015-10-03 21:32:38 +08:00
|
|
|
CONFIGFS_ATTR(gadget_config_desc_, MaxPower);
|
|
|
|
CONFIGFS_ATTR(gadget_config_desc_, bmAttributes);
|
2012-12-24 04:10:24 +08:00
|
|
|
|
|
|
|
static struct configfs_attribute *gadget_config_attrs[] = {
|
2015-10-03 21:32:38 +08:00
|
|
|
&gadget_config_desc_attr_MaxPower,
|
|
|
|
&gadget_config_desc_attr_bmAttributes,
|
2012-12-24 04:10:24 +08:00
|
|
|
NULL,
|
|
|
|
};
|
|
|
|
|
2017-10-16 23:18:46 +08:00
|
|
|
static const struct config_item_type gadget_config_type = {
|
2012-12-24 04:10:24 +08:00
|
|
|
.ct_item_ops = &gadget_config_item_ops,
|
|
|
|
.ct_attrs = gadget_config_attrs,
|
|
|
|
.ct_owner = THIS_MODULE,
|
|
|
|
};
|
|
|
|
|
2017-10-16 23:18:46 +08:00
|
|
|
static const struct config_item_type gadget_root_type = {
|
2012-12-24 04:10:24 +08:00
|
|
|
.ct_item_ops = &gadget_root_item_ops,
|
|
|
|
.ct_attrs = gadget_root_attrs,
|
|
|
|
.ct_owner = THIS_MODULE,
|
|
|
|
};
|
|
|
|
|
|
|
|
static void composite_init_dev(struct usb_composite_dev *cdev)
|
|
|
|
{
|
|
|
|
spin_lock_init(&cdev->lock);
|
|
|
|
INIT_LIST_HEAD(&cdev->configs);
|
|
|
|
INIT_LIST_HEAD(&cdev->gstrings);
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct config_group *function_make(
|
|
|
|
struct config_group *group,
|
|
|
|
const char *name)
|
|
|
|
{
|
|
|
|
struct gadget_info *gi;
|
|
|
|
struct usb_function_instance *fi;
|
|
|
|
char buf[MAX_NAME_LEN];
|
|
|
|
char *func_name;
|
|
|
|
char *instance_name;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = snprintf(buf, MAX_NAME_LEN, "%s", name);
|
|
|
|
if (ret >= MAX_NAME_LEN)
|
|
|
|
return ERR_PTR(-ENAMETOOLONG);
|
|
|
|
|
|
|
|
func_name = buf;
|
|
|
|
instance_name = strchr(func_name, '.');
|
|
|
|
if (!instance_name) {
|
|
|
|
pr_err("Unable to locate . in FUNC.INSTANCE\n");
|
|
|
|
return ERR_PTR(-EINVAL);
|
|
|
|
}
|
|
|
|
*instance_name = '\0';
|
|
|
|
instance_name++;
|
|
|
|
|
|
|
|
fi = usb_get_function_instance(func_name);
|
|
|
|
if (IS_ERR(fi))
|
2013-09-26 15:55:25 +08:00
|
|
|
return ERR_CAST(fi);
|
2012-12-24 04:10:24 +08:00
|
|
|
|
2015-07-18 07:23:45 +08:00
|
|
|
ret = config_item_set_name(&fi->group.cg_item, "%s", name);
|
2012-12-24 04:10:24 +08:00
|
|
|
if (ret) {
|
|
|
|
usb_put_function_instance(fi);
|
|
|
|
return ERR_PTR(ret);
|
|
|
|
}
|
2013-12-03 22:15:21 +08:00
|
|
|
if (fi->set_inst_name) {
|
|
|
|
ret = fi->set_inst_name(fi, instance_name);
|
|
|
|
if (ret) {
|
|
|
|
usb_put_function_instance(fi);
|
|
|
|
return ERR_PTR(ret);
|
|
|
|
}
|
|
|
|
}
|
2012-12-24 04:10:24 +08:00
|
|
|
|
|
|
|
gi = container_of(group, struct gadget_info, functions_group);
|
|
|
|
|
|
|
|
mutex_lock(&gi->lock);
|
|
|
|
list_add_tail(&fi->cfs_list, &gi->available_func);
|
|
|
|
mutex_unlock(&gi->lock);
|
|
|
|
return &fi->group;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void function_drop(
|
|
|
|
struct config_group *group,
|
|
|
|
struct config_item *item)
|
|
|
|
{
|
|
|
|
struct usb_function_instance *fi = to_usb_function_instance(item);
|
|
|
|
struct gadget_info *gi;
|
|
|
|
|
|
|
|
gi = container_of(group, struct gadget_info, functions_group);
|
|
|
|
|
|
|
|
mutex_lock(&gi->lock);
|
|
|
|
list_del(&fi->cfs_list);
|
|
|
|
mutex_unlock(&gi->lock);
|
|
|
|
config_item_put(item);
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct configfs_group_operations functions_ops = {
|
|
|
|
.make_group = &function_make,
|
|
|
|
.drop_item = &function_drop,
|
|
|
|
};
|
|
|
|
|
2017-10-16 23:18:46 +08:00
|
|
|
static const struct config_item_type functions_type = {
|
2012-12-24 04:10:24 +08:00
|
|
|
.ct_group_ops = &functions_ops,
|
|
|
|
.ct_owner = THIS_MODULE,
|
|
|
|
};
|
|
|
|
|
|
|
|
GS_STRINGS_RW(gadget_config_name, configuration);
|
|
|
|
|
|
|
|
static struct configfs_attribute *gadget_config_name_langid_attrs[] = {
|
2015-10-03 21:32:38 +08:00
|
|
|
&gadget_config_name_attr_configuration,
|
2012-12-24 04:10:24 +08:00
|
|
|
NULL,
|
|
|
|
};
|
|
|
|
|
|
|
|
static void gadget_config_name_attr_release(struct config_item *item)
|
|
|
|
{
|
|
|
|
struct gadget_config_name *cn = to_gadget_config_name(item);
|
|
|
|
|
|
|
|
kfree(cn->configuration);
|
|
|
|
|
|
|
|
list_del(&cn->list);
|
|
|
|
kfree(cn);
|
|
|
|
}
|
|
|
|
|
|
|
|
USB_CONFIG_STRING_RW_OPS(gadget_config_name);
|
|
|
|
USB_CONFIG_STRINGS_LANG(gadget_config_name, config_usb_cfg);
|
|
|
|
|
|
|
|
static struct config_group *config_desc_make(
|
|
|
|
struct config_group *group,
|
|
|
|
const char *name)
|
|
|
|
{
|
|
|
|
struct gadget_info *gi;
|
|
|
|
struct config_usb_cfg *cfg;
|
|
|
|
char buf[MAX_NAME_LEN];
|
|
|
|
char *num_str;
|
|
|
|
u8 num;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
gi = container_of(group, struct gadget_info, configs_group);
|
|
|
|
ret = snprintf(buf, MAX_NAME_LEN, "%s", name);
|
|
|
|
if (ret >= MAX_NAME_LEN)
|
|
|
|
return ERR_PTR(-ENAMETOOLONG);
|
|
|
|
|
|
|
|
num_str = strchr(buf, '.');
|
|
|
|
if (!num_str) {
|
|
|
|
pr_err("Unable to locate . in name.bConfigurationValue\n");
|
|
|
|
return ERR_PTR(-EINVAL);
|
|
|
|
}
|
|
|
|
|
|
|
|
*num_str = '\0';
|
|
|
|
num_str++;
|
|
|
|
|
|
|
|
if (!strlen(buf))
|
|
|
|
return ERR_PTR(-EINVAL);
|
|
|
|
|
|
|
|
ret = kstrtou8(num_str, 0, &num);
|
|
|
|
if (ret)
|
|
|
|
return ERR_PTR(ret);
|
|
|
|
|
|
|
|
cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
|
|
|
|
if (!cfg)
|
|
|
|
return ERR_PTR(-ENOMEM);
|
|
|
|
cfg->c.label = kstrdup(buf, GFP_KERNEL);
|
|
|
|
if (!cfg->c.label) {
|
|
|
|
ret = -ENOMEM;
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
cfg->c.bConfigurationValue = num;
|
|
|
|
cfg->c.MaxPower = CONFIG_USB_GADGET_VBUS_DRAW;
|
|
|
|
cfg->c.bmAttributes = USB_CONFIG_ATT_ONE;
|
|
|
|
INIT_LIST_HEAD(&cfg->string_list);
|
|
|
|
INIT_LIST_HEAD(&cfg->func_list);
|
|
|
|
|
|
|
|
config_group_init_type_name(&cfg->group, name,
|
|
|
|
&gadget_config_type);
|
2016-02-26 18:02:14 +08:00
|
|
|
|
2012-12-24 04:10:24 +08:00
|
|
|
config_group_init_type_name(&cfg->strings_group, "strings",
|
|
|
|
&gadget_config_name_strings_type);
|
2016-02-26 18:02:14 +08:00
|
|
|
configfs_add_default_group(&cfg->strings_group, &cfg->group);
|
2012-12-24 04:10:24 +08:00
|
|
|
|
|
|
|
ret = usb_add_config_only(&gi->cdev, &cfg->c);
|
|
|
|
if (ret)
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
return &cfg->group;
|
|
|
|
err:
|
|
|
|
kfree(cfg->c.label);
|
|
|
|
kfree(cfg);
|
|
|
|
return ERR_PTR(ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void config_desc_drop(
|
|
|
|
struct config_group *group,
|
|
|
|
struct config_item *item)
|
|
|
|
{
|
|
|
|
config_item_put(item);
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct configfs_group_operations config_desc_ops = {
|
|
|
|
.make_group = &config_desc_make,
|
|
|
|
.drop_item = &config_desc_drop,
|
|
|
|
};
|
|
|
|
|
2017-10-16 23:18:46 +08:00
|
|
|
static const struct config_item_type config_desc_type = {
|
2012-12-24 04:10:24 +08:00
|
|
|
.ct_group_ops = &config_desc_ops,
|
|
|
|
.ct_owner = THIS_MODULE,
|
|
|
|
};
|
|
|
|
|
|
|
|
GS_STRINGS_RW(gadget_strings, manufacturer);
|
|
|
|
GS_STRINGS_RW(gadget_strings, product);
|
|
|
|
GS_STRINGS_RW(gadget_strings, serialnumber);
|
|
|
|
|
|
|
|
static struct configfs_attribute *gadget_strings_langid_attrs[] = {
|
2015-10-03 21:32:38 +08:00
|
|
|
&gadget_strings_attr_manufacturer,
|
|
|
|
&gadget_strings_attr_product,
|
|
|
|
&gadget_strings_attr_serialnumber,
|
2012-12-24 04:10:24 +08:00
|
|
|
NULL,
|
|
|
|
};
|
|
|
|
|
|
|
|
static void gadget_strings_attr_release(struct config_item *item)
|
|
|
|
{
|
|
|
|
struct gadget_strings *gs = to_gadget_strings(item);
|
|
|
|
|
|
|
|
kfree(gs->manufacturer);
|
|
|
|
kfree(gs->product);
|
|
|
|
kfree(gs->serialnumber);
|
|
|
|
|
|
|
|
list_del(&gs->list);
|
|
|
|
kfree(gs);
|
|
|
|
}
|
|
|
|
|
|
|
|
USB_CONFIG_STRING_RW_OPS(gadget_strings);
|
|
|
|
USB_CONFIG_STRINGS_LANG(gadget_strings, gadget_info);
|
|
|
|
|
2014-05-08 20:06:25 +08:00
|
|
|
static inline struct os_desc *to_os_desc(struct config_item *item)
|
|
|
|
{
|
|
|
|
return container_of(to_config_group(item), struct os_desc, group);
|
|
|
|
}
|
|
|
|
|
2015-10-03 21:32:38 +08:00
|
|
|
static inline struct gadget_info *os_desc_item_to_gadget_info(
|
|
|
|
struct config_item *item)
|
2014-05-08 20:06:25 +08:00
|
|
|
{
|
2015-10-03 21:32:38 +08:00
|
|
|
return to_gadget_info(to_os_desc(item)->group.cg_item.ci_parent);
|
|
|
|
}
|
2014-05-08 20:06:25 +08:00
|
|
|
|
2015-10-03 21:32:38 +08:00
|
|
|
static ssize_t os_desc_use_show(struct config_item *item, char *page)
|
|
|
|
{
|
2017-04-15 09:35:09 +08:00
|
|
|
return sprintf(page, "%d\n",
|
2015-10-03 21:32:38 +08:00
|
|
|
os_desc_item_to_gadget_info(item)->use_os_desc);
|
2014-05-08 20:06:25 +08:00
|
|
|
}
|
|
|
|
|
2015-10-03 21:32:38 +08:00
|
|
|
static ssize_t os_desc_use_store(struct config_item *item, const char *page,
|
2014-05-08 20:06:25 +08:00
|
|
|
size_t len)
|
|
|
|
{
|
2015-10-03 21:32:38 +08:00
|
|
|
struct gadget_info *gi = os_desc_item_to_gadget_info(item);
|
2014-05-08 20:06:25 +08:00
|
|
|
int ret;
|
|
|
|
bool use;
|
|
|
|
|
|
|
|
mutex_lock(&gi->lock);
|
|
|
|
ret = strtobool(page, &use);
|
|
|
|
if (!ret) {
|
|
|
|
gi->use_os_desc = use;
|
|
|
|
ret = len;
|
|
|
|
}
|
|
|
|
mutex_unlock(&gi->lock);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-10-03 21:32:38 +08:00
|
|
|
static ssize_t os_desc_b_vendor_code_show(struct config_item *item, char *page)
|
2014-05-08 20:06:25 +08:00
|
|
|
{
|
2017-04-15 09:35:09 +08:00
|
|
|
return sprintf(page, "0x%02x\n",
|
2015-10-03 21:32:38 +08:00
|
|
|
os_desc_item_to_gadget_info(item)->b_vendor_code);
|
2014-05-08 20:06:25 +08:00
|
|
|
}
|
|
|
|
|
2015-10-03 21:32:38 +08:00
|
|
|
static ssize_t os_desc_b_vendor_code_store(struct config_item *item,
|
2014-05-08 20:06:25 +08:00
|
|
|
const char *page, size_t len)
|
|
|
|
{
|
2015-10-03 21:32:38 +08:00
|
|
|
struct gadget_info *gi = os_desc_item_to_gadget_info(item);
|
2014-05-08 20:06:25 +08:00
|
|
|
int ret;
|
|
|
|
u8 b_vendor_code;
|
|
|
|
|
|
|
|
mutex_lock(&gi->lock);
|
|
|
|
ret = kstrtou8(page, 0, &b_vendor_code);
|
|
|
|
if (!ret) {
|
|
|
|
gi->b_vendor_code = b_vendor_code;
|
|
|
|
ret = len;
|
|
|
|
}
|
|
|
|
mutex_unlock(&gi->lock);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-10-03 21:32:38 +08:00
|
|
|
static ssize_t os_desc_qw_sign_show(struct config_item *item, char *page)
|
2014-05-08 20:06:25 +08:00
|
|
|
{
|
2015-10-03 21:32:38 +08:00
|
|
|
struct gadget_info *gi = os_desc_item_to_gadget_info(item);
|
2017-04-15 09:35:08 +08:00
|
|
|
int res;
|
2014-05-08 20:06:25 +08:00
|
|
|
|
2017-04-15 09:35:08 +08:00
|
|
|
res = utf16s_to_utf8s((wchar_t *) gi->qw_sign, OS_STRING_QW_SIGN_LEN,
|
|
|
|
UTF16_LITTLE_ENDIAN, page, PAGE_SIZE - 1);
|
|
|
|
page[res++] = '\n';
|
|
|
|
|
|
|
|
return res;
|
2014-05-08 20:06:25 +08:00
|
|
|
}
|
|
|
|
|
2015-10-03 21:32:38 +08:00
|
|
|
static ssize_t os_desc_qw_sign_store(struct config_item *item, const char *page,
|
2014-05-08 20:06:25 +08:00
|
|
|
size_t len)
|
|
|
|
{
|
2015-10-03 21:32:38 +08:00
|
|
|
struct gadget_info *gi = os_desc_item_to_gadget_info(item);
|
2014-05-08 20:06:25 +08:00
|
|
|
int res, l;
|
|
|
|
|
|
|
|
l = min((int)len, OS_STRING_QW_SIGN_LEN >> 1);
|
|
|
|
if (page[l - 1] == '\n')
|
|
|
|
--l;
|
|
|
|
|
|
|
|
mutex_lock(&gi->lock);
|
|
|
|
res = utf8s_to_utf16s(page, l,
|
|
|
|
UTF16_LITTLE_ENDIAN, (wchar_t *) gi->qw_sign,
|
|
|
|
OS_STRING_QW_SIGN_LEN);
|
|
|
|
if (res > 0)
|
|
|
|
res = len;
|
|
|
|
mutex_unlock(&gi->lock);
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2015-10-03 21:32:38 +08:00
|
|
|
CONFIGFS_ATTR(os_desc_, use);
|
|
|
|
CONFIGFS_ATTR(os_desc_, b_vendor_code);
|
|
|
|
CONFIGFS_ATTR(os_desc_, qw_sign);
|
2014-05-08 20:06:25 +08:00
|
|
|
|
|
|
|
static struct configfs_attribute *os_desc_attrs[] = {
|
2015-10-03 21:32:38 +08:00
|
|
|
&os_desc_attr_use,
|
|
|
|
&os_desc_attr_b_vendor_code,
|
|
|
|
&os_desc_attr_qw_sign,
|
2014-05-08 20:06:25 +08:00
|
|
|
NULL,
|
|
|
|
};
|
|
|
|
|
|
|
|
static void os_desc_attr_release(struct config_item *item)
|
|
|
|
{
|
|
|
|
struct os_desc *os_desc = to_os_desc(item);
|
|
|
|
kfree(os_desc);
|
|
|
|
}
|
|
|
|
|
2014-05-08 20:06:26 +08:00
|
|
|
static int os_desc_link(struct config_item *os_desc_ci,
|
|
|
|
struct config_item *usb_cfg_ci)
|
|
|
|
{
|
|
|
|
struct gadget_info *gi = container_of(to_config_group(os_desc_ci),
|
|
|
|
struct gadget_info, os_desc_group);
|
|
|
|
struct usb_composite_dev *cdev = &gi->cdev;
|
|
|
|
struct config_usb_cfg *c_target =
|
|
|
|
container_of(to_config_group(usb_cfg_ci),
|
|
|
|
struct config_usb_cfg, group);
|
|
|
|
struct usb_configuration *c;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
mutex_lock(&gi->lock);
|
|
|
|
list_for_each_entry(c, &cdev->configs, list) {
|
|
|
|
if (c == &c_target->c)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (c != &c_target->c) {
|
|
|
|
ret = -EINVAL;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cdev->os_desc_config) {
|
|
|
|
ret = -EBUSY;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
cdev->os_desc_config = &c_target->c;
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
out:
|
|
|
|
mutex_unlock(&gi->lock);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2016-11-28 20:22:42 +08:00
|
|
|
static void os_desc_unlink(struct config_item *os_desc_ci,
|
2014-05-08 20:06:26 +08:00
|
|
|
struct config_item *usb_cfg_ci)
|
|
|
|
{
|
|
|
|
struct gadget_info *gi = container_of(to_config_group(os_desc_ci),
|
|
|
|
struct gadget_info, os_desc_group);
|
|
|
|
struct usb_composite_dev *cdev = &gi->cdev;
|
|
|
|
|
|
|
|
mutex_lock(&gi->lock);
|
2015-11-23 16:56:36 +08:00
|
|
|
if (gi->composite.gadget_driver.udc_name)
|
2014-05-08 20:06:26 +08:00
|
|
|
unregister_gadget(gi);
|
|
|
|
cdev->os_desc_config = NULL;
|
2015-11-23 16:56:36 +08:00
|
|
|
WARN_ON(gi->composite.gadget_driver.udc_name);
|
2014-05-08 20:06:26 +08:00
|
|
|
mutex_unlock(&gi->lock);
|
|
|
|
}
|
|
|
|
|
2014-05-08 20:06:25 +08:00
|
|
|
static struct configfs_item_operations os_desc_ops = {
|
|
|
|
.release = os_desc_attr_release,
|
2014-05-08 20:06:26 +08:00
|
|
|
.allow_link = os_desc_link,
|
|
|
|
.drop_link = os_desc_unlink,
|
2014-05-08 20:06:25 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
static struct config_item_type os_desc_type = {
|
|
|
|
.ct_item_ops = &os_desc_ops,
|
|
|
|
.ct_attrs = os_desc_attrs,
|
|
|
|
.ct_owner = THIS_MODULE,
|
|
|
|
};
|
|
|
|
|
2014-05-08 20:06:28 +08:00
|
|
|
static inline struct usb_os_desc_ext_prop
|
|
|
|
*to_usb_os_desc_ext_prop(struct config_item *item)
|
|
|
|
{
|
|
|
|
return container_of(item, struct usb_os_desc_ext_prop, item);
|
|
|
|
}
|
|
|
|
|
2015-10-03 21:32:38 +08:00
|
|
|
static ssize_t ext_prop_type_show(struct config_item *item, char *page)
|
2014-05-08 20:06:28 +08:00
|
|
|
{
|
2017-04-15 09:35:09 +08:00
|
|
|
return sprintf(page, "%d\n", to_usb_os_desc_ext_prop(item)->type);
|
2014-05-08 20:06:28 +08:00
|
|
|
}
|
|
|
|
|
2015-10-03 21:32:38 +08:00
|
|
|
static ssize_t ext_prop_type_store(struct config_item *item,
|
2014-05-08 20:06:28 +08:00
|
|
|
const char *page, size_t len)
|
|
|
|
{
|
2015-10-03 21:32:38 +08:00
|
|
|
struct usb_os_desc_ext_prop *ext_prop = to_usb_os_desc_ext_prop(item);
|
2014-05-08 20:06:28 +08:00
|
|
|
struct usb_os_desc *desc = to_usb_os_desc(ext_prop->item.ci_parent);
|
|
|
|
u8 type;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (desc->opts_mutex)
|
|
|
|
mutex_lock(desc->opts_mutex);
|
|
|
|
ret = kstrtou8(page, 0, &type);
|
|
|
|
if (ret)
|
|
|
|
goto end;
|
|
|
|
if (type < USB_EXT_PROP_UNICODE || type > USB_EXT_PROP_UNICODE_MULTI) {
|
|
|
|
ret = -EINVAL;
|
|
|
|
goto end;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((ext_prop->type == USB_EXT_PROP_BINARY ||
|
|
|
|
ext_prop->type == USB_EXT_PROP_LE32 ||
|
|
|
|
ext_prop->type == USB_EXT_PROP_BE32) &&
|
|
|
|
(type == USB_EXT_PROP_UNICODE ||
|
|
|
|
type == USB_EXT_PROP_UNICODE_ENV ||
|
|
|
|
type == USB_EXT_PROP_UNICODE_LINK))
|
|
|
|
ext_prop->data_len <<= 1;
|
|
|
|
else if ((ext_prop->type == USB_EXT_PROP_UNICODE ||
|
|
|
|
ext_prop->type == USB_EXT_PROP_UNICODE_ENV ||
|
|
|
|
ext_prop->type == USB_EXT_PROP_UNICODE_LINK) &&
|
|
|
|
(type == USB_EXT_PROP_BINARY ||
|
|
|
|
type == USB_EXT_PROP_LE32 ||
|
|
|
|
type == USB_EXT_PROP_BE32))
|
|
|
|
ext_prop->data_len >>= 1;
|
|
|
|
ext_prop->type = type;
|
|
|
|
ret = len;
|
|
|
|
|
|
|
|
end:
|
|
|
|
if (desc->opts_mutex)
|
|
|
|
mutex_unlock(desc->opts_mutex);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-10-03 21:32:38 +08:00
|
|
|
static ssize_t ext_prop_data_show(struct config_item *item, char *page)
|
2014-05-08 20:06:28 +08:00
|
|
|
{
|
2015-10-03 21:32:38 +08:00
|
|
|
struct usb_os_desc_ext_prop *ext_prop = to_usb_os_desc_ext_prop(item);
|
2014-05-08 20:06:28 +08:00
|
|
|
int len = ext_prop->data_len;
|
|
|
|
|
|
|
|
if (ext_prop->type == USB_EXT_PROP_UNICODE ||
|
|
|
|
ext_prop->type == USB_EXT_PROP_UNICODE_ENV ||
|
|
|
|
ext_prop->type == USB_EXT_PROP_UNICODE_LINK)
|
|
|
|
len >>= 1;
|
|
|
|
memcpy(page, ext_prop->data, len);
|
|
|
|
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
2015-10-03 21:32:38 +08:00
|
|
|
static ssize_t ext_prop_data_store(struct config_item *item,
|
2014-05-08 20:06:28 +08:00
|
|
|
const char *page, size_t len)
|
|
|
|
{
|
2015-10-03 21:32:38 +08:00
|
|
|
struct usb_os_desc_ext_prop *ext_prop = to_usb_os_desc_ext_prop(item);
|
2014-05-08 20:06:28 +08:00
|
|
|
struct usb_os_desc *desc = to_usb_os_desc(ext_prop->item.ci_parent);
|
|
|
|
char *new_data;
|
|
|
|
size_t ret_len = len;
|
|
|
|
|
|
|
|
if (page[len - 1] == '\n' || page[len - 1] == '\0')
|
|
|
|
--len;
|
2014-05-26 23:21:20 +08:00
|
|
|
new_data = kmemdup(page, len, GFP_KERNEL);
|
2014-05-08 20:06:28 +08:00
|
|
|
if (!new_data)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
if (desc->opts_mutex)
|
|
|
|
mutex_lock(desc->opts_mutex);
|
|
|
|
kfree(ext_prop->data);
|
|
|
|
ext_prop->data = new_data;
|
|
|
|
desc->ext_prop_len -= ext_prop->data_len;
|
|
|
|
ext_prop->data_len = len;
|
|
|
|
desc->ext_prop_len += ext_prop->data_len;
|
|
|
|
if (ext_prop->type == USB_EXT_PROP_UNICODE ||
|
|
|
|
ext_prop->type == USB_EXT_PROP_UNICODE_ENV ||
|
|
|
|
ext_prop->type == USB_EXT_PROP_UNICODE_LINK) {
|
|
|
|
desc->ext_prop_len -= ext_prop->data_len;
|
|
|
|
ext_prop->data_len <<= 1;
|
|
|
|
ext_prop->data_len += 2;
|
|
|
|
desc->ext_prop_len += ext_prop->data_len;
|
|
|
|
}
|
|
|
|
if (desc->opts_mutex)
|
|
|
|
mutex_unlock(desc->opts_mutex);
|
|
|
|
return ret_len;
|
|
|
|
}
|
|
|
|
|
2015-10-03 21:32:38 +08:00
|
|
|
CONFIGFS_ATTR(ext_prop_, type);
|
|
|
|
CONFIGFS_ATTR(ext_prop_, data);
|
2014-05-08 20:06:28 +08:00
|
|
|
|
|
|
|
static struct configfs_attribute *ext_prop_attrs[] = {
|
2015-10-03 21:32:38 +08:00
|
|
|
&ext_prop_attr_type,
|
|
|
|
&ext_prop_attr_data,
|
2014-05-08 20:06:28 +08:00
|
|
|
NULL,
|
|
|
|
};
|
|
|
|
|
|
|
|
static void usb_os_desc_ext_prop_release(struct config_item *item)
|
|
|
|
{
|
|
|
|
struct usb_os_desc_ext_prop *ext_prop = to_usb_os_desc_ext_prop(item);
|
|
|
|
|
|
|
|
kfree(ext_prop); /* frees a whole chunk */
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct configfs_item_operations ext_prop_ops = {
|
|
|
|
.release = usb_os_desc_ext_prop_release,
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct config_item *ext_prop_make(
|
|
|
|
struct config_group *group,
|
|
|
|
const char *name)
|
|
|
|
{
|
|
|
|
struct usb_os_desc_ext_prop *ext_prop;
|
|
|
|
struct config_item_type *ext_prop_type;
|
|
|
|
struct usb_os_desc *desc;
|
|
|
|
char *vlabuf;
|
|
|
|
|
|
|
|
vla_group(data_chunk);
|
|
|
|
vla_item(data_chunk, struct usb_os_desc_ext_prop, ext_prop, 1);
|
|
|
|
vla_item(data_chunk, struct config_item_type, ext_prop_type, 1);
|
|
|
|
|
|
|
|
vlabuf = kzalloc(vla_group_size(data_chunk), GFP_KERNEL);
|
|
|
|
if (!vlabuf)
|
|
|
|
return ERR_PTR(-ENOMEM);
|
|
|
|
|
|
|
|
ext_prop = vla_ptr(vlabuf, data_chunk, ext_prop);
|
|
|
|
ext_prop_type = vla_ptr(vlabuf, data_chunk, ext_prop_type);
|
|
|
|
|
|
|
|
desc = container_of(group, struct usb_os_desc, group);
|
|
|
|
ext_prop_type->ct_item_ops = &ext_prop_ops;
|
|
|
|
ext_prop_type->ct_attrs = ext_prop_attrs;
|
|
|
|
ext_prop_type->ct_owner = desc->owner;
|
|
|
|
|
|
|
|
config_item_init_type_name(&ext_prop->item, name, ext_prop_type);
|
|
|
|
|
|
|
|
ext_prop->name = kstrdup(name, GFP_KERNEL);
|
|
|
|
if (!ext_prop->name) {
|
|
|
|
kfree(vlabuf);
|
|
|
|
return ERR_PTR(-ENOMEM);
|
|
|
|
}
|
|
|
|
desc->ext_prop_len += 14;
|
|
|
|
ext_prop->name_len = 2 * strlen(ext_prop->name) + 2;
|
|
|
|
if (desc->opts_mutex)
|
|
|
|
mutex_lock(desc->opts_mutex);
|
|
|
|
desc->ext_prop_len += ext_prop->name_len;
|
|
|
|
list_add_tail(&ext_prop->entry, &desc->ext_prop);
|
|
|
|
++desc->ext_prop_count;
|
|
|
|
if (desc->opts_mutex)
|
|
|
|
mutex_unlock(desc->opts_mutex);
|
|
|
|
|
|
|
|
return &ext_prop->item;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ext_prop_drop(struct config_group *group, struct config_item *item)
|
|
|
|
{
|
|
|
|
struct usb_os_desc_ext_prop *ext_prop = to_usb_os_desc_ext_prop(item);
|
|
|
|
struct usb_os_desc *desc = to_usb_os_desc(&group->cg_item);
|
|
|
|
|
|
|
|
if (desc->opts_mutex)
|
|
|
|
mutex_lock(desc->opts_mutex);
|
|
|
|
list_del(&ext_prop->entry);
|
|
|
|
--desc->ext_prop_count;
|
|
|
|
kfree(ext_prop->name);
|
|
|
|
desc->ext_prop_len -= (ext_prop->name_len + ext_prop->data_len + 14);
|
|
|
|
if (desc->opts_mutex)
|
|
|
|
mutex_unlock(desc->opts_mutex);
|
|
|
|
config_item_put(item);
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct configfs_group_operations interf_grp_ops = {
|
|
|
|
.make_item = &ext_prop_make,
|
|
|
|
.drop_item = &ext_prop_drop,
|
|
|
|
};
|
|
|
|
|
2015-10-03 21:32:38 +08:00
|
|
|
static ssize_t interf_grp_compatible_id_show(struct config_item *item,
|
2014-06-18 20:24:48 +08:00
|
|
|
char *page)
|
2014-05-08 20:06:26 +08:00
|
|
|
{
|
2015-10-03 21:32:38 +08:00
|
|
|
memcpy(page, to_usb_os_desc(item)->ext_compat_id, 8);
|
2014-05-08 20:06:26 +08:00
|
|
|
return 8;
|
|
|
|
}
|
|
|
|
|
2015-10-03 21:32:38 +08:00
|
|
|
static ssize_t interf_grp_compatible_id_store(struct config_item *item,
|
2014-06-18 20:24:48 +08:00
|
|
|
const char *page, size_t len)
|
2014-05-08 20:06:26 +08:00
|
|
|
{
|
2015-10-03 21:32:38 +08:00
|
|
|
struct usb_os_desc *desc = to_usb_os_desc(item);
|
2014-05-08 20:06:26 +08:00
|
|
|
int l;
|
|
|
|
|
|
|
|
l = min_t(int, 8, len);
|
|
|
|
if (page[l - 1] == '\n')
|
|
|
|
--l;
|
|
|
|
if (desc->opts_mutex)
|
|
|
|
mutex_lock(desc->opts_mutex);
|
|
|
|
memcpy(desc->ext_compat_id, page, l);
|
|
|
|
|
|
|
|
if (desc->opts_mutex)
|
|
|
|
mutex_unlock(desc->opts_mutex);
|
|
|
|
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
2015-10-03 21:32:38 +08:00
|
|
|
static ssize_t interf_grp_sub_compatible_id_show(struct config_item *item,
|
2014-06-18 20:24:48 +08:00
|
|
|
char *page)
|
2014-05-08 20:06:26 +08:00
|
|
|
{
|
2015-10-03 21:32:38 +08:00
|
|
|
memcpy(page, to_usb_os_desc(item)->ext_compat_id + 8, 8);
|
2014-05-08 20:06:26 +08:00
|
|
|
return 8;
|
|
|
|
}
|
|
|
|
|
2015-10-03 21:32:38 +08:00
|
|
|
static ssize_t interf_grp_sub_compatible_id_store(struct config_item *item,
|
2014-06-18 20:24:48 +08:00
|
|
|
const char *page, size_t len)
|
2014-05-08 20:06:26 +08:00
|
|
|
{
|
2015-10-03 21:32:38 +08:00
|
|
|
struct usb_os_desc *desc = to_usb_os_desc(item);
|
2014-05-08 20:06:26 +08:00
|
|
|
int l;
|
|
|
|
|
|
|
|
l = min_t(int, 8, len);
|
|
|
|
if (page[l - 1] == '\n')
|
|
|
|
--l;
|
|
|
|
if (desc->opts_mutex)
|
|
|
|
mutex_lock(desc->opts_mutex);
|
|
|
|
memcpy(desc->ext_compat_id + 8, page, l);
|
|
|
|
|
|
|
|
if (desc->opts_mutex)
|
|
|
|
mutex_unlock(desc->opts_mutex);
|
|
|
|
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
2015-10-03 21:32:38 +08:00
|
|
|
CONFIGFS_ATTR(interf_grp_, compatible_id);
|
|
|
|
CONFIGFS_ATTR(interf_grp_, sub_compatible_id);
|
2014-05-08 20:06:26 +08:00
|
|
|
|
|
|
|
static struct configfs_attribute *interf_grp_attrs[] = {
|
2015-10-03 21:32:38 +08:00
|
|
|
&interf_grp_attr_compatible_id,
|
|
|
|
&interf_grp_attr_sub_compatible_id,
|
2014-05-08 20:06:26 +08:00
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
2017-09-30 23:54:52 +08:00
|
|
|
struct config_group *usb_os_desc_prepare_interf_dir(
|
|
|
|
struct config_group *parent,
|
|
|
|
int n_interf,
|
|
|
|
struct usb_os_desc **desc,
|
|
|
|
char **names,
|
|
|
|
struct module *owner)
|
2014-05-08 20:06:26 +08:00
|
|
|
{
|
2016-02-26 18:02:14 +08:00
|
|
|
struct config_group *os_desc_group;
|
2014-05-08 20:06:26 +08:00
|
|
|
struct config_item_type *os_desc_type, *interface_type;
|
|
|
|
|
|
|
|
vla_group(data_chunk);
|
|
|
|
vla_item(data_chunk, struct config_group, os_desc_group, 1);
|
|
|
|
vla_item(data_chunk, struct config_item_type, os_desc_type, 1);
|
|
|
|
vla_item(data_chunk, struct config_item_type, interface_type, 1);
|
|
|
|
|
|
|
|
char *vlabuf = kzalloc(vla_group_size(data_chunk), GFP_KERNEL);
|
|
|
|
if (!vlabuf)
|
2017-09-30 23:54:52 +08:00
|
|
|
return ERR_PTR(-ENOMEM);
|
2014-05-08 20:06:26 +08:00
|
|
|
|
|
|
|
os_desc_group = vla_ptr(vlabuf, data_chunk, os_desc_group);
|
|
|
|
os_desc_type = vla_ptr(vlabuf, data_chunk, os_desc_type);
|
|
|
|
interface_type = vla_ptr(vlabuf, data_chunk, interface_type);
|
|
|
|
|
|
|
|
os_desc_type->ct_owner = owner;
|
|
|
|
config_group_init_type_name(os_desc_group, "os_desc", os_desc_type);
|
2016-02-26 18:02:14 +08:00
|
|
|
configfs_add_default_group(os_desc_group, parent);
|
2014-05-08 20:06:26 +08:00
|
|
|
|
2014-05-08 20:06:28 +08:00
|
|
|
interface_type->ct_group_ops = &interf_grp_ops;
|
2014-05-08 20:06:26 +08:00
|
|
|
interface_type->ct_attrs = interf_grp_attrs;
|
|
|
|
interface_type->ct_owner = owner;
|
|
|
|
|
|
|
|
while (n_interf--) {
|
|
|
|
struct usb_os_desc *d;
|
|
|
|
|
|
|
|
d = desc[n_interf];
|
2014-05-08 20:06:28 +08:00
|
|
|
d->owner = owner;
|
2014-05-08 20:06:26 +08:00
|
|
|
config_group_init_type_name(&d->group, "", interface_type);
|
2014-06-18 20:24:49 +08:00
|
|
|
config_item_set_name(&d->group.cg_item, "interface.%s",
|
|
|
|
names[n_interf]);
|
2016-02-26 18:02:14 +08:00
|
|
|
configfs_add_default_group(&d->group, os_desc_group);
|
2014-05-08 20:06:26 +08:00
|
|
|
}
|
|
|
|
|
2017-09-30 23:54:52 +08:00
|
|
|
return os_desc_group;
|
2014-05-08 20:06:26 +08:00
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(usb_os_desc_prepare_interf_dir);
|
|
|
|
|
2012-12-24 04:10:24 +08:00
|
|
|
static int configfs_do_nothing(struct usb_composite_dev *cdev)
|
|
|
|
{
|
2013-04-08 05:11:47 +08:00
|
|
|
WARN_ON(1);
|
2012-12-24 04:10:24 +08:00
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
int composite_dev_prepare(struct usb_composite_driver *composite,
|
|
|
|
struct usb_composite_dev *dev);
|
|
|
|
|
2014-05-08 20:06:26 +08:00
|
|
|
int composite_os_desc_req_prepare(struct usb_composite_dev *cdev,
|
|
|
|
struct usb_ep *ep0);
|
|
|
|
|
2012-12-24 04:10:24 +08:00
|
|
|
static void purge_configs_funcs(struct gadget_info *gi)
|
|
|
|
{
|
|
|
|
struct usb_configuration *c;
|
|
|
|
|
|
|
|
list_for_each_entry(c, &gi->cdev.configs, list) {
|
|
|
|
struct usb_function *f, *tmp;
|
|
|
|
struct config_usb_cfg *cfg;
|
|
|
|
|
|
|
|
cfg = container_of(c, struct config_usb_cfg, c);
|
|
|
|
|
|
|
|
list_for_each_entry_safe(f, tmp, &c->functions, list) {
|
|
|
|
|
|
|
|
list_move_tail(&f->list, &cfg->func_list);
|
|
|
|
if (f->unbind) {
|
2016-08-29 17:22:29 +08:00
|
|
|
dev_dbg(&gi->cdev.gadget->dev,
|
2018-06-14 14:32:46 +08:00
|
|
|
"unbind function '%s'/%p\n",
|
|
|
|
f->name, f);
|
2012-12-24 04:10:24 +08:00
|
|
|
f->unbind(c, f);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
c->next_interface_id = 0;
|
2015-03-20 22:48:56 +08:00
|
|
|
memset(c->interface, 0, sizeof(c->interface));
|
2016-02-06 09:06:35 +08:00
|
|
|
c->superspeed_plus = 0;
|
2012-12-24 04:10:24 +08:00
|
|
|
c->superspeed = 0;
|
|
|
|
c->highspeed = 0;
|
|
|
|
c->fullspeed = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int configfs_composite_bind(struct usb_gadget *gadget,
|
|
|
|
struct usb_gadget_driver *gdriver)
|
|
|
|
{
|
|
|
|
struct usb_composite_driver *composite = to_cdriver(gdriver);
|
|
|
|
struct gadget_info *gi = container_of(composite,
|
|
|
|
struct gadget_info, composite);
|
|
|
|
struct usb_composite_dev *cdev = &gi->cdev;
|
|
|
|
struct usb_configuration *c;
|
|
|
|
struct usb_string *s;
|
|
|
|
unsigned i;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
/* the gi->lock is hold by the caller */
|
usb: gadget: configfs: fix concurrent issue between composite APIs
We meet several NULL pointer issues if configfs_composite_unbind
and composite_setup (or composite_disconnect) are running together.
These issues occur when do the function switch stress test, the
configfs_compsoite_unbind is called from user mode by
echo "" to /sys/../UDC entry, and meanwhile, the setup interrupt
or disconnect interrupt occurs by hardware. The composite_setup
will get the cdev from get_gadget_data, but configfs_composite_unbind
will set gadget data as NULL, so the NULL pointer issue occurs.
This concurrent is hard to reproduce by native kernel, but can be
reproduced by android kernel.
In this commit, we introduce one spinlock belongs to structure
gadget_info since we can't use the same spinlock in usb_composite_dev
due to exclusive running together between composite_setup and
configfs_composite_unbind. And one bit flag 'unbind' to indicate the
code is at unbind routine, this bit is needed due to we release the
lock at during configfs_composite_unbind sometimes, and composite_setup
may be run at that time.
Several oops:
oops 1:
android_work: sent uevent USB_STATE=CONNECTED
configfs-gadget gadget: super-speed config #1: b
android_work: sent uevent USB_STATE=CONFIGURED
init: Received control message 'start' for 'adbd' from pid: 3515 (system_server)
Unable to handle kernel NULL pointer dereference at virtual address 0000002a
init: Received control message 'stop' for 'adbd' from pid: 3375 (/vendor/bin/hw/android.hardware.usb@1.1-servic)
Mem abort info:
Exception class = DABT (current EL), IL = 32 bits
SET = 0, FnV = 0
EA = 0, S1PTW = 0
Data abort info:
ISV = 0, ISS = 0x00000004
CM = 0, WnR = 0
user pgtable: 4k pages, 48-bit VAs, pgd = ffff8008f1b7f000
[000000000000002a] *pgd=0000000000000000
Internal error: Oops: 96000004 [#1] PREEMPT SMP
Modules linked in:
CPU: 4 PID: 2457 Comm: irq/125-5b11000 Not tainted 4.14.98-07846-g0b40a9b-dirty #16
Hardware name: Freescale i.MX8QM MEK (DT)
task: ffff8008f2a98000 task.stack: ffff00000b7b8000
PC is at composite_setup+0x44/0x1508
LR is at android_setup+0xb8/0x13c
pc : [<ffff0000089ffb3c>] lr : [<ffff000008a032fc>] pstate: 800001c5
sp : ffff00000b7bbb80
x29: ffff00000b7bbb80 x28: ffff8008f2a3c010
x27: 0000000000000001 x26: 0000000000000000 [1232/1897]
audit: audit_lost=25791 audit_rate_limit=5 audit_backlog_limit=64
x25: 00000000ffffffa1 x24: ffff8008f2a3c010
audit: rate limit exceeded
x23: 0000000000000409 x22: ffff000009c8e000
x21: ffff8008f7a8b428 x20: ffff00000afae000
x19: ffff0000089ff000 x18: 0000000000000000
x17: 0000000000000000 x16: ffff0000082b7c9c
x15: 0000000000000000 x14: f1866f5b952aca46
x13: e35502e30d44349c x12: 0000000000000008
x11: 0000000000000008 x10: 0000000000000a30
x9 : ffff00000b7bbd00 x8 : ffff8008f2a98a90
x7 : ffff8008f27a9c90 x6 : 0000000000000001
x5 : 0000000000000000 x4 : 0000000000000001
x3 : 0000000000000000 x2 : 0000000000000006
x1 : ffff0000089ff8d0 x0 : 732a010310b9ed00
X7: 0xffff8008f27a9c10:
9c10 00000002 00000000 00000001 00000000 13110000 ffff0000 00000002 00208040
9c30 00000000 00000000 00000000 00000000 00000000 00000005 00000029 00000000
9c50 00051778 00000001 f27a8e00 ffff8008 00000005 00000000 00000078 00000078
9c70 00000078 00000000 09031d48 ffff0000 00100000 00000000 00400000 00000000
9c90 00000001 00000000 00000000 00000000 00000000 00000000 ffefb1a0 ffff8008
9cb0 f27a9ca8 ffff8008 00000000 00000000 b9d88037 00000173 1618a3eb 00000001
9cd0 870a792a 0000002e 16188fe6 00000001 0000242b 00000000 00000000 00000000
using random self ethernet address
9cf0 019a4646 00000000 000547f3 00000000 ecfd6c33 00000002 00000000
using random host ethernet address
00000000
X8: 0xffff8008f2a98a10:
8a10 00000000 00000000 f7788d00 ffff8008 00000001 00000000 00000000 00000000
8a30 eb218000 ffff8008 f2a98000 ffff8008 f2a98000 ffff8008 09885000 ffff0000
8a50 f34df480 ffff8008 00000000 00000000 f2a98648 ffff8008 09c8e000 ffff0000
8a70 fff2c800 ffff8008 09031d48 ffff0000 0b7bbd00 ffff0000 0b7bbd00 ffff0000
8a90 080861bc ffff0000 00000000 00000000 00000000 00000000 00000000 00000000
8ab0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
8ad0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
8af0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
X21: 0xffff8008f7a8b3a8:
b3a8 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
b3c8 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
b3e8 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
b408 00000000 00000000 00000000 00000000 00000000 00000000 00000001 00000000
b428 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
b448 0053004d 00540046 00300031 00010030 eb07b520 ffff8008 20011201 00000003
b468 e418d109 0104404e 00010302 00000000 eb07b558 ffff8008 eb07b558 ffff8008
b488 f7a8b488 ffff8008 f7a8b488 ffff8008 f7a8b300 ffff8008 00000000 00000000
X24: 0xffff8008f2a3bf90:
bf90 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bfb0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bfd0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bff0 00000000 00000000 00000000 00000000 f76c8010 ffff8008 f76c8010 ffff8008
c010 00000000 00000000 f2a3c018 ffff8008 f2a3c018 ffff8008 08a067dc ffff0000
c030 f2a5a000 ffff8008 091c3650 ffff0000 f716fd18 ffff8008 f716fe30 ffff8008
c050 f2ce4a30 ffff8008 00000000 00000005 00000000 00000000 095d1568 ffff0000
c070 f76c8010 ffff8008 f2ce4b00 ffff8008 095cac68 ffff0000 f2a5a028 ffff8008
X28: 0xffff8008f2a3bf90:
bf90 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bfb0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bfd0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bff0 00000000 00000000 00000000 00000000 f76c8010 ffff8008 f76c8010 ffff8008
c010 00000000 00000000 f2a3c018 ffff8008 f2a3c018 ffff8008 08a067dc ffff0000
c030 f2a5a000 ffff8008 091c3650 ffff0000 f716fd18 ffff8008 f716fe30 ffff8008
c050 f2ce4a30 ffff8008 00000000 00000005 00000000 00000000 095d1568 ffff0000
c070 f76c8010 ffff8008 f2ce4b00 ffff8008 095cac68 ffff0000 f2a5a028 ffff8008
Process irq/125-5b11000 (pid: 2457, stack limit = 0xffff00000b7b8000)
Call trace:
Exception stack(0xffff00000b7bba40 to 0xffff00000b7bbb80)
ba40: 732a010310b9ed00 ffff0000089ff8d0 0000000000000006 0000000000000000
ba60: 0000000000000001 0000000000000000 0000000000000001 ffff8008f27a9c90
ba80: ffff8008f2a98a90 ffff00000b7bbd00 0000000000000a30 0000000000000008
baa0: 0000000000000008 e35502e30d44349c f1866f5b952aca46 0000000000000000
bac0: ffff0000082b7c9c 0000000000000000 0000000000000000 ffff0000089ff000
bae0: ffff00000afae000 ffff8008f7a8b428 ffff000009c8e000 0000000000000409
bb00: ffff8008f2a3c010 00000000ffffffa1 0000000000000000 0000000000000001
bb20: ffff8008f2a3c010 ffff00000b7bbb80 ffff000008a032fc ffff00000b7bbb80
bb40: ffff0000089ffb3c 00000000800001c5 ffff00000b7bbb80 732a010310b9ed00
bb60: ffffffffffffffff ffff0000080f777c ffff00000b7bbb80 ffff0000089ffb3c
[<ffff0000089ffb3c>] composite_setup+0x44/0x1508
[<ffff000008a032fc>] android_setup+0xb8/0x13c
[<ffff0000089bd9a8>] cdns3_ep0_delegate_req+0x44/0x70
[<ffff0000089bdff4>] cdns3_check_ep0_interrupt_proceed+0x33c/0x654
[<ffff0000089bca44>] cdns3_device_thread_irq_handler+0x4b0/0x4bc
[<ffff0000089b77b4>] cdns3_thread_irq+0x48/0x68
[<ffff000008145bf0>] irq_thread_fn+0x28/0x88
[<ffff000008145e38>] irq_thread+0x13c/0x228
[<ffff0000080fed70>] kthread+0x104/0x130
[<ffff000008085064>] ret_from_fork+0x10/0x18
oops2:
composite_disconnect: Calling disconnect on a Gadget that is not connected
android_work: did not send uevent (0 0 (null))
init: Received control message 'stop' for 'adbd' from pid: 3359 (/vendor/bin/hw/android.hardware.usb@1.1-service.imx)
init: Sending signal 9 to service 'adbd' (pid 22343) process group...
------------[ cut here ]------------
audit: audit_lost=180038 audit_rate_limit=5 audit_backlog_limit=64
audit: rate limit exceeded
WARNING: CPU: 0 PID: 3468 at kernel_imx/drivers/usb/gadget/composite.c:2009 composite_disconnect+0x80/0x88
Modules linked in:
CPU: 0 PID: 3468 Comm: HWC-UEvent-Thre Not tainted 4.14.98-07846-g0b40a9b-dirty #16
Hardware name: Freescale i.MX8QM MEK (DT)
task: ffff8008f2349c00 task.stack: ffff00000b0a8000
PC is at composite_disconnect+0x80/0x88
LR is at composite_disconnect+0x80/0x88
pc : [<ffff0000089ff9b0>] lr : [<ffff0000089ff9b0>] pstate: 600001c5
sp : ffff000008003dd0
x29: ffff000008003dd0 x28: ffff8008f2349c00
x27: ffff000009885018 x26: ffff000008004000
Timeout for IPC response!
x25: ffff000009885018 x24: ffff000009c8e280
x23: ffff8008f2d98010 x22: 00000000000001c0
x21: ffff8008f2d98394 x20: ffff8008f2d98010
x19: 0000000000000000 x18: 0000e3956f4f075a
fxos8700 4-001e: i2c block read acc failed
x17: 0000e395735727e8 x16: ffff00000829f4d4
x15: ffffffffffffffff x14: 7463656e6e6f6320
x13: 746f6e2009090920 x12: 7369207461687420
x11: 7465676461472061 x10: 206e6f207463656e
x9 : 6e6f637369642067 x8 : ffff000009c8e280
x7 : ffff0000086ca6cc x6 : ffff000009f15e78
x5 : 0000000000000000 x4 : 0000000000000000
x3 : ffffffffffffffff x2 : c3f28b86000c3900
x1 : c3f28b86000c3900 x0 : 000000000000004e
X20: 0xffff8008f2d97f90:
7f90 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
7fb0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
libprocessgroup: Failed to kill process cgroup uid 0 pid 22343 in 215ms, 1 processes remain
7fd0
Timeout for IPC response!
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
using random self ethernet address
7ff0 00000000 00000000 00000000 00000000 f76c8010 ffff8008 f76c8010 ffff8008
8010 00000100 00000000 f2d98018 ffff8008 f2d98018 ffff8008 08a067dc
using random host ethernet address
ffff0000
8030 f206d800 ffff8008 091c3650 ffff0000 f7957b18 ffff8008 f7957730 ffff8008
8050 f716a630 ffff8008 00000000 00000005 00000000 00000000 095d1568 ffff0000
8070 f76c8010 ffff8008 f716a800 ffff8008 095cac68 ffff0000 f206d828 ffff8008
X21: 0xffff8008f2d98314:
8314 ffff8008 00000000 00000000 00000000 00000000 00000000 00000000 00000000
8334 00000000 00000000 00000000 00000000 00000000 08a04cf4 ffff0000 00000000
8354 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
8374 00000000 00000000 00000000 00001001 00000000 00000000 00000000 00000000
8394 e4bbe4bb 0f230000 ffff0000 0afae000 ffff0000 ae001000 00000000 f206d400
Timeout for IPC response!
83b4 ffff8008 00000000 00000000 f7957b18 ffff8008 f7957718 ffff8008 f7957018
83d4 ffff8008 f7957118 ffff8008 f7957618 ffff8008 f7957818 ffff8008 f7957918
83f4 ffff8008 f7957d18 ffff8008 00000000 00000000 00000000 00000000 00000000
X23: 0xffff8008f2d97f90:
7f90 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
7fb0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
7fd0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
7ff0 00000000 00000000 00000000 00000000 f76c8010 ffff8008 f76c8010 ffff8008
8010 00000100 00000000 f2d98018 ffff8008 f2d98018 ffff8008 08a067dc ffff0000
8030 f206d800 ffff8008 091c3650 ffff0000 f7957b18 ffff8008 f7957730 ffff8008
8050 f716a630 ffff8008 00000000 00000005 00000000 00000000 095d1568 ffff0000
8070 f76c8010 ffff8008 f716a800 ffff8008 095cac68 ffff0000 f206d828 ffff8008
X28: 0xffff8008f2349b80:
9b80 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
9ba0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
9bc0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
9be0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
9c00 00000022 00000000 ffffffff ffffffff 00010001 00000000 00000000 00000000
9c20 0b0a8000 ffff0000 00000002 00404040 00000000 00000000 00000000 00000000
9c40 00000001 00000000 00000001 00000000 001ebd44 00000001 f390b800 ffff8008
9c60 00000000 00000001 00000070 00000070 00000070 00000000 09031d48 ffff0000
Call trace:
Exception stack(0xffff000008003c90 to 0xffff000008003dd0)
3c80: 000000000000004e c3f28b86000c3900
3ca0: c3f28b86000c3900 ffffffffffffffff 0000000000000000 0000000000000000
3cc0: ffff000009f15e78 ffff0000086ca6cc ffff000009c8e280 6e6f637369642067
3ce0: 206e6f207463656e 7465676461472061 7369207461687420 746f6e2009090920
3d00: 7463656e6e6f6320 ffffffffffffffff ffff00000829f4d4 0000e395735727e8
3d20: 0000e3956f4f075a 0000000000000000 ffff8008f2d98010 ffff8008f2d98394
3d40: 00000000000001c0 ffff8008f2d98010 ffff000009c8e280 ffff000009885018
3d60: ffff000008004000 ffff000009885018 ffff8008f2349c00 ffff000008003dd0
3d80: ffff0000089ff9b0 ffff000008003dd0 ffff0000089ff9b0 00000000600001c5
3da0: ffff8008f33f2cd8 0000000000000000 0000ffffffffffff 0000000000000000
init: Received control message 'start' for 'adbd' from pid: 3359 (/vendor/bin/hw/android.hardware.usb@1.1-service.imx)
3dc0: ffff000008003dd0 ffff0000089ff9b0
[<ffff0000089ff9b0>] composite_disconnect+0x80/0x88
[<ffff000008a044d4>] android_disconnect+0x3c/0x68
[<ffff0000089ba9f8>] cdns3_device_irq_handler+0xfc/0x2c8
[<ffff0000089b84c0>] cdns3_irq+0x44/0x94
[<ffff00000814494c>] __handle_irq_event_percpu+0x60/0x24c
[<ffff000008144c0c>] handle_irq_event+0x58/0xc0
[<ffff00000814873c>] handle_fasteoi_irq+0x98/0x180
[<ffff000008143a10>] generic_handle_irq+0x24/0x38
[<ffff000008144170>] __handle_domain_irq+0x60/0xac
[<ffff0000080819c4>] gic_handle_irq+0xd4/0x17c
Signed-off-by: Peter Chen <peter.chen@nxp.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
2019-08-27 03:10:55 +08:00
|
|
|
gi->unbind = 0;
|
2012-12-24 04:10:24 +08:00
|
|
|
cdev->gadget = gadget;
|
|
|
|
set_gadget_data(gadget, cdev);
|
|
|
|
ret = composite_dev_prepare(composite, cdev);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
/* and now the gadget bind */
|
|
|
|
ret = -EINVAL;
|
|
|
|
|
|
|
|
if (list_empty(&gi->cdev.configs)) {
|
2014-05-05 07:39:34 +08:00
|
|
|
pr_err("Need at least one configuration in %s.\n",
|
2012-12-24 04:10:24 +08:00
|
|
|
gi->composite.name);
|
|
|
|
goto err_comp_cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
list_for_each_entry(c, &gi->cdev.configs, list) {
|
|
|
|
struct config_usb_cfg *cfg;
|
|
|
|
|
|
|
|
cfg = container_of(c, struct config_usb_cfg, c);
|
|
|
|
if (list_empty(&cfg->func_list)) {
|
2014-05-05 07:39:34 +08:00
|
|
|
pr_err("Config %s/%d of %s needs at least one function.\n",
|
2012-12-24 04:10:24 +08:00
|
|
|
c->label, c->bConfigurationValue,
|
|
|
|
gi->composite.name);
|
|
|
|
goto err_comp_cleanup;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* init all strings */
|
|
|
|
if (!list_empty(&gi->string_list)) {
|
|
|
|
struct gadget_strings *gs;
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
list_for_each_entry(gs, &gi->string_list, list) {
|
|
|
|
|
|
|
|
gi->gstrings[i] = &gs->stringtab_dev;
|
|
|
|
gs->stringtab_dev.strings = gs->strings;
|
|
|
|
gs->strings[USB_GADGET_MANUFACTURER_IDX].s =
|
|
|
|
gs->manufacturer;
|
|
|
|
gs->strings[USB_GADGET_PRODUCT_IDX].s = gs->product;
|
|
|
|
gs->strings[USB_GADGET_SERIAL_IDX].s = gs->serialnumber;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
gi->gstrings[i] = NULL;
|
|
|
|
s = usb_gstrings_attach(&gi->cdev, gi->gstrings,
|
|
|
|
USB_GADGET_FIRST_AVAIL_IDX);
|
2013-05-07 19:50:31 +08:00
|
|
|
if (IS_ERR(s)) {
|
|
|
|
ret = PTR_ERR(s);
|
2012-12-24 04:10:24 +08:00
|
|
|
goto err_comp_cleanup;
|
2013-05-07 19:50:31 +08:00
|
|
|
}
|
2012-12-24 04:10:24 +08:00
|
|
|
|
|
|
|
gi->cdev.desc.iManufacturer = s[USB_GADGET_MANUFACTURER_IDX].id;
|
|
|
|
gi->cdev.desc.iProduct = s[USB_GADGET_PRODUCT_IDX].id;
|
|
|
|
gi->cdev.desc.iSerialNumber = s[USB_GADGET_SERIAL_IDX].id;
|
|
|
|
}
|
|
|
|
|
2014-05-08 20:06:25 +08:00
|
|
|
if (gi->use_os_desc) {
|
|
|
|
cdev->use_os_string = true;
|
|
|
|
cdev->b_vendor_code = gi->b_vendor_code;
|
|
|
|
memcpy(cdev->qw_sign, gi->qw_sign, OS_STRING_QW_SIGN_LEN);
|
|
|
|
}
|
|
|
|
|
2015-07-09 15:18:48 +08:00
|
|
|
if (gadget_is_otg(gadget) && !otg_desc[0]) {
|
|
|
|
struct usb_descriptor_header *usb_desc;
|
|
|
|
|
|
|
|
usb_desc = usb_otg_descriptor_alloc(gadget);
|
|
|
|
if (!usb_desc) {
|
|
|
|
ret = -ENOMEM;
|
|
|
|
goto err_comp_cleanup;
|
|
|
|
}
|
|
|
|
usb_otg_descriptor_init(gadget, usb_desc);
|
|
|
|
otg_desc[0] = usb_desc;
|
|
|
|
otg_desc[1] = NULL;
|
|
|
|
}
|
|
|
|
|
2012-12-24 04:10:24 +08:00
|
|
|
/* Go through all configs, attach all functions */
|
|
|
|
list_for_each_entry(c, &gi->cdev.configs, list) {
|
|
|
|
struct config_usb_cfg *cfg;
|
|
|
|
struct usb_function *f;
|
|
|
|
struct usb_function *tmp;
|
|
|
|
struct gadget_config_name *cn;
|
|
|
|
|
2015-07-09 15:18:48 +08:00
|
|
|
if (gadget_is_otg(gadget))
|
|
|
|
c->descriptors = otg_desc;
|
|
|
|
|
2012-12-24 04:10:24 +08:00
|
|
|
cfg = container_of(c, struct config_usb_cfg, c);
|
|
|
|
if (!list_empty(&cfg->string_list)) {
|
|
|
|
i = 0;
|
|
|
|
list_for_each_entry(cn, &cfg->string_list, list) {
|
|
|
|
cfg->gstrings[i] = &cn->stringtab_dev;
|
|
|
|
cn->stringtab_dev.strings = &cn->strings;
|
|
|
|
cn->strings.s = cn->configuration;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
cfg->gstrings[i] = NULL;
|
|
|
|
s = usb_gstrings_attach(&gi->cdev, cfg->gstrings, 1);
|
2013-05-07 19:50:31 +08:00
|
|
|
if (IS_ERR(s)) {
|
|
|
|
ret = PTR_ERR(s);
|
2012-12-24 04:10:24 +08:00
|
|
|
goto err_comp_cleanup;
|
2013-05-07 19:50:31 +08:00
|
|
|
}
|
2012-12-24 04:10:24 +08:00
|
|
|
c->iConfiguration = s[0].id;
|
|
|
|
}
|
|
|
|
|
|
|
|
list_for_each_entry_safe(f, tmp, &cfg->func_list, list) {
|
|
|
|
list_del(&f->list);
|
|
|
|
ret = usb_add_function(c, f);
|
2013-08-08 15:43:28 +08:00
|
|
|
if (ret) {
|
|
|
|
list_add(&f->list, &cfg->func_list);
|
2012-12-24 04:10:24 +08:00
|
|
|
goto err_purge_funcs;
|
2013-08-08 15:43:28 +08:00
|
|
|
}
|
2012-12-24 04:10:24 +08:00
|
|
|
}
|
|
|
|
usb_ep_autoconfig_reset(cdev->gadget);
|
|
|
|
}
|
2014-05-08 20:06:26 +08:00
|
|
|
if (cdev->use_os_string) {
|
|
|
|
ret = composite_os_desc_req_prepare(cdev, gadget->ep0);
|
|
|
|
if (ret)
|
|
|
|
goto err_purge_funcs;
|
|
|
|
}
|
|
|
|
|
2012-12-24 04:10:24 +08:00
|
|
|
usb_ep_autoconfig_reset(cdev->gadget);
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
err_purge_funcs:
|
|
|
|
purge_configs_funcs(gi);
|
|
|
|
err_comp_cleanup:
|
|
|
|
composite_dev_cleanup(cdev);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void configfs_composite_unbind(struct usb_gadget *gadget)
|
|
|
|
{
|
|
|
|
struct usb_composite_dev *cdev;
|
|
|
|
struct gadget_info *gi;
|
usb: gadget: configfs: fix concurrent issue between composite APIs
We meet several NULL pointer issues if configfs_composite_unbind
and composite_setup (or composite_disconnect) are running together.
These issues occur when do the function switch stress test, the
configfs_compsoite_unbind is called from user mode by
echo "" to /sys/../UDC entry, and meanwhile, the setup interrupt
or disconnect interrupt occurs by hardware. The composite_setup
will get the cdev from get_gadget_data, but configfs_composite_unbind
will set gadget data as NULL, so the NULL pointer issue occurs.
This concurrent is hard to reproduce by native kernel, but can be
reproduced by android kernel.
In this commit, we introduce one spinlock belongs to structure
gadget_info since we can't use the same spinlock in usb_composite_dev
due to exclusive running together between composite_setup and
configfs_composite_unbind. And one bit flag 'unbind' to indicate the
code is at unbind routine, this bit is needed due to we release the
lock at during configfs_composite_unbind sometimes, and composite_setup
may be run at that time.
Several oops:
oops 1:
android_work: sent uevent USB_STATE=CONNECTED
configfs-gadget gadget: super-speed config #1: b
android_work: sent uevent USB_STATE=CONFIGURED
init: Received control message 'start' for 'adbd' from pid: 3515 (system_server)
Unable to handle kernel NULL pointer dereference at virtual address 0000002a
init: Received control message 'stop' for 'adbd' from pid: 3375 (/vendor/bin/hw/android.hardware.usb@1.1-servic)
Mem abort info:
Exception class = DABT (current EL), IL = 32 bits
SET = 0, FnV = 0
EA = 0, S1PTW = 0
Data abort info:
ISV = 0, ISS = 0x00000004
CM = 0, WnR = 0
user pgtable: 4k pages, 48-bit VAs, pgd = ffff8008f1b7f000
[000000000000002a] *pgd=0000000000000000
Internal error: Oops: 96000004 [#1] PREEMPT SMP
Modules linked in:
CPU: 4 PID: 2457 Comm: irq/125-5b11000 Not tainted 4.14.98-07846-g0b40a9b-dirty #16
Hardware name: Freescale i.MX8QM MEK (DT)
task: ffff8008f2a98000 task.stack: ffff00000b7b8000
PC is at composite_setup+0x44/0x1508
LR is at android_setup+0xb8/0x13c
pc : [<ffff0000089ffb3c>] lr : [<ffff000008a032fc>] pstate: 800001c5
sp : ffff00000b7bbb80
x29: ffff00000b7bbb80 x28: ffff8008f2a3c010
x27: 0000000000000001 x26: 0000000000000000 [1232/1897]
audit: audit_lost=25791 audit_rate_limit=5 audit_backlog_limit=64
x25: 00000000ffffffa1 x24: ffff8008f2a3c010
audit: rate limit exceeded
x23: 0000000000000409 x22: ffff000009c8e000
x21: ffff8008f7a8b428 x20: ffff00000afae000
x19: ffff0000089ff000 x18: 0000000000000000
x17: 0000000000000000 x16: ffff0000082b7c9c
x15: 0000000000000000 x14: f1866f5b952aca46
x13: e35502e30d44349c x12: 0000000000000008
x11: 0000000000000008 x10: 0000000000000a30
x9 : ffff00000b7bbd00 x8 : ffff8008f2a98a90
x7 : ffff8008f27a9c90 x6 : 0000000000000001
x5 : 0000000000000000 x4 : 0000000000000001
x3 : 0000000000000000 x2 : 0000000000000006
x1 : ffff0000089ff8d0 x0 : 732a010310b9ed00
X7: 0xffff8008f27a9c10:
9c10 00000002 00000000 00000001 00000000 13110000 ffff0000 00000002 00208040
9c30 00000000 00000000 00000000 00000000 00000000 00000005 00000029 00000000
9c50 00051778 00000001 f27a8e00 ffff8008 00000005 00000000 00000078 00000078
9c70 00000078 00000000 09031d48 ffff0000 00100000 00000000 00400000 00000000
9c90 00000001 00000000 00000000 00000000 00000000 00000000 ffefb1a0 ffff8008
9cb0 f27a9ca8 ffff8008 00000000 00000000 b9d88037 00000173 1618a3eb 00000001
9cd0 870a792a 0000002e 16188fe6 00000001 0000242b 00000000 00000000 00000000
using random self ethernet address
9cf0 019a4646 00000000 000547f3 00000000 ecfd6c33 00000002 00000000
using random host ethernet address
00000000
X8: 0xffff8008f2a98a10:
8a10 00000000 00000000 f7788d00 ffff8008 00000001 00000000 00000000 00000000
8a30 eb218000 ffff8008 f2a98000 ffff8008 f2a98000 ffff8008 09885000 ffff0000
8a50 f34df480 ffff8008 00000000 00000000 f2a98648 ffff8008 09c8e000 ffff0000
8a70 fff2c800 ffff8008 09031d48 ffff0000 0b7bbd00 ffff0000 0b7bbd00 ffff0000
8a90 080861bc ffff0000 00000000 00000000 00000000 00000000 00000000 00000000
8ab0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
8ad0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
8af0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
X21: 0xffff8008f7a8b3a8:
b3a8 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
b3c8 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
b3e8 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
b408 00000000 00000000 00000000 00000000 00000000 00000000 00000001 00000000
b428 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
b448 0053004d 00540046 00300031 00010030 eb07b520 ffff8008 20011201 00000003
b468 e418d109 0104404e 00010302 00000000 eb07b558 ffff8008 eb07b558 ffff8008
b488 f7a8b488 ffff8008 f7a8b488 ffff8008 f7a8b300 ffff8008 00000000 00000000
X24: 0xffff8008f2a3bf90:
bf90 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bfb0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bfd0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bff0 00000000 00000000 00000000 00000000 f76c8010 ffff8008 f76c8010 ffff8008
c010 00000000 00000000 f2a3c018 ffff8008 f2a3c018 ffff8008 08a067dc ffff0000
c030 f2a5a000 ffff8008 091c3650 ffff0000 f716fd18 ffff8008 f716fe30 ffff8008
c050 f2ce4a30 ffff8008 00000000 00000005 00000000 00000000 095d1568 ffff0000
c070 f76c8010 ffff8008 f2ce4b00 ffff8008 095cac68 ffff0000 f2a5a028 ffff8008
X28: 0xffff8008f2a3bf90:
bf90 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bfb0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bfd0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bff0 00000000 00000000 00000000 00000000 f76c8010 ffff8008 f76c8010 ffff8008
c010 00000000 00000000 f2a3c018 ffff8008 f2a3c018 ffff8008 08a067dc ffff0000
c030 f2a5a000 ffff8008 091c3650 ffff0000 f716fd18 ffff8008 f716fe30 ffff8008
c050 f2ce4a30 ffff8008 00000000 00000005 00000000 00000000 095d1568 ffff0000
c070 f76c8010 ffff8008 f2ce4b00 ffff8008 095cac68 ffff0000 f2a5a028 ffff8008
Process irq/125-5b11000 (pid: 2457, stack limit = 0xffff00000b7b8000)
Call trace:
Exception stack(0xffff00000b7bba40 to 0xffff00000b7bbb80)
ba40: 732a010310b9ed00 ffff0000089ff8d0 0000000000000006 0000000000000000
ba60: 0000000000000001 0000000000000000 0000000000000001 ffff8008f27a9c90
ba80: ffff8008f2a98a90 ffff00000b7bbd00 0000000000000a30 0000000000000008
baa0: 0000000000000008 e35502e30d44349c f1866f5b952aca46 0000000000000000
bac0: ffff0000082b7c9c 0000000000000000 0000000000000000 ffff0000089ff000
bae0: ffff00000afae000 ffff8008f7a8b428 ffff000009c8e000 0000000000000409
bb00: ffff8008f2a3c010 00000000ffffffa1 0000000000000000 0000000000000001
bb20: ffff8008f2a3c010 ffff00000b7bbb80 ffff000008a032fc ffff00000b7bbb80
bb40: ffff0000089ffb3c 00000000800001c5 ffff00000b7bbb80 732a010310b9ed00
bb60: ffffffffffffffff ffff0000080f777c ffff00000b7bbb80 ffff0000089ffb3c
[<ffff0000089ffb3c>] composite_setup+0x44/0x1508
[<ffff000008a032fc>] android_setup+0xb8/0x13c
[<ffff0000089bd9a8>] cdns3_ep0_delegate_req+0x44/0x70
[<ffff0000089bdff4>] cdns3_check_ep0_interrupt_proceed+0x33c/0x654
[<ffff0000089bca44>] cdns3_device_thread_irq_handler+0x4b0/0x4bc
[<ffff0000089b77b4>] cdns3_thread_irq+0x48/0x68
[<ffff000008145bf0>] irq_thread_fn+0x28/0x88
[<ffff000008145e38>] irq_thread+0x13c/0x228
[<ffff0000080fed70>] kthread+0x104/0x130
[<ffff000008085064>] ret_from_fork+0x10/0x18
oops2:
composite_disconnect: Calling disconnect on a Gadget that is not connected
android_work: did not send uevent (0 0 (null))
init: Received control message 'stop' for 'adbd' from pid: 3359 (/vendor/bin/hw/android.hardware.usb@1.1-service.imx)
init: Sending signal 9 to service 'adbd' (pid 22343) process group...
------------[ cut here ]------------
audit: audit_lost=180038 audit_rate_limit=5 audit_backlog_limit=64
audit: rate limit exceeded
WARNING: CPU: 0 PID: 3468 at kernel_imx/drivers/usb/gadget/composite.c:2009 composite_disconnect+0x80/0x88
Modules linked in:
CPU: 0 PID: 3468 Comm: HWC-UEvent-Thre Not tainted 4.14.98-07846-g0b40a9b-dirty #16
Hardware name: Freescale i.MX8QM MEK (DT)
task: ffff8008f2349c00 task.stack: ffff00000b0a8000
PC is at composite_disconnect+0x80/0x88
LR is at composite_disconnect+0x80/0x88
pc : [<ffff0000089ff9b0>] lr : [<ffff0000089ff9b0>] pstate: 600001c5
sp : ffff000008003dd0
x29: ffff000008003dd0 x28: ffff8008f2349c00
x27: ffff000009885018 x26: ffff000008004000
Timeout for IPC response!
x25: ffff000009885018 x24: ffff000009c8e280
x23: ffff8008f2d98010 x22: 00000000000001c0
x21: ffff8008f2d98394 x20: ffff8008f2d98010
x19: 0000000000000000 x18: 0000e3956f4f075a
fxos8700 4-001e: i2c block read acc failed
x17: 0000e395735727e8 x16: ffff00000829f4d4
x15: ffffffffffffffff x14: 7463656e6e6f6320
x13: 746f6e2009090920 x12: 7369207461687420
x11: 7465676461472061 x10: 206e6f207463656e
x9 : 6e6f637369642067 x8 : ffff000009c8e280
x7 : ffff0000086ca6cc x6 : ffff000009f15e78
x5 : 0000000000000000 x4 : 0000000000000000
x3 : ffffffffffffffff x2 : c3f28b86000c3900
x1 : c3f28b86000c3900 x0 : 000000000000004e
X20: 0xffff8008f2d97f90:
7f90 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
7fb0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
libprocessgroup: Failed to kill process cgroup uid 0 pid 22343 in 215ms, 1 processes remain
7fd0
Timeout for IPC response!
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
using random self ethernet address
7ff0 00000000 00000000 00000000 00000000 f76c8010 ffff8008 f76c8010 ffff8008
8010 00000100 00000000 f2d98018 ffff8008 f2d98018 ffff8008 08a067dc
using random host ethernet address
ffff0000
8030 f206d800 ffff8008 091c3650 ffff0000 f7957b18 ffff8008 f7957730 ffff8008
8050 f716a630 ffff8008 00000000 00000005 00000000 00000000 095d1568 ffff0000
8070 f76c8010 ffff8008 f716a800 ffff8008 095cac68 ffff0000 f206d828 ffff8008
X21: 0xffff8008f2d98314:
8314 ffff8008 00000000 00000000 00000000 00000000 00000000 00000000 00000000
8334 00000000 00000000 00000000 00000000 00000000 08a04cf4 ffff0000 00000000
8354 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
8374 00000000 00000000 00000000 00001001 00000000 00000000 00000000 00000000
8394 e4bbe4bb 0f230000 ffff0000 0afae000 ffff0000 ae001000 00000000 f206d400
Timeout for IPC response!
83b4 ffff8008 00000000 00000000 f7957b18 ffff8008 f7957718 ffff8008 f7957018
83d4 ffff8008 f7957118 ffff8008 f7957618 ffff8008 f7957818 ffff8008 f7957918
83f4 ffff8008 f7957d18 ffff8008 00000000 00000000 00000000 00000000 00000000
X23: 0xffff8008f2d97f90:
7f90 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
7fb0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
7fd0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
7ff0 00000000 00000000 00000000 00000000 f76c8010 ffff8008 f76c8010 ffff8008
8010 00000100 00000000 f2d98018 ffff8008 f2d98018 ffff8008 08a067dc ffff0000
8030 f206d800 ffff8008 091c3650 ffff0000 f7957b18 ffff8008 f7957730 ffff8008
8050 f716a630 ffff8008 00000000 00000005 00000000 00000000 095d1568 ffff0000
8070 f76c8010 ffff8008 f716a800 ffff8008 095cac68 ffff0000 f206d828 ffff8008
X28: 0xffff8008f2349b80:
9b80 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
9ba0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
9bc0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
9be0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
9c00 00000022 00000000 ffffffff ffffffff 00010001 00000000 00000000 00000000
9c20 0b0a8000 ffff0000 00000002 00404040 00000000 00000000 00000000 00000000
9c40 00000001 00000000 00000001 00000000 001ebd44 00000001 f390b800 ffff8008
9c60 00000000 00000001 00000070 00000070 00000070 00000000 09031d48 ffff0000
Call trace:
Exception stack(0xffff000008003c90 to 0xffff000008003dd0)
3c80: 000000000000004e c3f28b86000c3900
3ca0: c3f28b86000c3900 ffffffffffffffff 0000000000000000 0000000000000000
3cc0: ffff000009f15e78 ffff0000086ca6cc ffff000009c8e280 6e6f637369642067
3ce0: 206e6f207463656e 7465676461472061 7369207461687420 746f6e2009090920
3d00: 7463656e6e6f6320 ffffffffffffffff ffff00000829f4d4 0000e395735727e8
3d20: 0000e3956f4f075a 0000000000000000 ffff8008f2d98010 ffff8008f2d98394
3d40: 00000000000001c0 ffff8008f2d98010 ffff000009c8e280 ffff000009885018
3d60: ffff000008004000 ffff000009885018 ffff8008f2349c00 ffff000008003dd0
3d80: ffff0000089ff9b0 ffff000008003dd0 ffff0000089ff9b0 00000000600001c5
3da0: ffff8008f33f2cd8 0000000000000000 0000ffffffffffff 0000000000000000
init: Received control message 'start' for 'adbd' from pid: 3359 (/vendor/bin/hw/android.hardware.usb@1.1-service.imx)
3dc0: ffff000008003dd0 ffff0000089ff9b0
[<ffff0000089ff9b0>] composite_disconnect+0x80/0x88
[<ffff000008a044d4>] android_disconnect+0x3c/0x68
[<ffff0000089ba9f8>] cdns3_device_irq_handler+0xfc/0x2c8
[<ffff0000089b84c0>] cdns3_irq+0x44/0x94
[<ffff00000814494c>] __handle_irq_event_percpu+0x60/0x24c
[<ffff000008144c0c>] handle_irq_event+0x58/0xc0
[<ffff00000814873c>] handle_fasteoi_irq+0x98/0x180
[<ffff000008143a10>] generic_handle_irq+0x24/0x38
[<ffff000008144170>] __handle_domain_irq+0x60/0xac
[<ffff0000080819c4>] gic_handle_irq+0xd4/0x17c
Signed-off-by: Peter Chen <peter.chen@nxp.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
2019-08-27 03:10:55 +08:00
|
|
|
unsigned long flags;
|
2012-12-24 04:10:24 +08:00
|
|
|
|
|
|
|
/* the gi->lock is hold by the caller */
|
|
|
|
|
|
|
|
cdev = get_gadget_data(gadget);
|
|
|
|
gi = container_of(cdev, struct gadget_info, cdev);
|
usb: gadget: configfs: fix concurrent issue between composite APIs
We meet several NULL pointer issues if configfs_composite_unbind
and composite_setup (or composite_disconnect) are running together.
These issues occur when do the function switch stress test, the
configfs_compsoite_unbind is called from user mode by
echo "" to /sys/../UDC entry, and meanwhile, the setup interrupt
or disconnect interrupt occurs by hardware. The composite_setup
will get the cdev from get_gadget_data, but configfs_composite_unbind
will set gadget data as NULL, so the NULL pointer issue occurs.
This concurrent is hard to reproduce by native kernel, but can be
reproduced by android kernel.
In this commit, we introduce one spinlock belongs to structure
gadget_info since we can't use the same spinlock in usb_composite_dev
due to exclusive running together between composite_setup and
configfs_composite_unbind. And one bit flag 'unbind' to indicate the
code is at unbind routine, this bit is needed due to we release the
lock at during configfs_composite_unbind sometimes, and composite_setup
may be run at that time.
Several oops:
oops 1:
android_work: sent uevent USB_STATE=CONNECTED
configfs-gadget gadget: super-speed config #1: b
android_work: sent uevent USB_STATE=CONFIGURED
init: Received control message 'start' for 'adbd' from pid: 3515 (system_server)
Unable to handle kernel NULL pointer dereference at virtual address 0000002a
init: Received control message 'stop' for 'adbd' from pid: 3375 (/vendor/bin/hw/android.hardware.usb@1.1-servic)
Mem abort info:
Exception class = DABT (current EL), IL = 32 bits
SET = 0, FnV = 0
EA = 0, S1PTW = 0
Data abort info:
ISV = 0, ISS = 0x00000004
CM = 0, WnR = 0
user pgtable: 4k pages, 48-bit VAs, pgd = ffff8008f1b7f000
[000000000000002a] *pgd=0000000000000000
Internal error: Oops: 96000004 [#1] PREEMPT SMP
Modules linked in:
CPU: 4 PID: 2457 Comm: irq/125-5b11000 Not tainted 4.14.98-07846-g0b40a9b-dirty #16
Hardware name: Freescale i.MX8QM MEK (DT)
task: ffff8008f2a98000 task.stack: ffff00000b7b8000
PC is at composite_setup+0x44/0x1508
LR is at android_setup+0xb8/0x13c
pc : [<ffff0000089ffb3c>] lr : [<ffff000008a032fc>] pstate: 800001c5
sp : ffff00000b7bbb80
x29: ffff00000b7bbb80 x28: ffff8008f2a3c010
x27: 0000000000000001 x26: 0000000000000000 [1232/1897]
audit: audit_lost=25791 audit_rate_limit=5 audit_backlog_limit=64
x25: 00000000ffffffa1 x24: ffff8008f2a3c010
audit: rate limit exceeded
x23: 0000000000000409 x22: ffff000009c8e000
x21: ffff8008f7a8b428 x20: ffff00000afae000
x19: ffff0000089ff000 x18: 0000000000000000
x17: 0000000000000000 x16: ffff0000082b7c9c
x15: 0000000000000000 x14: f1866f5b952aca46
x13: e35502e30d44349c x12: 0000000000000008
x11: 0000000000000008 x10: 0000000000000a30
x9 : ffff00000b7bbd00 x8 : ffff8008f2a98a90
x7 : ffff8008f27a9c90 x6 : 0000000000000001
x5 : 0000000000000000 x4 : 0000000000000001
x3 : 0000000000000000 x2 : 0000000000000006
x1 : ffff0000089ff8d0 x0 : 732a010310b9ed00
X7: 0xffff8008f27a9c10:
9c10 00000002 00000000 00000001 00000000 13110000 ffff0000 00000002 00208040
9c30 00000000 00000000 00000000 00000000 00000000 00000005 00000029 00000000
9c50 00051778 00000001 f27a8e00 ffff8008 00000005 00000000 00000078 00000078
9c70 00000078 00000000 09031d48 ffff0000 00100000 00000000 00400000 00000000
9c90 00000001 00000000 00000000 00000000 00000000 00000000 ffefb1a0 ffff8008
9cb0 f27a9ca8 ffff8008 00000000 00000000 b9d88037 00000173 1618a3eb 00000001
9cd0 870a792a 0000002e 16188fe6 00000001 0000242b 00000000 00000000 00000000
using random self ethernet address
9cf0 019a4646 00000000 000547f3 00000000 ecfd6c33 00000002 00000000
using random host ethernet address
00000000
X8: 0xffff8008f2a98a10:
8a10 00000000 00000000 f7788d00 ffff8008 00000001 00000000 00000000 00000000
8a30 eb218000 ffff8008 f2a98000 ffff8008 f2a98000 ffff8008 09885000 ffff0000
8a50 f34df480 ffff8008 00000000 00000000 f2a98648 ffff8008 09c8e000 ffff0000
8a70 fff2c800 ffff8008 09031d48 ffff0000 0b7bbd00 ffff0000 0b7bbd00 ffff0000
8a90 080861bc ffff0000 00000000 00000000 00000000 00000000 00000000 00000000
8ab0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
8ad0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
8af0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
X21: 0xffff8008f7a8b3a8:
b3a8 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
b3c8 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
b3e8 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
b408 00000000 00000000 00000000 00000000 00000000 00000000 00000001 00000000
b428 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
b448 0053004d 00540046 00300031 00010030 eb07b520 ffff8008 20011201 00000003
b468 e418d109 0104404e 00010302 00000000 eb07b558 ffff8008 eb07b558 ffff8008
b488 f7a8b488 ffff8008 f7a8b488 ffff8008 f7a8b300 ffff8008 00000000 00000000
X24: 0xffff8008f2a3bf90:
bf90 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bfb0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bfd0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bff0 00000000 00000000 00000000 00000000 f76c8010 ffff8008 f76c8010 ffff8008
c010 00000000 00000000 f2a3c018 ffff8008 f2a3c018 ffff8008 08a067dc ffff0000
c030 f2a5a000 ffff8008 091c3650 ffff0000 f716fd18 ffff8008 f716fe30 ffff8008
c050 f2ce4a30 ffff8008 00000000 00000005 00000000 00000000 095d1568 ffff0000
c070 f76c8010 ffff8008 f2ce4b00 ffff8008 095cac68 ffff0000 f2a5a028 ffff8008
X28: 0xffff8008f2a3bf90:
bf90 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bfb0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bfd0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bff0 00000000 00000000 00000000 00000000 f76c8010 ffff8008 f76c8010 ffff8008
c010 00000000 00000000 f2a3c018 ffff8008 f2a3c018 ffff8008 08a067dc ffff0000
c030 f2a5a000 ffff8008 091c3650 ffff0000 f716fd18 ffff8008 f716fe30 ffff8008
c050 f2ce4a30 ffff8008 00000000 00000005 00000000 00000000 095d1568 ffff0000
c070 f76c8010 ffff8008 f2ce4b00 ffff8008 095cac68 ffff0000 f2a5a028 ffff8008
Process irq/125-5b11000 (pid: 2457, stack limit = 0xffff00000b7b8000)
Call trace:
Exception stack(0xffff00000b7bba40 to 0xffff00000b7bbb80)
ba40: 732a010310b9ed00 ffff0000089ff8d0 0000000000000006 0000000000000000
ba60: 0000000000000001 0000000000000000 0000000000000001 ffff8008f27a9c90
ba80: ffff8008f2a98a90 ffff00000b7bbd00 0000000000000a30 0000000000000008
baa0: 0000000000000008 e35502e30d44349c f1866f5b952aca46 0000000000000000
bac0: ffff0000082b7c9c 0000000000000000 0000000000000000 ffff0000089ff000
bae0: ffff00000afae000 ffff8008f7a8b428 ffff000009c8e000 0000000000000409
bb00: ffff8008f2a3c010 00000000ffffffa1 0000000000000000 0000000000000001
bb20: ffff8008f2a3c010 ffff00000b7bbb80 ffff000008a032fc ffff00000b7bbb80
bb40: ffff0000089ffb3c 00000000800001c5 ffff00000b7bbb80 732a010310b9ed00
bb60: ffffffffffffffff ffff0000080f777c ffff00000b7bbb80 ffff0000089ffb3c
[<ffff0000089ffb3c>] composite_setup+0x44/0x1508
[<ffff000008a032fc>] android_setup+0xb8/0x13c
[<ffff0000089bd9a8>] cdns3_ep0_delegate_req+0x44/0x70
[<ffff0000089bdff4>] cdns3_check_ep0_interrupt_proceed+0x33c/0x654
[<ffff0000089bca44>] cdns3_device_thread_irq_handler+0x4b0/0x4bc
[<ffff0000089b77b4>] cdns3_thread_irq+0x48/0x68
[<ffff000008145bf0>] irq_thread_fn+0x28/0x88
[<ffff000008145e38>] irq_thread+0x13c/0x228
[<ffff0000080fed70>] kthread+0x104/0x130
[<ffff000008085064>] ret_from_fork+0x10/0x18
oops2:
composite_disconnect: Calling disconnect on a Gadget that is not connected
android_work: did not send uevent (0 0 (null))
init: Received control message 'stop' for 'adbd' from pid: 3359 (/vendor/bin/hw/android.hardware.usb@1.1-service.imx)
init: Sending signal 9 to service 'adbd' (pid 22343) process group...
------------[ cut here ]------------
audit: audit_lost=180038 audit_rate_limit=5 audit_backlog_limit=64
audit: rate limit exceeded
WARNING: CPU: 0 PID: 3468 at kernel_imx/drivers/usb/gadget/composite.c:2009 composite_disconnect+0x80/0x88
Modules linked in:
CPU: 0 PID: 3468 Comm: HWC-UEvent-Thre Not tainted 4.14.98-07846-g0b40a9b-dirty #16
Hardware name: Freescale i.MX8QM MEK (DT)
task: ffff8008f2349c00 task.stack: ffff00000b0a8000
PC is at composite_disconnect+0x80/0x88
LR is at composite_disconnect+0x80/0x88
pc : [<ffff0000089ff9b0>] lr : [<ffff0000089ff9b0>] pstate: 600001c5
sp : ffff000008003dd0
x29: ffff000008003dd0 x28: ffff8008f2349c00
x27: ffff000009885018 x26: ffff000008004000
Timeout for IPC response!
x25: ffff000009885018 x24: ffff000009c8e280
x23: ffff8008f2d98010 x22: 00000000000001c0
x21: ffff8008f2d98394 x20: ffff8008f2d98010
x19: 0000000000000000 x18: 0000e3956f4f075a
fxos8700 4-001e: i2c block read acc failed
x17: 0000e395735727e8 x16: ffff00000829f4d4
x15: ffffffffffffffff x14: 7463656e6e6f6320
x13: 746f6e2009090920 x12: 7369207461687420
x11: 7465676461472061 x10: 206e6f207463656e
x9 : 6e6f637369642067 x8 : ffff000009c8e280
x7 : ffff0000086ca6cc x6 : ffff000009f15e78
x5 : 0000000000000000 x4 : 0000000000000000
x3 : ffffffffffffffff x2 : c3f28b86000c3900
x1 : c3f28b86000c3900 x0 : 000000000000004e
X20: 0xffff8008f2d97f90:
7f90 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
7fb0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
libprocessgroup: Failed to kill process cgroup uid 0 pid 22343 in 215ms, 1 processes remain
7fd0
Timeout for IPC response!
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
using random self ethernet address
7ff0 00000000 00000000 00000000 00000000 f76c8010 ffff8008 f76c8010 ffff8008
8010 00000100 00000000 f2d98018 ffff8008 f2d98018 ffff8008 08a067dc
using random host ethernet address
ffff0000
8030 f206d800 ffff8008 091c3650 ffff0000 f7957b18 ffff8008 f7957730 ffff8008
8050 f716a630 ffff8008 00000000 00000005 00000000 00000000 095d1568 ffff0000
8070 f76c8010 ffff8008 f716a800 ffff8008 095cac68 ffff0000 f206d828 ffff8008
X21: 0xffff8008f2d98314:
8314 ffff8008 00000000 00000000 00000000 00000000 00000000 00000000 00000000
8334 00000000 00000000 00000000 00000000 00000000 08a04cf4 ffff0000 00000000
8354 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
8374 00000000 00000000 00000000 00001001 00000000 00000000 00000000 00000000
8394 e4bbe4bb 0f230000 ffff0000 0afae000 ffff0000 ae001000 00000000 f206d400
Timeout for IPC response!
83b4 ffff8008 00000000 00000000 f7957b18 ffff8008 f7957718 ffff8008 f7957018
83d4 ffff8008 f7957118 ffff8008 f7957618 ffff8008 f7957818 ffff8008 f7957918
83f4 ffff8008 f7957d18 ffff8008 00000000 00000000 00000000 00000000 00000000
X23: 0xffff8008f2d97f90:
7f90 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
7fb0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
7fd0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
7ff0 00000000 00000000 00000000 00000000 f76c8010 ffff8008 f76c8010 ffff8008
8010 00000100 00000000 f2d98018 ffff8008 f2d98018 ffff8008 08a067dc ffff0000
8030 f206d800 ffff8008 091c3650 ffff0000 f7957b18 ffff8008 f7957730 ffff8008
8050 f716a630 ffff8008 00000000 00000005 00000000 00000000 095d1568 ffff0000
8070 f76c8010 ffff8008 f716a800 ffff8008 095cac68 ffff0000 f206d828 ffff8008
X28: 0xffff8008f2349b80:
9b80 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
9ba0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
9bc0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
9be0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
9c00 00000022 00000000 ffffffff ffffffff 00010001 00000000 00000000 00000000
9c20 0b0a8000 ffff0000 00000002 00404040 00000000 00000000 00000000 00000000
9c40 00000001 00000000 00000001 00000000 001ebd44 00000001 f390b800 ffff8008
9c60 00000000 00000001 00000070 00000070 00000070 00000000 09031d48 ffff0000
Call trace:
Exception stack(0xffff000008003c90 to 0xffff000008003dd0)
3c80: 000000000000004e c3f28b86000c3900
3ca0: c3f28b86000c3900 ffffffffffffffff 0000000000000000 0000000000000000
3cc0: ffff000009f15e78 ffff0000086ca6cc ffff000009c8e280 6e6f637369642067
3ce0: 206e6f207463656e 7465676461472061 7369207461687420 746f6e2009090920
3d00: 7463656e6e6f6320 ffffffffffffffff ffff00000829f4d4 0000e395735727e8
3d20: 0000e3956f4f075a 0000000000000000 ffff8008f2d98010 ffff8008f2d98394
3d40: 00000000000001c0 ffff8008f2d98010 ffff000009c8e280 ffff000009885018
3d60: ffff000008004000 ffff000009885018 ffff8008f2349c00 ffff000008003dd0
3d80: ffff0000089ff9b0 ffff000008003dd0 ffff0000089ff9b0 00000000600001c5
3da0: ffff8008f33f2cd8 0000000000000000 0000ffffffffffff 0000000000000000
init: Received control message 'start' for 'adbd' from pid: 3359 (/vendor/bin/hw/android.hardware.usb@1.1-service.imx)
3dc0: ffff000008003dd0 ffff0000089ff9b0
[<ffff0000089ff9b0>] composite_disconnect+0x80/0x88
[<ffff000008a044d4>] android_disconnect+0x3c/0x68
[<ffff0000089ba9f8>] cdns3_device_irq_handler+0xfc/0x2c8
[<ffff0000089b84c0>] cdns3_irq+0x44/0x94
[<ffff00000814494c>] __handle_irq_event_percpu+0x60/0x24c
[<ffff000008144c0c>] handle_irq_event+0x58/0xc0
[<ffff00000814873c>] handle_fasteoi_irq+0x98/0x180
[<ffff000008143a10>] generic_handle_irq+0x24/0x38
[<ffff000008144170>] __handle_domain_irq+0x60/0xac
[<ffff0000080819c4>] gic_handle_irq+0xd4/0x17c
Signed-off-by: Peter Chen <peter.chen@nxp.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
2019-08-27 03:10:55 +08:00
|
|
|
spin_lock_irqsave(&gi->spinlock, flags);
|
|
|
|
gi->unbind = 1;
|
|
|
|
spin_unlock_irqrestore(&gi->spinlock, flags);
|
2012-12-24 04:10:24 +08:00
|
|
|
|
2015-07-09 15:18:48 +08:00
|
|
|
kfree(otg_desc[0]);
|
|
|
|
otg_desc[0] = NULL;
|
2012-12-24 04:10:24 +08:00
|
|
|
purge_configs_funcs(gi);
|
|
|
|
composite_dev_cleanup(cdev);
|
|
|
|
usb_ep_autoconfig_reset(cdev->gadget);
|
usb: gadget: configfs: fix concurrent issue between composite APIs
We meet several NULL pointer issues if configfs_composite_unbind
and composite_setup (or composite_disconnect) are running together.
These issues occur when do the function switch stress test, the
configfs_compsoite_unbind is called from user mode by
echo "" to /sys/../UDC entry, and meanwhile, the setup interrupt
or disconnect interrupt occurs by hardware. The composite_setup
will get the cdev from get_gadget_data, but configfs_composite_unbind
will set gadget data as NULL, so the NULL pointer issue occurs.
This concurrent is hard to reproduce by native kernel, but can be
reproduced by android kernel.
In this commit, we introduce one spinlock belongs to structure
gadget_info since we can't use the same spinlock in usb_composite_dev
due to exclusive running together between composite_setup and
configfs_composite_unbind. And one bit flag 'unbind' to indicate the
code is at unbind routine, this bit is needed due to we release the
lock at during configfs_composite_unbind sometimes, and composite_setup
may be run at that time.
Several oops:
oops 1:
android_work: sent uevent USB_STATE=CONNECTED
configfs-gadget gadget: super-speed config #1: b
android_work: sent uevent USB_STATE=CONFIGURED
init: Received control message 'start' for 'adbd' from pid: 3515 (system_server)
Unable to handle kernel NULL pointer dereference at virtual address 0000002a
init: Received control message 'stop' for 'adbd' from pid: 3375 (/vendor/bin/hw/android.hardware.usb@1.1-servic)
Mem abort info:
Exception class = DABT (current EL), IL = 32 bits
SET = 0, FnV = 0
EA = 0, S1PTW = 0
Data abort info:
ISV = 0, ISS = 0x00000004
CM = 0, WnR = 0
user pgtable: 4k pages, 48-bit VAs, pgd = ffff8008f1b7f000
[000000000000002a] *pgd=0000000000000000
Internal error: Oops: 96000004 [#1] PREEMPT SMP
Modules linked in:
CPU: 4 PID: 2457 Comm: irq/125-5b11000 Not tainted 4.14.98-07846-g0b40a9b-dirty #16
Hardware name: Freescale i.MX8QM MEK (DT)
task: ffff8008f2a98000 task.stack: ffff00000b7b8000
PC is at composite_setup+0x44/0x1508
LR is at android_setup+0xb8/0x13c
pc : [<ffff0000089ffb3c>] lr : [<ffff000008a032fc>] pstate: 800001c5
sp : ffff00000b7bbb80
x29: ffff00000b7bbb80 x28: ffff8008f2a3c010
x27: 0000000000000001 x26: 0000000000000000 [1232/1897]
audit: audit_lost=25791 audit_rate_limit=5 audit_backlog_limit=64
x25: 00000000ffffffa1 x24: ffff8008f2a3c010
audit: rate limit exceeded
x23: 0000000000000409 x22: ffff000009c8e000
x21: ffff8008f7a8b428 x20: ffff00000afae000
x19: ffff0000089ff000 x18: 0000000000000000
x17: 0000000000000000 x16: ffff0000082b7c9c
x15: 0000000000000000 x14: f1866f5b952aca46
x13: e35502e30d44349c x12: 0000000000000008
x11: 0000000000000008 x10: 0000000000000a30
x9 : ffff00000b7bbd00 x8 : ffff8008f2a98a90
x7 : ffff8008f27a9c90 x6 : 0000000000000001
x5 : 0000000000000000 x4 : 0000000000000001
x3 : 0000000000000000 x2 : 0000000000000006
x1 : ffff0000089ff8d0 x0 : 732a010310b9ed00
X7: 0xffff8008f27a9c10:
9c10 00000002 00000000 00000001 00000000 13110000 ffff0000 00000002 00208040
9c30 00000000 00000000 00000000 00000000 00000000 00000005 00000029 00000000
9c50 00051778 00000001 f27a8e00 ffff8008 00000005 00000000 00000078 00000078
9c70 00000078 00000000 09031d48 ffff0000 00100000 00000000 00400000 00000000
9c90 00000001 00000000 00000000 00000000 00000000 00000000 ffefb1a0 ffff8008
9cb0 f27a9ca8 ffff8008 00000000 00000000 b9d88037 00000173 1618a3eb 00000001
9cd0 870a792a 0000002e 16188fe6 00000001 0000242b 00000000 00000000 00000000
using random self ethernet address
9cf0 019a4646 00000000 000547f3 00000000 ecfd6c33 00000002 00000000
using random host ethernet address
00000000
X8: 0xffff8008f2a98a10:
8a10 00000000 00000000 f7788d00 ffff8008 00000001 00000000 00000000 00000000
8a30 eb218000 ffff8008 f2a98000 ffff8008 f2a98000 ffff8008 09885000 ffff0000
8a50 f34df480 ffff8008 00000000 00000000 f2a98648 ffff8008 09c8e000 ffff0000
8a70 fff2c800 ffff8008 09031d48 ffff0000 0b7bbd00 ffff0000 0b7bbd00 ffff0000
8a90 080861bc ffff0000 00000000 00000000 00000000 00000000 00000000 00000000
8ab0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
8ad0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
8af0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
X21: 0xffff8008f7a8b3a8:
b3a8 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
b3c8 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
b3e8 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
b408 00000000 00000000 00000000 00000000 00000000 00000000 00000001 00000000
b428 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
b448 0053004d 00540046 00300031 00010030 eb07b520 ffff8008 20011201 00000003
b468 e418d109 0104404e 00010302 00000000 eb07b558 ffff8008 eb07b558 ffff8008
b488 f7a8b488 ffff8008 f7a8b488 ffff8008 f7a8b300 ffff8008 00000000 00000000
X24: 0xffff8008f2a3bf90:
bf90 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bfb0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bfd0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bff0 00000000 00000000 00000000 00000000 f76c8010 ffff8008 f76c8010 ffff8008
c010 00000000 00000000 f2a3c018 ffff8008 f2a3c018 ffff8008 08a067dc ffff0000
c030 f2a5a000 ffff8008 091c3650 ffff0000 f716fd18 ffff8008 f716fe30 ffff8008
c050 f2ce4a30 ffff8008 00000000 00000005 00000000 00000000 095d1568 ffff0000
c070 f76c8010 ffff8008 f2ce4b00 ffff8008 095cac68 ffff0000 f2a5a028 ffff8008
X28: 0xffff8008f2a3bf90:
bf90 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bfb0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bfd0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bff0 00000000 00000000 00000000 00000000 f76c8010 ffff8008 f76c8010 ffff8008
c010 00000000 00000000 f2a3c018 ffff8008 f2a3c018 ffff8008 08a067dc ffff0000
c030 f2a5a000 ffff8008 091c3650 ffff0000 f716fd18 ffff8008 f716fe30 ffff8008
c050 f2ce4a30 ffff8008 00000000 00000005 00000000 00000000 095d1568 ffff0000
c070 f76c8010 ffff8008 f2ce4b00 ffff8008 095cac68 ffff0000 f2a5a028 ffff8008
Process irq/125-5b11000 (pid: 2457, stack limit = 0xffff00000b7b8000)
Call trace:
Exception stack(0xffff00000b7bba40 to 0xffff00000b7bbb80)
ba40: 732a010310b9ed00 ffff0000089ff8d0 0000000000000006 0000000000000000
ba60: 0000000000000001 0000000000000000 0000000000000001 ffff8008f27a9c90
ba80: ffff8008f2a98a90 ffff00000b7bbd00 0000000000000a30 0000000000000008
baa0: 0000000000000008 e35502e30d44349c f1866f5b952aca46 0000000000000000
bac0: ffff0000082b7c9c 0000000000000000 0000000000000000 ffff0000089ff000
bae0: ffff00000afae000 ffff8008f7a8b428 ffff000009c8e000 0000000000000409
bb00: ffff8008f2a3c010 00000000ffffffa1 0000000000000000 0000000000000001
bb20: ffff8008f2a3c010 ffff00000b7bbb80 ffff000008a032fc ffff00000b7bbb80
bb40: ffff0000089ffb3c 00000000800001c5 ffff00000b7bbb80 732a010310b9ed00
bb60: ffffffffffffffff ffff0000080f777c ffff00000b7bbb80 ffff0000089ffb3c
[<ffff0000089ffb3c>] composite_setup+0x44/0x1508
[<ffff000008a032fc>] android_setup+0xb8/0x13c
[<ffff0000089bd9a8>] cdns3_ep0_delegate_req+0x44/0x70
[<ffff0000089bdff4>] cdns3_check_ep0_interrupt_proceed+0x33c/0x654
[<ffff0000089bca44>] cdns3_device_thread_irq_handler+0x4b0/0x4bc
[<ffff0000089b77b4>] cdns3_thread_irq+0x48/0x68
[<ffff000008145bf0>] irq_thread_fn+0x28/0x88
[<ffff000008145e38>] irq_thread+0x13c/0x228
[<ffff0000080fed70>] kthread+0x104/0x130
[<ffff000008085064>] ret_from_fork+0x10/0x18
oops2:
composite_disconnect: Calling disconnect on a Gadget that is not connected
android_work: did not send uevent (0 0 (null))
init: Received control message 'stop' for 'adbd' from pid: 3359 (/vendor/bin/hw/android.hardware.usb@1.1-service.imx)
init: Sending signal 9 to service 'adbd' (pid 22343) process group...
------------[ cut here ]------------
audit: audit_lost=180038 audit_rate_limit=5 audit_backlog_limit=64
audit: rate limit exceeded
WARNING: CPU: 0 PID: 3468 at kernel_imx/drivers/usb/gadget/composite.c:2009 composite_disconnect+0x80/0x88
Modules linked in:
CPU: 0 PID: 3468 Comm: HWC-UEvent-Thre Not tainted 4.14.98-07846-g0b40a9b-dirty #16
Hardware name: Freescale i.MX8QM MEK (DT)
task: ffff8008f2349c00 task.stack: ffff00000b0a8000
PC is at composite_disconnect+0x80/0x88
LR is at composite_disconnect+0x80/0x88
pc : [<ffff0000089ff9b0>] lr : [<ffff0000089ff9b0>] pstate: 600001c5
sp : ffff000008003dd0
x29: ffff000008003dd0 x28: ffff8008f2349c00
x27: ffff000009885018 x26: ffff000008004000
Timeout for IPC response!
x25: ffff000009885018 x24: ffff000009c8e280
x23: ffff8008f2d98010 x22: 00000000000001c0
x21: ffff8008f2d98394 x20: ffff8008f2d98010
x19: 0000000000000000 x18: 0000e3956f4f075a
fxos8700 4-001e: i2c block read acc failed
x17: 0000e395735727e8 x16: ffff00000829f4d4
x15: ffffffffffffffff x14: 7463656e6e6f6320
x13: 746f6e2009090920 x12: 7369207461687420
x11: 7465676461472061 x10: 206e6f207463656e
x9 : 6e6f637369642067 x8 : ffff000009c8e280
x7 : ffff0000086ca6cc x6 : ffff000009f15e78
x5 : 0000000000000000 x4 : 0000000000000000
x3 : ffffffffffffffff x2 : c3f28b86000c3900
x1 : c3f28b86000c3900 x0 : 000000000000004e
X20: 0xffff8008f2d97f90:
7f90 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
7fb0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
libprocessgroup: Failed to kill process cgroup uid 0 pid 22343 in 215ms, 1 processes remain
7fd0
Timeout for IPC response!
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
using random self ethernet address
7ff0 00000000 00000000 00000000 00000000 f76c8010 ffff8008 f76c8010 ffff8008
8010 00000100 00000000 f2d98018 ffff8008 f2d98018 ffff8008 08a067dc
using random host ethernet address
ffff0000
8030 f206d800 ffff8008 091c3650 ffff0000 f7957b18 ffff8008 f7957730 ffff8008
8050 f716a630 ffff8008 00000000 00000005 00000000 00000000 095d1568 ffff0000
8070 f76c8010 ffff8008 f716a800 ffff8008 095cac68 ffff0000 f206d828 ffff8008
X21: 0xffff8008f2d98314:
8314 ffff8008 00000000 00000000 00000000 00000000 00000000 00000000 00000000
8334 00000000 00000000 00000000 00000000 00000000 08a04cf4 ffff0000 00000000
8354 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
8374 00000000 00000000 00000000 00001001 00000000 00000000 00000000 00000000
8394 e4bbe4bb 0f230000 ffff0000 0afae000 ffff0000 ae001000 00000000 f206d400
Timeout for IPC response!
83b4 ffff8008 00000000 00000000 f7957b18 ffff8008 f7957718 ffff8008 f7957018
83d4 ffff8008 f7957118 ffff8008 f7957618 ffff8008 f7957818 ffff8008 f7957918
83f4 ffff8008 f7957d18 ffff8008 00000000 00000000 00000000 00000000 00000000
X23: 0xffff8008f2d97f90:
7f90 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
7fb0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
7fd0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
7ff0 00000000 00000000 00000000 00000000 f76c8010 ffff8008 f76c8010 ffff8008
8010 00000100 00000000 f2d98018 ffff8008 f2d98018 ffff8008 08a067dc ffff0000
8030 f206d800 ffff8008 091c3650 ffff0000 f7957b18 ffff8008 f7957730 ffff8008
8050 f716a630 ffff8008 00000000 00000005 00000000 00000000 095d1568 ffff0000
8070 f76c8010 ffff8008 f716a800 ffff8008 095cac68 ffff0000 f206d828 ffff8008
X28: 0xffff8008f2349b80:
9b80 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
9ba0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
9bc0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
9be0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
9c00 00000022 00000000 ffffffff ffffffff 00010001 00000000 00000000 00000000
9c20 0b0a8000 ffff0000 00000002 00404040 00000000 00000000 00000000 00000000
9c40 00000001 00000000 00000001 00000000 001ebd44 00000001 f390b800 ffff8008
9c60 00000000 00000001 00000070 00000070 00000070 00000000 09031d48 ffff0000
Call trace:
Exception stack(0xffff000008003c90 to 0xffff000008003dd0)
3c80: 000000000000004e c3f28b86000c3900
3ca0: c3f28b86000c3900 ffffffffffffffff 0000000000000000 0000000000000000
3cc0: ffff000009f15e78 ffff0000086ca6cc ffff000009c8e280 6e6f637369642067
3ce0: 206e6f207463656e 7465676461472061 7369207461687420 746f6e2009090920
3d00: 7463656e6e6f6320 ffffffffffffffff ffff00000829f4d4 0000e395735727e8
3d20: 0000e3956f4f075a 0000000000000000 ffff8008f2d98010 ffff8008f2d98394
3d40: 00000000000001c0 ffff8008f2d98010 ffff000009c8e280 ffff000009885018
3d60: ffff000008004000 ffff000009885018 ffff8008f2349c00 ffff000008003dd0
3d80: ffff0000089ff9b0 ffff000008003dd0 ffff0000089ff9b0 00000000600001c5
3da0: ffff8008f33f2cd8 0000000000000000 0000ffffffffffff 0000000000000000
init: Received control message 'start' for 'adbd' from pid: 3359 (/vendor/bin/hw/android.hardware.usb@1.1-service.imx)
3dc0: ffff000008003dd0 ffff0000089ff9b0
[<ffff0000089ff9b0>] composite_disconnect+0x80/0x88
[<ffff000008a044d4>] android_disconnect+0x3c/0x68
[<ffff0000089ba9f8>] cdns3_device_irq_handler+0xfc/0x2c8
[<ffff0000089b84c0>] cdns3_irq+0x44/0x94
[<ffff00000814494c>] __handle_irq_event_percpu+0x60/0x24c
[<ffff000008144c0c>] handle_irq_event+0x58/0xc0
[<ffff00000814873c>] handle_fasteoi_irq+0x98/0x180
[<ffff000008143a10>] generic_handle_irq+0x24/0x38
[<ffff000008144170>] __handle_domain_irq+0x60/0xac
[<ffff0000080819c4>] gic_handle_irq+0xd4/0x17c
Signed-off-by: Peter Chen <peter.chen@nxp.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
2019-08-27 03:10:55 +08:00
|
|
|
spin_lock_irqsave(&gi->spinlock, flags);
|
2012-12-24 04:10:24 +08:00
|
|
|
cdev->gadget = NULL;
|
|
|
|
set_gadget_data(gadget, NULL);
|
usb: gadget: configfs: fix concurrent issue between composite APIs
We meet several NULL pointer issues if configfs_composite_unbind
and composite_setup (or composite_disconnect) are running together.
These issues occur when do the function switch stress test, the
configfs_compsoite_unbind is called from user mode by
echo "" to /sys/../UDC entry, and meanwhile, the setup interrupt
or disconnect interrupt occurs by hardware. The composite_setup
will get the cdev from get_gadget_data, but configfs_composite_unbind
will set gadget data as NULL, so the NULL pointer issue occurs.
This concurrent is hard to reproduce by native kernel, but can be
reproduced by android kernel.
In this commit, we introduce one spinlock belongs to structure
gadget_info since we can't use the same spinlock in usb_composite_dev
due to exclusive running together between composite_setup and
configfs_composite_unbind. And one bit flag 'unbind' to indicate the
code is at unbind routine, this bit is needed due to we release the
lock at during configfs_composite_unbind sometimes, and composite_setup
may be run at that time.
Several oops:
oops 1:
android_work: sent uevent USB_STATE=CONNECTED
configfs-gadget gadget: super-speed config #1: b
android_work: sent uevent USB_STATE=CONFIGURED
init: Received control message 'start' for 'adbd' from pid: 3515 (system_server)
Unable to handle kernel NULL pointer dereference at virtual address 0000002a
init: Received control message 'stop' for 'adbd' from pid: 3375 (/vendor/bin/hw/android.hardware.usb@1.1-servic)
Mem abort info:
Exception class = DABT (current EL), IL = 32 bits
SET = 0, FnV = 0
EA = 0, S1PTW = 0
Data abort info:
ISV = 0, ISS = 0x00000004
CM = 0, WnR = 0
user pgtable: 4k pages, 48-bit VAs, pgd = ffff8008f1b7f000
[000000000000002a] *pgd=0000000000000000
Internal error: Oops: 96000004 [#1] PREEMPT SMP
Modules linked in:
CPU: 4 PID: 2457 Comm: irq/125-5b11000 Not tainted 4.14.98-07846-g0b40a9b-dirty #16
Hardware name: Freescale i.MX8QM MEK (DT)
task: ffff8008f2a98000 task.stack: ffff00000b7b8000
PC is at composite_setup+0x44/0x1508
LR is at android_setup+0xb8/0x13c
pc : [<ffff0000089ffb3c>] lr : [<ffff000008a032fc>] pstate: 800001c5
sp : ffff00000b7bbb80
x29: ffff00000b7bbb80 x28: ffff8008f2a3c010
x27: 0000000000000001 x26: 0000000000000000 [1232/1897]
audit: audit_lost=25791 audit_rate_limit=5 audit_backlog_limit=64
x25: 00000000ffffffa1 x24: ffff8008f2a3c010
audit: rate limit exceeded
x23: 0000000000000409 x22: ffff000009c8e000
x21: ffff8008f7a8b428 x20: ffff00000afae000
x19: ffff0000089ff000 x18: 0000000000000000
x17: 0000000000000000 x16: ffff0000082b7c9c
x15: 0000000000000000 x14: f1866f5b952aca46
x13: e35502e30d44349c x12: 0000000000000008
x11: 0000000000000008 x10: 0000000000000a30
x9 : ffff00000b7bbd00 x8 : ffff8008f2a98a90
x7 : ffff8008f27a9c90 x6 : 0000000000000001
x5 : 0000000000000000 x4 : 0000000000000001
x3 : 0000000000000000 x2 : 0000000000000006
x1 : ffff0000089ff8d0 x0 : 732a010310b9ed00
X7: 0xffff8008f27a9c10:
9c10 00000002 00000000 00000001 00000000 13110000 ffff0000 00000002 00208040
9c30 00000000 00000000 00000000 00000000 00000000 00000005 00000029 00000000
9c50 00051778 00000001 f27a8e00 ffff8008 00000005 00000000 00000078 00000078
9c70 00000078 00000000 09031d48 ffff0000 00100000 00000000 00400000 00000000
9c90 00000001 00000000 00000000 00000000 00000000 00000000 ffefb1a0 ffff8008
9cb0 f27a9ca8 ffff8008 00000000 00000000 b9d88037 00000173 1618a3eb 00000001
9cd0 870a792a 0000002e 16188fe6 00000001 0000242b 00000000 00000000 00000000
using random self ethernet address
9cf0 019a4646 00000000 000547f3 00000000 ecfd6c33 00000002 00000000
using random host ethernet address
00000000
X8: 0xffff8008f2a98a10:
8a10 00000000 00000000 f7788d00 ffff8008 00000001 00000000 00000000 00000000
8a30 eb218000 ffff8008 f2a98000 ffff8008 f2a98000 ffff8008 09885000 ffff0000
8a50 f34df480 ffff8008 00000000 00000000 f2a98648 ffff8008 09c8e000 ffff0000
8a70 fff2c800 ffff8008 09031d48 ffff0000 0b7bbd00 ffff0000 0b7bbd00 ffff0000
8a90 080861bc ffff0000 00000000 00000000 00000000 00000000 00000000 00000000
8ab0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
8ad0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
8af0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
X21: 0xffff8008f7a8b3a8:
b3a8 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
b3c8 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
b3e8 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
b408 00000000 00000000 00000000 00000000 00000000 00000000 00000001 00000000
b428 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
b448 0053004d 00540046 00300031 00010030 eb07b520 ffff8008 20011201 00000003
b468 e418d109 0104404e 00010302 00000000 eb07b558 ffff8008 eb07b558 ffff8008
b488 f7a8b488 ffff8008 f7a8b488 ffff8008 f7a8b300 ffff8008 00000000 00000000
X24: 0xffff8008f2a3bf90:
bf90 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bfb0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bfd0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bff0 00000000 00000000 00000000 00000000 f76c8010 ffff8008 f76c8010 ffff8008
c010 00000000 00000000 f2a3c018 ffff8008 f2a3c018 ffff8008 08a067dc ffff0000
c030 f2a5a000 ffff8008 091c3650 ffff0000 f716fd18 ffff8008 f716fe30 ffff8008
c050 f2ce4a30 ffff8008 00000000 00000005 00000000 00000000 095d1568 ffff0000
c070 f76c8010 ffff8008 f2ce4b00 ffff8008 095cac68 ffff0000 f2a5a028 ffff8008
X28: 0xffff8008f2a3bf90:
bf90 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bfb0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bfd0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bff0 00000000 00000000 00000000 00000000 f76c8010 ffff8008 f76c8010 ffff8008
c010 00000000 00000000 f2a3c018 ffff8008 f2a3c018 ffff8008 08a067dc ffff0000
c030 f2a5a000 ffff8008 091c3650 ffff0000 f716fd18 ffff8008 f716fe30 ffff8008
c050 f2ce4a30 ffff8008 00000000 00000005 00000000 00000000 095d1568 ffff0000
c070 f76c8010 ffff8008 f2ce4b00 ffff8008 095cac68 ffff0000 f2a5a028 ffff8008
Process irq/125-5b11000 (pid: 2457, stack limit = 0xffff00000b7b8000)
Call trace:
Exception stack(0xffff00000b7bba40 to 0xffff00000b7bbb80)
ba40: 732a010310b9ed00 ffff0000089ff8d0 0000000000000006 0000000000000000
ba60: 0000000000000001 0000000000000000 0000000000000001 ffff8008f27a9c90
ba80: ffff8008f2a98a90 ffff00000b7bbd00 0000000000000a30 0000000000000008
baa0: 0000000000000008 e35502e30d44349c f1866f5b952aca46 0000000000000000
bac0: ffff0000082b7c9c 0000000000000000 0000000000000000 ffff0000089ff000
bae0: ffff00000afae000 ffff8008f7a8b428 ffff000009c8e000 0000000000000409
bb00: ffff8008f2a3c010 00000000ffffffa1 0000000000000000 0000000000000001
bb20: ffff8008f2a3c010 ffff00000b7bbb80 ffff000008a032fc ffff00000b7bbb80
bb40: ffff0000089ffb3c 00000000800001c5 ffff00000b7bbb80 732a010310b9ed00
bb60: ffffffffffffffff ffff0000080f777c ffff00000b7bbb80 ffff0000089ffb3c
[<ffff0000089ffb3c>] composite_setup+0x44/0x1508
[<ffff000008a032fc>] android_setup+0xb8/0x13c
[<ffff0000089bd9a8>] cdns3_ep0_delegate_req+0x44/0x70
[<ffff0000089bdff4>] cdns3_check_ep0_interrupt_proceed+0x33c/0x654
[<ffff0000089bca44>] cdns3_device_thread_irq_handler+0x4b0/0x4bc
[<ffff0000089b77b4>] cdns3_thread_irq+0x48/0x68
[<ffff000008145bf0>] irq_thread_fn+0x28/0x88
[<ffff000008145e38>] irq_thread+0x13c/0x228
[<ffff0000080fed70>] kthread+0x104/0x130
[<ffff000008085064>] ret_from_fork+0x10/0x18
oops2:
composite_disconnect: Calling disconnect on a Gadget that is not connected
android_work: did not send uevent (0 0 (null))
init: Received control message 'stop' for 'adbd' from pid: 3359 (/vendor/bin/hw/android.hardware.usb@1.1-service.imx)
init: Sending signal 9 to service 'adbd' (pid 22343) process group...
------------[ cut here ]------------
audit: audit_lost=180038 audit_rate_limit=5 audit_backlog_limit=64
audit: rate limit exceeded
WARNING: CPU: 0 PID: 3468 at kernel_imx/drivers/usb/gadget/composite.c:2009 composite_disconnect+0x80/0x88
Modules linked in:
CPU: 0 PID: 3468 Comm: HWC-UEvent-Thre Not tainted 4.14.98-07846-g0b40a9b-dirty #16
Hardware name: Freescale i.MX8QM MEK (DT)
task: ffff8008f2349c00 task.stack: ffff00000b0a8000
PC is at composite_disconnect+0x80/0x88
LR is at composite_disconnect+0x80/0x88
pc : [<ffff0000089ff9b0>] lr : [<ffff0000089ff9b0>] pstate: 600001c5
sp : ffff000008003dd0
x29: ffff000008003dd0 x28: ffff8008f2349c00
x27: ffff000009885018 x26: ffff000008004000
Timeout for IPC response!
x25: ffff000009885018 x24: ffff000009c8e280
x23: ffff8008f2d98010 x22: 00000000000001c0
x21: ffff8008f2d98394 x20: ffff8008f2d98010
x19: 0000000000000000 x18: 0000e3956f4f075a
fxos8700 4-001e: i2c block read acc failed
x17: 0000e395735727e8 x16: ffff00000829f4d4
x15: ffffffffffffffff x14: 7463656e6e6f6320
x13: 746f6e2009090920 x12: 7369207461687420
x11: 7465676461472061 x10: 206e6f207463656e
x9 : 6e6f637369642067 x8 : ffff000009c8e280
x7 : ffff0000086ca6cc x6 : ffff000009f15e78
x5 : 0000000000000000 x4 : 0000000000000000
x3 : ffffffffffffffff x2 : c3f28b86000c3900
x1 : c3f28b86000c3900 x0 : 000000000000004e
X20: 0xffff8008f2d97f90:
7f90 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
7fb0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
libprocessgroup: Failed to kill process cgroup uid 0 pid 22343 in 215ms, 1 processes remain
7fd0
Timeout for IPC response!
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
using random self ethernet address
7ff0 00000000 00000000 00000000 00000000 f76c8010 ffff8008 f76c8010 ffff8008
8010 00000100 00000000 f2d98018 ffff8008 f2d98018 ffff8008 08a067dc
using random host ethernet address
ffff0000
8030 f206d800 ffff8008 091c3650 ffff0000 f7957b18 ffff8008 f7957730 ffff8008
8050 f716a630 ffff8008 00000000 00000005 00000000 00000000 095d1568 ffff0000
8070 f76c8010 ffff8008 f716a800 ffff8008 095cac68 ffff0000 f206d828 ffff8008
X21: 0xffff8008f2d98314:
8314 ffff8008 00000000 00000000 00000000 00000000 00000000 00000000 00000000
8334 00000000 00000000 00000000 00000000 00000000 08a04cf4 ffff0000 00000000
8354 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
8374 00000000 00000000 00000000 00001001 00000000 00000000 00000000 00000000
8394 e4bbe4bb 0f230000 ffff0000 0afae000 ffff0000 ae001000 00000000 f206d400
Timeout for IPC response!
83b4 ffff8008 00000000 00000000 f7957b18 ffff8008 f7957718 ffff8008 f7957018
83d4 ffff8008 f7957118 ffff8008 f7957618 ffff8008 f7957818 ffff8008 f7957918
83f4 ffff8008 f7957d18 ffff8008 00000000 00000000 00000000 00000000 00000000
X23: 0xffff8008f2d97f90:
7f90 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
7fb0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
7fd0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
7ff0 00000000 00000000 00000000 00000000 f76c8010 ffff8008 f76c8010 ffff8008
8010 00000100 00000000 f2d98018 ffff8008 f2d98018 ffff8008 08a067dc ffff0000
8030 f206d800 ffff8008 091c3650 ffff0000 f7957b18 ffff8008 f7957730 ffff8008
8050 f716a630 ffff8008 00000000 00000005 00000000 00000000 095d1568 ffff0000
8070 f76c8010 ffff8008 f716a800 ffff8008 095cac68 ffff0000 f206d828 ffff8008
X28: 0xffff8008f2349b80:
9b80 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
9ba0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
9bc0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
9be0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
9c00 00000022 00000000 ffffffff ffffffff 00010001 00000000 00000000 00000000
9c20 0b0a8000 ffff0000 00000002 00404040 00000000 00000000 00000000 00000000
9c40 00000001 00000000 00000001 00000000 001ebd44 00000001 f390b800 ffff8008
9c60 00000000 00000001 00000070 00000070 00000070 00000000 09031d48 ffff0000
Call trace:
Exception stack(0xffff000008003c90 to 0xffff000008003dd0)
3c80: 000000000000004e c3f28b86000c3900
3ca0: c3f28b86000c3900 ffffffffffffffff 0000000000000000 0000000000000000
3cc0: ffff000009f15e78 ffff0000086ca6cc ffff000009c8e280 6e6f637369642067
3ce0: 206e6f207463656e 7465676461472061 7369207461687420 746f6e2009090920
3d00: 7463656e6e6f6320 ffffffffffffffff ffff00000829f4d4 0000e395735727e8
3d20: 0000e3956f4f075a 0000000000000000 ffff8008f2d98010 ffff8008f2d98394
3d40: 00000000000001c0 ffff8008f2d98010 ffff000009c8e280 ffff000009885018
3d60: ffff000008004000 ffff000009885018 ffff8008f2349c00 ffff000008003dd0
3d80: ffff0000089ff9b0 ffff000008003dd0 ffff0000089ff9b0 00000000600001c5
3da0: ffff8008f33f2cd8 0000000000000000 0000ffffffffffff 0000000000000000
init: Received control message 'start' for 'adbd' from pid: 3359 (/vendor/bin/hw/android.hardware.usb@1.1-service.imx)
3dc0: ffff000008003dd0 ffff0000089ff9b0
[<ffff0000089ff9b0>] composite_disconnect+0x80/0x88
[<ffff000008a044d4>] android_disconnect+0x3c/0x68
[<ffff0000089ba9f8>] cdns3_device_irq_handler+0xfc/0x2c8
[<ffff0000089b84c0>] cdns3_irq+0x44/0x94
[<ffff00000814494c>] __handle_irq_event_percpu+0x60/0x24c
[<ffff000008144c0c>] handle_irq_event+0x58/0xc0
[<ffff00000814873c>] handle_fasteoi_irq+0x98/0x180
[<ffff000008143a10>] generic_handle_irq+0x24/0x38
[<ffff000008144170>] __handle_domain_irq+0x60/0xac
[<ffff0000080819c4>] gic_handle_irq+0xd4/0x17c
Signed-off-by: Peter Chen <peter.chen@nxp.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
2019-08-27 03:10:55 +08:00
|
|
|
spin_unlock_irqrestore(&gi->spinlock, flags);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int configfs_composite_setup(struct usb_gadget *gadget,
|
|
|
|
const struct usb_ctrlrequest *ctrl)
|
|
|
|
{
|
|
|
|
struct usb_composite_dev *cdev;
|
|
|
|
struct gadget_info *gi;
|
|
|
|
unsigned long flags;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
cdev = get_gadget_data(gadget);
|
|
|
|
if (!cdev)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
gi = container_of(cdev, struct gadget_info, cdev);
|
|
|
|
spin_lock_irqsave(&gi->spinlock, flags);
|
|
|
|
cdev = get_gadget_data(gadget);
|
|
|
|
if (!cdev || gi->unbind) {
|
|
|
|
spin_unlock_irqrestore(&gi->spinlock, flags);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = composite_setup(gadget, ctrl);
|
|
|
|
spin_unlock_irqrestore(&gi->spinlock, flags);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void configfs_composite_disconnect(struct usb_gadget *gadget)
|
|
|
|
{
|
|
|
|
struct usb_composite_dev *cdev;
|
|
|
|
struct gadget_info *gi;
|
|
|
|
unsigned long flags;
|
|
|
|
|
|
|
|
cdev = get_gadget_data(gadget);
|
|
|
|
if (!cdev)
|
|
|
|
return;
|
|
|
|
|
|
|
|
gi = container_of(cdev, struct gadget_info, cdev);
|
|
|
|
spin_lock_irqsave(&gi->spinlock, flags);
|
|
|
|
cdev = get_gadget_data(gadget);
|
|
|
|
if (!cdev || gi->unbind) {
|
|
|
|
spin_unlock_irqrestore(&gi->spinlock, flags);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
composite_disconnect(gadget);
|
|
|
|
spin_unlock_irqrestore(&gi->spinlock, flags);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void configfs_composite_suspend(struct usb_gadget *gadget)
|
|
|
|
{
|
|
|
|
struct usb_composite_dev *cdev;
|
|
|
|
struct gadget_info *gi;
|
|
|
|
unsigned long flags;
|
|
|
|
|
|
|
|
cdev = get_gadget_data(gadget);
|
|
|
|
if (!cdev)
|
|
|
|
return;
|
|
|
|
|
|
|
|
gi = container_of(cdev, struct gadget_info, cdev);
|
|
|
|
spin_lock_irqsave(&gi->spinlock, flags);
|
|
|
|
cdev = get_gadget_data(gadget);
|
|
|
|
if (!cdev || gi->unbind) {
|
|
|
|
spin_unlock_irqrestore(&gi->spinlock, flags);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
composite_suspend(gadget);
|
|
|
|
spin_unlock_irqrestore(&gi->spinlock, flags);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void configfs_composite_resume(struct usb_gadget *gadget)
|
|
|
|
{
|
|
|
|
struct usb_composite_dev *cdev;
|
|
|
|
struct gadget_info *gi;
|
|
|
|
unsigned long flags;
|
|
|
|
|
|
|
|
cdev = get_gadget_data(gadget);
|
|
|
|
if (!cdev)
|
|
|
|
return;
|
|
|
|
|
|
|
|
gi = container_of(cdev, struct gadget_info, cdev);
|
|
|
|
spin_lock_irqsave(&gi->spinlock, flags);
|
|
|
|
cdev = get_gadget_data(gadget);
|
|
|
|
if (!cdev || gi->unbind) {
|
|
|
|
spin_unlock_irqrestore(&gi->spinlock, flags);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
composite_resume(gadget);
|
|
|
|
spin_unlock_irqrestore(&gi->spinlock, flags);
|
2012-12-24 04:10:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static const struct usb_gadget_driver configfs_driver_template = {
|
|
|
|
.bind = configfs_composite_bind,
|
|
|
|
.unbind = configfs_composite_unbind,
|
|
|
|
|
usb: gadget: configfs: fix concurrent issue between composite APIs
We meet several NULL pointer issues if configfs_composite_unbind
and composite_setup (or composite_disconnect) are running together.
These issues occur when do the function switch stress test, the
configfs_compsoite_unbind is called from user mode by
echo "" to /sys/../UDC entry, and meanwhile, the setup interrupt
or disconnect interrupt occurs by hardware. The composite_setup
will get the cdev from get_gadget_data, but configfs_composite_unbind
will set gadget data as NULL, so the NULL pointer issue occurs.
This concurrent is hard to reproduce by native kernel, but can be
reproduced by android kernel.
In this commit, we introduce one spinlock belongs to structure
gadget_info since we can't use the same spinlock in usb_composite_dev
due to exclusive running together between composite_setup and
configfs_composite_unbind. And one bit flag 'unbind' to indicate the
code is at unbind routine, this bit is needed due to we release the
lock at during configfs_composite_unbind sometimes, and composite_setup
may be run at that time.
Several oops:
oops 1:
android_work: sent uevent USB_STATE=CONNECTED
configfs-gadget gadget: super-speed config #1: b
android_work: sent uevent USB_STATE=CONFIGURED
init: Received control message 'start' for 'adbd' from pid: 3515 (system_server)
Unable to handle kernel NULL pointer dereference at virtual address 0000002a
init: Received control message 'stop' for 'adbd' from pid: 3375 (/vendor/bin/hw/android.hardware.usb@1.1-servic)
Mem abort info:
Exception class = DABT (current EL), IL = 32 bits
SET = 0, FnV = 0
EA = 0, S1PTW = 0
Data abort info:
ISV = 0, ISS = 0x00000004
CM = 0, WnR = 0
user pgtable: 4k pages, 48-bit VAs, pgd = ffff8008f1b7f000
[000000000000002a] *pgd=0000000000000000
Internal error: Oops: 96000004 [#1] PREEMPT SMP
Modules linked in:
CPU: 4 PID: 2457 Comm: irq/125-5b11000 Not tainted 4.14.98-07846-g0b40a9b-dirty #16
Hardware name: Freescale i.MX8QM MEK (DT)
task: ffff8008f2a98000 task.stack: ffff00000b7b8000
PC is at composite_setup+0x44/0x1508
LR is at android_setup+0xb8/0x13c
pc : [<ffff0000089ffb3c>] lr : [<ffff000008a032fc>] pstate: 800001c5
sp : ffff00000b7bbb80
x29: ffff00000b7bbb80 x28: ffff8008f2a3c010
x27: 0000000000000001 x26: 0000000000000000 [1232/1897]
audit: audit_lost=25791 audit_rate_limit=5 audit_backlog_limit=64
x25: 00000000ffffffa1 x24: ffff8008f2a3c010
audit: rate limit exceeded
x23: 0000000000000409 x22: ffff000009c8e000
x21: ffff8008f7a8b428 x20: ffff00000afae000
x19: ffff0000089ff000 x18: 0000000000000000
x17: 0000000000000000 x16: ffff0000082b7c9c
x15: 0000000000000000 x14: f1866f5b952aca46
x13: e35502e30d44349c x12: 0000000000000008
x11: 0000000000000008 x10: 0000000000000a30
x9 : ffff00000b7bbd00 x8 : ffff8008f2a98a90
x7 : ffff8008f27a9c90 x6 : 0000000000000001
x5 : 0000000000000000 x4 : 0000000000000001
x3 : 0000000000000000 x2 : 0000000000000006
x1 : ffff0000089ff8d0 x0 : 732a010310b9ed00
X7: 0xffff8008f27a9c10:
9c10 00000002 00000000 00000001 00000000 13110000 ffff0000 00000002 00208040
9c30 00000000 00000000 00000000 00000000 00000000 00000005 00000029 00000000
9c50 00051778 00000001 f27a8e00 ffff8008 00000005 00000000 00000078 00000078
9c70 00000078 00000000 09031d48 ffff0000 00100000 00000000 00400000 00000000
9c90 00000001 00000000 00000000 00000000 00000000 00000000 ffefb1a0 ffff8008
9cb0 f27a9ca8 ffff8008 00000000 00000000 b9d88037 00000173 1618a3eb 00000001
9cd0 870a792a 0000002e 16188fe6 00000001 0000242b 00000000 00000000 00000000
using random self ethernet address
9cf0 019a4646 00000000 000547f3 00000000 ecfd6c33 00000002 00000000
using random host ethernet address
00000000
X8: 0xffff8008f2a98a10:
8a10 00000000 00000000 f7788d00 ffff8008 00000001 00000000 00000000 00000000
8a30 eb218000 ffff8008 f2a98000 ffff8008 f2a98000 ffff8008 09885000 ffff0000
8a50 f34df480 ffff8008 00000000 00000000 f2a98648 ffff8008 09c8e000 ffff0000
8a70 fff2c800 ffff8008 09031d48 ffff0000 0b7bbd00 ffff0000 0b7bbd00 ffff0000
8a90 080861bc ffff0000 00000000 00000000 00000000 00000000 00000000 00000000
8ab0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
8ad0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
8af0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
X21: 0xffff8008f7a8b3a8:
b3a8 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
b3c8 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
b3e8 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
b408 00000000 00000000 00000000 00000000 00000000 00000000 00000001 00000000
b428 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
b448 0053004d 00540046 00300031 00010030 eb07b520 ffff8008 20011201 00000003
b468 e418d109 0104404e 00010302 00000000 eb07b558 ffff8008 eb07b558 ffff8008
b488 f7a8b488 ffff8008 f7a8b488 ffff8008 f7a8b300 ffff8008 00000000 00000000
X24: 0xffff8008f2a3bf90:
bf90 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bfb0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bfd0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bff0 00000000 00000000 00000000 00000000 f76c8010 ffff8008 f76c8010 ffff8008
c010 00000000 00000000 f2a3c018 ffff8008 f2a3c018 ffff8008 08a067dc ffff0000
c030 f2a5a000 ffff8008 091c3650 ffff0000 f716fd18 ffff8008 f716fe30 ffff8008
c050 f2ce4a30 ffff8008 00000000 00000005 00000000 00000000 095d1568 ffff0000
c070 f76c8010 ffff8008 f2ce4b00 ffff8008 095cac68 ffff0000 f2a5a028 ffff8008
X28: 0xffff8008f2a3bf90:
bf90 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bfb0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bfd0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bff0 00000000 00000000 00000000 00000000 f76c8010 ffff8008 f76c8010 ffff8008
c010 00000000 00000000 f2a3c018 ffff8008 f2a3c018 ffff8008 08a067dc ffff0000
c030 f2a5a000 ffff8008 091c3650 ffff0000 f716fd18 ffff8008 f716fe30 ffff8008
c050 f2ce4a30 ffff8008 00000000 00000005 00000000 00000000 095d1568 ffff0000
c070 f76c8010 ffff8008 f2ce4b00 ffff8008 095cac68 ffff0000 f2a5a028 ffff8008
Process irq/125-5b11000 (pid: 2457, stack limit = 0xffff00000b7b8000)
Call trace:
Exception stack(0xffff00000b7bba40 to 0xffff00000b7bbb80)
ba40: 732a010310b9ed00 ffff0000089ff8d0 0000000000000006 0000000000000000
ba60: 0000000000000001 0000000000000000 0000000000000001 ffff8008f27a9c90
ba80: ffff8008f2a98a90 ffff00000b7bbd00 0000000000000a30 0000000000000008
baa0: 0000000000000008 e35502e30d44349c f1866f5b952aca46 0000000000000000
bac0: ffff0000082b7c9c 0000000000000000 0000000000000000 ffff0000089ff000
bae0: ffff00000afae000 ffff8008f7a8b428 ffff000009c8e000 0000000000000409
bb00: ffff8008f2a3c010 00000000ffffffa1 0000000000000000 0000000000000001
bb20: ffff8008f2a3c010 ffff00000b7bbb80 ffff000008a032fc ffff00000b7bbb80
bb40: ffff0000089ffb3c 00000000800001c5 ffff00000b7bbb80 732a010310b9ed00
bb60: ffffffffffffffff ffff0000080f777c ffff00000b7bbb80 ffff0000089ffb3c
[<ffff0000089ffb3c>] composite_setup+0x44/0x1508
[<ffff000008a032fc>] android_setup+0xb8/0x13c
[<ffff0000089bd9a8>] cdns3_ep0_delegate_req+0x44/0x70
[<ffff0000089bdff4>] cdns3_check_ep0_interrupt_proceed+0x33c/0x654
[<ffff0000089bca44>] cdns3_device_thread_irq_handler+0x4b0/0x4bc
[<ffff0000089b77b4>] cdns3_thread_irq+0x48/0x68
[<ffff000008145bf0>] irq_thread_fn+0x28/0x88
[<ffff000008145e38>] irq_thread+0x13c/0x228
[<ffff0000080fed70>] kthread+0x104/0x130
[<ffff000008085064>] ret_from_fork+0x10/0x18
oops2:
composite_disconnect: Calling disconnect on a Gadget that is not connected
android_work: did not send uevent (0 0 (null))
init: Received control message 'stop' for 'adbd' from pid: 3359 (/vendor/bin/hw/android.hardware.usb@1.1-service.imx)
init: Sending signal 9 to service 'adbd' (pid 22343) process group...
------------[ cut here ]------------
audit: audit_lost=180038 audit_rate_limit=5 audit_backlog_limit=64
audit: rate limit exceeded
WARNING: CPU: 0 PID: 3468 at kernel_imx/drivers/usb/gadget/composite.c:2009 composite_disconnect+0x80/0x88
Modules linked in:
CPU: 0 PID: 3468 Comm: HWC-UEvent-Thre Not tainted 4.14.98-07846-g0b40a9b-dirty #16
Hardware name: Freescale i.MX8QM MEK (DT)
task: ffff8008f2349c00 task.stack: ffff00000b0a8000
PC is at composite_disconnect+0x80/0x88
LR is at composite_disconnect+0x80/0x88
pc : [<ffff0000089ff9b0>] lr : [<ffff0000089ff9b0>] pstate: 600001c5
sp : ffff000008003dd0
x29: ffff000008003dd0 x28: ffff8008f2349c00
x27: ffff000009885018 x26: ffff000008004000
Timeout for IPC response!
x25: ffff000009885018 x24: ffff000009c8e280
x23: ffff8008f2d98010 x22: 00000000000001c0
x21: ffff8008f2d98394 x20: ffff8008f2d98010
x19: 0000000000000000 x18: 0000e3956f4f075a
fxos8700 4-001e: i2c block read acc failed
x17: 0000e395735727e8 x16: ffff00000829f4d4
x15: ffffffffffffffff x14: 7463656e6e6f6320
x13: 746f6e2009090920 x12: 7369207461687420
x11: 7465676461472061 x10: 206e6f207463656e
x9 : 6e6f637369642067 x8 : ffff000009c8e280
x7 : ffff0000086ca6cc x6 : ffff000009f15e78
x5 : 0000000000000000 x4 : 0000000000000000
x3 : ffffffffffffffff x2 : c3f28b86000c3900
x1 : c3f28b86000c3900 x0 : 000000000000004e
X20: 0xffff8008f2d97f90:
7f90 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
7fb0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
libprocessgroup: Failed to kill process cgroup uid 0 pid 22343 in 215ms, 1 processes remain
7fd0
Timeout for IPC response!
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
using random self ethernet address
7ff0 00000000 00000000 00000000 00000000 f76c8010 ffff8008 f76c8010 ffff8008
8010 00000100 00000000 f2d98018 ffff8008 f2d98018 ffff8008 08a067dc
using random host ethernet address
ffff0000
8030 f206d800 ffff8008 091c3650 ffff0000 f7957b18 ffff8008 f7957730 ffff8008
8050 f716a630 ffff8008 00000000 00000005 00000000 00000000 095d1568 ffff0000
8070 f76c8010 ffff8008 f716a800 ffff8008 095cac68 ffff0000 f206d828 ffff8008
X21: 0xffff8008f2d98314:
8314 ffff8008 00000000 00000000 00000000 00000000 00000000 00000000 00000000
8334 00000000 00000000 00000000 00000000 00000000 08a04cf4 ffff0000 00000000
8354 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
8374 00000000 00000000 00000000 00001001 00000000 00000000 00000000 00000000
8394 e4bbe4bb 0f230000 ffff0000 0afae000 ffff0000 ae001000 00000000 f206d400
Timeout for IPC response!
83b4 ffff8008 00000000 00000000 f7957b18 ffff8008 f7957718 ffff8008 f7957018
83d4 ffff8008 f7957118 ffff8008 f7957618 ffff8008 f7957818 ffff8008 f7957918
83f4 ffff8008 f7957d18 ffff8008 00000000 00000000 00000000 00000000 00000000
X23: 0xffff8008f2d97f90:
7f90 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
7fb0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
7fd0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
7ff0 00000000 00000000 00000000 00000000 f76c8010 ffff8008 f76c8010 ffff8008
8010 00000100 00000000 f2d98018 ffff8008 f2d98018 ffff8008 08a067dc ffff0000
8030 f206d800 ffff8008 091c3650 ffff0000 f7957b18 ffff8008 f7957730 ffff8008
8050 f716a630 ffff8008 00000000 00000005 00000000 00000000 095d1568 ffff0000
8070 f76c8010 ffff8008 f716a800 ffff8008 095cac68 ffff0000 f206d828 ffff8008
X28: 0xffff8008f2349b80:
9b80 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
9ba0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
9bc0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
9be0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
9c00 00000022 00000000 ffffffff ffffffff 00010001 00000000 00000000 00000000
9c20 0b0a8000 ffff0000 00000002 00404040 00000000 00000000 00000000 00000000
9c40 00000001 00000000 00000001 00000000 001ebd44 00000001 f390b800 ffff8008
9c60 00000000 00000001 00000070 00000070 00000070 00000000 09031d48 ffff0000
Call trace:
Exception stack(0xffff000008003c90 to 0xffff000008003dd0)
3c80: 000000000000004e c3f28b86000c3900
3ca0: c3f28b86000c3900 ffffffffffffffff 0000000000000000 0000000000000000
3cc0: ffff000009f15e78 ffff0000086ca6cc ffff000009c8e280 6e6f637369642067
3ce0: 206e6f207463656e 7465676461472061 7369207461687420 746f6e2009090920
3d00: 7463656e6e6f6320 ffffffffffffffff ffff00000829f4d4 0000e395735727e8
3d20: 0000e3956f4f075a 0000000000000000 ffff8008f2d98010 ffff8008f2d98394
3d40: 00000000000001c0 ffff8008f2d98010 ffff000009c8e280 ffff000009885018
3d60: ffff000008004000 ffff000009885018 ffff8008f2349c00 ffff000008003dd0
3d80: ffff0000089ff9b0 ffff000008003dd0 ffff0000089ff9b0 00000000600001c5
3da0: ffff8008f33f2cd8 0000000000000000 0000ffffffffffff 0000000000000000
init: Received control message 'start' for 'adbd' from pid: 3359 (/vendor/bin/hw/android.hardware.usb@1.1-service.imx)
3dc0: ffff000008003dd0 ffff0000089ff9b0
[<ffff0000089ff9b0>] composite_disconnect+0x80/0x88
[<ffff000008a044d4>] android_disconnect+0x3c/0x68
[<ffff0000089ba9f8>] cdns3_device_irq_handler+0xfc/0x2c8
[<ffff0000089b84c0>] cdns3_irq+0x44/0x94
[<ffff00000814494c>] __handle_irq_event_percpu+0x60/0x24c
[<ffff000008144c0c>] handle_irq_event+0x58/0xc0
[<ffff00000814873c>] handle_fasteoi_irq+0x98/0x180
[<ffff000008143a10>] generic_handle_irq+0x24/0x38
[<ffff000008144170>] __handle_domain_irq+0x60/0xac
[<ffff0000080819c4>] gic_handle_irq+0xd4/0x17c
Signed-off-by: Peter Chen <peter.chen@nxp.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
2019-08-27 03:10:55 +08:00
|
|
|
.setup = configfs_composite_setup,
|
|
|
|
.reset = configfs_composite_disconnect,
|
|
|
|
.disconnect = configfs_composite_disconnect,
|
2012-12-24 04:10:24 +08:00
|
|
|
|
usb: gadget: configfs: fix concurrent issue between composite APIs
We meet several NULL pointer issues if configfs_composite_unbind
and composite_setup (or composite_disconnect) are running together.
These issues occur when do the function switch stress test, the
configfs_compsoite_unbind is called from user mode by
echo "" to /sys/../UDC entry, and meanwhile, the setup interrupt
or disconnect interrupt occurs by hardware. The composite_setup
will get the cdev from get_gadget_data, but configfs_composite_unbind
will set gadget data as NULL, so the NULL pointer issue occurs.
This concurrent is hard to reproduce by native kernel, but can be
reproduced by android kernel.
In this commit, we introduce one spinlock belongs to structure
gadget_info since we can't use the same spinlock in usb_composite_dev
due to exclusive running together between composite_setup and
configfs_composite_unbind. And one bit flag 'unbind' to indicate the
code is at unbind routine, this bit is needed due to we release the
lock at during configfs_composite_unbind sometimes, and composite_setup
may be run at that time.
Several oops:
oops 1:
android_work: sent uevent USB_STATE=CONNECTED
configfs-gadget gadget: super-speed config #1: b
android_work: sent uevent USB_STATE=CONFIGURED
init: Received control message 'start' for 'adbd' from pid: 3515 (system_server)
Unable to handle kernel NULL pointer dereference at virtual address 0000002a
init: Received control message 'stop' for 'adbd' from pid: 3375 (/vendor/bin/hw/android.hardware.usb@1.1-servic)
Mem abort info:
Exception class = DABT (current EL), IL = 32 bits
SET = 0, FnV = 0
EA = 0, S1PTW = 0
Data abort info:
ISV = 0, ISS = 0x00000004
CM = 0, WnR = 0
user pgtable: 4k pages, 48-bit VAs, pgd = ffff8008f1b7f000
[000000000000002a] *pgd=0000000000000000
Internal error: Oops: 96000004 [#1] PREEMPT SMP
Modules linked in:
CPU: 4 PID: 2457 Comm: irq/125-5b11000 Not tainted 4.14.98-07846-g0b40a9b-dirty #16
Hardware name: Freescale i.MX8QM MEK (DT)
task: ffff8008f2a98000 task.stack: ffff00000b7b8000
PC is at composite_setup+0x44/0x1508
LR is at android_setup+0xb8/0x13c
pc : [<ffff0000089ffb3c>] lr : [<ffff000008a032fc>] pstate: 800001c5
sp : ffff00000b7bbb80
x29: ffff00000b7bbb80 x28: ffff8008f2a3c010
x27: 0000000000000001 x26: 0000000000000000 [1232/1897]
audit: audit_lost=25791 audit_rate_limit=5 audit_backlog_limit=64
x25: 00000000ffffffa1 x24: ffff8008f2a3c010
audit: rate limit exceeded
x23: 0000000000000409 x22: ffff000009c8e000
x21: ffff8008f7a8b428 x20: ffff00000afae000
x19: ffff0000089ff000 x18: 0000000000000000
x17: 0000000000000000 x16: ffff0000082b7c9c
x15: 0000000000000000 x14: f1866f5b952aca46
x13: e35502e30d44349c x12: 0000000000000008
x11: 0000000000000008 x10: 0000000000000a30
x9 : ffff00000b7bbd00 x8 : ffff8008f2a98a90
x7 : ffff8008f27a9c90 x6 : 0000000000000001
x5 : 0000000000000000 x4 : 0000000000000001
x3 : 0000000000000000 x2 : 0000000000000006
x1 : ffff0000089ff8d0 x0 : 732a010310b9ed00
X7: 0xffff8008f27a9c10:
9c10 00000002 00000000 00000001 00000000 13110000 ffff0000 00000002 00208040
9c30 00000000 00000000 00000000 00000000 00000000 00000005 00000029 00000000
9c50 00051778 00000001 f27a8e00 ffff8008 00000005 00000000 00000078 00000078
9c70 00000078 00000000 09031d48 ffff0000 00100000 00000000 00400000 00000000
9c90 00000001 00000000 00000000 00000000 00000000 00000000 ffefb1a0 ffff8008
9cb0 f27a9ca8 ffff8008 00000000 00000000 b9d88037 00000173 1618a3eb 00000001
9cd0 870a792a 0000002e 16188fe6 00000001 0000242b 00000000 00000000 00000000
using random self ethernet address
9cf0 019a4646 00000000 000547f3 00000000 ecfd6c33 00000002 00000000
using random host ethernet address
00000000
X8: 0xffff8008f2a98a10:
8a10 00000000 00000000 f7788d00 ffff8008 00000001 00000000 00000000 00000000
8a30 eb218000 ffff8008 f2a98000 ffff8008 f2a98000 ffff8008 09885000 ffff0000
8a50 f34df480 ffff8008 00000000 00000000 f2a98648 ffff8008 09c8e000 ffff0000
8a70 fff2c800 ffff8008 09031d48 ffff0000 0b7bbd00 ffff0000 0b7bbd00 ffff0000
8a90 080861bc ffff0000 00000000 00000000 00000000 00000000 00000000 00000000
8ab0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
8ad0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
8af0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
X21: 0xffff8008f7a8b3a8:
b3a8 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
b3c8 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
b3e8 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
b408 00000000 00000000 00000000 00000000 00000000 00000000 00000001 00000000
b428 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
b448 0053004d 00540046 00300031 00010030 eb07b520 ffff8008 20011201 00000003
b468 e418d109 0104404e 00010302 00000000 eb07b558 ffff8008 eb07b558 ffff8008
b488 f7a8b488 ffff8008 f7a8b488 ffff8008 f7a8b300 ffff8008 00000000 00000000
X24: 0xffff8008f2a3bf90:
bf90 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bfb0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bfd0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bff0 00000000 00000000 00000000 00000000 f76c8010 ffff8008 f76c8010 ffff8008
c010 00000000 00000000 f2a3c018 ffff8008 f2a3c018 ffff8008 08a067dc ffff0000
c030 f2a5a000 ffff8008 091c3650 ffff0000 f716fd18 ffff8008 f716fe30 ffff8008
c050 f2ce4a30 ffff8008 00000000 00000005 00000000 00000000 095d1568 ffff0000
c070 f76c8010 ffff8008 f2ce4b00 ffff8008 095cac68 ffff0000 f2a5a028 ffff8008
X28: 0xffff8008f2a3bf90:
bf90 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bfb0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bfd0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bff0 00000000 00000000 00000000 00000000 f76c8010 ffff8008 f76c8010 ffff8008
c010 00000000 00000000 f2a3c018 ffff8008 f2a3c018 ffff8008 08a067dc ffff0000
c030 f2a5a000 ffff8008 091c3650 ffff0000 f716fd18 ffff8008 f716fe30 ffff8008
c050 f2ce4a30 ffff8008 00000000 00000005 00000000 00000000 095d1568 ffff0000
c070 f76c8010 ffff8008 f2ce4b00 ffff8008 095cac68 ffff0000 f2a5a028 ffff8008
Process irq/125-5b11000 (pid: 2457, stack limit = 0xffff00000b7b8000)
Call trace:
Exception stack(0xffff00000b7bba40 to 0xffff00000b7bbb80)
ba40: 732a010310b9ed00 ffff0000089ff8d0 0000000000000006 0000000000000000
ba60: 0000000000000001 0000000000000000 0000000000000001 ffff8008f27a9c90
ba80: ffff8008f2a98a90 ffff00000b7bbd00 0000000000000a30 0000000000000008
baa0: 0000000000000008 e35502e30d44349c f1866f5b952aca46 0000000000000000
bac0: ffff0000082b7c9c 0000000000000000 0000000000000000 ffff0000089ff000
bae0: ffff00000afae000 ffff8008f7a8b428 ffff000009c8e000 0000000000000409
bb00: ffff8008f2a3c010 00000000ffffffa1 0000000000000000 0000000000000001
bb20: ffff8008f2a3c010 ffff00000b7bbb80 ffff000008a032fc ffff00000b7bbb80
bb40: ffff0000089ffb3c 00000000800001c5 ffff00000b7bbb80 732a010310b9ed00
bb60: ffffffffffffffff ffff0000080f777c ffff00000b7bbb80 ffff0000089ffb3c
[<ffff0000089ffb3c>] composite_setup+0x44/0x1508
[<ffff000008a032fc>] android_setup+0xb8/0x13c
[<ffff0000089bd9a8>] cdns3_ep0_delegate_req+0x44/0x70
[<ffff0000089bdff4>] cdns3_check_ep0_interrupt_proceed+0x33c/0x654
[<ffff0000089bca44>] cdns3_device_thread_irq_handler+0x4b0/0x4bc
[<ffff0000089b77b4>] cdns3_thread_irq+0x48/0x68
[<ffff000008145bf0>] irq_thread_fn+0x28/0x88
[<ffff000008145e38>] irq_thread+0x13c/0x228
[<ffff0000080fed70>] kthread+0x104/0x130
[<ffff000008085064>] ret_from_fork+0x10/0x18
oops2:
composite_disconnect: Calling disconnect on a Gadget that is not connected
android_work: did not send uevent (0 0 (null))
init: Received control message 'stop' for 'adbd' from pid: 3359 (/vendor/bin/hw/android.hardware.usb@1.1-service.imx)
init: Sending signal 9 to service 'adbd' (pid 22343) process group...
------------[ cut here ]------------
audit: audit_lost=180038 audit_rate_limit=5 audit_backlog_limit=64
audit: rate limit exceeded
WARNING: CPU: 0 PID: 3468 at kernel_imx/drivers/usb/gadget/composite.c:2009 composite_disconnect+0x80/0x88
Modules linked in:
CPU: 0 PID: 3468 Comm: HWC-UEvent-Thre Not tainted 4.14.98-07846-g0b40a9b-dirty #16
Hardware name: Freescale i.MX8QM MEK (DT)
task: ffff8008f2349c00 task.stack: ffff00000b0a8000
PC is at composite_disconnect+0x80/0x88
LR is at composite_disconnect+0x80/0x88
pc : [<ffff0000089ff9b0>] lr : [<ffff0000089ff9b0>] pstate: 600001c5
sp : ffff000008003dd0
x29: ffff000008003dd0 x28: ffff8008f2349c00
x27: ffff000009885018 x26: ffff000008004000
Timeout for IPC response!
x25: ffff000009885018 x24: ffff000009c8e280
x23: ffff8008f2d98010 x22: 00000000000001c0
x21: ffff8008f2d98394 x20: ffff8008f2d98010
x19: 0000000000000000 x18: 0000e3956f4f075a
fxos8700 4-001e: i2c block read acc failed
x17: 0000e395735727e8 x16: ffff00000829f4d4
x15: ffffffffffffffff x14: 7463656e6e6f6320
x13: 746f6e2009090920 x12: 7369207461687420
x11: 7465676461472061 x10: 206e6f207463656e
x9 : 6e6f637369642067 x8 : ffff000009c8e280
x7 : ffff0000086ca6cc x6 : ffff000009f15e78
x5 : 0000000000000000 x4 : 0000000000000000
x3 : ffffffffffffffff x2 : c3f28b86000c3900
x1 : c3f28b86000c3900 x0 : 000000000000004e
X20: 0xffff8008f2d97f90:
7f90 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
7fb0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
libprocessgroup: Failed to kill process cgroup uid 0 pid 22343 in 215ms, 1 processes remain
7fd0
Timeout for IPC response!
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
using random self ethernet address
7ff0 00000000 00000000 00000000 00000000 f76c8010 ffff8008 f76c8010 ffff8008
8010 00000100 00000000 f2d98018 ffff8008 f2d98018 ffff8008 08a067dc
using random host ethernet address
ffff0000
8030 f206d800 ffff8008 091c3650 ffff0000 f7957b18 ffff8008 f7957730 ffff8008
8050 f716a630 ffff8008 00000000 00000005 00000000 00000000 095d1568 ffff0000
8070 f76c8010 ffff8008 f716a800 ffff8008 095cac68 ffff0000 f206d828 ffff8008
X21: 0xffff8008f2d98314:
8314 ffff8008 00000000 00000000 00000000 00000000 00000000 00000000 00000000
8334 00000000 00000000 00000000 00000000 00000000 08a04cf4 ffff0000 00000000
8354 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
8374 00000000 00000000 00000000 00001001 00000000 00000000 00000000 00000000
8394 e4bbe4bb 0f230000 ffff0000 0afae000 ffff0000 ae001000 00000000 f206d400
Timeout for IPC response!
83b4 ffff8008 00000000 00000000 f7957b18 ffff8008 f7957718 ffff8008 f7957018
83d4 ffff8008 f7957118 ffff8008 f7957618 ffff8008 f7957818 ffff8008 f7957918
83f4 ffff8008 f7957d18 ffff8008 00000000 00000000 00000000 00000000 00000000
X23: 0xffff8008f2d97f90:
7f90 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
7fb0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
7fd0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
7ff0 00000000 00000000 00000000 00000000 f76c8010 ffff8008 f76c8010 ffff8008
8010 00000100 00000000 f2d98018 ffff8008 f2d98018 ffff8008 08a067dc ffff0000
8030 f206d800 ffff8008 091c3650 ffff0000 f7957b18 ffff8008 f7957730 ffff8008
8050 f716a630 ffff8008 00000000 00000005 00000000 00000000 095d1568 ffff0000
8070 f76c8010 ffff8008 f716a800 ffff8008 095cac68 ffff0000 f206d828 ffff8008
X28: 0xffff8008f2349b80:
9b80 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
9ba0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
9bc0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
9be0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
9c00 00000022 00000000 ffffffff ffffffff 00010001 00000000 00000000 00000000
9c20 0b0a8000 ffff0000 00000002 00404040 00000000 00000000 00000000 00000000
9c40 00000001 00000000 00000001 00000000 001ebd44 00000001 f390b800 ffff8008
9c60 00000000 00000001 00000070 00000070 00000070 00000000 09031d48 ffff0000
Call trace:
Exception stack(0xffff000008003c90 to 0xffff000008003dd0)
3c80: 000000000000004e c3f28b86000c3900
3ca0: c3f28b86000c3900 ffffffffffffffff 0000000000000000 0000000000000000
3cc0: ffff000009f15e78 ffff0000086ca6cc ffff000009c8e280 6e6f637369642067
3ce0: 206e6f207463656e 7465676461472061 7369207461687420 746f6e2009090920
3d00: 7463656e6e6f6320 ffffffffffffffff ffff00000829f4d4 0000e395735727e8
3d20: 0000e3956f4f075a 0000000000000000 ffff8008f2d98010 ffff8008f2d98394
3d40: 00000000000001c0 ffff8008f2d98010 ffff000009c8e280 ffff000009885018
3d60: ffff000008004000 ffff000009885018 ffff8008f2349c00 ffff000008003dd0
3d80: ffff0000089ff9b0 ffff000008003dd0 ffff0000089ff9b0 00000000600001c5
3da0: ffff8008f33f2cd8 0000000000000000 0000ffffffffffff 0000000000000000
init: Received control message 'start' for 'adbd' from pid: 3359 (/vendor/bin/hw/android.hardware.usb@1.1-service.imx)
3dc0: ffff000008003dd0 ffff0000089ff9b0
[<ffff0000089ff9b0>] composite_disconnect+0x80/0x88
[<ffff000008a044d4>] android_disconnect+0x3c/0x68
[<ffff0000089ba9f8>] cdns3_device_irq_handler+0xfc/0x2c8
[<ffff0000089b84c0>] cdns3_irq+0x44/0x94
[<ffff00000814494c>] __handle_irq_event_percpu+0x60/0x24c
[<ffff000008144c0c>] handle_irq_event+0x58/0xc0
[<ffff00000814873c>] handle_fasteoi_irq+0x98/0x180
[<ffff000008143a10>] generic_handle_irq+0x24/0x38
[<ffff000008144170>] __handle_domain_irq+0x60/0xac
[<ffff0000080819c4>] gic_handle_irq+0xd4/0x17c
Signed-off-by: Peter Chen <peter.chen@nxp.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
2019-08-27 03:10:55 +08:00
|
|
|
.suspend = configfs_composite_suspend,
|
|
|
|
.resume = configfs_composite_resume,
|
2014-10-08 18:03:36 +08:00
|
|
|
|
2012-12-24 04:10:24 +08:00
|
|
|
.max_speed = USB_SPEED_SUPER,
|
|
|
|
.driver = {
|
|
|
|
.owner = THIS_MODULE,
|
|
|
|
.name = "configfs-gadget",
|
|
|
|
},
|
2016-05-05 16:46:05 +08:00
|
|
|
.match_existing_only = 1,
|
2012-12-24 04:10:24 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
static struct config_group *gadgets_make(
|
|
|
|
struct config_group *group,
|
|
|
|
const char *name)
|
|
|
|
{
|
|
|
|
struct gadget_info *gi;
|
|
|
|
|
|
|
|
gi = kzalloc(sizeof(*gi), GFP_KERNEL);
|
|
|
|
if (!gi)
|
|
|
|
return ERR_PTR(-ENOMEM);
|
|
|
|
|
2016-02-26 18:02:14 +08:00
|
|
|
config_group_init_type_name(&gi->group, name, &gadget_root_type);
|
2012-12-24 04:10:24 +08:00
|
|
|
|
|
|
|
config_group_init_type_name(&gi->functions_group, "functions",
|
|
|
|
&functions_type);
|
2016-02-26 18:02:14 +08:00
|
|
|
configfs_add_default_group(&gi->functions_group, &gi->group);
|
|
|
|
|
2012-12-24 04:10:24 +08:00
|
|
|
config_group_init_type_name(&gi->configs_group, "configs",
|
|
|
|
&config_desc_type);
|
2016-02-26 18:02:14 +08:00
|
|
|
configfs_add_default_group(&gi->configs_group, &gi->group);
|
|
|
|
|
2012-12-24 04:10:24 +08:00
|
|
|
config_group_init_type_name(&gi->strings_group, "strings",
|
|
|
|
&gadget_strings_strings_type);
|
2016-02-26 18:02:14 +08:00
|
|
|
configfs_add_default_group(&gi->strings_group, &gi->group);
|
|
|
|
|
2014-05-08 20:06:25 +08:00
|
|
|
config_group_init_type_name(&gi->os_desc_group, "os_desc",
|
|
|
|
&os_desc_type);
|
2016-02-26 18:02:14 +08:00
|
|
|
configfs_add_default_group(&gi->os_desc_group, &gi->group);
|
2012-12-24 04:10:24 +08:00
|
|
|
|
|
|
|
gi->composite.bind = configfs_do_nothing;
|
|
|
|
gi->composite.unbind = configfs_do_nothing;
|
|
|
|
gi->composite.suspend = NULL;
|
|
|
|
gi->composite.resume = NULL;
|
|
|
|
gi->composite.max_speed = USB_SPEED_SUPER;
|
|
|
|
|
|
|
|
mutex_init(&gi->lock);
|
|
|
|
INIT_LIST_HEAD(&gi->string_list);
|
|
|
|
INIT_LIST_HEAD(&gi->available_func);
|
|
|
|
|
|
|
|
composite_init_dev(&gi->cdev);
|
|
|
|
gi->cdev.desc.bLength = USB_DT_DEVICE_SIZE;
|
|
|
|
gi->cdev.desc.bDescriptorType = USB_DT_DEVICE;
|
|
|
|
gi->cdev.desc.bcdDevice = cpu_to_le16(get_default_bcdDevice());
|
|
|
|
|
|
|
|
gi->composite.gadget_driver = configfs_driver_template;
|
|
|
|
|
|
|
|
gi->composite.gadget_driver.function = kstrdup(name, GFP_KERNEL);
|
|
|
|
gi->composite.name = gi->composite.gadget_driver.function;
|
|
|
|
|
|
|
|
if (!gi->composite.gadget_driver.function)
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
return &gi->group;
|
|
|
|
err:
|
|
|
|
kfree(gi);
|
|
|
|
return ERR_PTR(-ENOMEM);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void gadgets_drop(struct config_group *group, struct config_item *item)
|
|
|
|
{
|
|
|
|
config_item_put(item);
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct configfs_group_operations gadgets_ops = {
|
|
|
|
.make_group = &gadgets_make,
|
|
|
|
.drop_item = &gadgets_drop,
|
|
|
|
};
|
|
|
|
|
2017-10-16 23:18:46 +08:00
|
|
|
static const struct config_item_type gadgets_type = {
|
2012-12-24 04:10:24 +08:00
|
|
|
.ct_group_ops = &gadgets_ops,
|
|
|
|
.ct_owner = THIS_MODULE,
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct configfs_subsystem gadget_subsys = {
|
|
|
|
.su_group = {
|
|
|
|
.cg_item = {
|
|
|
|
.ci_namebuf = "usb_gadget",
|
|
|
|
.ci_type = &gadgets_type,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
.su_mutex = __MUTEX_INITIALIZER(gadget_subsys.su_mutex),
|
|
|
|
};
|
|
|
|
|
2013-09-26 20:38:15 +08:00
|
|
|
void unregister_gadget_item(struct config_item *item)
|
|
|
|
{
|
|
|
|
struct gadget_info *gi = to_gadget_info(item);
|
|
|
|
|
2016-07-27 10:03:19 +08:00
|
|
|
mutex_lock(&gi->lock);
|
2013-09-26 20:38:15 +08:00
|
|
|
unregister_gadget(gi);
|
2016-07-27 10:03:19 +08:00
|
|
|
mutex_unlock(&gi->lock);
|
2013-09-26 20:38:15 +08:00
|
|
|
}
|
2014-04-02 02:19:32 +08:00
|
|
|
EXPORT_SYMBOL_GPL(unregister_gadget_item);
|
2013-09-26 20:38:15 +08:00
|
|
|
|
2012-12-24 04:10:24 +08:00
|
|
|
static int __init gadget_cfs_init(void)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
config_group_init(&gadget_subsys.su_group);
|
|
|
|
|
|
|
|
ret = configfs_register_subsystem(&gadget_subsys);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
module_init(gadget_cfs_init);
|
|
|
|
|
|
|
|
static void __exit gadget_cfs_exit(void)
|
|
|
|
{
|
|
|
|
configfs_unregister_subsystem(&gadget_subsys);
|
|
|
|
}
|
|
|
|
module_exit(gadget_cfs_exit);
|