# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.236 -> 1.237 # drivers/usb/uhci.c 1.22 -> 1.23 # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 02/03/22 johannes@erdfelt.com 1.237 # USB uhci driver update # # (3 updates in one, greg k-h merged them) # # *** # [PATCH] uhci.c 2.4.19-pre3 kmem_cache_alloc flags # # My previous patch which cleaned up some of the spinlocks, moved one of # the spinlocks around a call to kmem_cache_alloc. It would sometimes # erroneously call it with GFP_KERNEL. # # This patch fixes the problem by always calling it with GFP_ATOMIC. # Thanks to Greg for pointing this out to me. # # *** # [PATCH] uhci.c 2.4.19-pre3 erroneous completion callback # # uhci.c would call the completion callback when the call to submit_urb # failed. This is a rare situation. # # This patch only calls the completion handler if the URB successfully # completed immediately (as in the case of talking to the virtual root # hub). # # *** # [PATCH] uhci.c 2.4.19-pre3 interrupt deadlock # # Unfortunately, I left out one line from my spinlock cleanup patch # recently. # # As a result, using interrupt URB's could cause a deadlock on SMP # kernels. # -------------------------------------------- # diff -Nru a/drivers/usb/uhci.c b/drivers/usb/uhci.c --- a/drivers/usb/uhci.c Fri Mar 22 15:48:27 2002 +++ b/drivers/usb/uhci.c Fri Mar 22 15:48:27 2002 @@ -618,7 +618,7 @@ { struct urb_priv *urbp; - urbp = kmem_cache_alloc(uhci_up_cachep, in_interrupt() ? SLAB_ATOMIC : SLAB_KERNEL); + urbp = kmem_cache_alloc(uhci_up_cachep, SLAB_ATOMIC); if (!urbp) { err("uhci_alloc_urb_priv: couldn't allocate memory for urb_priv\n"); return NULL; @@ -1585,7 +1585,9 @@ spin_unlock(&urb->lock); spin_unlock_irqrestore(&uhci->urb_list_lock, flags); - uhci_call_completion(urb); + /* Only call completion if it was successful */ + if (!ret) + uhci_call_completion(urb); return ret; } @@ -1651,6 +1653,7 @@ /* Interrupts are an exception */ if (urb->interval) { uhci_add_complete(urb); + spin_unlock_irqrestore(&urb->lock, flags); return; /* <-- note return */ }