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

📄 eicon_mod.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
                                                        for(idi_length = 0; idi_length < 32; idi_length++)                                                          if (idi_d[idi_length].type == 0) break;                                                        if ((idi_length < 1) || (idi_length >= 32)) {					                  eicon_log(card, 1, "eicon: invalid idi table length.\n");                                                          break;                                                        }        						for(i = 3; i >= 0; i--) {								if (!(card = eicon_findnpcicard(dstart.card_id - i)))									return -EINVAL;									card->flags |= EICON_FLAGS_LOADED;								card->flags |= EICON_FLAGS_RUNNING;								card->d = &idi_d[idi_length - (i+1)];								eicon_pci_init_conf(card);								if (card->d->channels > 1) {									cmd.command = ISDN_STAT_ADDCH;									cmd.driver = card->myid;									cmd.arg = card->d->channels - 1;									card->interface.statcallb(&cmd);								}								cmd.command = ISDN_STAT_RUN;    								cmd.driver = card->myid;        								cmd.arg = 0;                    								card->interface.statcallb(&cmd);								eicon_log(card, 1, "Eicon: %d/4BRI started, %d channels (feat. 0x%x)\n",									4-i, card->d->channels, card->d->features);							}						}					}					return ret;#else					return -EINVAL;#endif#endif /* CONFIG_PCI */			}			break;		case ISDN_CMD_DIAL:			if (!card->flags & EICON_FLAGS_RUNNING)				return -ENODEV;			if (!(chan = find_channel(card, c->arg & 0x1f)))				break;			spin_lock_irqsave(&eicon_lock, flags);			if ((chan->fsm_state != EICON_STATE_NULL) && (chan->fsm_state != EICON_STATE_LISTEN)) {				spin_unlock_irqrestore(&eicon_lock, flags);				eicon_log(card, 1, "Dial on channel %d with state %d\n",					chan->No, chan->fsm_state);				return -EBUSY;			}			chan->fsm_state = EICON_STATE_OCALL;			spin_unlock_irqrestore(&eicon_lock, flags);						ret = idi_connect_req(card, chan, c->parm.setup.phone,						     c->parm.setup.eazmsn,						     c->parm.setup.si1,						     c->parm.setup.si2);			if (ret) {				cmd.driver = card->myid;				cmd.command = ISDN_STAT_DHUP;				cmd.arg &= 0x1f;				card->interface.statcallb(&cmd);			}			return ret;		case ISDN_CMD_ACCEPTD:			if (!card->flags & EICON_FLAGS_RUNNING)				return -ENODEV;			if (!(chan = find_channel(card, c->arg & 0x1f)))				break;			if (chan->fsm_state == EICON_STATE_ICALL) { 				idi_connect_res(card, chan);			}			return 0;		case ISDN_CMD_ACCEPTB:			if (!card->flags & EICON_FLAGS_RUNNING)				return -ENODEV;			return 0;		case ISDN_CMD_HANGUP:			if (!card->flags & EICON_FLAGS_RUNNING)				return -ENODEV;			if (!(chan = find_channel(card, c->arg & 0x1f)))				break;			idi_hangup(card, chan);			return 0;		case ISDN_CMD_SETEAZ:			if (!card->flags & EICON_FLAGS_RUNNING)				return -ENODEV;			if (!(chan = find_channel(card, c->arg & 0x1f)))				break;			chan->eazmask = 0x3ff;			eicon_idi_listen_req(card, chan);			return 0;		case ISDN_CMD_CLREAZ:			if (!card->flags & EICON_FLAGS_RUNNING)				return -ENODEV;			if (!(chan = find_channel(card, c->arg & 0x1f)))				break;			chan->eazmask = 0;			eicon_idi_listen_req(card, chan);			return 0;		case ISDN_CMD_SETL2:			if (!card->flags & EICON_FLAGS_RUNNING)				return -ENODEV;			if (!(chan = find_channel(card, c->arg & 0x1f)))				break;			chan->l2prot = (c->arg >> 8);			return 0;		case ISDN_CMD_GETL2:			if (!card->flags & EICON_FLAGS_RUNNING)				return -ENODEV;			if (!(chan = find_channel(card, c->arg & 0x1f)))				break;			return chan->l2prot;		case ISDN_CMD_SETL3:			if (!card->flags & EICON_FLAGS_RUNNING)				return -ENODEV;			if (!(chan = find_channel(card, c->arg & 0x1f)))				break;			chan->l3prot = (c->arg >> 8);#ifdef CONFIG_ISDN_TTY_FAX			if (chan->l3prot == ISDN_PROTO_L3_FCLASS2) {				chan->fax = c->parm.fax;				eicon_log(card, 128, "idi_cmd: Ch%d: SETL3 struct fax=0x%x\n",chan->No, chan->fax);			}#endif			return 0;		case ISDN_CMD_GETL3:			if (!card->flags & EICON_FLAGS_RUNNING)				return -ENODEV;			if (!(chan = find_channel(card, c->arg & 0x1f)))				break;			return chan->l3prot;		case ISDN_CMD_GETEAZ:			if (!card->flags & EICON_FLAGS_RUNNING)				return -ENODEV;			eicon_log(card, 1, "eicon CMD_GETEAZ not implemented\n");			return 0;		case ISDN_CMD_SETSIL:			if (!card->flags & EICON_FLAGS_RUNNING)				return -ENODEV;			eicon_log(card, 1, "eicon CMD_SETSIL not implemented\n");			return 0;		case ISDN_CMD_GETSIL:			if (!card->flags & EICON_FLAGS_RUNNING)				return -ENODEV;			eicon_log(card, 1, "eicon CMD_GETSIL not implemented\n");			return 0;		case ISDN_CMD_LOCK:#ifdef MODULE			mod_inc_use_count();#endif			return 0;		case ISDN_CMD_UNLOCK:#ifdef MODULE			mod_dec_use_count();#endif			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;

⌨️ 快捷键说明

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