Worked for me too, though I don't think I've seen that failure.

- Dave

----- Original Message ----- 
From: "Roman Weissgaerber" <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Cc: <[EMAIL PROTECTED]>
Sent: Tuesday, March 13, 2001 3:37 AM
Subject: [linux-usb-devel] pegasus driver


> Hi Petkan,
> 
> there are some races in the pegasus driver.
> 
> When you submit an URB please keep in mind that the 
> callback of the URB can be called earlier than
> the URB-submition returns. In this case you wake up the
> thread first and than put it to sleep.
> This **really** happens on
> a CPU time eating HC architecture.
> 
> The attached patch against kernel 2.4.2ac20 solves 
> this.
> 
> 
> - Roman


--------------------------------------------------------------------------------


> --- linux-2.4.2ac20/drivers/usb/pegasus.c Tue Mar 13 12:18:21 2001
> +++ usb/pegasus.c Tue Mar 13 12:23:09 2001
> @@ -124,7 +124,8 @@
>  static int get_registers(pegasus_t *pegasus, __u16 indx, __u16 size, void *data)
>  {
>   int ret;
> -
> + DECLARE_WAITQUEUE (wait, current);
> + 
>   while ( pegasus->flags & ETH_REGS_CHANGED ) {
>   pegasus->flags |= CTRL_URB_SLEEP;
>   interruptible_sleep_on( &pegasus->ctrl_wait );
> @@ -140,13 +141,18 @@
>     usb_rcvctrlpipe(pegasus->usb,0),
>     (char *)&pegasus->dr,
>     data, size, ctrl_callback, pegasus );
> -
> + 
> + add_wait_queue (&pegasus->ctrl_wait, &wait);   
> + set_current_state(TASK_INTERRUPTIBLE);
> + pegasus->flags |= CTRL_URB_SLEEP;
> + 
>   if ( (ret = usb_submit_urb( &pegasus->ctrl_urb )) ) {
>   err( __FUNCTION__ " BAD CTRLs %d", ret);
>   goto out;
>   }
> - pegasus->flags |= CTRL_URB_SLEEP;
> - interruptible_sleep_on( &pegasus->ctrl_wait );
> + 
> + schedule();
> + remove_wait_queue (&pegasus->ctrl_wait, &wait); 
>  out:
>   return ret;
>  }
> @@ -155,7 +161,8 @@
>  static int set_registers(pegasus_t *pegasus, __u16 indx, __u16 size, void *data)
>  {
>   int ret;
> -
> + DECLARE_WAITQUEUE (wait, current);
> + 
>   while ( pegasus->flags & ETH_REGS_CHANGED ) {
>   pegasus->flags |= CTRL_URB_SLEEP ;
>   interruptible_sleep_on( &pegasus->ctrl_wait );
> @@ -171,14 +178,18 @@
>     usb_sndctrlpipe(pegasus->usb,0),
>     (char *)&pegasus->dr,
>     data, size, ctrl_callback, pegasus );
> -
> +   
> + add_wait_queue (&pegasus->ctrl_wait, &wait);   
> + set_current_state(TASK_INTERRUPTIBLE);
> + pegasus->flags |= CTRL_URB_SLEEP;
> + 
>   if ( (ret = usb_submit_urb( &pegasus->ctrl_urb )) ) {
>   err( __FUNCTION__ " BAD CTRL %d", ret);
>   return ret;
>   }
> - pegasus->flags |= CTRL_URB_SLEEP;
> - interruptible_sleep_on( &pegasus->ctrl_wait );
> -
> + 
> + schedule();
> + remove_wait_queue (&pegasus->ctrl_wait, &wait); 
>   return ret;
>  }
>  
> @@ -187,7 +198,8 @@
>  {
>   int ret;
>   __u16 dat = data;
> - 
> + DECLARE_WAITQUEUE (wait, current);
> +
>   while ( pegasus->flags & ETH_REGS_CHANGED ) {
>   pegasus->flags |= CTRL_URB_SLEEP;
>   interruptible_sleep_on( &pegasus->ctrl_wait );
> @@ -204,13 +216,18 @@
>     (char *)&pegasus->dr,
>     &data, 1, ctrl_callback, pegasus );
>  
> + add_wait_queue (&pegasus->ctrl_wait, &wait);   
> + set_current_state(TASK_INTERRUPTIBLE);
> + pegasus->flags |= CTRL_URB_SLEEP;
> + 
>   if ( (ret = usb_submit_urb( &pegasus->ctrl_urb )) ) {
>   err( __FUNCTION__ " BAD CTRL %d", ret);
>   return ret;
>   }
> - pegasus->flags |= CTRL_URB_SLEEP;
> - interruptible_sleep_on( &pegasus->ctrl_wait );
>   
> + schedule();
> + remove_wait_queue (&pegasus->ctrl_wait, &wait); 
> +
>   return ret;
>  }
>  
> 


_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
http://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to