headers: remove sched.h from interrupt.h
[safe/jmp/linux-2.6] / net / irda / irnet / irnet_irda.c
index c378e66..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 *************************/
 /*
@@ -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);
 }
@@ -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
        {
@@ -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");
 }
@@ -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 */
 
 
@@ -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 */