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

📄 isar.c

📁 arm平台上的uclinux系统全部源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
						bcs->hw.isar.rcvbuf, bcs->hw.isar.rcvidx-2);					skb_queue_tail(&bcs->rqueue, skb);					isar_sched_event(bcs, B_RCVBUFREADY);				}			}		}		break;	default:		printk(KERN_ERR"isar_rcv_frame mode (%x)error\n", bcs->mode);		cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);		break;	}}voidisar_fill_fifo(struct BCState *bcs){	struct IsdnCardState *cs = bcs->cs;	int count;	u_char msb;	u_char *ptr;	long flags;	if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))		debugl1(cs, "isar_fill_fifo");	if (!bcs->tx_skb)		return;	if (bcs->tx_skb->len <= 0)		return;	if (!(bcs->hw.isar.reg->bstat & 		(bcs->hw.isar.dpath == 1 ? BSTAT_RDM1 : BSTAT_RDM2)))		return;	if (bcs->tx_skb->len > bcs->hw.isar.mml) {		msb = 0;		count = bcs->hw.isar.mml;	} else {		count = bcs->tx_skb->len;		msb = HDLC_FED;	}	if (!bcs->hw.isar.txcnt)		msb |= HDLC_FST;	save_flags(flags);	cli();	ptr = bcs->tx_skb->data;	skb_pull(bcs->tx_skb, count);	bcs->tx_cnt -= count;	bcs->hw.isar.txcnt += count;	switch (bcs->mode) {	case L1_MODE_NULL:		printk(KERN_ERR"isar_fill_fifo wrong mode 0\n");		break;	case L1_MODE_TRANS:		if (!sendmsg(cs, SET_DPS(bcs->hw.isar.dpath) | ISAR_HIS_SDATA,			0, count, ptr)) {			if (cs->debug)				debugl1(cs, "isar bin data send dp%d failed",					bcs->hw.isar.dpath);		}		break;	case L1_MODE_HDLC:		if (!sendmsg(cs, SET_DPS(bcs->hw.isar.dpath) | ISAR_HIS_SDATA,			msb, count, ptr)) {			if (cs->debug)				debugl1(cs, "isar hdlc data send dp%d failed",					bcs->hw.isar.dpath);		}		break;	default:		printk(KERN_ERR"isar_fill_fifo mode (%x)error\n", bcs->mode);		break;	}	restore_flags(flags);}inlinestruct BCState *sel_bcs_isar(struct IsdnCardState *cs, u_char dpath){	if ((!dpath) || (dpath == 3))		return(NULL);	if (cs->bcs[0].hw.isar.dpath == dpath)		return(&cs->bcs[0]);	if (cs->bcs[1].hw.isar.dpath == dpath)		return(&cs->bcs[1]);	return(NULL);}inline voidsend_frames(struct BCState *bcs){	if (bcs->tx_skb) {		if (bcs->tx_skb->len) {			isar_fill_fifo(bcs);			return;		} else {			if (bcs->st->lli.l1writewakeup &&				(PACKET_NOACK != bcs->tx_skb->pkt_type))					bcs->st->lli.l1writewakeup(bcs->st, bcs->hw.isar.txcnt);			dev_kfree_skb(bcs->tx_skb, FREE_WRITE);			bcs->hw.isar.txcnt = 0; 			bcs->tx_skb = NULL;		}	}	if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {		bcs->hw.isar.txcnt = 0;		test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);		isar_fill_fifo(bcs);	} else {		test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);		isar_sched_event(bcs, B_XMTBUFREADY);	}}inline voidcheck_send(struct IsdnCardState *cs, u_char rdm){	struct BCState *bcs;		if (rdm & BSTAT_RDM1) {		if ((bcs = sel_bcs_isar(cs, 1))) {			if (bcs->mode) {				send_frames(bcs);			}		}	}	if (rdm & BSTAT_RDM2) {		if ((bcs = sel_bcs_isar(cs, 2))) {			if (bcs->mode) {				send_frames(bcs);			}		}	}	}static char debbuf[64];voidisar_int_main(struct IsdnCardState *cs){	long flags;	struct isar_reg *ireg = cs->bcs[0].hw.isar.reg;	struct BCState *bcs;	save_flags(flags);	cli();	get_irq_infos(cs, ireg);	switch (ireg->iis & ISAR_IIS_MSCMSD) {		case ISAR_IIS_RDATA:			if ((bcs = sel_bcs_isar(cs, ireg->iis >> 6))) {				isar_rcv_frame(cs, bcs);			} else {				debugl1(cs, "isar spurious IIS_RDATA %x/%x/%x",					ireg->iis, ireg->cmsb, ireg->clsb);				printk(KERN_WARNING"isar spurious IIS_RDATA %x/%x/%x\n",					ireg->iis, ireg->cmsb, ireg->clsb);				cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);			}			break;		case ISAR_IIS_GSTEV:			cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);			ireg->bstat |= ireg->cmsb;			check_send(cs, ireg->cmsb);			break;		case ISAR_IIS_BSTEV:			cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);			if (cs->debug & L1_DEB_WARN)				debugl1(cs, "Buffer STEV dpath%d msb(%x)",					ireg->iis>>6, ireg->cmsb);			break;		case ISAR_IIS_DIAG:		case ISAR_IIS_PSTRSP:		case ISAR_IIS_PSTEV:		case ISAR_IIS_BSTRSP:		case ISAR_IIS_IOM2RSP:			rcv_mbox(cs, ireg, (u_char *)ireg->par);			if ((cs->debug & (L1_DEB_HSCX | L1_DEB_HSCX_FIFO))				== L1_DEB_HSCX) {				u_char *tp=debbuf;				tp += sprintf(debbuf, "msg iis(%x) msb(%x)",					ireg->iis, ireg->cmsb);				QuickHex(tp, (u_char *)ireg->par, ireg->clsb);				debugl1(cs, debbuf);			}			break;		default:			rcv_mbox(cs, ireg, debbuf);			if (cs->debug & L1_DEB_WARN)				debugl1(cs, "unhandled msg iis(%x) ctrl(%x/%x)",					ireg->iis, ireg->cmsb, ireg->clsb);			break;	}	restore_flags(flags);}voidsetup_pump(struct BCState *bcs) {	struct IsdnCardState *cs = bcs->cs;	u_char dps = SET_DPS(bcs->hw.isar.dpath);		switch (bcs->mode) {		case L1_MODE_NULL:		case L1_MODE_TRANS:		case L1_MODE_HDLC:			if (!sendmsg(cs, dps | ISAR_HIS_PUMPCFG, PMOD_BYPASS, 0, NULL)) {				if (cs->debug)					debugl1(cs, "isar pump bypass cfg dp%d failed",						bcs->hw.isar.dpath);			}			break;	}	if (!sendmsg(cs, dps | ISAR_HIS_PSTREQ, 0, 0, NULL)) {		if (cs->debug)			debugl1(cs, "isar pump status req dp%d failed",				bcs->hw.isar.dpath);	}}voidsetup_sart(struct BCState *bcs) {	struct IsdnCardState *cs = bcs->cs;	u_char dps = SET_DPS(bcs->hw.isar.dpath);		switch (bcs->mode) {		case L1_MODE_NULL:			if (!sendmsg(cs, dps | ISAR_HIS_SARTCFG, SMODE_DISABLE, 0, NULL)) {				if (cs->debug)					debugl1(cs, "isar sart disable dp%d failed",						bcs->hw.isar.dpath);			}			break;		case L1_MODE_TRANS:			if (!sendmsg(cs, dps | ISAR_HIS_SARTCFG, SMODE_BINARY, 2, "\0\0")) {				if (cs->debug)					debugl1(cs, "isar sart binary dp%d failed",						bcs->hw.isar.dpath);			}			break;		case L1_MODE_HDLC:			if (!sendmsg(cs, dps | ISAR_HIS_SARTCFG, SMODE_HDLC, 1, "\0")) {				if (cs->debug)					debugl1(cs, "isar sart binary dp%d failed",						bcs->hw.isar.dpath);			}			break;	}	if (!sendmsg(cs, dps | ISAR_HIS_BSTREQ, 0, 0, NULL)) {		if (cs->debug)			debugl1(cs, "isar buf stat req dp%d failed",				bcs->hw.isar.dpath);	}}voidsetup_iom2(struct BCState *bcs) {	struct IsdnCardState *cs = bcs->cs;	u_char dps = SET_DPS(bcs->hw.isar.dpath);	u_char cmsb = 0, msg[5] = {0x10,0,0,0,0};		switch (bcs->mode) {		case L1_MODE_NULL:			/* dummy slot */			msg[1] = msg[3] = bcs->hw.isar.dpath + 2;			break;		case L1_MODE_TRANS:		case L1_MODE_HDLC:			cmsb = 0x80;			if (bcs->channel)				msg[1] = msg[3] = 1;			break;	}	if (!sendmsg(cs, dps | ISAR_HIS_IOM2CFG, cmsb, 5, msg)) {		if (cs->debug)			debugl1(cs, "isar iom2 dp%d failed", bcs->hw.isar.dpath);	}	if (!sendmsg(cs, dps | ISAR_HIS_IOM2REQ, 0, 0, NULL)) {		if (cs->debug)			debugl1(cs, "isar IOM2 cfg req dp%d failed",				bcs->hw.isar.dpath);	}}intmodeisar(struct BCState *bcs, int mode, int bc){	struct IsdnCardState *cs = bcs->cs;	/* Here we are selecting the best datapath for requested mode */	if(bcs->mode == L1_MODE_NULL) { /* New Setup */		bcs->channel = bc;		switch (mode) {			case L1_MODE_NULL: /* init */				break;			case L1_MODE_TRANS:			case L1_MODE_HDLC:				/* best is datapath 2 */				if (!test_and_set_bit(ISAR_DP2_USE, 					&bcs->hw.isar.reg->Flags))					bcs->hw.isar.dpath = 2;				else if (!test_and_set_bit(ISAR_DP1_USE,					&bcs->hw.isar.reg->Flags))					bcs->hw.isar.dpath = 1;				else {					printk(KERN_ERR"isar modeisar both pathes in use\n");					return(1);				}				break;		}	}	if (cs->debug & L1_DEB_HSCX)		debugl1(cs, "isar dp%d mode %d->%d ichan %d",			bcs->hw.isar.dpath, bcs->mode, mode, bc);	bcs->mode = mode;	setup_pump(bcs);	setup_sart(bcs);	setup_iom2(bcs);	if (bcs->mode == L1_MODE_NULL) {		/* Clear resources */		if (bcs->hw.isar.dpath == 1)			test_and_clear_bit(ISAR_DP1_USE, &bcs->hw.isar.reg->Flags);		else if (bcs->hw.isar.dpath == 2)			test_and_clear_bit(ISAR_DP2_USE, &bcs->hw.isar.reg->Flags);		bcs->hw.isar.dpath = 0;	}	return(0);}voidisar_setup(struct IsdnCardState *cs){	u_char msg;	int i;		/* Dpath 1, 2 */	msg = 61;	for (i=0; i<2; i++) {		/* Buffer Config */		if (!sendmsg(cs, (i ? ISAR_HIS_DPS2 : ISAR_HIS_DPS1) |			ISAR_HIS_P12CFG, 4, 1, &msg)) {			if (cs->debug)				debugl1(cs, "isar P%dCFG failed", i+1);		}		cs->bcs[i].hw.isar.mml = msg;		cs->bcs[i].mode = 0;		cs->bcs[i].hw.isar.dpath = i + 1;		modeisar(&cs->bcs[i], 0, 0);	}}voidisar_l2l1(struct PStack *st, int pr, void *arg){	struct sk_buff *skb = arg;	long flags;	switch (pr) {		case (PH_DATA | REQUEST):			save_flags(flags);			cli();			if (st->l1.bcs->tx_skb) {				skb_queue_tail(&st->l1.bcs->squeue, skb);				restore_flags(flags);			} else {				st->l1.bcs->tx_skb = skb;				test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);				if (st->l1.bcs->cs->debug & L1_DEB_HSCX)					debugl1(st->l1.bcs->cs, "DRQ set BC_FLG_BUSY");				st->l1.bcs->hw.isar.txcnt = 0;				restore_flags(flags);				st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);			}			break;		case (PH_PULL | INDICATION):			if (st->l1.bcs->tx_skb) {				printk(KERN_WARNING "isar_l2l1: this shouldn't happen\n");				break;			}			test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);			if (st->l1.bcs->cs->debug & L1_DEB_HSCX)				debugl1(st->l1.bcs->cs, "PUI set BC_FLG_BUSY");			st->l1.bcs->tx_skb = skb;			st->l1.bcs->hw.isar.txcnt = 0;			st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);			break;		case (PH_PULL | REQUEST):			if (!st->l1.bcs->tx_skb) {				test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);				st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);			} else				test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);			break;		case (PH_ACTIVATE | REQUEST):			test_and_set_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);			modeisar(st->l1.bcs, st->l1.mode, st->l1.bc);			l1_msg_b(st, pr, arg);			break;		case (PH_DEACTIVATE | REQUEST):			l1_msg_b(st, pr, arg);			break;		case (PH_DEACTIVATE | CONFIRM):			test_and_clear_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);			test_and_clear_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);			if (st->l1.bcs->cs->debug & L1_DEB_HSCX)				debugl1(st->l1.bcs->cs, "PDAC clear BC_FLG_BUSY");			modeisar(st->l1.bcs, 0, st->l1.bc);			st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);			break;	}}voidclose_isarstate(struct BCState *bcs){	modeisar(bcs, 0, bcs->channel);	if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {		if (bcs->hw.isar.rcvbuf) {			kfree(bcs->hw.isar.rcvbuf);			bcs->hw.isar.rcvbuf = NULL;		}		discard_queue(&bcs->rqueue);		discard_queue(&bcs->squeue);		if (bcs->tx_skb) {			dev_kfree_skb(bcs->tx_skb, FREE_WRITE);			bcs->tx_skb = NULL;			test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);			if (bcs->cs->debug & L1_DEB_HSCX)				debugl1(bcs->cs, "closeisar clear BC_FLG_BUSY");		}	}}intopen_isarstate(struct IsdnCardState *cs, struct BCState *bcs){	if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {		if (!(bcs->hw.isar.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) {			printk(KERN_WARNING			       "HiSax: No memory for isar.rcvbuf\n");			return (1);		}		skb_queue_head_init(&bcs->rqueue);		skb_queue_head_init(&bcs->squeue);	}	bcs->tx_skb = NULL;	test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);	if (cs->debug & L1_DEB_HSCX)		debugl1(cs, "openisar clear BC_FLG_BUSY");	bcs->event = 0;	bcs->hw.isar.rcvidx = 0;	bcs->tx_cnt = 0;	return (0);}intsetstack_isar(struct PStack *st, struct BCState *bcs){	bcs->channel = st->l1.bc;	if (open_isarstate(st->l1.hardware, bcs))		return (-1);	st->l1.bcs = bcs;	st->l2.l2l1 = isar_l2l1;	setstack_manager(st);	bcs->st = st;	setstack_l1_B(st);	return (0);}HISAX_INITFUNC(void initisar(struct IsdnCardState *cs)){	cs->bcs[0].BC_SetStack = setstack_isar;	cs->bcs[1].BC_SetStack = setstack_isar;	cs->bcs[0].BC_Close = close_isarstate;	cs->bcs[1].BC_Close = close_isarstate;}

⌨️ 快捷键说明

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