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 __init
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 __exit
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 __init
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 __exit
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
));