亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關(guān)于我們
? 蟲蟲下載站

?? wcfxo.c

?? This a SOFTWARE pbx DRIVER
?? C
?? 第 1 頁 / 共 2 頁
字號(hào):
/* * Wilcard X100P FXO Interface Driver for Zapata Telephony interface * * Written by Mark Spencer <markster@linux-support.net> *            Matthew Fredrickson <creslin@linux-support.net> * * Copyright (C) 2001, Linux Support Services, Inc. * * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */#include <linux/kernel.h>#include <linux/errno.h>#include <linux/module.h>#include <linux/init.h>#include <linux/usb.h>#include <linux/errno.h>#include <linux/pci.h>#ifdef STANDALONE_ZAPATA#include "zaptel.h"#else#include <linux/zaptel.h>#endif#ifdef LINUX26#include <linux/moduleparam.h>#endif/* Uncomment to enable tasklet handling in the FXO driver.  Not recommended   in general, but may improve interactive performance *//* #define ENABLE_TASKLETS *//* Un-comment the following for POTS line support for Japan *//* #define	JAPAN *//* Un-comment for lines (eg from and ISDN TA) that remove *//* phone power during ringing                             *//* #define ZERO_BATT_RING */#define WC_MAX_IFACES 128#define WC_CNTL    	0x00#define WC_OPER		0x01#define WC_AUXC    	0x02#define WC_AUXD    	0x03#define WC_MASK0   	0x04#define WC_MASK1   	0x05#define WC_INTSTAT 	0x06#define WC_DMAWS	0x08#define WC_DMAWI	0x0c#define WC_DMAWE	0x10#define WC_DMARS	0x18#define WC_DMARI	0x1c#define WC_DMARE	0x20#define WC_AUXFUNC	0x2b#define WC_SERCTL	0x2d#define WC_FSCDELAY	0x2f#define FLAG_EMPTY	0#define FLAG_WRITE	1#define FLAG_READ	2#ifdef 	ZERO_BATT_RING			/* Need to debounce Off/On hook too */#define	JAPAN#endif#define RING_DEBOUNCE	64		/* Ringer Debounce (in ms) */#ifdef	JAPAN#define BATT_DEBOUNCE	30		/* Battery debounce (in ms) */#define OH_DEBOUNCE	350		/* Off/On hook debounce (in ms) */#else#define BATT_DEBOUNCE	80		/* Battery debounce (in ms) */#endif#define MINPEGTIME	10 * 8		/* 30 ms peak to peak gets us no more than 100 Hz */#define PEGTIME		50 * 8		/* 50ms peak to peak gets us rings of 10 Hz or more */#define PEGCOUNT	5		/* 5 cycles of pegging means RING */struct reg {	unsigned long flags;	unsigned char index;	unsigned char reg;	unsigned char value;};static int wecareregs[] = { 5, 6, 9, 11, 12, 13, 17, 19, };struct wcfxo {	struct pci_dev *dev;	char *variety;	struct zt_span span;	struct zt_chan chan;	int usecount;	int dead;	int pos;	unsigned long flags;	int freeregion;	int ring;	int offhook;	int battery;	int wregcount;	int readpos;	int rreadpos;	unsigned int pegtimer;	int pegcount;	int peg;	int battdebounce;	int nobatttimer;	int ringdebounce;#ifdef	JAPAN	int ohdebounce;#endif	int allread;	int regoffset;			/* How far off our registers are from what we expect */	int alt;	int ignoreread;	int reset;	/* Up to 6 register can be written at a time */	struct reg regs[ZT_CHUNKSIZE];	struct reg oldregs[ZT_CHUNKSIZE];	unsigned char lasttx[ZT_CHUNKSIZE];	/* Up to 32 registers of whatever we most recently read */	unsigned char readregs[32];	unsigned long ioaddr;	dma_addr_t 	readdma;	dma_addr_t	writedma;	volatile int *writechunk;					/* Double-word aligned write memory */	volatile int *readchunk;					/* Double-word aligned read memory */#ifdef ZERO_BATT_RING	int onhook;#endif#ifdef ENABLE_TASKLETS	int taskletrun;	int taskletsched;	int taskletpending;	int taskletexec;	int txerrors;	int ints;	struct tasklet_struct wcfxo_tlet;#endif};#define FLAG_INVERTSER		(1 << 0)#define FLAG_USE_XTAL		(1 << 1)#define FLAG_DOUBLE_CLOCK	(1 << 2)#define FLAG_RESET_ON_AUX5	(1 << 3)struct wcfxo_desc {	char *name;	unsigned long flags;};static struct wcfxo_desc wcx100p = { "Wildcard X100P",		FLAG_INVERTSER | FLAG_USE_XTAL | FLAG_DOUBLE_CLOCK };static struct wcfxo_desc wcx101p = { "Wildcard X101P",		FLAG_USE_XTAL | FLAG_DOUBLE_CLOCK };static struct wcfxo_desc generic = { "Generic Clone",		FLAG_USE_XTAL | FLAG_DOUBLE_CLOCK };static struct wcfxo *ifaces[WC_MAX_IFACES];static void wcfxo_release(struct wcfxo *wc);static int debug = 0;static int monitor = 0;static int quiet = 0;static int boost = 0;static int opermode = 0;static struct fxo_mode {	char *name;	int ohs;	int act;	int dct;	int rz;	int rt;	int lim;	int vol;} fxo_modes[] ={	{ "FCC", 0, 0, 2, 0, 0, 0, 0 }, 	/* US */	{ "CTR21", 0, 0, 3, 0, 0, 3, 0 },	/* Austria, Belgium, Denmark, Finland, France, Germany, 										   Greece, Iceland, Ireland, Italy, Luxembourg, Netherlands,										   Norway, Portugal, Spain, Sweden, Switzerland, and UK */};static inline void wcfxo_transmitprep(struct wcfxo *wc, unsigned char ints){	volatile int *writechunk;	int x;	int written=0;	unsigned short cmd;	/* if nothing to transmit, have to do the zt_transmit() anyway */	if (!(ints & 3)) {		/* Calculate Transmission */		zt_transmit(&wc->span);		return;	}	/* Remember what it was we just sent */	memcpy(wc->lasttx, wc->chan.writechunk, ZT_CHUNKSIZE);	if (ints & 0x01)  {		/* Write is at interrupt address.  Start writing from normal offset */		writechunk = wc->writechunk;	} else {		writechunk = wc->writechunk + ZT_CHUNKSIZE * 2;	}	zt_transmit(&wc->span);	for (x=0;x<ZT_CHUNKSIZE;x++) {		/* Send a sample, as a 32-bit word, and be sure to indicate that a command follows */		if (wc->flags & FLAG_INVERTSER)			writechunk[x << 1] = cpu_to_le32(				~((unsigned short)(ZT_XLAW(wc->chan.writechunk[x], (&wc->chan)))| 0x1) << 16				);		else			writechunk[x << 1] = cpu_to_le32(				((unsigned short)(ZT_XLAW(wc->chan.writechunk[x], (&wc->chan)))| 0x1) << 16				);		/* We always have a command to follow our signal */		if (!wc->regs[x].flags) {			/* Fill in an empty register command with a read for a potentially useful register  */			wc->regs[x].flags = FLAG_READ;			wc->regs[x].reg = wecareregs[wc->readpos];			wc->regs[x].index = wc->readpos;			wc->readpos++;			if (wc->readpos >= (sizeof(wecareregs) / sizeof(wecareregs[0]))) {				wc->allread = 1;				wc->readpos = 0;			}		}		/* Prepare the command to follow it */		switch(wc->regs[x].flags) {		case FLAG_READ:			cmd = (wc->regs[x].reg | 0x20) << 8;			break;		case FLAG_WRITE:			cmd = (wc->regs[x].reg << 8) | (wc->regs[x].value & 0xff);			written = 1;			/* Wait at least four samples before reading */			wc->ignoreread = 4;			break;		default:			printk("wcfxo: Huh?  No read or write??\n");			cmd = 0;		}		/* Setup the write chunk */		if (wc->flags & FLAG_INVERTSER)			writechunk[(x << 1) + 1] = cpu_to_le32(~(cmd << 16));		else			writechunk[(x << 1) + 1] = cpu_to_le32(cmd << 16);	}	if (written)		wc->readpos = 0;	wc->wregcount = 0;	for (x=0;x<ZT_CHUNKSIZE;x++) {		/* Rotate through registers */		wc->oldregs[x] = wc->regs[x];		wc->regs[x].flags = FLAG_EMPTY;	}}static inline void wcfxo_receiveprep(struct wcfxo *wc, unsigned char ints){	volatile int *readchunk;	int x;	int realreg;	int realval;	int sample;	if (ints & 0x04)		/* Read is at interrupt address.  Valid data is available at normal offset */		readchunk = wc->readchunk;	else		readchunk = wc->readchunk + ZT_CHUNKSIZE * 2;	/* Keep track of how quickly our peg alternates */	wc->pegtimer+=ZT_CHUNKSIZE;	for (x=0;x<ZT_CHUNKSIZE;x++) {		/* We always have a command to follow our signal.  */		if (wc->oldregs[x].flags == FLAG_READ && !wc->ignoreread) {			realreg = wecareregs[(wc->regs[x].index + wc->regoffset) %							(sizeof(wecareregs) / sizeof(wecareregs[0]))];			realval = (le32_to_cpu(readchunk[(x << 1) +wc->alt]) >> 16) & 0xff;			if ((realval == 0x89) && (realreg != 0x9)) {				/* Some sort of slippage, correct for it */				while(realreg != 0x9) {					/* Find register 9 */					realreg = wecareregs[(wc->regs[x].index + ++wc->regoffset) %										 (sizeof(wecareregs) / sizeof(wecareregs[0]))];					wc->regoffset = wc->regoffset % (sizeof(wecareregs) / sizeof(wecareregs[0]));				}				if (debug)					printk("New regoffset: %d\n", wc->regoffset);			}			/* Receive into the proper register */			wc->readregs[realreg] = realval;		}		/* Look for pegging to indicate ringing */		sample = (short)(le32_to_cpu(readchunk[(x << 1) + (1 - wc->alt)]) >> 16);		if ((sample > 32000) && (wc->peg != 1)) {			if ((wc->pegtimer < PEGTIME) && (wc->pegtimer > MINPEGTIME))				wc->pegcount++;			wc->pegtimer = 0;			wc->peg = 1;		} else if ((sample < -32000) && (wc->peg != -1)) {			if ((wc->pegtimer < PEGTIME) && (wc->pegtimer > MINPEGTIME))				wc->pegcount++;			wc->pegtimer = 0;			wc->peg = -1;		}		wc->chan.readchunk[x] = ZT_LIN2X((sample), (&wc->chan));	}	if (wc->pegtimer > PEGTIME) {		/* Reset pegcount if our timer expires */		wc->pegcount = 0;	}	/* Decrement debouncer if appropriate */	if (wc->ringdebounce)		wc->ringdebounce--;	if (!wc->offhook && !wc->ringdebounce) {		if (!wc->ring && (wc->pegcount > PEGCOUNT)) {			/* It's ringing */			if (debug)				printk("RING!\n");			zt_hooksig(&wc->chan, ZT_RXSIG_RING);			wc->ring = 1;		}		if (wc->ring && !wc->pegcount) {			/* No more ring */			if (debug)				printk("NO RING!\n");			zt_hooksig(&wc->chan, ZT_RXSIG_OFFHOOK);			wc->ring = 0;		}	}	if (wc->ignoreread)		wc->ignoreread--;	/* Do the echo cancellation...  We are echo cancelling against	   what we sent two chunks ago*/	zt_ec_chunk(&wc->chan, wc->chan.readchunk, wc->lasttx);	/* Receive the result */	zt_receive(&wc->span);}#ifdef ENABLE_TASKLETSstatic void wcfxo_tasklet(unsigned long data){	struct wcfxo *wc = (struct wcfxo *)data;	wc->taskletrun++;	/* Run tasklet */	if (wc->taskletpending) {		wc->taskletexec++;		wcfxo_receiveprep(wc, wc->ints);		wcfxo_transmitprep(wc, wc->ints);	}	wc->taskletpending = 0;}#endifstatic void wcfxo_stop_dma(struct wcfxo *wc);static void wcfxo_restart_dma(struct wcfxo *wc);#ifdef LINUX26static irqreturn_t wcfxo_interrupt(int irq, void *dev_id, struct pt_regs *regs)#elsestatic void wcfxo_interrupt(int irq, void *dev_id, struct pt_regs *regs)#endif{	struct wcfxo *wc = dev_id;	unsigned char ints;	unsigned char b;#ifdef DEBUG_RING	static int oldb = 0;	static int oldcnt = 0;#endif	ints = inb(wc->ioaddr + WC_INTSTAT);	outb(ints, wc->ioaddr + WC_INTSTAT);	if (!ints)#ifdef LINUX26		return IRQ_NONE;#else		return;#endif			if (ints & 0x0c) {  /* if there is a rx interrupt pending */#ifdef ENABLE_TASKLETS		wc->ints = ints;		if (!wc->taskletpending) {			wc->taskletpending = 1;			wc->taskletsched++;			tasklet_hi_schedule(&wc->wcfxo_tlet);		} else			wc->txerrors++;#else		wcfxo_receiveprep(wc, ints);		/* transmitprep looks to see if there is anything to transmit		   and returns by itself if there is nothing */		wcfxo_transmitprep(wc, ints);#endif	}	if (ints & 0x10) {		printk("FXO PCI Master abort\n");		/* Stop DMA andlet the watchdog start it again */		wcfxo_stop_dma(wc);#ifdef LINUX26		return IRQ_RETVAL(1);#else		return;#endif			}	if (ints & 0x20) {		printk("PCI Target abort\n");#ifdef LINUX26		return IRQ_RETVAL(1);#else		return;#endif			}	if (1 /* !(wc->report % 0xf) */) {		/* Check for BATTERY from register and debounce for 8 ms */		b = wc->readregs[0xc] & 0xf;		if (!b) {			wc->nobatttimer++;#if 0			if (wc->battery)				printk("Battery loss: %d (%d debounce)\n", b, wc->battdebounce);#endif			if (wc->battery && !wc->battdebounce) {				if (debug)					printk("NO BATTERY!\n");				wc->battery =  0;#ifdef	JAPAN				if ((!wc->ohdebounce) && wc->offhook) {					zt_hooksig(&wc->chan, ZT_RXSIG_ONHOOK);					if (debug)						printk("Signalled On Hook\n");#ifdef	ZERO_BATT_RING					wc->onhook++;#endif				}#else				zt_hooksig(&wc->chan, ZT_RXSIG_ONHOOK);#endif				wc->battdebounce = BATT_DEBOUNCE;			} else if (!wc->battery)				wc->battdebounce = BATT_DEBOUNCE;			if ((wc->nobatttimer > 5000) &&#ifdef	ZERO_BATT_RING			    !(wc->readregs[0x05] & 0x04) &&#endif			    (!wc->span.alarms)) {				wc->span.alarms = ZT_ALARM_RED;				zt_alarm_notify(&wc->span);			}		} else if (b == 0xf) {			if (!wc->battery && !wc->battdebounce) {				if (debug)					printk("BATTERY!\n");#ifdef	ZERO_BATT_RING				if (wc->onhook) {					wc->onhook = 0;					zt_hooksig(&wc->chan, ZT_RXSIG_OFFHOOK);					if (debug)						printk("Signalled Off Hook\n");				}#else				zt_hooksig(&wc->chan, ZT_RXSIG_OFFHOOK);#endif				wc->battery = 1;				wc->nobatttimer = 0;				wc->battdebounce = BATT_DEBOUNCE;				if (wc->span.alarms) {					wc->span.alarms = 0;					zt_alarm_notify(&wc->span);				}			} else if (wc->battery)				wc->battdebounce = BATT_DEBOUNCE;		} else {			/* It's something else... */				wc->battdebounce = BATT_DEBOUNCE;		}

?? 快捷鍵說明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號(hào) Ctrl + =
減小字號(hào) Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
天堂蜜桃一区二区三区| 麻豆精品蜜桃视频网站| 日韩一级精品视频在线观看| 高清shemale亚洲人妖| 一区二区三区四区激情| 久久精品免费在线观看| 欧美一区二区在线不卡| 97久久人人超碰| 国产综合色产在线精品| 日韩中文字幕亚洲一区二区va在线| 久久久另类综合| 日韩欧美自拍偷拍| 欧美色男人天堂| 91香蕉视频污在线| 粉嫩av一区二区三区| 精品一区二区日韩| 视频精品一区二区| 亚洲婷婷综合色高清在线| 精品99一区二区| 日韩亚洲欧美成人一区| 7777精品伊人久久久大香线蕉完整版 | 久99久精品视频免费观看| 亚洲色图色小说| 国产精品大尺度| 久久人人爽爽爽人久久久| 欧美一区二区三区在线视频 | 欧美日韩在线播放三区四区| www.亚洲激情.com| 国产成人免费在线视频| 久久er精品视频| 蜜乳av一区二区三区| 日韩成人精品视频| 日韩精品视频网| 日本不卡一区二区三区| 五月天网站亚洲| 五月婷婷色综合| 日本在线观看不卡视频| 日韩av网站免费在线| 日韩高清不卡一区二区三区| 无吗不卡中文字幕| 性做久久久久久免费观看欧美| 亚洲日本丝袜连裤袜办公室| 国产精品伦一区| 国产精品美女久久久久久2018| 国产视频一区二区三区在线观看 | 精品美女一区二区三区| 精品久久久久一区| 久久久91精品国产一区二区精品| 久久影院视频免费| 欧美—级在线免费片| 国产精品色呦呦| 日韩美女久久久| 亚洲成人自拍网| 男女男精品网站| 韩国精品在线观看| 成人精品国产一区二区4080| www.亚洲人| 欧美日韩在线播放一区| 日韩三级视频在线观看| 久久久三级国产网站| 中文字幕一区二区三区视频| 一区二区在线免费观看| 亚洲一区二区三区四区在线| 日韩福利视频网| 国产毛片精品视频| hitomi一区二区三区精品| 色综合中文综合网| 26uuuu精品一区二区| 国产精品视频一二| 亚洲自拍偷拍综合| 日韩精品91亚洲二区在线观看| 激情欧美日韩一区二区| 成人精品免费视频| 欧美顶级少妇做爰| 中文字幕免费在线观看视频一区| 中文字幕在线播放不卡一区| 五月婷婷综合在线| 风间由美性色一区二区三区| 色婷婷国产精品久久包臀| 制服丝袜在线91| 中文字幕精品三区| 性欧美疯狂xxxxbbbb| 国产成人精品在线看| 欧美色精品天天在线观看视频| 精品国产伦一区二区三区观看方式| 国产精品电影院| 秋霞电影网一区二区| 国产91精品露脸国语对白| 欧美日韩免费视频| 国产精品麻豆欧美日韩ww| 日本视频在线一区| 色激情天天射综合网| 久久亚洲私人国产精品va媚药| 亚洲国产欧美在线| 高清日韩电视剧大全免费| 欧美精品亚洲二区| 18成人在线观看| 久久99精品久久久久久动态图| 色婷婷精品久久二区二区蜜臀av| 久久综合九色综合97婷婷| 亚洲国产中文字幕在线视频综合| 国产精品88888| 欧美一区二区视频在线观看 | 亚洲欧洲日韩一区二区三区| 蜜桃久久久久久| 欧美性大战久久久久久久蜜臀| 国产女主播视频一区二区| 美女脱光内衣内裤视频久久影院| 欧美主播一区二区三区| 国产精品美女久久久久久2018 | 不卡av在线免费观看| 欧美大度的电影原声| 亚洲国产一区二区视频| 不卡视频一二三四| 国产亚洲精品中文字幕| 久久99久久99小草精品免视看| 精品视频一区三区九区| 亚洲精品中文字幕在线观看| 国产91综合网| 欧美韩国日本综合| 国产精品中文字幕一区二区三区| 日韩一区二区精品在线观看| 婷婷国产v国产偷v亚洲高清| 欧美在线免费视屏| 亚洲免费观看在线观看| 91猫先生在线| 国产精品国产馆在线真实露脸| 国产成人av一区| 精品噜噜噜噜久久久久久久久试看| 美女久久久精品| 日韩欧美第一区| 麻豆精品蜜桃视频网站| 日韩精品最新网址| 蜜桃在线一区二区三区| 日韩久久久精品| 国产永久精品大片wwwapp| 久久综合精品国产一区二区三区| 国产在线一区观看| 精品国产1区二区| 国产suv精品一区二区6| 国产日韩影视精品| 高清成人在线观看| 国产精品久久影院| 色婷婷综合久久久| 亚洲v精品v日韩v欧美v专区| 91精品国产麻豆国产自产在线 | 老司机精品视频导航| 日韩欧美久久一区| 国产米奇在线777精品观看| 久久精品一区二区三区不卡牛牛| 国产精品一区在线观看你懂的| 久久久久国产免费免费| 东方aⅴ免费观看久久av| 国产精品乱码一区二区三区软件 | 日韩欧美黄色影院| 国产福利一区在线观看| 国产精品久久久久精k8| 日本乱人伦一区| 午夜欧美一区二区三区在线播放| 欧美一级二级在线观看| 国产激情视频一区二区在线观看 | 亚洲青青青在线视频| 91传媒视频在线播放| 肉色丝袜一区二区| 久久九九久精品国产免费直播| 99在线热播精品免费| 亚洲精品视频一区| 日韩亚洲欧美在线观看| 成人av高清在线| 天堂av在线一区| 久久精品一区二区三区四区| 91激情在线视频| 国内成人精品2018免费看| 国产精品久久久久婷婷| 欧美日韩免费在线视频| 国产成人免费视频| 视频在线观看国产精品| 国产午夜精品一区二区 | 欧美伦理影视网| 国产精品18久久久久久久久| 亚洲精品乱码久久久久久| 日韩免费看的电影| 91论坛在线播放| 久久99精品久久久久婷婷| 亚洲精品国产无套在线观 | 亚洲一二三区视频在线观看| 精品国免费一区二区三区| 91麻豆精品一区二区三区| 精品一区二区在线播放| 尤物av一区二区| 久久日一线二线三线suv| 欧美少妇bbb| 岛国av在线一区| 秋霞午夜av一区二区三区| 亚洲女子a中天字幕| 久久久久久久久久久久电影| 欧美日韩一级黄| 99国产一区二区三精品乱码| 另类小说视频一区二区| 亚洲小说欧美激情另类|