me8100.c
changeset 14 c3f6d5e9713a
parent 13 f7fb771d7842
child 15 b9baa645576a
equal deleted inserted replaced
13:f7fb771d7842 14:c3f6d5e9713a
   476 
   476 
   477   info->subinfo[0].regbase = info->me8100_regbase;
   477   info->subinfo[0].regbase = info->me8100_regbase;
   478   info->subinfo[1].regbase = info->me8100_regbase + 0x0C;
   478   info->subinfo[1].regbase = info->me8100_regbase + 0x0C;
   479 
   479 
   480   for (i = 0; i <= 1; ++i) {
   480   for (i = 0; i <= 1; ++i) {
   481     info->subinfo[i].int_seen = 0;
   481     info->subinfo[i].int_seen = jiffies;    /* suppose we got just the first irq */
   482     info->subinfo[i].int_count = 0;
   482     info->subinfo[i].int_count = 0;
   483     info->subinfo[i].fasync_ptr = NULL;
   483     info->subinfo[i].fasync_ptr = NULL;
   484     init_waitqueue_head(&info->subinfo[i].readq);
   484     init_waitqueue_head(&info->subinfo[i].readq);
   485   }
   485   }
   486   
   486   
   717     PDEBUG("*** writer closes\n");
   717     PDEBUG("*** writer closes\n");
   718     if (0 == --subinfo->num_writer) {
   718     if (0 == --subinfo->num_writer) {
   719 	PDEBUG("*** last writer...\n");
   719 	PDEBUG("*** last writer...\n");
   720 	/*
   720 	/*
   721 	PDEBUG("*** resetting ENIO mode ctrl: 0x%x\n", subinfo->ctrl_reg);
   721 	PDEBUG("*** resetting ENIO mode ctrl: 0x%x\n", subinfo->ctrl_reg);
   722 	subinfo->ctrl_reg &= !subinfo->ctrl_wflags;
   722 	subinfo->ctrl_reg &= ~subinfo->ctrl_wflags;
   723 	subinfo->ctrl_wflags = 0;
   723 	subinfo->ctrl_wflags = 0;
   724 	outw(subinfo->ctrl_reg, subinfo->regbase + ME8100_CTRL_REG);
   724 	outw(subinfo->ctrl_reg, subinfo->regbase + ME8100_CTRL_REG);
   725 	*/
   725 	*/
   726     }
   726     }
   727   }
   727   }
   728 
   728 
   729   if (file_ptr->f_mode & FMODE_READ) {
   729   if (file_ptr->f_mode & FMODE_READ) {
   730     PDEBUG("*** reader close\n");
   730     PDEBUG("*** reader close\n");
   731     if (0 == --subinfo->num_reader) {
   731     if (0 == --subinfo->num_reader) {
   732       PDEBUG("*** last reader...\n");
   732       PDEBUG("*** last reader...\n");
   733       subinfo->ctrl_reg &= !subinfo->ctrl_rflags;
   733       subinfo->ctrl_reg &= ~subinfo->ctrl_rflags;
   734       subinfo->ctrl_rflags = 0;
   734       subinfo->ctrl_rflags = 0;
   735       PDEBUG("*** resetting IRQ mode ctrl: 0x%x\n", subinfo->ctrl_reg);
   735       PDEBUG("*** resetting IRQ mode ctrl: 0x%x\n", subinfo->ctrl_reg);
   736       outw(subinfo->ctrl_reg, subinfo->regbase + ME8100_CTRL_REG);
   736       outw(subinfo->ctrl_reg, subinfo->regbase + ME8100_CTRL_REG);
   737      }
   737      }
   738   }
   738   }
  2103  *--------------------------------------------------------------------------
  2103  *--------------------------------------------------------------------------
  2104  * Author: GG                                                               
  2104  * Author: GG                                                               
  2105  * Modification:                                                            
  2105  * Modification:                                                            
  2106  */
  2106  */
  2107 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){
       
  2108   int i;
  2108   unsigned char icsr;
  2109   unsigned char icsr;
  2109   unsigned short dummy;
       
  2110   me8100_info_type *info;
  2110   me8100_info_type *info;
  2111   //unsigned short icsr_mask[] = { 0x45, 0x68 };
  2111 
  2112 
  2112   /* A: 0x04 & 0x40 & 0x01 */
       
  2113   /* B: 0x20 & 0x40 & 0x08 */
       
  2114   unsigned short icsr_mask[] = { 0x45, 0x68 };
       
  2115 
       
  2116   info = (me8100_info_type *) dev_id;
  2113 
  2117 
  2114   PDEBUG("=====> me8100_isr() is executed\n");
  2118   PDEBUG("=====> me8100_isr() is executed\n");
  2115 
  2119 
  2116   info = (me8100_info_type *) dev_id;
       
  2117 
  2120 
  2118   if(irq != info->int_line){
  2121   if(irq != info->int_line){
  2119     PDEBUG("me8100_isr():incorrect interrupt num: %d\n", irq);
  2122     PDEBUG("me8100_isr():incorrect interrupt num: %d\n", irq);
  2120     return;
  2123     return;
  2121   }
  2124   }
  2122 
  2125 
  2123   info->subinfo[0].int_seen = 0;
       
  2124   info->subinfo[1].int_seen = 0;
       
  2125 
  2126 
  2126   icsr = inb(info->plx_regbase + PLX_ICSR);
  2127   icsr = inb(info->plx_regbase + PLX_ICSR);
  2127   PDEBUG("== ICSR: 0x%04x\n", icsr);
  2128   PDEBUG("== ICSR: 0x%04x\n", icsr);
  2128 
  2129 
  2129 
  2130   /* We got an interrupt.  Now try each possible subdevice in turn.
  2130   /* A: 0x04 & 0x40 & 0x01 */
  2131    * (There is the possibility that all subdevices raised an intterupt
  2131   /* B: 0x20 & 0x40 & 0x08 */
  2132    * at the same time.  I don't know how this is resolved by the board.
  2132   if((icsr & 0x45) == 0x45) {
  2133    * So we've to try each subdevice in turn.) */
  2133     struct me8100_subinfo *subinfo = &info->subinfo[0];
  2134   for (i = 0; i <= 1; ++i) {
  2134     PDEBUG("me8100_isr():Int1 occured\n");
  2135     if ((icsr & icsr_mask[i]) == icsr_mask[i]) {
  2135     subinfo->int_seen = 1;
  2136 
  2136     subinfo->int_count++;
  2137       struct me8100_subinfo *subinfo = &info->subinfo[i];
  2137     dummy = inw(info->me8100_regbase + ME8100_RES_INT_REG_A); 
  2138       subinfo->int_seen = jiffies;
  2138     wake_up_interruptible(&subinfo->readq);
  2139       ++subinfo->int_count;
  2139     if (subinfo->fasync_ptr) kill_fasync(&subinfo->fasync_ptr, SIGIO, POLL_IN);
  2140 
  2140 
  2141       subinfo->int_di = inw(subinfo->regbase + ME8100_INT_DI_REG);
  2141   } else if((icsr & 0x68) == 0x68) {
  2142       inw(subinfo->regbase + ME8100_RES_INT_REG);	  // dummy read
  2142     struct me8100_subinfo *subinfo = &info->subinfo[1];
  2143 
  2143     PDEBUG("me8100_isr():Int2 occured\n");
  2144       PDEBUG("===> read: 0x%04x\n", subinfo->int_di);
  2144     subinfo->int_seen = 1;
  2145       wake_up_interruptible(&subinfo->readq);
  2145     subinfo->int_count++;
  2146       if (subinfo->fasync_ptr) kill_fasync(&subinfo->fasync_ptr, SIGIO, POLL_IN);
  2146     dummy = inw(info->me8100_regbase + ME8100_RES_INT_REG_B); 
  2147     }
  2147     wake_up_interruptible(&subinfo->readq);
  2148   }
  2148     if (subinfo->fasync_ptr) kill_fasync(&subinfo->fasync_ptr, SIGIO, POLL_IN);
  2149 
  2149 
       
  2150   } else {
       
  2151     PDEBUG("me8100_isr():Not this Board\n");
       
  2152     return;
       
  2153   }
       
  2154 
  2150 
  2155   return;
  2151   return;
  2156 
  2152 
  2157 } 
  2153 } 
  2158 
  2154 
  2200  * This seems to be ok, since it's not expected to read more than one word at once
  2196  * This seems to be ok, since it's not expected to read more than one word at once
  2201  * (the port is one word wide only!)
  2197  * (the port is one word wide only!)
  2202  *
  2198  *
  2203  * If a a reader (identified by the file_ptr) calls this functions the first time,
  2199  * If a a reader (identified by the file_ptr) calls this functions the first time,
  2204  * the current input is returned.  Every succsessive read is then put to sleep until
  2200  * the current input is returned.  Every succsessive read is then put to sleep until
  2205  * the status of the input changed.  (Unless the IRQ behaviour if the device is changed by
  2201  * the status of the input changed.  (Signalled by an interrupt.)  If awoken from
  2206  * some ioctl()s.)
  2202  * interrupt, the value that caused the interrupt ist read.
  2207  */
  2203  */
  2208 ssize_t me8100_read(struct file * file_ptr, char *buffer, size_t len, loff_t *offset) 
  2204 ssize_t me8100_read(struct file * file_ptr, char *buffer, size_t len, loff_t *offset) 
  2209 {
  2205 {
  2210   int err;
  2206   int err;
  2211   unsigned short val;
  2207   unsigned short val;
  2218   minor = MINOR(file_ptr->f_dentry->d_inode->i_rdev);
  2214   minor = MINOR(file_ptr->f_dentry->d_inode->i_rdev);
  2219   subinfo = &info_vec[DEVICE(minor)].subinfo[SUBDEVICE(minor)];
  2215   subinfo = &info_vec[DEVICE(minor)].subinfo[SUBDEVICE(minor)];
  2220   
  2216   
  2221   if (len == 0) return 0;	/* do we really need this check? */
  2217   if (len == 0) return 0;	/* do we really need this check? */
  2222   if (len < 0) return -EINVAL;	/* do we really need this check? */
  2218   if (len < 0) return -EINVAL;	/* do we really need this check? */
  2223   if (priv->last_read > subinfo->last_change) {
  2219 
       
  2220   if (priv->last_read >= subinfo->int_seen) {	/* alread seen, sleep */
  2224     PDEBUG("*** going to sleep\n");
  2221     PDEBUG("*** going to sleep\n");
  2225     interruptible_sleep_on(&subinfo->readq);
  2222     if (wait_event_interruptible(subinfo->readq, (priv->last_read != subinfo->int_seen))) {
  2226   }
  2223       PDEBUG("** awoken on signal?\n");
  2227   priv->last_read = jiffies;
  2224       return -ERESTARTSYS;
  2228 
  2225     }
  2229   val = inw(subinfo->regbase + ME8100_DI_REG);
  2226     val = subinfo->int_di;	/* the value that caused the interrupt */
  2230   PDEBUG("me8100_read: val=0x%04x\n", val);
  2227   } else {					/* not yet seen ... */
       
  2228     val = inw(subinfo->regbase + ME8100_DI_REG);
       
  2229     PDEBUG("me8100_read: val=0x%04x\n", val);
       
  2230   }
       
  2231 
       
  2232   priv->last_read = subinfo->int_seen;
  2231 
  2233 
  2232   if (len >= sizeof(val)) {
  2234   if (len >= sizeof(val)) {
  2233     err = put_user(val, (unsigned short*) buffer);
  2235     err = put_user(val, (unsigned short*) buffer);
  2234     len = sizeof(val);
  2236     len = sizeof(val);
  2235   } else {
  2237   } else {