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

📄 hfc_2bs0.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (idx != bcs->tx_skb->len) {		debugl1(cs, "FIFO Send BUSY error");		printk(KERN_WARNING "HFC S FIFO channel %d BUSY Error\n", bcs->channel);	} else {		count =  bcs->tx_skb->len;		bcs->tx_cnt -= count;		if (PACKET_NOACK == bcs->tx_skb->pkt_type)			count = -1;		dev_kfree_skb_any(bcs->tx_skb);		bcs->tx_skb = NULL;		if (bcs->mode != L1_MODE_TRANS) {		  WaitForBusy(cs);		  WaitNoBusy(cs);		  cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F1_INC | HFC_SEND | HFC_CHANNEL(bcs->channel));		}		if (test_bit(FLG_LLI_L1WAKEUP,&bcs->st->lli.flag) &&			(count >= 0)) {			u_long	flags;			spin_lock_irqsave(&bcs->aclock, flags);			bcs->ackcnt += count;			spin_unlock_irqrestore(&bcs->aclock, flags);			schedule_event(bcs, B_ACKPENDING);		}		test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);	}	return;}voidmain_irq_hfc(struct BCState *bcs){	struct IsdnCardState *cs = bcs->cs;	int z1, z2, rcnt;	u_char f1, f2, cip;	int receive, transmit, count = 5;	struct sk_buff *skb;      Begin:	count--;	cip = HFC_CIP | HFC_F1 | HFC_REC | HFC_CHANNEL(bcs->channel);	if ((cip & 0xc3) != (cs->hw.hfc.cip & 0xc3)) {		cs->BC_Write_Reg(cs, HFC_STATUS, cip, cip);		WaitForBusy(cs);	}	WaitNoBusy(cs);	receive = 0;	if (bcs->mode == L1_MODE_HDLC) {		f1 = cs->BC_Read_Reg(cs, HFC_DATA, cip);		cip = HFC_CIP | HFC_F2 | HFC_REC | HFC_CHANNEL(bcs->channel);		WaitNoBusy(cs);		f2 = cs->BC_Read_Reg(cs, HFC_DATA, cip);		if (f1 != f2) {			if (cs->debug & L1_DEB_HSCX)				debugl1(cs, "hfc rec %d f1(%d) f2(%d)",					bcs->channel, f1, f2);			receive = 1; 		}	}	if (receive || (bcs->mode == L1_MODE_TRANS)) {		WaitForBusy(cs);		z1 = ReadZReg(bcs, HFC_Z1 | HFC_REC | HFC_CHANNEL(bcs->channel));		z2 = ReadZReg(bcs, HFC_Z2 | HFC_REC | HFC_CHANNEL(bcs->channel));		rcnt = z1 - z2;		if (rcnt < 0)			rcnt += cs->hw.hfc.fifosize;		if ((bcs->mode == L1_MODE_HDLC) || (rcnt)) {			rcnt++;			if (cs->debug & L1_DEB_HSCX)				debugl1(cs, "hfc rec %d z1(%x) z2(%x) cnt(%d)",					bcs->channel, z1, z2, rcnt);			/*              sti(); */			if ((skb = hfc_empty_fifo(bcs, rcnt))) {				skb_queue_tail(&bcs->rqueue, skb);				schedule_event(bcs, B_RCVBUFREADY);			}		}		receive = 1;	}	if (bcs->tx_skb) {		transmit = 1;		test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);		hfc_fill_fifo(bcs);		if (test_bit(BC_FLG_BUSY, &bcs->Flag))			transmit = 0;	} else {		if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {			transmit = 1;			test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);			hfc_fill_fifo(bcs);			if (test_bit(BC_FLG_BUSY, &bcs->Flag))				transmit = 0;		} else {			transmit = 0;			schedule_event(bcs, B_XMTBUFREADY);		}	}	if ((receive || transmit) && count)		goto Begin;	return;}static voidmode_hfc(struct BCState *bcs, int mode, int bc){	struct IsdnCardState *cs = bcs->cs;	if (cs->debug & L1_DEB_HSCX)		debugl1(cs, "HFC 2BS0 mode %d bchan %d/%d",			mode, bc, bcs->channel);	bcs->mode = mode;	bcs->channel = bc;	switch (mode) {		case (L1_MODE_NULL):		        if (bc) {				cs->hw.hfc.ctmt &= ~1;				cs->hw.hfc.isac_spcr &= ~0x03;			}			else {				cs->hw.hfc.ctmt &= ~2;				cs->hw.hfc.isac_spcr &= ~0x0c;			}			break;		case (L1_MODE_TRANS):		        cs->hw.hfc.ctmt &= ~(1 << bc); /* set HDLC mode */ 			cs->BC_Write_Reg(cs, HFC_STATUS, cs->hw.hfc.ctmt, cs->hw.hfc.ctmt);			hfc_clear_fifo(bcs); /* complete fifo clear */ 			if (bc) {				cs->hw.hfc.ctmt |= 1;				cs->hw.hfc.isac_spcr &= ~0x03;				cs->hw.hfc.isac_spcr |= 0x02;			} else {				cs->hw.hfc.ctmt |= 2;				cs->hw.hfc.isac_spcr &= ~0x0c;				cs->hw.hfc.isac_spcr |= 0x08;			}			break;		case (L1_MODE_HDLC):			if (bc) {				cs->hw.hfc.ctmt &= ~1;				cs->hw.hfc.isac_spcr &= ~0x03;				cs->hw.hfc.isac_spcr |= 0x02;			} else {				cs->hw.hfc.ctmt &= ~2;				cs->hw.hfc.isac_spcr &= ~0x0c;				cs->hw.hfc.isac_spcr |= 0x08;			}			break;	}	cs->BC_Write_Reg(cs, HFC_STATUS, cs->hw.hfc.ctmt, cs->hw.hfc.ctmt);	cs->writeisac(cs, ISAC_SPCR, cs->hw.hfc.isac_spcr);	if (mode == L1_MODE_HDLC)		hfc_clear_fifo(bcs);}static voidhfc_l2l1(struct PStack *st, int pr, void *arg){	struct BCState	*bcs = st->l1.bcs;	struct sk_buff	*skb = arg;	u_long		flags;	switch (pr) {		case (PH_DATA | REQUEST):			spin_lock_irqsave(&bcs->cs->lock, flags);			if (bcs->tx_skb) {				skb_queue_tail(&bcs->squeue, skb);			} else {				bcs->tx_skb = skb;				test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);				bcs->cs->BC_Send_Data(bcs);			}			spin_unlock_irqrestore(&bcs->cs->lock, flags);			break;		case (PH_PULL | INDICATION):			spin_lock_irqsave(&bcs->cs->lock, flags);			if (bcs->tx_skb) {				printk(KERN_WARNING "hfc_l2l1: this shouldn't happen\n");			} else {				test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);				bcs->tx_skb = skb;				bcs->cs->BC_Send_Data(bcs);			}			spin_unlock_irqrestore(&bcs->cs->lock, flags);			break;		case (PH_PULL | REQUEST):			if (!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):			spin_lock_irqsave(&bcs->cs->lock, flags);			test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag);			mode_hfc(bcs, st->l1.mode, st->l1.bc);			spin_unlock_irqrestore(&bcs->cs->lock, flags);			l1_msg_b(st, pr, arg);			break;		case (PH_DEACTIVATE | REQUEST):			l1_msg_b(st, pr, arg);			break;		case (PH_DEACTIVATE | CONFIRM):			spin_lock_irqsave(&bcs->cs->lock, flags);			test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag);			test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);			mode_hfc(bcs, 0, st->l1.bc);			spin_unlock_irqrestore(&bcs->cs->lock, flags);			st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);			break;	}}static voidclose_hfcstate(struct BCState *bcs){	mode_hfc(bcs, 0, bcs->channel);	if (test_bit(BC_FLG_INIT, &bcs->Flag)) {		skb_queue_purge(&bcs->rqueue);		skb_queue_purge(&bcs->squeue);		if (bcs->tx_skb) {			dev_kfree_skb_any(bcs->tx_skb);			bcs->tx_skb = NULL;			test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);		}	}	test_and_clear_bit(BC_FLG_INIT, &bcs->Flag);}static intopen_hfcstate(struct IsdnCardState *cs, struct BCState *bcs){	if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {		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);	bcs->event = 0;	bcs->tx_cnt = 0;	return (0);}static intsetstack_hfc(struct PStack *st, struct BCState *bcs){	bcs->channel = st->l1.bc;	if (open_hfcstate(st->l1.hardware, bcs))		return (-1);	st->l1.bcs = bcs;	st->l2.l2l1 = hfc_l2l1;	setstack_manager(st);	bcs->st = st;	setstack_l1_B(st);	return (0);}static void __initinit_send(struct BCState *bcs){	int i;	if (!(bcs->hw.hfc.send = kmalloc(32 * sizeof(unsigned int), GFP_ATOMIC))) {		printk(KERN_WARNING		       "HiSax: No memory for hfc.send\n");		return;	}	for (i = 0; i < 32; i++)		bcs->hw.hfc.send[i] = 0x1fff;}void __initinithfc(struct IsdnCardState *cs){	init_send(&cs->bcs[0]);	init_send(&cs->bcs[1]);	cs->BC_Send_Data = &hfc_fill_fifo;	cs->bcs[0].BC_SetStack = setstack_hfc;	cs->bcs[1].BC_SetStack = setstack_hfc;	cs->bcs[0].BC_Close = close_hfcstate;	cs->bcs[1].BC_Close = close_hfcstate;	mode_hfc(cs->bcs, 0, 0);	mode_hfc(cs->bcs + 1, 0, 0);}voidreleasehfc(struct IsdnCardState *cs){	kfree(cs->bcs[0].hw.hfc.send);	cs->bcs[0].hw.hfc.send = NULL;	kfree(cs->bcs[1].hw.hfc.send);	cs->bcs[1].hw.hfc.send = NULL;}

⌨️ 快捷键说明

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