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