I was able to crash the 5.0 firmware again today after a 7 hour run
This time I had the following patch applied:


Index: wireless-testing/drivers/net/wireless/b43/dma.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/b43/dma.c
+++ wireless-testing/drivers/net/wireless/b43/dma.c
@@ -40,6 +40,7 @@
 #include <linux/etherdevice.h>
 #include <asm/div64.h>

+static int b43_freeze = 0;

 /* 32bit DMA ops. */
 static
@@ -1292,6 +1293,8 @@ int b43_dma_tx(struct b43_wldev *dev, st
        unsigned long flags;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);

+       if (b43_freeze)
+               return -ENOMEM;
        hdr = (struct ieee80211_hdr *)skb->data;
        if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) {
                /* The multicast ring will be sent after the DTIM */
@@ -1372,7 +1375,11 @@ void b43_dma_handle_txstatus(struct b43_
        while (1) {
                B43_WARN_ON(!(slot >= 0 && slot < ring->nr_slots));
                desc = ops->idx2desc(ring, slot, &meta);
-
+               if (meta->skb == 0x6b6b6b6b) {
+                       printk(KERN_INFO "b43: Double call of b43_dma_handle_"
+                              "txstatus for cookie 0x%X\n", status->cookie);
+                       meta->skb = NULL;
+               }
                if (meta->skb)
                        unmap_descbuffer(ring, meta->dmaaddr, meta->skb->len,
                                         1);
@@ -1383,7 +1390,13 @@ void b43_dma_handle_txstatus(struct b43_
                if (meta->is_last_fragment) {
                        struct ieee80211_tx_info *info;

-                       BUG_ON(!meta->skb);
+                       if (!meta->skb) {
+                               printk(KERN_INFO "b43: Cookie is 0x%X for bad 
skb\n",
status->cookie);
+                               printk(KERN_INFO "b43: DMA Output is frozen\n");
+                               b43_freeze = 1;
+                               B43_WARN_ON(1);
+                               return;
+                       }

                        info = IEEE80211_SKB_CB(meta->skb);

@@ -1402,7 +1415,7 @@ void b43_dma_handle_txstatus(struct b43_
                        ieee80211_tx_status_irqsafe(dev->wl->hw, meta->skb);

                        /* skb is freed by ieee80211_tx_status_irqsafe() */
-                       meta->skb = NULL;
+                       meta->skb = 0x6b6b6b6b;
                } else {
                        /* No need to call free_descriptor_buffer here, as
                         * this is only the txhdr, which is not allocated.

Besides freezing TX when an error occurs, I also "poisoned" meta->skb rather 
than making
it NULL after the call to ieee80211_tx_status_irqsafe(). I could then detect a 
double call
with the same cookie, which is exactly what happened.

I will now have time to code a dump of shared memory when the error occurs, but 
we do know
what the mistake is.

Larry

_______________________________________________
Bcm43xx-dev mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/bcm43xx-dev

Reply via email to