123 |
123 |
124 |
124 |
125 /* Major Device Number. 0 means to get it automatically from the System */ |
125 /* Major Device Number. 0 means to get it automatically from the System */ |
126 static unsigned int major = 0; |
126 static unsigned int major = 0; |
127 |
127 |
128 /* The queue all the readers are on. */ |
|
129 DECLARE_WAIT_QUEUE_HEAD(me8100_readq); |
|
130 |
|
131 |
|
132 |
|
133 /* Prototypes */ |
128 /* Prototypes */ |
134 static int me8100_open(struct inode *, struct file *); |
129 static int me8100_open(struct inode *, struct file *); |
135 static int me8100_release(struct inode *, struct file *); |
130 static int me8100_release(struct inode *, struct file *); |
136 static int me8100_ioctl(struct inode *, struct file *, |
131 static int me8100_ioctl(struct inode *, struct file *, |
137 unsigned int , unsigned long ); |
132 unsigned int , unsigned long ); |
628 |
624 |
629 struct me8100_private_data *priv; |
625 struct me8100_private_data *priv; |
630 |
626 |
631 PDEBUG("*** open for reading\n"); |
627 PDEBUG("*** open for reading\n"); |
632 |
628 |
|
629 /* Allocate memory for the private data. If allocating fails, |
|
630 * call m8100_release() (which in turn decrements the mod-in-use-count) |
|
631 * and return IO error. */ |
|
632 if (NULL == (priv = kmalloc(sizeof(*priv), GFP_KERNEL))) { |
|
633 printk(KERN_ERR"ME8100:me8100_open: kmalloc() failed.\n"); |
|
634 me8100_release(inode_ptr, file_ptr); |
|
635 return -EIO; |
|
636 } |
|
637 |
|
638 priv->last_read = 0; |
|
639 file_ptr->private_data = priv; |
|
640 |
633 /* The first reader should setup the IRQs (enabling IRQ handling |
641 /* The first reader should setup the IRQs (enabling IRQ handling |
634 * with the full bit mask. It might be modified later. */ |
642 * with the full bit mask. It might be modified later. */ |
635 if (0 == subinfo->num_reader++) { |
643 if (0 == subinfo->num_reader++) { |
636 int mask = 0xffff; |
644 int mask; |
637 unsigned short icsr = PCI_INT_EN |
645 unsigned short icsr; |
638 | ((LOCAL_INT_EN | LOCAL_INT_POL) << (3 * subdevice)); |
646 |
639 PDEBUG("*** first reader...\n"); |
647 mask = 0xffff; |
640 subinfo->ctrl_rflags = 0; |
648 icsr = PCI_INT_EN | ((LOCAL_INT_EN | LOCAL_INT_POL) << (3 * subdevice)); |
641 |
649 |
642 /* Allocate memory for the private data. If allocating fails, |
650 PDEBUG("*** first reader on subdevice %d\n", subdevice); |
643 * call m8100_release() (which in turn decrements the mod-in-use-count) |
|
644 * and return IO error. */ |
|
645 if (NULL == (priv = kmalloc(sizeof(*priv), GFP_KERNEL))) { |
|
646 printk(KERN_ERR"ME8100:me8100_open: kmalloc() failed.\n"); |
|
647 me8100_release(inode_ptr, file_ptr); |
|
648 return -EIO; |
|
649 } |
|
650 |
|
651 priv->last_read = 0; |
|
652 file_ptr->private_data = priv; |
|
653 |
651 |
654 /* 1) setup the PLX register */ |
652 /* 1) setup the PLX register */ |
655 PDEBUG("*** plx = 0x%0x\n", icsr); |
653 PDEBUG("*** plx = 0x%0x\n", icsr); |
656 outb(icsr, info->plx_regbase + PLX_ICSR); |
654 outb(icsr, info->plx_regbase + PLX_ICSR); |
657 |
655 |
658 /* 2) setup the irq flags in regbase */ |
656 /* 2) setup the interrupt mask */ |
|
657 PDEBUG("*** irqmask = 0x%04x\n", mask); |
|
658 outw(mask, subinfo->regbase + ME8100_MASK_REG); |
|
659 |
|
660 /* 3) setup the irq flags in regbase */ |
659 subinfo->ctrl_rflags = ME8100_CTRL_IRQ_MASK; |
661 subinfo->ctrl_rflags = ME8100_CTRL_IRQ_MASK; |
660 subinfo->ctrl_reg |= subinfo->ctrl_rflags; |
662 subinfo->ctrl_reg |= subinfo->ctrl_rflags; |
661 PDEBUG("*** adding 0x%0x to ctrl => 0x%04x\n", |
663 PDEBUG("*** adding 0x%0x to ctrl => 0x%04x\n", |
662 subinfo->ctrl_rflags, subinfo->ctrl_reg); |
664 subinfo->ctrl_rflags, subinfo->ctrl_reg); |
663 outw(subinfo->ctrl_reg, subinfo->regbase + ME8100_CTRL_REG); |
665 outw(subinfo->ctrl_reg, subinfo->regbase + ME8100_CTRL_REG); |
664 |
|
665 /* 3) setup the interrupt mask */ |
|
666 PDEBUG("*** irqmask = 0x%04x\n", mask); |
|
667 outw(mask, subinfo->regbase + ME8100_MASK_REG); |
|
668 |
666 |
669 } /* first reader */ |
667 } /* first reader */ |
670 } /* reader */ |
668 } /* reader */ |
671 |
669 |
672 |
670 |
716 |
714 |
717 /* Resetting write mode if last writer is gone */ |
715 /* Resetting write mode if last writer is gone */ |
718 if (file_ptr->f_mode & FMODE_WRITE) { |
716 if (file_ptr->f_mode & FMODE_WRITE) { |
719 PDEBUG("*** writer closes\n"); |
717 PDEBUG("*** writer closes\n"); |
720 if (0 == --subinfo->num_writer) { |
718 if (0 == --subinfo->num_writer) { |
|
719 PDEBUG("*** last writer...\n"); |
721 /* |
720 /* |
722 PDEBUG("*** resetting ENIO mode ctrl: 0x%x\n", subinfo->ctrl_reg); |
721 PDEBUG("*** resetting ENIO mode ctrl: 0x%x\n", subinfo->ctrl_reg); |
723 subinfo->ctrl_reg &= !subinfo->ctrl_wflags; |
722 subinfo->ctrl_reg &= !subinfo->ctrl_wflags; |
724 subinfo->ctrl_wflags = 0; |
723 subinfo->ctrl_wflags = 0; |
725 outw(subinfo->ctrl_reg, subinfo->regbase + ME8100_CTRL_REG); |
724 outw(subinfo->ctrl_reg, subinfo->regbase + ME8100_CTRL_REG); |
2132 struct me8100_subinfo *subinfo = &info->subinfo[0]; |
2133 struct me8100_subinfo *subinfo = &info->subinfo[0]; |
2133 PDEBUG("me8100_isr():Int1 occured\n"); |
2134 PDEBUG("me8100_isr():Int1 occured\n"); |
2134 subinfo->int_seen = 1; |
2135 subinfo->int_seen = 1; |
2135 subinfo->int_count++; |
2136 subinfo->int_count++; |
2136 dummy = inw(info->me8100_regbase + ME8100_RES_INT_REG_A); |
2137 dummy = inw(info->me8100_regbase + ME8100_RES_INT_REG_A); |
|
2138 wake_up_interruptible(&subinfo->readq); |
2137 if (subinfo->fasync_ptr) kill_fasync(&subinfo->fasync_ptr, SIGIO, POLL_IN); |
2139 if (subinfo->fasync_ptr) kill_fasync(&subinfo->fasync_ptr, SIGIO, POLL_IN); |
2138 |
2140 |
2139 } else if((icsr & 0x68) == 0x68) { |
2141 } else if((icsr & 0x68) == 0x68) { |
2140 struct me8100_subinfo *subinfo = &info->subinfo[1]; |
2142 struct me8100_subinfo *subinfo = &info->subinfo[1]; |
2141 PDEBUG("me8100_isr():Int2 occured\n"); |
2143 PDEBUG("me8100_isr():Int2 occured\n"); |
2142 subinfo->int_seen = 1; |
2144 subinfo->int_seen = 1; |
2143 subinfo->int_count++; |
2145 subinfo->int_count++; |
2144 dummy = inw(info->me8100_regbase + ME8100_RES_INT_REG_B); |
2146 dummy = inw(info->me8100_regbase + ME8100_RES_INT_REG_B); |
|
2147 wake_up_interruptible(&subinfo->readq); |
2145 if (subinfo->fasync_ptr) kill_fasync(&subinfo->fasync_ptr, SIGIO, POLL_IN); |
2148 if (subinfo->fasync_ptr) kill_fasync(&subinfo->fasync_ptr, SIGIO, POLL_IN); |
2146 |
2149 |
2147 } else { |
2150 } else { |
2148 PDEBUG("me8100_isr():Not this Board\n"); |
2151 PDEBUG("me8100_isr():Not this Board\n"); |
2149 return; |
2152 return; |
2150 } |
2153 } |
2151 |
2154 |
2152 PDEBUG("*** wake up sleeper\n"); |
2155 return; |
2153 /* should be splitted too (one queue for each channel) */ |
2156 |
2154 wake_up_interruptible(&me8100_readq); |
|
2155 } |
2157 } |
2156 |
2158 |
2157 |
2159 |
2158 |
2160 |
2159 |
2161 |
2218 |
2220 |
2219 if (len == 0) return 0; /* do we really need this check? */ |
2221 if (len == 0) return 0; /* do we really need this check? */ |
2220 if (len < 0) return -EINVAL; /* do we really need this check? */ |
2222 if (len < 0) return -EINVAL; /* do we really need this check? */ |
2221 if (priv->last_read > subinfo->last_change) { |
2223 if (priv->last_read > subinfo->last_change) { |
2222 PDEBUG("*** going to sleep\n"); |
2224 PDEBUG("*** going to sleep\n"); |
2223 interruptible_sleep_on(&me8100_readq); |
2225 interruptible_sleep_on(&subinfo->readq); |
2224 } |
2226 } |
2225 priv->last_read = jiffies; |
2227 priv->last_read = jiffies; |
2226 |
2228 |
2227 val = inw(subinfo->regbase + ME8100_DI_REG); |
2229 val = inw(subinfo->regbase + ME8100_DI_REG); |
2228 PDEBUG("me8100_read: val=0x%04x\n", val); |
2230 PDEBUG("me8100_read: val=0x%04x\n", val); |