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

📄 callc.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
			event = EV_LEASED;		case (PH_DEACTIVATE | INDICATION):		case (PH_DEACTIVATE | CONFIRM):			if (test_bit(FLG_TWO_DCHAN, &chanp->cs->HW_Flags))				i = 1;			else				i = 0;			while (i < 2) {				FsmEvent(&chanp->fi, event, NULL);				chanp++;				i++;			}			break;		default:			printk(KERN_WARNING				"transd_l1l2 unknown primitive %#x\n", pr);			break;	}}static voiddistr_debug(struct IsdnCardState *csta, int debugflags){	int i;	struct Channel *chanp = csta->channel;	for (i = 0; i < (2 + MAX_WAITING_CALLS) ; i++) {		chanp[i].debug = debugflags;		chanp[i].fi.debug = debugflags & 2;		chanp[i].d_st->l2.l2m.debug = debugflags & 8;		chanp[i].b_st->l2.l2m.debug = debugflags & 0x10;		chanp[i].d_st->l2.debug = debugflags & 0x20;		chanp[i].b_st->l2.debug = debugflags & 0x40;		chanp[i].d_st->l3.l3m.debug = debugflags & 0x80;		chanp[i].b_st->l3.l3m.debug = debugflags & 0x100;		chanp[i].b_st->ma.tei_m.debug = debugflags & 0x200;		chanp[i].b_st->ma.debug = debugflags & 0x200;		chanp[i].d_st->l1.l1m.debug = debugflags & 0x1000;		chanp[i].b_st->l1.l1m.debug = debugflags & 0x2000;	}	if (debugflags & 4)		csta->debug |= DEB_DLOG_HEX;	else		csta->debug &= ~DEB_DLOG_HEX;}static char tmpbuf[256];static voidcapi_debug(struct Channel *chanp, capi_msg *cm){	char *t = tmpbuf;	t += QuickHex(t, (u_char *)cm, (cm->Length>50)? 50: cm->Length);	t--;	*t= 0;	HiSax_putstatus(chanp->cs, "Ch", "%d CAPIMSG %s", chanp->chan, tmpbuf);}voidlli_got_fac_req(struct Channel *chanp, capi_msg *cm) {	if ((cm->para[0] != 3) || (cm->para[1] != 0))		return;	if (cm->para[2]<3)		return;	if (cm->para[4] != 0)		return;	switch(cm->para[3]) {		case 4: /* Suspend */			strncpy(chanp->setup.phone, &cm->para[5], cm->para[5] +1);			FsmEvent(&chanp->fi, EV_SUSPEND, cm);			break;		case 5: /* Resume */			strncpy(chanp->setup.phone, &cm->para[5], cm->para[5] +1);			if (chanp->fi.state == ST_NULL) {				FsmEvent(&chanp->fi, EV_RESUME, cm);			} else {				FsmDelTimer(&chanp->dial_timer, 72);				FsmAddTimer(&chanp->dial_timer, 80, EV_RESUME, cm, 73);			}			break;	}}voidlli_got_manufacturer(struct Channel *chanp, struct IsdnCardState *cs, capi_msg *cm) {	if ((cs->typ == ISDN_CTYPE_ELSA) || (cs->typ == ISDN_CTYPE_ELSA_PNP) ||		(cs->typ == ISDN_CTYPE_ELSA_PCI)) {		if (cs->hw.elsa.MFlag) {			cs->cardmsg(cs, CARD_AUX_IND, cm->para);		}	}}/***************************************************************//* Limit the available number of channels for the current card *//***************************************************************/static int set_channel_limit(struct IsdnCardState *cs, int chanmax){	isdn_ctrl ic;	int i, ii;	if ((chanmax < 0) || (chanmax > 2))		return(-EINVAL);	cs->chanlimit = 0;	for (ii = 0; ii < 2; ii++) {		ic.driver = cs->myid;		ic.command = ISDN_STAT_DISCH;		ic.arg = ii;		if (ii >= chanmax)			ic.parm.num[0] = 0; /* disabled */		else			ic.parm.num[0] = 1; /* enabled */		i = cs->iif.statcallb(&ic); 		if (i) return(-EINVAL);		if (ii < chanmax) 			cs->chanlimit++;	}	return(0);} /* set_channel_limit */intHiSax_command(isdn_ctrl * ic){	struct IsdnCardState *csta = hisax_findcard(ic->driver);	struct PStack *st;	struct Channel *chanp;	int i;	u_int num;	if (!csta) {		printk(KERN_ERR		"HiSax: if_command %d called with invalid driverId %d!\n",			ic->command, ic->driver);		return -ENODEV;	}	switch (ic->command) {		case (ISDN_CMD_SETEAZ):			chanp = csta->channel + ic->arg;			break;		case (ISDN_CMD_SETL2):			chanp = csta->channel + (ic->arg & 0xff);			if (chanp->debug & 1)				link_debug(chanp, 1, "SETL2 card %d %ld",					csta->cardnr + 1, ic->arg >> 8);			chanp->l2_protocol = ic->arg >> 8;			break;		case (ISDN_CMD_SETL3):			chanp = csta->channel + (ic->arg & 0xff);			if (chanp->debug & 1)				link_debug(chanp, 1, "SETL3 card %d %ld",					csta->cardnr + 1, ic->arg >> 8);			chanp->l3_protocol = ic->arg >> 8;			break;		case (ISDN_CMD_DIAL):			chanp = csta->channel + (ic->arg & 0xff);			if (chanp->debug & 1)				link_debug(chanp, 1, "DIAL %s -> %s (%d,%d)",					ic->parm.setup.eazmsn, ic->parm.setup.phone,					ic->parm.setup.si1, ic->parm.setup.si2);			memcpy(&chanp->setup, &ic->parm.setup, sizeof(setup_parm));			if (!strcmp(chanp->setup.eazmsn, "0"))				chanp->setup.eazmsn[0] = '\0';			/* this solution is dirty and may be change, if			 * we make a callreference based callmanager */			if (chanp->fi.state == ST_NULL) {				FsmEvent(&chanp->fi, EV_DIAL, NULL);			} else {				FsmDelTimer(&chanp->dial_timer, 70);				FsmAddTimer(&chanp->dial_timer, 50, EV_DIAL, NULL, 71);			}			break;		case (ISDN_CMD_ACCEPTB):			chanp = csta->channel + ic->arg;			if (chanp->debug & 1)				link_debug(chanp, 1, "ACCEPTB");			FsmEvent(&chanp->fi, EV_ACCEPTB, NULL);			break;		case (ISDN_CMD_ACCEPTD):			chanp = csta->channel + ic->arg;			memcpy(&chanp->setup, &ic->parm.setup, sizeof(setup_parm));			if (chanp->debug & 1)				link_debug(chanp, 1, "ACCEPTD");			FsmEvent(&chanp->fi, EV_ACCEPTD, NULL);			break;		case (ISDN_CMD_HANGUP):			chanp = csta->channel + ic->arg;			if (chanp->debug & 1)				link_debug(chanp, 1, "HANGUP");			FsmEvent(&chanp->fi, EV_HANGUP, NULL);			break;		case (CAPI_PUT_MESSAGE):			chanp = csta->channel + ic->arg;			if (chanp->debug & 1)				capi_debug(chanp, &ic->parm.cmsg);			if (ic->parm.cmsg.Length < 8)				break;			switch(ic->parm.cmsg.Command) {				case CAPI_FACILITY:					if (ic->parm.cmsg.Subcommand == CAPI_REQ)						lli_got_fac_req(chanp, &ic->parm.cmsg);					break;				case CAPI_MANUFACTURER:					if (ic->parm.cmsg.Subcommand == CAPI_REQ)						lli_got_manufacturer(chanp, csta, &ic->parm.cmsg);					break;				default:					break;			}			break;		case (ISDN_CMD_LOCK):			HiSax_mod_inc_use_count();#ifdef MODULE			if (csta->channel[0].debug & 0x400)				HiSax_putstatus(csta, "   LOCK ", "modcnt %lx",					MOD_USE_COUNT);#endif				/* MODULE */			break;		case (ISDN_CMD_UNLOCK):			HiSax_mod_dec_use_count();#ifdef MODULE			if (csta->channel[0].debug & 0x400)				HiSax_putstatus(csta, " UNLOCK ", "modcnt %lx",					MOD_USE_COUNT);#endif				/* MODULE */			break;		case (ISDN_CMD_IOCTL):			switch (ic->arg) {				case (0):					num = *(unsigned int *) ic->parm.num;					HiSax_reportcard(csta->cardnr, num);					break;				case (1):					num = *(unsigned int *) ic->parm.num;					distr_debug(csta, num);					printk(KERN_DEBUG "HiSax: debugging flags card %d set to %x\n",						csta->cardnr + 1, num);					HiSax_putstatus(csta, "debugging flags ",						"card %d set to %x", csta->cardnr + 1, num);					break;				case (2):					num = *(unsigned int *) ic->parm.num;					csta->channel[0].b_st->l1.delay = num;					csta->channel[1].b_st->l1.delay = num;					HiSax_putstatus(csta, "delay ", "card %d set to %d ms",						csta->cardnr + 1, num);					printk(KERN_DEBUG "HiSax: delay card %d set to %d ms\n",						csta->cardnr + 1, num);					break;				case (3):					for (i = 0; i < *(unsigned int *) ic->parm.num; i++)						HiSax_mod_dec_use_count();					break;				case (4):					for (i = 0; i < *(unsigned int *) ic->parm.num; i++)						HiSax_mod_inc_use_count();					break;				case (5):	/* set card in leased mode */					num = *(unsigned int *) ic->parm.num;					if ((num <1) || (num > 2)) {						HiSax_putstatus(csta, "Set LEASED ",							"wrong channel %d", num);						printk(KERN_WARNING "HiSax: Set LEASED wrong channel %d\n",							num);					} else {						num--;						chanp = csta->channel +num;						chanp->leased = 1;						HiSax_putstatus(csta, "Card",							"%d channel %d set leased mode\n",							csta->cardnr + 1, num + 1);						chanp->d_st->l1.l1l2 = leased_l1l2;						chanp->d_st->lli.l4l3 = leased_l4l3;						chanp->d_st->lli.l4l3(chanp->d_st,							DL_ESTABLISH | REQUEST, NULL);					}					break;				case (6):	/* set B-channel test loop */					num = *(unsigned int *) ic->parm.num;					if (csta->stlist)						csta->stlist->l2.l2l1(csta->stlist,							PH_TESTLOOP | REQUEST, (void *) (long)num);					break;				case (7):	/* set card in PTP mode */					num = *(unsigned int *) ic->parm.num;					if (test_bit(FLG_TWO_DCHAN, &csta->HW_Flags)) {						printk(KERN_ERR "HiSax PTP mode only with one TEI possible\n");					} else if (num) {						test_and_set_bit(FLG_PTP, &csta->channel[0].d_st->l2.flag);						test_and_set_bit(FLG_FIXED_TEI, &csta->channel[0].d_st->l2.flag);						csta->channel[0].d_st->l2.tei = 0;						HiSax_putstatus(csta, "set card ", "in PTP mode");						printk(KERN_DEBUG "HiSax: set card in PTP mode\n");						printk(KERN_INFO "LAYER2 WATCHING ESTABLISH\n");						csta->channel[0].d_st->lli.l4l3(csta->channel[0].d_st,							DL_ESTABLISH | REQUEST, NULL);					} else {						test_and_clear_bit(FLG_PTP, &csta->channel[0].d_st->l2.flag);						test_and_clear_bit(FLG_FIXED_TEI, &csta->channel[0].d_st->l2.flag);						HiSax_putstatus(csta, "set card ", "in PTMP mode");						printk(KERN_DEBUG "HiSax: set card in PTMP mode\n");					}					break;				case (8):	/* set card in FIXED TEI mode */					num = *(unsigned int *) ic->parm.num;					chanp = csta->channel + (num & 1);					num = num >>1;					if (num == 127) {						test_and_clear_bit(FLG_FIXED_TEI, &chanp->d_st->l2.flag);						chanp->d_st->l2.tei = -1;						HiSax_putstatus(csta, "set card ", "in VAR TEI mode");						printk(KERN_DEBUG "HiSax: set card in VAR TEI mode\n");					} else {						test_and_set_bit(FLG_FIXED_TEI, &chanp->d_st->l2.flag);						chanp->d_st->l2.tei = num;						HiSax_putstatus(csta, "set card ", "in FIXED TEI (%d) mode", num);						printk(KERN_DEBUG "HiSax: set card in FIXED TEI (%d) mode\n",							num);					}					chanp->d_st->lli.l4l3(chanp->d_st,						DL_ESTABLISH | REQUEST, NULL);					break;#ifdef MODULE				case (55):					MOD_USE_COUNT = 0;					HiSax_mod_inc_use_count();					break;#endif				/* MODULE */				case (11):					num = csta->debug & DEB_DLOG_HEX;					csta->debug = *(unsigned int *) ic->parm.num;					csta->debug |= num;					HiSax_putstatus(cards[0].cs, "l1 debugging ",						"flags card %d set to %x",						csta->cardnr + 1, csta->debug);					printk(KERN_DEBUG "HiSax: l1 debugging flags card %d set to %x\n",						csta->cardnr + 1, csta->debug);					break;				case (13):					csta->channel[0].d_st->l3.debug = *(unsigned int *) ic->parm.num;					csta->channel[1].d_st->l3.debug = *(unsigned int *) ic->parm.num;					HiSax_putstatus(cards[0].cs, "l3 debugging ",						"flags card %d set to %x\n", csta->cardnr + 1,						*(unsigned int *) ic->parm.num);					printk(KERN_DEBUG "HiSax: l3 debugging flags card %d set to %x\n",						csta->cardnr + 1, *(unsigned int *) ic->parm.num);					break;				case (10):					i = *(unsigned int *) ic->parm.num;					return(set_channel_limit(csta, i));				default:					if (csta->auxcmd)						return(csta->auxcmd(csta, ic));					printk(KERN_DEBUG "HiSax: invalid ioclt %d\n",						(int) ic->arg);					return (-EINVAL);			}			break;				case (ISDN_CMD_PROCEED):			chanp = csta->channel + ic->arg;			if (chanp->debug & 1)				link_debug(chanp, 1, "PROCEED");			FsmEvent(&chanp->fi, EV_PROCEED, NULL);			break;		case (ISDN_CMD_ALERT):			chanp = csta->channel + ic->arg;			if (chanp->debug & 1)				link_debug(chanp, 1, "ALERT");			FsmEvent(&chanp->fi, EV_ALERT, NULL);			break;		case (ISDN_CMD_REDIR):			chanp = csta->channel + ic->arg;			if (chanp->debug & 1)				link_debug(chanp, 1, "REDIR");			memcpy(&chanp->setup, &ic->parm.setup, sizeof(setup_parm));			FsmEvent(&chanp->fi, EV_REDIR, NULL);			break;		/* protocol specific io commands */		case (ISDN_CMD_PROT_IO):			for (st = csta->stlist; st; st = st->next)				if (st->protocol == (ic->arg & 0xFF))					return(st->lli.l4l3_proto(st, ic));			return(-EINVAL);			break;		default:			if (csta->auxcmd)				return(csta->auxcmd(csta, ic));			return(-EINVAL);	}	return (0);}intHiSax_writebuf_skb(int id, int chan, int ack, struct sk_buff *skb){	struct IsdnCardState *csta = hisax_findcard(id);	struct Channel *chanp;	struct PStack *st;	int len = skb->len;	unsigned long flags;	struct sk_buff *nskb;	if (!csta) {		printk(KERN_ERR			"HiSax: if_sendbuf called with invalid driverId!\n");		return -ENODEV;	}	chanp = csta->channel + chan;	st = chanp->b_st;	if (!chanp->data_open) {		link_debug(chanp, 1, "writebuf: channel not open");		return -EIO;	}	if (len > MAX_DATA_SIZE) {		link_debug(chanp, 1, "writebuf: packet too large (%d bytes)", len);		printk(KERN_WARNING "HiSax_writebuf: packet too large (%d bytes) !\n",			len);		return -EINVAL;	}	if (len) {		if ((len + chanp->bcs->tx_cnt) > MAX_DATA_MEM) {			/* Must return 0 here, since this is not an error			 * but a temporary lack of resources.			 */			if (chanp->debug & 0x800)				link_debug(chanp, 1, "writebuf: no buffers for %d bytes", len);			return 0;		} else if (chanp->debug & 0x800)			link_debug(chanp, 1, "writebuf %d/%d/%d", len, chanp->bcs->tx_cnt,MAX_DATA_MEM);		save_flags(flags);		cli();		nskb = skb_clone(skb, GFP_ATOMIC);		if (nskb) {			if (!ack)				nskb->pkt_type = PACKET_NOACK;			if (chanp->l2_active_protocol == ISDN_PROTO_L2_X75I)				st->l3.l3l2(st, DL_DATA | REQUEST, nskb);			else {				chanp->bcs->tx_cnt += len;				st->l2.l2l1(st, PH_DATA | REQUEST, nskb);			}			dev_kfree_skb(skb);		} else			len = 0;		restore_flags(flags);	}	return (len);}

⌨️ 快捷键说明

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