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

📄 t1isa.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $Id: t1isa.c,v 1.1.2.3 2004/02/10 01:07:12 keil Exp $ *  * Module for AVM T1 HEMA-card. *  * Copyright 1999 by Carsten Paeth <calle@calle.de> *  * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. * */#include <linux/module.h>#include <linux/kernel.h>#include <linux/skbuff.h>#include <linux/delay.h>#include <linux/mm.h>#include <linux/interrupt.h>#include <linux/ioport.h>#include <linux/capi.h>#include <linux/netdevice.h>#include <linux/kernelcapi.h>#include <linux/init.h>#include <linux/pci.h>#include <asm/io.h>#include <linux/isdn/capicmd.h>#include <linux/isdn/capiutil.h>#include <linux/isdn/capilli.h>#include "avmcard.h"/* ------------------------------------------------------------- */static char *revision = "$Revision: 1.1.2.3 $";/* ------------------------------------------------------------- */MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM T1 HEMA ISA card");MODULE_AUTHOR("Carsten Paeth");MODULE_LICENSE("GPL");/* ------------------------------------------------------------- */static int hema_irq_table[16] ={0, 0, 0, 0x80,				/* irq 3 */ 0, 0x90,				/* irq 5 */ 0, 0xA0,				/* irq 7 */ 0, 0xB0,				/* irq 9 */ 0xC0,				/* irq 10 */ 0xD0,				/* irq 11 */ 0xE0,				/* irq 12 */ 0, 0, 0xF0,				/* irq 15 */};static int t1_detectandinit(unsigned int base, unsigned irq, int cardnr){	unsigned char cregs[8];	unsigned char reverse_cardnr;	unsigned char dummy;	int i;	reverse_cardnr =   ((cardnr & 0x01) << 3) | ((cardnr & 0x02) << 1)		         | ((cardnr & 0x04) >> 1) | ((cardnr & 0x08) >> 3);	cregs[0] = (HEMA_VERSION_ID << 4) | (reverse_cardnr & 0xf);	cregs[1] = 0x00; /* fast & slow link connected to CON1 */	cregs[2] = 0x05; /* fast link 20MBit, slow link 20 MBit */	cregs[3] = 0;	cregs[4] = 0x11; /* zero wait state */	cregs[5] = hema_irq_table[irq & 0xf];	cregs[6] = 0;	cregs[7] = 0;	/*	 * no one else should use the ISA bus in this moment,	 * but no function there to prevent this :-(	 * save_flags(flags); cli();	 */	/* board reset */	t1outp(base, T1_RESETBOARD, 0xf);	mdelay(100);	dummy = t1inp(base, T1_FASTLINK+T1_OUTSTAT); /* first read */	/* write config */	dummy = (base >> 4) & 0xff;	for (i=1;i<=0xf;i++) t1outp(base, i, dummy);	t1outp(base, HEMA_PAL_ID & 0xf, dummy);	t1outp(base, HEMA_PAL_ID >> 4, cregs[0]);	for(i=1;i<7;i++) t1outp(base, 0, cregs[i]);	t1outp(base, ((base >> 4)) & 0x3, cregs[7]);	/* restore_flags(flags); */	mdelay(100);	t1outp(base, T1_FASTLINK+T1_RESETLINK, 0);	t1outp(base, T1_SLOWLINK+T1_RESETLINK, 0);	mdelay(10);	t1outp(base, T1_FASTLINK+T1_RESETLINK, 1);	t1outp(base, T1_SLOWLINK+T1_RESETLINK, 1);	mdelay(100);	t1outp(base, T1_FASTLINK+T1_RESETLINK, 0);	t1outp(base, T1_SLOWLINK+T1_RESETLINK, 0);	mdelay(10);	t1outp(base, T1_FASTLINK+T1_ANALYSE, 0);	mdelay(5);	t1outp(base, T1_SLOWLINK+T1_ANALYSE, 0);	if (t1inp(base, T1_FASTLINK+T1_OUTSTAT) != 0x1) /* tx empty */		return 1;	if (t1inp(base, T1_FASTLINK+T1_INSTAT) != 0x0) /* rx empty */		return 2;	if (t1inp(base, T1_FASTLINK+T1_IRQENABLE) != 0x0)		return 3;	if ((t1inp(base, T1_FASTLINK+T1_FIFOSTAT) & 0xf0) != 0x70)		return 4;	if ((t1inp(base, T1_FASTLINK+T1_IRQMASTER) & 0x0e) != 0)		return 5;	if ((t1inp(base, T1_FASTLINK+T1_IDENT) & 0x7d) != 1)		return 6;	if (t1inp(base, T1_SLOWLINK+T1_OUTSTAT) != 0x1) /* tx empty */		return 7;	if ((t1inp(base, T1_SLOWLINK+T1_IRQMASTER) & 0x0e) != 0)		return 8;	if ((t1inp(base, T1_SLOWLINK+T1_IDENT) & 0x7d) != 0)		return 9;        return 0;}static irqreturn_t t1isa_interrupt(int interrupt, void *devptr, struct pt_regs *regs){	avmcard *card = devptr;	avmctrl_info *cinfo = &card->ctrlinfo[0];	struct capi_ctr *ctrl = &cinfo->capi_ctrl;	unsigned char b1cmd;	struct sk_buff *skb;	unsigned ApplId;	unsigned MsgLen;	unsigned DataB3Len;	unsigned NCCI;	unsigned WindowSize;	unsigned long flags;	spin_lock_irqsave(&card->lock, flags);	while (b1_rx_full(card->port)) {		b1cmd = b1_get_byte(card->port);		switch (b1cmd) {		case RECEIVE_DATA_B3_IND:			ApplId = (unsigned) b1_get_word(card->port);			MsgLen = t1_get_slice(card->port, card->msgbuf);			DataB3Len = t1_get_slice(card->port, card->databuf);			spin_unlock_irqrestore(&card->lock, flags);			if (MsgLen < 30) { /* not CAPI 64Bit */				memset(card->msgbuf+MsgLen, 0, 30-MsgLen);				MsgLen = 30;				CAPIMSG_SETLEN(card->msgbuf, 30);			}			if (!(skb = alloc_skb(DataB3Len+MsgLen, GFP_ATOMIC))) {				printk(KERN_ERR "%s: incoming packet dropped\n",					card->name);			} else {				memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);				memcpy(skb_put(skb, DataB3Len), card->databuf, DataB3Len);				capi_ctr_handle_message(ctrl, ApplId, skb);			}			break;		case RECEIVE_MESSAGE:			ApplId = (unsigned) b1_get_word(card->port);			MsgLen = t1_get_slice(card->port, card->msgbuf);			spin_unlock_irqrestore(&card->lock, flags);			if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) {				printk(KERN_ERR "%s: incoming packet dropped\n",						card->name);			} else {				memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);				if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3)					capilib_data_b3_conf(&cinfo->ncci_head, ApplId,							     CAPIMSG_NCCI(skb->data),							     CAPIMSG_MSGID(skb->data));				capi_ctr_handle_message(ctrl, ApplId, skb);			}			break;		case RECEIVE_NEW_NCCI:			ApplId = b1_get_word(card->port);			NCCI = b1_get_word(card->port);			WindowSize = b1_get_word(card->port);			spin_unlock_irqrestore(&card->lock, flags);			capilib_new_ncci(&cinfo->ncci_head, ApplId, NCCI, WindowSize);			break;		case RECEIVE_FREE_NCCI:			ApplId = b1_get_word(card->port);			NCCI = b1_get_word(card->port);			spin_unlock_irqrestore(&card->lock, flags);			if (NCCI != 0xffffffff)				capilib_free_ncci(&cinfo->ncci_head, ApplId, NCCI);			break;		case RECEIVE_START:			b1_put_byte(card->port, SEND_POLLACK);			spin_unlock_irqrestore(&card->lock, flags);			capi_ctr_resume_output(ctrl);			break;		case RECEIVE_STOP:			spin_unlock_irqrestore(&card->lock, flags);			capi_ctr_suspend_output(ctrl);			break;		case RECEIVE_INIT:			cinfo->versionlen = t1_get_slice(card->port, cinfo->versionbuf);			spin_unlock_irqrestore(&card->lock, flags);			b1_parse_version(cinfo);			printk(KERN_INFO "%s: %s-card (%s) now active\n",			       card->name,			       cinfo->version[VER_CARDTYPE],			       cinfo->version[VER_DRIVER]);			capi_ctr_ready(ctrl);			break;		case RECEIVE_TASK_READY:			ApplId = (unsigned) b1_get_word(card->port);			MsgLen = t1_get_slice(card->port, card->msgbuf);			spin_unlock_irqrestore(&card->lock, flags);			card->msgbuf[MsgLen] = 0;			while (    MsgLen > 0			       && (   card->msgbuf[MsgLen-1] == '\n'				   || card->msgbuf[MsgLen-1] == '\r')) {				card->msgbuf[MsgLen-1] = 0;				MsgLen--;			}			printk(KERN_INFO "%s: task %d \"%s\" ready.\n",					card->name, ApplId, card->msgbuf);			break;		case RECEIVE_DEBUGMSG:			MsgLen = t1_get_slice(card->port, card->msgbuf);			spin_unlock_irqrestore(&card->lock, flags);			card->msgbuf[MsgLen] = 0;			while (    MsgLen > 0			       && (   card->msgbuf[MsgLen-1] == '\n'				   || card->msgbuf[MsgLen-1] == '\r')) {				card->msgbuf[MsgLen-1] = 0;				MsgLen--;			}			printk(KERN_INFO "%s: DEBUG: %s\n", card->name, card->msgbuf);			break;		case 0xff:			spin_unlock_irqrestore(&card->lock, flags);			printk(KERN_ERR "%s: card reseted ?\n", card->name);			return IRQ_HANDLED;		default:			spin_unlock_irqrestore(&card->lock, flags);			printk(KERN_ERR "%s: b1_interrupt: 0x%x ???\n",					card->name, b1cmd);			return IRQ_NONE;		}	}	return IRQ_HANDLED;}/* ------------------------------------------------------------- */static int t1isa_load_firmware(struct capi_ctr *ctrl, capiloaddata *data){	avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);	avmcard *card = cinfo->card;	unsigned int port = card->port;	unsigned long flags;	int retval;	t1_disable_irq(port);	b1_reset(port);	if ((retval = b1_load_t4file(card, &data->firmware))) {

⌨️ 快捷键说明

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