Hello Greg:
Thanks for your response.
I observed if I set the interrupt interval to 8(just try) I found the
problem was disappeared. Surprise remove is ok. 
Unfortunately, the system crashed during transiting packets with long
packets.
The following code I captured from our driver. My kernel version is
version 2.6.11-1.1368_fc4.

Best regards,

Wei-Shun Liao
#===============================================================
Here is the function the driver initialize all urbs
#================================================================
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
#define wb_usb_alloc_urb(_A) usb_alloc_urb(_A)
#else
#define wb_usb_alloc_urb(_A) usb_alloc_urb(_A,GFP_ATOMIC)
#endif

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
#define wb_usb_submit_urb(_A) usb_submit_urb(_A)
#else
#define wb_usb_submit_urb(_A) usb_submit_urb(_A,GFP_KERNEL)
#endif

int alloc_all_urbs(PWBUSB wbusb)
{       
    #ifdef _PE_USB_INI_DUMP_
    WBDEBUG(("[ws]alloc_all_urbs ->\n"));
    #endif
    //to allocate an urb for bulk control or interupt transfer the first
argument is "0"
    wbusb->rx_urb = wb_usb_alloc_urb(0);
        if (!wbusb->rx_urb)
                return 0;
        wbusb->tx_urb = wb_usb_alloc_urb(0);
        if (!wbusb->tx_urb) {
                usb_free_urb(wbusb->rx_urb);
                return 0;
        }
        wbusb->intr_urb = wb_usb_alloc_urb(0);//urb interrupt allocated
        if (!wbusb->intr_urb) {
                usb_free_urb(wbusb->rx_urb);
                usb_free_urb(wbusb->tx_urb);
                return 0;
        }
        #ifdef _PE_USB_INI_DUMP_
                WBDEBUG(("Interrupt urb alloc ok\n"));
        #endif
/*      wbusb->ctrl_urb = usb_alloc_urb(0);
        if (!wbusb->intr_urb) {
                usb_free_urb(wbusb->rx_urb);
                usb_free_urb(wbusb->tx_urb);
                usb_free_urb(wbusb->intr_urb);
                return 0;
        }
*/
        #ifdef _PE_USB_INI_DUMP_
        WBDEBUG(("[ws]alloc_all_urbs <-\n"));
    #endif
        return 1;
}
#===========================================================
Here is the function the driver submit urb
#===========================================================

VOID Wb35Tx_EP2VM( IN PVOID p )
{
        phw_data_t  pHwData=p;
        PWBUSB          pWbusb = &pHwData->wbusb;
        ///struct usb_endpoint_descriptor
*intendpoint=pWbusb->intendpoint;
        struct usb_device *     usbdev=pHwData->wbusb.udev;
        PWB35TX pWb35Tx = &pHwData->Wb35Tx;
        PURB    pUrb = pHwData->wbusb.intr_urb; 
        int     retv=0;
        do
        {
            #ifdef _PE_TX_DUMP_
                WBDEBUG(("Wb35Tx_EP2VM--->\n"));
        #endif 
                if( pHwData->SurpriseRemove || pWb35Tx->tx_halt )
                        break;
                // Clear the count
                pWb35Tx->EP2_buf[0] = 0;
                //WBDEBUG(("the USB DEVICE speed =
%d\n",usbdev->speed));
                #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
                 usb_fill_int_urb( pUrb, usbdev,
usb_rcvintpipe(usbdev,2) 
                        ,pWb35Tx->EP2_buf, MAX_INTERRUPT_LENGTH  
                        ,Wb35Tx_EP2VM_complete,pHwData,32);
                #else
                usb_fill_int_urb(pUrb, usbdev, usb_rcvintpipe(usbdev,2) 
                        ,pWb35Tx->EP2_buf, MAX_INTERRUPT_LENGTH  
                        ,Wb35Tx_EP2VM_complete,pHwData,1);
                #endif
                if((retv=wb_usb_submit_urb(pUrb))<0)
                {
                        #ifdef _PE_TX_DUMP_
                        WBDEBUG(("EP2 Tx Irp sending error=%d\n",retv));
                        #endif
                        break;
                }
        #ifdef _PE_TX_DUMP_
                WBDEBUG(("Wb35Tx_EP2VM_ok<---\n"));
        #endif
                return;
        }while(FALSE);
    #ifdef _PE_TX_DUMP_
        WBDEBUG(("Wb35Tx_EP2VM_fail<---\n"));
    #endif
        pWb35Tx->EP2vm_state = VM_STOP;
        OS_ATOMIC_DEC( &pWb35Tx->TxResultCount );
}

#===============================================================
Here is the callback function for usb_submit_urb()
#================================================================
VOID Wb35Tx_EP2VM_complete(struct urb *purb)
{
        T02_DESCRIPTOR  T02;
        phw_data_t      pHwData = purb->context;
        PADAPTER        Adapter = (PADAPTER)pHwData->Adapter;
        PWB35TX         pWb35Tx = &pHwData->Wb35Tx;
        PULONG          pltmp = (PULONG)pWb35Tx->EP2_buf;
        ULONG           i;
        #ifdef _PE_TX_DUMP_
        WBDEBUG(("Wb35Tx_EP2VM_complete--->\n"));
        #endif

        if( purb->status==0 )
        {
                pWb35Tx->EP2vm_state = VM_COMPLETED;

                // Update the Tx result
                // Modify for minimum memory access and DWORD alignment.
Little endian is required
                T02.value = pltmp[0] >> 8; // [31:8] -> [24:0]
                for( i=1; i<=(pltmp[0]&0xff); i++ ) // (pltmp[0]&0xff)
is Tx result count.
                {
                        T02.value |= ((pltmp[i] & 0xff) << 24);
                        Mds_SendComplete( Adapter, &T02 );
                        T02.value = pltmp[i] >> 8;
                }
                // Start to get the next result, if previous Irp return
OK
                pWb35Tx->EP2vm_state = VM_RUNNING;
                
                Wb35Tx_EP2VM( pHwData );
        }
        #ifdef _PE_TX_DUMP_
        WBDEBUG(("Wb35Tx_EP2VM_complete<---\n"));
    #endif
}
#================================================================
Here are the functions to kill and free urb
#================================================================
VOID Wb35Tx_stop( IN PVOID p )
{
        phw_data_t  pHwData=p;
        PWB35TX pWb35Tx = &pHwData->Wb35Tx;
        PURB pTxUrb  = pHwData->wbusb.tx_urb;
        PURB pIntrUrb = pHwData->wbusb.intr_urb;
        if( pWb35Tx->EP2vm_state == VM_RUNNING )
        {
        #if LINUX_VERSION_CODE< KERNEL_VERSION(2,5,0)
                usb_unlink_urb(pIntrUrb);// <--- interrupt endpoint
        #else
                usb_kill_urb(pIntrUrb); //<--- interrupt endpoint
        #endif
        #ifdef _PE_TX_DUMP_
                WBDEBUG(("EP2 Tx stop\n"));
        #endif
                pWb35Tx->EP2vm_state= VM_STOP;
        }

        if( pWb35Tx->EP4vm_state == VM_RUNNING )
        {
        #if LINUX_VERSION_CODE< KERNEL_VERSION(2,5,0)
                usb_unlink_urb(pTxUrb); //<--- Tx endpoint
        #else
                usb_kill_urb(pTxUrb); //<--- Tx endpoint
        #endif
                #ifdef _PE_TX_DUMP_
                WBDEBUG(("EP4 Tx stop\n"));
                #endif
        }
}

VOID Wb35Tx_destroy( IN PVOID p )
{
        phw_data_t  pHwData=p;
        PURB        pTxUrb  = pHwData->wbusb.tx_urb;
        PURB        pIntrUrb = pHwData->wbusb.intr_urb;
    
    usb_free_urb( pTxUrb );
    usb_free_urb( pIntrUrb );//<--- interrupt endpoint
#ifdef _PE_TX_DUMP_
        WBDEBUG(("Wb35TX_destory\n"));
#endif
}













-----Original Message-----
From: Greg KH [mailto:[EMAIL PROTECTED] 
Sent: Thursday, December 15, 2005 7:06 AM
To: PD43 WSLiao0
Cc: linux-usb-devel@lists.sourceforge.net
Subject: Re: [linux-usb-devel] ~surprise remove problem~

On Wed, Dec 14, 2005 at 01:11:55PM +0800, [EMAIL PROTECTED] wrote:
> Dear all:
> 
> I am doing porting task for our company wireless NIC driver from 2.4.x
> to 2.6.x.
> I got a problem about the surprise remove after loading driver
> successfully.
> The system was crashed and halted, when plug out the NIC without
typing"
> rmmod xxx".
> However, if plugging out NIC after typing" rmmod xxx ". It was ok.
> On the hand, I also tried to mark the code of interrupt endpoint to
> submit interrupt urb.
> The problem disappeared and I saw the system tried to call disconnect
> function in our driver. 
> Therefore, I doubt the USB core doesn't support surprise remove for
> interrupt endpoint.
> Can any one give me any suggestion or advice to solve this problem?

Hm, it should "just work", unless you have a bug in your driver :)

Have a pointer to your driver anywhere so we can take a look?

thanks,

greg k-h

===========================================================================================The
 privileged confidential information contained in this email is intended for 
use only by the addressees as indicated by the original sender of this email. 
If you are not the addressee indicated in this email or are not responsible for 
delivery of the email to such  a person, please kindly reply to the sender 
indicating this fact and delete all copies of it from your computer and network 
server immediately. Your cooperation is highly appreciated. It is advised that 
any unauthorized use of confidential information of Winbond is strictly 
prohibited; and any information in this email irrelevant to the official 
business of Winbond shall be deemed as neither given nor endorsed by Winbond.
===========================================================================================If
 your computer is unable to decode Chinese font, please ignore the following 
message.It essentially repeats the statement in English given 
above.¥»«H¥ó¤º©Ò§tµØ¨¹¹q¤lªº°]²£©Ê¾÷±K©Ê¸ê°T, 
¶È±ÂÅv­ìµo«H¤H«ü©w¤§¦¬«H¤H¨ú¾\\¤§¥Î. 
°²¨Ï±z¨Ã«D³Q«ü©w¤§¦¬«H¤H©Î¦]¥ô¦ó­ì¦]¦b¥¼¸g±ÂÅvªº±¡§Î¤§¤U¦¬¨ì¥»«H¥ó, 
½Ð±z§iª¾­ìµo«H¤H¨Ã¥ß§Y±N«H¥ó±q¹q¸£»Pºô¸ô¦øªA¾¹¤¤¤©¥H®ø°£. ¹ï©ó±zªº¦X§@, 
§Ú­Ì¥ý¦¹­PÁÂ. ¯S¦¹´£¿ô, 
¥ô¦ó¥¼¸g±ÂÅv¾Õ¦Û¨Ï¥ÎµØ¨¹¹q¤lªº¾÷±K¸ê°Tªº¦æ¬°¬O³QÄY®æ¸T¤îªº. 
«H¥ó»PµØ¨¹¹q¤lÀç·~µLÃö¤§¤º®e,¤£±oµø¬°µØ¨¹¹q¤l¤§¥ß³õ©Î·N¨£.


-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems?  Stop!  Download the new AJAX search engine that makes
searching your log files as easy as surfing the  web.  DOWNLOAD SPLUNK!
http://ads.osdn.com/?ad_idv37&alloc_id865&op=click
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to