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

📄 avm_a1.c

📁 arm平台上的uclinux系统全部源代码
💻 C
字号:
/* $Id: avm_a1.c,v 1.1.1.1 1999/11/15 13:42:17 vadim Exp $ * avm_a1.c     low level stuff for AVM A1 (Fritz) isdn cards * * Author       Karsten Keil (keil@isdn4linux.de) * * * $Log: avm_a1.c,v $ * Revision 1.1.1.1  1999/11/15 13:42:17  vadim * Initial import * * Revision 1.6.2.12  1998/11/03 00:05:44  keil * certification related changes * fixed logging for smaller stack use * * Revision 1.6.2.11  1998/09/27 13:05:30  keil * Apply most changes from 2.1.X (HiSax 3.1) * * Revision 1.6.2.10  1998/05/27 18:04:50  keil * HiSax 3.0 * * Revision 1.6.2.9  1998/04/08 21:58:39  keil * New init code * * Revision 1.6.2.8  1998/01/27 22:37:49  keil * fast io * * Revision 1.6.2.7  1998/01/13 23:06:11  keil * really disable internal timer * * Revision 1.6.2.6  1998/01/02 06:49:01  calle * Perodic timer of A1 now disabled, no need for linux driver. * * Revision 1.6.2.5  1997/11/15 18:50:41  keil * new common init function * * Revision 1.6.2.4  1997/10/17 22:13:29  keil * update to last hisax version * * Revision 2.1  1997/07/27 21:47:13  keil * new interface structures * * Revision 2.0  1997/06/26 11:02:48  keil * New Layer and card interface * * Revision 1.6  1997/04/13 19:54:07  keil * Change in IRQ check delay for SMP * * Revision 1.5  1997/04/06 22:54:10  keil * Using SKB's * * Revision 1.4  1997/01/27 15:50:21  keil * SMP proof,cosmetics * * Revision 1.3  1997/01/21 22:14:20  keil * cleanups * * Revision 1.2  1996/10/27 22:07:31  keil * cosmetic changes * * Revision 1.1  1996/10/13 20:04:49  keil * Initial revision * * */#define __NO_VERSION__#include "hisax.h"#include "isac.h"#include "hscx.h"#include "isdnl1.h"extern const char *CardType[];static const char *avm_revision = "$Revision: 1.1.1.1 $";#define	 AVM_A1_STAT_ISAC	0x01#define	 AVM_A1_STAT_HSCX	0x02#define	 AVM_A1_STAT_TIMER	0x04#define byteout(addr,val) outb(val,addr)#define bytein(addr) inb(addr)static inline u_charreadreg(unsigned int adr, u_char off){	return (bytein(adr + off));}static inline voidwritereg(unsigned int adr, u_char off, u_char data){	byteout(adr + off, data);}static inline voidread_fifo(unsigned int adr, u_char * data, int size){	insb(adr, data, size);}static voidwrite_fifo(unsigned int adr, u_char * data, int size){	outsb(adr, data, size);}/* Interface functions */static u_charReadISAC(struct IsdnCardState *cs, u_char offset){	return (readreg(cs->hw.avm.isac, offset));}static voidWriteISAC(struct IsdnCardState *cs, u_char offset, u_char value){	writereg(cs->hw.avm.isac, offset, value);}static voidReadISACfifo(struct IsdnCardState *cs, u_char * data, int size){	read_fifo(cs->hw.avm.isacfifo, data, size);}static voidWriteISACfifo(struct IsdnCardState *cs, u_char * data, int size){	write_fifo(cs->hw.avm.isacfifo, data, size);}static u_charReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset){	return (readreg(cs->hw.avm.hscx[hscx], offset));}static voidWriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value){	writereg(cs->hw.avm.hscx[hscx], offset, value);}/* * fast interrupt HSCX stuff goes here */#define READHSCX(cs, nr, reg) readreg(cs->hw.avm.hscx[nr], reg)#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.avm.hscx[nr], reg, data)#define READHSCXFIFO(cs, nr, ptr, cnt) read_fifo(cs->hw.avm.hscxfifo[nr], ptr, cnt)#define WRITEHSCXFIFO(cs, nr, ptr, cnt) write_fifo(cs->hw.avm.hscxfifo[nr], ptr, cnt)#include "hscx_irq.c"static voidavm_a1_interrupt(int intno, void *dev_id, struct pt_regs *regs){	struct IsdnCardState *cs = dev_id;	u_char val, sval, stat = 0;	if (!cs) {		printk(KERN_WARNING "AVM A1: Spurious interrupt!\n");		return;	}	while (((sval = bytein(cs->hw.avm.cfg_reg)) & 0xf) != 0x7) {		if (!(sval & AVM_A1_STAT_TIMER)) {			byteout(cs->hw.avm.cfg_reg, 0x1E);			sval = bytein(cs->hw.avm.cfg_reg);		} else if (cs->debug & L1_DEB_INTSTAT)			debugl1(cs, "avm IntStatus %x", sval);		if (!(sval & AVM_A1_STAT_HSCX)) {			val = readreg(cs->hw.avm.hscx[1], HSCX_ISTA);			if (val) {				hscx_int_main(cs, val);				stat |= 1;			}		}		if (!(sval & AVM_A1_STAT_ISAC)) {			val = readreg(cs->hw.avm.isac, ISAC_ISTA);			if (val) {				isac_interrupt(cs, val);				stat |= 2;			}		}	}	if (stat & 1) {		writereg(cs->hw.avm.hscx[0], HSCX_MASK, 0xFF);		writereg(cs->hw.avm.hscx[1], HSCX_MASK, 0xFF);		writereg(cs->hw.avm.hscx[0], HSCX_MASK, 0x0);		writereg(cs->hw.avm.hscx[1], HSCX_MASK, 0x0);	}	if (stat & 2) {		writereg(cs->hw.avm.isac, ISAC_MASK, 0xFF);		writereg(cs->hw.avm.isac, ISAC_MASK, 0x0);	}}inline static voidrelease_ioregs(struct IsdnCardState *cs, int mask){	release_region(cs->hw.avm.cfg_reg, 8);	if (mask & 1)		release_region(cs->hw.avm.isac + 32, 32);	if (mask & 2)		release_region(cs->hw.avm.isacfifo, 1);	if (mask & 4)		release_region(cs->hw.avm.hscx[0] + 32, 32);	if (mask & 8)		release_region(cs->hw.avm.hscxfifo[0], 1);	if (mask & 0x10)		release_region(cs->hw.avm.hscx[1] + 32, 32);	if (mask & 0x20)		release_region(cs->hw.avm.hscxfifo[1], 1);}static intAVM_card_msg(struct IsdnCardState *cs, int mt, void *arg){	switch (mt) {		case CARD_RESET:			return(0);		case CARD_RELEASE:			release_ioregs(cs, 0x3f);			return(0);		case CARD_SETIRQ:			return(request_irq(cs->irq, &avm_a1_interrupt,					I4L_IRQ_FLAG, "HiSax", cs));		case CARD_INIT:			inithscxisac(cs, 1);			byteout(cs->hw.avm.cfg_reg, 0x16);			byteout(cs->hw.avm.cfg_reg, 0x1E);			inithscxisac(cs, 2);			return(0);		case CARD_TEST:			return(0);	}	return(0);}__initfunc(intsetup_avm_a1(struct IsdnCard *card)){	u_char val;	struct IsdnCardState *cs = card->cs;	long flags;	char tmp[64];	strcpy(tmp, avm_revision);	printk(KERN_INFO "HiSax: AVM driver Rev. %s\n", HiSax_getrev(tmp));	if (cs->typ != ISDN_CTYPE_A1)		return (0);	cs->hw.avm.cfg_reg = card->para[1] + 0x1800;	cs->hw.avm.isac = card->para[1] + 0x1400 - 0x20;	cs->hw.avm.hscx[0] = card->para[1] + 0x400 - 0x20;	cs->hw.avm.hscx[1] = card->para[1] + 0xc00 - 0x20;	cs->hw.avm.isacfifo = card->para[1] + 0x1000;	cs->hw.avm.hscxfifo[0] = card->para[1];	cs->hw.avm.hscxfifo[1] = card->para[1] + 0x800;	cs->irq = card->para[0];	if (check_region((cs->hw.avm.cfg_reg), 8)) {		printk(KERN_WARNING		       "HiSax: %s config port %x-%x already in use\n",		       CardType[card->typ],		       cs->hw.avm.cfg_reg,		       cs->hw.avm.cfg_reg + 8);		return (0);	} else {		request_region(cs->hw.avm.cfg_reg, 8, "avm cfg");	}	if (check_region((cs->hw.avm.isac + 32), 32)) {		printk(KERN_WARNING		       "HiSax: %s isac ports %x-%x already in use\n",		       CardType[cs->typ],		       cs->hw.avm.isac + 32,		       cs->hw.avm.isac + 64);		release_ioregs(cs, 0);		return (0);	} else {		request_region(cs->hw.avm.isac + 32, 32, "HiSax isac");	}	if (check_region((cs->hw.avm.isacfifo), 1)) {		printk(KERN_WARNING		       "HiSax: %s isac fifo port %x already in use\n",		       CardType[cs->typ],		       cs->hw.avm.isacfifo);		release_ioregs(cs, 1);		return (0);	} else {		request_region(cs->hw.avm.isacfifo, 1, "HiSax isac fifo");	}	if (check_region((cs->hw.avm.hscx[0]) + 32, 32)) {		printk(KERN_WARNING		       "HiSax: %s hscx A ports %x-%x already in use\n",		       CardType[cs->typ],		       cs->hw.avm.hscx[0] + 32,		       cs->hw.avm.hscx[0] + 64);		release_ioregs(cs, 3);		return (0);	} else {		request_region(cs->hw.avm.hscx[0] + 32, 32, "HiSax hscx A");	}	if (check_region(cs->hw.avm.hscxfifo[0], 1)) {		printk(KERN_WARNING		       "HiSax: %s hscx A fifo port %x already in use\n",		       CardType[cs->typ],		       cs->hw.avm.hscxfifo[0]);		release_ioregs(cs, 7);		return (0);	} else {		request_region(cs->hw.avm.hscxfifo[0], 1, "HiSax hscx A fifo");	}	if (check_region(cs->hw.avm.hscx[1] + 32, 32)) {		printk(KERN_WARNING		       "HiSax: %s hscx B ports %x-%x already in use\n",		       CardType[cs->typ],		       cs->hw.avm.hscx[1] + 32,		       cs->hw.avm.hscx[1] + 64);		release_ioregs(cs, 0xf);		return (0);	} else {		request_region(cs->hw.avm.hscx[1] + 32, 32, "HiSax hscx B");	}	if (check_region(cs->hw.avm.hscxfifo[1], 1)) {		printk(KERN_WARNING		       "HiSax: %s hscx B fifo port %x already in use\n",		       CardType[cs->typ],		       cs->hw.avm.hscxfifo[1]);		release_ioregs(cs, 0x1f);		return (0);	} else {		request_region(cs->hw.avm.hscxfifo[1], 1, "HiSax hscx B fifo");	}	save_flags(flags);	byteout(cs->hw.avm.cfg_reg, 0x0);	sti();	HZDELAY(HZ / 5 + 1);	byteout(cs->hw.avm.cfg_reg, 0x1);	HZDELAY(HZ / 5 + 1);	byteout(cs->hw.avm.cfg_reg, 0x0);	HZDELAY(HZ / 5 + 1);	val = cs->irq;	if (val == 9)		val = 2;	byteout(cs->hw.avm.cfg_reg + 1, val);	HZDELAY(HZ / 5 + 1);	byteout(cs->hw.avm.cfg_reg, 0x0);	HZDELAY(HZ / 5 + 1);	restore_flags(flags);	val = bytein(cs->hw.avm.cfg_reg);	printk(KERN_INFO "AVM A1: Byte at %x is %x\n",	       cs->hw.avm.cfg_reg, val);	val = bytein(cs->hw.avm.cfg_reg + 3);	printk(KERN_INFO "AVM A1: Byte at %x is %x\n",	       cs->hw.avm.cfg_reg + 3, val);	val = bytein(cs->hw.avm.cfg_reg + 2);	printk(KERN_INFO "AVM A1: Byte at %x is %x\n",	       cs->hw.avm.cfg_reg + 2, val);	val = bytein(cs->hw.avm.cfg_reg);	printk(KERN_INFO "AVM A1: Byte at %x is %x\n",	       cs->hw.avm.cfg_reg, val);	printk(KERN_INFO	       "HiSax: %s config irq:%d cfg:0x%X\n",	       CardType[cs->typ], cs->irq,	       cs->hw.avm.cfg_reg);	printk(KERN_INFO	       "HiSax: isac:0x%X/0x%X\n",	       cs->hw.avm.isac + 32, cs->hw.avm.isacfifo);	printk(KERN_INFO	       "HiSax: hscx A:0x%X/0x%X  hscx B:0x%X/0x%X\n",	       cs->hw.avm.hscx[0] + 32, cs->hw.avm.hscxfifo[0],	       cs->hw.avm.hscx[1] + 32, cs->hw.avm.hscxfifo[1]);	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 = &AVM_card_msg;	ISACVersion(cs, "AVM A1:");	if (HscxVersion(cs, "AVM A1:")) {		printk(KERN_WARNING		       "AVM A1: wrong HSCX versions check IO address\n");		release_ioregs(cs, 0x3f);		return (0);	}	return (1);}

⌨️ 快捷键说明

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