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

📄 capifunc.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
			card->remove_in_progress = 1;			list_del(tmp);			break;		}	}	diva_os_leave_spin_lock(&api_lock, &old_irql, "remove card");	if (card) {		/*		 * Detach CAPI. Sendf cannot call to CAPI any more.		 * After detach no call to send_message() is done too.		 */		detach_capi_ctr(&card->capi_ctrl);		/*		 * Now get API lock (to ensure stable state of LI tables)		 * and update the adapter map/LI table.		 */		diva_os_enter_spin_lock(&api_lock, &old_irql, "remove card");		clean_adapter(card->Id - 1, &free_mem_q);		DBG_TRC(("DelAdapterMap (%d) -> (%d)",				ControllerMap[card->Id], card->Id))				ControllerMap[card->Id] = 0;		DBG_TRC(("adapter remove, max_adapter=%d",				max_adapter));		diva_os_leave_spin_lock(&api_lock, &old_irql, "remove card");				/* After releasing the lock, we can free the memory */		diva_os_free (0, card);	}	/* free queued memory areas */	list_for_each_safe(link, tmp, &free_mem_q) {		list_del(link);		diva_os_free(0, link);	}}/* * remove cards */static void divacapi_remove_cards(void){	DESCRIPTOR d;	struct list_head *tmp;	diva_card *card;	diva_os_spin_lock_magic_t old_irql;rescan:	diva_os_enter_spin_lock(&api_lock, &old_irql, "remove cards");	list_for_each(tmp, &cards) {		card = list_entry(tmp, diva_card, list);		diva_os_leave_spin_lock(&api_lock, &old_irql, "remove cards");		d.request = card->d.request;		divacapi_remove_card(&d);		goto rescan;	}	diva_os_leave_spin_lock(&api_lock, &old_irql, "remove cards");}/* * sync_callback */static void sync_callback(ENTITY * e){	diva_os_spin_lock_magic_t old_irql;	DBG_TRC(("cb:Id=%x,Rc=%x,Ind=%x", e->Id, e->Rc, e->Ind))	diva_os_enter_spin_lock(&api_lock, &old_irql, "sync_callback");	callback(e);	diva_os_leave_spin_lock(&api_lock, &old_irql, "sync_callback");}/* * add a new card */static int diva_add_card(DESCRIPTOR * d){	int k = 0, i = 0;	diva_os_spin_lock_magic_t old_irql;	diva_card *card = NULL;	struct capi_ctr *ctrl = NULL;	DIVA_CAPI_ADAPTER *a = NULL;	IDI_SYNC_REQ sync_req;	char serial[16];	void* mem_to_free;	LI_CONFIG *new_li_config_table;	int j;	if (!(card = (diva_card *) diva_os_malloc(0, sizeof(diva_card)))) {		DBG_ERR(("diva_add_card: failed to allocate card struct."))		    return (0);	}	memset((char *) card, 0x00, sizeof(diva_card));	memcpy(&card->d, d, sizeof(DESCRIPTOR));	sync_req.GetName.Req = 0;	sync_req.GetName.Rc = IDI_SYNC_REQ_GET_NAME;	card->d.request((ENTITY *) & sync_req);	strlcpy(card->name, sync_req.GetName.name, sizeof(card->name));	ctrl = &card->capi_ctrl;	strcpy(ctrl->name, card->name);	ctrl->register_appl = diva_register_appl;	ctrl->release_appl = diva_release_appl;	ctrl->send_message = diva_send_message;	ctrl->procinfo = diva_procinfo;	ctrl->driverdata = card;	diva_os_set_controller_struct(ctrl);	if (attach_capi_ctr(ctrl)) {		DBG_ERR(("diva_add_card: failed to attach controller."))		    diva_os_free(0, card);		return (0);	}		diva_os_enter_spin_lock(&api_lock, &old_irql, "find id");	card->Id = find_free_id();	diva_os_leave_spin_lock(&api_lock, &old_irql, "find id");		strlcpy(ctrl->manu, M_COMPANY, sizeof(ctrl->manu));	ctrl->version.majorversion = 2;	ctrl->version.minorversion = 0;	ctrl->version.majormanuversion = DRRELMAJOR;	ctrl->version.minormanuversion = DRRELMINOR;	sync_req.GetSerial.Req = 0;	sync_req.GetSerial.Rc = IDI_SYNC_REQ_GET_SERIAL;	sync_req.GetSerial.serial = 0;	card->d.request((ENTITY *) & sync_req);	if ((i = ((sync_req.GetSerial.serial & 0xff000000) >> 24))) {		sprintf(serial, "%ld-%d",			sync_req.GetSerial.serial & 0x00ffffff, i + 1);	} else {		sprintf(serial, "%ld", sync_req.GetSerial.serial);	}	serial[CAPI_SERIAL_LEN - 1] = 0;	strlcpy(ctrl->serial, serial, sizeof(ctrl->serial));	a = &adapter[card->Id - 1];	card->adapter = a;	a->os_card = card;	ControllerMap[card->Id] = (byte) (ctrl->cnr);	DBG_TRC(("AddAdapterMap (%d) -> (%d)", ctrl->cnr, card->Id))	    sync_req.xdi_capi_prms.Req = 0;	sync_req.xdi_capi_prms.Rc = IDI_SYNC_REQ_XDI_GET_CAPI_PARAMS;	sync_req.xdi_capi_prms.info.structure_length =	    sizeof(diva_xdi_get_capi_parameters_t);	card->d.request((ENTITY *) & sync_req);	a->flag_dynamic_l1_down =	    sync_req.xdi_capi_prms.info.flag_dynamic_l1_down;	a->group_optimization_enabled =	    sync_req.xdi_capi_prms.info.group_optimization_enabled;	a->request = DIRequest;	/* card->d.request; */	a->max_plci = card->d.channels + 30;	a->max_listen = (card->d.channels > 2) ? 8 : 2;	if (!	    (a->plci =	     (PLCI *) diva_os_malloc(0, sizeof(PLCI) * a->max_plci))) {		DBG_ERR(("diva_add_card: failed alloc plci struct."))		    memset(a, 0, sizeof(DIVA_CAPI_ADAPTER));		return (0);	}	memset(a->plci, 0, sizeof(PLCI) * a->max_plci);	for (k = 0; k < a->max_plci; k++) {		a->Id = (byte) card->Id;		a->plci[k].Sig.callback = sync_callback;		a->plci[k].Sig.XNum = 1;		a->plci[k].Sig.X = a->plci[k].XData;		a->plci[k].Sig.user[0] = (word) (card->Id - 1);		a->plci[k].Sig.user[1] = (word) k;		a->plci[k].NL.callback = sync_callback;		a->plci[k].NL.XNum = 1;		a->plci[k].NL.X = a->plci[k].XData;		a->plci[k].NL.user[0] = (word) ((card->Id - 1) | 0x8000);		a->plci[k].NL.user[1] = (word) k;		a->plci[k].adapter = a;	}	a->profile.Number = card->Id;	a->profile.Channels = card->d.channels;	if (card->d.features & DI_FAX3) {		a->profile.Global_Options = 0x71;		if (card->d.features & DI_CODEC)			a->profile.Global_Options |= 0x6;#if IMPLEMENT_DTMF		a->profile.Global_Options |= 0x8;#endif				/* IMPLEMENT_DTMF */		a->profile.Global_Options |= 0x80; /* Line Interconnect */#if IMPLEMENT_ECHO_CANCELLER		a->profile.Global_Options |= 0x100;#endif				/* IMPLEMENT_ECHO_CANCELLER */		a->profile.B1_Protocols = 0xdf;		a->profile.B2_Protocols = 0x1fdb;		a->profile.B3_Protocols = 0xb7;		a->manufacturer_features = MANUFACTURER_FEATURE_HARDDTMF;	} else {		a->profile.Global_Options = 0x71;		if (card->d.features & DI_CODEC)			a->profile.Global_Options |= 0x2;		a->profile.B1_Protocols = 0x43;		a->profile.B2_Protocols = 0x1f0f;		a->profile.B3_Protocols = 0x07;		a->manufacturer_features = 0;	}	a->li_pri = (a->profile.Channels > 2);	a->li_channels = a->li_pri ? MIXER_CHANNELS_PRI : MIXER_CHANNELS_BRI;	a->li_base = 0;	for (i = 0; &adapter[i] != a; i++) {		if (adapter[i].request)			a->li_base = adapter[i].li_base + adapter[i].li_channels;	}	k = li_total_channels + a->li_channels;	new_li_config_table =		(LI_CONFIG *) diva_os_malloc(0, ((k * sizeof(LI_CONFIG) + 3) & ~3) + (2 * k) * ((k + 3) & ~3));	if (new_li_config_table == NULL) {		DBG_ERR(("diva_add_card: failed alloc li_config table."))		memset(a, 0, sizeof(DIVA_CAPI_ADAPTER));		return (0);	}	/* Prevent access to line interconnect table in process update */	diva_os_enter_spin_lock(&api_lock, &old_irql, "add card");		j = 0;	for (i = 0; i < k; i++) {		if ((i >= a->li_base) && (i < a->li_base + a->li_channels))			memset(&new_li_config_table[i], 0, sizeof(LI_CONFIG));		else			memcpy(&new_li_config_table[i], &li_config_table[j], sizeof(LI_CONFIG));		new_li_config_table[i].flag_table =			((byte *) new_li_config_table) + (((k * sizeof(LI_CONFIG) + 3) & ~3) + (2 * i) * ((k + 3) & ~3));		new_li_config_table[i].coef_table =			((byte *) new_li_config_table) + (((k * sizeof(LI_CONFIG) + 3) & ~3) + (2 * i + 1) * ((k + 3) & ~3));		if ((i >= a->li_base) && (i < a->li_base + a->li_channels)) {			new_li_config_table[i].adapter = a;			memset(&new_li_config_table[i].flag_table[0], 0, k);			memset(&new_li_config_table[i].coef_table[0], 0, k);		} else {			if (a->li_base != 0) {				memcpy(&new_li_config_table[i].flag_table[0],				       &li_config_table[j].flag_table[0],				       a->li_base);				memcpy(&new_li_config_table[i].coef_table[0],				       &li_config_table[j].coef_table[0],				       a->li_base);			}			memset(&new_li_config_table[i].flag_table[a->li_base], 0, a->li_channels);			memset(&new_li_config_table[i].coef_table[a->li_base], 0, a->li_channels);			if (a->li_base + a->li_channels < k) {				memcpy(&new_li_config_table[i].flag_table[a->li_base +				       a->li_channels],				       &li_config_table[j].flag_table[a->li_base],				       k - (a->li_base + a->li_channels));				memcpy(&new_li_config_table[i].coef_table[a->li_base +				       a->li_channels],				       &li_config_table[j].coef_table[a->li_base],				       k - (a->li_base + a->li_channels));			}			j++;		}	}	li_total_channels = k;	mem_to_free = li_config_table;	li_config_table = new_li_config_table;	for (i = card->Id; i < max_adapter; i++) {		if (adapter[i].request)			adapter[i].li_base += a->li_channels;	}	if (a == &adapter[max_adapter])		max_adapter++;	list_add(&(card->list), &cards);	AutomaticLaw(a);	diva_os_leave_spin_lock(&api_lock, &old_irql, "add card");	if (mem_to_free) {		diva_os_free (0, mem_to_free);	}	i = 0;	while (i++ < 30) {		if (a->automatic_law > 3)			break;		diva_os_sleep(10);	}	/* profile information */	PUT_WORD(&ctrl->profile.nbchannel, card->d.channels);	ctrl->profile.goptions = a->profile.Global_Options;	ctrl->profile.support1 = a->profile.B1_Protocols;	ctrl->profile.support2 = a->profile.B2_Protocols;	ctrl->profile.support3 = a->profile.B3_Protocols;	/* manufacturer profile information */	ctrl->profile.manu[0] = a->man_profile.private_options;	ctrl->profile.manu[1] = a->man_profile.rtp_primary_payloads;	ctrl->profile.manu[2] = a->man_profile.rtp_additional_payloads;	ctrl->profile.manu[3] = 0;	ctrl->profile.manu[4] = 0;	capi_ctr_ready(ctrl);	DBG_TRC(("adapter added, max_adapter=%d", max_adapter));	return (1);}/* *  register appl */static void diva_register_appl(struct capi_ctr *ctrl, __u16 appl,			       capi_register_params * rp){	APPL *this;	word bnum, xnum;	int i = 0;	unsigned char *p;	void *DataNCCI, *DataFlags, *ReceiveBuffer, *xbuffer_used;	void **xbuffer_ptr, **xbuffer_internal;	diva_os_spin_lock_magic_t old_irql;	unsigned int mem_len;	int nconn = rp->level3cnt;	if (diva_os_in_irq()) {		DBG_ERR(("CAPI_REGISTER - in irq context !"))		return;	}	DBG_TRC(("application register Id=%d", appl))	if (appl > MAX_APPL) {		DBG_ERR(("CAPI_REGISTER - appl.Id exceeds MAX_APPL"))		return;	}	if (nconn <= 0)		nconn = ctrl->profile.nbchannel * -nconn;        if (nconn == 0)		nconn = ctrl->profile.nbchannel;	DBG_LOG(("CAPI_REGISTER - Id = %d", appl))	DBG_LOG(("  MaxLogicalConnections = %d(%d)", nconn, rp->level3cnt))	DBG_LOG(("  MaxBDataBuffers       = %d", rp->datablkcnt))	DBG_LOG(("  MaxBDataLength        = %d", rp->datablklen))	if (nconn < 1 ||	    nconn > 255 ||	    rp->datablklen < 80 ||	    rp->datablklen > 2150 || rp->datablkcnt > 255) {		DBG_ERR(("CAPI_REGISTER - invalid parameters"))		return;	}	if (application[appl - 1].Id == appl) {		DBG_LOG(("CAPI_REGISTER - appl already registered"))		return;	/* appl already registered */	}	/* alloc memory */	bnum = nconn * rp->datablkcnt;	xnum = nconn * MAX_DATA_B3;	mem_len  = bnum * sizeof(word);		/* DataNCCI */	mem_len += bnum * sizeof(word);		/* DataFlags */	mem_len += bnum * rp->datablklen;	/* ReceiveBuffer */	mem_len += xnum;			/* xbuffer_used */	mem_len += xnum * sizeof(void *);	/* xbuffer_ptr */	mem_len += xnum * sizeof(void *);	/* xbuffer_internal */	mem_len += xnum * rp->datablklen;	/* xbuffer_ptr[xnum] */	DBG_LOG(("  Allocated Memory      = %d", mem_len))	if (!(p = diva_os_malloc(0, mem_len))) {		DBG_ERR(("CAPI_REGISTER - memory allocation failed"))		return;	}	memset(p, 0, mem_len);	DataNCCI = (void *)p;	p += bnum * sizeof(word);	DataFlags = (void *)p;	p += bnum * sizeof(word);	ReceiveBuffer = (void *)p;	p += bnum * rp->datablklen;	xbuffer_used = (void *)p;	p += xnum;	xbuffer_ptr = (void **)p;	p += xnum * sizeof(void *);	xbuffer_internal = (void **)p;	p += xnum * sizeof(void *);	for (i = 0; i < xnum; i++) {		xbuffer_ptr[i] = (void *)p;		p += rp->datablklen;	}	/* initialize application data */	diva_os_enter_spin_lock(&api_lock, &old_irql, "register_appl");	this = &application[appl - 1];

⌨️ 快捷键说明

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