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

📄 hfc_pci.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 4 页
字号:
				cs->hw.hfcpci.fifo_en &= ~HFCPCI_FIFOEN_B1;				cs->hw.hfcpci.int_m1 &= ~(HFCPCI_INTS_B1TRANS + HFCPCI_INTS_B1REC);			}			break;		case (L1_MODE_TRANS):		        hfcpci_clear_fifo_rx(cs, fifo2);		        hfcpci_clear_fifo_tx(cs, fifo2);			if (bc) {				cs->hw.hfcpci.sctrl |= SCTRL_B2_ENA;				cs->hw.hfcpci.sctrl_r |= SCTRL_B2_ENA;			} else {				cs->hw.hfcpci.sctrl |= SCTRL_B1_ENA;				cs->hw.hfcpci.sctrl_r |= SCTRL_B1_ENA;			}			if (fifo2) {				cs->hw.hfcpci.fifo_en |= HFCPCI_FIFOEN_B2;				cs->hw.hfcpci.int_m1 |= (HFCPCI_INTS_B2TRANS + HFCPCI_INTS_B2REC);				cs->hw.hfcpci.ctmt |= 2;				cs->hw.hfcpci.conn &= ~0x18;			} else {				cs->hw.hfcpci.fifo_en |= HFCPCI_FIFOEN_B1;				cs->hw.hfcpci.int_m1 |= (HFCPCI_INTS_B1TRANS + HFCPCI_INTS_B1REC);				cs->hw.hfcpci.ctmt |= 1;				cs->hw.hfcpci.conn &= ~0x03;			}			break;		case (L1_MODE_HDLC):		        hfcpci_clear_fifo_rx(cs, fifo2);		        hfcpci_clear_fifo_tx(cs, fifo2);			if (bc) {				cs->hw.hfcpci.sctrl |= SCTRL_B2_ENA;				cs->hw.hfcpci.sctrl_r |= SCTRL_B2_ENA;			} else {				cs->hw.hfcpci.sctrl |= SCTRL_B1_ENA;				cs->hw.hfcpci.sctrl_r |= SCTRL_B1_ENA;			}			if (fifo2) {			        cs->hw.hfcpci.last_bfifo_cnt[1] = 0;  				cs->hw.hfcpci.fifo_en |= HFCPCI_FIFOEN_B2;				cs->hw.hfcpci.int_m1 |= (HFCPCI_INTS_B2TRANS + HFCPCI_INTS_B2REC);				cs->hw.hfcpci.ctmt &= ~2;				cs->hw.hfcpci.conn &= ~0x18;			} else {			        cs->hw.hfcpci.last_bfifo_cnt[0] = 0;  				cs->hw.hfcpci.fifo_en |= HFCPCI_FIFOEN_B1;				cs->hw.hfcpci.int_m1 |= (HFCPCI_INTS_B1TRANS + HFCPCI_INTS_B1REC);				cs->hw.hfcpci.ctmt &= ~1;				cs->hw.hfcpci.conn &= ~0x03;			}			break;		case (L1_MODE_EXTRN):			if (bc) {				cs->hw.hfcpci.conn |= 0x10;				cs->hw.hfcpci.sctrl |= SCTRL_B2_ENA;				cs->hw.hfcpci.sctrl_r |= SCTRL_B2_ENA;				cs->hw.hfcpci.fifo_en &= ~HFCPCI_FIFOEN_B2;				cs->hw.hfcpci.int_m1 &= ~(HFCPCI_INTS_B2TRANS + HFCPCI_INTS_B2REC);			} else {				cs->hw.hfcpci.conn |= 0x02;				cs->hw.hfcpci.sctrl |= SCTRL_B1_ENA;				cs->hw.hfcpci.sctrl_r |= SCTRL_B1_ENA;				cs->hw.hfcpci.fifo_en &= ~HFCPCI_FIFOEN_B1;				cs->hw.hfcpci.int_m1 &= ~(HFCPCI_INTS_B1TRANS + HFCPCI_INTS_B1REC);			}			break;	}	Write_hfc(cs, HFCPCI_SCTRL_E, cs->hw.hfcpci.sctrl_e);	Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1);	Write_hfc(cs, HFCPCI_FIFO_EN, cs->hw.hfcpci.fifo_en);	Write_hfc(cs, HFCPCI_SCTRL, cs->hw.hfcpci.sctrl);	Write_hfc(cs, HFCPCI_SCTRL_R, cs->hw.hfcpci.sctrl_r);	Write_hfc(cs, HFCPCI_CTMT, cs->hw.hfcpci.ctmt);	Write_hfc(cs, HFCPCI_CONNECT, cs->hw.hfcpci.conn);}/******************************//* Layer2 -> Layer 1 Transfer *//******************************/static voidhfcpci_l2l1(struct PStack *st, int pr, void *arg){	struct BCState	*bcs = st->l1.bcs;	u_long		flags;	struct sk_buff	*skb = arg;	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) {				spin_unlock_irqrestore(&bcs->cs->lock, flags);				printk(KERN_WARNING "hfc_l2l1: this shouldn't happen\n");				break;			}//			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_hfcpci(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_hfcpci(bcs, 0, st->l1.bc);			spin_unlock_irqrestore(&bcs->cs->lock, flags);			st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);			break;	}}/******************************************//* deactivate B-channel access and queues *//******************************************/static voidclose_hfcpci(struct BCState *bcs){	mode_hfcpci(bcs, 0, bcs->channel);	if (test_and_clear_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);		}	}}/*************************************//* init B-channel queues and control *//*************************************/static intopen_hfcpcistate(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);}/*********************************//* inits the stack for B-channel *//*********************************/static intsetstack_2b(struct PStack *st, struct BCState *bcs){	bcs->channel = st->l1.bc;	if (open_hfcpcistate(st->l1.hardware, bcs))		return (-1);	st->l1.bcs = bcs;	st->l2.l2l1 = hfcpci_l2l1;	setstack_manager(st);	bcs->st = st;	setstack_l1_B(st);	return (0);}/***************************//* handle L1 state changes *//***************************/static voidhfcpci_bh(struct IsdnCardState *cs){	u_long	flags;//      struct PStack *stptr;	if (!cs)		return;	if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) {		if (!cs->hw.hfcpci.nt_mode)			switch (cs->dc.hfcpci.ph_state) {				case (0):					l1_msg(cs, HW_RESET | INDICATION, NULL);					break;				case (3):					l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL);					break;				case (8):					l1_msg(cs, HW_RSYNC | INDICATION, NULL);					break;				case (6):					l1_msg(cs, HW_INFO2 | INDICATION, NULL);					break;				case (7):					l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL);					break;				default:					break;		} else {			spin_lock_irqsave(&cs->lock, flags);			switch (cs->dc.hfcpci.ph_state) {				case (2):					if (cs->hw.hfcpci.nt_timer < 0) {						cs->hw.hfcpci.nt_timer = 0;						cs->hw.hfcpci.int_m1 &= ~HFCPCI_INTS_TIMER;						Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1);						/* Clear already pending ints */						if (Read_hfc(cs, HFCPCI_INT_S1));						Write_hfc(cs, HFCPCI_STATES, 4 | HFCPCI_LOAD_STATE);						udelay(10);						Write_hfc(cs, HFCPCI_STATES, 4);						cs->dc.hfcpci.ph_state = 4;					} else {						cs->hw.hfcpci.int_m1 |= HFCPCI_INTS_TIMER;						Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1);						cs->hw.hfcpci.ctmt &= ~HFCPCI_AUTO_TIMER;						cs->hw.hfcpci.ctmt |= HFCPCI_TIM3_125;						Write_hfc(cs, HFCPCI_CTMT, cs->hw.hfcpci.ctmt | HFCPCI_CLTIMER);						Write_hfc(cs, HFCPCI_CTMT, cs->hw.hfcpci.ctmt | HFCPCI_CLTIMER);						cs->hw.hfcpci.nt_timer = NT_T1_COUNT;						Write_hfc(cs, HFCPCI_STATES, 2 | HFCPCI_NT_G2_G3);	/* allow G2 -> G3 transition */					}					break;				case (1):				case (3):				case (4):					cs->hw.hfcpci.nt_timer = 0;					cs->hw.hfcpci.int_m1 &= ~HFCPCI_INTS_TIMER;					Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1);					break;				default:					break;			}			spin_unlock_irqrestore(&cs->lock, flags);		}	}	if (test_and_clear_bit(D_RCVBUFREADY, &cs->event))		DChannel_proc_rcv(cs);	if (test_and_clear_bit(D_XMTBUFREADY, &cs->event))		DChannel_proc_xmt(cs);}/********************************//* called for card init message *//********************************/static void __initinithfcpci(struct IsdnCardState *cs){	cs->bcs[0].BC_SetStack = setstack_2b;	cs->bcs[1].BC_SetStack = setstack_2b;	cs->bcs[0].BC_Close = close_hfcpci;	cs->bcs[1].BC_Close = close_hfcpci;	cs->dbusytimer.function = (void *) hfcpci_dbusy_timer;	cs->dbusytimer.data = (long) cs;	init_timer(&cs->dbusytimer);	mode_hfcpci(cs->bcs, 0, 0);	mode_hfcpci(cs->bcs + 1, 0, 1);}/*******************************************//* handle card messages from control layer *//*******************************************/static inthfcpci_card_msg(struct IsdnCardState *cs, int mt, void *arg){	u_long flags;	if (cs->debug & L1_DEB_ISAC)		debugl1(cs, "HFCPCI: card_msg %x", mt);	switch (mt) {		case CARD_RESET:			spin_lock_irqsave(&cs->lock, flags);			reset_hfcpci(cs);			spin_unlock_irqrestore(&cs->lock, flags);			return (0);		case CARD_RELEASE:			release_io_hfcpci(cs);			return (0);		case CARD_INIT:			spin_lock_irqsave(&cs->lock, flags);			inithfcpci(cs);			reset_hfcpci(cs);			spin_unlock_irqrestore(&cs->lock, flags);			msleep(80);				/* Timeout 80ms */			/* now switch timer interrupt off */			spin_lock_irqsave(&cs->lock, flags);			cs->hw.hfcpci.int_m1 &= ~HFCPCI_INTS_TIMER;			Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1);			/* reinit mode reg */			Write_hfc(cs, HFCPCI_MST_MODE, cs->hw.hfcpci.mst_m);			spin_unlock_irqrestore(&cs->lock, flags);			return (0);		case CARD_TEST:			return (0);	}	return (0);}/* this variable is used as card index when more than one cards are present */static struct pci_dev *dev_hfcpci __initdata = NULL;#endif				/* CONFIG_PCI */int __initsetup_hfcpci(struct IsdnCard *card){	u_long flags;	struct IsdnCardState *cs = card->cs;	char tmp[64];	int i;	struct pci_dev *tmp_hfcpci = NULL;#ifdef __BIG_ENDIAN#error "not running on big endian machines now"#endif	strcpy(tmp, hfcpci_revision);	printk(KERN_INFO "HiSax: HFC-PCI driver Rev. %s\n", HiSax_getrev(tmp));#ifdef CONFIG_PCI	cs->hw.hfcpci.int_s1 = 0;	cs->dc.hfcpci.ph_state = 0;	cs->hw.hfcpci.fifo = 255;	if (cs->typ == ISDN_CTYPE_HFC_PCI) {		i = 0;		while (id_list[i].vendor_id) {			tmp_hfcpci = pci_find_device(id_list[i].vendor_id,						     id_list[i].device_id,						     dev_hfcpci);			i++;			if (tmp_hfcpci) {				if (pci_enable_device(tmp_hfcpci))					continue;				pci_set_master(tmp_hfcpci);				if ((card->para[0]) && (card->para[0] != (tmp_hfcpci->resource[ 0].start & PCI_BASE_ADDRESS_IO_MASK)))					continue;				else					break;			}		}		if (tmp_hfcpci) {			i--;			dev_hfcpci = tmp_hfcpci;	/* old device */			cs->hw.hfcpci.dev = dev_hfcpci;			cs->irq = dev_hfcpci->irq;			if (!cs->irq) {				printk(KERN_WARNING "HFC-PCI: No IRQ for PCI card found\n");				return (0);			}			cs->hw.hfcpci.pci_io = (char *) dev_hfcpci->resource[ 1].start;			printk(KERN_INFO "HiSax: HFC-PCI card manufacturer: %s card name: %s\n", id_list[i].vendor_name, id_list[i].card_name);		} else {			printk(KERN_WARNING "HFC-PCI: No PCI card found\n");			return (0);		}		if (!cs->hw.hfcpci.pci_io) {			printk(KERN_WARNING "HFC-PCI: No IO-Mem for PCI card found\n");			return (0);		}		/* Allocate memory for FIFOS */		/* Because the HFC-PCI needs a 32K physical alignment, we */		/* need to allocate the double mem and align the address */		if (!(cs->hw.hfcpci.share_start = kmalloc(65536, GFP_KERNEL))) {			printk(KERN_WARNING "HFC-PCI: Error allocating memory for FIFO!\n");			return 0;		}		cs->hw.hfcpci.fifos = (void *)		    (((ulong) cs->hw.hfcpci.share_start) & ~0x7FFF) + 0x8000;		pci_write_config_dword(cs->hw.hfcpci.dev, 0x80, (u_int) virt_to_bus(cs->hw.hfcpci.fifos));		cs->hw.hfcpci.pci_io = ioremap((ulong) cs->hw.hfcpci.pci_io, 256);		printk(KERN_INFO		       "HFC-PCI: defined at mem %#x fifo %#x(%#x) IRQ %d HZ %d\n",		       (u_int) cs->hw.hfcpci.pci_io,		       (u_int) cs->hw.hfcpci.fifos,		       (u_int) virt_to_bus(cs->hw.hfcpci.fifos),		       cs->irq, HZ);		spin_lock_irqsave(&cs->lock, flags);		pci_write_config_word(cs->hw.hfcpci.dev, PCI_COMMAND, PCI_ENA_MEMIO);	/* enable memory mapped ports, disable busmaster */		cs->hw.hfcpci.int_m2 = 0;	/* disable alle interrupts */		cs->hw.hfcpci.int_m1 = 0;		Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1);		Write_hfc(cs, HFCPCI_INT_M2, cs->hw.hfcpci.int_m2);		/* At this point the needed PCI config is done */		/* fifos are still not enabled */		INIT_WORK(&cs->tqueue, (void *)(void *) hfcpci_bh, cs);		cs->setstack_d = setstack_hfcpci;		cs->BC_Send_Data = &hfcpci_send_data;		cs->readisac = NULL;		cs->writeisac = NULL;		cs->readisacfifo = NULL;		cs->writeisacfifo = NULL;		cs->BC_Read_Reg = NULL;		cs->BC_Write_Reg = NULL;		cs->irq_func = &hfcpci_interrupt;		cs->irq_flags |= SA_SHIRQ;		cs->hw.hfcpci.timer.function = (void *) hfcpci_Timer;		cs->hw.hfcpci.timer.data = (long) cs;		init_timer(&cs->hw.hfcpci.timer);		cs->cardmsg = &hfcpci_card_msg;		cs->auxcmd = &hfcpci_auxcmd;		spin_unlock_irqrestore(&cs->lock, flags);		return (1);	} else		return (0);	/* no valid card type */#else	printk(KERN_WARNING "HFC-PCI: NO_PCI_BIOS\n");	return (0);#endif				/* CONFIG_PCI */}

⌨️ 快捷键说明

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