diff -r 984e6da93d95 -r 23bb80f9220c me8100.c --- 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 #include +#include #include #include #include @@ -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: */