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

📄 sportster.c

📁 linux-2.6.15.6
💻 C
字号:
/* $Id: sportster.c,v 1.16.2.4 2004/01/13 23:48:39 keil Exp $ * * low level stuff for USR Sportster internal TA * * Author       Karsten Keil * Copyright    by Karsten Keil      <keil@isdn4linux.de> *  * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. * * Thanks to Christian "naddy" Weisgerber (3Com, US Robotics) for documentation * * */#include <linux/init.h>#include "hisax.h"#include "isac.h"#include "hscx.h"#include "isdnl1.h"extern const char *CardType[];static const char *sportster_revision = "$Revision: 1.16.2.4 $";#define byteout(addr,val) outb(val,addr)#define bytein(addr) inb(addr)#define	 SPORTSTER_ISAC		0xC000#define	 SPORTSTER_HSCXA	0x0000#define	 SPORTSTER_HSCXB	0x4000#define	 SPORTSTER_RES_IRQ	0x8000#define	 SPORTSTER_RESET	0x80#define	 SPORTSTER_INTE		0x40static inline intcalc_off(unsigned int base, unsigned int off){	return(base + ((off & 0xfc)<<8) + ((off & 3)<<1));}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 (bytein(calc_off(cs->hw.spt.isac, offset)));}static voidWriteISAC(struct IsdnCardState *cs, u_char offset, u_char value){	byteout(calc_off(cs->hw.spt.isac, offset), value);}static voidReadISACfifo(struct IsdnCardState *cs, u_char * data, int size){	read_fifo(cs->hw.spt.isac, data, size);}static voidWriteISACfifo(struct IsdnCardState *cs, u_char * data, int size){	write_fifo(cs->hw.spt.isac, data, size);}static u_charReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset){	return (bytein(calc_off(cs->hw.spt.hscx[hscx], offset)));}static voidWriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value){	byteout(calc_off(cs->hw.spt.hscx[hscx], offset), value);}/* * fast interrupt HSCX stuff goes here */#define READHSCX(cs, nr, reg) bytein(calc_off(cs->hw.spt.hscx[nr], reg))#define WRITEHSCX(cs, nr, reg, data) byteout(calc_off(cs->hw.spt.hscx[nr], reg), data)#define READHSCXFIFO(cs, nr, ptr, cnt) read_fifo(cs->hw.spt.hscx[nr], ptr, cnt)#define WRITEHSCXFIFO(cs, nr, ptr, cnt) write_fifo(cs->hw.spt.hscx[nr], ptr, cnt)#include "hscx_irq.c"static irqreturn_tsportster_interrupt(int intno, void *dev_id, struct pt_regs *regs){	struct IsdnCardState *cs = dev_id;	u_char val;	u_long flags;	spin_lock_irqsave(&cs->lock, flags);	val = READHSCX(cs, 1, HSCX_ISTA);      Start_HSCX:	if (val)		hscx_int_main(cs, val);	val = ReadISAC(cs, ISAC_ISTA);      Start_ISAC:	if (val)		isac_interrupt(cs, val);	val = READHSCX(cs, 1, HSCX_ISTA);	if (val) {		if (cs->debug & L1_DEB_HSCX)			debugl1(cs, "HSCX IntStat after IntRoutine");		goto Start_HSCX;	}	val = ReadISAC(cs, ISAC_ISTA);	if (val) {		if (cs->debug & L1_DEB_ISAC)			debugl1(cs, "ISAC IntStat after IntRoutine");		goto Start_ISAC;	}	/* get a new irq impulse if there any pending */	bytein(cs->hw.spt.cfg_reg + SPORTSTER_RES_IRQ +1);	spin_unlock_irqrestore(&cs->lock, flags);	return IRQ_HANDLED;}static voidrelease_io_sportster(struct IsdnCardState *cs){	int i, adr;	byteout(cs->hw.spt.cfg_reg + SPORTSTER_RES_IRQ, 0);	for (i=0; i<64; i++) {		adr = cs->hw.spt.cfg_reg + i *1024;		release_region(adr, 8);	}}static voidreset_sportster(struct IsdnCardState *cs){	cs->hw.spt.res_irq |= SPORTSTER_RESET; /* Reset On */	byteout(cs->hw.spt.cfg_reg + SPORTSTER_RES_IRQ, cs->hw.spt.res_irq);	mdelay(10);	cs->hw.spt.res_irq &= ~SPORTSTER_RESET; /* Reset Off */	byteout(cs->hw.spt.cfg_reg + SPORTSTER_RES_IRQ, cs->hw.spt.res_irq);	mdelay(10);}static intSportster_card_msg(struct IsdnCardState *cs, int mt, void *arg){	u_long flags;	switch (mt) {		case CARD_RESET:			spin_lock_irqsave(&cs->lock, flags);			reset_sportster(cs);			spin_unlock_irqrestore(&cs->lock, flags);			return(0);		case CARD_RELEASE:			release_io_sportster(cs);			return(0);		case CARD_INIT:			spin_lock_irqsave(&cs->lock, flags);			reset_sportster(cs);			inithscxisac(cs, 1);			cs->hw.spt.res_irq |= SPORTSTER_INTE; /* IRQ On */			byteout(cs->hw.spt.cfg_reg + SPORTSTER_RES_IRQ, cs->hw.spt.res_irq);			inithscxisac(cs, 2);			spin_unlock_irqrestore(&cs->lock, flags);			return(0);		case CARD_TEST:			return(0);	}	return(0);}static int __initget_io_range(struct IsdnCardState *cs){	int i, j, adr;		for (i=0;i<64;i++) {		adr = cs->hw.spt.cfg_reg + i *1024;		if (!request_region(adr, 8, "sportster")) {			printk(KERN_WARNING				"HiSax: %s config port %x-%x already in use\n",				CardType[cs->typ], adr, adr + 8);			break;		} 	}	if (i==64)		return(1);	else {		for (j=0; j<i; j++) {			adr = cs->hw.spt.cfg_reg + j *1024;			release_region(adr, 8);		}		return(0);	}}int __initsetup_sportster(struct IsdnCard *card){	struct IsdnCardState *cs = card->cs;	char tmp[64];	strcpy(tmp, sportster_revision);	printk(KERN_INFO "HiSax: USR Sportster driver Rev. %s\n", HiSax_getrev(tmp));	if (cs->typ != ISDN_CTYPE_SPORTSTER)		return (0);	cs->hw.spt.cfg_reg = card->para[1];	cs->irq = card->para[0];	if (!get_io_range(cs))		return (0);	cs->hw.spt.isac = cs->hw.spt.cfg_reg + SPORTSTER_ISAC;	cs->hw.spt.hscx[0] = cs->hw.spt.cfg_reg + SPORTSTER_HSCXA;	cs->hw.spt.hscx[1] = cs->hw.spt.cfg_reg + SPORTSTER_HSCXB;		switch(cs->irq) {		case 5:	cs->hw.spt.res_irq = 1;			break;		case 7:	cs->hw.spt.res_irq = 2;			break;		case 10:cs->hw.spt.res_irq = 3;			break;		case 11:cs->hw.spt.res_irq = 4;			break;		case 12:cs->hw.spt.res_irq = 5;			break;		case 14:cs->hw.spt.res_irq = 6;			break;		case 15:cs->hw.spt.res_irq = 7;			break;		default:release_io_sportster(cs);			printk(KERN_WARNING "Sportster: wrong IRQ\n");			return(0);	}	printk(KERN_INFO "HiSax: %s config irq:%d cfg:0x%X\n",		CardType[cs->typ], cs->irq, cs->hw.spt.cfg_reg);	setup_isac(cs);	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 = &Sportster_card_msg;	cs->irq_func = &sportster_interrupt;	ISACVersion(cs, "Sportster:");	if (HscxVersion(cs, "Sportster:")) {		printk(KERN_WARNING		       "Sportster: wrong HSCX versions check IO address\n");		release_io_sportster(cs);		return (0);	}	return (1);}

⌨️ 快捷键说明

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