headers: remove sched.h from interrupt.h
[safe/jmp/linux-2.6] / net / irda / irnet / irnet_irda.c
index 07ec326..cccc2e9 100644 (file)
@@ -9,6 +9,30 @@
  */
 
 #include "irnet_irda.h"                /* Private header */
+#include <linux/sched.h>
+#include <linux/seq_file.h>
+#include <asm/unaligned.h>
+
+/*
+ * 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 *************************/
 /*
@@ -118,7 +142,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 +212,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 +304,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 +462,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 +523,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 +653,7 @@ irda_irnet_destroy(irnet_socket *   self)
 
   /* Unregister with LM-IAS */
   if(self->iriap)
-    { 
+    {
       iriap_close(self->iriap);
       self->iriap = NULL;
     }
@@ -696,7 +722,7 @@ irnet_daddr_to_dname(irnet_socket * self)
        {
          /* Yes !!! Get it.. */
          strlcpy(self->rname, discoveries[i].info, sizeof(self->rname));
-         self->rname[NICKNAME_MAX_LEN + 1] = '\0';
+         self->rname[sizeof(self->rname) - 1] = '\0';
          DEBUG(IRDA_SERV_INFO, "Device 0x%08x is in fact ``%s''.\n",
                self->daddr, self->rname);
          kfree(discoveries);
@@ -945,7 +971,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 +1102,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 +1160,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 +1185,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 +1254,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 +1327,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 +1482,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 +1545,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 +1664,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);
@@ -1656,7 +1675,7 @@ irnet_discovery_indication(discinfo_t *           discovery,
   /* Notify the control channel */
   irnet_post_event(NULL, IRNET_DISCOVER,
                   discovery->saddr, discovery->daddr, discovery->info,
-                  u16ho(discovery->hints));
+                  get_unaligned((__u16 *)discovery->hints));
 
   DEXIT(IRDA_OCB_TRACE, "\n");
 }
@@ -1676,7 +1695,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);
@@ -1687,7 +1706,7 @@ irnet_expiry_indication(discinfo_t *      expiry,
   /* Notify the control channel */
   irnet_post_event(NULL, IRNET_EXPIRE,
                   expiry->saddr, expiry->daddr, expiry->info,
-                  u16ho(expiry->hints));
+                  get_unaligned((__u16 *)expiry->hints));
 
   DEXIT(IRDA_OCB_TRACE, "\n");
 }
@@ -1701,34 +1720,23 @@ irnet_expiry_indication(discinfo_t *    expiry,
  */
 
 #ifdef CONFIG_PROC_FS
-/*------------------------------------------------------------------*/
-/*
- * Function irnet_proc_read (buf, start, offset, len, unused)
- *
- *    Give some info to the /proc file system
- */
 static int
-irnet_proc_read(char * buf,
-               char ** start,
-               off_t   offset,
-               int     len)
+irnet_proc_show(struct seq_file *m, void *v)
 {
   irnet_socket *       self;
   char *               state;
   int                  i = 0;
 
-  len = 0;
-       
   /* Get the IrNET server information... */
-  len += sprintf(buf+len, "IrNET server - ");
-  len += sprintf(buf+len, "IrDA state: %s, ",
+  seq_printf(m, "IrNET server - ");
+  seq_printf(m, "IrDA state: %s, ",
                 (irnet_server.running ? "running" : "dead"));
-  len += sprintf(buf+len, "stsap_sel: %02x, ", irnet_server.s.stsap_sel);
-  len += sprintf(buf+len, "dtsap_sel: %02x\n", irnet_server.s.dtsap_sel);
+  seq_printf(m, "stsap_sel: %02x, ", irnet_server.s.stsap_sel);
+  seq_printf(m, "dtsap_sel: %02x\n", irnet_server.s.dtsap_sel);
 
   /* Do we need to continue ? */
   if(!irnet_server.running)
-    return len;
+    return 0;
 
   /* Protect access to the instance list */
   spin_lock_bh(&irnet_server.spinlock);
@@ -1738,23 +1746,23 @@ irnet_proc_read(char *  buf,
   while(self != NULL)
     {
       /* Start printing info about the socket. */
-      len += sprintf(buf+len, "\nIrNET socket %d - ", i++);
+      seq_printf(m, "\nIrNET socket %d - ", i++);
 
       /* First, get the requested configuration */
-      len += sprintf(buf+len, "Requested IrDA name: \"%s\", ", self->rname);
-      len += sprintf(buf+len, "daddr: %08x, ", self->rdaddr);
-      len += sprintf(buf+len, "saddr: %08x\n", self->rsaddr);
+      seq_printf(m, "Requested IrDA name: \"%s\", ", self->rname);
+      seq_printf(m, "daddr: %08x, ", self->rdaddr);
+      seq_printf(m, "saddr: %08x\n", self->rsaddr);
 
       /* Second, get all the PPP info */
-      len += sprintf(buf+len, "        PPP state: %s",
+      seq_printf(m, "  PPP state: %s",
                 (self->ppp_open ? "registered" : "unregistered"));
       if(self->ppp_open)
        {
-         len += sprintf(buf+len, ", unit: ppp%d",
+         seq_printf(m, ", unit: ppp%d",
                         ppp_unit_number(&self->chan));
-         len += sprintf(buf+len, ", channel: %d",
+         seq_printf(m, ", channel: %d",
                         ppp_channel_index(&self->chan));
-         len += sprintf(buf+len, ", mru: %d",
+         seq_printf(m, ", mru: %d",
                         self->mru);
          /* Maybe add self->flags ? Later... */
        }
@@ -1773,10 +1781,10 @@ irnet_proc_read(char *  buf,
              state = "weird";
            else
              state = "idle";
-      len += sprintf(buf+len, "\n      IrDA state: %s, ", state);
-      len += sprintf(buf+len, "daddr: %08x, ", self->daddr);
-      len += sprintf(buf+len, "stsap_sel: %02x, ", self->stsap_sel);
-      len += sprintf(buf+len, "dtsap_sel: %02x\n", self->dtsap_sel);
+      seq_printf(m, "\n        IrDA state: %s, ", state);
+      seq_printf(m, "daddr: %08x, ", self->daddr);
+      seq_printf(m, "stsap_sel: %02x, ", self->stsap_sel);
+      seq_printf(m, "dtsap_sel: %02x\n", self->dtsap_sel);
 
       /* Next socket, please... */
       self = (irnet_socket *) hashbin_get_next(irnet_server.list);
@@ -1785,8 +1793,21 @@ irnet_proc_read(char *   buf,
   /* Spin lock end */
   spin_unlock_bh(&irnet_server.spinlock);
 
-  return len;
+  return 0;
 }
+
+static int irnet_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, irnet_proc_show, NULL);
+}
+
+static const struct file_operations irnet_proc_fops = {
+       .owner          = THIS_MODULE,
+       .open           = irnet_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
 #endif /* PROC_FS */
 
 
@@ -1811,7 +1832,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 */
@@ -1825,7 +1846,7 @@ irda_irnet_init(void)
 
 #ifdef CONFIG_PROC_FS
   /* Add a /proc file for irnet infos */
-  create_proc_info_entry("irnet", 0, proc_irda, irnet_proc_read);
+  proc_create("irnet", 0, proc_irda, &irnet_proc_fops);
 #endif /* CONFIG_PROC_FS */
 
   /* Setup the IrNET server */