Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=c577c2b99387b5ff8607d42d6eaff9ec024d4773
Commit:     c577c2b99387b5ff8607d42d6eaff9ec024d4773
Parent:     7bb1bbe615de25d955b974cb47d40fa198154bb9
Author:     Samuel Ortiz <[EMAIL PROTECTED]>
AuthorDate: Fri Mar 16 20:31:03 2007 -0700
Committer:  David S. Miller <[EMAIL PROTECTED]>
CommitDate: Tue Mar 20 00:09:42 2007 -0700

    [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 <[EMAIL PROTECTED]>
    Signed-off-by: David S. Miller <[EMAIL PROTECTED]>
---
 net/irda/irnet/irnet.h      |    2 +-
 net/irda/irnet/irnet_irda.c |   34 +++++++++++++++++++++++++---------
 2 files changed, 26 insertions(+), 10 deletions(-)

diff --git a/net/irda/irnet/irnet.h b/net/irda/irnet/irnet.h
index 873ae18..bc2e15c 100644
--- a/net/irda/irnet/irnet.h
+++ b/net/irda/irnet/irnet.h
@@ -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 */
diff --git a/net/irda/irnet/irnet_irda.c b/net/irda/irnet/irnet_irda.c
index c378e66..a4f1439 100644
--- a/net/irda/irnet/irnet_irda.c
+++ b/net/irda/irnet/irnet_irda.c
@@ -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
        {
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to