diff options
Diffstat (limited to 'drivers/net/iseries_veth.c')
-rw-r--r-- | drivers/net/iseries_veth.c | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index 231b2d2d3264..427ac8cc56be 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c | |||
@@ -117,7 +117,7 @@ struct veth_msg { | |||
117 | struct veth_msg *next; | 117 | struct veth_msg *next; |
118 | struct VethFramesData data; | 118 | struct VethFramesData data; |
119 | int token; | 119 | int token; |
120 | unsigned long in_use; | 120 | int in_use; |
121 | struct sk_buff *skb; | 121 | struct sk_buff *skb; |
122 | struct device *dev; | 122 | struct device *dev; |
123 | }; | 123 | }; |
@@ -957,6 +957,8 @@ static int veth_transmit_to_one(struct sk_buff *skb, HvLpIndex rlp, | |||
957 | goto drop; | 957 | goto drop; |
958 | } | 958 | } |
959 | 959 | ||
960 | msg->in_use = 1; | ||
961 | |||
960 | dma_length = skb->len; | 962 | dma_length = skb->len; |
961 | dma_address = dma_map_single(port->dev, skb->data, | 963 | dma_address = dma_map_single(port->dev, skb->data, |
962 | dma_length, DMA_TO_DEVICE); | 964 | dma_length, DMA_TO_DEVICE); |
@@ -971,7 +973,6 @@ static int veth_transmit_to_one(struct sk_buff *skb, HvLpIndex rlp, | |||
971 | msg->data.addr[0] = dma_address; | 973 | msg->data.addr[0] = dma_address; |
972 | msg->data.len[0] = dma_length; | 974 | msg->data.len[0] = dma_length; |
973 | msg->data.eofmask = 1 << VETH_EOF_SHIFT; | 975 | msg->data.eofmask = 1 << VETH_EOF_SHIFT; |
974 | set_bit(0, &(msg->in_use)); | ||
975 | rc = veth_signaldata(cnx, VethEventTypeFrames, msg->token, &msg->data); | 976 | rc = veth_signaldata(cnx, VethEventTypeFrames, msg->token, &msg->data); |
976 | 977 | ||
977 | if (rc != HvLpEvent_Rc_Good) | 978 | if (rc != HvLpEvent_Rc_Good) |
@@ -981,10 +982,8 @@ static int veth_transmit_to_one(struct sk_buff *skb, HvLpIndex rlp, | |||
981 | return 0; | 982 | return 0; |
982 | 983 | ||
983 | recycle_and_drop: | 984 | recycle_and_drop: |
985 | /* we free the skb below, so tell veth_recycle_msg() not to. */ | ||
984 | msg->skb = NULL; | 986 | msg->skb = NULL; |
985 | /* need to set in use to make veth_recycle_msg in case this | ||
986 | * was a mapping failure */ | ||
987 | set_bit(0, &msg->in_use); | ||
988 | veth_recycle_msg(cnx, msg); | 987 | veth_recycle_msg(cnx, msg); |
989 | drop: | 988 | drop: |
990 | port->stats.tx_errors++; | 989 | port->stats.tx_errors++; |
@@ -1066,12 +1065,14 @@ static int veth_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1066 | return 0; | 1065 | return 0; |
1067 | } | 1066 | } |
1068 | 1067 | ||
1068 | /* You must hold the connection's lock when you call this function. */ | ||
1069 | static void veth_recycle_msg(struct veth_lpar_connection *cnx, | 1069 | static void veth_recycle_msg(struct veth_lpar_connection *cnx, |
1070 | struct veth_msg *msg) | 1070 | struct veth_msg *msg) |
1071 | { | 1071 | { |
1072 | u32 dma_address, dma_length; | 1072 | u32 dma_address, dma_length; |
1073 | 1073 | ||
1074 | if (test_and_clear_bit(0, &msg->in_use)) { | 1074 | if (msg->in_use) { |
1075 | msg->in_use = 0; | ||
1075 | dma_address = msg->data.addr[0]; | 1076 | dma_address = msg->data.addr[0]; |
1076 | dma_length = msg->data.len[0]; | 1077 | dma_length = msg->data.len[0]; |
1077 | 1078 | ||