Skip to content

Commit 561aa0e

Browse files
Thomas-fourierdavem330
authored andcommitted
nui: Fix dma_mapping_error() check
dma_map_XXX() functions return values DMA_MAPPING_ERROR as error values which is often ~0. The error value should be tested with dma_mapping_error(). This patch creates a new function in niu_ops to test if the mapping failed. The test is fixed in niu_rbr_add_page(), added in niu_start_xmit() and the successfully mapped pages are unmaped upon error. Fixes: ec2deec ("niu: Fix to check for dma mapping errors.") Signed-off-by: Thomas Fourier <[email protected]> Reviewed-by: Simon Horman <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 34a500c commit 561aa0e

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

drivers/net/ethernet/sun/niu.c

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3336,7 +3336,7 @@ static int niu_rbr_add_page(struct niu *np, struct rx_ring_info *rp,
33363336

33373337
addr = np->ops->map_page(np->device, page, 0,
33383338
PAGE_SIZE, DMA_FROM_DEVICE);
3339-
if (!addr) {
3339+
if (np->ops->mapping_error(np->device, addr)) {
33403340
__free_page(page);
33413341
return -ENOMEM;
33423342
}
@@ -6676,6 +6676,8 @@ static netdev_tx_t niu_start_xmit(struct sk_buff *skb,
66766676
len = skb_headlen(skb);
66776677
mapping = np->ops->map_single(np->device, skb->data,
66786678
len, DMA_TO_DEVICE);
6679+
if (np->ops->mapping_error(np->device, mapping))
6680+
goto out_drop;
66796681

66806682
prod = rp->prod;
66816683

@@ -6717,6 +6719,8 @@ static netdev_tx_t niu_start_xmit(struct sk_buff *skb,
67176719
mapping = np->ops->map_page(np->device, skb_frag_page(frag),
67186720
skb_frag_off(frag), len,
67196721
DMA_TO_DEVICE);
6722+
if (np->ops->mapping_error(np->device, mapping))
6723+
goto out_unmap;
67206724

67216725
rp->tx_buffs[prod].skb = NULL;
67226726
rp->tx_buffs[prod].mapping = mapping;
@@ -6741,6 +6745,19 @@ static netdev_tx_t niu_start_xmit(struct sk_buff *skb,
67416745
out:
67426746
return NETDEV_TX_OK;
67436747

6748+
out_unmap:
6749+
while (i--) {
6750+
const skb_frag_t *frag;
6751+
6752+
prod = PREVIOUS_TX(rp, prod);
6753+
frag = &skb_shinfo(skb)->frags[i];
6754+
np->ops->unmap_page(np->device, rp->tx_buffs[prod].mapping,
6755+
skb_frag_size(frag), DMA_TO_DEVICE);
6756+
}
6757+
6758+
np->ops->unmap_single(np->device, rp->tx_buffs[rp->prod].mapping,
6759+
skb_headlen(skb), DMA_TO_DEVICE);
6760+
67446761
out_drop:
67456762
rp->tx_errors++;
67466763
kfree_skb(skb);
@@ -9644,13 +9661,19 @@ static void niu_pci_unmap_single(struct device *dev, u64 dma_address,
96449661
dma_unmap_single(dev, dma_address, size, direction);
96459662
}
96469663

9664+
static int niu_pci_mapping_error(struct device *dev, u64 addr)
9665+
{
9666+
return dma_mapping_error(dev, addr);
9667+
}
9668+
96479669
static const struct niu_ops niu_pci_ops = {
96489670
.alloc_coherent = niu_pci_alloc_coherent,
96499671
.free_coherent = niu_pci_free_coherent,
96509672
.map_page = niu_pci_map_page,
96519673
.unmap_page = niu_pci_unmap_page,
96529674
.map_single = niu_pci_map_single,
96539675
.unmap_single = niu_pci_unmap_single,
9676+
.mapping_error = niu_pci_mapping_error,
96549677
};
96559678

96569679
static void niu_driver_version(void)
@@ -10019,13 +10042,19 @@ static void niu_phys_unmap_single(struct device *dev, u64 dma_address,
1001910042
/* Nothing to do. */
1002010043
}
1002110044

10045+
static int niu_phys_mapping_error(struct device *dev, u64 dma_address)
10046+
{
10047+
return false;
10048+
}
10049+
1002210050
static const struct niu_ops niu_phys_ops = {
1002310051
.alloc_coherent = niu_phys_alloc_coherent,
1002410052
.free_coherent = niu_phys_free_coherent,
1002510053
.map_page = niu_phys_map_page,
1002610054
.unmap_page = niu_phys_unmap_page,
1002710055
.map_single = niu_phys_map_single,
1002810056
.unmap_single = niu_phys_unmap_single,
10057+
.mapping_error = niu_phys_mapping_error,
1002910058
};
1003010059

1003110060
static int niu_of_probe(struct platform_device *op)

drivers/net/ethernet/sun/niu.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2879,6 +2879,9 @@ struct tx_ring_info {
28792879
#define NEXT_TX(tp, index) \
28802880
(((index) + 1) < (tp)->pending ? ((index) + 1) : 0)
28812881

2882+
#define PREVIOUS_TX(tp, index) \
2883+
(((index) - 1) >= 0 ? ((index) - 1) : (((tp)->pending) - 1))
2884+
28822885
static inline u32 niu_tx_avail(struct tx_ring_info *tp)
28832886
{
28842887
return (tp->pending -
@@ -3140,6 +3143,7 @@ struct niu_ops {
31403143
enum dma_data_direction direction);
31413144
void (*unmap_single)(struct device *dev, u64 dma_address,
31423145
size_t size, enum dma_data_direction direction);
3146+
int (*mapping_error)(struct device *dev, u64 dma_address);
31433147
};
31443148

31453149
struct niu_link_config {

0 commit comments

Comments
 (0)