diff options
author | Stanislaw Gruszka <sgruszka@redhat.com> | 2013-02-13 08:27:05 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-02-14 14:24:07 -0500 |
commit | 4ea545d476d3182056aeb042c439237ed61d261e (patch) | |
tree | a216861969701e1f48e64d829caf700966088980 /drivers/net/wireless/rt2x00 | |
parent | 52301a815e81cdcbcf971ba28df0376dc7f3961c (diff) |
rt2x00: check for dma mappings errors
Check output of dma_map_single functions which nowadays can fail (when
IOMMU is used). On write_beacon callbacks just print error, similar
like padding error is handled by rt2800_write_beacon.
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rt2x00')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2400pci.c | 12 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2500pci.c | 7 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00queue.c | 26 |
4 files changed, 36 insertions, 13 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index a2d2bc2c7b3d..221beaaa83f1 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c | |||
@@ -1185,8 +1185,14 @@ static void rt2400pci_write_beacon(struct queue_entry *entry, | |||
1185 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); | 1185 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); |
1186 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | 1186 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); |
1187 | 1187 | ||
1188 | rt2x00queue_map_txskb(entry); | 1188 | if (rt2x00queue_map_txskb(entry)) { |
1189 | 1189 | ERROR(rt2x00dev, "Fail to map beacon, aborting\n"); | |
1190 | goto out; | ||
1191 | } | ||
1192 | /* | ||
1193 | * Enable beaconing again. | ||
1194 | */ | ||
1195 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); | ||
1190 | /* | 1196 | /* |
1191 | * Write the TX descriptor for the beacon. | 1197 | * Write the TX descriptor for the beacon. |
1192 | */ | 1198 | */ |
@@ -1196,7 +1202,7 @@ static void rt2400pci_write_beacon(struct queue_entry *entry, | |||
1196 | * Dump beacon to userspace through debugfs. | 1202 | * Dump beacon to userspace through debugfs. |
1197 | */ | 1203 | */ |
1198 | rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb); | 1204 | rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb); |
1199 | 1205 | out: | |
1200 | /* | 1206 | /* |
1201 | * Enable beaconing again. | 1207 | * Enable beaconing again. |
1202 | */ | 1208 | */ |
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 9bea10f53f0a..39edc59e8d03 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c | |||
@@ -1338,7 +1338,10 @@ static void rt2500pci_write_beacon(struct queue_entry *entry, | |||
1338 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); | 1338 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); |
1339 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | 1339 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); |
1340 | 1340 | ||
1341 | rt2x00queue_map_txskb(entry); | 1341 | if (rt2x00queue_map_txskb(entry)) { |
1342 | ERROR(rt2x00dev, "Fail to map beacon, aborting\n"); | ||
1343 | goto out; | ||
1344 | } | ||
1342 | 1345 | ||
1343 | /* | 1346 | /* |
1344 | * Write the TX descriptor for the beacon. | 1347 | * Write the TX descriptor for the beacon. |
@@ -1349,7 +1352,7 @@ static void rt2500pci_write_beacon(struct queue_entry *entry, | |||
1349 | * Dump beacon to userspace through debugfs. | 1352 | * Dump beacon to userspace through debugfs. |
1350 | */ | 1353 | */ |
1351 | rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb); | 1354 | rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb); |
1352 | 1355 | out: | |
1353 | /* | 1356 | /* |
1354 | * Enable beaconing again. | 1357 | * Enable beaconing again. |
1355 | */ | 1358 | */ |
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 9a3f31a543ce..086abb403a4f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -1169,8 +1169,10 @@ static inline bool rt2x00_is_soc(struct rt2x00_dev *rt2x00dev) | |||
1169 | /** | 1169 | /** |
1170 | * rt2x00queue_map_txskb - Map a skb into DMA for TX purposes. | 1170 | * rt2x00queue_map_txskb - Map a skb into DMA for TX purposes. |
1171 | * @entry: Pointer to &struct queue_entry | 1171 | * @entry: Pointer to &struct queue_entry |
1172 | * | ||
1173 | * Returns -ENOMEM if mapping fail, 0 otherwise. | ||
1172 | */ | 1174 | */ |
1173 | void rt2x00queue_map_txskb(struct queue_entry *entry); | 1175 | int rt2x00queue_map_txskb(struct queue_entry *entry); |
1174 | 1176 | ||
1175 | /** | 1177 | /** |
1176 | * rt2x00queue_unmap_skb - Unmap a skb from DMA. | 1178 | * rt2x00queue_unmap_skb - Unmap a skb from DMA. |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index f35d85a71bbc..e26ec9d817cf 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
@@ -87,24 +87,35 @@ struct sk_buff *rt2x00queue_alloc_rxskb(struct queue_entry *entry, gfp_t gfp) | |||
87 | skbdesc->entry = entry; | 87 | skbdesc->entry = entry; |
88 | 88 | ||
89 | if (test_bit(REQUIRE_DMA, &rt2x00dev->cap_flags)) { | 89 | if (test_bit(REQUIRE_DMA, &rt2x00dev->cap_flags)) { |
90 | skbdesc->skb_dma = dma_map_single(rt2x00dev->dev, | 90 | dma_addr_t skb_dma; |
91 | skb->data, | 91 | |
92 | skb->len, | 92 | skb_dma = dma_map_single(rt2x00dev->dev, skb->data, skb->len, |
93 | DMA_FROM_DEVICE); | 93 | DMA_FROM_DEVICE); |
94 | if (unlikely(dma_mapping_error(rt2x00dev->dev, skb_dma))) { | ||
95 | dev_kfree_skb_any(skb); | ||
96 | return NULL; | ||
97 | } | ||
98 | |||
99 | skbdesc->skb_dma = skb_dma; | ||
94 | skbdesc->flags |= SKBDESC_DMA_MAPPED_RX; | 100 | skbdesc->flags |= SKBDESC_DMA_MAPPED_RX; |
95 | } | 101 | } |
96 | 102 | ||
97 | return skb; | 103 | return skb; |
98 | } | 104 | } |
99 | 105 | ||
100 | void rt2x00queue_map_txskb(struct queue_entry *entry) | 106 | int rt2x00queue_map_txskb(struct queue_entry *entry) |
101 | { | 107 | { |
102 | struct device *dev = entry->queue->rt2x00dev->dev; | 108 | struct device *dev = entry->queue->rt2x00dev->dev; |
103 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | 109 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
104 | 110 | ||
105 | skbdesc->skb_dma = | 111 | skbdesc->skb_dma = |
106 | dma_map_single(dev, entry->skb->data, entry->skb->len, DMA_TO_DEVICE); | 112 | dma_map_single(dev, entry->skb->data, entry->skb->len, DMA_TO_DEVICE); |
113 | |||
114 | if (unlikely(dma_mapping_error(dev, skbdesc->skb_dma))) | ||
115 | return -ENOMEM; | ||
116 | |||
107 | skbdesc->flags |= SKBDESC_DMA_MAPPED_TX; | 117 | skbdesc->flags |= SKBDESC_DMA_MAPPED_TX; |
118 | return 0; | ||
108 | } | 119 | } |
109 | EXPORT_SYMBOL_GPL(rt2x00queue_map_txskb); | 120 | EXPORT_SYMBOL_GPL(rt2x00queue_map_txskb); |
110 | 121 | ||
@@ -545,8 +556,9 @@ static int rt2x00queue_write_tx_data(struct queue_entry *entry, | |||
545 | /* | 556 | /* |
546 | * Map the skb to DMA. | 557 | * Map the skb to DMA. |
547 | */ | 558 | */ |
548 | if (test_bit(REQUIRE_DMA, &rt2x00dev->cap_flags)) | 559 | if (test_bit(REQUIRE_DMA, &rt2x00dev->cap_flags) && |
549 | rt2x00queue_map_txskb(entry); | 560 | rt2x00queue_map_txskb(entry)) |
561 | return -ENOMEM; | ||
550 | 562 | ||
551 | return 0; | 563 | return 0; |
552 | } | 564 | } |