# HG changeset patch # User heiko # Date 1011640491 -3600 # Node ID f7fb771d7842cd66e9dc7349da30c30edb0a069a # Parent 67e56b4bce8156465137ddb246d524c8da4a4288 geht diff -r 67e56b4bce81 -r f7fb771d7842 me8100.c --- a/me8100.c Mon Jan 21 19:35:53 2002 +0100 +++ b/me8100.c Mon Jan 21 20:14:51 2002 +0100 @@ -125,11 +125,6 @@ /* Major Device Number. 0 means to get it automatically from the System */ static unsigned int major = 0; -/* The queue all the readers are on. */ -DECLARE_WAIT_QUEUE_HEAD(me8100_readq); - - - /* Prototypes */ static int me8100_open(struct inode *, struct file *); static int me8100_release(struct inode *, struct file *); @@ -486,6 +481,7 @@ info->subinfo[i].int_seen = 0; info->subinfo[i].int_count = 0; info->subinfo[i].fasync_ptr = NULL; + init_waitqueue_head(&info->subinfo[i].readq); } @@ -630,42 +626,44 @@ PDEBUG("*** open for reading\n"); + /* Allocate memory for the private data. If allocating fails, + * call m8100_release() (which in turn decrements the mod-in-use-count) + * and return IO error. */ + if (NULL == (priv = kmalloc(sizeof(*priv), GFP_KERNEL))) { + printk(KERN_ERR"ME8100:me8100_open: kmalloc() failed.\n"); + me8100_release(inode_ptr, file_ptr); + return -EIO; + } + + priv->last_read = 0; + file_ptr->private_data = priv; + /* The first reader should setup the IRQs (enabling IRQ handling * with the full bit mask. It might be modified later. */ if (0 == subinfo->num_reader++) { - int mask = 0xffff; - unsigned short icsr = PCI_INT_EN - | ((LOCAL_INT_EN | LOCAL_INT_POL) << (3 * subdevice)); - PDEBUG("*** first reader...\n"); - subinfo->ctrl_rflags = 0; + int mask; + unsigned short icsr; - /* Allocate memory for the private data. If allocating fails, - * call m8100_release() (which in turn decrements the mod-in-use-count) - * and return IO error. */ - if (NULL == (priv = kmalloc(sizeof(*priv), GFP_KERNEL))) { - printk(KERN_ERR"ME8100:me8100_open: kmalloc() failed.\n"); - me8100_release(inode_ptr, file_ptr); - return -EIO; - } + mask = 0xffff; + icsr = PCI_INT_EN | ((LOCAL_INT_EN | LOCAL_INT_POL) << (3 * subdevice)); - priv->last_read = 0; - file_ptr->private_data = priv; + PDEBUG("*** first reader on subdevice %d\n", subdevice); /* 1) setup the PLX register */ PDEBUG("*** plx = 0x%0x\n", icsr); outb(icsr, info->plx_regbase + PLX_ICSR); - /* 2) setup the irq flags in regbase */ + /* 2) setup the interrupt mask */ + PDEBUG("*** irqmask = 0x%04x\n", mask); + outw(mask, subinfo->regbase + ME8100_MASK_REG); + + /* 3) setup the irq flags in regbase */ subinfo->ctrl_rflags = ME8100_CTRL_IRQ_MASK; subinfo->ctrl_reg |= subinfo->ctrl_rflags; PDEBUG("*** adding 0x%0x to ctrl => 0x%04x\n", subinfo->ctrl_rflags, subinfo->ctrl_reg); outw(subinfo->ctrl_reg, subinfo->regbase + ME8100_CTRL_REG); - /* 3) setup the interrupt mask */ - PDEBUG("*** irqmask = 0x%04x\n", mask); - outw(mask, subinfo->regbase + ME8100_MASK_REG); - } /* first reader */ } /* reader */ @@ -718,6 +716,7 @@ if (file_ptr->f_mode & FMODE_WRITE) { PDEBUG("*** writer closes\n"); if (0 == --subinfo->num_writer) { + PDEBUG("*** last writer...\n"); /* PDEBUG("*** resetting ENIO mode ctrl: 0x%x\n", subinfo->ctrl_reg); subinfo->ctrl_reg &= !subinfo->ctrl_wflags; @@ -2109,6 +2108,8 @@ unsigned char icsr; unsigned short dummy; me8100_info_type *info; + //unsigned short icsr_mask[] = { 0x45, 0x68 }; + PDEBUG("=====> me8100_isr() is executed\n"); @@ -2134,6 +2135,7 @@ subinfo->int_seen = 1; subinfo->int_count++; dummy = inw(info->me8100_regbase + ME8100_RES_INT_REG_A); + wake_up_interruptible(&subinfo->readq); if (subinfo->fasync_ptr) kill_fasync(&subinfo->fasync_ptr, SIGIO, POLL_IN); } else if((icsr & 0x68) == 0x68) { @@ -2142,6 +2144,7 @@ subinfo->int_seen = 1; subinfo->int_count++; dummy = inw(info->me8100_regbase + ME8100_RES_INT_REG_B); + wake_up_interruptible(&subinfo->readq); if (subinfo->fasync_ptr) kill_fasync(&subinfo->fasync_ptr, SIGIO, POLL_IN); } else { @@ -2149,9 +2152,8 @@ return; } - PDEBUG("*** wake up sleeper\n"); - /* should be splitted too (one queue for each channel) */ - wake_up_interruptible(&me8100_readq); + return; + } @@ -2220,7 +2222,7 @@ if (len < 0) return -EINVAL; /* do we really need this check? */ if (priv->last_read > subinfo->last_change) { PDEBUG("*** going to sleep\n"); - interruptible_sleep_on(&me8100_readq); + interruptible_sleep_on(&subinfo->readq); } priv->last_read = jiffies; diff -r 67e56b4bce81 -r f7fb771d7842 me8100.h --- a/me8100.h Mon Jan 21 19:35:53 2002 +0100 +++ b/me8100.h Mon Jan 21 20:14:51 2002 +0100 @@ -218,6 +218,7 @@ int int_count; struct fasync_struct *fasync_ptr; + wait_queue_head_t readq; }; typedef struct{