1 /* $Id: mntfunc.c,v 1.19.6.4 2005/01/31 12:22:20 armin Exp $
3 * Driver for Eicon DIVA Server ISDN cards.
6 * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
7 * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
9 * This software may be used and distributed according to the terms
10 * of the GNU General Public License, incorporated herein by reference.
19 extern char *DRIVERRELEASE_MNT;
21 #define DBG_MINIMUM (DL_LOG + DL_FTL + DL_ERR)
22 #define DBG_DEFAULT (DBG_MINIMUM + DL_XLOG + DL_REG)
24 extern void DIVA_DIDD_Read(void *, int);
26 static dword notify_handle;
27 static DESCRIPTOR DAdapter;
28 static DESCRIPTOR MAdapter;
29 static DESCRIPTOR MaintDescriptor =
30 { IDI_DIMAINT, 0, 0, (IDI_CALL) diva_maint_prtComp };
32 extern int diva_os_copy_to_user(void *os_handle, void __user *dst,
33 const void *src, int length);
34 extern int diva_os_copy_from_user(void *os_handle, void *dst,
35 const void __user *src, int length);
37 static void no_printf(unsigned char *x, ...)
39 /* dummy debug function */
45 * DIDD callback function
47 static void *didd_callback(void *context, DESCRIPTOR * adapter,
50 if (adapter->type == IDI_DADAPTER) {
51 DBG_ERR(("cb: Change in DAdapter ? Oops ?."));
52 } else if (adapter->type == IDI_DIMAINT) {
55 memset(&MAdapter, 0, sizeof(MAdapter));
58 memcpy(&MAdapter, adapter, sizeof(MAdapter));
59 dprintf = (DIVA_DI_PRINTF) MAdapter.request;
60 DbgRegister("MAINT", DRIVERRELEASE_MNT, DBG_DEFAULT);
62 } else if ((adapter->type > 0) && (adapter->type < 16)) {
64 diva_mnt_remove_xdi_adapter(adapter);
66 diva_mnt_add_xdi_adapter(adapter);
75 static int DIVA_INIT_FUNCTION connect_didd(void)
80 DESCRIPTOR DIDD_Table[MAX_DESCRIPTORS];
82 DIVA_DIDD_Read(DIDD_Table, sizeof(DIDD_Table));
84 for (x = 0; x < MAX_DESCRIPTORS; x++) {
85 if (DIDD_Table[x].type == IDI_DADAPTER) { /* DADAPTER found */
87 memcpy(&DAdapter, &DIDD_Table[x], sizeof(DAdapter));
88 req.didd_notify.e.Req = 0;
89 req.didd_notify.e.Rc =
90 IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY;
91 req.didd_notify.info.callback = (void *)didd_callback;
92 req.didd_notify.info.context = NULL;
93 DAdapter.request((ENTITY *) & req);
94 if (req.didd_notify.e.Rc != 0xff)
96 notify_handle = req.didd_notify.info.handle;
97 /* Register MAINT (me) */
98 req.didd_add_adapter.e.Req = 0;
99 req.didd_add_adapter.e.Rc =
100 IDI_SYNC_REQ_DIDD_ADD_ADAPTER;
101 req.didd_add_adapter.info.descriptor =
102 (void *) &MaintDescriptor;
103 DAdapter.request((ENTITY *) & req);
104 if (req.didd_add_adapter.e.Rc != 0xff)
106 } else if ((DIDD_Table[x].type > 0)
107 && (DIDD_Table[x].type < 16)) {
108 diva_mnt_add_xdi_adapter(&DIDD_Table[x]);
115 * disconnect from didd
117 static void DIVA_EXIT_FUNCTION disconnect_didd(void)
121 req.didd_notify.e.Req = 0;
122 req.didd_notify.e.Rc = IDI_SYNC_REQ_DIDD_REMOVE_ADAPTER_NOTIFY;
123 req.didd_notify.info.handle = notify_handle;
124 DAdapter.request((ENTITY *) & req);
126 req.didd_remove_adapter.e.Req = 0;
127 req.didd_remove_adapter.e.Rc = IDI_SYNC_REQ_DIDD_REMOVE_ADAPTER;
128 req.didd_remove_adapter.info.p_request =
129 (IDI_CALL) MaintDescriptor.request;
130 DAdapter.request((ENTITY *) & req);
136 int maint_read_write(void __user *buf, int count)
142 if (count < (3 * sizeof(dword)))
145 if (diva_os_copy_from_user(NULL, (void *) &data[0],
146 buf, 3 * sizeof(dword))) {
150 cmd = *(dword *) & data[0]; /* command */
151 id = *(dword *) & data[4]; /* driver id */
152 mask = *(dword *) & data[8]; /* mask or size */
155 case DITRACE_CMD_GET_DRIVER_INFO:
156 if ((ret = diva_get_driver_info(id, data, sizeof(data))) > 0) {
157 if ((count < ret) || diva_os_copy_to_user
158 (NULL, buf, (void *) &data[0], ret))
165 case DITRACE_READ_DRIVER_DBG_MASK:
166 if ((ret = diva_get_driver_dbg_mask(id, (byte *) data)) > 0) {
167 if ((count < ret) || diva_os_copy_to_user
168 (NULL, buf, (void *) &data[0], ret))
175 case DITRACE_WRITE_DRIVER_DBG_MASK:
176 if ((ret = diva_set_driver_dbg_mask(id, mask)) <= 0) {
182 Filter commands will ignore the ID due to fact that filtering affects
183 the B- channel and Audio Tap trace levels only. Also MAINT driver will
184 select the right trace ID by itself
186 case DITRACE_WRITE_SELECTIVE_TRACE_FILTER:
188 ret = diva_set_trace_filter (1, "*");
189 } else if (mask < sizeof(data)) {
190 if (diva_os_copy_from_user(NULL, data, (char __user *)buf+12, mask)) {
193 ret = diva_set_trace_filter ((int)mask, data);
200 case DITRACE_READ_SELECTIVE_TRACE_FILTER:
201 if ((ret = diva_get_trace_filter (sizeof(data), data)) > 0) {
202 if (diva_os_copy_to_user (NULL, buf, data, ret))
209 case DITRACE_READ_TRACE_ENTRY:{
210 diva_os_spin_lock_magic_t old_irql;
212 diva_dbg_entry_head_t *pmsg;
215 if (!(pbuf = diva_os_malloc(0, mask))) {
221 diva_maint_get_message(&size, &old_irql))) {
225 diva_maint_ack_message(0, &old_irql);
230 memcpy(pbuf, pmsg, size);
231 diva_maint_ack_message(1, &old_irql);
232 if ((count < size) ||
233 diva_os_copy_to_user (NULL, buf, (void *) pbuf, size))
237 diva_os_free(0, pbuf);
241 case DITRACE_READ_TRACE_ENTRYS:{
242 diva_os_spin_lock_magic_t old_irql;
244 diva_dbg_entry_head_t *pmsg;
252 if (!(pbuf = diva_os_malloc(0, mask))) {
258 diva_maint_get_message(&size, &old_irql))) {
261 if ((size + 8) > mask) {
262 diva_maint_ack_message(0, &old_irql);
268 pbuf[written++] = (byte) size;
269 pbuf[written++] = (byte) (size >> 8);
275 memcpy(&pbuf[written], pmsg, size);
276 diva_maint_ack_message(1, &old_irql);
285 if ((count < written) || diva_os_copy_to_user(NULL, buf, (void *) pbuf, written)) {
290 diva_os_free(0, pbuf);
303 int DIVA_INIT_FUNCTION mntfunc_init(int *buffer_length, void **buffer,
304 unsigned long diva_dbg_mem)
306 if (*buffer_length < 64) {
309 if (*buffer_length > 512) {
310 *buffer_length = 512;
312 *buffer_length *= 1024;
315 *buffer = (void *) diva_dbg_mem;
317 while ((*buffer_length >= (64 * 1024))
319 (!(*buffer = diva_os_malloc (0, *buffer_length)))) {
320 *buffer_length -= 1024;
324 DBG_ERR(("init: Can not alloc trace buffer"));
329 if (diva_maint_init(*buffer, *buffer_length, (diva_dbg_mem == 0))) {
331 diva_os_free (0, *buffer);
333 DBG_ERR(("init: maint init failed"));
337 if (!connect_didd()) {
338 DBG_ERR(("init: failed to connect to DIDD."));
341 diva_os_free (0, *buffer);
351 void DIVA_EXIT_FUNCTION mntfunc_finit(void)
358 while (diva_mnt_shutdown_xdi_adapters() && i--) {
364 if ((buffer = diva_maint_finit())) {
365 diva_os_free (0, buffer);
368 memset(&MAdapter, 0, sizeof(MAdapter));