📄 ul_tors.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 + -