Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
divasfunc.c
Go to the documentation of this file.
1 /* $Id: divasfunc.c,v 1.23.4.2 2004/08/28 20:03:53 armin Exp $
2  *
3  * Low level driver for Eicon DIVA Server ISDN cards.
4  *
5  * Copyright 2000-2003 by Armin Schindler ([email protected])
6  * Copyright 2000-2003 Cytronics & Melware ([email protected])
7  *
8  * This software may be used and distributed according to the terms
9  * of the GNU General Public License, incorporated herein by reference.
10  */
11 
12 #include "platform.h"
13 #include "di_defs.h"
14 #include "pc.h"
15 #include "di.h"
16 #include "io.h"
17 #include "divasync.h"
18 #include "diva.h"
19 #include "xdi_vers.h"
20 
21 #define DBG_MINIMUM (DL_LOG + DL_FTL + DL_ERR)
22 #define DBG_DEFAULT (DBG_MINIMUM + DL_XLOG + DL_REG)
23 
24 static int debugmask;
25 
26 extern void DIVA_DIDD_Read(void *, int);
27 
29 
30 extern char *DRIVERRELEASE_DIVAS;
31 
32 static dword notify_handle;
33 static DESCRIPTOR DAdapter;
34 static DESCRIPTOR MAdapter;
35 
36 /* --------------------------------------------------------------------------
37  MAINT driver connector section
38  -------------------------------------------------------------------------- */
39 static void no_printf(unsigned char *x, ...)
40 {
41  /* dummy debug function */
42 }
43 
44 #include "debuglib.c"
45 
46 /*
47  * get the adapters serial number
48  */
50 {
51  int contr = 0;
52 
53  if ((contr = ((IoAdapter->serialNo & 0xff000000) >> 24))) {
54  sprintf(buf, "%d-%d",
55  IoAdapter->serialNo & 0x00ffffff, contr + 1);
56  } else {
57  sprintf(buf, "%d", IoAdapter->serialNo);
58  }
59 }
60 
61 /*
62  * register a new adapter
63  */
65 {
66  DESCRIPTOR d;
68 
69  if (card && ((card - 1) < MAX_ADAPTER) &&
70  IoAdapters[card - 1] && Requests[card - 1]) {
71  d.type = IoAdapters[card - 1]->Properties.DescType;
72  d.request = Requests[card - 1];
73  d.channels = IoAdapters[card - 1]->Properties.Channels;
74  d.features = IoAdapters[card - 1]->Properties.Features;
75  DBG_TRC(("DIDD register A(%d) channels=%d", card,
76  d.channels))
77  /* workaround for different Name in structure */
78  strlcpy(IoAdapters[card - 1]->Name,
79  IoAdapters[card - 1]->Properties.Name,
80  sizeof(IoAdapters[card - 1]->Name));
81  req.didd_remove_adapter.e.Req = 0;
83  req.didd_add_adapter.info.descriptor = (void *) &d;
84  DAdapter.request((ENTITY *)&req);
85  if (req.didd_add_adapter.e.Rc != 0xff) {
86  DBG_ERR(("DIDD register A(%d) failed !", card))
87  }
88  IoAdapters[card - 1]->os_trap_nfy_Fnc = NULL;
89  }
90 }
91 
92 /*
93  * remove an adapter
94  */
96 {
98  ADAPTER *a = &IoAdapters[card - 1]->a;
99 
100  IoAdapters[card - 1]->os_trap_nfy_Fnc = NULL;
101  DBG_TRC(("DIDD de-register A(%d)", card))
102  req.didd_remove_adapter.e.Req = 0;
104  req.didd_remove_adapter.info.p_request =
105  (IDI_CALL) Requests[card - 1];
106  DAdapter.request((ENTITY *)&req);
107  memset(&(a->IdTable), 0x00, 256);
108 }
109 
110 /*
111  * start debug
112  */
113 static void start_dbg(void)
114 {
115  DbgRegister("DIVAS", DRIVERRELEASE_DIVAS, (debugmask) ? debugmask : DBG_DEFAULT);
116  DBG_LOG(("DIVA ISDNXDI BUILD (%s[%s])",
117  DIVA_BUILD, diva_xdi_common_code_build))
118  }
119 
120 /*
121  * stop debug
122  */
123 static void stop_dbg(void)
124 {
125  DbgDeregister();
126  memset(&MAdapter, 0, sizeof(MAdapter));
127  dprintf = no_printf;
128 }
129 
130 /*
131  * didd callback function
132  */
133 static void *didd_callback(void *context, DESCRIPTOR *adapter,
134  int removal)
135 {
136  if (adapter->type == IDI_DADAPTER) {
137  DBG_ERR(("Notification about IDI_DADAPTER change ! Oops."));
138  return (NULL);
139  }
140 
141  if (adapter->type == IDI_DIMAINT) {
142  if (removal) {
143  stop_dbg();
144  } else {
145  memcpy(&MAdapter, adapter, sizeof(MAdapter));
146  dprintf = (DIVA_DI_PRINTF) MAdapter.request;
147  start_dbg();
148  }
149  }
150  return (NULL);
151 }
152 
153 /*
154  * connect to didd
155  */
156 static int __init connect_didd(void)
157 {
158  int x = 0;
159  int dadapter = 0;
161  DESCRIPTOR DIDD_Table[MAX_DESCRIPTORS];
162 
163  DIVA_DIDD_Read(DIDD_Table, sizeof(DIDD_Table));
164 
165  for (x = 0; x < MAX_DESCRIPTORS; x++) {
166  if (DIDD_Table[x].type == IDI_DADAPTER) { /* DADAPTER found */
167  dadapter = 1;
168  memcpy(&DAdapter, &DIDD_Table[x], sizeof(DAdapter));
169  req.didd_notify.e.Req = 0;
170  req.didd_notify.e.Rc =
172  req.didd_notify.info.callback = (void *)didd_callback;
173  req.didd_notify.info.context = NULL;
174  DAdapter.request((ENTITY *)&req);
175  if (req.didd_notify.e.Rc != 0xff) {
176  stop_dbg();
177  return (0);
178  }
179  notify_handle = req.didd_notify.info.handle;
180  } else if (DIDD_Table[x].type == IDI_DIMAINT) { /* MAINT found */
181  memcpy(&MAdapter, &DIDD_Table[x], sizeof(DAdapter));
182  dprintf = (DIVA_DI_PRINTF) MAdapter.request;
183  start_dbg();
184  }
185  }
186 
187  if (!dadapter) {
188  stop_dbg();
189  }
190 
191  return (dadapter);
192 }
193 
194 /*
195  * disconnect from didd
196  */
197 static void disconnect_didd(void)
198 {
200 
201  stop_dbg();
202 
203  req.didd_notify.e.Req = 0;
205  req.didd_notify.info.handle = notify_handle;
206  DAdapter.request((ENTITY *)&req);
207 }
208 
209 /*
210  * init
211  */
212 int __init divasfunc_init(int dbgmask)
213 {
214  char *version;
215 
216  debugmask = dbgmask;
217 
218  if (!connect_didd()) {
219  DBG_ERR(("divasfunc: failed to connect to DIDD."))
220  return (0);
221  }
222 
223  version = diva_xdi_common_code_build;
224 
226 
227  return (1);
228 }
229 
230 /*
231  * exit
232  */
233 void divasfunc_exit(void)
234 {
236  disconnect_didd();
237 }