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

📄 capifunc.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
/* $Id: capifunc.c,v 1.61.4.7 2005/02/11 19:40:25 armin Exp $ * * ISDN interface module for Eicon active cards DIVA. * CAPI Interface common functions *  * Copyright 2000-2003 by Armin Schindler (mac@melware.de)  * Copyright 2000-2003 Cytronics & Melware (info@melware.de) *  * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. * */#include "platform.h"#include "os_capi.h"#include "di_defs.h"#include "capi20.h"#include "divacapi.h"#include "divasync.h"#include "capifunc.h"#define DBG_MINIMUM  (DL_LOG + DL_FTL + DL_ERR)#define DBG_DEFAULT  (DBG_MINIMUM + DL_XLOG + DL_REG)DIVA_CAPI_ADAPTER *adapter = (DIVA_CAPI_ADAPTER *) NULL;APPL *application = (APPL *) NULL;byte max_appl = MAX_APPL;byte max_adapter = 0;static CAPI_MSG *mapped_msg = (CAPI_MSG *) NULL;byte UnMapController(byte);char DRIVERRELEASE_CAPI[32];extern void AutomaticLaw(DIVA_CAPI_ADAPTER *);extern void callback(ENTITY *);extern word api_remove_start(void);extern word CapiRelease(word);extern word CapiRegister(word);extern word api_put(APPL *, CAPI_MSG *);static diva_os_spin_lock_t api_lock;static LIST_HEAD(cards);static dword notify_handle;static void DIRequest(ENTITY * e);static DESCRIPTOR MAdapter;static DESCRIPTOR DAdapter;static byte ControllerMap[MAX_DESCRIPTORS + 1];static void diva_register_appl(struct capi_ctr *, __u16,			       capi_register_params *);static void diva_release_appl(struct capi_ctr *, __u16);static char *diva_procinfo(struct capi_ctr *);static u16 diva_send_message(struct capi_ctr *,			     diva_os_message_buffer_s *);extern void diva_os_set_controller_struct(struct capi_ctr *);extern void DIVA_DIDD_Read(DESCRIPTOR *, int);/* * debug */static void no_printf(unsigned char *, ...);#include "debuglib.c"static void xlog(char *x, ...){#ifndef DIVA_NO_DEBUGLIB	va_list ap;	if (myDriverDebugHandle.dbgMask & DL_XLOG) {		va_start(ap, x);		if (myDriverDebugHandle.dbg_irq) {			myDriverDebugHandle.dbg_irq(myDriverDebugHandle.id,						    DLI_XLOG, x, ap);		} else if (myDriverDebugHandle.dbg_old) {			myDriverDebugHandle.dbg_old(myDriverDebugHandle.id,						    x, ap);		}		va_end(ap);	}#endif}/* * info for proc */static char *diva_procinfo(struct capi_ctr *ctrl){	return (ctrl->serial);}/* * stop debugging */static void stop_dbg(void){	DbgDeregister();	memset(&MAdapter, 0, sizeof(MAdapter));	dprintf = no_printf;}/* * dummy debug function */static void no_printf(unsigned char *x, ...){}/* * Controller mapping */byte MapController(byte Controller){	byte i;	byte MappedController = 0;	byte ctrl = Controller & 0x7f;	/* mask external controller bit off */	for (i = 1; i < max_adapter + 1; i++) {		if (ctrl == ControllerMap[i]) {			MappedController = (byte) i;			break;		}	}	if (i > max_adapter) {		ControllerMap[0] = ctrl;		MappedController = 0;	}	return (MappedController | (Controller & 0x80));	/* put back external controller bit */}/* * Controller unmapping */byte UnMapController(byte MappedController){	byte Controller;	byte ctrl = MappedController & 0x7f;	/* mask external controller bit off */	if (ctrl <= max_adapter) {		Controller = ControllerMap[ctrl];	} else {		Controller = 0;	}	return (Controller | (MappedController & 0x80));	/* put back external controller bit */}/* * find a new free id */static int find_free_id(void){	int num = 0;	DIVA_CAPI_ADAPTER *a;	while (num < MAX_DESCRIPTORS) {		a = &adapter[num];		if (!a->Id)			break;		num++;	}	return(num + 1);}/* * find a card structure by controller number */static diva_card *find_card_by_ctrl(word controller){	struct list_head *tmp;	diva_card *card;	list_for_each(tmp, &cards) {		card = list_entry(tmp, diva_card, list);		if (ControllerMap[card->Id] == controller) {			if (card->remove_in_progress)				card = NULL;			return(card);		}	}	return (diva_card *) 0;}/* * Buffer RX/TX  */void *TransmitBufferSet(APPL * appl, dword ref){	appl->xbuffer_used[ref] = TRUE;	DBG_PRV1(("%d:xbuf_used(%d)", appl->Id, ref + 1))	    return (void *) ref;}void *TransmitBufferGet(APPL * appl, void *p){	if (appl->xbuffer_internal[(dword) p])		return appl->xbuffer_internal[(dword) p];	return appl->xbuffer_ptr[(dword) p];}void TransmitBufferFree(APPL * appl, void *p){	appl->xbuffer_used[(dword) p] = FALSE;	DBG_PRV1(("%d:xbuf_free(%d)", appl->Id, ((dword) p) + 1))}void *ReceiveBufferGet(APPL * appl, int Num){	return &appl->ReceiveBuffer[Num * appl->MaxDataLength];}/* * api_remove_start/complete for cleanup */void api_remove_complete(void){	DBG_PRV1(("api_remove_complete"))}/* * main function called by message.c */void sendf(APPL * appl, word command, dword Id, word Number, byte * format, ...){	word i, j;	word length = 12, dlength = 0;	byte *write;	CAPI_MSG msg;	byte *string = NULL;	va_list ap;	diva_os_message_buffer_s *dmb;	diva_card *card = NULL;	dword tmp;	if (!appl)		return;	DBG_PRV1(("sendf(a=%d,cmd=%x,format=%s)",		  appl->Id, command, (byte *) format))	PUT_WORD(&msg.header.appl_id, appl->Id);	PUT_WORD(&msg.header.command, command);	if ((byte) (command >> 8) == 0x82)		Number = appl->Number++;	PUT_WORD(&msg.header.number, Number);	PUT_DWORD(&msg.header.controller, Id);	write = (byte *) & msg;	write += 12;	va_start(ap, format);	for (i = 0; format[i]; i++) {		switch (format[i]) {		case 'b':			tmp = va_arg(ap, dword);			*(byte *) write = (byte) (tmp & 0xff);			write += 1;			length += 1;			break;		case 'w':			tmp = va_arg(ap, dword);			PUT_WORD(write, (tmp & 0xffff));			write += 2;			length += 2;			break;		case 'd':			tmp = va_arg(ap, dword);			PUT_DWORD(write, tmp);			write += 4;			length += 4;			break;		case 's':		case 'S':			string = va_arg(ap, byte *);			length += string[0] + 1;			for (j = 0; j <= string[0]; j++)				*write++ = string[j];			break;		}	}	va_end(ap);	PUT_WORD(&msg.header.length, length);	msg.header.controller = UnMapController(msg.header.controller);	if (command == _DATA_B3_I)		dlength = GET_WORD(			      ((byte *) & msg.info.data_b3_ind.Data_Length));	if (!(dmb = diva_os_alloc_message_buffer(length + dlength,					  (void **) &write))) {		DBG_ERR(("sendf: alloc_message_buffer failed, incoming msg dropped."))		return;	}	/* copy msg header to sk_buff */	memcpy(write, (byte *) & msg, length);	/* if DATA_B3_IND, copy data too */	if (command == _DATA_B3_I) {		dword data = GET_DWORD(&msg.info.data_b3_ind.Data);		memcpy(write + length, (void *) data, dlength);	}#ifndef DIVA_NO_DEBUGLIB	if (myDriverDebugHandle.dbgMask & DL_XLOG) {		switch (command) {		default:			xlog("\x00\x02", &msg, 0x81, length);			break;		case _DATA_B3_R | CONFIRM:			if (myDriverDebugHandle.dbgMask & DL_BLK)				xlog("\x00\x02", &msg, 0x81, length);			break;		case _DATA_B3_I:			if (myDriverDebugHandle.dbgMask & DL_BLK) {				xlog("\x00\x02", &msg, 0x81, length);				for (i = 0; i < dlength; i += 256) {				  DBG_BLK((((char *) GET_DWORD(&msg.info.data_b3_ind.Data)) + i,				  	((dlength - i) < 256) ? (dlength - i) : 256))				  if (!(myDriverDebugHandle.dbgMask & DL_PRV0))					  break; /* not more if not explicitely requested */				}			}			break;		}	}#endif	/* find the card structure for this controller */	if (!(card = find_card_by_ctrl(write[8] & 0x7f))) {		DBG_ERR(("sendf - controller %d not found, incoming msg dropped",			 write[8] & 0x7f))		diva_os_free_message_buffer(dmb);		return;	}	/* send capi msg to capi layer */	capi_ctr_handle_message(&card->capi_ctrl, appl->Id, dmb);}/* * cleanup adapter */static void clean_adapter(int id, struct list_head *free_mem_q){	DIVA_CAPI_ADAPTER *a;	int i, k;	a = &adapter[id];	k = li_total_channels - a->li_channels;	if (k == 0) {		if (li_config_table) {			list_add((struct list_head *)li_config_table, free_mem_q);			li_config_table = NULL;		}	} else {		if (a->li_base < k) {			memmove(&li_config_table[a->li_base],				&li_config_table[a->li_base + a->li_channels],				(k - a->li_base) * sizeof(LI_CONFIG));			for (i = 0; i < k; i++) {				memmove(&li_config_table[i].flag_table[a->li_base],					&li_config_table[i].flag_table[a->li_base + a->li_channels],					k - a->li_base);				memmove(&li_config_table[i].					coef_table[a->li_base],					&li_config_table[i].coef_table[a->li_base + a->li_channels],					k - a->li_base);			}		}	}	li_total_channels = k;	for (i = id; i < max_adapter; i++) {		if (adapter[i].request)			adapter[i].li_base -= a->li_channels;	}	if (a->plci)		list_add((struct list_head *)a->plci, free_mem_q);	memset(a, 0x00, sizeof(DIVA_CAPI_ADAPTER));	while ((max_adapter != 0) && !adapter[max_adapter - 1].request)		max_adapter--;}/* * remove a card, but ensures consistent state of LI tables * in the time adapter is removed */static void divacapi_remove_card(DESCRIPTOR * d){	diva_card *card = NULL;	diva_os_spin_lock_magic_t old_irql;	LIST_HEAD(free_mem_q);	struct list_head *link;	struct list_head *tmp;	/*	 * Set "remove in progress flag".	 * Ensures that there is no call from sendf to CAPI in	 * the time CAPI controller is about to be removed.	 */	diva_os_enter_spin_lock(&api_lock, &old_irql, "remove card");	list_for_each(tmp, &cards) {		card = list_entry(tmp, diva_card, list);		if (card->d.request == d->request) {

⌨️ 快捷键说明

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