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

📄 ul_tors.c

📁 linux下的RS485的驱动 值得一看
💻 C
字号:
/*******************************************************************  uLan Communication - uL_DRV - multiplatform uLan driver  ul_tors.c	- initialize and free of one driver  (C) Copyright 1996-2004 by Pavel Pisa - project originator        http://cmp.felk.cvut.cz/~pisa  (C) Copyright 1996-2004 PiKRON Ltd.        http://www.pikron.com  (C) Copyright 2002-2004 Petr Smolik    The uLan driver project can be used and distributed   in compliance with any of next licenses   - GPL - GNU Public License     See file COPYING for details.   - LGPL - Lesser GNU Public License   - MPL - Mozilla Public License   - and other licenses added by project originator  Code can be modified and re-distributed under any combination  of the above listed licenses. If contributor does not agree with  some of the licenses, he/she can delete appropriate line.  WARNING: if you delete all lines, you are not allowed to  distribute code or sources in any form. *******************************************************************//*******************************************************************//* initialize and free of one driver */ /* set initial state */void ul_drv_new_init_state(ul_drv* udrv, int my_adr){  /* init sequencer */  udrv->fnc_sp=&udrv->fnc_stack[0]; #ifdef UL_WITH_FRAME_FSM  udrv->fnc_act=&uld_drvloop; #else /*UL_WITH_FRAME_FSM*/  udrv->fnc_act=&uld_null_fnc; #endif /*UL_WITH_FRAME_FSM*/  udrv->my_adr=my_adr; #ifdef uld_kwt_wq_init  uld_kwt_wq_init(udrv); #endif  udrv->fnc_timeout=NULL;  /* udrv->flags=0; */  udrv->magic=UL_DRV_MAGIC;  udrv->operators=NULL;}/* setups buffers, ports and irq for sucesfully detected device */int ul_drv_new_start(ul_drv* udrv, unsigned buffer_size){ int ret;  int test_cnt;  #ifdef FOR_LINUX_KERNEL   unsigned long probe_irqs;  #endif /* FOR_LINUX_KERNEL */  /* init ports */  ret=udrv->fnc_cctrl(udrv,UL_CC_PINIT,0);  UL_PRINTF(KERN_INFO "uLan_pinit ret %d\n",ret);  if(ret>=0)  { /* take buffer memory */    ret=ul_mem_init(udrv,buffer_size);    UL_PRINTF(KERN_INFO "ul_mem_init ret %d\n",ret);    if(ret>=0)    { /* request irq */      test_cnt=3;      ret=udrv->fnc_cctrl(udrv,UL_CC_RQIRQ,0);     #ifdef UL_WITH_FRAME_FSM      if(ret==UL_RC_ENOFNC){ /* default IRQ handling */	ret=0;	#ifdef FOR_LINUX_KERNEL	while(test_cnt--&&udrv->irq<=0)	{ /* probe for IRQ */	  probe_irq_off(probe_irq_on());	  probe_irqs=probe_irq_on();	  ret=udrv->fnc_cctrl(udrv,UL_CC_GENIRQ,1);	  udelay(100);	  udrv->irq=probe_irq_off(probe_irqs);	  ret=udrv->fnc_cctrl(udrv,UL_CC_GENIRQ,0);	  UL_PRINTF(KERN_INFO "uLan ul_drv_new : probed irq %d\n",udrv->irq);	};	#endif /* FOR_LINUX_KERNEL */	if(udrv->irq<=0) ret=-1;	  #ifndef _WIN32	  else ret=request_irq(udrv->irq, uld_irq_handler,                               UL_SA_IRQ_FLAGS , "ulan", udrv);	  #endif /* _WIN32 */      }     #endif /*UL_WITH_FRAME_FSM*/      if (ret>=0)      { /* sucessful initialization */	INIT_UDRV_WDTIM(udrv);	INIT_UDRV_BH(udrv);	uld_set_dfl(udrv,CHIPOK);	return 0;      } else UL_PRINTF(KERN_ERR "uLan ul_drv_new : cannot request irq %d\n",udrv->irq);      ul_mem_done(udrv);    } else UL_PRINTF(KERN_ERR "uLan ul_drv_new : no memory for buffers\n");    ret=udrv->fnc_cctrl(udrv,UL_CC_PDONE,0);  } else UL_PRINTF(KERN_ERR "uLan ul_drv_new : port 0x%lx init error\n",                   udrv->port);  return -1;}#ifndef _WIN32/* initialize new driver from given parameters */ul_drv *ul_drv_new(int port, int irq, int baud, int my_adr, char *chip_name, long baudbase){  ul_drv* udrv;  int ret;  int chipidx=0;  int chipprobe=1;  /* covert chip name to index */  if(chip_name&&strcmp(chip_name,"auto")) {    for(chipidx=0;1;chipidx++){      if(!ul_chip_types[chipidx].chip_name){	UL_PRINTF(KERN_ERR "uLan ul_drv_new : unknown chip type %s\n",chip_name);	return NULL;      }      if(!strcmp(ul_chip_types[chipidx].chip_name,chip_name)){	chipprobe=0; break;      }    }  }  UL_PRINTF(KERN_INFO "uLan ul_drv_new : chip %s index %d probe %d\n", 		 chip_name?chip_name:"auto",chipidx,chipprobe);  /* mem for ul_drv */  if(!(udrv=MALLOC(sizeof(ul_drv)))) return NULL;  /* clear memory */  memset(udrv,0,sizeof(ul_drv));  /* set initial state */  ul_drv_new_init_state(udrv, my_adr);  /* init chip driver */  ret=-1;  do{    ul_chip_init_fnc *chip_init;    int chip_flags=ul_chip_types[chipidx].chip_flags;    int chip_options=ul_chip_types[chipidx].chip_options;    chip_init=ul_chip_types[chipidx].chip_init;    if(chipprobe&&(ul_chip_types[chipidx].chip_flags&UL_CHIPT_NOPROBE))      continue;    /* if(ret=u510_init(udrv, port, irq, baud, baudbase))>=0) */    if((chip_flags&UL_CHIPT_RQPORT)&&!port) continue;    if((chip_flags&UL_CHIPT_RQIRQ)&&!irq) continue;    if((ret=(*chip_init)(udrv, port, irq, baud, baudbase, chip_options))>=0){      UL_PRINTF(KERN_INFO "uLan ul_drv_new : %s found at 0x%lx\n",   		 ul_chip_types[chipidx].chip_name,udrv->port);      break;    }  }while(chipprobe&&ul_chip_types[++chipidx].chip_name);  if(ret>=0)  { /* setups buffers, ports and irq for sucesfully detected device */    if(ul_drv_new_start(udrv,ulbuffer)>=0)      return udrv;  }  UL_PRINTF(KERN_ERR "uLan ul_drv_new : failed to init\n");  FREE(udrv);  return NULL;};/* destroy driver */void ul_drv_free(ul_drv *udrv){  if(!udrv) return;  if(uld_test_dfl(udrv,CHIPOK))  { if(udrv->fnc_cctrl(udrv,UL_CC_FREEIRQ,0)==UL_RC_ENOFNC)      if(udrv->irq)        free_irq(udrv->irq,udrv);   }  if(udrv->irq>0) ul_synchronize_irq(udrv->irq);  KILL_UDRV_BH(udrv);  DONE_UDRV_WDTIM(udrv);  schedule();  if(uld_test_dfl(udrv,CHIPOK))  { uld_clear_dfl(udrv,CHIPOK);    udrv->fnc_cctrl(udrv,UL_CC_PDONE,0);  };  if(udrv->irq>0) ul_synchronize_irq(udrv->irq);  KILL_UDRV_BH(udrv);  { /* first not complete sanity check of client list */    ul_opdata *opptr;    UL_DRV_LOCK_FINI    UL_DRV_LOCK;    while((opptr=udrv->operators)!=NULL){      udrv->operators=opptr->opnext;       if(udrv->operators!=NULL) udrv->operators->opprew=NULL;      opptr->udrv=NULL;     #ifdef FOR_LINUX_KERNEL      wake_up_interruptible(&opptr->wqrec);     #endif /*FOR_LINUX_KERNEL*/    }    UL_DRV_UNLOCK;  };  ul_mem_done(udrv);  FREE(udrv);};#endif /* _WIN32 */

⌨️ 快捷键说明

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