]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/irda/irnet/irnet_irda.c
Pull regset into release branch
[linux-2.6-omap-h63xx.git] / net / irda / irnet / irnet_irda.c
index f65c7a83bc5cf95d3f5884ec9391a888b59e590f..a4f1439ffdd8b80a4d5847121abe041adeba7627 100644 (file)
 
 #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.
@@ -118,7 +139,7 @@ irnet_open_tsap(irnet_socket *      self)
 
   /* Open an IrTTP instance */
   self->tsap = irttp_open_tsap(LSAP_ANY, DEFAULT_INITIAL_CREDIT,
-                              &notify);        
+                              &notify);
   DABORT(self->tsap == NULL, -ENOMEM,
         IRDA_SR_ERROR, "Unable to allocate TSAP !\n");
 
@@ -188,7 +209,7 @@ irnet_ias_to_tsap(irnet_socket *    self,
          if(value->t.integer != -1)
            /* Get the remote TSAP selector */
            dtsap_sel = value->t.integer;
-         else 
+         else
            self->errno = -EADDRNOTAVAIL;
          break;
        default:
@@ -280,8 +301,8 @@ irnet_connect_tsap(irnet_socket *   self)
     }
 
   /* Connect to remote device */
-  err = irttp_connect_request(self->tsap, self->dtsap_sel, 
-                             self->rsaddr, self->daddr, NULL, 
+  err = irttp_connect_request(self->tsap, self->dtsap_sel,
+                             self->rsaddr, self->daddr, NULL,
                              self->max_sdu_size_rx, NULL);
   if(err != 0)
     {
@@ -438,7 +459,7 @@ irnet_dname_to_daddr(irnet_socket * self)
   if(discoveries == NULL)
     DRETURN(-ENETUNREACH, IRDA_SR_INFO, "Cachelog empty...\n");
 
-  /* 
+  /*
    * Now, check all discovered devices (if any), and connect
    * client only about the services that the client is
    * interested in...
@@ -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);
 }
@@ -627,7 +650,7 @@ irda_irnet_destroy(irnet_socket *   self)
 
   /* Unregister with LM-IAS */
   if(self->iriap)
-    { 
+    {
       iriap_close(self->iriap);
       self->iriap = NULL;
     }
@@ -945,7 +968,7 @@ irnet_setup_server(void)
 
   /* Register with LM-IAS (so that people can connect to us) */
   irnet_server.ias_obj = irias_new_object(IRNET_SERVICE_NAME, jiffies);
-  irias_add_integer_attrib(irnet_server.ias_obj, IRNET_IAS_VALUE, 
+  irias_add_integer_attrib(irnet_server.ias_obj, IRNET_IAS_VALUE,
                           irnet_server.s.stsap_sel, IAS_KERNEL_ATTR);
   irias_insert_object(irnet_server.ias_obj);
 
@@ -1076,7 +1099,7 @@ irnet_data_indication(void *      instance,
  */
 static void
 irnet_disconnect_indication(void *     instance,
-                           void *      sap, 
+                           void *      sap,
                            LM_REASON   reason,
                            struct sk_buff *skb)
 {
@@ -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
        {
@@ -1166,10 +1182,10 @@ irnet_disconnect_indication(void *      instance,
  */
 static void
 irnet_connect_confirm(void *   instance,
-                     void *    sap, 
+                     void *    sap,
                      struct qos_info *qos,
                      __u32     max_sdu_size,
-                     __u8      max_header_size, 
+                     __u8      max_header_size,
                      struct sk_buff *skb)
 {
   irnet_socket *       self = (irnet_socket *) instance;
@@ -1235,7 +1251,7 @@ irnet_connect_confirm(void *      instance,
 static void
 irnet_flow_indication(void *   instance,
                      void *    sap,
-                     LOCAL_FLOW flow) 
+                     LOCAL_FLOW flow)
 {
   irnet_socket *       self = (irnet_socket *) instance;
   LOCAL_FLOW           oldflow = self->tx_flow;
@@ -1308,13 +1324,13 @@ irnet_status_indication(void *  instance,
  * Some other node is attempting to connect to the IrNET service, and has
  * sent a connection request on our server socket.
  * We just redirect the connection to the relevant IrNET socket.
- * 
+ *
  * Note : we also make sure that between 2 irnet nodes, there can
  * exist only one irnet connection.
  */
 static void
 irnet_connect_indication(void *                instance,
-                        void *         sap, 
+                        void *         sap,
                         struct qos_info *qos,
                         __u32          max_sdu_size,
                         __u8           max_header_size,
@@ -1463,7 +1479,7 @@ irnet_connect_indication(void *           instance,
  */
 static void
 irnet_getvalue_confirm(int     result,
-                      __u16    obj_id, 
+                      __u16    obj_id,
                       struct ias_value *value,
                       void *   priv)
 {
@@ -1526,7 +1542,7 @@ irnet_getvalue_confirm(int        result,
  */
 static void
 irnet_discovervalue_confirm(int                result,
-                           __u16       obj_id, 
+                           __u16       obj_id,
                            struct ias_value *value,
                            void *      priv)
 {
@@ -1645,7 +1661,7 @@ irnet_discovery_indication(discinfo_t *           discovery,
                           void *               priv)
 {
   irnet_socket *       self = &irnet_server.s;
-       
+
   DENTER(IRDA_OCB_TRACE, "(self=0x%p)\n", self);
   DASSERT(priv == &irnet_server, , IRDA_OCB_ERROR,
          "Invalid instance (0x%p) !!!\n", priv);
@@ -1676,7 +1692,7 @@ irnet_expiry_indication(discinfo_t *      expiry,
                        void *          priv)
 {
   irnet_socket *       self = &irnet_server.s;
-       
+
   DENTER(IRDA_OCB_TRACE, "(self=0x%p)\n", self);
   DASSERT(priv == &irnet_server, , IRDA_OCB_ERROR,
          "Invalid instance (0x%p) !!!\n", priv);
@@ -1718,7 +1734,7 @@ irnet_proc_read(char *    buf,
   int                  i = 0;
 
   len = 0;
-       
+
   /* Get the IrNET server information... */
   len += sprintf(buf+len, "IrNET server - ");
   len += sprintf(buf+len, "IrDA state: %s, ",
@@ -1811,7 +1827,7 @@ irda_irnet_init(void)
   memset(&irnet_server, 0, sizeof(struct irnet_root));
 
   /* Setup start of irnet instance list */
-  irnet_server.list = hashbin_new(HB_NOLOCK); 
+  irnet_server.list = hashbin_new(HB_NOLOCK);
   DABORT(irnet_server.list == NULL, -ENOMEM,
         MODULE_ERROR, "Can't allocate hashbin!\n");
   /* Init spinlock for instance list */