===================================================================
@@ -505,6 +505,7 @@ td_fill (struct ohci_hcd *ohci, u32 info
struct urb_priv *urb_priv = urb->hcpriv;
int is_iso = info & TD_ISO;
int hash;
+ volatile struct td * volatile td1, * volatile td2;
// ASSERT (index < urb_priv->length);
@@ -558,11 +559,30 @@ td_fill (struct ohci_hcd *ohci, u32 info
/* hash it for later reverse mapping */
hash = TD_HASH_FUNC (td->td_dma);
+
+ td1 = ohci->td_hash[hash];
+ td2 = NULL;
+ if (td1) {
+ td2 = td1->td_hash;
+ if (td2 == td1 || td2 == td) {
+ ohci_err(ohci, "Circular hash: %d %p %p %p\n",
+ hash, td1, td2, td);
+ td2 = td1->td_hash = NULL;
+ }
+ }
+
td->td_hash = ohci->td_hash [hash];
ohci->td_hash [hash] = td;
/* HC might read the TD (or cachelines) right away ... */
wmb ();
+
+ if (td1 && td1->td_hash != td2) {
+ ohci_err(ohci, "Hash value changed: %d %p %p %p\n",
+ hash, td1, td2, td);
+ td1->td_hash = (struct td *) td2;
+ }
+
td->ed->hwTailP = td->hwNextTD;
}