diff -r b560de13b236 -r a60ff25672a0 me8100.c --- a/me8100.c Fri Jan 18 20:45:23 2002 +0100 +++ b/me8100.c Fri Jan 18 21:00:56 2002 +0100 @@ -606,7 +606,8 @@ if (0 == subinfo->num_writer++) { subinfo->ctrl_reg |= ME8100_CTRL_ENIO | ME8100_CTRL_SOURCE; - PDEBUG("*** adding ENIO+SOURCE mode: ctrl: 0x%x\n", subinfo->ctrl_reg); + PDEBUG("*** adding %0x to ctrl: 0x%04x\n", + ME8100_CTRL_ENIO | ME8100_CTRL_SOURCE, subinfo->ctrl_reg); outw(subinfo->ctrl_reg, subinfo->regbase + ME8100_CTRL_REG); } } @@ -622,38 +623,44 @@ PDEBUG("*** open for reading\n"); - if (!(priv = kmalloc(sizeof(*priv), GFP_KERNEL))) { - printk(KERN_ERR"ME8100:me8100_open: kmalloc() failed.\n"); - me8100_release(inode_ptr, file_ptr); - return -EIO; - } + if (0 == subinfo->num_reader++) { + + PDEBUG("*** first reader...\n"); + + if (!(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; + priv->last_read = 0; + file_ptr->private_data = priv; - /* Now we've to setup the IRQ line. We suppose that it should be done - * in "mask" manner. If somebody wishes to do it the otherway or if somebody - * wants to change the mask, ioctl() should be used. */ - { - int mask = 0xffff; - unsigned short icsr = PCI_INT_EN | ((LOCAL_INT_EN | LOCAL_INT_POL) << (3 * subdevice)); + /* Now we've to setup the IRQ line. We suppose that it should be done + * in "mask" manner. If somebody wishes to do it the otherway or if somebody + * wants to change the mask, ioctl() should be used. */ + { + int mask = 0xffff; + unsigned short icsr = PCI_INT_EN | ((LOCAL_INT_EN | LOCAL_INT_POL) << (3 * subdevice)); - /* 1) setup the PLX register */ - PDEBUG("*** plx = 0x%0x\n", icsr); - outb(icsr, info->plx_regbase + PLX_ICSR); + /* 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 */ - subinfo->ctrl_reg |= ME8100_CTRL_IRQ_MASK; - PDEBUG("*** ctrl = 0x%04x\n", subinfo->ctrl_reg); - outw(subinfo->ctrl_reg, subinfo->regbase + ME8100_CTRL_REG); + /* 2) setup the irq flags in regbase */ + subinfo->ctrl_reg |= ME8100_CTRL_IRQ_MASK; + PDEBUG("*** adding %0x to ctrl: 0x%04x\n", ME8100_CTRL_IRQ_MASK, + 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); + /* 3) setup the interrupt mask */ + PDEBUG("*** irqmask = 0x%04x\n", mask); + outw(mask, subinfo->regbase + ME8100_MASK_REG); - } - } + } + } /* first reader */ + } /* reader */ return 0; @@ -705,11 +712,22 @@ PDEBUG("*** writer closes\n"); if (0 == --subinfo->num_writer) { subinfo->ctrl_reg &= !ME8100_CTRL_ENIO; - // PDEBUG("*** resetting ENIO mode ctrl: 0x%x\n", subinfo->ctrl_reg); - // outw(subinfo->ctrl_reg, subinfo->regbase + ME8100_CTRL_REG); + PDEBUG("*** resetting ENIO mode ctrl: 0x%x\n", subinfo->ctrl_reg); + outw(subinfo->ctrl_reg, subinfo->regbase + ME8100_CTRL_REG); } } + if (file_ptr->f_mode & FMODE_READ) { + PDEBUG("*** reader close\n"); + if (0 == --subinfo->num_reader) { + PDEBUG("*** last reader...\n"); + subinfo->ctrl_reg &= !ME8100_CTRL_IRQ_MASK; /* 11 */ + PDEBUG("*** resetting IRQ mode ctrl: 0x%x\n", subinfo->ctrl_reg); + outw(subinfo->ctrl_reg, subinfo->regbase + ME8100_CTRL_REG); + } + } + + /* resetting the board on last close */ if (--info->board_in_use == 0) {