diff options
author | Larry Finger <Larry.Finger@lwfinger.net> | 2009-10-30 12:58:21 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-10-30 16:50:40 -0400 |
commit | d2d8cda7fc0b7a133492e70332217a7f20757615 (patch) | |
tree | 0b958bd40c37ac67f09c753ef0a2ae467e61af3c /drivers | |
parent | e6e898cfea5f35d64f850277e7fa295c386cf953 (diff) |
b43legacy: Fix DMA TX bounce buffer copying
This patch is adapted from the submission by Michael Buesch <mb@bu3sch.de>
for a bounce-buffer copying problem with b43.
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/b43legacy/dma.c | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c index 866403415811..0a86bdf53154 100644 --- a/drivers/net/wireless/b43legacy/dma.c +++ b/drivers/net/wireless/b43legacy/dma.c | |||
@@ -1240,8 +1240,9 @@ struct b43legacy_dmaring *parse_cookie(struct b43legacy_wldev *dev, | |||
1240 | } | 1240 | } |
1241 | 1241 | ||
1242 | static int dma_tx_fragment(struct b43legacy_dmaring *ring, | 1242 | static int dma_tx_fragment(struct b43legacy_dmaring *ring, |
1243 | struct sk_buff *skb) | 1243 | struct sk_buff **in_skb) |
1244 | { | 1244 | { |
1245 | struct sk_buff *skb = *in_skb; | ||
1245 | const struct b43legacy_dma_ops *ops = ring->ops; | 1246 | const struct b43legacy_dma_ops *ops = ring->ops; |
1246 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 1247 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
1247 | u8 *header; | 1248 | u8 *header; |
@@ -1305,8 +1306,14 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring, | |||
1305 | } | 1306 | } |
1306 | 1307 | ||
1307 | memcpy(skb_put(bounce_skb, skb->len), skb->data, skb->len); | 1308 | memcpy(skb_put(bounce_skb, skb->len), skb->data, skb->len); |
1309 | memcpy(bounce_skb->cb, skb->cb, sizeof(skb->cb)); | ||
1310 | bounce_skb->dev = skb->dev; | ||
1311 | skb_set_queue_mapping(bounce_skb, skb_get_queue_mapping(skb)); | ||
1312 | info = IEEE80211_SKB_CB(bounce_skb); | ||
1313 | |||
1308 | dev_kfree_skb_any(skb); | 1314 | dev_kfree_skb_any(skb); |
1309 | skb = bounce_skb; | 1315 | skb = bounce_skb; |
1316 | *in_skb = bounce_skb; | ||
1310 | meta->skb = skb; | 1317 | meta->skb = skb; |
1311 | meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); | 1318 | meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); |
1312 | if (b43legacy_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) { | 1319 | if (b43legacy_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) { |
@@ -1360,8 +1367,10 @@ int b43legacy_dma_tx(struct b43legacy_wldev *dev, | |||
1360 | struct sk_buff *skb) | 1367 | struct sk_buff *skb) |
1361 | { | 1368 | { |
1362 | struct b43legacy_dmaring *ring; | 1369 | struct b43legacy_dmaring *ring; |
1370 | struct ieee80211_hdr *hdr; | ||
1363 | int err = 0; | 1371 | int err = 0; |
1364 | unsigned long flags; | 1372 | unsigned long flags; |
1373 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
1365 | 1374 | ||
1366 | ring = priority_to_txring(dev, skb_get_queue_mapping(skb)); | 1375 | ring = priority_to_txring(dev, skb_get_queue_mapping(skb)); |
1367 | spin_lock_irqsave(&ring->lock, flags); | 1376 | spin_lock_irqsave(&ring->lock, flags); |
@@ -1386,7 +1395,11 @@ int b43legacy_dma_tx(struct b43legacy_wldev *dev, | |||
1386 | goto out_unlock; | 1395 | goto out_unlock; |
1387 | } | 1396 | } |
1388 | 1397 | ||
1389 | err = dma_tx_fragment(ring, skb); | 1398 | /* dma_tx_fragment might reallocate the skb, so invalidate pointers pointing |
1399 | * into the skb data or cb now. */ | ||
1400 | hdr = NULL; | ||
1401 | info = NULL; | ||
1402 | err = dma_tx_fragment(ring, &skb); | ||
1390 | if (unlikely(err == -ENOKEY)) { | 1403 | if (unlikely(err == -ENOKEY)) { |
1391 | /* Drop this packet, as we don't have the encryption key | 1404 | /* Drop this packet, as we don't have the encryption key |
1392 | * anymore and must not transmit it unencrypted. */ | 1405 | * anymore and must not transmit it unencrypted. */ |