]>
Commit | Line | Data |
---|---|---|
1 | #include "cdb_read.h" | |
2 | ||
3 | int max_ce = MAXCARDS; | |
4 | int ce_idx = 0; | |
5 | int max_vario = MAXVARIO; | |
6 | int vario_idx; | |
7 | int name_str_cnt = 0; | |
8 | int max_name_str_cnt = MAXNAMECNT; | |
9 | int max_ivendor = MAXCARDS; | |
10 | int ivendor_idx = 0; | |
11 | ||
12 | char *name_str; | |
13 | cdb_isdn_card *cards; | |
14 | cdb_isdn_vario *varios; | |
15 | cdb_isdn_vendor *vendors; | |
16 | ||
17 | int *isdncard_id; | |
18 | ||
19 | int drvid_cnt; | |
20 | int drv_subtyp_cnt; | |
21 | int drv_typ_cnt; | |
22 | int supported_cnt; | |
23 | ||
24 | int not_supported = 0; | |
25 | ||
26 | static struct _vendorshortnames_t _vendorshortnames[] = { | |
27 | {"AVM Computersysteme Vertriebs GmbH","AVM"}, | |
28 | {"High Soft Tech","HST"}, | |
29 | {"Cologne Chip AG","CC"}, | |
30 | {"Telekom AG","DTAG"}, | |
31 | {"TigerJet","TJET"}, | |
32 | {"ASUSCOM","Asus"}, | |
33 | {"U.S.Robotics","USR"}, | |
34 | {"SGS Thomson Microelectronics","SGST"}, | |
35 | {"Abocom/Magitek","Abocom"}, | |
36 | {NULL,NULL}, | |
37 | }; | |
38 | ||
39 | static int compare_vendor(cdb_isdn_vendor *v1, cdb_isdn_vendor *v2) { | |
40 | return(strcasecmp(v1->name, v2->name)); | |
41 | } | |
42 | ||
43 | static int compare_card(cdb_isdn_card *c1, cdb_isdn_card *c2) { | |
44 | return(strcasecmp(c1->name, c2->name)); | |
45 | } | |
46 | ||
47 | int compare_name(const int *c1, const int *c2) { | |
48 | return(strcasecmp(cards[*c1].name, | |
49 | cards[*c2].name)); | |
50 | } | |
51 | ||
52 | static int compare_type(cdb_isdn_vario *v1, cdb_isdn_vario *v2) { | |
53 | int x= v1->typ - v2->typ; | |
54 | ||
55 | if (!x) | |
56 | x=v1->subtyp - v2->subtyp; | |
57 | return(x); | |
58 | } | |
59 | ||
60 | static int compare_id(const int *c1, const int *c2) { | |
61 | int x = cards[*c1].vendor - cards[*c2].vendor; | |
62 | ||
63 | if (!x) | |
64 | x = cards[*c1].device - | |
65 | cards[*c2].device; | |
66 | if (!x) | |
67 | x = cards[*c1].subvendor - | |
68 | cards[*c2].subvendor; | |
69 | if (!x) | |
70 | x = cards[*c1].subdevice - | |
71 | cards[*c2].subdevice; | |
72 | return(x); | |
73 | } | |
74 | ||
75 | static char *add_name(const char *str, int merge) { | |
76 | char *p; | |
77 | int l; | |
78 | ||
79 | if (!str) | |
80 | return(NULL); | |
81 | if (merge) { | |
82 | p = name_str; | |
83 | while (*p) { | |
84 | if (!strcmp(p, str)) | |
85 | break; | |
86 | p += strlen(p) +1; | |
87 | if (p >= (name_str + max_name_str_cnt)) | |
88 | return(NULL); | |
89 | } | |
90 | if (*p) | |
91 | return(p); | |
92 | } else { | |
93 | p = name_str + name_str_cnt; | |
94 | } | |
95 | l = strlen(str) +1; | |
96 | if ((p + l) >= (name_str + max_name_str_cnt)) | |
97 | return(NULL); | |
98 | strcpy(p, str); | |
99 | name_str_cnt += l; | |
100 | return(p); | |
101 | } | |
102 | ||
103 | static char stmp[4096],sstmp[4096]; | |
104 | ||
105 | static char *add_lname(int v, const char *str) { | |
106 | sprintf(stmp, "%s %s", vendors[v].shortname, str); | |
107 | return(add_name(stmp, 1)); | |
108 | } | |
109 | ||
110 | static char *add_name_list(const char *str, const char *list) { | |
111 | if (!list || !list[0]) | |
112 | return(add_name(str, 1)); | |
113 | sprintf(stmp, "%s,%s", list, str); | |
114 | return(add_name(stmp, 1)); | |
115 | } | |
116 | ||
117 | static char *add_sortedname_list(const char *str, const char *list, const char *fmt) { | |
118 | u_int v,i,flg=0; | |
119 | char *t,*p; | |
120 | if (!list || !list[0]) | |
121 | return(add_name(str, 1)); | |
122 | strncpy(stmp, list, 4096); | |
123 | sscanf(str, fmt, &v); | |
124 | p = sstmp; | |
125 | t = strtok(stmp, ","); | |
126 | while (t) { | |
127 | sscanf(t, fmt, &i); | |
128 | if (!flg && i>v) { | |
129 | flg++; | |
130 | p += sprintf(p, fmt, v); | |
131 | *p++ = ','; | |
132 | } | |
133 | p += sprintf(p, fmt, i); | |
134 | *p++ = ','; | |
135 | t = strtok(NULL, ","); | |
136 | } | |
137 | if (!flg) | |
138 | p += sprintf(p, fmt, v); | |
139 | else | |
140 | p--; | |
141 | *p = 0; | |
142 | return(add_name(sstmp, 1)); | |
143 | } | |
144 | ||
145 | static int add_vendor(char *v, int card) { | |
146 | int i,found = 0; | |
147 | ||
148 | for(i=0;i < ivendor_idx; i++) { | |
149 | if (!strcmp(v, vendors[i].name)) { | |
150 | vendors[i].refcnt++; | |
151 | return(i); | |
152 | } | |
153 | } | |
154 | if (ivendor_idx < max_ivendor) { | |
155 | i=0; | |
156 | while (_vendorshortnames[i].lname) { | |
157 | if (!strcmp(v, _vendorshortnames[i].lname)) { | |
158 | found++; | |
159 | break; | |
160 | } else if (!strcmp(v, _vendorshortnames[i].sname)) { | |
161 | found++; | |
162 | break; | |
163 | } | |
164 | i++; | |
165 | } | |
166 | if (found) { | |
167 | if (!(vendors[ivendor_idx].name = add_name(_vendorshortnames[i].lname, 1))) | |
168 | return(-1); | |
169 | if (!(vendors[ivendor_idx].shortname = add_name(_vendorshortnames[i].sname, 1))) | |
170 | return(-1); | |
171 | } else { | |
172 | char *p; | |
173 | if (!(vendors[ivendor_idx].name = add_name(v, 1))) | |
174 | return(-1); | |
175 | p = strtok(v, " "); | |
176 | if (p) { | |
177 | if (!(vendors[ivendor_idx].shortname = add_name(p, 1))) | |
178 | return(-1); | |
179 | } else | |
180 | vendors[ivendor_idx].shortname = vendors[ivendor_idx].name; | |
181 | } | |
182 | vendors[ivendor_idx].vnr = ivendor_idx; | |
183 | vendors[ivendor_idx].refcnt++; | |
184 | ivendor_idx++; | |
185 | return(ivendor_idx-1); | |
186 | } else | |
187 | return(-1); | |
188 | } | |
189 | ||
190 | static int new_vario(char *v, int c) { | |
191 | ||
192 | vario_idx++; | |
193 | if (vario_idx>=max_vario) | |
194 | return(-1); | |
195 | drvid_cnt = 0; | |
196 | drv_subtyp_cnt = 0; | |
197 | drv_typ_cnt = 0; | |
198 | not_supported = 0; | |
199 | supported_cnt = 0; | |
200 | if (!(varios[vario_idx].name = add_name(v, 1))) | |
201 | return(-1); | |
202 | if (cards[c].vario>0) { | |
203 | varios[vario_idx-1].next_vario = vario_idx; | |
204 | } else | |
205 | cards[c].vario = vario_idx; | |
206 | varios[vario_idx].handle = vario_idx; | |
207 | varios[vario_idx].card_ref = c; | |
208 | cards[c].vario_cnt++; | |
209 | return(0); | |
210 | } | |
211 | ||
212 | void del_vario(void) { | |
213 | fprintf(stderr, "del_vario: %d %s\n", vario_idx, cards[varios[vario_idx].card_ref].name); | |
214 | cards[varios[vario_idx].card_ref].vario_cnt--; | |
215 | if (vario_idx>0) { | |
216 | if (varios[vario_idx-1].next_vario == vario_idx) { | |
217 | if (cards[varios[vario_idx].card_ref].vario_cnt == 1) | |
218 | cards[varios[vario_idx].card_ref].vario = vario_idx-1; | |
219 | varios[vario_idx-1].next_vario = 0; | |
220 | } else if (cards[varios[vario_idx].card_ref].vario == vario_idx) { | |
221 | cards[varios[vario_idx].card_ref].vario = 0; | |
222 | } else { | |
223 | fprintf(stderr, "del_vario:internal error\n"); | |
224 | exit(98); | |
225 | } | |
226 | } | |
227 | memset(&varios[vario_idx], 0, sizeof(cdb_isdn_vario)); | |
228 | vario_idx--; | |
229 | } | |
230 | ||
231 | int new_entry(void) { | |
232 | if (not_supported) { | |
233 | not_supported = 0; | |
234 | fprintf(stderr, "new_entry:not_supported %s\n", cards[ce_idx].name); | |
235 | if (cards[ce_idx].vario_cnt < 1) { | |
236 | vendors[cards[ce_idx].vhandle].refcnt--; | |
237 | memset(&cards[ce_idx], 0, sizeof(cdb_isdn_card)); | |
238 | ce_idx--; | |
239 | } | |
240 | } | |
241 | ce_idx++; | |
242 | if (ce_idx >= max_ce) | |
243 | return(1); | |
244 | cards[ce_idx].handle = ce_idx; | |
245 | cards[ce_idx].vendor = PCI_ANY_ID; | |
246 | cards[ce_idx].device = PCI_ANY_ID; | |
247 | cards[ce_idx].subvendor = PCI_ANY_ID; | |
248 | cards[ce_idx].subdevice = PCI_ANY_ID; | |
249 | return(0); | |
250 | } | |
251 | ||
252 | void add_current_item(int item, char *val) { | |
253 | int i; | |
254 | char *old; | |
255 | ||
256 | if ((item != vario) && not_supported) | |
257 | return; | |
258 | switch (item) { | |
259 | case vendor: | |
260 | i = add_vendor(val, ce_idx); | |
261 | if (i<0) { | |
262 | fprintf(stderr, "error in add_vendor %s\n", val); | |
263 | exit(100); | |
264 | } | |
265 | cards[ce_idx].vhandle = i; | |
266 | break; | |
267 | case device: | |
268 | cards[ce_idx].name = add_name(val, 1); | |
269 | if (!cards[ce_idx].name) { | |
270 | fprintf(stderr, "error in add_name %s\n", val); | |
271 | exit(101); | |
272 | } | |
273 | cards[ce_idx].lname = add_lname(cards[ce_idx].vhandle, val); | |
274 | if (!cards[ce_idx].lname) { | |
275 | fprintf(stderr, "error in add_lname %s\n", val); | |
276 | exit(101); | |
277 | } | |
278 | break; | |
279 | case vendor_id: | |
280 | i = sscanf(val,"%x", &cards[ce_idx].vendor); | |
281 | if (i!=1) { | |
282 | fprintf(stderr, "error to hex %s\n", val); | |
283 | exit(102); | |
284 | } | |
285 | break; | |
286 | case device_id: | |
287 | i = sscanf(val,"%x", &cards[ce_idx].device); | |
288 | if (i!=1) { | |
289 | fprintf(stderr, "error to hex %s\n", val); | |
290 | exit(102); | |
291 | } | |
292 | break; | |
293 | case subvendor_id: | |
294 | i = sscanf(val,"%x", &cards[ce_idx].subvendor); | |
295 | if (i!=1) { | |
296 | fprintf(stderr, "error to hex %s\n", val); | |
297 | exit(102); | |
298 | } | |
299 | break; | |
300 | case subdevice_id: | |
301 | i = sscanf(val,"%x", &cards[ce_idx].subdevice); | |
302 | if (i!=1) { | |
303 | fprintf(stderr, "error to hex %s\n", val); | |
304 | exit(102); | |
305 | } | |
306 | break; | |
307 | case device_class: | |
308 | cards[ce_idx].Class = add_name(val, 1); | |
309 | if (!cards[ce_idx].name) { | |
310 | fprintf(stderr, "error in add_name %s\n", val); | |
311 | exit(101); | |
312 | } | |
313 | break; | |
314 | case bus_type: | |
315 | cards[ce_idx].bus = add_name(val, 1); | |
316 | if (!cards[ce_idx].name) { | |
317 | fprintf(stderr, "error in add_name %s\n", val); | |
318 | exit(101); | |
319 | } | |
320 | break; | |
321 | case vario: | |
322 | if (new_vario(val, ce_idx)) { | |
323 | fprintf(stderr, "error in new_vario(%s, %d)\n", val, ce_idx); | |
324 | exit(103); | |
325 | } | |
326 | break; | |
327 | case SMP: | |
328 | if (!strcasecmp(val, "no")) | |
329 | varios[vario_idx].smp = 0; | |
330 | else if (!strcasecmp(val, "yes")) | |
331 | varios[vario_idx].smp = 1; | |
332 | break; | |
333 | case drv_id: | |
334 | if (drvid_cnt) { | |
335 | fprintf(stderr, "more as one drvid_cnt (%s) card (%s)\n", val, cards[ce_idx].name); | |
336 | } else { | |
337 | i = sscanf(val,"%x", &varios[vario_idx].drvid); | |
338 | if (i!=1) { | |
339 | fprintf(stderr, "error to hex %s\n", val); | |
340 | exit(102); | |
341 | } | |
342 | } | |
343 | drvid_cnt++; | |
344 | break; | |
345 | case drv_subtyp: | |
346 | if (drv_subtyp_cnt) { | |
347 | fprintf(stderr, "more as one drv_subtyp (%s) card (%s)\n", val, cards[ce_idx].name); | |
348 | } else { | |
349 | i = sscanf(val,"%d", &varios[vario_idx].subtyp); | |
350 | if (i!=1) { | |
351 | fprintf(stderr, "error to decimal %s\n", val); | |
352 | exit(104); | |
353 | } | |
354 | } | |
355 | drv_subtyp_cnt++; | |
356 | break; | |
357 | case drv_typ: | |
358 | if (drv_typ_cnt) { | |
359 | fprintf(stderr, "more as one drv_typ (%s) card (%s)\n", val, cards[ce_idx].name); | |
360 | } else { | |
361 | i = sscanf(val,"%d", &varios[vario_idx].typ); | |
362 | if (i!=1) { | |
363 | fprintf(stderr, "error to decimal %s\n", val); | |
364 | exit(104); | |
365 | } | |
366 | } | |
367 | drv_typ_cnt++; | |
368 | break; | |
369 | case interface: | |
370 | varios[vario_idx].interface = add_name_list(val, varios[vario_idx].interface); | |
371 | break; | |
372 | case line_cnt: | |
373 | i = sscanf(val,"%d", &cards[ce_idx].line_cnt); | |
374 | if (i!=1) { | |
375 | fprintf(stderr, "error to hex %s\n", val); | |
376 | exit(102); | |
377 | } | |
378 | break; | |
379 | case line_protocol: | |
380 | varios[vario_idx].protocol = add_name_list(val, varios[vario_idx].protocol); | |
381 | break; | |
382 | case module: | |
383 | varios[vario_idx].mod_name = add_name(val, 1); | |
384 | break; | |
385 | case need_packages: | |
386 | varios[vario_idx].need_pkg = add_name_list(val, varios[vario_idx].need_pkg); | |
387 | break; | |
388 | case supported: | |
389 | if (supported_cnt) | |
390 | fprintf(stderr, "more as one supported entry (%s) vendor(%s) card(%s)\n", val, | |
391 | vendors[cards[ce_idx].vhandle].name, cards[ce_idx].name); | |
392 | if (!strcasecmp(val, "not")) { | |
393 | not_supported = 1; | |
394 | del_vario(); | |
395 | } | |
396 | supported_cnt++; | |
397 | break; | |
398 | case feature: | |
399 | varios[vario_idx].features = add_name_list(val, varios[vario_idx].features); | |
400 | break; | |
401 | case info: | |
402 | old = name_str + name_str_cnt; | |
403 | varios[vario_idx].info = add_name(val, 1); | |
404 | if (old == varios[vario_idx].info) | |
405 | fprintf(stderr, "info(%s): %s\n", cards[ce_idx].name, varios[vario_idx].info); | |
406 | break; | |
407 | case special: | |
408 | break; | |
409 | case firmware: | |
410 | varios[vario_idx].firmware = add_name(val, 1); | |
411 | break; | |
412 | case short_description: | |
413 | old = name_str + name_str_cnt; | |
414 | varios[vario_idx].description = add_name(val, 1); | |
415 | if (old == varios[vario_idx].description) | |
416 | fprintf(stderr, "description(%s): %s\n", cards[ce_idx].name, varios[vario_idx].description); | |
417 | break; | |
418 | case IRQ: | |
419 | varios[vario_idx].irq = add_sortedname_list(val, varios[vario_idx].irq, "%d"); | |
420 | break; | |
421 | case IO: | |
422 | varios[vario_idx].io = add_sortedname_list(val, varios[vario_idx].io, "0x%x"); | |
423 | break; | |
424 | case MEMBASE: | |
425 | varios[vario_idx].membase = add_sortedname_list(val, varios[vario_idx].membase, "0x%x"); | |
426 | break; | |
427 | case alternative_name: | |
428 | break; | |
429 | case revision: | |
430 | i = sscanf(val,"%x", &cards[ce_idx].revision); | |
431 | if (i!=1) { | |
432 | fprintf(stderr, "error to hex %s\n", val); | |
433 | exit(102); | |
434 | } | |
435 | if ((cards[ce_idx].subvendor == PCI_ANY_ID) && | |
436 | (cards[ce_idx].subdevice == PCI_ANY_ID)) | |
437 | cards[ce_idx].subvendor = cards[ce_idx].revision; | |
438 | break; | |
439 | } | |
440 | } | |
441 | ||
442 | void SortVendors(void) { | |
443 | int v,c; | |
444 | ||
445 | qsort(vendors, ivendor_idx, sizeof(cdb_isdn_vendor), (fcmp)compare_vendor); | |
446 | /* readjust card data */ | |
447 | for (c = 1; c <= ce_idx; c++) { | |
448 | for (v = 0; v < ivendor_idx; v++) { | |
449 | if (cards[c].vhandle == vendors[v].vnr) { | |
450 | cards[c].vhandle = v; | |
451 | break; | |
452 | } | |
453 | } | |
454 | } | |
455 | /* now adjust own handle */ | |
456 | for (v = 0; v < ivendor_idx; v++) { | |
457 | vendors[v].vnr = v; | |
458 | } | |
459 | } | |
460 | ||
461 | void SortCards(void) { | |
462 | int v,c; | |
463 | ||
464 | qsort(&cards[1], ce_idx, sizeof(cdb_isdn_card), (fcmp)compare_card); | |
465 | /* readjust vario data */ | |
466 | for (v = 1; v <= vario_idx; v++) { | |
467 | for (c = 1; c <= ce_idx; c++) { | |
468 | if (cards[c].handle == varios[v].card_ref) { | |
469 | varios[v].card_ref = c; | |
470 | break; | |
471 | } | |
472 | } | |
473 | } | |
474 | /* now adjust own handle */ | |
475 | for (c = 0; c <= ce_idx; c++) { | |
476 | cards[c].handle = c; | |
477 | } | |
478 | isdncard_id = malloc(ce_idx*sizeof(int)); | |
479 | if (!isdncard_id) { | |
480 | fprintf(stderr, "no mem for isdncard_id (%d entries)\n", ce_idx); | |
481 | exit(97); | |
482 | } | |
483 | for (c = 0; c < ce_idx; c++) | |
484 | isdncard_id[c] = c + 1; | |
485 | qsort(isdncard_id, ce_idx, sizeof(int), (fcmp)compare_id); | |
486 | } | |
487 | ||
488 | void SortVarios(void) { | |
489 | int v,c,i; | |
490 | ||
491 | qsort(&varios[1], vario_idx, sizeof(cdb_isdn_vario), (fcmp)compare_type); | |
492 | /* readjust vario data */ | |
493 | for (v = 1; v <= vario_idx; v++) { | |
494 | if (varios[v].next_vario) { | |
495 | for (i = 1; i <= vario_idx; i++) { | |
496 | if (varios[i].handle == varios[v].next_vario) { | |
497 | varios[v].next_vario = i; | |
498 | break; | |
499 | } | |
500 | } | |
501 | } | |
502 | } | |
503 | /* readjust card data */ | |
504 | for (c = 1; c <= ce_idx; c++) { | |
505 | for (v = 1; v <= vario_idx; v++) { | |
506 | if (varios[v].handle == cards[c].vario) { | |
507 | cards[c].vario = v; | |
508 | break; | |
509 | } | |
510 | } | |
511 | } | |
512 | /* now adjust own handle */ | |
513 | for (v = 1; v <= vario_idx; v++) { | |
514 | varios[v].handle = v; | |
515 | } | |
516 | } | |
517 |