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

📄 eicon_mod.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 3 页
字号:
			eicon_log(card, 1, "eicon CMD_GETSIL not implemented\n");			return 0;		case ISDN_CMD_LOCK:			MOD_INC_USE_COUNT;			return 0;		case ISDN_CMD_UNLOCK:			MOD_DEC_USE_COUNT;			return 0;#ifdef CONFIG_ISDN_TTY_FAX		case ISDN_CMD_FAXCMD:			if (!card->flags & EICON_FLAGS_RUNNING)				return -ENODEV;			if (!(chan = find_channel(card, c->arg & 0x1f)))				break;			if (!chan->fax)				break;			idi_fax_cmd(card, chan);			return 0;#endif		case ISDN_CMD_AUDIO:			if (!card->flags & EICON_FLAGS_RUNNING)				return -ENODEV;			if (!(chan = find_channel(card, c->arg & 0x1f)))				break;			idi_audio_cmd(card, chan, c->arg >> 8, c->parm.num);			return 0;		case CAPI_PUT_MESSAGE:			if (!card->flags & EICON_FLAGS_RUNNING)				return -ENODEV;			if (!(chan = find_channel(card, c->arg & 0x1f)))				break;			if (c->parm.cmsg.Length < 8)				break;			switch(c->parm.cmsg.Command) {				case CAPI_FACILITY:					if (c->parm.cmsg.Subcommand == CAPI_REQ)						return(capipmsg(card, chan, &c->parm.cmsg));					break;				case CAPI_MANUFACTURER:				default:					break;			}			return 0;        }	        return -EINVAL;}/* * Find card with given driverId */static inline eicon_card *eicon_findcard(int driverid){        eicon_card *p = cards;        while (p) {                if (p->myid == driverid)                        return p;                p = p->next;        }        return (eicon_card *) 0;}/* * Wrapper functions for interface to linklevel */static intif_command(isdn_ctrl * c){        eicon_card *card = eicon_findcard(c->driver);        if (card)                return (eicon_command(card, c));        printk(KERN_ERR             "eicon: if_command %d called with invalid driverId %d!\n",               c->command, c->driver);        return -ENODEV;}static intif_writecmd(const u_char * buf, int len, int user, int id, int channel){        return (len);}static intif_readstatus(u_char * buf, int len, int user, int id, int channel){	int count = 0;	int cnt = 0;	ulong flags = 0;	u_char *p = buf;	struct sk_buff *skb;        eicon_card *card = eicon_findcard(id);	        if (card) {                if (!card->flags & EICON_FLAGS_RUNNING)                        return -ENODEV;			spin_lock_irqsave(&eicon_lock, flags);		while((skb = skb_dequeue(&card->statq))) {			if ((skb->len + count) > len)				cnt = len - count;			else				cnt = skb->len;			if (user)				copy_to_user(p, skb->data, cnt);			else				memcpy(p, skb->data, cnt);			count += cnt;			p += cnt;			if (cnt == skb->len) {				dev_kfree_skb(skb);				if (card->statq_entries > 0)					card->statq_entries--;			} else {				skb_pull(skb, cnt);				skb_queue_head(&card->statq, skb);				spin_unlock_irqrestore(&eicon_lock, flags);				return count;			}		}		card->statq_entries = 0;		spin_unlock_irqrestore(&eicon_lock, flags);		return count;        }        printk(KERN_ERR               "eicon: if_readstatus called with invalid driverId!\n");        return 0;}static intif_sendbuf(int id, int channel, int ack, struct sk_buff *skb){        eicon_card *card = eicon_findcard(id);	eicon_chan *chan;	int ret = 0;	int len;	len = skb->len;	        if (card) {                if (!card->flags & EICON_FLAGS_RUNNING)                        return -ENODEV;        	if (!(chan = find_channel(card, channel)))			return -ENODEV;		if (chan->fsm_state == EICON_STATE_ACTIVE) {#ifdef CONFIG_ISDN_TTY_FAX			if (chan->l2prot == ISDN_PROTO_L2_FAX) {				if ((ret = idi_faxdata_send(card, chan, skb)) > 0)					ret = len;			}			else#endif				ret = idi_send_data(card, chan, ack, skb, 1, 1);			return (ret);		} else {			return -ENODEV;		}        }        printk(KERN_ERR               "eicon: if_sendbuf called with invalid driverId!\n");        return -ENODEV;}/* jiftime() copied from HiSax */static inline int jiftime(char *s, long mark){        s += 8;        *s-- = '\0';        *s-- = mark % 10 + '0';        mark /= 10;        *s-- = mark % 10 + '0';        mark /= 10;        *s-- = '.';        *s-- = mark % 10 + '0';        mark /= 10;        *s-- = mark % 6 + '0';        mark /= 6;        *s-- = ':';        *s-- = mark % 10 + '0';        mark /= 10;        *s-- = mark % 10 + '0';        return(8);}voideicon_putstatus(eicon_card * card, char * buf){	ulong flags;	int count;	isdn_ctrl cmd;	u_char *p;	struct sk_buff *skb;	if (!card) {		if (!(card = cards))			return;	}	spin_lock_irqsave(&eicon_lock, flags);	count = strlen(buf);	skb = alloc_skb(count, GFP_ATOMIC);	if (!skb) {		spin_unlock_irqrestore(&eicon_lock, flags);		printk(KERN_ERR "eicon: could not alloc skb in putstatus\n");		return;	}	p = skb_put(skb, count);	memcpy(p, buf, count);	skb_queue_tail(&card->statq, skb);	if (card->statq_entries >= MAX_STATUS_BUFFER) {		if ((skb = skb_dequeue(&card->statq))) {			count -= skb->len;			dev_kfree_skb(skb);		} else			count = 0;	} else		card->statq_entries++;	spin_unlock_irqrestore(&eicon_lock, flags);        if (count) {                cmd.command = ISDN_STAT_STAVAIL;                cmd.driver = card->myid;                cmd.arg = count;		card->interface.statcallb(&cmd);        }}/* * Debug and Log  */voideicon_log(eicon_card * card, int level, const char *fmt, ...){	va_list args;	char Line[160];	u_char *p;	if ((DebugVar & level) || (DebugVar & 256)) {		va_start(args, fmt);		if (DebugVar & level) {			if (DebugVar & 256) {				/* log-buffer */				p = Line;				p += jiftime(p, jiffies);				*p++ = 32;				p += vsprintf(p, fmt, args);				*p = 0;					eicon_putstatus(card, Line);			} else {				/* printk, syslogd */				vsprintf(Line, fmt, args);				printk(KERN_DEBUG "%s", Line);			}		}		va_end(args);	}}/* * Allocate a new card-struct, initialize it * link it into cards-list. */static voideicon_alloccard(int Type, int membase, int irq, char *id, int card_id){	int i;	int j;	int qloop;#ifdef CONFIG_ISDN_DRV_EICON_ISA	char qid[5];#endif        eicon_card *card;	qloop = (Type == EICON_CTYPE_QUADRO)?2:0;	for (i = 0; i <= qloop; i++) {		if (!(card = (eicon_card *) kmalloc(sizeof(eicon_card), GFP_KERNEL))) {			eicon_log(card, 1,			       "eicon: (%s) Could not allocate card-struct.\n", id);			return;		}		memset((char *) card, 0, sizeof(eicon_card));		skb_queue_head_init(&card->sndq);		skb_queue_head_init(&card->rcvq);		skb_queue_head_init(&card->rackq);		skb_queue_head_init(&card->sackq);		skb_queue_head_init(&card->statq);		card->statq_entries = 0;		card->snd_tq.routine = (void *) (void *) eicon_transmit;		card->snd_tq.data = card;		card->rcv_tq.routine = (void *) (void *) eicon_rcv_dispatch;		card->rcv_tq.data = card;		card->ack_tq.routine = (void *) (void *) eicon_ack_dispatch;		card->ack_tq.data = card;		card->interface.maxbufsize = 4000;		card->interface.command = if_command;		card->interface.writebuf_skb = if_sendbuf;		card->interface.writecmd = if_writecmd;		card->interface.readstat = if_readstatus;		card->interface.features =			ISDN_FEATURE_L2_X75I |			ISDN_FEATURE_L2_HDLC |			ISDN_FEATURE_L2_TRANS |			ISDN_FEATURE_L3_TRANS |			ISDN_FEATURE_P_UNKNOWN;		card->interface.hl_hdrlen = 20;		card->ptype = ISDN_PTYPE_UNKNOWN;		strncpy(card->interface.id, id, sizeof(card->interface.id) - 1);		card->myid = -1;		card->type = Type;		switch (Type) {#ifdef CONFIG_ISDN_DRV_EICON_ISA#if CONFIG_MCA /* only needed for MCA */                        case EICON_CTYPE_S:                        case EICON_CTYPE_SX:                        case EICON_CTYPE_SCOM:				if (MCA_bus) {	                                if (membase == -1)        	                                membase = EICON_ISA_MEMBASE;                	                if (irq == -1)                        	                irq = EICON_ISA_IRQ;	                                card->bus = EICON_BUS_MCA;        	                        card->hwif.isa.card = (void *)card;                	                card->hwif.isa.shmem = (eicon_isa_shmem *)membase;					card->hwif.isa.physmem = (unsigned long)membase;                        	        card->hwif.isa.master = 1;	                                card->hwif.isa.irq = irq;        	                        card->hwif.isa.type = Type;                	                card->nchannels = 2;                        	        card->interface.channels = 1;				} else {					printk(KERN_WARNING						"eicon (%s): no MCA bus detected.\n",						card->interface.id);					kfree(card);					return;				}                                break;#endif /* CONFIG_MCA */			case EICON_CTYPE_QUADRO:				if (membase == -1)					membase = EICON_ISA_MEMBASE;				if (irq == -1)					irq = EICON_ISA_IRQ;                                card->bus = EICON_BUS_ISA;				card->hwif.isa.card = (void *)card;				card->hwif.isa.shmem = (eicon_isa_shmem *)(membase + (i+1) * EICON_ISA_QOFFSET);				card->hwif.isa.physmem = (unsigned long)(membase + (i+1) * EICON_ISA_QOFFSET);				card->hwif.isa.master = 0;				strcpy(card->interface.id, id);				if (id[strlen(id) - 1] == 'a') {					card->interface.id[strlen(id) - 1] = 'a' + i + 1;				} else {					sprintf(qid, "_%c",'2' + i);					strcat(card->interface.id, qid);				}				printk(KERN_INFO "Eicon: Quadro: Driver-Id %s added.\n",					card->interface.id);				if (i == 0) {					eicon_card *p = cards;					while(p) {						if ((p->hwif.isa.master) && (p->hwif.isa.irq == irq)) {							p->qnext = card;							break;						}						p = p->next;					}					if (!p) {						eicon_log(card, 1, "eicon_alloccard: Quadro Master not found.\n");						kfree(card);						return;					}				} else {					cards->qnext = card;				}				card->hwif.isa.irq = irq;				card->hwif.isa.type = Type;				card->nchannels = 2;				card->interface.channels = 1;				break;#endif#ifdef CONFIG_PCI#ifdef CONFIG_ISDN_DRV_EICON_PCI			case EICON_CTYPE_MAESTRA:                                card->bus = EICON_BUS_PCI;				card->interface.features |=					ISDN_FEATURE_L2_V11096 |					ISDN_FEATURE_L2_V11019 |					ISDN_FEATURE_L2_V11038 |					ISDN_FEATURE_L2_MODEM |					ISDN_FEATURE_L2_FAX | 					ISDN_FEATURE_L3_TRANSDSP |					ISDN_FEATURE_L3_FCLASS2;                                card->hwif.pci.card = (void *)card;                                card->hwif.pci.master = card_id;                                card->hwif.pci.irq = irq;                                card->hwif.pci.type = Type;				card->flags = 0;                                card->nchannels = 2;				card->interface.channels = 1;				break;			case EICON_CTYPE_MAESTRAQ:                                card->bus = EICON_BUS_PCI;				card->interface.features |=					ISDN_FEATURE_L2_V11096 |					ISDN_FEATURE_L2_V11019 |					ISDN_FEATURE_L2_V11038 |					ISDN_FEATURE_L2_MODEM |					ISDN_FEATURE_L2_FAX | 					ISDN_FEATURE_L3_TRANSDSP |					ISDN_FEATURE_L3_FCLASS2;                                card->hwif.pci.card = (void *)card;                                card->hwif.pci.master = card_id;                                card->hwif.pci.irq = irq;                                card->hwif.pci.type = Type;				card->flags = 0;                                card->nchannels = 2;				card->interface.channels = 1;				break;			case EICON_CTYPE_MAESTRAP:                                card->bus = EICON_BUS_PCI;				card->interface.features |=					ISDN_FEATURE_L2_V11096 |					ISDN_FEATURE_L2_V11019 |					ISDN_FEATURE_L2_V11038 |					ISDN_FEATURE_L2_MODEM |					ISDN_FEATURE_L2_FAX |					ISDN_FEATURE_L3_TRANSDSP |					ISDN_FEATURE_L3_FCLASS2;                                card->hwif.pci.card = (void *)card;                                card->hwif.pci.master = card_id;                                card->hwif.pci.irq = irq;                                card->hwif.pci.type = Type;				card->flags = 0;                                card->nchannels = 30;				card->interface.channels = 1;				break;#endif#endif#ifdef CONFIG_ISDN_DRV_EICON_ISA			case EICON_CTYPE_ISABRI:				if (membase == -1)					membase = EICON_ISA_MEMBASE;				if (irq == -1)					irq = EICON_ISA_IRQ;				card->bus = EICON_BUS_ISA;				card->hwif.isa.card = (void *)card;				card->hwif.isa.shmem = (eicon_isa_shmem *)membase;				card->hwif.isa.physmem = (unsigned long)membase;				card->hwif.isa.master = 1;				card->hwif.isa.irq = irq;				card->hwif.isa.type = Type;				card->nchannels = 2;				card->interface.channels = 1;				break;			case EICON_CTYPE_ISAPRI:				if (membase == -1)					membase = EICON_ISA_MEMBASE;				if (irq == -1)					irq = EICON_ISA_IRQ;                                card->bus = EICON_BUS_ISA;				card->hwif.isa.card = (void *)card;				card->hwif.isa.shmem = (eicon_isa_shmem *)membase;				card->hwif.isa.physmem = (unsigned long)membase;				card->hwif.isa.master = 1;				card->hwif.isa.irq = irq;				card->hwif.isa.type = Type;				card->nchannels = 30;				card->interface.channels = 1;				break;#endif			default:				eicon_log(card, 1, "eicon_alloccard: Invalid type %d\n", Type);				kfree(card);				return;		}		if (!(card->bch = (eicon_chan *) kmalloc(sizeof(eicon_chan) * (card->nchannels + 1)							 , GFP_KERNEL))) {			eicon_log(card, 1,			       "eicon: (%s) Could not allocate bch-struct.\n", id);			kfree(card);			return;		}		for (j=0; j< (card->nchannels + 1); j++) {			memset((char *)&card->bch[j], 0, sizeof(eicon_chan));			card->bch[j].statectrl = 0;			card->bch[j].l2prot = ISDN_PROTO_L2_X75I;			card->bch[j].l3prot = ISDN_PROTO_L3_TRANS;			card->bch[j].e.D3Id = 0;			card->bch[j].e.B2Id = 0;			card->bch[j].e.Req = 0;			card->bch[j].No = j;			card->bch[j].tskb1 = NULL;			card->bch[j].tskb2 = NULL;			skb_queue_head_init(&card->bch[j].e.X);			skb_queue_head_init(&card->bch[j].e.R);		}#ifdef CONFIG_ISDN_DRV_EICON_PCI		/* *** Diva Server *** */		if (!(card->dbuf = (DBUFFER *) kmalloc((sizeof(DBUFFER) * (card->nchannels + 1))*2							 , GFP_KERNEL))) {			eicon_log(card, 1,			       "eicon: (%s) Could not allocate DBUFFER-struct.\n", id);			kfree(card);			kfree(card->bch);			return;		}		if (!(card->sbuf = (BUFFERS *) kmalloc((sizeof(BUFFERS) * (card->nchannels + 1)) * 2, GFP_KERNEL))) {			eicon_log(card, 1,			       "eicon: (%s) Could not allocate BUFFERS-struct.\n", id);			kfree(card);			kfree(card->bch);			kfree(card->dbuf);			return;		}		if (!(card->sbufp = (char *) kmalloc((270 * (card->nchannels + 1)) * 2, GFP_KERNEL))) {			eicon_log(card, 1,			       "eicon: (%s) Could not allocate BUFFERSP-struct.\n", id);			kfree(card);			kfree(card->bch);			kfree(card->dbuf);			kfree(card->sbuf);			return;		}		for (j=0; j< (card->nchannels + 1); j++) {			memset((char *)&card->dbuf[j], 0, sizeof(DBUFFER));			card->bch[j].de.RBuffer = (DBUFFER *)&card->dbuf[j];			memset((char *)&card->dbuf[j+(card->nchannels+1)], 0, sizeof(BUFFERS));			card->bch[j].be.RBuffer = (DBUFFER *)&card->dbuf[j+(card->nchannels+1)];			memset((char *)&card->sbuf[j], 0, sizeof(BUFFERS));			card->bch[j].de.X = (BUFFERS *)&card->sbuf[j];			memset((char *)&card->sbuf[j+(card->nchannels+1)], 0, sizeof(BUFFERS));			card->bch[j].be.X = (BUFFERS *)&card->sbuf[j+(card->nchannels+1)];			memset((char *)&card->sbufp[j], 0, 270);			card->bch[j].de.X->P = (char *)&card->sbufp[j * 270];			memset((char *)&card->sbufp[j+(card->nchannels+1)], 0, 270);			card->bch[j].be.X->P = (char *)&card->sbufp[(j+(card->nchannels+1)) * 270];

⌨️ 快捷键说明

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