[IrDA]: Calling ppp_unregister_channel() from process context
We need to call ppp_unregister_channel() when IrNET disconnects, and this must be done from a process context. Bug reported and patch tested by Guennadi Liakhovetski. Signed-off-by: Samuel Ortiz <samuel@sortiz.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
7bb1bbe615
commit
c577c2b993
2 changed files with 26 additions and 10 deletions
|
@ -419,7 +419,7 @@ typedef struct irnet_socket
|
|||
u32 raccm; /* to please pppd - dummy) */
|
||||
unsigned int flags; /* PPP flags (compression, ...) */
|
||||
unsigned int rbits; /* Unused receive flags ??? */
|
||||
|
||||
struct work_struct disconnect_work; /* Process context disconnection */
|
||||
/* ------------------------ IrTTP part ------------------------ */
|
||||
/* We create a pseudo "socket" over the IrDA tranport */
|
||||
unsigned long ttp_open; /* Set when IrTTP is ready */
|
||||
|
|
|
@ -10,6 +10,27 @@
|
|||
|
||||
#include "irnet_irda.h" /* Private header */
|
||||
|
||||
/*
|
||||
* PPP disconnect work: we need to make sure we're in
|
||||
* process context when calling ppp_unregister_channel().
|
||||
*/
|
||||
static void irnet_ppp_disconnect(struct work_struct *work)
|
||||
{
|
||||
irnet_socket * self =
|
||||
container_of(work, irnet_socket, disconnect_work);
|
||||
|
||||
if (self == NULL)
|
||||
return;
|
||||
/*
|
||||
* If we were connected, cleanup & close the PPP
|
||||
* channel, which will kill pppd (hangup) and the rest.
|
||||
*/
|
||||
if (self->ppp_open && !self->ttp_open && !self->ttp_connect) {
|
||||
ppp_unregister_channel(&self->chan);
|
||||
self->ppp_open = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/************************* CONTROL CHANNEL *************************/
|
||||
/*
|
||||
* When ppp is not active, /dev/irnet act as a control channel.
|
||||
|
@ -499,6 +520,8 @@ irda_irnet_create(irnet_socket * self)
|
|||
#endif /* DISCOVERY_NOMASK */
|
||||
self->tx_flow = FLOW_START; /* Flow control from IrTTP */
|
||||
|
||||
INIT_WORK(&self->disconnect_work, irnet_ppp_disconnect);
|
||||
|
||||
DEXIT(IRDA_SOCK_TRACE, "\n");
|
||||
return(0);
|
||||
}
|
||||
|
@ -1134,15 +1157,8 @@ irnet_disconnect_indication(void * instance,
|
|||
{
|
||||
if(test_open)
|
||||
{
|
||||
#ifdef MISSING_PPP_API
|
||||
/* ppp_unregister_channel() wants a user context, which we
|
||||
* are guaranteed to NOT have here. What are we supposed
|
||||
* to do here ? Jean II */
|
||||
/* If we were connected, cleanup & close the PPP channel,
|
||||
* which will kill pppd (hangup) and the rest */
|
||||
ppp_unregister_channel(&self->chan);
|
||||
self->ppp_open = 0;
|
||||
#endif
|
||||
/* ppp_unregister_channel() wants a user context. */
|
||||
schedule_work(&self->disconnect_work);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue