me8100.c
changeset 4 a90b94337569
parent 3 fc24e3b47731
child 7 ee662c2e14f9
equal deleted inserted replaced
3:fc24e3b47731 4:a90b94337569
   132 static int me8100_ioctl(struct inode *, struct file *, 
   132 static int me8100_ioctl(struct inode *, struct file *, 
   133 			unsigned int , unsigned long ); 
   133 			unsigned int , unsigned long ); 
   134 static int me8100_fasync(int, struct file *, int);
   134 static int me8100_fasync(int, struct file *, int);
   135 static void me8100_isr(int, void *, struct pt_regs *);
   135 static void me8100_isr(int, void *, struct pt_regs *);
   136 static ssize_t me8100_read(struct file *, char *, size_t, loff_t *);
   136 static ssize_t me8100_read(struct file *, char *, size_t, loff_t *);
       
   137 static ssize_t me8100_write(struct file *, const char *, size_t, loff_t *);
   137 
   138 
   138 static int me8100_init_board(me8100_info_type *, struct pci_dev *);
   139 static int me8100_init_board(me8100_info_type *, struct pci_dev *);
   139 static int me8100_reset_board(me8100_info_type *);
   140 static int me8100_reset_board(me8100_info_type *);
   140 
   141 
   141 static int me8100_read_id_a(unsigned short *, me8100_info_type *);
   142 static int me8100_read_id_a(unsigned short *, me8100_info_type *);
   170 static int me8100_setup_icsr(unsigned char *, me8100_info_type *);
   171 static int me8100_setup_icsr(unsigned char *, me8100_info_type *);
   171 static int me8100_read_icsr(unsigned char *, me8100_info_type *);
   172 static int me8100_read_icsr(unsigned char *, me8100_info_type *);
   172 static int me8100_get_board_info(me8100_info_type *, me8100_info_type *);
   173 static int me8100_get_board_info(me8100_info_type *, me8100_info_type *);
   173 static int me8100_get_int_count(me8100_int_occur_type *, me8100_info_type *);
   174 static int me8100_get_int_count(me8100_int_occur_type *, me8100_info_type *);
   174 
   175 
   175 static inline int DEVICE(int i) { return MINOR(i) & 0x0f; }
   176 static inline int DEVICE(int i) { return i & 0x0f; }
   176 static inline int SUBDEVICE(int i) { return MINOR(i) >> 4; }
   177 static inline int SUBDEVICE(int i) { return i >> 4; }
   177 
   178 
   178 
   179 
   179 /* File operations provided by the driver */
   180 /* File operations provided by the driver */
   180 static struct file_operations me8100_file_operations = {
   181 static struct file_operations me8100_file_operations = {
   181 #ifdef LINUX_24
   182 #ifdef LINUX_24
   182   owner:    THIS_MODULE,        /* owner               */
   183   owner:    THIS_MODULE,        /* owner               */
   183 #endif
   184 #endif
   184   llseek:   NULL,	        /* lseek()             */
   185   llseek:   NULL,	        /* lseek()             */
   185   read:	    me8100_read, 	/* read()              */
   186   read:	    me8100_read, 	/* read()              */
   186   write:    NULL,    		/* write()             */
   187   write:    me8100_write,	/* write()             */
   187   readdir:  NULL,	        /* readdir()           */
   188   readdir:  NULL,	        /* readdir()           */
   188   poll:	    NULL,	        /* poll()              */
   189   poll:	    NULL,	        /* poll()              */
   189   ioctl:    me8100_ioctl,       /* ioctl()             */
   190   ioctl:    me8100_ioctl,       /* ioctl()             */
   190   mmap:	    NULL,   		/* mmap()              */
   191   mmap:	    NULL,   		/* mmap()              */
   191   open:	    me8100_open,        /* open()              */
   192   open:	    me8100_open,        /* open()              */
   433     return -EIO;
   434     return -EIO;
   434   }
   435   }
   435   info->me8100_regbase_size = ME8100_BASE_SIZE;
   436   info->me8100_regbase_size = ME8100_BASE_SIZE;
   436   info->me8100_regbase = me8100_regbase_tmp & PCI_BASE_ADDRESS_IO_MASK;
   437   info->me8100_regbase = me8100_regbase_tmp & PCI_BASE_ADDRESS_IO_MASK;
   437   PDEBUG("me8100_init_board():IO at 0x%04X\n", info->me8100_regbase);
   438   PDEBUG("me8100_init_board():IO at 0x%04X\n", info->me8100_regbase);
       
   439 
       
   440   info->subinfo[0].regbase = info->me8100_regbase;
       
   441   info->subinfo[1].regbase = info->me8100_regbase + 0x0C;
   438   
   442   
   439 
   443 
   440   /*--------------------------- init device info ----------------------------*/
   444   /*--------------------------- init device info ----------------------------*/
   441 
   445 
   442   result = pci_read_config_dword(pci_dev_ptr, 0x2C, &info->serial_no);
   446   result = pci_read_config_dword(pci_dev_ptr, 0x2C, &info->serial_no);
   570  * Modification:                                                            
   574  * Modification:                                                            
   571  *   01.10.04  Guard board_in_use with spin_lock, cause of race condition
   575  *   01.10.04  Guard board_in_use with spin_lock, cause of race condition
   572  *             when compiling for SMP.
   576  *             when compiling for SMP.
   573  */
   577  */
   574 static int me8100_open(struct inode *inode_ptr, struct file *file_ptr){
   578 static int me8100_open(struct inode *inode_ptr, struct file *file_ptr){
   575   int minor = 0;
   579   int device,subdevice;
   576   me8100_info_type *info;
   580   me8100_info_type *info;
   577 
   581   struct me8100_subinfo *subinfo;
   578   PDEBUG("*** me8100_open() is executed for pid: %d\n", file_ptr->f_owner.pid);
   582 
   579 
   583   PDEBUG("*** me8100_open() is executed\n");
   580   minor = DEVICE(inode_ptr->i_rdev);
   584 
   581 
   585   device = DEVICE(MINOR(inode_ptr->i_rdev));
   582   PDEBUG("*** device: %d, subdevice %d\n", DEVICE(inode_ptr->i_rdev),
   586   subdevice = SUBDEVICE(MINOR(inode_ptr->i_rdev));
   583       SUBDEVICE(inode_ptr->i_rdev));
   587   info = &info_vec[device];
   584 
   588   subinfo = &info->subinfo[subdevice];
   585   if(minor >= me8100_board_count){
   589 
   586     printk(KERN_ERR"ME8100:me8100_open():Board %d doesn't exist\n", minor);
   590   PDEBUG("*** device: %d, subdevice %d\n", device, subdevice);
       
   591 
       
   592   if(device >= me8100_board_count){
       
   593     printk(KERN_ERR"ME8100:me8100_open():Board %d doesn't exist\n", device);
   587     return -ENODEV;
   594     return -ENODEV;
   588   }
   595   }
   589   info = &info_vec[minor];
       
   590 
   596 
   591   spin_lock(&info->use_lock);
   597   spin_lock(&info->use_lock);
   592   if(info->board_in_use){
   598   if(info->board_in_use){
   593     printk(KERN_ERR "WARNING: ME8100:me8100_open():Board %d already in use\n", minor);
   599     printk(KERN_ERR "WARNING: ME8100:me8100_open():Board %d already in use\n", device);
   594   }
   600   }
   595   ++info->board_in_use;
   601   ++info->board_in_use;
   596   spin_unlock(&info->use_lock);
   602   spin_unlock(&info->use_lock);
   597 
   603 
   598   /* info->file_ptr = file_ptr; */  /* müssen wir uns nicht hier merken! */
   604   if (file_ptr->f_mode & FMODE_WRITE) {
       
   605     PDEBUG("*** open for writing\n");
       
   606 
       
   607     if (0 == subinfo->num_writer++) {
       
   608       subinfo->ctrl_reg |= ME8100_CTRL_ENIO | ME8100_CTRL_SOURCE;
       
   609       PDEBUG("*** setting ENIO+SOURCE mode: ctrl: 0x%x\n", subinfo->ctrl_reg);
       
   610       outw(subinfo->ctrl_reg, subinfo->regbase + ME8100_CTRL_REG);
       
   611     }
       
   612   }
   599 
   613 
   600   MOD_INC_USE_COUNT;
   614   MOD_INC_USE_COUNT;
   601 
   615 
   602   return 0;
   616   return 0;
   603 }
   617 }
   629  *--------------------------------------------------------------------------
   643  *--------------------------------------------------------------------------
   630  * Author: GG                                                               
   644  * Author: GG                                                               
   631  * Modification:                                                            
   645  * Modification:                                                            
   632  */
   646  */
   633 static int me8100_release(struct inode *inode_ptr, struct file *file_ptr){
   647 static int me8100_release(struct inode *inode_ptr, struct file *file_ptr){
   634   int minor;
   648   int device;
   635   int err;
   649   int err;
   636   me8100_info_type *info;
   650   me8100_info_type *info;
       
   651   struct me8100_subinfo* subinfo;
   637 
   652 
   638   
   653   
   639   PDEBUG("me8100_release() is executed\n");
   654   PDEBUG("me8100_release() is executed\n");
   640 
   655 
   641   minor = DEVICE(inode_ptr->i_rdev);
   656   device = DEVICE(MINOR(inode_ptr->i_rdev));
   642   info = &info_vec[minor];
   657   info = &info_vec[device];
       
   658   subinfo = &info->subinfo[SUBDEVICE(MINOR(inode_ptr->i_rdev))];
       
   659 
       
   660   /* Resetting write mode if last writer is gone */
       
   661   if (file_ptr->f_mode & FMODE_WRITE) {
       
   662     PDEBUG("*** writer closes\n");
       
   663     if (0 == --subinfo->num_writer) {
       
   664 	subinfo->ctrl_reg &= !ME8100_CTRL_ENIO;
       
   665 	// PDEBUG("*** resetting ENIO mode ctrl: 0x%x\n", subinfo->ctrl_reg);
       
   666 	// outw(subinfo->ctrl_reg, subinfo->regbase + ME8100_CTRL_REG);
       
   667     }
       
   668   }
   643 
   669 
   644   /* resetting the board on last close */
   670   /* resetting the board on last close */
   645 
   671 
   646   if (--info->board_in_use == 0) {
   672   if (--info->board_in_use == 0) {
   647     err = me8100_reset_board(info);
   673     err = me8100_reset_board(info);
   692 static int me8100_ioctl(struct inode * inode_ptr, 
   718 static int me8100_ioctl(struct inode * inode_ptr, 
   693 			struct file *file_ptr, 
   719 			struct file *file_ptr, 
   694 			unsigned int service, 
   720 			unsigned int service, 
   695 			unsigned long arg){
   721 			unsigned long arg){
   696 
   722 
   697   int minor = 0;
   723   int minor, device;
   698 
   724 
   699   PDEBUG("me8100_ioctl() is executed\n");
   725   PDEBUG("me8100_ioctl() is executed\n");
   700 
   726 
   701   minor = DEVICE(inode_ptr->i_rdev);      
   727   minor = MINOR(inode_ptr->i_rdev);
       
   728   device = DEVICE(minor);
   702 
   729 
   703   if(_IOC_TYPE(service) != ME8100_MAGIC){
   730   if(_IOC_TYPE(service) != ME8100_MAGIC){
   704     printk(KERN_ERR"ME8100:Invalid ME8100_MAGIC\n");
   731     printk(KERN_ERR"ME8100:Invalid ME8100_MAGIC\n");
   705     return -EINVAL;
   732     return -EINVAL;
   706   }
   733   }
   709     return -EINVAL;
   736     return -EINVAL;
   710   }
   737   }
   711 
   738 
   712   switch(service){
   739   switch(service){
   713   case ME8100_READ_ID_A:
   740   case ME8100_READ_ID_A:
   714     return me8100_read_id_a((unsigned short *) arg, &info_vec[minor]);
   741     return me8100_read_id_a((unsigned short *) arg, &info_vec[device]);
   715   case ME8100_WRITE_CTRL_A:
   742   case ME8100_WRITE_CTRL_A:
   716     return me8100_write_ctrl_a((unsigned short *) arg, &info_vec[minor]);
   743     return me8100_write_ctrl_a((unsigned short *) arg, &info_vec[device]);
   717   case ME8100_RES_INT_A:
   744   case ME8100_RES_INT_A:
   718     return me8100_res_int_a(&info_vec[minor]);
   745     return me8100_res_int_a(&info_vec[device]);
   719   case ME8100_READ_DI_A:
   746   case ME8100_READ_DI_A:
   720     return me8100_read_di_a((unsigned short *) arg, &info_vec[minor]);
   747     return me8100_read_di_a((unsigned short *) arg, &info_vec[device]);
   721   case ME8100_WRITE_DO_A:
   748   case ME8100_WRITE_DO_A:
   722     return me8100_write_do_a((unsigned short *) arg, &info_vec[minor]);
   749     return me8100_write_do_a((unsigned short *) arg, &info_vec[device]);
   723   case ME8100_WRITE_PATTERN_A:
   750   case ME8100_WRITE_PATTERN_A:
   724     return me8100_write_pattern_a((unsigned short *) arg, &info_vec[minor]);
   751     return me8100_write_pattern_a((unsigned short *) arg, &info_vec[device]);
   725   case ME8100_WRITE_MASK_A:
   752   case ME8100_WRITE_MASK_A:
   726     return me8100_write_mask_a((unsigned short *) arg, &info_vec[minor]);
   753     return me8100_write_mask_a((unsigned short *) arg, &info_vec[device]);
   727   case ME8100_READ_INT_DI_A:
   754   case ME8100_READ_INT_DI_A:
   728     return me8100_read_int_di_a((unsigned short *) arg, &info_vec[minor]);
   755     return me8100_read_int_di_a((unsigned short *) arg, &info_vec[device]);
   729   case ME8100_READ_ID_B:
   756   case ME8100_READ_ID_B:
   730     return me8100_read_id_b((unsigned short *) arg, &info_vec[minor]);
   757     return me8100_read_id_b((unsigned short *) arg, &info_vec[device]);
   731   case ME8100_WRITE_CTRL_B:
   758   case ME8100_WRITE_CTRL_B:
   732     return me8100_write_ctrl_b((unsigned short *) arg, &info_vec[minor]);
   759     return me8100_write_ctrl_b((unsigned short *) arg, &info_vec[device]);
   733   case ME8100_RES_INT_B:
   760   case ME8100_RES_INT_B:
   734     return me8100_res_int_b(&info_vec[minor]);
   761     return me8100_res_int_b(&info_vec[device]);
   735   case ME8100_READ_DI_B:
   762   case ME8100_READ_DI_B:
   736     return me8100_read_di_b((unsigned short *) arg, &info_vec[minor]);
   763     return me8100_read_di_b((unsigned short *) arg, &info_vec[device]);
   737   case ME8100_WRITE_DO_B:
   764   case ME8100_WRITE_DO_B:
   738     return me8100_write_do_b((unsigned short *) arg, &info_vec[minor]);
   765     return me8100_write_do_b((unsigned short *) arg, &info_vec[device]);
   739   case ME8100_WRITE_PATTERN_B:
   766   case ME8100_WRITE_PATTERN_B:
   740     return me8100_write_pattern_b((unsigned short *) arg, &info_vec[minor]);
   767     return me8100_write_pattern_b((unsigned short *) arg, &info_vec[device]);
   741   case ME8100_WRITE_MASK_B:
   768   case ME8100_WRITE_MASK_B:
   742     return me8100_write_mask_b((unsigned short *) arg, &info_vec[minor]);
   769     return me8100_write_mask_b((unsigned short *) arg, &info_vec[device]);
   743   case ME8100_READ_INT_DI_B:
   770   case ME8100_READ_INT_DI_B:
   744     return me8100_read_int_di_b((unsigned short *) arg, &info_vec[minor]);
   771     return me8100_read_int_di_b((unsigned short *) arg, &info_vec[device]);
   745   case ME8100_WRITE_COUNTER_0:
   772   case ME8100_WRITE_COUNTER_0:
   746     return me8100_write_counter_0((unsigned char *) arg, &info_vec[minor]);
   773     return me8100_write_counter_0((unsigned char *) arg, &info_vec[device]);
   747   case ME8100_WRITE_COUNTER_1:
   774   case ME8100_WRITE_COUNTER_1:
   748     return me8100_write_counter_1((unsigned char *) arg, &info_vec[minor]);
   775     return me8100_write_counter_1((unsigned char *) arg, &info_vec[device]);
   749   case ME8100_WRITE_COUNTER_2:
   776   case ME8100_WRITE_COUNTER_2:
   750     return me8100_write_counter_2((unsigned char *) arg, &info_vec[minor]);
   777     return me8100_write_counter_2((unsigned char *) arg, &info_vec[device]);
   751   case ME8100_READ_COUNTER_0:
   778   case ME8100_READ_COUNTER_0:
   752     return me8100_read_counter_0((unsigned char *) arg, &info_vec[minor]);
   779     return me8100_read_counter_0((unsigned char *) arg, &info_vec[device]);
   753   case ME8100_READ_COUNTER_1:
   780   case ME8100_READ_COUNTER_1:
   754     return me8100_read_counter_1((unsigned char *) arg, &info_vec[minor]);
   781     return me8100_read_counter_1((unsigned char *) arg, &info_vec[device]);
   755   case ME8100_READ_COUNTER_2:
   782   case ME8100_READ_COUNTER_2:
   756     return me8100_read_counter_2((unsigned char *) arg, &info_vec[minor]);
   783     return me8100_read_counter_2((unsigned char *) arg, &info_vec[device]);
   757   case ME8100_SETUP_COUNTER:
   784   case ME8100_SETUP_COUNTER:
   758     return me8100_setup_counter((unsigned char *) arg, &info_vec[minor]);
   785     return me8100_setup_counter((unsigned char *) arg, &info_vec[device]);
   759   case ME8100_GET_SERIAL:
   786   case ME8100_GET_SERIAL:
   760     return me8100_get_serial((unsigned int *) arg, &info_vec[minor]);
   787     return me8100_get_serial((unsigned int *) arg, &info_vec[device]);
   761   case ME8100_GET_NAME:
   788   case ME8100_GET_NAME:
   762     return me8100_get_name((me8100_version_enum_type *) arg, &info_vec[minor]);
   789     return me8100_get_name((me8100_version_enum_type *) arg, &info_vec[device]);
   763   case ME8100_INT_OCCUR:    
   790   case ME8100_INT_OCCUR:    
   764     return me8100_int_occur((me8100_int_occur_type *) arg, &info_vec[minor]);
   791     return me8100_int_occur((me8100_int_occur_type *) arg, &info_vec[device]);
   765   case ME8100_SETUP_ICSR:
   792   case ME8100_SETUP_ICSR:
   766     return me8100_setup_icsr((unsigned char *) arg, &info_vec[minor]);
   793     return me8100_setup_icsr((unsigned char *) arg, &info_vec[device]);
   767   case ME8100_READ_ICSR:
   794   case ME8100_READ_ICSR:
   768     return me8100_read_icsr((unsigned char *) arg, &info_vec[minor]);
   795     return me8100_read_icsr((unsigned char *) arg, &info_vec[device]);
   769   case ME8100_GET_BOARD_INFO:
   796   case ME8100_GET_BOARD_INFO:
   770     return me8100_get_board_info((me8100_info_type *)arg, &info_vec[minor]);
   797     return me8100_get_board_info((me8100_info_type *)arg, &info_vec[device]);
   771   case ME8100_GET_INT_COUNT:
   798   case ME8100_GET_INT_COUNT:
   772     return me8100_get_int_count((me8100_int_occur_type *)arg,&info_vec[minor]);
   799     return me8100_get_int_count((me8100_int_occur_type *)arg,&info_vec[device]);
   773   default:
   800   default:
   774     return -EINVAL;
   801     return -EINVAL;
   775   }
   802   }
   776   
   803   
   777   return 0;
   804   return 0;
   805  * Author: GG                                                               
   832  * Author: GG                                                               
   806  * Modufication:                                                            
   833  * Modufication:                                                            
   807  */
   834  */
   808 static int me8100_fasync(int fd, struct file *file_ptr, int mode){
   835 static int me8100_fasync(int fd, struct file *file_ptr, int mode){
   809   int val;
   836   int val;
   810   int minor;
   837   int device;
   811   me8100_info_type *info;
   838   me8100_info_type *info;
   812 
   839 
   813   minor = DEVICE(file_ptr->f_dentry->d_inode->i_rdev);
   840   device = DEVICE(MINOR(file_ptr->f_dentry->d_inode->i_rdev));
   814   info = &info_vec[minor];
   841   info = &info_vec[device];
   815 
   842 
   816   PDEBUG("me8100_fasync() is executed\n");
   843   PDEBUG("me8100_fasync() is executed\n");
   817   PDEBUG("** fasync_ptr: %p\n", info->fasync_ptr);
   844   PDEBUG("** fasync_ptr: %p\n", info->fasync_ptr);
   818   val = fasync_helper(fd, file_ptr, mode, &info->fasync_ptr);
   845   val = fasync_helper(fd, file_ptr, mode, &info->fasync_ptr);
   819   PDEBUG("** fasync_ptr: %p\n", info->fasync_ptr);
   846   PDEBUG("** fasync_ptr: %p\n", info->fasync_ptr);
  1034   PDEBUG("me8100_write_do_a:To offset=0x%02X\n", ME8100_DO_REG_A);
  1061   PDEBUG("me8100_write_do_a:To offset=0x%02X\n", ME8100_DO_REG_A);
  1035   outw(do_a, info->me8100_regbase + ME8100_DO_REG_A);    
  1062   outw(do_a, info->me8100_regbase + ME8100_DO_REG_A);    
  1036  
  1063  
  1037   return 0;
  1064   return 0;
  1038 }
  1065 }
  1039 
       
  1040 
       
  1041 
  1066 
  1042 /*
  1067 /*
  1043  * Routine:                                                                 
  1068  * Routine:                                                                 
  1044  *   me8100_write_pattern_a                                                 
  1069  *   me8100_write_pattern_a                                                 
  1045  *                                                                          
  1070  *                                                                          
  2065  * Author: GG                                                               
  2090  * Author: GG                                                               
  2066  * Modification:                                                            
  2091  * Modification:                                                            
  2067  */
  2092  */
  2068 void cleanup_module(void){
  2093 void cleanup_module(void){
  2069   extern unsigned int major;
  2094   extern unsigned int major;
  2070   int minor;
  2095   int device;
  2071   int err;
  2096   int err;
  2072 
  2097 
  2073 
  2098 
  2074   PDEBUG("cleanup_module() is executed\n");
  2099   PDEBUG("cleanup_module() is executed\n");
  2075 
  2100 
  2076   for (minor = me8100_board_count - 1; minor > -1; --minor) {
  2101   for (device = me8100_board_count - 1; device > -1; --device) {
  2077     free_irq(info_vec[minor].int_line, (void *) &info_vec[minor]);
  2102     free_irq(info_vec[device].int_line, (void *) &info_vec[device]);
  2078   }
  2103   }
  2079   
  2104   
  2080   if(major){
  2105   if(major){
  2081     err = unregister_chrdev(major, ME8100_NAME);
  2106     err = unregister_chrdev(major, ME8100_NAME);
  2082     if(err)
  2107     if(err)
  2083       printk(KERN_WARNING"ME8100:cleanup_module():cannot unregister major\n");
  2108       printk(KERN_WARNING"ME8100:cleanup_module():cannot unregister major\n");
  2084   }
  2109   }
  2085 }
  2110 }
  2086 
  2111 
  2087 ssize_t me8100_read(struct file * file_ptr, char *buffer, size_t len, loff_t *offset) {
  2112 ssize_t me8100_read(struct file * file_ptr, char *buffer, size_t len, loff_t *offset) 
  2088   PDEBUG("me8100_read() called\n");
  2113 {
       
  2114   PDEBUG("me8100_read(%d) called\n", len);
  2089   return -EINVAL;
  2115   return -EINVAL;
       
  2116 }
       
  2117 
       
  2118 /* Writing: we do only write one word (an unsigned short) and return immediatly.  Yes,
       
  2119  * we could loop over the complete buffer, but it's not expected to get more data
       
  2120  * than one word.  If there's more output, the responsibility is transferred back
       
  2121  * to the C library(?).
       
  2122  */
       
  2123 ssize_t me8100_write(struct file * file_ptr, const char *buffer, size_t len, loff_t *offset) 
       
  2124 {
       
  2125   int err;
       
  2126   unsigned short val;
       
  2127   int minor;
       
  2128   
       
  2129   minor = MINOR(file_ptr->f_dentry->d_inode->i_rdev);
       
  2130   PDEBUG("me8100_write(%d) called\n", len);
       
  2131 
       
  2132   if (len == 0) return 0;	  /* do we need this? */
       
  2133   if (len < 0) return -EINVAL;	  /* do we need this? */
       
  2134 
       
  2135   /* Take care of "short" writes! */
       
  2136   if (len >= sizeof(unsigned short)) {
       
  2137     err = get_user(val, (unsigned short*) buffer);
       
  2138     len = sizeof(unsigned short);
       
  2139   } else {
       
  2140     err = get_user(val, (char*) buffer);
       
  2141     val &= 0xff;
       
  2142   }
       
  2143 
       
  2144   if (err) return err;
       
  2145 
       
  2146   PDEBUG("*** me8100_write: val=0x%04x\n", val);
       
  2147   outw(val, info_vec[DEVICE(minor)].subinfo[SUBDEVICE(minor)].regbase + ME8100_DO_REG);
       
  2148 
       
  2149   return len;
  2090 }
  2150 }
  2091 
  2151 
  2092 /* 
  2152 /* 
  2093   vim:sts=2 sw=2 aw ai sm: 
  2153   vim:sts=2 sw=2 aw ai sm: 
  2094  */
  2154  */