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 | } |