aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorStefano Brivio <stefano.brivio@polimi.it>2008-02-02 13:16:03 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-02-05 14:35:46 -0500
commit8dd0100ce9511e52614ecd0a6587c13ce5769c8b (patch)
tree0c3e89e2b154f2f778d6a0ae84006817ef275ebb /drivers
parent9eca9a8e81928685b4de00ecef83a7c13c340fc9 (diff)
b43legacy: fix DMA slot resource leakage
This fixes four resource leakages. In any error path we must deallocate the DMA frame slots we previously allocated by request_slot(). This is done by storing the ring pointers before doing any ring allocation and restoring the old pointers in case of an error. This patch by Michael Buesch has been ported to b43legacy. Cc: Michael Buesch <mb@bu3sch.de> Signed-off-by: Stefano Brivio <stefano.brivio@polimi.it> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/b43legacy/dma.c14
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 }