diff -u -p linux/net/irda/irlap.d6.c linux/net/irda/irlap.c --- linux/net/irda/irlap.d6.c Thu Aug 29 14:01:35 2002 +++ linux/net/irda/irlap.c Thu Aug 29 14:20:41 2002 @@ -116,6 +116,7 @@ struct irlap_cb *irlap_open(struct net_d memset(self, 0, sizeof(struct irlap_cb)); self->magic = LAP_MAGIC; + // self->local_busy = 0; /* Make a binding between the layers */ self->netdev = dev; @@ -434,6 +435,7 @@ void irlap_disconnect_request(struct irl ASSERT(self->magic == LAP_MAGIC, return;); /* Don't disconnect until all data frames are successfully sent */ + /* Should check local_busy - Jean II */ if (skb_queue_len(&self->txq) > 0) { self->disconnect_pending = TRUE; diff -u -p linux/net/irda/irlap_event.d6.c linux/net/irda/irlap_event.c --- linux/net/irda/irlap_event.d6.c Thu Aug 29 14:00:48 2002 +++ linux/net/irda/irlap_event.c Thu Aug 29 14:16:53 2002 @@ -245,6 +245,13 @@ void irlap_do_event(struct irlap_cb *sel IRDA_DEBUG(3, __FUNCTION__ "(), event = %s, state = %s\n", irlap_event[event], irlap_state[self->state]); + /* Prevent race conditions with irlap_data_request() : + * if !=0, higher layer requests are just queued. + * We may re-enter the state machine via irlap_start_poll_timer(), + * so we need to keep track of how many time we go through here + * to "unlock" the state machine at the right time. - Jean II */ + self->local_busy++; + ret = (*state[self->state])(self, event, skb, info); /* @@ -264,9 +271,6 @@ void irlap_do_event(struct irlap_cb *sel skb_queue_len(&self->txq)); if (skb_queue_len(&self->txq)) { - /* Prevent race conditions with irlap_data_request() */ - self->local_busy = TRUE; - /* Theory of operation. * We send frames up to when we fill the window or * reach line capacity. Those frames will queue up @@ -296,8 +300,6 @@ void irlap_do_event(struct irlap_cb *sel if (ret == -EPROTO) break; /* Try again later! */ } - /* Finished transmitting */ - self->local_busy = FALSE; } else if (self->disconnect_pending) { self->disconnect_pending = FALSE; @@ -311,6 +313,13 @@ void irlap_do_event(struct irlap_cb *sel /* case LAP_RESET_CHECK: */ default: break; + } + /* Finished state machine, re-enable higher layer requests. */ + self->local_busy--; + /* Paranoia */ + if((self->local_busy < 0) || (self->local_busy > 3)){ + IRDA_DEBUG(0, "%s() : local_busy out of control : %d\n", + __FUNCTION__, self->local_busy); } }