Pete Zaitcev wrote: > > When I saw it, two thoughts crossed my mind > 1. No need to cover malloc Right. Fixed in the attached patch. > > 2. Time to de-inline that function I'm not sure it's time yet. I'll leave that up to Dave Brownell. I also added locks in the lookup routine dma_to_ed_td(). It's always a fast lookup, and it's possible the list could change in the middle of the search either by interrupt code or another processor, although I don't think currently the add/free routines are called at interrupt time. Steve
--- drivers/usb/usb-ohci.h.orig Mon May 7 10:12:42 2001 +++ drivers/usb/usb-ohci.h Mon May 7 11:41:24 2001 @@ -453,16 +453,26 @@ /* to support non-PCI OHCIs, you need custom bus/mem/... glue */ #endif +/* Lock for TD/ED hashing */ +static spinlock_t usb_hash_lock = SPIN_LOCK_UNLOCKED; /* Recover a TD/ED using its collision chain */ static inline void * dma_to_ed_td (struct hash_list_t * entry, dma_addr_t dma) { - struct hash_t * scan = entry->head; + struct hash_t * scan; + unsigned long flags; + + spin_lock_irqsave (&usb_hash_lock, flags); + + scan = entry->head; while (scan && scan->dma != dma) scan = scan->next; if (!scan) BUG(); + + spin_unlock_irqrestore (&usb_hash_lock, flags); + return scan->virt; } @@ -480,16 +490,20 @@ td_dma); } + /* Add a hash entry for a TD/ED; return true on success */ static inline int hash_add_ed_td(struct hash_list_t * entry, void * virt, dma_addr_t dma) { struct hash_t * scan; - + unsigned long flags; + scan = (struct hash_t *)kmalloc(sizeof(struct hash_t), ALLOC_FLAGS); if (!scan) return 0; + spin_lock_irqsave (&usb_hash_lock, flags); + if (!entry->tail) { entry->head = entry->tail = scan; } else { @@ -500,6 +514,7 @@ scan->virt = virt; scan->dma = dma; scan->next = NULL; + spin_unlock_irqrestore (&usb_hash_lock, flags); return 1; } @@ -522,6 +537,10 @@ hash_free_ed_td (struct hash_list_t * entry, void * virt) { struct hash_t *scan, *prev; + unsigned long flags; + + spin_lock_irqsave (&usb_hash_lock, flags); + scan = prev = entry->head; // Find and unlink hash entry @@ -542,6 +561,7 @@ prev->next = scan->next; kfree(scan); } + spin_unlock_irqrestore (&usb_hash_lock, flags); } static inline void