It seems usb_unlink_urb(submitted_urb) causes a kernel
oops if called after the usbcore completes usb_disconnect(),
during fileop->close(), when the device is hardware-disconnected
while streaming.
                                                                          
Below is the oops from the kernel and (part of) the code calling
usb_unlink_urb(). The same code used to work on previous versions of the kernel.

Unable to handle kernel paging request at virtual address 6b6b6b8b
 printing eip:
c0207cf8
*pde = 00000000
Oops: 0000 [#1]
PREEMPT
Modules linked in: w9968cf_vpp ovcamchip w9968cf floppy ehci_hcd uhci_hcd ipt_TCPMSS 
ipt_state ipt_limit ipt_MASQUERADE iptable_nat ip_conntrack ipt_TOS ipt_multiport 
iptable_mangle ppp_synctty ppp_async iptable_filter ip_tables 8139too mii crc32 
ide_scsi scsi_mod ide_cd cdrom rtc
CPU:    0
EIP:    0060:[<c0207cf8>]    Not tainted
EFLAGS: 00210202   (2.6.7-rc1-bk1)
EIP is at usb_unlink_urb+0x18/0x30
eax: c3fe5d04   ebx: 00000001   ecx: 00000001   edx: 6b6b6b6b
esi: c2922084   edi: c36b40ec   ebp: c28a2f64   esp: c28a2f64
ds: 007b   es: 007b   ss: 0068
Process xawtv (pid: 4786, threadinfo=c28a2000 task=c336a710)
Stack: c28a2f7c c4968258 01922084 c2922084 c29227d0 c10931f4 c28a2f8c c496c80a
       c12eca88 00000000 c28a2fa8 c014c797 c345c96c c2e1f2d0 c12eca88 00000000
       c2f48750 c28a2fbc c014b086 00000004 08097ed0 40189884 c28a2000 c0105e47
Call Trace:
 [<c0106445>] show_stack+0x75/0x90
 [<c0106595>] show_registers+0x115/0x170
 [<c01066f2>] die+0x82/0xf0
 [<c0112a7e>] do_page_fault+0x20e/0x531
 [<c01060ad>] error_code+0x2d/0x40
 [<c4968258>] w9968cf_stop_transfer+0x158/0x1a0 [w9968cf]
 [<c496c80a>] w9968cf_release+0x2a/0xe0 [w9968cf]
 [<c014c797>] __fput+0x127/0x140
 [<c014b086>] filp_close+0x46/0x70
 [<c0105e47>] syscall_call+0x7/0xb
 
Code: 8b 52 20 85 d2 75 08 90 b8 ed ff ff ff 5d c3 ff 52 10 eb f9


static void w9968cf_stop_transfer(struct w9968cf_device* cam)
{
        struct usb_device *udev = cam->usbdev;

        ...
 
        for (i = W9968CF_URBS-1; i >= 0; i--)
                if (cam->urb[i]) {
                        if (!usb_unlink_urb(cam->urb[i])) {
                                /* From urb.c: "Successful cancelation means
                                   the request's completion handler _will be_
                                   called with a [-ENOENT] status code
                                   indicating that the request has been
                                   canceled". This means we can wait for it to
                                   wake up this code: */
                                wait_for_completion(&cam->urb_complete);
                                usb_free_urb(cam->urb[i]);
                                cam->urb[i] = NULL;
                        }
                }

        ...
}

static void w9968cf_urb_complete()
{
        if (urb->status == -ENOENT) {
                complete(&cam->urb_complete);
                return;
        }
        ....
}


-------------------------------------------------------
This SF.Net email is sponsored by: Oracle 10g
Get certified on the hottest thing ever to hit the market... Oracle 10g. 
Take an Oracle 10g class now, and we'll give you the exam FREE.
http://ads.osdn.com/?ad_id=3149&alloc_id=8166&op=click
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to