?? ul_c950pci.c
字號:
udrv->wait_time=((udrv->my_adr-u-1)&0xF)+4; if(((u&0x180)!=0x180)|| (u==0x1FF)) udrv->wait_time+=0x10; udrv->last_ctrl=0; udrv->char_buff=0; udrv->chip_temp=(udrv->my_adr&0x3F)|0x40; UL_FCALL2(*udrv->fnc_wait,u950pci_connect_1); return UL_RC_PROC;};int u950pci_connect_1(ul_drv *udrv, int ret_code){ if(ret_code!=UL_RC_ETIMEOUT) { UL_FRET; return UL_RC_EARBIT;} if(u950pci_rxd_cs(udrv)|| /* check for possible collision */ (u950pci_inb(udrv->port,UART_LSR)&UART_LSR_DR)) { UL_FRET; LOG_CHIO(" EARBIT!"); return UL_RC_EARBIT; } udrv->U950PCI_STATE|=U950PCI_STATE_TX; u950pci_acr_write(udrv,U950PCI_TX_ACR(udrv)); u950pci_outb(udrv->port,UART_LCR,U950PCI_LCR_ULB); u950pci_outb(udrv->port,UART_MCR,U950PCI_TX_MCR(udrv)); UL_FNEXT(u950pci_connect_2); /* wait to end of transfer */ u950pci_icr_write(udrv,UART_TTL,0); /* wait for TEMT */ u950pci_outb(udrv->port,UART_TX,0); u950pci_outb(udrv->port,UART_IER,UART_IER_THRI|UART_IER_RDI); return UL_RC_WIRQ;};int u950pci_connect_2(ul_drv *udrv, int ret_code){ u950pci_outb(udrv->port,UART_LCR,U950PCI_LCR_UL); u950pci_outb(udrv->port,UART_MCR,U950PCI_RX_MCR(udrv)); udrv->U950PCI_STATE&=~U950PCI_STATE_TX; u950pci_acr_write(udrv,U950PCI_RX_ACR(udrv)); if(u950pci_xfl_read(udrv,UART_RFL)>0) { UL_FRET; LOG_CHIO(" EARBIT1!"); return UL_RC_EARBIT; } if(udrv->chip_temp==1) { LOG_CHIO(" Connected"); UL_FRET; }else{ udrv->wait_time=(udrv->chip_temp&3)+1; udrv->chip_temp>>=2; UL_FCALL2(*udrv->fnc_wait,u950pci_connect_1); } return UL_RC_PROC;};/* UL_FNEXT(u950pci_recch); UL_FCALL(u950pci_recch); UL_FCALL2(u950pci_recch,u950pci_recch); UL_FRET;*/static char *u950pci_port_name="ulan_u950pci";/*** 16950pci initialize ports ***/int u950pci_pinit(ul_drv *udrv){ unsigned u; int baud=udrv->baud_val; int cpr, tcr, dl; if (UL_REQ_IOS(udrv->port,8,u950pci_port_name)<0) { LOG_FATAL(KERN_CRIT "uLan u950pci_pinit : cannot reguest ports !\n"); return UL_RC_EPORT; } /* Switch to enhanced mode */ u950pci_outb(udrv->port,UART_LCR,U950PCI_LCR_EFR); u950pci_outb(udrv->port,UART_EFR,UART_EFR_ECB); u950pci_outb(udrv->port,UART_LCR,U950PCI_LCR_UL); /* Disable transmitter output */ u950pci_outb(udrv->port,UART_MCR,U950PCI_RX_MCR(udrv)&3); /* Set up ACR and state */ u950pci_acr_write(udrv,U950PCI_RX_ACR(udrv)); udrv->U950PCI_STATE=U950PCI_STATE_FLUSH; #if 0 /* Read chip ID */ chip_id=u950pci_icr_read(udrv,UART_ID1)<<16; chip_id|=u950pci_icr_read(udrv,UART_ID2)<<8; chip_id|=u950pci_icr_read(udrv,UART_ID3); chip_rev=u950pci_icr_read(udrv,UART_REV); LOG_PORTS(KERN_INFO "uLan u950pci : chip ID %06X. rev %02x\n",chip_id,chip_rev); #endif udrv->chip_buff[0]=0; /* setup baud rate */ if(!baud) baud=19200; u=(udrv->baud_base*8+baud/2)/baud; if (u>0xFFFFFFF) u=0xFFFFFFF; udrv->baud_div=u; /*{long e, tcr_err=0xFFFFFFF; int i; tcr=-1; for(i=16;i>=4;i--){ if(i*0xFFFFFF<u) break; e=u%i; if(e<tcr_err){tcr=i;tcr_err=e;} } }*/ tcr=16; cpr=8; dl=(udrv->baud_div+(cpr*tcr)/2)/(cpr*tcr); /*LOG_PORTS*/ UL_PRINTF(KERN_INFO "uLan u950pci : baud setup TCR=%d CPR=%d DL=%d baud=%ld\n", tcr,cpr,dl,udrv->baud_base*8/(tcr*cpr*dl)); UL_PRINTF(KERN_INFO "uLan u950pci : baud=%d baud_base=%ld baud_div=%d\n", baud,udrv->baud_base,udrv->baud_div); u950pci_icr_write(udrv,UART_CPR,cpr); /* prescaller 1 to 31.875 step 0.125*/ u950pci_icr_write(udrv,UART_TCR,tcr); /* 4 to 16 times per clock */ u950pci_outb(udrv->port,UART_LCR,UART_LCR_DLAB); u950pci_outb(udrv->port,(uchar)UART_DLL,(uchar)dl); u950pci_outb(udrv->port,(uchar)UART_DLM,(uchar)(dl>>8)); u950pci_outb(udrv->port,UART_LCR,U950PCI_LCR_UL); /* setup initial FIFO levels */ u950pci_icr_write(udrv,UART_NMR,U950PCI_NMR_EN); /* 9-bit mode enable */ u950pci_outb(udrv->port,UART_IER,0); /* disable interrupt sources */ u950pci_outb(udrv->port,UART_FCR,UART_FCR_ENABLE_FIFO| UART_FCR_CLEAR_RCVR|UART_FCR_CLEAR_XMIT); /* enable and clear FIFOs */ u950pci_icr_write(udrv,UART_TTL,1); /* transmittion FIFO treshold */ u950pci_icr_write(udrv,UART_RTL,1); /* receive FIFO treshold */ u950pci_inb(udrv->port,UART_LSR); /* reset errors */ u950pci_inb(udrv->port,UART_RX); /* and other irq */ u950pci_outb(udrv->port,UART_MCR,U950PCI_RX_MCR(udrv)); /* Enable interrupts */ return UL_RC_PROC;};/*** 16950pci deinitialize ports ***/int u950pci_pdone(ul_drv *udrv){ u950pci_outb(udrv->port,UART_IER, 0); /* disable interrupts */ /* Switch enhanced mode off */ u950pci_outb(udrv->port,UART_LCR,U950PCI_LCR_EFR); u950pci_outb(udrv->port,UART_EFR,0); u950pci_outb(udrv->port,UART_LCR,U950PCI_LCR_UL); /* clean up */ u950pci_outb(udrv->port,UART_IER,0); /* disable interrupts */ u950pci_outb(udrv->port,UART_MCR,U950PCI_RX_MCR(udrv)&3); /* transmitter off */ u950pci_inb(udrv->port,UART_IIR); /* flush irq */ u950pci_inb(udrv->port,UART_LSR); /* flush irq */ UL_REL_IOS(udrv->port,8); return UL_RC_PROC;};/*** 16950pci generate irq for irq_probe */int u950pci_genirq(ul_drv *udrv,int param){ if(param){ u950pci_outb(udrv->port,UART_MCR, U950PCI_RX_MCR(udrv)); /* transmitter off */ u950pci_outb(udrv->port,UART_IER, UART_IER_MSI); /* enable interrupts */ u950pci_outb(udrv->port,UART_LCR, U950PCI_LCR_ULB); /* trig break */ }else{ u950pci_outb(udrv->port,UART_IER, 0); /* disable interrupts */ u950pci_outb(udrv->port,UART_MCR, U950PCI_RX_MCR(udrv)&3); /* transmitter off */ u950pci_outb(udrv->port,UART_LCR, U950PCI_LCR_UL); /* no break */ u950pci_inb(udrv->port,UART_MSR); /* flush irq */ } return UL_RC_PROC;};#if 0/*** 16950pci request IRQ handling */int u950pci_rqirq(ul_drv *udrv,int param){ return UL_RC_PROC;};/*** 16950pci release IRQ handling */int u950pci_freeirq(ul_drv *udrv,int param){ if(uldrv->irq) free_irq(udrv->irq, udrv); return UL_RC_PROC;};#endif/* support for hardware tests */int u950pci_hwtest(ul_drv *udrv,int param){ unsigned char uc; switch(param) { case 0x10: case 0x11: u950pci_outb(udrv->port,UART_IER, 0); /* disable interrupts */ u950pci_outb(udrv->port,UART_MCR, U950PCI_TX_MCR(udrv)); /* transmitter on */ u950pci_outb(udrv->port,UART_LCR, param&1? U950PCI_LCR_UL:U950PCI_LCR_ULB); /* set TD lines */ case 0x12: uc=u950pci_inb(udrv->port,UART_MSR); return u950pci_inb(udrv->port,UART_LSR)|(uc<<8)| (uc&(U950pci_MSR_RxD)?0:0x10000); case 0x13: u950pci_outb(udrv->port,UART_MCR, U950PCI_RX_MCR(udrv)); /* transmitter off */ uc=u950pci_inb(udrv->port,UART_MSR); return u950pci_inb(udrv->port,UART_LSR)|(uc<<8)| (uc&(U950pci_MSR_RxD)?0:0x10000); } return UL_RC_ENOFNC;};/*** Control functions of chip driver ***/int u950pci_cctrl(ul_drv *udrv, int ctrl_fnc, int param){ switch (ctrl_fnc) { case UL_CC_DIN: /* switch off line transmitter */ u950pci_outb(udrv->port,UART_MCR, U950PCI_RX_MCR(udrv)); u950pci_outb(udrv->port,UART_LCR, U950PCI_LCR_UL); u950pci_acr_write(udrv,U950PCI_RX_ACR(udrv)); return UL_RC_PROC; case UL_CC_DOUT: /* switch on line transmitter */ u950pci_outb(udrv->port,UART_MCR, U950PCI_TX_MCR(udrv)); u950pci_outb(udrv->port,UART_LCR, U950PCI_LCR_UL); u950pci_acr_write(udrv,U950PCI_RX_ACR(udrv)); return UL_RC_PROC; case UL_CC_PINIT: /* initialize ports (parameter baud)*/ return u950pci_pinit(udrv); case UL_CC_PDONE: /* deinitialize ports */ return u950pci_pdone(udrv); case UL_CC_GENIRQ: /* generate irq for irq_probe */ return u950pci_genirq(udrv,param); #if 0 case UL_CC_RQIRQ: /* request IRQ handling */ return u950pci_rqirq(udrv,param); case UL_CC_FREEIRQ: /* release IRQ handling */ return u950pci_freeirq(udrv,param); #endif case UL_CC_HWTEST: /* support for hardware testing */ return u950pci_hwtest(udrv,param); }; return UL_RC_ENOFNC;};/*** 16950pci chip driver initialize ***/int u950pci_init(ul_drv *udrv, int port, int irq, int baud, long baudbase, int options){ unsigned u; unsigned old_mcr, mcr_ie; unsigned chip_id, chip_rev; if(!irq||!port){ LOG_FATAL(KERN_CRIT "uLan u950pci_init : port or irq unknown\n"); return UL_RC_EPORT; } UL_PRINTF(KERN_INFO "uLan u950pci_init : irq %d port 0x%x\n",irq,port); if (UL_REQ_IOS(port,8,u950pci_port_name)<0) { LOG_FATAL(KERN_CRIT "uLan u950pci_init : cannot reguest ports !\n"); return UL_RC_EPORT; } old_mcr=u950pci_inb(port,UART_MCR); /* find right value for mcr_ie */ mcr_ie=U950PCI_MCR_IE; if(options&U950PCI_CHOPT_TXDTRNEG) mcr_ie^=U950PCI_MCR_TXDTRPOL; /* Disable output buffer */ u950pci_outb(port,UART_MCR,mcr_ie&3); /* Switch to enhanced mode */ u950pci_outb(port,UART_LCR,U950PCI_LCR_EFR); u950pci_outb(port,UART_EFR,UART_EFR_ECB); u950pci_outb(port,UART_LCR,U950PCI_LCR_UL); /* Disable transmitter output */ u950pci_outb(port,UART_MCR,mcr_ie&3); /* Set up ACR and state */ u950pci_outb(port,UART_SCR,UART_ACR); u950pci_outb(port,UART_ICR,U950PCI_ACR_UL|UART_ACR_ICRRD); /* Read chip ID */ u950pci_outb(port,UART_SCR,UART_ID1); chip_id=u950pci_inb(port,UART_ICR)<<16; u950pci_outb(port,UART_SCR,UART_ID2); chip_id|=u950pci_inb(port,UART_ICR)<<8; u950pci_outb(port,UART_SCR,UART_ID3); chip_id|=u950pci_inb(port,UART_ICR); u950pci_outb(port,UART_SCR,UART_REV); chip_rev=u950pci_inb(port,UART_ICR); LOG_PORTS(KERN_INFO "uLan u950pci : chip ID %06X. rev %02x\n",chip_id,chip_rev); /* Switch enhancements off */ u950pci_outb(port,UART_LCR,U950PCI_LCR_EFR); u950pci_outb(port,UART_EFR,0); u950pci_outb(port,UART_LCR,U950PCI_LCR_UL); { LOG_PORTS(KERN_INFO "uLan u950pci_init : init OK\n"); udrv->chip_options=options; udrv->baud_base=baudbase; /* setup configurations for RX/TX */ udrv->U950PCI_RX_ACRMCR=U950PCI_ACR_UL|(U950PCI_MCR_IE<<8); udrv->U950PCI_TX_ACRMCR=U950PCI_ACR_ULTX|(U950PCI_MCR_OE<<8); if(udrv->chip_options&U950PCI_CHOPT_TXDTRNEG){ udrv->U950PCI_RX_ACRMCR^=U950PCI_MCR_TXDTRPOL<<8; udrv->U950PCI_TX_ACRMCR^=U950PCI_ACR_TXDTRPOL|(U950PCI_MCR_TXDTRPOL<<8); } /* check and setup baud base oscilator frequency */ if(!udrv->baud_base){ if(udrv->chip_options&U950PCI_CHOPT_HSPDOSC) udrv->baud_base=14745600; else udrv->baud_base=1843200; } if(!baud) baud=19200; udrv->baud_val=baud; u=(udrv->baud_base*8+baud/2)/baud; if (u>0xFFFFFFF) u=0xFFFFFFF; udrv->baud_div=u; udrv->port=port; udrv->irq=irq; udrv->fnc_recch=&u950pci_recch; udrv->fnc_sndch=&u950pci_sndch; udrv->fnc_wait=&u950pci_wait; udrv->fnc_pool=&u950pci_pool; udrv->fnc_connect=&u950pci_connect; udrv->fnc_cctrl=&u950pci_cctrl; UL_REL_IOS(port,8); return 0; } LOG_PORTS(KERN_ERR "uLan u950pci_init : MCR test Error\n"); UL_REL_IOS(port,8); return UL_RC_EPORT;};
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -