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

📄 teles0.c

📁 arm平台上的uclinux系统全部源代码
💻 C
字号:
/* $Id: teles0.c,v 1.1.1.1 1999/11/15 13:42:18 vadim Exp $ * teles0.c     low level stuff for Teles Memory IO isdn cards *              based on the teles driver from Jan den Ouden * * Author       Karsten Keil (keil@temic-ech.spacenet.de) * * Thanks to    Jan den Ouden *              Fritz Elfert *              Beat Doebeli * * $Log: teles0.c,v $ * Revision 1.1.1.1  1999/11/15 13:42:18  vadim * Initial import * * Revision 1.8.2.9  1998/04/08 21:58:49  keil * New init code * * Revision 1.8.2.8  1998/03/07 23:15:40  tsbogend * made HiSax working on Linux/Alpha * * Revision 1.8.2.7  1998/02/03 23:17:16  keil * IRQ 9 * * Revision 1.8.2.6  1998/01/27 22:37:43  keil * fast io * * Revision 1.8.2.5  1997/11/15 18:51:00  keil * new common init function * * Revision 1.8.2.4  1997/10/17 22:14:26  keil * update to last hisax version * * Revision 2.1  1997/07/27 21:47:10  keil * new interface structures * * Revision 2.0  1997/06/26 11:02:43  keil * New Layer and card interface * * Revision 1.8  1997/04/13 19:54:04  keil * Change in IRQ check delay for SMP * * Revision 1.7  1997/04/06 22:54:04  keil * Using SKB's * * removed old log info /KKe * */#define __NO_VERSION__#include "hisax.h"#include "isdnl1.h"#include "isac.h"#include "hscx.h"extern const char *CardType[];const char *teles0_revision = "$Revision: 1.1.1.1 $";#define byteout(addr,val) outb(val,addr)#define bytein(addr) inb(addr)static inline u_charreadisac(unsigned int adr, u_char off){	return readb(adr + ((off & 1) ? 0x2ff : 0x100) + off);}static inline voidwriteisac(unsigned int adr, u_char off, u_char data){	writeb(data, adr + ((off & 1) ? 0x2ff : 0x100) + off); mb();}static inline u_charreadhscx(unsigned int adr, int hscx, u_char off){	return readb(adr + (hscx ? 0x1c0 : 0x180) +		     ((off & 1) ? 0x1ff : 0) + off);}static inline voidwritehscx(unsigned int adr, int hscx, u_char off, u_char data){	writeb(data, adr + (hscx ? 0x1c0 : 0x180) +	       ((off & 1) ? 0x1ff : 0) + off); mb();}static inline voidread_fifo_isac(unsigned int adr, u_char * data, int size){	register int i;	register u_char *ad = (u_char *) ((long)adr + 0x100);	for (i = 0; i < size; i++)		data[i] = readb(ad);}static inline voidwrite_fifo_isac(unsigned int adr, u_char * data, int size){	register int i;	register u_char *ad = (u_char *) ((long)adr + 0x100);	for (i = 0; i < size; i++) {		writeb(data[i], ad); mb();	}}static inline voidread_fifo_hscx(unsigned int adr, int hscx, u_char * data, int size){	register int i;	register u_char *ad = (u_char *) ((long)adr + (hscx ? 0x1c0 : 0x180));	for (i = 0; i < size; i++)		data[i] = readb(ad);}static inline voidwrite_fifo_hscx(unsigned int adr, int hscx, u_char * data, int size){	int i;	register u_char *ad = (u_char *) ((long)adr + (hscx ? 0x1c0 : 0x180));	for (i = 0; i < size; i++) {		writeb(data[i], ad); mb();	}}/* Interface functions */static u_charReadISAC(struct IsdnCardState *cs, u_char offset){	return (readisac(cs->hw.teles0.membase, offset));}static voidWriteISAC(struct IsdnCardState *cs, u_char offset, u_char value){	writeisac(cs->hw.teles0.membase, offset, value);}static voidReadISACfifo(struct IsdnCardState *cs, u_char * data, int size){	read_fifo_isac(cs->hw.teles0.membase, data, size);}static voidWriteISACfifo(struct IsdnCardState *cs, u_char * data, int size){	write_fifo_isac(cs->hw.teles0.membase, data, size);}static u_charReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset){	return (readhscx(cs->hw.teles0.membase, hscx, offset));}static voidWriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value){	writehscx(cs->hw.teles0.membase, hscx, offset, value);}/* * fast interrupt HSCX stuff goes here */#define READHSCX(cs, nr, reg) readhscx(cs->hw.teles0.membase, nr, reg)#define WRITEHSCX(cs, nr, reg, data) writehscx(cs->hw.teles0.membase, nr, reg, data)#define READHSCXFIFO(cs, nr, ptr, cnt) read_fifo_hscx(cs->hw.teles0.membase, nr, ptr, cnt)#define WRITEHSCXFIFO(cs, nr, ptr, cnt) write_fifo_hscx(cs->hw.teles0.membase, nr, ptr, cnt)#include "hscx_irq.c"static voidteles0_interrupt(int intno, void *dev_id, struct pt_regs *regs){	struct IsdnCardState *cs = dev_id;	u_char val, stat = 0;	int count = 0;	if (!cs) {		printk(KERN_WARNING "Teles0: Spurious interrupt!\n");		return;	}	val = readhscx(cs->hw.teles0.membase, 1, HSCX_ISTA);      Start_HSCX:	if (val) {		hscx_int_main(cs, val);		stat |= 1;	}	val = readisac(cs->hw.teles0.membase, ISAC_ISTA);      Start_ISAC:	if (val) {		isac_interrupt(cs, val);		stat |= 2;	}	count++;	val = readhscx(cs->hw.teles0.membase, 1, HSCX_ISTA);	if (val && count < 20) {		if (cs->debug & L1_DEB_HSCX)			debugl1(cs, "HSCX IntStat after IntRoutine");		goto Start_HSCX;	}	val = readisac(cs->hw.teles0.membase, ISAC_ISTA);	if (val && count < 20) {		if (cs->debug & L1_DEB_ISAC)			debugl1(cs, "ISAC IntStat after IntRoutine");		goto Start_ISAC;	}	if (stat & 1) {		writehscx(cs->hw.teles0.membase, 0, HSCX_MASK, 0xFF);		writehscx(cs->hw.teles0.membase, 1, HSCX_MASK, 0xFF);		writehscx(cs->hw.teles0.membase, 0, HSCX_MASK, 0x0);		writehscx(cs->hw.teles0.membase, 1, HSCX_MASK, 0x0);	}	if (stat & 2) {		writeisac(cs->hw.teles0.membase, ISAC_MASK, 0xFF);		writeisac(cs->hw.teles0.membase, ISAC_MASK, 0x0);	}}voidrelease_io_teles0(struct IsdnCardState *cs){	if (cs->hw.teles0.cfg_reg)		release_region(cs->hw.teles0.cfg_reg, 8);}static intreset_teles0(struct IsdnCardState *cs){	u_char cfval;	long flags;	save_flags(flags);	sti();	if (cs->hw.teles0.cfg_reg) {		switch (cs->irq) {			case 2:			case 9:				cfval = 0x00;				break;			case 3:				cfval = 0x02;				break;			case 4:				cfval = 0x04;				break;			case 5:				cfval = 0x06;				break;			case 10:				cfval = 0x08;				break;			case 11:				cfval = 0x0A;				break;			case 12:				cfval = 0x0C;				break;			case 15:				cfval = 0x0E;				break;			default:				return(1);		}		cfval |= ((cs->hw.teles0.membase >> 9) & 0xF0);		byteout(cs->hw.teles0.cfg_reg + 4, cfval);		HZDELAY(HZ / 10 + 1);		byteout(cs->hw.teles0.cfg_reg + 4, cfval | 1);		HZDELAY(HZ / 10 + 1);	}	writeb(0, cs->hw.teles0.membase + 0x80); mb();	HZDELAY(HZ / 5 + 1);	writeb(1, cs->hw.teles0.membase + 0x80); mb();	HZDELAY(HZ / 5 + 1);	restore_flags(flags);	return(0);}static intTeles_card_msg(struct IsdnCardState *cs, int mt, void *arg){	switch (mt) {		case CARD_RESET:			reset_teles0(cs);			return(0);		case CARD_RELEASE:			release_io_teles0(cs);			return(0);		case CARD_SETIRQ:			return(request_irq(cs->irq, &teles0_interrupt,					I4L_IRQ_FLAG, "HiSax", cs));		case CARD_INIT:			inithscxisac(cs, 3);			return(0);		case CARD_TEST:			return(0);	}	return(0);}__initfunc(intsetup_teles0(struct IsdnCard *card)){	u_char val;	struct IsdnCardState *cs = card->cs;	char tmp[64];	strcpy(tmp, teles0_revision);	printk(KERN_INFO "HiSax: Teles 8.0/16.0 driver Rev. %s\n", HiSax_getrev(tmp));	if ((cs->typ != ISDN_CTYPE_16_0) && (cs->typ != ISDN_CTYPE_8_0))		return (0);	if (cs->typ == ISDN_CTYPE_16_0)		cs->hw.teles0.cfg_reg = card->para[2];	else			/* 8.0 */		cs->hw.teles0.cfg_reg = 0;	if (card->para[1] < 0x10000) {		card->para[1] <<= 4;		printk(KERN_INFO		   "Teles0: membase configured DOSish, assuming 0x%lx\n",		       (unsigned long) card->para[1]);	}	cs->hw.teles0.membase = card->para[1];	cs->irq = card->para[0];	if (cs->hw.teles0.cfg_reg) {		if (check_region((cs->hw.teles0.cfg_reg), 8)) {			printk(KERN_WARNING			  "HiSax: %s config port %x-%x already in use\n",			       CardType[card->typ],			       cs->hw.teles0.cfg_reg,			       cs->hw.teles0.cfg_reg + 8);			return (0);		} else {			request_region(cs->hw.teles0.cfg_reg, 8, "teles cfg");		}	}	if (cs->hw.teles0.cfg_reg) {		if ((val = bytein(cs->hw.teles0.cfg_reg + 0)) != 0x51) {			printk(KERN_WARNING "Teles0: 16.0 Byte at %x is %x\n",			       cs->hw.teles0.cfg_reg + 0, val);			release_region(cs->hw.teles0.cfg_reg, 8);			return (0);		}		if ((val = bytein(cs->hw.teles0.cfg_reg + 1)) != 0x93) {			printk(KERN_WARNING "Teles0: 16.0 Byte at %x is %x\n",			       cs->hw.teles0.cfg_reg + 1, val);			release_region(cs->hw.teles0.cfg_reg, 8);			return (0);		}		val = bytein(cs->hw.teles0.cfg_reg + 2);	/* 0x1e=without AB								   * 0x1f=with AB								   * 0x1c 16.3 ???								 */		if (val != 0x1e && val != 0x1f) {			printk(KERN_WARNING "Teles0: 16.0 Byte at %x is %x\n",			       cs->hw.teles0.cfg_reg + 2, val);			release_region(cs->hw.teles0.cfg_reg, 8);			return (0);		}	}	/* 16.0 and 8.0 designed for IOM1 */	test_and_set_bit(HW_IOM1, &cs->HW_Flags);	printk(KERN_INFO	       "HiSax: %s config irq:%d mem:0x%X cfg:0x%X\n",	       CardType[cs->typ], cs->irq,	       cs->hw.teles0.membase, cs->hw.teles0.cfg_reg);	if (reset_teles0(cs)) {		printk(KERN_WARNING "Teles0: wrong IRQ\n");		release_io_teles0(cs);		return (0);	}	cs->readisac = &ReadISAC;	cs->writeisac = &WriteISAC;	cs->readisacfifo = &ReadISACfifo;	cs->writeisacfifo = &WriteISACfifo;	cs->BC_Read_Reg = &ReadHSCX;	cs->BC_Write_Reg = &WriteHSCX;	cs->BC_Send_Data = &hscx_fill_fifo;	cs->cardmsg = &Teles_card_msg;	ISACVersion(cs, "Teles0:");	if (HscxVersion(cs, "Teles0:")) {		printk(KERN_WARNING		 "Teles0: wrong HSCX versions check IO/MEM addresses\n");		release_io_teles0(cs);		return (0);	}	return (1);}

⌨️ 快捷键说明

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