ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / isdn / hardware / eicon / diddfunc.c
1 /* $Id: diddfunc.c,v 1.14 2003/08/25 10:06:37 schindler Exp $
2  *
3  * DIDD Interface module for Eicon active cards.
4  * 
5  * Functions are in dadapter.c 
6  * 
7  * Copyright 2002-2003 by Armin Schindler (mac@melware.de) 
8  * Copyright 2002-2003 Cytronics & Melware (info@melware.de)
9  * 
10  * This software may be used and distributed according to the terms
11  * of the GNU General Public License, incorporated herein by reference.
12  */
13
14 #include "platform.h"
15 #include "di_defs.h"
16 #include "dadapter.h"
17 #include "divasync.h"
18
19 #define MAX_DESCRIPTORS  32
20
21 #define DBG_MINIMUM  (DL_LOG + DL_FTL + DL_ERR)
22 #define DBG_DEFAULT  (DBG_MINIMUM + DL_XLOG + DL_REG)
23
24
25 extern void DIVA_DIDD_Read(void *, int);
26 extern char *DRIVERRELEASE_DIDD;
27 static dword notify_handle;
28 static DESCRIPTOR _DAdapter;
29
30 /*
31  * didd callback function
32  */
33 static void *didd_callback(void *context, DESCRIPTOR * adapter,
34                            int removal)
35 {
36         if (adapter->type == IDI_DADAPTER) {
37                 DBG_ERR(("Notification about IDI_DADAPTER change ! Oops."))
38                 return (NULL);
39         } else if (adapter->type == IDI_DIMAINT) {
40                 if (removal) {
41                         DbgDeregister();
42                 } else {
43                         DbgRegister("DIDD", DRIVERRELEASE_DIDD, DBG_DEFAULT);
44                 }
45         }
46         return (NULL);
47 }
48
49 /*
50  * connect to didd
51  */
52 static int DIVA_INIT_FUNCTION connect_didd(void)
53 {
54         int x = 0;
55         int dadapter = 0;
56         IDI_SYNC_REQ req;
57         DESCRIPTOR DIDD_Table[MAX_DESCRIPTORS];
58
59         DIVA_DIDD_Read(DIDD_Table, sizeof(DIDD_Table));
60
61         for (x = 0; x < MAX_DESCRIPTORS; x++) {
62                 if (DIDD_Table[x].type == IDI_DADAPTER) {       /* DADAPTER found */
63                         dadapter = 1;
64                         memcpy(&_DAdapter, &DIDD_Table[x], sizeof(_DAdapter));
65                         req.didd_notify.e.Req = 0;
66                         req.didd_notify.e.Rc =
67                             IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY;
68                         req.didd_notify.info.callback = (void *)didd_callback;
69                         req.didd_notify.info.context = 0;
70                         _DAdapter.request((ENTITY *) & req);
71                         if (req.didd_notify.e.Rc != 0xff)
72                                 return (0);
73                         notify_handle = req.didd_notify.info.handle;
74                 } else if (DIDD_Table[x].type == IDI_DIMAINT) { /* MAINT found */
75                         DbgRegister("DIDD", DRIVERRELEASE_DIDD, DBG_DEFAULT);
76                 }
77         }
78         return (dadapter);
79 }
80
81 /*
82  * disconnect from didd
83  */
84 static void DIVA_EXIT_FUNCTION disconnect_didd(void)
85 {
86         IDI_SYNC_REQ req;
87
88         req.didd_notify.e.Req = 0;
89         req.didd_notify.e.Rc = IDI_SYNC_REQ_DIDD_REMOVE_ADAPTER_NOTIFY;
90         req.didd_notify.info.handle = notify_handle;
91         _DAdapter.request((ENTITY *) & req);
92 }
93
94 /*
95  * init
96  */
97 int DIVA_INIT_FUNCTION diddfunc_init(void)
98 {
99         diva_didd_load_time_init();
100
101         if (!connect_didd()) {
102                 DBG_ERR(("init: failed to connect to DIDD."))
103                 diva_didd_load_time_finit();
104                 return (0);
105         }
106         return (1);
107 }
108
109 /*
110  * finit
111  */
112 void DIVA_EXIT_FUNCTION diddfunc_finit(void)
113 {
114         DbgDeregister();
115         disconnect_didd();
116         diva_didd_load_time_finit();
117 }