USB: s3c2410_udc: be aware of connected gadget driver

To escape from data abort in interrupt handler, it is required to
check for a connected gadget before delivering control requests.

The change fixes the following panic, which occurs with no loaded
gadget driver and input USB_REQ_GET_DESCRIPTOR request:

Kernel panic - not syncing: Fatal exception in interrupt
[<c0025874>] (unwind_backtrace+0x0/0xd8) from [<c0253f14>] (panic+0x40/0x110)
[<c0253f14>] (panic+0x40/0x110) from [<c002470c>] (die+0x154/0x180)
[<c002470c>] (die+0x154/0x180) from [<c0026448>] (__do_kernel_fault+0x64/0x74)
[<c0026448>] (__do_kernel_fault+0x64/0x74) from [<c0026610>] (do_page_fault+0x1b8/0x1cc)
[<c0026610>] (do_page_fault+0x1b8/0x1cc) from [<c00202d4>] (do_DataAbort+0x34/0x94)
[<c00202d4>] (do_DataAbort+0x34/0x94) from [<c0020a60>] (__dabt_svc+0x40/0x60)
Exception stack(0xc0327ea8 to 0xc0327ef0)
7ea0:                   bf0026b0 c0327ef0 c0327ee4 00000000 bf002590 00000093
7ec0: 00000001 bf0026b0 bf002990 00000000 00000008 0000143d 00003f00 c0327ef0
7ee0: bf001364 bf001360 20000093 ffffffff
[<c0020a60>] (__dabt_svc+0x40/0x60) from [<bf001360>] (s3c2410_udc_irq+0x5b8/0x778 [s3c2410_udc])
[<bf001360>] (s3c2410_udc_irq+0x5b8/0x778 [s3c2410_udc]) from [<c0058aa0>] (handle_IRQ_event+0x3c/0x104)
[<c0058aa0>] (handle_IRQ_event+0x3c/0x104) from [<c005a428>] (handle_edge_irq+0x12c/0x164)
[<c005a428>] (handle_edge_irq+0x12c/0x164) from [<c0020068>] (asm_do_IRQ+0x68/0x88)
[<c0020068>] (asm_do_IRQ+0x68/0x88) from [<c0020aa4>] (__irq_svc+0x24/0xa0)

Signed-off-by: Vladimir Zapolskiy <vzapolskiy@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
Vladimir Zapolskiy 2010-06-29 23:36:26 +04:00 коммит произвёл Greg Kroah-Hartman
Родитель 83a4eae9ae
Коммит 00c05aabf2
1 изменённых файлов: 4 добавлений и 0 удалений

Просмотреть файл

@ -735,6 +735,10 @@ static void s3c2410_udc_handle_ep0_idle(struct s3c2410_udc *dev,
else else
dev->ep0state = EP0_OUT_DATA_PHASE; dev->ep0state = EP0_OUT_DATA_PHASE;
if (!dev->driver)
return;
/* deliver the request to the gadget driver */
ret = dev->driver->setup(&dev->gadget, crq); ret = dev->driver->setup(&dev->gadget, crq);
if (ret < 0) { if (ret < 0) {
if (dev->req_config) { if (dev->req_config) {