me8100.c
changeset 26 23bb80f9220c
parent 24 24a49943680f
child 27 4516904df6b3
--- a/me8100.c	Fri Jan 25 21:31:37 2002 +0100
+++ b/me8100.c	Sat Jan 26 17:57:25 2002 +0100
@@ -87,6 +87,7 @@
 #include <linux/ioport.h>
 
 #include <linux/fs.h>
+#include <linux/proc_fs.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
@@ -173,6 +174,7 @@
 static int me8100_read_icsr(unsigned char *, me8100_info_t *);
 static int me8100_get_board_info(me8100_info_t *, me8100_info_t *);
 static int me8100_get_int_count(me8100_int_occur_type *, me8100_info_t *);
+static int me8100_read_proc(char*, char**, off_t, int, int*, void*);
 
 static inline int DEVICE(int i) { return i & 0x0f; }
 static inline int SUBDEVICE(int i) { return (i >> 4) - 1; }
@@ -221,8 +223,8 @@
  * Author: GG                                                               
  * Modification:                                                            
  */
+int init_module(void){
 #ifdef CONFIG_PCI
-int init_module(void){
   int result;
   unsigned short board_count = 0;
   unsigned short sort_count;
@@ -233,7 +235,7 @@
   /* Set the board context to 0 */
   memset(&info_vec, 0, sizeof(info_vec));
 
-  if (pci_present()){
+  if (pci_present()) {
     /* Search for ME8100_A boards */
     for(sort_count = 0; 
 	sort_count < ME8100_MAX_DEVICES; 
@@ -293,10 +295,12 @@
     if (result < 0){
       printk(KERN_ERR"ME8100:init_module():Can't get major no\n");
       return result;
-    }
-    else{
+    } else {
+      /* Finally successful. */
       major = result;
       PDEBUG("init_module():Major = %d\n", major);
+
+      create_proc_read_entry("me8100", 0, NULL, me8100_read_proc, NULL);
     }
   } 
   else{ 
@@ -304,10 +308,10 @@
     return -ENODEV;
   }
   return 0;
+#else
+  return -ENODEV
+#endif
 }  
-#else
-return -ENODEV
-#endif
 
 
 
@@ -2133,13 +2137,21 @@
 
       PDEBUG("==> Interrupt for subdevice %d\n", i);
 
+      /* Remember the the time the interrupt was seen. This is used
+       * later from read() to decide if it has to wait for further
+       * bytes on the input port. */
       subinfo->int_seen = jiffies;
       ++subinfo->int_count;
 
+      /* Read the word and store it for later read().  Then
+       * perform a "dummy" read to re-enable the IRQ line */
       subinfo->int_di = inw(subinfo->regbase + ME8100_INT_DI_REG);
-      inw(subinfo->regbase + ME8100_RES_INT_REG);	  // dummy read
+      inw(subinfo->regbase + ME8100_RES_INT_REG);
 
       PDEBUG("==> read: 0x%04x\n", subinfo->int_di);
+
+      /* Now wake up all sleeping processes and send the
+       * interrupt (SIGIO) signal to all asked for. */
       wake_up_interruptible(&subinfo->readq);
       if (subinfo->fasync_ptr) kill_fasync(&subinfo->fasync_ptr, SIGIO, POLL_IN);
     }
@@ -2186,6 +2198,8 @@
     if(err)
       printk(KERN_WARNING"ME8100:cleanup_module():cannot unregister major\n");
   }
+
+  remove_proc_entry("me8100", NULL);
 }
 
 /* Reading: we do only read (at most) one word (an usigned short) and return immediatly,
@@ -2214,7 +2228,7 @@
   if (len < 0) return -EINVAL;	/* do we really need this check? */
 
   /* If the time we did the last read operation is more recent than the
-   * last interupt, we have to go to sleep (or return -EAGAIN in non blockin
+   * last interupt, we have to go to sleep (or return -EAGAIN in non blocking
    * mode).  Then, if we're awoken, we return the value that triggered the
    * interrupt.  (If awoken from a signal, we return -ERESTARTSYS.)
    *
@@ -2232,9 +2246,7 @@
       return -ERESTARTSYS;
     val = subinfo->int_di;	
 
-  } else val = inw(subinfo->regbase + ME8100_DI_REG);
-
-  PDEBUG("me8100_read: val=0x%04x\n", val);
+  } else val = subinfo->int_di = inw(subinfo->regbase + ME8100_DI_REG);
 
   /* Remember the time of the last interrupt we've seen.  (It might be 
    * 0 if there was no interrupt yet.  This doesn't hurt, since the next
@@ -2242,6 +2254,9 @@
    */
   priv->last_read = subinfo->int_seen;
 
+
+  PDEBUG("me8100_read: val=0x%04x\n", val);
+
   /* Return at most 2 byte, but check if the read want's them both! */
   if (len >= sizeof(val)) {
     err = put_user(val, (unsigned short*) buffer);
@@ -2302,6 +2317,14 @@
 
 }
 
+int me8100_read_proc(char *buffer, char **start, off_t offset, int count, int *eof, void *data)
+{
+  int len = 0;
+  len += sprintf(buffer + len, "Version: $Id$\n");
+  *eof = 1;
+  return len;
+}
+
 /* 
   vim:sts=2 sw=2 aw ai sm: 
  */