]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/hwinfo/src/isdn/cdbisdn.c
Kleiner netter neuer Versuch.
[people/pmueller/ipfire-2.x.git] / src / hwinfo / src / isdn / cdbisdn.c
CommitLineData
a6316ce4
MT
1#include <stdlib.h>
2#include <stdio.h>
3#include <string.h>
4#include <errno.h>
5#include "hd.h"
6#include "hd_int.h"
7
8#define debprintf(a...)
9// #define debprintf(a...) fprintf(stderr, ## a)
10
11/* private data */
12
13#include "cdb/isdn_cdb.h"
14#include "cdb/cdb_hwdb.h"
15
16static int CDBISDN_vendor_cnt;
17static int CDBISDN_card_cnt;
18static int CDBISDN_vario_cnt;
19static int CDBISDN_name_size;
20static char *CDBISDN_names;
21
22static cdb_isdn_vendor *cdb_isdnvendor_info;
23static cdb_isdn_card *cdb_isdncard_info;
24static int *cdb_isdncard_idsorted;
25static cdb_isdn_vario *cdb_isdnvario_info;
26static int cdb_dbversion;
27static char cdb_date[32];
28
29static char line[1024];
30
31static int CDBISDN_readhwdb;
32
33static int
34init_cdbisdn(void)
35{
36 FILE *cdb;
37 char *s, *p = NULL;
38 int rectyp, l, cnt = 0, icnt = 0;
39
40 cdb = fopen(CDBISDN_HWDB_FILE, "rb");
41 if (!cdb) {
42 debprintf("open failure %s\n", CDBISDN_HWDB_FILE);
43 goto fallback;
44 }
45 while (!feof(cdb)) {
46 s = fgets(line, 1024, cdb);
47 if (!s)
48 break;
49 if (!s[0] || s[0] == '!' || s[0] == '#' || s[0] == '\n')
50 continue;
51 if (s[0] != '$') {
52 debprintf("got wrong line %s\n", s);
53 continue;
54 }
55 sscanf(s, "$%d", &rectyp);
56 switch(rectyp) {
57 case IWHREC_TYPE_VERSION:
58 sscanf(s + 4, "%d", &cdb_dbversion);
59 break;
60 case IWHREC_TYPE_DATE:
61 l = strlen(s + 4);
62 if (!l)
63 continue;
64 l--;
65 if (l > 31)
66 l = 31;
67 strncpy(cdb_date, s + 4, l);
68 cdb_date[l] = 0;
69 break;
70 case IWHREC_TYPE_NAME_SIZE:
71 sscanf(s + 4, "%d", &CDBISDN_name_size);
72 CDBISDN_names = calloc(CDBISDN_name_size + 1, 1);
73 if (!CDBISDN_names) {
74 debprintf("fail to allocate %d bytes for CDBISDN_names\n", CDBISDN_name_size);
75 goto fallback_close;
76 }
77 p = CDBISDN_names;
78 cnt = 0;
79 icnt = 0;
80 break;
81 case IWHREC_TYPE_NAME_DATA:
82 if (!p)
83 goto fallback_close;
84 l = strlen(s + 4);
85 icnt += l;
86 if (icnt > CDBISDN_name_size) {
87 debprintf("name_size overflow %d/%d\n", icnt, CDBISDN_name_size);
88 goto fallback_close;
89 }
90 strcpy(p, s + 4);
91 p[l-1] = 0;
92 p += l;
93 cnt++;
94 break;
95 case IWHREC_TYPE_NAME_COUNT:
96 sscanf(s + 4, "%d", &l);
97 if (cnt != l)
98 goto fallback_close;
99 break;
100 case IWHREC_TYPE_VENDOR_COUNT:
101 sscanf(s + 4, "%d", &CDBISDN_vendor_cnt);
102 cdb_isdnvendor_info = calloc(CDBISDN_vendor_cnt, sizeof(cdb_isdn_vendor));
103 if (!cdb_isdnvendor_info) {
104 debprintf("fail to allocate %d vendor structs\n", CDBISDN_vendor_cnt);
105 goto fallback_close;
106 }
107 cnt = 0;
108 break;
109 case IWHREC_TYPE_VENDOR_RECORD:
110 if (cnt >= CDBISDN_vendor_cnt) {
111 debprintf("vendor overflow %d/%d\n", cnt, CDBISDN_vendor_cnt);
112 goto fallback_close;
113 }
114 l = sscanf(s + 4, "%p %p %d %d",
115 &cdb_isdnvendor_info[cnt].name,
116 &cdb_isdnvendor_info[cnt].shortname,
117 &cdb_isdnvendor_info[cnt].vnr,
118 &cdb_isdnvendor_info[cnt].refcnt);
119 if (l != 4) {
120 debprintf("error reading vendor record %s\n", s);
121 goto fallback_close;
122 }
123 cdb_isdnvendor_info[cnt].name = CDBISDN_names + (u_long)cdb_isdnvendor_info[cnt].name;
124 cdb_isdnvendor_info[cnt].shortname = CDBISDN_names + (u_long)cdb_isdnvendor_info[cnt].shortname;
125 cnt++;
126 break;
127 case IWHREC_TYPE_CARD_COUNT:
128 sscanf(s + 4, "%d", &CDBISDN_card_cnt);
129 cdb_isdncard_info = calloc(CDBISDN_card_cnt + 1, sizeof(cdb_isdn_card));
130 cdb_isdncard_idsorted = calloc(CDBISDN_card_cnt, sizeof(int));
131 if (!cdb_isdncard_info || !cdb_isdncard_idsorted) {
132 debprintf("fail to allocate %d vendor structs\n", CDBISDN_card_cnt);
133 goto fallback_close;
134 }
135 cnt = 0;
136 icnt = 0;
137 break;
138 case IWHREC_TYPE_CARD_RECORD:
139 if (cnt > CDBISDN_card_cnt) {
140 debprintf("card overflow %d/%d\n", cnt, CDBISDN_card_cnt);
141 goto fallback_close;
142 }
143 l = sscanf(s + 4, "%d %d %p %p %p %p %d %d %d %d %d %d %d %d %d",
144 &cdb_isdncard_info[cnt].handle, /* internal identifier idx in database */
145 &cdb_isdncard_info[cnt].vhandle, /* internal identifier to vendor database */
146 &cdb_isdncard_info[cnt].name, /* cardname */
147 &cdb_isdncard_info[cnt].lname, /* vendor short name + cardname */
148 &cdb_isdncard_info[cnt].Class, /* CLASS of the card */
149 &cdb_isdncard_info[cnt].bus, /* bus type */
150 &cdb_isdncard_info[cnt].revision, /* revision used with USB */
151 &cdb_isdncard_info[cnt].vendor, /* Vendor ID for ISAPNP and PCI cards */
152 &cdb_isdncard_info[cnt].device, /* Device ID for ISAPNP and PCI cards */
153 &cdb_isdncard_info[cnt].subvendor, /* Subvendor ID for PCI cards */
154 &cdb_isdncard_info[cnt].subdevice, /* Subdevice ID for PCI cards */
155 &cdb_isdncard_info[cnt].features, /* feature flags */
156 &cdb_isdncard_info[cnt].line_cnt, /* count of ISDN ports */
157 &cdb_isdncard_info[cnt].vario_cnt, /* count of driver varios */
158 &cdb_isdncard_info[cnt].vario); /* referenz to driver vario record */
159 if (l != 15) {
160 debprintf("error reading card record %s\n", s);
161 goto fallback_close;
162 }
163 cdb_isdncard_info[cnt].name = CDBISDN_names + (u_long)cdb_isdncard_info[cnt].name;
164 cdb_isdncard_info[cnt].lname = CDBISDN_names + (u_long)cdb_isdncard_info[cnt].lname;
165 cdb_isdncard_info[cnt].Class = CDBISDN_names + (u_long)cdb_isdncard_info[cnt].Class;
166 cdb_isdncard_info[cnt].bus = CDBISDN_names + (u_long)cdb_isdncard_info[cnt].bus;
167 cnt++;
168 break;
169 case IWHREC_TYPE_CARD_IDSORTED:
170 if (icnt >= CDBISDN_card_cnt) {
171 debprintf("card overflow %d/%d\n", icnt, CDBISDN_card_cnt);
172 goto fallback_close;
173 }
174 sscanf(s + 4, "%d", &cdb_isdncard_idsorted[icnt]);
175 icnt++;
176 break;
177 case IWHREC_TYPE_VARIO_COUNT:
178 sscanf(s + 4, "%d", &CDBISDN_vario_cnt);
179 cdb_isdnvario_info = calloc(CDBISDN_vario_cnt+1, sizeof(cdb_isdn_vario));
180 if (!cdb_isdnvario_info) {
181 debprintf("fail to allocate %d vario structs\n", CDBISDN_vario_cnt);
182 goto fallback_close;
183 }
184 cnt = 0;
185 break;
186 case IWHREC_TYPE_VARIO_RECORD:
187 if (cnt > CDBISDN_vario_cnt) {
188 debprintf("vario overflow %d/%d\n", cnt, CDBISDN_vario_cnt);
189 goto fallback_close;
190 }
191 l = sscanf(s + 4, "%d %d %d %d %d %d %p %p %p %p %p %p %p %p %p %p %p %p %p %p %d %p",
192 &cdb_isdnvario_info[cnt].handle, /* idx in database */
193 &cdb_isdnvario_info[cnt].next_vario, /* link to alternate vario */
194 &cdb_isdnvario_info[cnt].drvid, /* unique id of the driver vario */
195 &cdb_isdnvario_info[cnt].typ, /* Type to identify the driver */
196 &cdb_isdnvario_info[cnt].subtyp, /* Subtype of the driver type */
197 &cdb_isdnvario_info[cnt].smp, /* SMP supported ? */
198 &cdb_isdnvario_info[cnt].mod_name, /* name of the driver module */
199 &cdb_isdnvario_info[cnt].para_str, /* optional parameter string */
200 &cdb_isdnvario_info[cnt].mod_preload, /* optional modules to preload */
201 &cdb_isdnvario_info[cnt].cfg_prog, /* optional cfg prog */
202 &cdb_isdnvario_info[cnt].firmware, /* optional firmware to load */
203 &cdb_isdnvario_info[cnt].description, /* optional description */
204 &cdb_isdnvario_info[cnt].need_pkg, /* list of packages needed for function */
205 &cdb_isdnvario_info[cnt].info, /* optional additional info */
206 &cdb_isdnvario_info[cnt].protocol, /* supported D-channel protocols */
207 &cdb_isdnvario_info[cnt].interface, /* supported API interfaces */
208 &cdb_isdnvario_info[cnt].io, /* possible IO ports with legacy ISA cards */
209 &cdb_isdnvario_info[cnt].irq, /* possible interrupts with legacy ISA cards */
210 &cdb_isdnvario_info[cnt].membase, /* possible membase with legacy ISA cards */
211 &cdb_isdnvario_info[cnt].features, /* optional features*/
212 &cdb_isdnvario_info[cnt].card_ref, /* reference to a card */
213 &cdb_isdnvario_info[cnt].name); /* driver name */
214 if (l != 22) {
215 debprintf("error reading vario record %s\n", s);
216 goto fallback_close;
217 }
218 cdb_isdnvario_info[cnt].mod_name = CDBISDN_names + (u_long)cdb_isdnvario_info[cnt].mod_name;
219 cdb_isdnvario_info[cnt].para_str = CDBISDN_names + (u_long)cdb_isdnvario_info[cnt].para_str;
220 cdb_isdnvario_info[cnt].mod_preload = CDBISDN_names + (u_long)cdb_isdnvario_info[cnt].mod_preload;
221 cdb_isdnvario_info[cnt].cfg_prog = CDBISDN_names + (u_long)cdb_isdnvario_info[cnt].cfg_prog;
222 cdb_isdnvario_info[cnt].firmware = CDBISDN_names + (u_long)cdb_isdnvario_info[cnt].firmware;
223 cdb_isdnvario_info[cnt].description = CDBISDN_names + (u_long)cdb_isdnvario_info[cnt].description;
224 cdb_isdnvario_info[cnt].need_pkg = CDBISDN_names + (u_long)cdb_isdnvario_info[cnt].need_pkg;
225 cdb_isdnvario_info[cnt].info = CDBISDN_names + (u_long)cdb_isdnvario_info[cnt].info;
226 cdb_isdnvario_info[cnt].protocol = CDBISDN_names + (u_long)cdb_isdnvario_info[cnt].protocol;
227 cdb_isdnvario_info[cnt].interface = CDBISDN_names + (u_long)cdb_isdnvario_info[cnt].interface;
228 cdb_isdnvario_info[cnt].io = CDBISDN_names + (u_long)cdb_isdnvario_info[cnt].io;
229 cdb_isdnvario_info[cnt].irq = CDBISDN_names + (u_long)cdb_isdnvario_info[cnt].irq;
230 cdb_isdnvario_info[cnt].membase = CDBISDN_names + (u_long)cdb_isdnvario_info[cnt].membase;
231 cdb_isdnvario_info[cnt].features = CDBISDN_names + (u_long)cdb_isdnvario_info[cnt].features;
232 cdb_isdnvario_info[cnt].name = CDBISDN_names + (u_long)cdb_isdnvario_info[cnt].name;
233 cnt++;
234 break;
235 default:
236 debprintf("got wrong RecType %d\n", rectyp);
237 break;
238 }
239 }
240 fclose(cdb);
241 if (CDBISDN_name_size == 0 ||
242 CDBISDN_vendor_cnt == 0 ||
243 CDBISDN_card_cnt == 0 ||
244 CDBISDN_vario_cnt == 0)
245 goto fallback;
246 debprintf("successfull reading %s\n", CDBISDN_HWDB_FILE);
247 CDBISDN_readhwdb = 1;
248 return(0);
249fallback_close:
250 fclose(cdb);
251fallback:
252 debprintf("error reading %s\n", CDBISDN_HWDB_FILE);
253 CDBISDN_vendor_cnt = (sizeof(cdb_isdnvendor_info_init) / sizeof(cdb_isdn_vendor));
254 CDBISDN_card_cnt = ((sizeof(cdb_isdncard_info_init) / sizeof(cdb_isdn_card)) -1);
255 CDBISDN_vario_cnt = ((sizeof(cdb_isdnvario_info_init) / sizeof(cdb_isdn_vario))-1);
256 cdb_isdnvendor_info = cdb_isdnvendor_info_init;
257 cdb_isdncard_info = cdb_isdncard_info_init;
258 cdb_isdncard_idsorted = cdb_isdncard_idsorted_init;
259 cdb_isdnvario_info = cdb_isdnvario_info_init;
260 cdb_dbversion = CDBISDN_DBVERSION;
261 strncpy(cdb_date, CDBISDN_DATE, 31);
262 CDBISDN_readhwdb = 1;
263 return(1);
264}
265
266typedef int (*fcmp) (const void *, const void *);
267
268static int compare_type(cdb_isdn_vario *v1, cdb_isdn_vario *v2) {
269 int x= v1->typ - v2->typ;
270
271 if (!x)
272 x=v1->subtyp - v2->subtyp;
273 return(x);
274}
275
276static int compare_id(const int *c1, const int *c2) {
277 int x= cdb_isdncard_info[*c1].vendor - cdb_isdncard_info[*c2].vendor;
278
279 if (!x)
280 x=cdb_isdncard_info[*c1].device - cdb_isdncard_info[*c2].device;
281 if (!x)
282 x=cdb_isdncard_info[*c1].subvendor - cdb_isdncard_info[*c2].subvendor;
283 if (!x)
284 x=cdb_isdncard_info[*c1].subdevice - cdb_isdncard_info[*c2].subdevice;
285 return(x);
286}
287
288/* interface */
289
290cdb_isdn_vendor *hd_cdbisdn_get_vendor(int handle)
291{
292 if (!CDBISDN_readhwdb)
293 init_cdbisdn();
294 if (handle<0)
295 return(NULL);
296 if ((unsigned)handle >= CDBISDN_vendor_cnt)
297 return(NULL);
298 return(&cdb_isdnvendor_info[handle]);
299}
300
301cdb_isdn_card *hd_cdbisdn_get_card(int handle)
302{
303 if (!CDBISDN_readhwdb)
304 init_cdbisdn();
305 if (handle<=0)
306 return(NULL);
307 if ((unsigned) handle>CDBISDN_card_cnt)
308 return(NULL);
309 return(&cdb_isdncard_info[handle]);
310}
311
312cdb_isdn_vario *hd_cdbisdn_get_vario_from_type(int typ, int subtyp)
313{
314 cdb_isdn_vario key, *ret;
315
316 if (!CDBISDN_readhwdb)
317 CDBISDN_readhwdb = init_cdbisdn();
318 key.typ = typ;
319 key.subtyp = subtyp;
320 if (!(ret=bsearch(&key, &cdb_isdnvario_info[1], CDBISDN_vario_cnt, sizeof(cdb_isdn_vario), (fcmp)compare_type))) {
321 debprintf("ret NULL\n");
322 return(NULL);
323 }
324 return(ret);
325}
326
327cdb_isdn_card *hd_cdbisdn_get_card_from_type(int typ, int subtyp)
328{
329 cdb_isdn_vario *civ;
330
331 if (!CDBISDN_readhwdb)
332 init_cdbisdn();
333 civ = hd_cdbisdn_get_vario_from_type(typ, subtyp);
334 if (civ) {
335 if (civ->card_ref > 0)
336 return(&cdb_isdncard_info[civ->card_ref]);
337 }
338 return(NULL);
339}
340
341cdb_isdn_card *hd_cdbisdn_get_card_from_id(int vendor, int device, int subvendor, int subdevice)
342{
343 int key, *ret;
344
345 if (!CDBISDN_readhwdb)
346 init_cdbisdn();
347 key = 0;
348 cdb_isdncard_info[key].vendor = vendor;
349 cdb_isdncard_info[key].device = device;
350 cdb_isdncard_info[key].subvendor = subvendor;
351 cdb_isdncard_info[key].subdevice = subdevice;
352 if (!(ret=bsearch(&key, cdb_isdncard_idsorted, CDBISDN_card_cnt, sizeof(int), (fcmp)compare_id))) {
353 debprintf("bs1 ret NULL\n");
354 key = 0;
355 cdb_isdncard_info[key].subvendor = PCI_ANY_ID;
356 cdb_isdncard_info[key].subdevice = PCI_ANY_ID;
357 if (!(ret=bsearch(&key, cdb_isdncard_idsorted, CDBISDN_card_cnt, sizeof(int), (fcmp)compare_id))) {
358 debprintf("bs2 ret NULL\n");
359 return(NULL);
360 }
361 }
362 debprintf("ret idx %d\n", *ret);
363 if (*ret <= 0)
364 return(NULL);
365 if ((unsigned) *ret > CDBISDN_card_cnt)
366 return(NULL);
367 return(&cdb_isdncard_info[*ret]);
368}
369
370cdb_isdn_vario *hd_cdbisdn_get_vario(int handle)
371{
372 if (!CDBISDN_readhwdb)
373 init_cdbisdn();
374 if (handle<=0)
375 return(NULL);
376 if ((unsigned) handle > CDBISDN_vario_cnt)
377 return(NULL);
378 return(&cdb_isdnvario_info[handle]);
379}
380
381int hd_cdbisdn_get_version(void)
382{
383 if (!CDBISDN_readhwdb)
384 init_cdbisdn();
385 return(CDBISDN_VERSION);
386}
387
388int hd_cdbisdn_get_db_version(void)
389{
390 if (!CDBISDN_readhwdb)
391 init_cdbisdn();
392 return(cdb_dbversion);
393}
394
395char *hd_cdbisdn_get_db_date(void)
396{
397 if (!CDBISDN_readhwdb)
398 init_cdbisdn();
399 return(cdb_date);
400}