aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorMichael Ellerman <michael@ellerman.id.au>2005-09-01 11:29:07 +1000
committerJeff Garzik <jgarzik@pobox.com>2005-08-31 22:39:43 -0400
commitcbf9074cc30ca0eee19c9bd7304faf9f1beb1e76 (patch)
treef3d0133df8c9a46135148e34b0a553849153c04f /drivers/net
parent[PATCH] iseries_veth: Replace lock-protected atomic with an ordinary variable (diff)
downloadlinux-dev-cbf9074cc30ca0eee19c9bd7304faf9f1beb1e76.tar.xz
linux-dev-cbf9074cc30ca0eee19c9bd7304faf9f1beb1e76.zip
[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')
-rw-r--r--drivers/net/iseries_veth.c17
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,
struct veth_lpar_connection *cnx = veth_cnx[rlp];
struct veth_port *port = (struct veth_port *) dev->priv;
HvLpEvent_Rc rc;
- u32 dma_address, dma_length;
struct veth_msg *msg = NULL;
int err = 0;
unsigned long flags;
@@ -959,20 +958,19 @@ static int veth_transmit_to_one(struct sk_buff *skb, HvLpIndex rlp,
msg->in_use = 1;
- dma_length = skb->len;
- dma_address = dma_map_single(port->dev, skb->data,
- dma_length, DMA_TO_DEVICE);
+ msg->data.addr[0] = dma_map_single(port->dev, skb->data,
+ skb->len, DMA_TO_DEVICE);
- if (dma_mapping_error(dma_address))
+ if (dma_mapping_error(msg->data.addr[0]))
goto recycle_and_drop;
/* Is it really necessary to check the length and address
* fields of the first entry here? */
msg->skb = skb;
msg->dev = port->dev;
- msg->data.addr[0] = dma_address;
- msg->data.len[0] = dma_length;
+ msg->data.len[0] = skb->len;
msg->data.eofmask = 1 << VETH_EOF_SHIFT;
+
rc = veth_signaldata(cnx, VethEventTypeFrames, msg->token, &msg->data);
if (rc != HvLpEvent_Rc_Good)
@@ -1076,8 +1074,9 @@ static void veth_recycle_msg(struct veth_lpar_connection *cnx,
dma_address = msg->data.addr[0];
dma_length = msg->data.len[0];
- dma_unmap_single(msg->dev, dma_address, dma_length,
- DMA_TO_DEVICE);
+ if (!dma_mapping_error(dma_address))
+ dma_unmap_single(msg->dev, dma_address, dma_length,
+ DMA_TO_DEVICE);
if (msg->skb) {
dev_kfree_skb_any(msg->skb);