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

📄 gazel.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $Id: gazel.c,v 2.19.2.4 2004/01/14 16:04:48 keil Exp $ * * low level stuff for Gazel isdn cards * * Author       BeWan Systems *              based on source code from Karsten Keil * Copyright    by BeWan Systems *  * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. * */#include <linux/config.h>#include <linux/init.h>#include "hisax.h"#include "isac.h"#include "hscx.h"#include "isdnl1.h"#include "ipac.h"#include <linux/pci.h>extern const char *CardType[];static const char *gazel_revision = "$Revision: 2.19.2.4 $";#define R647      1#define R685      2#define R753      3#define R742      4#define PLX_CNTRL    0x50	/* registre de controle PLX */#define RESET_GAZEL  0x4#define RESET_9050   0x40000000#define PLX_INCSR    0x4C	/* registre d'IT du 9050 */#define INT_ISAC_EN  0x8	/* 1 = enable IT isac */#define INT_ISAC     0x20	/* 1 = IT isac en cours */#define INT_HSCX_EN  0x1	/* 1 = enable IT hscx */#define INT_HSCX     0x4	/* 1 = IT hscx en cours */#define INT_PCI_EN   0x40	/* 1 = enable IT PCI */#define INT_IPAC_EN  0x3	/* enable IT ipac */#define byteout(addr,val) outb(val,addr)#define bytein(addr) inb(addr)static inline u_charreadreg(unsigned int adr, u_short off){	return bytein(adr + off);}static inline voidwritereg(unsigned int adr, u_short 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);}static inline u_charreadreg_ipac(unsigned int adr, u_short off){	register u_char ret;	byteout(adr, off);	ret = bytein(adr + 4);	return ret;}static inline voidwritereg_ipac(unsigned int adr, u_short off, u_char data){	byteout(adr, off);	byteout(adr + 4, data);}static inline voidread_fifo_ipac(unsigned int adr, u_short off, u_char * data, int size){	byteout(adr, off);	insb(adr + 4, data, size);}static voidwrite_fifo_ipac(unsigned int adr, u_short off, u_char * data, int size){	byteout(adr, off);	outsb(adr + 4, data, size);}/* Interface functions */static u_charReadISAC(struct IsdnCardState *cs, u_char offset){	u_short off2 = offset;	switch (cs->subtyp) {		case R647:			off2 = ((off2 << 8 & 0xf000) | (off2 & 0xf));		case R685:			return (readreg(cs->hw.gazel.isac, off2));		case R753:		case R742:			return (readreg_ipac(cs->hw.gazel.ipac, 0x80 + off2));	}	return 0;}static voidWriteISAC(struct IsdnCardState *cs, u_char offset, u_char value){	u_short off2 = offset;	switch (cs->subtyp) {		case R647:			off2 = ((off2 << 8 & 0xf000) | (off2 & 0xf));		case R685:			writereg(cs->hw.gazel.isac, off2, value);			break;		case R753:		case R742:			writereg_ipac(cs->hw.gazel.ipac, 0x80 + off2, value);			break;	}}static voidReadISACfifo(struct IsdnCardState *cs, u_char * data, int size){	switch (cs->subtyp) {		case R647:		case R685:			read_fifo(cs->hw.gazel.isacfifo, data, size);			break;		case R753:		case R742:			read_fifo_ipac(cs->hw.gazel.ipac, 0x80, data, size);			break;	}}static voidWriteISACfifo(struct IsdnCardState *cs, u_char * data, int size){	switch (cs->subtyp) {		case R647:		case R685:			write_fifo(cs->hw.gazel.isacfifo, data, size);			break;		case R753:		case R742:			write_fifo_ipac(cs->hw.gazel.ipac, 0x80, data, size);			break;	}}static voidReadHSCXfifo(struct IsdnCardState *cs, int hscx, u_char * data, int size){	switch (cs->subtyp) {		case R647:		case R685:			read_fifo(cs->hw.gazel.hscxfifo[hscx], data, size);			break;		case R753:		case R742:			read_fifo_ipac(cs->hw.gazel.ipac, hscx * 0x40, data, size);			break;	}}static voidWriteHSCXfifo(struct IsdnCardState *cs, int hscx, u_char * data, int size){	switch (cs->subtyp) {		case R647:		case R685:			write_fifo(cs->hw.gazel.hscxfifo[hscx], data, size);			break;		case R753:		case R742:			write_fifo_ipac(cs->hw.gazel.ipac, hscx * 0x40, data, size);			break;	}}static u_charReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset){	u_short off2 = offset;	switch (cs->subtyp) {		case R647:			off2 = ((off2 << 8 & 0xf000) | (off2 & 0xf));		case R685:			return (readreg(cs->hw.gazel.hscx[hscx], off2));		case R753:		case R742:			return (readreg_ipac(cs->hw.gazel.ipac, hscx * 0x40 + off2));	}	return 0;}static voidWriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value){	u_short off2 = offset;	switch (cs->subtyp) {		case R647:			off2 = ((off2 << 8 & 0xf000) | (off2 & 0xf));		case R685:			writereg(cs->hw.gazel.hscx[hscx], off2, value);			break;		case R753:		case R742:			writereg_ipac(cs->hw.gazel.ipac, hscx * 0x40 + off2, value);			break;	}}/* * fast interrupt HSCX stuff goes here */#define READHSCX(cs, nr, reg) ReadHSCX(cs, nr, reg)#define WRITEHSCX(cs, nr, reg, data) WriteHSCX(cs, nr, reg, data)#define READHSCXFIFO(cs, nr, ptr, cnt) ReadHSCXfifo(cs, nr, ptr, cnt)#define WRITEHSCXFIFO(cs, nr, ptr, cnt) WriteHSCXfifo(cs, nr, ptr, cnt)#include "hscx_irq.c"static irqreturn_tgazel_interrupt(int intno, void *dev_id, struct pt_regs *regs){#define MAXCOUNT 5	struct IsdnCardState *cs = dev_id;	u_char valisac, valhscx;	int count = 0;	u_long flags;	spin_lock_irqsave(&cs->lock, flags);	do {		valhscx = ReadHSCX(cs, 1, HSCX_ISTA);		if (valhscx)			hscx_int_main(cs, valhscx);		valisac = ReadISAC(cs, ISAC_ISTA);		if (valisac)			isac_interrupt(cs, valisac);		count++;	} while ((valhscx || valisac) && (count < MAXCOUNT));	WriteHSCX(cs, 0, HSCX_MASK, 0xFF);	WriteHSCX(cs, 1, HSCX_MASK, 0xFF);	WriteISAC(cs, ISAC_MASK, 0xFF);	WriteISAC(cs, ISAC_MASK, 0x0);	WriteHSCX(cs, 0, HSCX_MASK, 0x0);	WriteHSCX(cs, 1, HSCX_MASK, 0x0);	spin_unlock_irqrestore(&cs->lock, flags);	return IRQ_HANDLED;}static irqreturn_tgazel_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs){	struct IsdnCardState *cs = dev_id;	u_char ista, val;	int count = 0;	u_long flags;		spin_lock_irqsave(&cs->lock, flags);	ista = ReadISAC(cs, IPAC_ISTA - 0x80);	do {		if (ista & 0x0f) {			val = ReadHSCX(cs, 1, HSCX_ISTA);			if (ista & 0x01)				val |= 0x01;			if (ista & 0x04)				val |= 0x02;			if (ista & 0x08)				val |= 0x04;			if (val) {				hscx_int_main(cs, val);			}		}		if (ista & 0x20) {			val = 0xfe & ReadISAC(cs, ISAC_ISTA);			if (val) {				isac_interrupt(cs, val);			}		}		if (ista & 0x10) {			val = 0x01;			isac_interrupt(cs, val);		}		ista = ReadISAC(cs, IPAC_ISTA - 0x80);		count++;	}	while ((ista & 0x3f) && (count < MAXCOUNT));	WriteISAC(cs, IPAC_MASK - 0x80, 0xFF);	WriteISAC(cs, IPAC_MASK - 0x80, 0xC0);	spin_unlock_irqrestore(&cs->lock, flags);	return IRQ_HANDLED;}static voidrelease_io_gazel(struct IsdnCardState *cs){	unsigned int i;	switch (cs->subtyp) {		case R647:			for (i = 0x0000; i < 0xC000; i += 0x1000)				release_region(i + cs->hw.gazel.hscx[0], 16);			release_region(0xC000 + cs->hw.gazel.hscx[0], 1);			break;		case R685:			release_region(cs->hw.gazel.hscx[0], 0x100);			release_region(cs->hw.gazel.cfg_reg, 0x80);			break;		case R753:			release_region(cs->hw.gazel.ipac, 0x8);			release_region(cs->hw.gazel.cfg_reg, 0x80);			break;		case R742:			release_region(cs->hw.gazel.ipac, 8);			break;	}

⌨️ 快捷键说明

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