aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorG. Liakhovetski <gl@dsa-ac.de>2007-06-08 22:15:17 -0400
committerDavid S. Miller <davem@davemloft.net>2007-06-08 22:15:17 -0400
commitc0cfe7faa12f189ef1024fce5a710791d0062355 (patch)
treee3f6e22de451d8d679235f8adea313a25c5de497
parent81d84a94be8085475c3585596e52b06ccbedd922 (diff)
[IrDA]: Fix Rx/Tx path race.
From: G. Liakhovetski <gl@dsa-ac.de> We need to switch to NRM _before_ sending the final packet otherwise we might hit a race condition where we get the first packet from the peer while we're still in LAP_XMIT_P. Signed-off-by: Samuel Ortiz <samuel@sortiz.org> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/irda/irlap.h17
-rw-r--r--net/irda/irlap_event.c18
-rw-r--r--net/irda/irlap_frame.c3
3 files changed, 20 insertions, 18 deletions
diff --git a/include/net/irda/irlap.h b/include/net/irda/irlap.h
index f0248fb8e196..a3d370efb903 100644
--- a/include/net/irda/irlap.h
+++ b/include/net/irda/irlap.h
@@ -289,4 +289,21 @@ static inline void irlap_clear_disconnect(struct irlap_cb *self)
289 self->disconnect_pending = FALSE; 289 self->disconnect_pending = FALSE;
290} 290}
291 291
292/*
293 * Function irlap_next_state (self, state)
294 *
295 * Switches state and provides debug information
296 *
297 */
298static inline void irlap_next_state(struct irlap_cb *self, IRLAP_STATE state)
299{
300 /*
301 if (!self || self->magic != LAP_MAGIC)
302 return;
303
304 IRDA_DEBUG(4, "next LAP state = %s\n", irlap_state[state]);
305 */
306 self->state = state;
307}
308
292#endif 309#endif
diff --git a/net/irda/irlap_event.c b/net/irda/irlap_event.c
index 0b02073ffdf3..71c805506933 100644
--- a/net/irda/irlap_event.c
+++ b/net/irda/irlap_event.c
@@ -317,23 +317,6 @@ void irlap_do_event(struct irlap_cb *self, IRLAP_EVENT event,
317} 317}
318 318
319/* 319/*
320 * Function irlap_next_state (self, state)
321 *
322 * Switches state and provides debug information
323 *
324 */
325static inline void irlap_next_state(struct irlap_cb *self, IRLAP_STATE state)
326{
327 /*
328 if (!self || self->magic != LAP_MAGIC)
329 return;
330
331 IRDA_DEBUG(4, "next LAP state = %s\n", irlap_state[state]);
332 */
333 self->state = state;
334}
335
336/*
337 * Function irlap_state_ndm (event, skb, frame) 320 * Function irlap_state_ndm (event, skb, frame)
338 * 321 *
339 * NDM (Normal Disconnected Mode) state 322 * NDM (Normal Disconnected Mode) state
@@ -1086,7 +1069,6 @@ static int irlap_state_xmit_p(struct irlap_cb *self, IRLAP_EVENT event,
1086 } else { 1069 } else {
1087 /* Final packet of window */ 1070 /* Final packet of window */
1088 irlap_send_data_primary_poll(self, skb); 1071 irlap_send_data_primary_poll(self, skb);
1089 irlap_next_state(self, LAP_NRM_P);
1090 1072
1091 /* 1073 /*
1092 * Make sure state machine does not try to send 1074 * Make sure state machine does not try to send
diff --git a/net/irda/irlap_frame.c b/net/irda/irlap_frame.c
index 3c5a68e36414..3013c49ab975 100644
--- a/net/irda/irlap_frame.c
+++ b/net/irda/irlap_frame.c
@@ -798,16 +798,19 @@ void irlap_send_data_primary_poll(struct irlap_cb *self, struct sk_buff *skb)
798 self->vs = (self->vs + 1) % 8; 798 self->vs = (self->vs + 1) % 8;
799 self->ack_required = FALSE; 799 self->ack_required = FALSE;
800 800
801 irlap_next_state(self, LAP_NRM_P);
801 irlap_send_i_frame(self, tx_skb, CMD_FRAME); 802 irlap_send_i_frame(self, tx_skb, CMD_FRAME);
802 } else { 803 } else {
803 IRDA_DEBUG(4, "%s(), sending unreliable frame\n", __FUNCTION__); 804 IRDA_DEBUG(4, "%s(), sending unreliable frame\n", __FUNCTION__);
804 805
805 if (self->ack_required) { 806 if (self->ack_required) {
806 irlap_send_ui_frame(self, skb_get(skb), self->caddr, CMD_FRAME); 807 irlap_send_ui_frame(self, skb_get(skb), self->caddr, CMD_FRAME);
808 irlap_next_state(self, LAP_NRM_P);
807 irlap_send_rr_frame(self, CMD_FRAME); 809 irlap_send_rr_frame(self, CMD_FRAME);
808 self->ack_required = FALSE; 810 self->ack_required = FALSE;
809 } else { 811 } else {
810 skb->data[1] |= PF_BIT; 812 skb->data[1] |= PF_BIT;
813 irlap_next_state(self, LAP_NRM_P);
811 irlap_send_ui_frame(self, skb_get(skb), self->caddr, CMD_FRAME); 814 irlap_send_ui_frame(self, skb_get(skb), self->caddr, CMD_FRAME);
812 } 815 }
813 } 816 }