diff options
author | Michael Ellerman <michael@ellerman.id.au> | 2005-08-31 21:29:07 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-08-31 22:39:43 -0400 |
commit | cbf9074cc30ca0eee19c9bd7304faf9f1beb1e76 (patch) | |
tree | f3d0133df8c9a46135148e34b0a553849153c04f /drivers/net/iseries_veth.c | |
parent | b08bd5c0a3110f143faeef9cd057d9d8ff2f0714 (diff) |
[PATCH] iseries_veth: Only call dma_unmap_single() if dma_map_single() succeeded
The iseries_veth driver unconditionally calls dma_unmap_single() even
when the corresponding dma_map_single() may have failed.
Rework the code a bit to keep the return value from dma_unmap_single()
around, and then check if it's a dma_mapping_error() before we do
the dma_unmap_single().
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers/net/iseries_veth.c')
-rw-r--r-- | drivers/net/iseries_veth.c | 17 |
1 files changed, 8 insertions, 9 deletions
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index 427ac8cc56be..91d79db96e82 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c | |||
@@ -931,7 +931,6 @@ static int veth_transmit_to_one(struct sk_buff *skb, HvLpIndex rlp, | |||
931 | struct veth_lpar_connection *cnx = veth_cnx[rlp]; | 931 | struct veth_lpar_connection *cnx = veth_cnx[rlp]; |
932 | struct veth_port *port = (struct veth_port *) dev->priv; | 932 | struct veth_port *port = (struct veth_port *) dev->priv; |
933 | HvLpEvent_Rc rc; | 933 | HvLpEvent_Rc rc; |
934 | u32 dma_address, dma_length; | ||
935 | struct veth_msg *msg = NULL; | 934 | struct veth_msg *msg = NULL; |
936 | int err = 0; | 935 | int err = 0; |
937 | unsigned long flags; | 936 | unsigned long flags; |
@@ -959,20 +958,19 @@ static int veth_transmit_to_one(struct sk_buff *skb, HvLpIndex rlp, | |||
959 | 958 | ||
960 | msg->in_use = 1; | 959 | msg->in_use = 1; |
961 | 960 | ||
962 | dma_length = skb->len; | 961 | msg->data.addr[0] = dma_map_single(port->dev, skb->data, |
963 | dma_address = dma_map_single(port->dev, skb->data, | 962 | skb->len, DMA_TO_DEVICE); |
964 | dma_length, DMA_TO_DEVICE); | ||
965 | 963 | ||
966 | if (dma_mapping_error(dma_address)) | 964 | if (dma_mapping_error(msg->data.addr[0])) |
967 | goto recycle_and_drop; | 965 | goto recycle_and_drop; |
968 | 966 | ||
969 | /* Is it really necessary to check the length and address | 967 | /* Is it really necessary to check the length and address |
970 | * fields of the first entry here? */ | 968 | * fields of the first entry here? */ |
971 | msg->skb = skb; | 969 | msg->skb = skb; |
972 | msg->dev = port->dev; | 970 | msg->dev = port->dev; |
973 | msg->data.addr[0] = dma_address; | 971 | msg->data.len[0] = skb->len; |
974 | msg->data.len[0] = dma_length; | ||
975 | msg->data.eofmask = 1 << VETH_EOF_SHIFT; | 972 | msg->data.eofmask = 1 << VETH_EOF_SHIFT; |
973 | |||
976 | rc = veth_signaldata(cnx, VethEventTypeFrames, msg->token, &msg->data); | 974 | rc = veth_signaldata(cnx, VethEventTypeFrames, msg->token, &msg->data); |
977 | 975 | ||
978 | if (rc != HvLpEvent_Rc_Good) | 976 | if (rc != HvLpEvent_Rc_Good) |
@@ -1076,8 +1074,9 @@ static void veth_recycle_msg(struct veth_lpar_connection *cnx, | |||
1076 | dma_address = msg->data.addr[0]; | 1074 | dma_address = msg->data.addr[0]; |
1077 | dma_length = msg->data.len[0]; | 1075 | dma_length = msg->data.len[0]; |
1078 | 1076 | ||
1079 | dma_unmap_single(msg->dev, dma_address, dma_length, | 1077 | if (!dma_mapping_error(dma_address)) |
1080 | DMA_TO_DEVICE); | 1078 | dma_unmap_single(msg->dev, dma_address, dma_length, |
1079 | DMA_TO_DEVICE); | ||
1081 | 1080 | ||
1082 | if (msg->skb) { | 1081 | if (msg->skb) { |
1083 | dev_kfree_skb_any(msg->skb); | 1082 | dev_kfree_skb_any(msg->skb); |