diff -u -p linux/net/irda/irlap.d2.c linux/net/irda/irlap.c --- linux/net/irda/irlap.d2.c Thu Sep 4 18:30:08 2003 +++ linux/net/irda/irlap.c Thu Sep 4 18:30:37 2003 @@ -221,8 +221,11 @@ void irlap_close(struct irlap_cb *self) ASSERT(self != NULL, return;); ASSERT(self->magic == LAP_MAGIC, return;); - irlap_disconnect_indication(self, LAP_DISC_INDICATION); + /* We used to send a LAP_DISC_INDICATION here, but this was + * racy. This has been move within irlmp_unregister_link() + * itself. Jean II */ + /* Kill the LAP and all LSAPs on top of it */ irlmp_unregister_link(self->saddr); self->notify.instance = NULL; diff -u -p linux/net/irda/irlmp.d2.c linux/net/irda/irlmp.c --- linux/net/irda/irlmp.d2.c Thu Sep 4 18:30:15 2003 +++ linux/net/irda/irlmp.c Thu Sep 4 18:30:37 2003 @@ -321,15 +321,23 @@ void irlmp_unregister_link(__u32 saddr) IRDA_DEBUG(4, "%s()\n", __FUNCTION__); + /* We must remove ourselves from the hashbin *first*. This ensure + * that no more LSAPs will be open on this link and no discovery + * will be triggered anymore. Jean II */ link = hashbin_remove(irlmp->links, saddr, NULL); if (link) { ASSERT(link->magic == LMP_LAP_MAGIC, return;); + /* Kill all the LSAPs on this link. Jean II */ + link->reason = LAP_DISC_INDICATION; + link->daddr = DEV_ADDR_ANY; + irlmp_do_lap_event(link, LM_LAP_DISCONNECT_INDICATION, NULL); + /* Remove all discoveries discovered at this link */ irlmp_expire_discoveries(irlmp->cachelog, link->saddr, TRUE); + /* Final cleanup */ del_timer(&link->idle_timer); - link->magic = 0; kfree(link); }