Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c577c2b9 authored by Samuel Ortiz's avatar Samuel Ortiz Committed by David S. Miller
Browse files

[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: default avatarSamuel Ortiz <samuel@sortiz.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7bb1bbe6
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -419,7 +419,7 @@ typedef struct irnet_socket
  u32			raccm;		/* to please pppd - dummy) */
  u32			raccm;		/* to please pppd - dummy) */
  unsigned int		flags;		/* PPP flags (compression, ...) */
  unsigned int		flags;		/* PPP flags (compression, ...) */
  unsigned int		rbits;		/* Unused receive flags ??? */
  unsigned int		rbits;		/* Unused receive flags ??? */

  struct work_struct disconnect_work;   /* Process context disconnection */
  /* ------------------------ IrTTP part ------------------------ */
  /* ------------------------ IrTTP part ------------------------ */
  /* We create a pseudo "socket" over the IrDA tranport */
  /* We create a pseudo "socket" over the IrDA tranport */
  unsigned long		ttp_open;	/* Set when IrTTP is ready */
  unsigned long		ttp_open;	/* Set when IrTTP is ready */
+25 −9
Original line number Original line Diff line number Diff line
@@ -10,6 +10,27 @@


#include "irnet_irda.h"		/* Private header */
#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 *************************/
/************************* CONTROL CHANNEL *************************/
/*
/*
 * When ppp is not active, /dev/irnet act as a 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 */
#endif /* DISCOVERY_NOMASK */
  self->tx_flow = FLOW_START;	/* Flow control from IrTTP */
  self->tx_flow = FLOW_START;	/* Flow control from IrTTP */


  INIT_WORK(&self->disconnect_work, irnet_ppp_disconnect);

  DEXIT(IRDA_SOCK_TRACE, "\n");
  DEXIT(IRDA_SOCK_TRACE, "\n");
  return(0);
  return(0);
}
}
@@ -1134,15 +1157,8 @@ irnet_disconnect_indication(void * instance,
    {
    {
      if(test_open)
      if(test_open)
	{
	{
#ifdef MISSING_PPP_API
	  /* ppp_unregister_channel() wants a user context. */
	  /* ppp_unregister_channel() wants a user context, which we
	  schedule_work(&self->disconnect_work);
	   * 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
	}
	}
      else
      else
	{
	{