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