me8100.c
changeset 13 f7fb771d7842
parent 12 67e56b4bce81
child 14 c3f6d5e9713a
equal deleted inserted replaced
12:67e56b4bce81 13:f7fb771d7842
   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 ); 
   484 
   479 
   485   for (i = 0; i <= 1; ++i) {
   480   for (i = 0; i <= 1; ++i) {
   486     info->subinfo[i].int_seen = 0;
   481     info->subinfo[i].int_seen = 0;
   487     info->subinfo[i].int_count = 0;
   482     info->subinfo[i].int_count = 0;
   488     info->subinfo[i].fasync_ptr = NULL;
   483     info->subinfo[i].fasync_ptr = NULL;
       
   484     init_waitqueue_head(&info->subinfo[i].readq);
   489   }
   485   }
   490   
   486   
   491   
   487   
   492   /*--------------------------- Reset the board -----------------------------*/
   488   /*--------------------------- Reset the board -----------------------------*/
   493 
   489 
   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);
  2107  */
  2106  */
  2108 static void me8100_isr(int irq, void *dev_id, struct pt_regs *regs){
  2107 static void me8100_isr(int irq, void *dev_id, struct pt_regs *regs){
  2109   unsigned char icsr;
  2108   unsigned char icsr;
  2110   unsigned short dummy;
  2109   unsigned short dummy;
  2111   me8100_info_type *info;
  2110   me8100_info_type *info;
       
  2111   //unsigned short icsr_mask[] = { 0x45, 0x68 };
       
  2112 
  2112 
  2113 
  2113   PDEBUG("=====> me8100_isr() is executed\n");
  2114   PDEBUG("=====> me8100_isr() is executed\n");
  2114 
  2115 
  2115   info = (me8100_info_type *) dev_id;
  2116   info = (me8100_info_type *) dev_id;
  2116 
  2117 
  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);