diff options
| -rw-r--r-- | drivers/net/wireless/b43legacy/dma.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c index 0023de8235bf..6e08405e8026 100644 --- a/drivers/net/wireless/b43legacy/dma.c +++ b/drivers/net/wireless/b43legacy/dma.c | |||
| @@ -1164,7 +1164,7 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring, | |||
| 1164 | { | 1164 | { |
| 1165 | const struct b43legacy_dma_ops *ops = ring->ops; | 1165 | const struct b43legacy_dma_ops *ops = ring->ops; |
| 1166 | u8 *header; | 1166 | u8 *header; |
| 1167 | int slot; | 1167 | int slot, old_top_slot, old_used_slots; |
| 1168 | int err; | 1168 | int err; |
| 1169 | struct b43legacy_dmadesc_generic *desc; | 1169 | struct b43legacy_dmadesc_generic *desc; |
| 1170 | struct b43legacy_dmadesc_meta *meta; | 1170 | struct b43legacy_dmadesc_meta *meta; |
| @@ -1174,6 +1174,9 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring, | |||
| 1174 | #define SLOTS_PER_PACKET 2 | 1174 | #define SLOTS_PER_PACKET 2 |
| 1175 | B43legacy_WARN_ON(skb_shinfo(skb)->nr_frags != 0); | 1175 | B43legacy_WARN_ON(skb_shinfo(skb)->nr_frags != 0); |
| 1176 | 1176 | ||
| 1177 | old_top_slot = ring->current_slot; | ||
| 1178 | old_used_slots = ring->used_slots; | ||
| 1179 | |||
| 1177 | /* Get a slot for the header. */ | 1180 | /* Get a slot for the header. */ |
| 1178 | slot = request_slot(ring); | 1181 | slot = request_slot(ring); |
| 1179 | desc = ops->idx2desc(ring, slot, &meta_hdr); | 1182 | desc = ops->idx2desc(ring, slot, &meta_hdr); |
| @@ -1184,8 +1187,11 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring, | |||
| 1184 | err = b43legacy_generate_txhdr(ring->dev, header, | 1187 | err = b43legacy_generate_txhdr(ring->dev, header, |
| 1185 | skb->data, skb->len, ctl, | 1188 | skb->data, skb->len, ctl, |
| 1186 | generate_cookie(ring, slot)); | 1189 | generate_cookie(ring, slot)); |
| 1187 | if (unlikely(err)) | 1190 | if (unlikely(err)) { |
| 1191 | ring->current_slot = old_top_slot; | ||
| 1192 | ring->used_slots = old_used_slots; | ||
| 1188 | return err; | 1193 | return err; |
| 1194 | } | ||
| 1189 | 1195 | ||
| 1190 | meta_hdr->dmaaddr = map_descbuffer(ring, (unsigned char *)header, | 1196 | meta_hdr->dmaaddr = map_descbuffer(ring, (unsigned char *)header, |
| 1191 | sizeof(struct b43legacy_txhdr_fw3), 1); | 1197 | sizeof(struct b43legacy_txhdr_fw3), 1); |
| @@ -1208,6 +1214,8 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring, | |||
| 1208 | if (dma_mapping_error(meta->dmaaddr)) { | 1214 | if (dma_mapping_error(meta->dmaaddr)) { |
| 1209 | bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA); | 1215 | bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA); |
| 1210 | if (!bounce_skb) { | 1216 | if (!bounce_skb) { |
| 1217 | ring->current_slot = old_top_slot; | ||
| 1218 | ring->used_slots = old_used_slots; | ||
| 1211 | err = -ENOMEM; | 1219 | err = -ENOMEM; |
| 1212 | goto out_unmap_hdr; | 1220 | goto out_unmap_hdr; |
| 1213 | } | 1221 | } |
| @@ -1218,6 +1226,8 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring, | |||
| 1218 | meta->skb = skb; | 1226 | meta->skb = skb; |
| 1219 | meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); | 1227 | meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); |
| 1220 | if (dma_mapping_error(meta->dmaaddr)) { | 1228 | if (dma_mapping_error(meta->dmaaddr)) { |
| 1229 | ring->current_slot = old_top_slot; | ||
| 1230 | ring->used_slots = old_used_slots; | ||
| 1221 | err = -EIO; | 1231 | err = -EIO; |
| 1222 | goto out_free_bounce; | 1232 | goto out_free_bounce; |
| 1223 | } | 1233 | } |
