Author: bschmidt
Date: Sun Jan  2 10:01:29 2011
New Revision: 216886
URL: http://svn.freebsd.org/changeset/base/216886

Log:
  MFC r216824:
  The RX path is missing a few bus_dmamap_*() calls, this results in
  modification of memory which was already free'd and eventually in:
  wpi0: could not map mbuf (error 12)
  wpi0: wpi_rx_intr: bus_dmamap_load failed, error 12
  and an usuable device.
  
  PR:           kern/144898
  Approved by:  re (kib)

Modified:
  releng/8.2/sys/dev/wpi/if_wpi.c
Directory Properties:
  releng/8.2/sys/   (props changed)
  releng/8.2/sys/amd64/include/xen/   (props changed)
  releng/8.2/sys/cddl/contrib/opensolaris/   (props changed)
  releng/8.2/sys/contrib/dev/acpica/   (props changed)
  releng/8.2/sys/contrib/pf/   (props changed)

Modified: releng/8.2/sys/dev/wpi/if_wpi.c
==============================================================================
--- releng/8.2/sys/dev/wpi/if_wpi.c     Sun Jan  2 09:03:53 2011        
(r216885)
+++ releng/8.2/sys/dev/wpi/if_wpi.c     Sun Jan  2 10:01:29 2011        
(r216886)
@@ -1052,9 +1052,18 @@ wpi_free_rx_ring(struct wpi_softc *sc, s
 
        wpi_dma_contig_free(&ring->desc_dma);
 
-       for (i = 0; i < WPI_RX_RING_COUNT; i++)
-               if (ring->data[i].m != NULL)
-                       m_freem(ring->data[i].m);
+       for (i = 0; i < WPI_RX_RING_COUNT; i++) {
+               struct wpi_rx_data *data = &ring->data[i];
+
+               if (data->m != NULL) {
+                       bus_dmamap_sync(ring->data_dmat, data->map,
+                           BUS_DMASYNC_POSTREAD);
+                       bus_dmamap_unload(ring->data_dmat, data->map);
+                       m_freem(data->m);
+               }
+               if (data->map != NULL)
+                       bus_dmamap_destroy(ring->data_dmat, data->map);
+       }
 }
 
 static int
@@ -1461,6 +1470,7 @@ wpi_rx_intr(struct wpi_softc *sc, struct
                return;
        }
 
+       bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_POSTREAD);
        head = (struct wpi_rx_head *)((caddr_t)(stat + 1) + stat->len);
        tail = (struct wpi_rx_tail *)((caddr_t)(head + 1) + le16toh(head->len));
 
@@ -1491,6 +1501,8 @@ wpi_rx_intr(struct wpi_softc *sc, struct
                ifp->if_ierrors++;
                return;
        }
+       bus_dmamap_unload(ring->data_dmat, data->map);
+
        error = bus_dmamap_load(ring->data_dmat, data->map,
            mtod(mnew, caddr_t), MJUMPAGESIZE,
            wpi_dma_map_addr, &paddr, BUS_DMA_NOWAIT);
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to