When read data from g_printer, we see a Segmentation fault. eg:
Unable to handle kernel paging request at virtual address
bf048000 pgd
=
cf038000 [
bf048000] *pgd=
8e8cf811, *pte=
00000000, *ppte=
00000000
Internal error: Oops: 7 [#1] PREEMPT ARM Modules linked in: bluetooth
rfcomm g_printer
CPU: 0 Not tainted (3.4.43-WR5.0.1.9_standard #1)
PC is at __copy_to_user_std+0x310/0x3a8 LR is at 0x4c808010
pc : [<
c036e990>] lr : [<
4c808010>] psr:
20000013
sp :
cf883ea8 ip :
80801018 fp :
cf883f24
r10:
bf04706c r9 :
18a21205 r8 :
21953888
r7 :
201588aa r6 :
5109aa16 r5 :
0705aaa2 r4 :
5140aa8a
r3 :
0000004c r2 :
00000fdc r1 :
bf048000 r0 :
bef5fc3c
Flags: nzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user
Control:
10c5387d Table:
8f038019 DAC:
00000015 Process
g_printer_test. (pid: 661, stack limit = 0xcf8822e8)
Stack: (0xcf883ea8 to 0xcf884000)
3ea0:
bf047068 00001fff bef5ecb9 cf882000 00001fff bef5ecb9
3ec0:
00001fff 00000000 cf2e8724 bf044d3c 80000013 80000013 00000001
bf04706c
3ee0:
cf883f24 cf883ef0 c012e5ac c0324388 c007c8ac c0046298 00008180
cf29b900
3f00:
00002000 bef5ecb8 cf883f68 00000003 cf882000 cf29b900 cf883f54
cf883f28
3f20:
c012ea08 bf044b0c c000eb88 00000000 cf883f7c 00000000 00000000
00002000
3f40:
bef5ecb8 00000003 cf883fa4 cf883f58 c012eae8 c012e960 00000001
bef60cb8
3f60:
000000a8 c000eb88 00000000 00000000 cf883fa4 00000000 c014329c
00000000
3f80:
000000d4 41af63f0 00000003 c000eb88 cf882000 00000000 00000000
cf883fa8
3fa0:
c000e920 c012eaa4 00000000 000000d4 00000003 bef5ecb8 00002000
bef5ecb8
3fc0:
00000000 000000d4 41af63f0 00000003 b6f534c0 00000000 419f9000
00000000
3fe0:
00000000 bef5ecac 000086d9 41a986bc 60000010 00000003 0109608a
0088828a
Code:
f5d1f07c e8b100f0 e1a03c2e e2522020 (
e8b15300) ---[ end trace
97e2618e250e3377 ]--- Segmentation fault
The root cause is the dev->rx_buffers list has been broken.
When we call printer_read(), the following call tree is triggered:
printer_read()
|
+---setup_rx_reqs(req)
| |
| +---usb_ep_queue(req)
| | |
| | +---...
| | |
| | +---rx_complete(req).
| |
| +---add the req to dev->rx_reqs_active
|
+---while(!list_empty(&dev->rx_buffers)))
The route happens when we don't use DMA or fail to start DMA in USB
driver. We can see: in the case, in rx_complete() it will add the req
to dev->rx_buffers. meanwhile we see that we will also add the req to
dev->rx_reqs_active after usb_ep_queue() return, so this adding will
break the dev->rx_buffers out.
After, when we call list_empty() to check dev->rx_buffers in while(),
due to can't check correctly dev->rx_buffers, so the Segmentation fault
occurs when copy_to_user() is called.
Signed-off-by: wenlin.kang <wenlin.kang@windriver.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
DBG(dev, "rx submit --> %d\n", error);
list_add(&req->list, &dev->rx_reqs);
break;
- } else {
+ }
+ /* if the req is empty, then add it into dev->rx_reqs_active. */
+ else if (list_empty(&req->list)) {
list_add(&req->list, &dev->rx_reqs_active);
}
}