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

📄 tor2.c

📁 This a SOFTWARE pbx DRIVER
💻 C
📖 第 1 页 / 共 3 页
字号:
			return -ENOSYS;		    default:			printk("Tor2: Unknown maint command: %d\n", cmd);			break;		}		return 0;	}	switch(cmd) {    case ZT_MAINT_NONE:	t1out(p->tor,tspan,0x19,(japan ? 0x80 : 0x00)); /* no local loop */	t1out(p->tor,tspan,0x0a,0); /* no remote loop */	break;    case ZT_MAINT_LOCALLOOP:	t1out(p->tor,tspan,0x19,0x40 | (japan ? 0x80 : 0x00)); /* local loop */	t1out(p->tor,tspan,0x0a,0); /* no remote loop */	break;    case ZT_MAINT_REMOTELOOP:	t1out(p->tor,tspan,0x1e,(japan ? 0x80 : 0x00)); /* no local loop */	t1out(p->tor,tspan,0x0a,0x40); /* remote loop */	break;    case ZT_MAINT_LOOPUP:	t1out(p->tor,tspan,0x30,2); /* send loopup code */	t1out(p->tor,tspan,0x12,0x22); /* send loopup code */	t1out(p->tor,tspan,0x13,0x80); /* send loopup code */	break;    case ZT_MAINT_LOOPDOWN:	t1out(p->tor,tspan,0x30,2); /* send loopdown code */	t1out(p->tor,tspan,0x12,0x62); /* send loopdown code */	t1out(p->tor,tspan,0x13,0x90); /* send loopdown code */	break;    case ZT_MAINT_LOOPSTOP:	t1out(p->tor,tspan,0x30,0);	/* stop sending loopup code */	break;    default:	printk("Tor2: Unknown maint command: %d\n", cmd);	break;   }    return 0;}static inline void tor2_run(struct tor2 *tor){	int x,y;	for (x = 0; x < SPANS_PER_CARD; x++) {		if (tor->spans[x].flags & ZT_FLAG_RUNNING) {			/* since the Tormenta 2 PCI is double-buffered, you			   need to delay the transmit data 2 entire chunks so			   that the transmit will be in sync with the receive */			for (y=0;y<tor->spans[x].channels;y++) {				zt_ec_chunk(&tor->spans[x].chans[y], 				    tor->spans[x].chans[y].readchunk, 					tor->ec_chunk2[x][y]);				memcpy(tor->ec_chunk2[x][y],tor->ec_chunk1[x][y],					ZT_CHUNKSIZE);				memcpy(tor->ec_chunk1[x][y],					tor->spans[x].chans[y].writechunk,						ZT_CHUNKSIZE);			}			zt_receive(&tor->spans[x]);		}	}	for (x = 0; x < SPANS_PER_CARD; x++) {		if (tor->spans[x].flags & ZT_FLAG_RUNNING)			zt_transmit(&tor->spans[x]);	}}#ifdef ENABLE_TASKLETSstatic void tor2_tasklet(unsigned long data){	struct tor2 *tor = (struct tor2 *)data;	tor->taskletrun++;	if (tor->taskletpending) {		tor->taskletexec++;		tor2_run(tor);	}	tor->taskletpending = 0;}#endifstatic int syncsrc = 0;static int syncnum = 0 /* -1 */;static int syncspan = 0;static spinlock_t synclock = SPIN_LOCK_UNLOCKED;static int tor2_findsync(struct tor2 *tor){	int i;	int x;	unsigned long flags;	int p;	int nonzero;	int newsyncsrc = 0;			/* Zaptel span number */	int newsyncnum = 0;			/* tor2 card number */	int newsyncspan = 0;		/* span on given tor2 card */	spin_lock_irqsave(&synclock, flags);#if 1	if (!tor->num) {		/* If we're the first card, go through all the motions, up to 8 levels		   of sync source */		p = 1;		while (p < 8) {			nonzero = 0;			for (x=0;cards[x];x++) {				for (i = 0; i < SPANS_PER_CARD; i++) {					if (cards[x]->syncpos[i]) {						nonzero = 1;						if ((cards[x]->syncpos[i] == p) &&						    !(cards[x]->spans[i].alarms & (ZT_ALARM_RED | ZT_ALARM_BLUE | ZT_ALARM_LOOPBACK)) &&							(cards[x]->spans[i].flags & ZT_FLAG_RUNNING)) {								/* This makes a good sync source */								newsyncsrc = cards[x]->spans[i].spanno;								newsyncnum = x;								newsyncspan = i + 1;								/* Jump out */								goto found;						}					}				}					}			if (nonzero)				p++;			else 				break;		}found:				if ((syncnum != newsyncnum) || (syncsrc != newsyncsrc) || (newsyncspan != syncspan)) {			syncnum = newsyncnum;			syncsrc = newsyncsrc;			syncspan = newsyncspan;			if (debug) printk("New syncnum: %d, syncsrc: %d, syncspan: %d\n", syncnum, syncsrc, syncspan);		}	}#endif		/* update sync src info */	if (tor->syncsrc != syncsrc) {		tor->syncsrc = syncsrc;		/* Update sync sources */		for (i = 0; i < SPANS_PER_CARD; i++) {			tor->spans[i].syncsrc = tor->syncsrc;		}		if (syncnum == tor->num) {#if 1			/* actually set the sync register */			tor->mem8[SYNCREG] = syncspan;#endif						if (debug) printk("Card %d, using sync span %d, master\n", tor->num, syncspan);			tor->master = MASTER;			} else {#if 1			/* time from the timing cable */			tor->mem8[SYNCREG] = SYNCEXTERN;#endif						tor->master = 0;			if (debug) printk("Card %d, using Timing Bus, NOT master\n", tor->num);			}	}	spin_unlock_irqrestore(&synclock, flags);	return 0;}#ifdef LINUX26static irqreturn_t tor2_intr(int irq, void *dev_id, struct pt_regs *regs)#elsestatic void tor2_intr(int irq, void *dev_id, struct pt_regs *regs)#endif{	int n, i, j, k, syncsrc;	unsigned long rxword,txword;	unsigned char c, rxc;	unsigned char abits, bbits;	struct tor2 *tor = (struct tor2 *) dev_id;		  /* make sure its a real interrupt for us */	if (!(tor->mem8[STATREG] & INTACTIVE)) /* if not, just return */	   {#ifdef LINUX26		return IRQ_NONE;#else		return; #endif			   }	if (tor->cardtype == TYPE_E1)		  /* set outbit, interrupt enable, and ack interrupt */		tor->mem8[CTLREG] = OUTBIT | INTENA | INTACK | E1DIV | tor->master;	else		  /* set outbit, interrupt enable, and ack interrupt */		tor->mem8[CTLREG] = OUTBIT | INTENA | INTACK | tor->master;#if	0	if (!tor->passno)		printk("Interrupt handler\n");#endif	/* do the transmit output */	for (n = 0; n < tor->spans[0].channels; n++) {		for (i = 0; i < ZT_CHUNKSIZE; i++) {			/* span 1 */			txword = tor->spans[0].chans[n].writechunk[i] << 24;			/* span 2 */			txword |= tor->spans[1].chans[n].writechunk[i] << 16;			/* span 3 */			txword |= tor->spans[2].chans[n].writechunk[i] << 8;			/* span 4 */			txword |= tor->spans[3].chans[n].writechunk[i];			/* write to part */			tor->mem32[tor->datxlt[n] + (32 * i)] = cpu_to_le32(txword);		}	}	/* Do the receive input */	for (n = 0; n < tor->spans[0].channels; n++) {		for (i = 0; i < ZT_CHUNKSIZE; i++) {			/* read from */			rxword = le32_to_cpu(tor->mem32[tor->datxlt[n] + (32 * i)]);			/* span 1 */			tor->spans[0].chans[n].readchunk[i] = rxword >> 24;			/* span 2 */			tor->spans[1].chans[n].readchunk[i] = (rxword & 0xff0000) >> 16;			/* span 3 */			tor->spans[2].chans[n].readchunk[i] = (rxword & 0xff00) >> 8;			/* span 4 */			tor->spans[3].chans[n].readchunk[i] = rxword & 0xff;		}	}	i = tor->passno & 15;	/* if an E1 card, do rx signalling for it */	if ((i < 3) && (tor->cardtype == TYPE_E1)) { /* if an E1 card */		for (j = (i * 5); j < (i * 5) + 5; j++) {			for (k = 1; k <= SPANS_PER_CARD; k++) {				c = t1in(tor,k,0x31 + j);				rxc = c & 15;				if (rxc != tor->spans[k - 1].chans[j + 16].rxsig) {					/* Check for changes in received bits */					if (!(tor->spans[k - 1].chans[j + 16].sig & ZT_SIG_CLEAR))						zt_rbsbits(&tor->spans[k - 1].chans[j + 16], rxc);				}				rxc = c >> 4;				if (rxc != tor->spans[k - 1].chans[j].rxsig) {					/* Check for changes in received bits */					if (!(tor->spans[k - 1].chans[j].sig & ZT_SIG_CLEAR))						zt_rbsbits(&tor->spans[k - 1].chans[j], rxc);				}			}		}	}	  /* if a T1, do the signalling */	if ((i < 12) && (tor->cardtype == TYPE_T1)) {		k = (i / 3);	/* get span */		n = (i % 3);	/* get base */		abits = t1in(tor,k + 1, 0x60 + n);		bbits = t1in(tor,k + 1, 0x63 + n);		for (j=0; j< 8; j++) {			/* Get channel number */			i = (n * 8) + j;			rxc = 0;			if (abits & (1 << j)) rxc |= ZT_ABIT;			if (bbits & (1 << j)) rxc |= ZT_BBIT;			if (tor->spans[k].chans[i].rxsig != rxc) {				/* Check for changes in received bits */				if (!(tor->spans[k].chans[i].sig & ZT_SIG_CLEAR)) {					zt_rbsbits(&tor->spans[k].chans[i], rxc);				}			}		}	}	for (i = 0; i < SPANS_PER_CARD; i++) { /* Go thru all the spans */		  /* if alarm timer, and it's timed out */		if (tor->alarmtimer[i]) {			if (!--tor->alarmtimer[i]) {				  /* clear recover status */				tor->spans[i].alarms &= ~ZT_ALARM_RECOVER;				if (tor->cardtype == TYPE_E1)					t1out(tor,i + 1,0x21,0x5f); /* turn off yel */				else 					t1out(tor,i + 1,0x35,0x10); /* turn off yel */				zt_alarm_notify(&tor->spans[i]);  /* let them know */			   }		}	}	i = tor->passno & 15;	if ((i >= 10) && (i <= 13) && !(tor->passno & 0x30))	   {		j = 0;  /* clear this alarm status */		i -= 10;		if (tor->cardtype == TYPE_T1) {			c = t1in(tor,i + 1,0x31); /* get RIR2 */			tor->spans[i].rxlevel = c >> 6;  /* get rx level */			t1out(tor,i + 1,0x20,0xff); 			c = t1in(tor,i + 1,0x20);  /* get the status */			  /* detect the code, only if we are not sending one */			if ((!tor->spans[i].mainttimer) && (c & 0x80))  /* if loop-up code detected */			   {				  /* set into remote loop, if not there already */				if ((tor->loopupcnt[i]++ > 80) && 					(tor->spans[i].maintstat != ZT_MAINT_REMOTELOOP))				   {					t1out(tor,i + 1,0x1e,(japan ? 0x80 : 0x00)); /* no local loop */					t1out(tor,i + 1,0x0a,0x40); /* remote loop */					tor->spans[i].maintstat = ZT_MAINT_REMOTELOOP;				   }			   } else tor->loopupcnt[i] = 0;			  /* detect the code, only if we are not sending one */			if ((!tor->spans[i].mainttimer) && (c & 0x40))  /* if loop-down code detected */			   {				  /* if in remote loop, get out of it */				if ((tor->loopdowncnt[i]++ > 80) &&					(tor->spans[i].maintstat == ZT_MAINT_REMOTELOOP))				   {					t1out(tor,i + 1,0x1e,(japan ? 0x80 : 0x00)); /* no local loop */					t1out(tor,i + 1,0x0a,0); /* no remote loop */					tor->spans[i].maintstat = ZT_MAINT_NONE;				   }			   } else tor->loopdowncnt[i] = 0;			if (c & 3) /* if red alarm */			   {				j |= ZT_ALARM_RED;			   }			if (c & 8) /* if blue alarm */			   {				j |= ZT_ALARM_BLUE;			   }		} else { /* its an E1 card */			t1out(tor,i + 1,6,0xff); 			c = t1in(tor,i + 1,6);  /* get the status */			if (c & 9) /* if red alarm */			   {				j |= ZT_ALARM_RED;			   }			if (c & 2) /* if blue alarm */			   {				j |= ZT_ALARM_BLUE;			   }		}		  /* only consider previous carrier alarm state */		tor->spans[i].alarms &= (ZT_ALARM_RED | ZT_ALARM_BLUE | ZT_ALARM_NOTOPEN);		n = 1; /* set to 1 so will not be in yellow alarm if we dont			care about open channels */		  /* if to have yellow alarm if nothing open */		if (tor->spans[i].lineconfig & ZT_CONFIG_NOTOPEN)		   {			  /* go thru all chans, and count # open */			for (n = 0,k = 0; k < tor->spans[i].channels; k++) 			   {				if (((tor->chans[i] + k)->flags & ZT_FLAG_OPEN) ||				    ((tor->chans[i] + k)->flags & ZT_FLAG_NETDEV)) n++;			   }			  /* if none open, set alarm condition */			if (!n) j |= ZT_ALARM_NOTOPEN; 		   }		  /* if no more alarms, and we had some */		if ((!j) && tor->spans[i].alarms)		   {			tor->alarmtimer[i] = ZT_ALARMSETTLE_TIME; 		   }		if (tor->alarmtimer[i]) j |= ZT_ALARM_RECOVER;		  /* if going into alarm state, set yellow alarm */		if ((j) && (!tor->spans[i].alarms)) {			if (tor->cardtype == TYPE_E1)				t1out(tor,i + 1,0x21,0x7f);			else				t1out(tor,i + 1,0x35,0x11);		}		if (c & 4) /* if yellow alarm */			j |= ZT_ALARM_YELLOW;		if (tor->spans[i].maintstat || tor->spans[i].mainttimer) j |= ZT_ALARM_LOOPBACK;		tor->spans[i].alarms = j;		c = (LEDRED | LEDGREEN) << (2 * i);		tor->leds &= ~c;  /* mask out bits for this span */		/* light LED's if span configured and running */		if (tor->spans[i].flags & ZT_FLAG_RUNNING) {			if (j & ZT_ALARM_RED) tor->leds |= LEDRED << (2 * i);			else if (j & ZT_ALARM_YELLOW) tor->leds |= (LEDRED | LEDGREEN) << (2 * i);			else tor->leds |= LEDGREEN << (2 * i);		}		tor->mem8[LEDREG] = tor->leds;		zt_alarm_notify(&tor->spans[i]);	   }	if (!(tor->passno % 1000)) /* even second boundary */	   {		  /* do all spans */		for (i = 1; i <= SPANS_PER_CARD; i++)		   {			if (tor->cardtype == TYPE_E1)			{				   /* add this second's BPV count to total one */				tor->spans[i - 1].bpvcount += t1in(tor,i,1) + (t1in(tor,i,0) << 8);				if (tor->spans[i - 1].lineconfig & ZT_CONFIG_CRC4)				{					tor->spans[i - 1].crc4count += t1in(tor,i,3) + ((t1in(tor,i,2) & 3) << 8);					tor->spans[i - 1].ebitcount += t1in(tor,i,5) + ((t1in(tor,i,4) & 3) << 8);				}                                tor->spans[i - 1].fascount += (t1in(tor,i,4) >> 2) + ((t1in(tor,i,2) & 0x3F) << 6);			}			else			{				   /* add this second's BPV count to total one */				tor->spans[i - 1].bpvcount += t1in(tor,i,0x24) + (t1in(tor,i,0x23) << 8);			}		   }	   }	if (!timingcable) {		/* re-evaluate active sync src (no cable version) */		tor->syncsrc = 0;		syncsrc = 0;		  /* if primary sync specified, see if we can use it */		if (tor->psyncs[0])		   {			  /* if no alarms, use it */			if (!(tor->spans[tor->psyncs[0] - 1].alarms & (ZT_ALARM_RED | ZT_ALARM_BLUE | 				ZT_ALARM_LOOPBACK))) {					tor->syncsrc = tor->psyncs[0];					syncsrc = tor->syncs[0];					}		   }		  /* if any others specified, see if we can use them */		for (i = 1; i < SPANS_PER_CARD; i++) {			   /* if we dont have one yet, and there is one specified at this level, see if we can use it */			if ((!tor->syncsrc) && (tor->psyncs[i])) {				  /* if no alarms, use it */				if (!(tor->spans[tor->psyncs[i] - 1].alarms & (ZT_ALARM_RED | ZT_ALARM_BLUE | 					ZT_ALARM_LOOPBACK))) {						tor->syncsrc = tor->psyncs[i];						syncsrc = tor->syncs[i];						}			}		}		/* update sync src info */		for (i = 0; i < SPANS_PER_CARD; i++) tor->spans[i].syncsrc = syncsrc;		/* actually set the sync register */		tor->mem8[SYNCREG] = tor->syncsrc;	} else	/* Timing cable version */		tor2_findsync(tor);	tor->passno++;#ifdef ENABLE_TASKLETS	if (!tor->taskletpending) {		tor->taskletpending = 1;		tor->taskletsched++;		tasklet_hi_schedule(&tor->tor2_tlet);	} else {		tor->txerrors++;	}#else	tor2_run(tor);#endif	/* We are not the timing bus master */	if (tor->cardtype == TYPE_E1)		/* clear OUTBIT and enable interrupts */		tor->mem8[CTLREG] = INTENA | E1DIV | tor->master;	else		/* clear OUTBIT and enable interrupts */		tor->mem8[CTLREG] = INTENA | tor->master;#ifdef LINUX26	return IRQ_RETVAL(1);#endif}static int tor2_ioctl(struct zt_chan *chan, unsigned int cmd, unsigned long data){	switch(cmd) {	default:		return -ENOTTY;	}	return 0;}MODULE_AUTHOR("Mark Spencer");MODULE_DESCRIPTION("Tormenta 2 PCI Quad T1 or E1 Zaptel Driver");#ifdef MODULE_LICENSEMODULE_LICENSE("GPL");#endif#ifdef LINUX26module_param(debug, int, 0600);module_param(loopback, int, 0600);module_param(timingcable, int, 0600);module_param(japan, int, 0600);#elseMODULE_PARM(debug, "i");MODULE_PARM(loopback, "i");MODULE_PARM(timingcable, "i");MODULE_PARM(japan, "i");#endifMODULE_DEVICE_TABLE(pci, tor2_pci_ids);module_init(tor2_init);module_exit(tor2_cleanup);

⌨️ 快捷键说明

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