⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eibdrv.c

📁 欧洲安装总线系统的USB串口接口驱动c程序源代码.软件代码由西门子公司提供
💻 C
📖 第 1 页 / 共 5 页
字号:
             (ftstation.state==FT_STATE_WAIT_FOR_RESET_ACK) ||             (ftstation.state==FT_STATE_WAIT_FOR_RESP_STATUS))            wake_up_interruptible(&wq_wait_for_ack);      }      set_fs(fs);   }   while(1);}int open_ftstation(void){  #if LINUX_VERSION_CODE >= VERSION_CODE(2,1,0)      struct dentry *ser_dentry=NULL;#endif      struct inode *ser_inode=NULL;   struct async_struct ser_async;   struct termios help_termios;   fs=get_fs();   set_fs(KERNEL_DS);#ifdef __SMP__   lock_kernel();#endif#if LINUX_VERSION_CODE >= VERSION_CODE(2,1,0)                                     ftstation.port.filp=filp_open(port,O_RDWR|O_NOCTTY|O_EXCL,0600);   if (IS_ERR(ftstation.port.filp))    {  printk(KERN_ERR "eibdrv (%i): cannot open serial port %s\n",c++,port);      goto fail_open_serport;   }   ser_dentry=ftstation.port.filp->f_dentry;   ftstation.port.inodp=ser_inode=ser_dentry->d_inode;#else   ftstation.port.filp=open_fp(port,O_RDWR|O_NOCTTY|O_EXCL,0600);   if (ftstation.port.filp==NULL)   {  printk(KERN_ERR "eibdrv (%i): cannot open serial port %s\n",c++,port);      goto fail_open_serport;   }   ftstation.port.inodp=ser_inode=ftstation.port.filp->f_inode;   #endif       if (ftstation.port.filp->f_op->ioctl(ser_inode,ftstation.port.filp,                TIOCSERGSTRUCT,(unsigned long)&ser_async)<0)   {  printk(KERN_ERR "eibdrv (%i): cannot get async_struct\n",c++);      goto fail_get_async;   }        ftstation.port.tty=ser_async.tty;   ftstation.port.old_termios=*(ftstation.port.tty->termios);               ftstation.port.tty->termios->c_iflag=IGNPAR |         // ignore bytes with parity or framing errors                                        INPCK;           // enable input parity checking    ftstation.port.tty->termios->c_oflag=0x00;   ftstation.port.tty->termios->c_cflag=symb_baudrate |  // baudrate                                        CRTSCTS |        // hardware flow control                                        CS8 |            // character size 8 bit                                        PARENB |         // parity bit                                         CLOCAL |         // ignore modem control lines                                        CREAD;           // enable receiver   ftstation.port.tty->termios->c_lflag=0x00;   ftstation.port.tty->termios->c_cc[VTIME]=0;   ftstation.port.tty->termios->c_cc[VMIN]=0;             ftstation.port.tty->driver.set_termios(ftstation.port.tty,&help_termios);   ftstation.port.tty->ldisc.set_termios(ftstation.port.tty,&help_termios);#ifdef __SMP__   unlock_kernel();#endif      if (mode==FT_SERVERMODE)   {  if ((ftstation.wpbuf=eib_get_wpbuf(wpbuf_size))==NULL)      {  printk(KERN_ERR "eibdrv (%i): cannot allocate memory for list of write processes\n",c++);         goto fail_wpbuf;      }            if ((ftstation.rpbuf=eib_get_rpbuf(rpbuf_size,rpbuf_msgbuf_size))==NULL)      {  printk(KERN_ERR "eibdrv (%i): cannot allocate memory for list of read processes\n",c++);         goto fail_rpbuf;      }             if ((ftstation.outbuf=eib_get_buf(outbuf_size))==NULL)      {  printk(KERN_ERR "eibdrv (%i): cannot allocate memory for message buffer\n",c++);         goto fail_outbuf;      }   }      set_fs(fs);         return 0;         fail_outbuf:       eib_return_rpbuf(ftstation.rpbuf);   fail_rpbuf:        eib_return_wpbuf(ftstation.wpbuf);   fail_wpbuf:        *(ftstation.port.tty->termios)=ftstation.port.old_termios;                      ftstation.port.tty->driver.set_termios(ftstation.port.tty,&help_termios);                      ftstation.port.tty->ldisc.set_termios(ftstation.port.tty,&help_termios);   fail_get_async:    #if LINUX_VERSION_CODE >= VERSION_CODE(2,1,0)                       filp_close(ftstation.port.filp,NULL);#else                      close_fp(ftstation.port.filp);#endif   fail_open_serport: #ifdef __SMP__                      unlock_kernel();#endif                      set_fs(fs);                      return -ESHUTDOWN;}int close_ftstation(void){  struct termios help_termios;      if (mode==FT_SERVERMODE)   {  eib_return_buf(ftstation.outbuf);      eib_return_rpbuf(ftstation.rpbuf);      eib_return_wpbuf(ftstation.wpbuf);   }      fs=get_fs();   set_fs(KERNEL_DS);#ifdef __SMP__   lock_kernel();#endif            *(ftstation.port.tty->termios)=ftstation.port.old_termios;               ftstation.port.tty->driver.set_termios(ftstation.port.tty,&help_termios);   ftstation.port.tty->ldisc.set_termios(ftstation.port.tty,&help_termios);#if LINUX_VERSION_CODE >= VERSION_CODE(2,1,0)    filp_close(ftstation.port.filp,NULL);   if (IS_ERR(ftstation.port.filp))    {  printk(KERN_ERR "eibdrv (%i): cannot close serial port %s\n",c++,port);      goto fail_close_serport;   }#else   if (close_fp(ftstation.port.filp)!=0)   {  printk(KERN_ERR "eibdrv (%i): cannot close serial port %s\n",c++,port);      goto fail_close_serport;   }#endif      #ifdef __SMP__   unlock_kernel();#endif      set_fs(fs);   return 0;         fail_close_serport:    #ifdef __SMP__                       unlock_kernel();#endif      		       set_fs(fs);                       return -ESHUTDOWN;}int eibdrv_open(struct inode *eib_inode,struct file *eib_filp){  int blockmode;   int result;   switch(mode)   {  case FT_SERVERMODE:              switch(ftstation.state)              {  case FT_STATE_INIT:                         if (ftstation.servproc==2) return -EBUSY;                         ftstation.servproc++;                         return 0;                 case FT_STATE_SHUTDOWN:                         return -EBUSY;                 default:                         if (!MOD_IN_USE)          // first open                         {  if ((eib_filp->f_flags & O_EXCL)!=0)                                ftstation.f_exclusive=FT_EXCLUSIVE_RW;                            else                                ftstation.f_exclusive=FT_SHARED_RW;                         }                         else                         {  if (((eib_filp->f_flags & O_EXCL)!=0) || (ftstation.f_exclusive==FT_EXCLUSIVE_RW))                               return -EBUSY;                         }                                                  if (!(eib_filp->f_flags&O_NONBLOCK))  blockmode=FT_PROC_BLOCKED;                         else                                  blockmode=FT_PROC_NONBLOCKED;                         result=eib_ins_rpbuf(ftstation.rpbuf,eib_filp,blockmode);                         if (!result) MOD_INC_USE_COUNT;                         return result;              }      case FT_STANDARDMODE:              if (!MOD_IN_USE)          // first open              {  if ((eib_filp->f_flags & O_EXCL)!=0)                     ftstation.f_exclusive=FT_EXCLUSIVE_RW;                 else                     ftstation.f_exclusive=FT_SHARED_RW;              }              else              {  if (((eib_filp->f_flags & O_EXCL)!=0) || (ftstation.f_exclusive==FT_EXCLUSIVE_RW))                    return -EBUSY;              }                                       MOD_INC_USE_COUNT;              return 0;   }    return 0;}#if LINUX_VERSION_CODE >= VERSION_CODE(2,1,0)int eibdrv_release(struct inode *eib_inodp,struct file *eib_filp)#elsevoid eibdrv_release(struct inode *eib_inodp,struct file *eib_filp)#endif{  switch(mode)   {  case FT_SERVERMODE:              switch(ftstation.state)              {  case FT_STATE_SHUTDOWN:                         ftstation.servproc--;                         wake_up_interruptible(&wq_shutdown);                         break;                 default:                         MOD_DEC_USE_COUNT;                         eib_rm_rpbuf(ftstation.rpbuf,eib_filp);                          break;              }              break;      case FT_STANDARDMODE:              MOD_DEC_USE_COUNT;              break;   }#if LINUX_VERSION_CODE >= VERSION_CODE(2,1,0)   return 0;#endif}    #if LINUX_VERSION_CODE >= VERSION_CODE(2,1,0)ssize_t eibdrv_write(struct file *eib_filp,const char *buf,size_t len,loff_t *pos)#elseread_write_t eibdrv_write(struct inode *eib_inodp, struct file *eib_filp,const char *buf,int len)#endif{  unsigned char element[EIB_BUF_ELEMENT_SIZE];   int blockmode;   int result;   int copylen;   int wmode,rmmode;   if (len>23) copylen=23; else copylen=len;#if LINUX_VERSION_CODE >= VERSION_CODE(2,1,0)   if (copy_from_user(&element[0],buf,copylen)!=0)      return -EFAULT;#else   memcpy_fromfs(&element[0],buf,copylen);#endif         if (!(eib_filp->f_flags & O_NONBLOCK)) blockmode=FT_PROC_BLOCKED;   else                                   blockmode=FT_PROC_NONBLOCKED;         wmode=eib_get_rpbuf_wmode(ftstation.rpbuf,eib_filp);   rmmode=wmode+1;   while((ftstation.wpbuf->count==wpbuf_size)||(ftstation.outbuf->count==outbuf_size))   {  if (blockmode==FT_PROC_NONBLOCKED)         return -EAGAIN;      else         interruptible_sleep_on(&wq_fullwproc);   }      eib_write_buf(ftstation.outbuf,&element[0],copylen);   eib_write_wpbuf(ftstation.wpbuf,current->pid,rmmode);   wake_up_interruptible(&wq_ser_write);      if (wmode==FT_WRITE_STANDARD) return copylen;   do   {  interruptible_sleep_on(&wq_wproc);      result=eib_condrm_wpbuf(ftstation.wpbuf,current->pid);   }   while (result==-ENORESULT);      return result;}#if LINUX_VERSION_CODE >= VERSION_CODE(2,1,0)ssize_t eibdrv_read(struct file *eib_filp,char *buf,size_t len,loff_t *pos)#elseread_write_t eibdrv_read(struct inode *eib_inodp,struct file *eib_filp,char *buf,int len)#endif{  unsigned char element[EIB_BUF_ELEMENT_SIZE];   int blockmode;   int copylen;   if (!(eib_filp->f_flags & O_NONBLOCK)) blockmode=FT_PROC_BLOCKED;   else                                   blockmode=FT_PROC_NONBLOCKED;   do   {  copylen=eib_rmsg_rpbuf(ftstation.rpbuf,eib_filp,&element[0]);      if (copylen>0)      {  if (copylen>len) copylen=len;#if LINUX_VERSION_CODE >= VERSION_CODE(2,1,0)                  if (copy_to_user(buf,&element[0],copylen)!=0)            return -EFAULT;#else         memcpy_tofs(buf,&element[0],copylen);#endif                  return copylen;      }      if (blockmode==FT_PROC_NONBLOCKED) return -EAGAIN;      interruptible_sleep_on(&wq_rproc);   }        while(1);}#if LINUX_VERSION_CODE >= VERSION_CODE(2,1,0)int eibdrv_fasync(int eib_fd,struct file *eib_filp,int flag){  return fasync_helper(eib_fd,eib_filp,flag,&(ftstation.pasync));}#elseint eibdrv_fasync(struct inode *eib_inodp,struct file *eib_filp,int flag){  return fasync_helper(eib_inodp,eib_filp,flag,&(ftstation.pasync));}#endifint eibdrv_ioctl(struct inode *eib_inode,struct file *eib_filp,                   unsigned int cmd,unsigned long arg){  int result;   Eib_statistics stat;/*    if (current->euid!=0)   // cmd only available to root user   {  switch(cmd)      {  case FT_SET_OUTBUF_SIZE:         case FT_SET_WPBUF_SIZE:         case FT_SET_RPBUF_SIZE:         case FT_SET_RPBUF_MSGSIZE:         case FT_GET_BAUDRATE:         case FT_GET_PORT_LENGTH:         case FT_GET_PORT:         case FT_ISSERVPROC:         case FT_RESET:         case FT_RESET_STAT:         case FT_GET_STAT:         case FT_GETRESET_STAT:                  return -EACCES;      }   }  */          switch(cmd)   {  case FT_GET_MODE :              return mode;      case FT_GET_BAUDRATE :              return symb_baudrate;      case FT_GET_PORT_LENGTH :              return strlen(port);      case FT_GET_PORT:      #if LINUX_VERSION_CODE >= VERSION_CODE(2,1,0)                             if (copy_to_user((char *)arg,port,strlen(port)+1)!=0)                 return -EFAULT;#else              memcpy_tofs((void *)arg,port,strlen(port)+1);            #endif              return strlen(port);                    case FT_RESET :              return ser_reset();      case FT_RESP_STATUS :              return ser_status();                          case FT_RESET_STAT :              reset_statistics(&ftstation.stat);              return 0;      case FT_GET_STAT :      case FT_GETRESET_STAT :              if (ftstation.stat.overflow>0)                  return -EOVERFLOW;              stat=ftstation.stat;    // copy_to_user may block!                               if (mode==FT_SERVERMODE)              {  stat.outbuf_count=eib_get_buf_count(ftstation.outbuf);                 stat.wpbuf_count=eib_get_wpbuf_count(ftstation.wpbuf);                 stat.rpbuf_count=eib_get_rpbuf_cou

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -