]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/2.6.35.8/usb-musb-gadget-fix-kernel-panic-if-using-out-ep-with-fifo_txrx-style.patch
4.9-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 2.6.35.8 / usb-musb-gadget-fix-kernel-panic-if-using-out-ep-with-fifo_txrx-style.patch
1 From bd2e74d657fc7d514881cc2117e323790b257914 Mon Sep 17 00:00:00 2001
2 From: Ming Lei <tom.leiming@gmail.com>
3 Date: Mon, 20 Sep 2010 10:32:01 +0300
4 Subject: usb: musb: gadget: fix kernel panic if using out ep with FIFO_TXRX style
5
6 From: Ming Lei <tom.leiming@gmail.com>
7
8 commit bd2e74d657fc7d514881cc2117e323790b257914 upstream.
9
10 For shared fifo hw endpoint(with FIFO_TXRX style), only ep_in
11 field of musb_hw_ep is intialized in musb_g_init_endpoints, and
12 ep_out is not initialized, but musb_g_rx and rxstate may access
13 ep_out field of musb_hw_ep by the method below:
14
15 musb_ep = &musb->endpoints[epnum].ep_out
16
17 which can cause the kernel panic[1] below, this patch fixes the issue
18 by getting 'musb_ep' from '&musb->endpoints[epnum].ep_in' for shared fifo
19 endpoint.
20
21 [1], kernel panic
22 [root@OMAP3EVM /]# musb_interrupt 1583: ** IRQ peripheral usb0008 tx0000 rx4000
23 musb_stage0_irq 460: <== Power=f0, DevCtl=99, int_usb=0x8
24 musb_g_rx 772: <== (null), rxcsr 4007 ffffffe8
25 musb_g_rx 786: iso overrun on ffffffe8
26 Unable to handle kernel NULL pointer dereference at virtual address 00000008
27 pgd = c0004000
28 [00000008] *pgd=00000000
29 Internal error: Oops: 17 [#1] PREEMPT
30 last sysfs file: /sys/devices/platform/musb_hdrc/usb1/usb_device/usbdev1.1/dev
31 Modules linked in: g_zero
32 CPU: 0 Tainted: G W (2.6.35-rc6-gkh-wl+ #92)
33 PC is at musb_g_rx+0xfc/0x2ec
34 LR is at vprintk+0x3f4/0x458
35 pc : [<c02c07a4>] lr : [<c006ccb0>] psr: 20000193
36 sp : c760bd78 ip : c03c9d70 fp : c760bdbc
37 r10: 00000000 r9 : fa0ab1e0 r8 : 0000000e
38 r7 : c7e80158 r6 : ffffffe8 r5 : 00000001 r4 : 00004003
39 r3 : 00010003 r2 : c760bcd8 r1 : c03cd030 r0 : 0000002e
40 Flags: nzCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment kernel
41 Control: 10c5387d Table: 8778c019 DAC: 00000017
42 Process kmemleak (pid: 421, stack limit = 0xc760a2e8)
43 Stack: (0xc760bd78 to 0xc760c000)
44 bd60: ffffffe8 c04b1b58
45 bd80: ffffffe8 c7c01ac0 00000000 c7e80d24 c0084238 00000001 00000001 c7e80158
46 bda0: 0000000e 00000008 00000099 000000f0 c760be04 c760bdc0 c02bcd68 c02c06b4
47 bdc0: 00000099 00000008 00004000 c760bdd8 c03cc4f8 00000000 00000002 c7e80158
48 bde0: c7d2e300 60000193 c760a000 0000005c 00000000 00000000 c760be24 c760be08
49 be00: c02bcecc c02bc1ac c7d2e300 c7d2e300 0000005c c760a000 c760be54 c760be28
50 be20: c00ad698 c02bce6c 00000000 c7d2e300 c067c258 0000005c c067c294 00000001
51 be40: c760a000 00000000 c760be74 c760be58 c00af984 c00ad5fc 0000005c 00000000
52 be60: 00000000 00000002 c760be8c c760be78 c0039080 c00af8d0 ffffffff fa200000
53 be80: c760beec c760be90 c0039b6c c003900c 00000001 00000000 c7d1e240 00000000
54 bea0: 00000000 c068bae8 00000000 60000013 00000001 00000000 00000000 c760beec
55 bec0: c0064ecc c760bed8 c00ff7d0 c003a0a8 60000013 ffffffff 00000000 c068bae8
56 bee0: c760bf24 c760bef0 c00ff7d0 c0064ec4 00000001 00000000 c00ff700 00000000
57 bf00: c0087f00 00000000 60000013 c0d76a70 c0e23795 00000001 c760bf4c c760bf28
58 bf20: c00ffdd8 c00ff70c c068bb08 c068bae8 60000013 c0100938 c068bb30 00000000
59 bf40: c760bf84 c760bf50 c010014c c00ffd84 00000001 00000000 c010000c 00012c00
60 bf60: c7c33f04 00012c00 c7c33f04 00000000 c0100938 00000000 c760bf9c c760bf88
61 bf80: c01009a8 c0100018 c760bfa8 c7c33f04 c760bff4 c760bfa0 c0088000 c0100944
62 bfa0: c760bf98 00000000 00000000 00000001 dead4ead ffffffff ffffffff c08ba2bc
63 bfc0: 00000000 c049e7fa 00000000 c0087f70 c760bfd0 c760bfd0 c7c33f04 c0087f70
64 bfe0: c006f5e8 00000013 00000000 c760bff8 c006f5e8 c0087f7c 7f0004ff df2000ff
65 Backtrace:
66 [<c02c06a8>] (musb_g_rx+0x0/0x2ec) from [<c02bcd68>] (musb_interrupt+0xbc8/0xcc0)
67 [<c02bc1a0>] (musb_interrupt+0x0/0xcc0) from [<c02bcecc>] (generic_interrupt+0x6c/0x84)
68 [<c02bce60>] (generic_interrupt+0x0/0x84) from [<c00ad698>] (handle_IRQ_event+0xa8/0x1ec)
69 r7:c760a000 r6:0000005c r5:c7d2e300 r4:c7d2e300
70 [<c00ad5f0>] (handle_IRQ_event+0x0/0x1ec) from [<c00af984>] (handle_level_irq+0xc0/0x13c)
71 [<c00af8c4>] (handle_level_irq+0x0/0x13c) from [<c0039080>] (asm_do_IRQ+0x80/0xa0)
72 r7:00000002 r6:00000000 r5:00000000 r4:0000005c
73 [<c0039000>] (asm_do_IRQ+0x0/0xa0) from [<c0039b6c>] (__irq_svc+0x4c/0xb4)
74 Exception stack(0xc760be90 to 0xc760bed8)
75 be80: 00000001 00000000 c7d1e240 00000000
76 bea0: 00000000 c068bae8 00000000 60000013 00000001 00000000 00000000 c760beec
77 bec0: c0064ecc c760bed8 c00ff7d0 c003a0a8 60000013 ffffffff
78 r5:fa200000 r4:ffffffff
79 [<c0064eb8>] (sub_preempt_count+0x0/0x100) from [<c00ff7d0>] (find_and_get_object+0xd0/0x110)
80 r5:c068bae8 r4:00000000
81 [<c00ff700>] (find_and_get_object+0x0/0x110) from [<c00ffdd8>] (scan_block+0x60/0x104)
82 r8:00000001 r7:c0e23795 r6:c0d76a70 r5:60000013 r4:00000000
83 [<c00ffd78>] (scan_block+0x0/0x104) from [<c010014c>] (kmemleak_scan+0x140/0x484)
84 [<c010000c>] (kmemleak_scan+0x0/0x484) from [<c01009a8>] (kmemleak_scan_thread+0x70/0xcc)
85 r8:00000000 r7:c0100938 r6:00000000 r5:c7c33f04 r4:00012c00
86 [<c0100938>] (kmemleak_scan_thread+0x0/0xcc) from [<c0088000>] (kthread+0x90/0x98)
87 r5:c7c33f04 r4:c760bfa8
88 [<c0087f70>] (kthread+0x0/0x98) from [<c006f5e8>] (do_exit+0x0/0x684)
89 r7:00000013 r6:c006f5e8 r5:c0087f70 r4:c7c33f04
90 Code: e3002312 e58d6000 e2833e16 eb0422d5 (e5963020)
91 ---[ end trace f3d5e96f75c297b7 ]---
92
93 Signed-off-by: Ming Lei <tom.leiming@gmail.com>
94 Reviewed-by: Sergei Shtylyov <sshtylyov@mvista.com>
95 Cc: David Brownell <dbrownell@users.sourceforge.net>
96 Cc: Anand Gadiyar <gadiyar@ti.com>
97 Cc: Mike Frysinger <vapier@gentoo.org>
98 Cc: Sergei Shtylyov <sshtylyov@ru.mvista.com>
99 Signed-off-by: Felipe Balbi <balbi@ti.com>
100 Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
101
102 ---
103 drivers/usb/musb/musb_gadget.c | 20 +++++++++++++++++---
104 1 file changed, 17 insertions(+), 3 deletions(-)
105
106 --- a/drivers/usb/musb/musb_gadget.c
107 +++ b/drivers/usb/musb/musb_gadget.c
108 @@ -568,11 +568,19 @@ static void rxstate(struct musb *musb, s
109 {
110 const u8 epnum = req->epnum;
111 struct usb_request *request = &req->request;
112 - struct musb_ep *musb_ep = &musb->endpoints[epnum].ep_out;
113 + struct musb_ep *musb_ep;
114 void __iomem *epio = musb->endpoints[epnum].regs;
115 unsigned fifo_count = 0;
116 - u16 len = musb_ep->packet_sz;
117 + u16 len;
118 u16 csr = musb_readw(epio, MUSB_RXCSR);
119 + struct musb_hw_ep *hw_ep = &musb->endpoints[epnum];
120 +
121 + if (hw_ep->is_shared_fifo)
122 + musb_ep = &hw_ep->ep_in;
123 + else
124 + musb_ep = &hw_ep->ep_out;
125 +
126 + len = musb_ep->packet_sz;
127
128 /* We shouldn't get here while DMA is active, but we do... */
129 if (dma_channel_status(musb_ep->dma) == MUSB_DMA_STATUS_BUSY) {
130 @@ -740,9 +748,15 @@ void musb_g_rx(struct musb *musb, u8 epn
131 u16 csr;
132 struct usb_request *request;
133 void __iomem *mbase = musb->mregs;
134 - struct musb_ep *musb_ep = &musb->endpoints[epnum].ep_out;
135 + struct musb_ep *musb_ep;
136 void __iomem *epio = musb->endpoints[epnum].regs;
137 struct dma_channel *dma;
138 + struct musb_hw_ep *hw_ep = &musb->endpoints[epnum];
139 +
140 + if (hw_ep->is_shared_fifo)
141 + musb_ep = &hw_ep->ep_in;
142 + else
143 + musb_ep = &hw_ep->ep_out;
144
145 musb_ep_select(mbase, epnum);
146