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

📄 ul_cps1.c

📁 linux下的RS485的驱动 值得一看
💻 C
📖 第 1 页 / 共 2 页
字号:
  while(!uld_atomic_test_dfl(udrv,KWTKILL) && !fatal_err){    uld_kwt_confirm(udrv);        while(!ul_usb_tx_fifo_full(&tx_fifo)){ /* when free Tx slot */      /* Initiate sending of message from the prep_bll queue */      if(!(tx_mes=udrv->con_message=udrv->prep_bll.first)) break;      /* printudrvbll(udrv); */      ul_bll_move_mes(&udrv->work_bll,tx_mes);      LOG_MESSAGES(KERN_INFO "ul_usb: KWT processing message\n");            if(!++ustamp) ustamp=1;      /* send frames of message */      for(frame=tx_mes;frame;frame=UL_BLK_HEAD(frame).next){	ret=ul_usb_ps1_send_frame(udrv, frame, ustamp);	if(ret<0) {          usb_clear_halt(dev, usb_sndbulkpipe(dev, udrv->ul_usb_outpipe_nr));          UL_BLK_HEAD(tx_mes).flg|=UL_BFL_FAIL;          ul_bll_move_mes(&udrv->proc_bll,tx_mes);          SCHEDULE_BH(udrv);          /* ulan_do_bh(udrv); */	  tx_mes=udrv->con_message=NULL;          break;	}	/* Message has no more frames */	if(!(UL_BLK_HEAD(frame).flg&UL_BFL_TAIL)||	   (UL_BLK_HEAD(frame).next==NULL)){	  tx_fifo.slot[tx_fifo.idxin].ustamp=ustamp;	  tx_fifo.slot[tx_fifo.idxin].msg=tx_mes;          tx_fifo.idxin=ul_usb_tx_fifo_incidx(&tx_fifo,tx_fifo.idxin);          #ifdef FOR_LINUX_KERNEL            tx_sta_time=jiffies;          #endif /* FOR_LINUX_KERNEL */          ul_usb_tx_fifo_print(&tx_fifo);	}      }    }        UL_MB();    in_urb_st=*(volatile unsigned *)&(udrv->ul_usb_in_urb_st);    UL_MB();    if(in_urb_st==2) {      UL_MB();      LOG_IRQ(KERN_CRIT "ul_usb : received head URB (d:%d,s:%d,c:%X,f:%X,l:%d) stmp %d\n",                   in_buf[0],in_buf[1],in_buf[2],in_buf[3],                   in_buf[6]+0x100*in_buf[7],in_buf[4]);      if(in_buf[3]&(U2UBFL_PROC|U2UBFL_FAIL)){        tx_mes=NULL;        ul_usb_tx_fifo_print(&tx_fifo);        if(!ul_usb_tx_fifo_empty(&tx_fifo)){          if(in_buf[4]==tx_fifo.slot[tx_fifo.idxout].ustamp){	    tx_mes=tx_fifo.slot[tx_fifo.idxout].msg;	  }else{            i=ul_usb_tx_fifo_incidx(&tx_fifo,tx_fifo.idxout);	    while((i!=tx_fifo.idxout)&&(tx_fifo.slot[i].msg!=NULL)){	      if(in_buf[4]==tx_fifo.slot[i].ustamp){	        do{                  tx_mes=tx_fifo.slot[tx_fifo.idxout].msg;	          UL_BLK_HEAD(tx_mes).flg|=UL_BFL_FAIL;                  ul_bll_move_mes(&udrv->proc_bll,tx_mes);		  tx_fifo.slot[tx_fifo.idxout].msg=NULL;		  tx_fifo.idxout=ul_usb_tx_fifo_incidx(&tx_fifo,tx_fifo.idxout);                }while(tx_fifo.idxout!=i);                SCHEDULE_BH(udrv);	        tx_mes=tx_fifo.slot[tx_fifo.idxout].msg;              }              i=ul_usb_tx_fifo_incidx(&tx_fifo,i);            }	    if(!tx_mes){              LOG_FATAL(KERN_CRIT "ul_usb_ps1_thread: incorrect ustamp of returned message\n");	    }else{              LOG_FATAL(KERN_CRIT "ul_usb_ps1_thread: some lost ustamp messages\n");	    }          }	}else{	  LOG_FATAL(KERN_CRIT "ul_usb_ps1_thread: tx_mes for returned message\n");	}	if(!tx_mes){          usb_clear_halt(dev, usb_rcvbulkpipe(dev, udrv->ul_usb_inpipe_nr));	}else{	  if(tail_frame&&(UL_BLK_HEAD(tx_mes).flg&UL_BFL_TAIL)){	    frame=tail_frame;	    LOG_MESSAGES("ul_usb_ps1_thread: tail receiption\n");	  }else{	    frame=tx_mes;	  }          if(in_buf[3]&U2UBFL_FAIL){	    UL_BLK_HEAD(tx_mes).flg|=UL_BFL_FAIL;	  }else if(in_buf[3]&U2UBFL_REC) {	    if(!(UL_BLK_HEAD(frame).flg&UL_BFL_REC)){	      UL_BLK_HEAD(tx_mes).flg|=UL_BFL_FAIL;              LOG_FATAL(KERN_CRIT "ul_usb_ps1_thread: tail rec mitchmatch\n");	    }else{	      len=in_buf[6]+in_buf[7]*0x100;	      UL_BLK_HEAD(frame).dadr=in_buf[0];	      UL_BLK_HEAD(frame).sadr=in_buf[1];	      UL_BLK_HEAD(frame).cmd=in_buf[2];	      UL_BLK_HEAD(frame).len=len;              ret=ul_usb_ps1_receive_data(udrv, frame, len);	      if(ret<0) {		UL_BLK_HEAD(tx_mes).flg|=UL_BFL_FAIL;        	LOG_FATAL(KERN_CRIT "ul_usb_ps1_thread: tail receive problem\n");	      }	    }	  }	    	  if((in_buf[3]&U2UBFL_TAIL)&&(UL_BLK_HEAD(frame).flg&UL_BFL_TAIL)	      &&!(UL_BLK_HEAD(tx_mes).flg&UL_BFL_FAIL)){	    tail_frame=UL_BLK_HEAD(frame).next;	    LOG_MESSAGES("ul_usb_ps1_thread: preparing for tail receive\n");          }else{	    if(UL_BLK_HEAD(tx_mes).flg&UL_BFL_M2IN || UL_BLK_HEAD(tx_mes).flg&UL_BFL_FAIL ||	     UL_BLK_HEAD(tx_mes).dadr==udrv->my_adr || !UL_BLK_HEAD(tx_mes).dadr){              ul_bll_move_mes(&udrv->proc_bll,tx_mes);              SCHEDULE_BH(udrv);              /* ulan_do_bh(udrv); */	    }else{              ul_bll_free_mes(tx_mes);	    }	    tx_mes=NULL;	    tail_frame=NULL;	    tx_fifo.slot[tx_fifo.idxout].msg=NULL;	    tx_fifo.idxout=ul_usb_tx_fifo_incidx(&tx_fifo,tx_fifo.idxout);	    ul_usb_tx_fifo_print(&tx_fifo);	  }	}      } else {	LOG_MESSAGES("uLan : begin of receive message\n");	i=0;        /* if(in_buf[3]&U2UBFL_TAIL ) i|=UL_BFL_TAIL; */        /* if(in_buf[3]&U2UBFL_REC) i|=UL_BFL_REC; */        rx_mes=ul_new_frame_head(udrv,in_buf[0]/*dadr*/,in_buf[1]/*sadr*/,              	                 in_buf[2]/*cmd*/, i/*flg*/);	if(rx_mes==NULL){ 	  LOG_FAILS(KERN_ERR "uLan : NO memory for receive\n");          usb_clear_halt(dev, usb_rcvbulkpipe(dev, udrv->ul_usb_inpipe_nr));	}else{	  ul_bll_ins(&udrv->work_bll,rx_mes);	  len=in_buf[6]+in_buf[7]*0x100;          ret=ul_usb_ps1_receive_data(udrv, rx_mes, len);	  if(ret<0) {            LOG_FATAL(KERN_CRIT "ul_usb_ps1_thread: message receive problem\n");            ul_bll_free_mes(rx_mes);	  }else{	    UL_BLK_HEAD(rx_mes).len=len;            UL_BLK_HEAD(rx_mes).stamp=ul_gen_stamp();            ul_bll_move_mes(&udrv->proc_bll,rx_mes);	  }          rx_mes=NULL;          SCHEDULE_BH(udrv);          /* ulan_do_bh(udrv); */          /* printudrvbll(udrv); */	}      }    }        if(in_urb_st!=1)    {      #ifdef FOR_LINUX_KERNEL        ret=16-udrv->ul_usb_in_urb_st;        if((ret==-ENODEV)||(ret==-EILSEQ)||(ret==-EPROTO)){          LOG_FATAL(KERN_INFO "ul_usb: usb2ulan device problem detected\n");          fatal_err=1;          continue;        }      #endif /* FOR_LINUX_KERNEL */      *(volatile unsigned *)&(udrv->ul_usb_in_urb_st)=1;      UL_MB();      if(uld_atomic_test_dfl(udrv,KWTKILL)) break;      LOG_IRQ(KERN_INFO "ul_usb: submitting URB\n");      #ifdef FOR_LINUX_KERNEL        usb_fill_bulk_urb (in_urb, dev, usb_rcvbulkpipe(dev, udrv->ul_usb_inpipe_nr),            (void*)in_buf, 8, ul_usb_ps1_complete_in, udrv);        ret=kc_usb_submit_urb(in_urb, GFP_KERNEL);        if (ret==-EPIPE) {          usb_clear_halt(dev, usb_rcvbulkpipe(dev, udrv->ul_usb_inpipe_nr));          ret=kc_usb_submit_urb(in_urb, GFP_KERNEL);        }          if(ret<0) {          LOG_FATAL(KERN_INFO "ul_usb: KWT usb_submit_urb fatal error %d\n",ret);          fatal_err=1;        }      #else        _usb_fill_bulk_urb (in_urb, dev, usb_rcvbulkpipe(dev, udrv->ul_usb_inpipe_nr),          (void*)in_buf, 8);        ret=_usb_submit_urb(dev,in_urb, NULL,ul_usb_ps1_complete_in,udrv,&in_irp);        if ( !NT_SUCCESS(ret)) {          LOG_FATAL(KERN_INFO "ul_usb: KWT usb_submit_urb fatal error %d\n",ret);          fatal_err=1;        }            #endif /* FOR_LINUX_KERNEL */    } else {      LOG_IRQ(KERN_INFO "ul_usb: KWT sleeping\n");      uld_kwt_wait(udrv);      LOG_IRQ(KERN_INFO "ul_usb: KWT wakeup\n");    }  }  /* Set converter parameters */  ret=usb_control_msg(dev, usb_rcvctrlpipe(dev,0),                      VENDOR_STOP_ULAN, USB_TYPE_VENDOR,                      /*value*/ 0, /*index*/ 0, NULL, 0, ULD_HZ);  if(ret<0) {    LOG_FATAL(KERN_CRIT "ul_usb_ps1_thread: KWT usb_control_msg error %d returned\n",ret);    fatal_err=1;  }    ul_usb_tx_fifo_print(&tx_fifo);  while(!ul_usb_tx_fifo_empty(&tx_fifo)){//    ul_bll_free_mes(tx_fifo.slot[tx_fifo.idxout].msg);    tx_mes=tx_fifo.slot[tx_fifo.idxout].msg;    UL_BLK_HEAD(tx_mes).flg|=UL_BFL_FAIL;    ul_bll_move_mes(&udrv->proc_bll,tx_mes);    tx_fifo.slot[tx_fifo.idxout].msg=NULL;    tx_fifo.idxout=ul_usb_tx_fifo_incidx(&tx_fifo,tx_fifo.idxout);  }    if(in_urb) {    #ifdef FOR_LINUX_KERNEL     #if (LINUX_VERSION_CODE >= VERSION(2,6,9))      usb_kill_urb(in_urb);     #else      usb_unlink_urb(in_urb);     #endif      usb_free_urb(in_urb);    #else      if (in_irp)         IoCancelIrp( in_irp);      FREE( in_urb);    #endif /* FOR_LINUX_KERNEL */    }    #ifdef FOR_LINUX_KERNEL    lock_kernel();  #endif /* FOR_LINUX_KERNEL */  LOG_IRQ(KERN_INFO "ul_usb: KWT finished\n");  uld_kwt_set_stopped(udrv);  #ifdef FOR_LINUX_KERNEL    unlock_kernel();  #else    PsTerminateSystemThread( STATUS_SUCCESS);  #endif /* FOR_LINUX_KERNEL */  return 0;}/*** Wake up worker thread  ***/int ul_usb_ps1_stroke(ul_drv *udrv){  uld_kwt_wake(udrv);  return 0;}/*** Control functions of chip driver  ***/int ul_usb_ps1_cctrl(ul_drv *udrv, int ctrl_fnc, int param){  switch (ctrl_fnc)  {   case UL_CC_PINIT:	/* initialize ports (parameter baud)*/  	{ return 0;  	};   case UL_CC_PDONE:	/* deinitialize ports */  	{ return 0;  	};   case UL_CC_RQIRQ:	/* request IRQ handling - kernel worker thread*/        {         if(uld_kwt_test_and_set_prepared(udrv)) {           LOG_IRQ("ul_usb_ps1_cctrl: KWT already running\n");          return 0;        };	uld_atomic_clear_dfl(udrv,KWTKILL);        #ifdef FOR_LINUX_KERNEL        if(kernel_thread(ul_usb_ps1_thread, udrv,             #if (LINUX_VERSION_CODE < VERSION(2,5,41))              CLONE_FS | CLONE_FILES | CLONE_SIGNAL             #else /* 2.5.41 */              CLONE_KERNEL             #endif /* 2.5.41 */            )<0){  	      LOG_FATAL(KERN_CRIT "ul_usb_ps1_cctrl: Cannot fork KWT thread!!!\n");  	      /*uld_atomic_clear_dfl(udrv,KWTRUN);*/	      uld_kwt_set_stopped(udrv);  	      return UL_RC_EKWT;          }        #endif /*FOR_LINUX_KERNEL*/        #ifdef _WIN32        {          NTSTATUS ntStatus;          ntStatus = PsCreateSystemThread( &udrv->kwt,                          THREAD_ALL_ACCESS, NULL, NULL, NULL, ul_usb_ps1_thread, udrv);          if (!NT_SUCCESS(ntStatus)) {   	    LOG_FATAL(KERN_CRIT "ul_usb_ps1_cctrl: Cannot fork KWT thread!!!\n");  	    /*uld_atomic_clear_dfl(udrv,KWTRUN);*/	    uld_kwt_set_stopped(udrv);  	    return UL_RC_EKWT;          }        }        #endif /* _WIN32 */        LOG_IRQ("ul_usb_ps1_cctrl: KWT forked\n");        return 0;        };   case UL_CC_FREEIRQ:	/* release IRQ handling - kernel worker thread*/  	{         if(!uld_kwt_is_running(udrv)) {           LOG_IRQ("ul_usb_ps1_cctrl: KWT already stopped\n");          return 0;      	};	uld_kwt_kill(udrv);	uld_kwt_wait_stopped(udrv);	LOG_IRQ("ul_usb_ps1_cctrl: KWT stopped\n");  	return 0;  	};  };  return UL_RC_ENOFNC;};/*** Petr Smolik's USB2ULAN version 1 initialize ***/int ul_usb_ps1_init(ul_drv *udrv, int port, int irq, int baud, long baudbase, int options){  udrv->chip_options=options;  if(!baud) baud=19200;  udrv->baud_val=baud;  if(!baudbase)    baudbase=57600;  udrv->baud_base=baudbase;  udrv->baud_div=(udrv->baud_base+baud/2)/baud;  udrv->port=port;  udrv->irq=0;   udrv->fnc_recch=NULL;  udrv->fnc_sndch=NULL;  udrv->fnc_wait=NULL;  udrv->fnc_pool=NULL;  udrv->fnc_connect=NULL;  udrv->fnc_cctrl=&ul_usb_ps1_cctrl;  udrv->fnc_stroke=&ul_usb_ps1_stroke;  udrv->ul_usb_max_pkt_size=8; /* <= U2U_PKT_BUF_SIZE */  udrv->ul_usb_max_msg_inpr=ul_usb_msg_inpr;  if(!udrv->ul_usb_max_msg_inpr)    udrv->ul_usb_max_msg_inpr=1; /* <= U2U_MAX_MSG_INPR */  udrv->ul_usb_outpipe_nr=1;     /* OUT pipe number */  udrv->ul_usb_inpipe_nr=1;      /* IN pipe number */  return 0;};

⌨️ 快捷键说明

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