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

📄 mntfunc.c

📁 底层驱动开发
💻 C
字号:
/* $Id: mntfunc.c,v 1.19.6.4 2005/01/31 12:22:20 armin Exp $ * * Driver for Eicon DIVA Server ISDN cards. * Maint module * * 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 "di_defs.h"#include "divasync.h"#include "debug_if.h"extern char *DRIVERRELEASE_MNT;#define DBG_MINIMUM  (DL_LOG + DL_FTL + DL_ERR)#define DBG_DEFAULT  (DBG_MINIMUM + DL_XLOG + DL_REG)extern void DIVA_DIDD_Read(void *, int);static dword notify_handle;static DESCRIPTOR DAdapter;static DESCRIPTOR MAdapter;static DESCRIPTOR MaintDescriptor =    { IDI_DIMAINT, 0, 0, (IDI_CALL) diva_maint_prtComp };extern int diva_os_copy_to_user(void *os_handle, void __user *dst,				const void *src, int length);extern int diva_os_copy_from_user(void *os_handle, void *dst,				  const void __user *src, int length);static void no_printf(unsigned char *x, ...){	/* dummy debug function */}#include "debuglib.c"/* *  DIDD callback function */static void *didd_callback(void *context, DESCRIPTOR * adapter,			   int removal){	if (adapter->type == IDI_DADAPTER) {		DBG_ERR(("cb: Change in DAdapter ? Oops ?."));	} else if (adapter->type == IDI_DIMAINT) {		if (removal) {			DbgDeregister();			memset(&MAdapter, 0, sizeof(MAdapter));			dprintf = no_printf;		} else {			memcpy(&MAdapter, adapter, sizeof(MAdapter));			dprintf = (DIVA_DI_PRINTF) MAdapter.request;			DbgRegister("MAINT", DRIVERRELEASE_MNT, DBG_DEFAULT);		}	} else if ((adapter->type > 0) && (adapter->type < 16)) {		if (removal) {			diva_mnt_remove_xdi_adapter(adapter);		} else {			diva_mnt_add_xdi_adapter(adapter);		}	}	return (NULL);}/* * connect to didd */static int DIVA_INIT_FUNCTION connect_didd(void){	int x = 0;	int dadapter = 0;	IDI_SYNC_REQ req;	DESCRIPTOR DIDD_Table[MAX_DESCRIPTORS];	DIVA_DIDD_Read(DIDD_Table, sizeof(DIDD_Table));	for (x = 0; x < MAX_DESCRIPTORS; x++) {		if (DIDD_Table[x].type == IDI_DADAPTER) {	/* DADAPTER found */			dadapter = 1;			memcpy(&DAdapter, &DIDD_Table[x], sizeof(DAdapter));			req.didd_notify.e.Req = 0;			req.didd_notify.e.Rc =			    IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY;			req.didd_notify.info.callback = (void *)didd_callback;			req.didd_notify.info.context = NULL;			DAdapter.request((ENTITY *) & req);			if (req.didd_notify.e.Rc != 0xff)				return (0);			notify_handle = req.didd_notify.info.handle;			/* Register MAINT (me) */			req.didd_add_adapter.e.Req = 0;			req.didd_add_adapter.e.Rc =			    IDI_SYNC_REQ_DIDD_ADD_ADAPTER;			req.didd_add_adapter.info.descriptor =			    (void *) &MaintDescriptor;			DAdapter.request((ENTITY *) & req);			if (req.didd_add_adapter.e.Rc != 0xff)				return (0);		} else if ((DIDD_Table[x].type > 0)			   && (DIDD_Table[x].type < 16)) {			diva_mnt_add_xdi_adapter(&DIDD_Table[x]);		}	}	return (dadapter);}/* * disconnect from didd */static void DIVA_EXIT_FUNCTION disconnect_didd(void){	IDI_SYNC_REQ req;	req.didd_notify.e.Req = 0;	req.didd_notify.e.Rc = IDI_SYNC_REQ_DIDD_REMOVE_ADAPTER_NOTIFY;	req.didd_notify.info.handle = notify_handle;	DAdapter.request((ENTITY *) & req);	req.didd_remove_adapter.e.Req = 0;	req.didd_remove_adapter.e.Rc = IDI_SYNC_REQ_DIDD_REMOVE_ADAPTER;	req.didd_remove_adapter.info.p_request =	    (IDI_CALL) MaintDescriptor.request;	DAdapter.request((ENTITY *) & req);}/* * read/write maint */int maint_read_write(void __user *buf, int count){	byte data[128];	dword cmd, id, mask;	int ret = 0;	if (count < (3 * sizeof(dword)))		return (-EFAULT);	if (diva_os_copy_from_user(NULL, (void *) &data[0],				   buf, 3 * sizeof(dword))) {		return (-EFAULT);	}	cmd = *(dword *) & data[0];	/* command */	id = *(dword *) & data[4];	/* driver id */	mask = *(dword *) & data[8];	/* mask or size */	switch (cmd) {	case DITRACE_CMD_GET_DRIVER_INFO:		if ((ret = diva_get_driver_info(id, data, sizeof(data))) > 0) {			if ((count < ret) || diva_os_copy_to_user			    (NULL, buf, (void *) &data[0], ret))				ret = -EFAULT;		} else {			ret = -EINVAL;		}		break;	case DITRACE_READ_DRIVER_DBG_MASK:		if ((ret = diva_get_driver_dbg_mask(id, (byte *) data)) > 0) {			if ((count < ret) || diva_os_copy_to_user			    (NULL, buf, (void *) &data[0], ret))				ret = -EFAULT;		} else {			ret = -ENODEV;		}		break;	case DITRACE_WRITE_DRIVER_DBG_MASK:		if ((ret = diva_set_driver_dbg_mask(id, mask)) <= 0) {			ret = -ENODEV;		}		break;    /*       Filter commands will ignore the ID due to fact that filtering affects       the B- channel and Audio Tap trace levels only. Also MAINT driver will       select the right trace ID by itself       */	case DITRACE_WRITE_SELECTIVE_TRACE_FILTER:		if (!mask) {			ret = diva_set_trace_filter (1, "*");		} else if (mask < sizeof(data)) {			if (diva_os_copy_from_user(NULL, data, (char __user *)buf+12, mask)) {				ret = -EFAULT;			} else {				ret = diva_set_trace_filter ((int)mask, data);			}		} else {			ret = -EINVAL;		}		break;	case DITRACE_READ_SELECTIVE_TRACE_FILTER:		if ((ret = diva_get_trace_filter (sizeof(data), data)) > 0) {			if (diva_os_copy_to_user (NULL, buf, data, ret))				ret = -EFAULT;		} else {			ret = -ENODEV;		}		break;	case DITRACE_READ_TRACE_ENTRY:{			diva_os_spin_lock_magic_t old_irql;			word size;			diva_dbg_entry_head_t *pmsg;			byte *pbuf;			if (!(pbuf = diva_os_malloc(0, mask))) {				return (-ENOMEM);			}			for(;;) {				if (!(pmsg =				    diva_maint_get_message(&size, &old_irql))) {					break;				}				if (size > mask) {					diva_maint_ack_message(0, &old_irql);					ret = -EINVAL;					break;				}				ret = size;				memcpy(pbuf, pmsg, size);				diva_maint_ack_message(1, &old_irql);				if ((count < size) ||				     diva_os_copy_to_user (NULL, buf, (void *) pbuf, size))							ret = -EFAULT;				break;			}			diva_os_free(0, pbuf);		}		break;	case DITRACE_READ_TRACE_ENTRYS:{			diva_os_spin_lock_magic_t old_irql;			word size;			diva_dbg_entry_head_t *pmsg;			byte *pbuf = NULL;			int written = 0;			if (mask < 4096) {				ret = -EINVAL;				break;			}			if (!(pbuf = diva_os_malloc(0, mask))) {				return (-ENOMEM);			}			for (;;) {				if (!(pmsg =				     diva_maint_get_message(&size, &old_irql))) {					break;				}				if ((size + 8) > mask) {					diva_maint_ack_message(0, &old_irql);					break;				}				/*				   Write entry length				 */				pbuf[written++] = (byte) size;				pbuf[written++] = (byte) (size >> 8);				pbuf[written++] = 0;				pbuf[written++] = 0;				/*				   Write message				 */				memcpy(&pbuf[written], pmsg, size);				diva_maint_ack_message(1, &old_irql);				written += size;				mask -= (size + 4);			}			pbuf[written++] = 0;			pbuf[written++] = 0;			pbuf[written++] = 0;			pbuf[written++] = 0;			if ((count < written) || diva_os_copy_to_user(NULL, buf, (void *) pbuf, written)) {				ret = -EFAULT;			} else {				ret = written;			}			diva_os_free(0, pbuf);		}		break;	default:		ret = -EINVAL;	}	return (ret);}/* *  init */int DIVA_INIT_FUNCTION mntfunc_init(int *buffer_length, void **buffer,				    unsigned long diva_dbg_mem){	if (*buffer_length < 64) {		*buffer_length = 64;	}	if (*buffer_length > 512) {		*buffer_length = 512;	}	*buffer_length *= 1024;	if (diva_dbg_mem) {		*buffer = (void *) diva_dbg_mem;	} else {		while ((*buffer_length >= (64 * 1024))		       &&		       (!(*buffer = diva_os_malloc (0, *buffer_length)))) {			*buffer_length -= 1024;		}		if (!*buffer) {			DBG_ERR(("init: Can not alloc trace buffer"));			return (0);		}	}	if (diva_maint_init(*buffer, *buffer_length, (diva_dbg_mem == 0))) {		if (!diva_dbg_mem) {			diva_os_free (0, *buffer);		}		DBG_ERR(("init: maint init failed"));		return (0);	}	if (!connect_didd()) {		DBG_ERR(("init: failed to connect to DIDD."));		diva_maint_finit();		if (!diva_dbg_mem) {			diva_os_free (0, *buffer);		}		return (0);	}	return (1);}/* *  exit */void DIVA_EXIT_FUNCTION mntfunc_finit(void){	void *buffer;	int i = 100;	DbgDeregister();	while (diva_mnt_shutdown_xdi_adapters() && i--) {		diva_os_sleep(10);	}	disconnect_didd();	if ((buffer = diva_maint_finit())) {		diva_os_free (0, buffer);	}	memset(&MAdapter, 0, sizeof(MAdapter));	dprintf = no_printf;}

⌨️ 快捷键说明

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