On Wed, 30 Aug 2006, David Brownell wrote:

> [ Resend ... Greg, this one should likely merge to 2.6.18, and I don't
> think I saw any other fix for this in your current patchset ]
> 
> This fixes a locking problem reported by the new lock debug tools which, while
> very cryptic, gave Alan Stern enough info to finger the problem: a routine
> wrongly enabled IRQs on exit, by using the wrong locking/irq primitives. 
> 
> This patch switches back to the primitives which save/restore IRQ flags.
> 
> Signed-off-by: David Brownell <[EMAIL PROTECTED]>
> 
> Index: g26/drivers/usb/core/hcd.c
> ===================================================================
> --- g26.orig/drivers/usb/core/hcd.c   2006-07-03 10:45:18.000000000 -0700
> +++ g26/drivers/usb/core/hcd.c        2006-07-25 14:00:14.000000000 -0700
> @@ -632,31 +632,33 @@ static int rh_urb_enqueue (struct usb_hc
>  
>  /*-------------------------------------------------------------------------*/
>  
> -/* Asynchronous unlinks of root-hub control URBs are legal, but they
> - * don't do anything.  Status URB unlinks must be made in process context
> - * with interrupts enabled.
> +/* Root hub control URBs are synchronous, so unlinking would be pointless.
> + * Status URBs may not be unlinked from interrupts (del_timer_sync rule).
>   */
>  static int usb_rh_urb_dequeue (struct usb_hcd *hcd, struct urb *urb)
>  {
> +     unsigned long   flags;
> +
>       if (usb_pipeendpoint(urb->pipe) == 0) { /* Control URB */
>               if (in_interrupt())
>                       return 0;               /* nothing to do */
>  
> -             spin_lock_irq(&urb->lock);      /* from usb_kill_urb */
> -             ++urb->reject;
> -             spin_unlock_irq(&urb->lock);
> +             spin_lock_irqsave(&urb->lock, flags);
> +             ++urb->reject;                  /* like usb_kill_urb */
> +             spin_unlock_irqrestore(&urb->lock, flags);
>  
>               wait_event(usb_kill_urb_queue,
>                               atomic_read(&urb->use_count) == 0);
>  
> -             spin_lock_irq(&urb->lock);
> +             spin_lock_irqsave(&urb->lock, flags);
>               --urb->reject;
> -             spin_unlock_irq(&urb->lock);
> +             spin_unlock_irqrestore(&urb->lock, flags);
>  
>       } else {                                /* Status URB */
>               if (!hcd->uses_new_polling)
>                       del_timer_sync (&hcd->rh_timer);
> -             local_irq_disable ();
> +
> +             local_irq_save (flags);
>               spin_lock (&hcd_root_hub_lock);
>               if (urb == hcd->status_urb) {
>                       hcd->status_urb = NULL;
> @@ -666,7 +668,7 @@ static int usb_rh_urb_dequeue (struct us
>               spin_unlock (&hcd_root_hub_lock);
>               if (urb)
>                       usb_hcd_giveback_urb (hcd, urb, NULL);
> -             local_irq_enable ();
> +             local_irq_restore (flags);
>       }
>  
>       return 0;
> 
> 

Oops, crossed lines.  Greg, this patch isn't needed.  One that you have 
already applied (as754) takes care of the problem.

Alan Stern


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to