1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17#include <linux/types.h>
18#include <linux/stddef.h>
19#include <linux/timer.h>
20#include <linux/config.h>
21#include <linux/init.h>
22#include "hisax.h"
23#include <linux/module.h>
24#include <linux/kernel_stat.h>
25#include <linux/workqueue.h>
26#include <linux/interrupt.h>
27#define HISAX_STATUS_BUFSIZE 4096
28#define INCLUDE_INLINE_FUNCS
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86const char *CardType[] = {
87 "No Card", "Teles 16.0", "Teles 8.0", "Teles 16.3",
88 "Creatix/Teles PnP", "AVM A1", "Elsa ML", "Elsa Quickstep",
89 "Teles PCMCIA", "ITK ix1-micro Rev.2", "Elsa PCMCIA",
90 "Eicon.Diehl Diva", "ISDNLink", "TeleInt", "Teles 16.3c",
91 "Sedlbauer Speed Card", "USR Sportster", "ith mic Linux",
92 "Elsa PCI", "Compaq ISA", "NETjet-S", "Teles PCI",
93 "Sedlbauer Speed Star (PCMCIA)", "AMD 7930", "NICCY", "S0Box",
94 "AVM A1 (PCMCIA)", "AVM Fritz PnP/PCI", "Sedlbauer Speed Fax +",
95 "Siemens I-Surf", "Acer P10", "HST Saphir", "Telekom A4T",
96 "Scitel Quadro", "Gazel", "HFC 2BDS0 PCI", "Winbond 6692",
97 "HFC 2BDS0 SX", "NETspider-U", "HFC-2BDS0-SP PCMCIA",
98 "Hotplug", "Formula-n enter:now PCI a/b",
99};
100
101#ifdef CONFIG_HISAX_ELSA
102#define DEFAULT_CARD ISDN_CTYPE_ELSA
103#define DEFAULT_CFG {0,0,0,0}
104#endif
105
106#ifdef CONFIG_HISAX_AVM_A1
107#undef DEFAULT_CARD
108#undef DEFAULT_CFG
109#define DEFAULT_CARD ISDN_CTYPE_A1
110#define DEFAULT_CFG {10,0x340,0,0}
111#endif
112
113#ifdef CONFIG_HISAX_AVM_A1_PCMCIA
114#undef DEFAULT_CARD
115#undef DEFAULT_CFG
116#define DEFAULT_CARD ISDN_CTYPE_A1_PCMCIA
117#define DEFAULT_CFG {11,0x170,0,0}
118#endif
119
120#ifdef CONFIG_HISAX_FRITZPCI
121#undef DEFAULT_CARD
122#undef DEFAULT_CFG
123#define DEFAULT_CARD ISDN_CTYPE_FRITZPCI
124#define DEFAULT_CFG {0,0,0,0}
125#endif
126
127#ifdef CONFIG_HISAX_16_3
128#undef DEFAULT_CARD
129#undef DEFAULT_CFG
130#define DEFAULT_CARD ISDN_CTYPE_16_3
131#define DEFAULT_CFG {15,0x180,0,0}
132#endif
133
134#ifdef CONFIG_HISAX_S0BOX
135#undef DEFAULT_CARD
136#undef DEFAULT_CFG
137#define DEFAULT_CARD ISDN_CTYPE_S0BOX
138#define DEFAULT_CFG {7,0x378,0,0}
139#endif
140
141#ifdef CONFIG_HISAX_16_0
142#undef DEFAULT_CARD
143#undef DEFAULT_CFG
144#define DEFAULT_CARD ISDN_CTYPE_16_0
145#define DEFAULT_CFG {15,0xd0000,0xd80,0}
146#endif
147
148#ifdef CONFIG_HISAX_TELESPCI
149#undef DEFAULT_CARD
150#undef DEFAULT_CFG
151#define DEFAULT_CARD ISDN_CTYPE_TELESPCI
152#define DEFAULT_CFG {0,0,0,0}
153#endif
154
155#ifdef CONFIG_HISAX_IX1MICROR2
156#undef DEFAULT_CARD
157#undef DEFAULT_CFG
158#define DEFAULT_CARD ISDN_CTYPE_IX1MICROR2
159#define DEFAULT_CFG {5,0x390,0,0}
160#endif
161
162#ifdef CONFIG_HISAX_DIEHLDIVA
163#undef DEFAULT_CARD
164#undef DEFAULT_CFG
165#define DEFAULT_CARD ISDN_CTYPE_DIEHLDIVA
166#define DEFAULT_CFG {0,0x0,0,0}
167#endif
168
169#ifdef CONFIG_HISAX_ASUSCOM
170#undef DEFAULT_CARD
171#undef DEFAULT_CFG
172#define DEFAULT_CARD ISDN_CTYPE_ASUSCOM
173#define DEFAULT_CFG {5,0x200,0,0}
174#endif
175
176#ifdef CONFIG_HISAX_TELEINT
177#undef DEFAULT_CARD
178#undef DEFAULT_CFG
179#define DEFAULT_CARD ISDN_CTYPE_TELEINT
180#define DEFAULT_CFG {5,0x300,0,0}
181#endif
182
183#ifdef CONFIG_HISAX_SEDLBAUER
184#undef DEFAULT_CARD
185#undef DEFAULT_CFG
186#define DEFAULT_CARD ISDN_CTYPE_SEDLBAUER
187#define DEFAULT_CFG {11,0x270,0,0}
188#endif
189
190#ifdef CONFIG_HISAX_SPORTSTER
191#undef DEFAULT_CARD
192#undef DEFAULT_CFG
193#define DEFAULT_CARD ISDN_CTYPE_SPORTSTER
194#define DEFAULT_CFG {7,0x268,0,0}
195#endif
196
197#ifdef CONFIG_HISAX_MIC
198#undef DEFAULT_CARD
199#undef DEFAULT_CFG
200#define DEFAULT_CARD ISDN_CTYPE_MIC
201#define DEFAULT_CFG {12,0x3e0,0,0}
202#endif
203
204#ifdef CONFIG_HISAX_NETJET
205#undef DEFAULT_CARD
206#undef DEFAULT_CFG
207#define DEFAULT_CARD ISDN_CTYPE_NETJET_S
208#define DEFAULT_CFG {0,0,0,0}
209#endif
210
211#ifdef CONFIG_HISAX_HFCS
212#undef DEFAULT_CARD
213#undef DEFAULT_CFG
214#define DEFAULT_CARD ISDN_CTYPE_TELES3C
215#define DEFAULT_CFG {5,0x500,0,0}
216#endif
217
218#ifdef CONFIG_HISAX_HFC_PCI
219#undef DEFAULT_CARD
220#undef DEFAULT_CFG
221#define DEFAULT_CARD ISDN_CTYPE_HFC_PCI
222#define DEFAULT_CFG {0,0,0,0}
223#endif
224
225#ifdef CONFIG_HISAX_HFC_SX
226#undef DEFAULT_CARD
227#undef DEFAULT_CFG
228#define DEFAULT_CARD ISDN_CTYPE_HFC_SX
229#define DEFAULT_CFG {5,0x2E0,0,0}
230#endif
231
232
233#ifdef CONFIG_HISAX_AMD7930
234#undef DEFAULT_CARD
235#undef DEFAULT_CFG
236#define DEFAULT_CARD ISDN_CTYPE_AMD7930
237#define DEFAULT_CFG {12,0x3e0,0,0}
238#endif
239
240#ifdef CONFIG_HISAX_NICCY
241#undef DEFAULT_CARD
242#undef DEFAULT_CFG
243#define DEFAULT_CARD ISDN_CTYPE_NICCY
244#define DEFAULT_CFG {0,0x0,0,0}
245#endif
246
247#ifdef CONFIG_HISAX_ISURF
248#undef DEFAULT_CARD
249#undef DEFAULT_CFG
250#define DEFAULT_CARD ISDN_CTYPE_ISURF
251#define DEFAULT_CFG {5,0x100,0xc8000,0}
252#endif
253
254#ifdef CONFIG_HISAX_HSTSAPHIR
255#undef DEFAULT_CARD
256#undef DEFAULT_CFG
257#define DEFAULT_CARD ISDN_CTYPE_HSTSAPHIR
258#define DEFAULT_CFG {5,0x250,0,0}
259#endif
260
261#ifdef CONFIG_HISAX_BKM_A4T
262#undef DEFAULT_CARD
263#undef DEFAULT_CFG
264#define DEFAULT_CARD ISDN_CTYPE_BKM_A4T
265#define DEFAULT_CFG {0,0x0,0,0}
266#endif
267
268#ifdef CONFIG_HISAX_SCT_QUADRO
269#undef DEFAULT_CARD
270#undef DEFAULT_CFG
271#define DEFAULT_CARD ISDN_CTYPE_SCT_QUADRO
272#define DEFAULT_CFG {1,0x0,0,0}
273#endif
274
275#ifdef CONFIG_HISAX_GAZEL
276#undef DEFAULT_CARD
277#undef DEFAULT_CFG
278#define DEFAULT_CARD ISDN_CTYPE_GAZEL
279#define DEFAULT_CFG {15,0x180,0,0}
280#endif
281
282#ifdef CONFIG_HISAX_W6692
283#undef DEFAULT_CARD
284#undef DEFAULT_CFG
285#define DEFAULT_CARD ISDN_CTYPE_W6692
286#define DEFAULT_CFG {0,0,0,0}
287#endif
288
289#ifdef CONFIG_HISAX_NETJET_U
290#undef DEFAULT_CARD
291#undef DEFAULT_CFG
292#define DEFAULT_CARD ISDN_CTYPE_NETJET_U
293#define DEFAULT_CFG {0,0,0,0}
294#endif
295
296#ifdef CONFIG_HISAX_1TR6
297#define DEFAULT_PROTO ISDN_PTYPE_1TR6
298#define DEFAULT_PROTO_NAME "1TR6"
299#endif
300#ifdef CONFIG_HISAX_NI1
301#undef DEFAULT_PROTO
302#define DEFAULT_PROTO ISDN_PTYPE_NI1
303#undef DEFAULT_PROTO_NAME
304#define DEFAULT_PROTO_NAME "NI1"
305#endif
306#ifdef CONFIG_HISAX_EURO
307#undef DEFAULT_PROTO
308#define DEFAULT_PROTO ISDN_PTYPE_EURO
309#undef DEFAULT_PROTO_NAME
310#define DEFAULT_PROTO_NAME "EURO"
311#endif
312#ifndef DEFAULT_PROTO
313#define DEFAULT_PROTO ISDN_PTYPE_UNKNOWN
314#define DEFAULT_PROTO_NAME "UNKNOWN"
315#endif
316#ifndef DEFAULT_CARD
317#define DEFAULT_CARD 0
318#define DEFAULT_CFG {0,0,0,0}
319#endif
320
321#define FIRST_CARD { \
322 DEFAULT_CARD, \
323 DEFAULT_PROTO, \
324 DEFAULT_CFG, \
325 NULL, \
326}
327
328struct IsdnCard cards[HISAX_MAX_CARDS] = {
329 FIRST_CARD,
330};
331
332#define HISAX_IDSIZE (HISAX_MAX_CARDS*8)
333static char HiSaxID[HISAX_IDSIZE] = { 0, };
334
335char *HiSax_id = HiSaxID;
336#ifdef MODULE
337
338static int type[HISAX_MAX_CARDS] = { 0, };
339static int protocol[HISAX_MAX_CARDS] = { 0, };
340static int io[HISAX_MAX_CARDS] = { 0, };
341#undef IO0_IO1
342#ifdef CONFIG_HISAX_16_3
343#define IO0_IO1
344#endif
345#ifdef CONFIG_HISAX_NICCY
346#undef IO0_IO1
347#define IO0_IO1
348#endif
349#ifdef IO0_IO1
350static int io0[HISAX_MAX_CARDS] __devinitdata = { 0, };
351static int io1[HISAX_MAX_CARDS] __devinitdata = { 0, };
352#endif
353static int irq[HISAX_MAX_CARDS] __devinitdata = { 0, };
354static int mem[HISAX_MAX_CARDS] __devinitdata = { 0, };
355static char *id = HiSaxID;
356
357MODULE_DESCRIPTION("ISDN4Linux: Driver for passive ISDN cards");
358MODULE_AUTHOR("Karsten Keil");
359MODULE_LICENSE("GPL");
360module_param_array(type, int, NULL, 0);
361module_param_array(protocol, int, NULL, 0);
362module_param_array(io, int, NULL, 0);
363module_param_array(irq, int, NULL, 0);
364module_param_array(mem, int, NULL, 0);
365module_param(id, charp, 0);
366#ifdef IO0_IO1
367module_param_array(io0, int, NULL, 0);
368module_param_array(io1, int, NULL, 0);
369#endif
370#endif
371
372int nrcards;
373
374extern char *l1_revision;
375extern char *l2_revision;
376extern char *l3_revision;
377extern char *lli_revision;
378extern char *tei_revision;
379
380char *HiSax_getrev(const char *revision)
381{
382 char *rev;
383 char *p;
384
385 if ((p = strchr(revision, ':'))) {
386 rev = p + 2;
387 p = strchr(rev, '$');
388 *--p = 0;
389 } else
390 rev = "???";
391 return rev;
392}
393
394void __init HiSaxVersion(void)
395{
396 char tmp[64];
397
398 printk(KERN_INFO "HiSax: Linux Driver for passive ISDN cards\n");
399#ifdef MODULE
400 printk(KERN_INFO "HiSax: Version 3.5 (module)\n");
401#else
402 printk(KERN_INFO "HiSax: Version 3.5 (kernel)\n");
403#endif
404 strcpy(tmp, l1_revision);
405 printk(KERN_INFO "HiSax: Layer1 Revision %s\n", HiSax_getrev(tmp));
406 strcpy(tmp, l2_revision);
407 printk(KERN_INFO "HiSax: Layer2 Revision %s\n", HiSax_getrev(tmp));
408 strcpy(tmp, tei_revision);
409 printk(KERN_INFO "HiSax: TeiMgr Revision %s\n", HiSax_getrev(tmp));
410 strcpy(tmp, l3_revision);
411 printk(KERN_INFO "HiSax: Layer3 Revision %s\n", HiSax_getrev(tmp));
412 strcpy(tmp, lli_revision);
413 printk(KERN_INFO "HiSax: LinkLayer Revision %s\n",
414 HiSax_getrev(tmp));
415}
416
417#ifndef MODULE
418#define MAX_ARG (HISAX_MAX_CARDS*5)
419static int __init HiSax_setup(char *line)
420{
421 int i, j, argc;
422 int ints[MAX_ARG + 1];
423 char *str;
424
425 str = get_options(line, MAX_ARG, ints);
426 argc = ints[0];
427 printk(KERN_DEBUG "HiSax_setup: argc(%d) str(%s)\n", argc, str);
428 i = 0;
429 j = 1;
430 while (argc && (i < HISAX_MAX_CARDS)) {
431 cards[i].protocol = DEFAULT_PROTO;
432 if (argc) {
433 cards[i].typ = ints[j];
434 j++;
435 argc--;
436 }
437 if (argc) {
438 cards[i].protocol = ints[j];
439 j++;
440 argc--;
441 }
442 if (argc) {
443 cards[i].para[0] = ints[j];
444 j++;
445 argc--;
446 }
447 if (argc) {
448 cards[i].para[1] = ints[j];
449 j++;
450 argc--;
451 }
452 if (argc) {
453 cards[i].para[2] = ints[j];
454 j++;
455 argc--;
456 }
457 i++;
458 }
459 if (str && *str) {
460 if (strlen(str) < HISAX_IDSIZE)
461 strcpy(HiSaxID, str);
462 else
463 printk(KERN_WARNING "HiSax: ID too long!");
464 } else
465 strcpy(HiSaxID, "HiSax");
466
467 HiSax_id = HiSaxID;
468 return 1;
469}
470
471__setup("hisax=", HiSax_setup);
472#endif
473
474#if CARD_TELES0
475extern int setup_teles0(struct IsdnCard *card);
476#endif
477
478#if CARD_TELES3
479extern int setup_teles3(struct IsdnCard *card);
480#endif
481
482#if CARD_S0BOX
483extern int setup_s0box(struct IsdnCard *card);
484#endif
485
486#if CARD_TELESPCI
487extern int setup_telespci(struct IsdnCard *card);
488#endif
489
490#if CARD_AVM_A1
491extern int setup_avm_a1(struct IsdnCard *card);
492#endif
493
494#if CARD_AVM_A1_PCMCIA
495extern int setup_avm_a1_pcmcia(struct IsdnCard *card);
496#endif
497
498#if CARD_FRITZPCI
499extern int setup_avm_pcipnp(struct IsdnCard *card);
500#endif
501
502#if CARD_ELSA
503extern int setup_elsa(struct IsdnCard *card);
504#endif
505
506#if CARD_IX1MICROR2
507extern int setup_ix1micro(struct IsdnCard *card);
508#endif
509
510#if CARD_DIEHLDIVA
511extern int setup_diva(struct IsdnCard *card);
512#endif
513
514#if CARD_ASUSCOM
515extern int setup_asuscom(struct IsdnCard *card);
516#endif
517
518#if CARD_TELEINT
519extern int setup_TeleInt(struct IsdnCard *card);
520#endif
521
522#if CARD_SEDLBAUER
523extern int setup_sedlbauer(struct IsdnCard *card);
524#endif
525
526#if CARD_SPORTSTER
527extern int setup_sportster(struct IsdnCard *card);
528#endif
529
530#if CARD_MIC
531extern int setup_mic(struct IsdnCard *card);
532#endif
533
534#if CARD_NETJET_S
535extern int setup_netjet_s(struct IsdnCard *card);
536#endif
537
538#if CARD_HFCS
539extern int setup_hfcs(struct IsdnCard *card);
540#endif
541
542#if CARD_HFC_PCI
543extern int setup_hfcpci(struct IsdnCard *card);
544#endif
545
546#if CARD_HFC_SX
547extern int setup_hfcsx(struct IsdnCard *card);
548#endif
549
550#if CARD_AMD7930
551extern int setup_amd7930(struct IsdnCard *card);
552#endif
553
554#if CARD_NICCY
555extern int setup_niccy(struct IsdnCard *card);
556#endif
557
558#if CARD_ISURF
559extern int setup_isurf(struct IsdnCard *card);
560#endif
561
562#if CARD_HSTSAPHIR
563extern int setup_saphir(struct IsdnCard *card);
564#endif
565
566#if CARD_TESTEMU
567extern int setup_testemu(struct IsdnCard *card);
568#endif
569
570#if CARD_BKM_A4T
571extern int setup_bkm_a4t(struct IsdnCard *card);
572#endif
573
574#if CARD_SCT_QUADRO
575extern int setup_sct_quadro(struct IsdnCard *card);
576#endif
577
578#if CARD_GAZEL
579extern int setup_gazel(struct IsdnCard *card);
580#endif
581
582#if CARD_W6692
583extern int setup_w6692(struct IsdnCard *card);
584#endif
585
586#if CARD_NETJET_U
587extern int setup_netjet_u(struct IsdnCard *card);
588#endif
589
590#if CARD_FN_ENTERNOW_PCI
591extern int setup_enternow_pci(struct IsdnCard *card);
592#endif
593
594
595
596
597static inline struct IsdnCardState *hisax_findcard(int driverid)
598{
599 int i;
600
601 for (i = 0; i < nrcards; i++)
602 if (cards[i].cs)
603 if (cards[i].cs->myid == driverid)
604 return cards[i].cs;
605 return NULL;
606}
607
608
609
610
611struct IsdnCardState *hisax_get_card(int cardnr)
612{
613 if ((cardnr <= nrcards) && (cardnr > 0))
614 if (cards[cardnr - 1].cs)
615 return cards[cardnr - 1].cs;
616 return NULL;
617}
618
619int HiSax_readstatus(u_char __user *buf, int len, int id, int channel)
620{
621 int count, cnt;
622 u_char __user *p = buf;
623 struct IsdnCardState *cs = hisax_findcard(id);
624
625 if (cs) {
626 if (len > HISAX_STATUS_BUFSIZE) {
627 printk(KERN_WARNING
628 "HiSax: status overflow readstat %d/%d\n",
629 len, HISAX_STATUS_BUFSIZE);
630 }
631 count = cs->status_end - cs->status_read + 1;
632 if (count >= len)
633 count = len;
634 copy_to_user(p, cs->status_read, count);
635 cs->status_read += count;
636 if (cs->status_read > cs->status_end)
637 cs->status_read = cs->status_buf;
638 p += count;
639 count = len - count;
640 while (count) {
641 if (count > HISAX_STATUS_BUFSIZE)
642 cnt = HISAX_STATUS_BUFSIZE;
643 else
644 cnt = count;
645 copy_to_user(p, cs->status_read, cnt);
646 p += cnt;
647 cs->status_read += cnt % HISAX_STATUS_BUFSIZE;
648 count -= cnt;
649 }
650 return len;
651 } else {
652 printk(KERN_ERR
653 "HiSax: if_readstatus called with invalid driverId!\n");
654 return -ENODEV;
655 }
656}
657
658int jiftime(char *s, long mark)
659{
660 s += 8;
661
662 *s-- = '\0';
663 *s-- = mark % 10 + '0';
664 mark /= 10;
665 *s-- = mark % 10 + '0';
666 mark /= 10;
667 *s-- = '.';
668 *s-- = mark % 10 + '0';
669 mark /= 10;
670 *s-- = mark % 6 + '0';
671 mark /= 6;
672 *s-- = ':';
673 *s-- = mark % 10 + '0';
674 mark /= 10;
675 *s-- = mark % 10 + '0';
676 return 8;
677}
678
679static u_char tmpbuf[HISAX_STATUS_BUFSIZE];
680
681void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt,
682 va_list args)
683{
684
685
686 u_long flags;
687 int count, i;
688 u_char *p;
689 isdn_ctrl ic;
690 int len;
691
692 if (!cs) {
693 printk(KERN_WARNING "HiSax: No CardStatus for message");
694 return;
695 }
696 spin_lock_irqsave(&cs->statlock, flags);
697 p = tmpbuf;
698 if (head) {
699 p += jiftime(p, jiffies);
700 p += sprintf(p, " %s", head);
701 p += vsprintf(p, fmt, args);
702 *p++ = '\n';
703 *p = 0;
704 len = p - tmpbuf;
705 p = tmpbuf;
706 } else {
707 p = fmt;
708 len = strlen(fmt);
709 }
710 if (len > HISAX_STATUS_BUFSIZE) {
711 spin_unlock_irqrestore(&cs->statlock, flags);
712 printk(KERN_WARNING "HiSax: status overflow %d/%d\n",
713 len, HISAX_STATUS_BUFSIZE);
714 return;
715 }
716 count = len;
717 i = cs->status_end - cs->status_write + 1;
718 if (i >= len)
719 i = len;
720 len -= i;
721 memcpy(cs->status_write, p, i);
722 cs->status_write += i;
723 if (cs->status_write > cs->status_end)
724 cs->status_write = cs->status_buf;
725 p += i;
726 if (len) {
727 memcpy(cs->status_write, p, len);
728 cs->status_write += len;
729 }
730#ifdef KERNELSTACK_DEBUG
731 i = (ulong) & len - current->kernel_stack_page;
732 sprintf(tmpbuf, "kstack %s %lx use %ld\n", current->comm,
733 current->kernel_stack_page, i);
734 len = strlen(tmpbuf);
735 for (p = tmpbuf, i = len; i > 0; i--, p++) {
736 *cs->status_write++ = *p;
737 if (cs->status_write > cs->status_end)
738 cs->status_write = cs->status_buf;
739 count++;
740 }
741#endif
742 spin_unlock_irqrestore(&cs->statlock, flags);
743 if (count) {
744 ic.command = ISDN_STAT_STAVAIL;
745 ic.driver = cs->myid;
746 ic.arg = count;
747 cs->iif.statcallb(&ic);
748 }
749}
750
751void HiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, ...)
752{
753 va_list args;
754
755 va_start(args, fmt);
756 VHiSax_putstatus(cs, head, fmt, args);
757 va_end(args);
758}
759
760int ll_run(struct IsdnCardState *cs, int addfeatures)
761{
762 isdn_ctrl ic;
763
764 ic.driver = cs->myid;
765 ic.command = ISDN_STAT_RUN;
766 cs->iif.features |= addfeatures;
767 cs->iif.statcallb(&ic);
768 return 0;
769}
770
771void ll_stop(struct IsdnCardState *cs)
772{
773 isdn_ctrl ic;
774
775 ic.command = ISDN_STAT_STOP;
776 ic.driver = cs->myid;
777 cs->iif.statcallb(&ic);
778
779}
780
781static void ll_unload(struct IsdnCardState *cs)
782{
783 isdn_ctrl ic;
784
785 ic.command = ISDN_STAT_UNLOAD;
786 ic.driver = cs->myid;
787 cs->iif.statcallb(&ic);
788 if (cs->status_buf)
789 kfree(cs->status_buf);
790 cs->status_read = NULL;
791 cs->status_write = NULL;
792 cs->status_end = NULL;
793 kfree(cs->dlog);
794 cs->dlog = NULL;
795}
796
797static void closecard(int cardnr)
798{
799 struct IsdnCardState *csta = cards[cardnr].cs;
800
801 if (csta->bcs->BC_Close != NULL) {
802 csta->bcs->BC_Close(csta->bcs + 1);
803 csta->bcs->BC_Close(csta->bcs);
804 }
805
806 skb_queue_purge(&csta->rq);
807 skb_queue_purge(&csta->sq);
808 if (csta->rcvbuf) {
809 kfree(csta->rcvbuf);
810 csta->rcvbuf = NULL;
811 }
812 if (csta->tx_skb) {
813 dev_kfree_skb(csta->tx_skb);
814 csta->tx_skb = NULL;
815 }
816 if (csta->DC_Close != NULL) {
817 csta->DC_Close(csta);
818 }
819 if (csta->cardmsg)
820 csta->cardmsg(csta, CARD_RELEASE, NULL);
821 if (csta->dbusytimer.function != NULL)
822 del_timer(&csta->dbusytimer);
823 ll_unload(csta);
824}
825
826static int init_card(struct IsdnCardState *cs)
827{
828 int irq_cnt, cnt = 3, ret;
829
830 if (!cs->irq) {
831 ret = cs->cardmsg(cs, CARD_INIT, NULL);
832 return(ret);
833 }
834 irq_cnt = kstat_irqs(cs->irq);
835 printk(KERN_INFO "%s: IRQ %d count %d\n", CardType[cs->typ],
836 cs->irq, irq_cnt);
837 if (request_irq(cs->irq, cs->irq_func, cs->irq_flags, "HiSax", cs)) {
838 printk(KERN_WARNING "HiSax: couldn't get interrupt %d\n",
839 cs->irq);
840 return 1;
841 }
842 while (cnt) {
843 cs->cardmsg(cs, CARD_INIT, NULL);
844
845 msleep(10);
846 printk(KERN_INFO "%s: IRQ %d count %d\n",
847 CardType[cs->typ], cs->irq, kstat_irqs(cs->irq));
848 if (kstat_irqs(cs->irq) == irq_cnt) {
849 printk(KERN_WARNING
850 "%s: IRQ(%d) getting no interrupts during init %d\n",
851 CardType[cs->typ], cs->irq, 4 - cnt);
852 if (cnt == 1) {
853 free_irq(cs->irq, cs);
854 return 2;
855 } else {
856 cs->cardmsg(cs, CARD_RESET, NULL);
857 cnt--;
858 }
859 } else {
860 cs->cardmsg(cs, CARD_TEST, NULL);
861 return 0;
862 }
863 }
864 return 3;
865}
866
867static int checkcard(int cardnr, char *id, int *busy_flag, struct module *lockowner)
868{
869 int ret = 0;
870 struct IsdnCard *card = cards + cardnr;
871 struct IsdnCardState *cs;
872
873 cs = kmalloc(sizeof(struct IsdnCardState), GFP_ATOMIC);
874 if (!cs) {
875 printk(KERN_WARNING
876 "HiSax: No memory for IsdnCardState(card %d)\n",
877 cardnr + 1);
878 goto out;
879 }
880 memset(cs, 0, sizeof(struct IsdnCardState));
881 card->cs = cs;
882 spin_lock_init(&cs->statlock);
883 spin_lock_init(&cs->lock);
884 cs->chanlimit = 2;
885 cs->logecho = 0;
886 cs->cardnr = cardnr;
887 cs->debug = L1_DEB_WARN;
888 cs->HW_Flags = 0;
889 cs->busy_flag = busy_flag;
890 cs->irq_flags = I4L_IRQ_FLAG;
891#if TEI_PER_CARD
892 if (card->protocol == ISDN_PTYPE_NI1)
893 test_and_set_bit(FLG_TWO_DCHAN, &cs->HW_Flags);
894#else
895 test_and_set_bit(FLG_TWO_DCHAN, &cs->HW_Flags);
896#endif
897 cs->protocol = card->protocol;
898
899 if (card->typ <= 0 || card->typ > ISDN_CTYPE_COUNT) {
900 printk(KERN_WARNING
901 "HiSax: Card Type %d out of range\n", card->typ);
902 goto outf_cs;
903 }
904 if (!(cs->dlog = kmalloc(MAX_DLOG_SPACE, GFP_ATOMIC))) {
905 printk(KERN_WARNING
906 "HiSax: No memory for dlog(card %d)\n", cardnr + 1);
907 goto outf_cs;
908 }
909 if (!(cs->status_buf = kmalloc(HISAX_STATUS_BUFSIZE, GFP_ATOMIC))) {
910 printk(KERN_WARNING
911 "HiSax: No memory for status_buf(card %d)\n",
912 cardnr + 1);
913 goto outf_dlog;
914 }
915 cs->stlist = NULL;
916 cs->status_read = cs->status_buf;
917 cs->status_write = cs->status_buf;
918 cs->status_end = cs->status_buf + HISAX_STATUS_BUFSIZE - 1;
919 cs->typ = card->typ;
920#ifdef MODULE
921 cs->iif.owner = lockowner;
922#endif
923 strcpy(cs->iif.id, id);
924 cs->iif.channels = 2;
925 cs->iif.maxbufsize = MAX_DATA_SIZE;
926 cs->iif.hl_hdrlen = MAX_HEADER_LEN;
927 cs->iif.features =
928 ISDN_FEATURE_L2_X75I |
929 ISDN_FEATURE_L2_HDLC |
930 ISDN_FEATURE_L2_HDLC_56K |
931 ISDN_FEATURE_L2_TRANS |
932 ISDN_FEATURE_L3_TRANS |
933#ifdef CONFIG_HISAX_1TR6
934 ISDN_FEATURE_P_1TR6 |
935#endif
936#ifdef CONFIG_HISAX_EURO
937 ISDN_FEATURE_P_EURO |
938#endif
939#ifdef CONFIG_HISAX_NI1
940 ISDN_FEATURE_P_NI1 |
941#endif
942 0;
943
944 cs->iif.command = HiSax_command;
945 cs->iif.writecmd = NULL;
946 cs->iif.writebuf_skb = HiSax_writebuf_skb;
947 cs->iif.readstat = HiSax_readstatus;
948 register_isdn(&cs->iif);
949 cs->myid = cs->iif.channels;
950 printk(KERN_INFO
951 "HiSax: Card %d Protocol %s Id=%s (%d)\n", cardnr + 1,
952 (card->protocol == ISDN_PTYPE_1TR6) ? "1TR6" :
953 (card->protocol == ISDN_PTYPE_EURO) ? "EDSS1" :
954 (card->protocol == ISDN_PTYPE_LEASED) ? "LEASED" :
955 (card->protocol == ISDN_PTYPE_NI1) ? "NI1" :
956 "NONE", cs->iif.id, cs->myid);
957 switch (card->typ) {
958#if CARD_TELES0
959 case ISDN_CTYPE_16_0:
960 case ISDN_CTYPE_8_0:
961 ret = setup_teles0(card);
962 break;
963#endif
964#if CARD_TELES3
965 case ISDN_CTYPE_16_3:
966 case ISDN_CTYPE_PNP:
967 case ISDN_CTYPE_TELESPCMCIA:
968 case ISDN_CTYPE_COMPAQ_ISA:
969 ret = setup_teles3(card);
970 break;
971#endif
972#if CARD_S0BOX
973 case ISDN_CTYPE_S0BOX:
974 ret = setup_s0box(card);
975 break;
976#endif
977#if CARD_TELESPCI
978 case ISDN_CTYPE_TELESPCI:
979 ret = setup_telespci(card);
980 break;
981#endif
982#if CARD_AVM_A1
983 case ISDN_CTYPE_A1:
984 ret = setup_avm_a1(card);
985 break;
986#endif
987#if CARD_AVM_A1_PCMCIA
988 case ISDN_CTYPE_A1_PCMCIA:
989 ret = setup_avm_a1_pcmcia(card);
990 break;
991#endif
992#if CARD_FRITZPCI
993 case ISDN_CTYPE_FRITZPCI:
994 ret = setup_avm_pcipnp(card);
995 break;
996#endif
997#if CARD_ELSA
998 case ISDN_CTYPE_ELSA:
999 case ISDN_CTYPE_ELSA_PNP:
1000 case ISDN_CTYPE_ELSA_PCMCIA:
1001 case ISDN_CTYPE_ELSA_PCI:
1002 ret = setup_elsa(card);
1003 break;
1004#endif
1005#if CARD_IX1MICROR2
1006 case ISDN_CTYPE_IX1MICROR2:
1007 ret = setup_ix1micro(card);
1008 break;
1009#endif
1010#if CARD_DIEHLDIVA
1011 case ISDN_CTYPE_DIEHLDIVA:
1012 ret = setup_diva(card);
1013 break;
1014#endif
1015#if CARD_ASUSCOM
1016 case ISDN_CTYPE_ASUSCOM:
1017 ret = setup_asuscom(card);
1018 break;
1019#endif
1020#if CARD_TELEINT
1021 case ISDN_CTYPE_TELEINT:
1022 ret = setup_TeleInt(card);
1023 break;
1024#endif
1025#if CARD_SEDLBAUER
1026 case ISDN_CTYPE_SEDLBAUER:
1027 case ISDN_CTYPE_SEDLBAUER_PCMCIA:
1028 case ISDN_CTYPE_SEDLBAUER_FAX:
1029 ret = setup_sedlbauer(card);
1030 break;
1031#endif
1032#if CARD_SPORTSTER
1033 case ISDN_CTYPE_SPORTSTER:
1034 ret = setup_sportster(card);
1035 break;
1036#endif
1037#if CARD_MIC
1038 case ISDN_CTYPE_MIC:
1039 ret = setup_mic(card);
1040 break;
1041#endif
1042#if CARD_NETJET_S
1043 case ISDN_CTYPE_NETJET_S:
1044 ret = setup_netjet_s(card);
1045 break;
1046#endif
1047#if CARD_HFCS
1048 case ISDN_CTYPE_TELES3C:
1049 case ISDN_CTYPE_ACERP10:
1050 ret = setup_hfcs(card);
1051 break;
1052#endif
1053#if CARD_HFC_PCI
1054 case ISDN_CTYPE_HFC_PCI:
1055 ret = setup_hfcpci(card);
1056 break;
1057#endif
1058#if CARD_HFC_SX
1059 case ISDN_CTYPE_HFC_SX:
1060 ret = setup_hfcsx(card);
1061 break;
1062#endif
1063#if CARD_NICCY
1064 case ISDN_CTYPE_NICCY:
1065 ret = setup_niccy(card);
1066 break;
1067#endif
1068#if CARD_AMD7930
1069 case ISDN_CTYPE_AMD7930:
1070 ret = setup_amd7930(card);
1071 break;
1072#endif
1073#if CARD_ISURF
1074 case ISDN_CTYPE_ISURF:
1075 ret = setup_isurf(card);
1076 break;
1077#endif
1078#if CARD_HSTSAPHIR
1079 case ISDN_CTYPE_HSTSAPHIR:
1080 ret = setup_saphir(card);
1081 break;
1082#endif
1083#if CARD_TESTEMU
1084 case ISDN_CTYPE_TESTEMU:
1085 ret = setup_testemu(card);
1086 break;
1087#endif
1088#if CARD_BKM_A4T
1089 case ISDN_CTYPE_BKM_A4T:
1090 ret = setup_bkm_a4t(card);
1091 break;
1092#endif
1093#if CARD_SCT_QUADRO
1094 case ISDN_CTYPE_SCT_QUADRO:
1095 ret = setup_sct_quadro(card);
1096 break;
1097#endif
1098#if CARD_GAZEL
1099 case ISDN_CTYPE_GAZEL:
1100 ret = setup_gazel(card);
1101 break;
1102#endif
1103#if CARD_W6692
1104 case ISDN_CTYPE_W6692:
1105 ret = setup_w6692(card);
1106 break;
1107#endif
1108#if CARD_NETJET_U
1109 case ISDN_CTYPE_NETJET_U:
1110 ret = setup_netjet_u(card);
1111 break;
1112#endif
1113#if CARD_FN_ENTERNOW_PCI
1114 case ISDN_CTYPE_ENTERNOW:
1115 ret = setup_enternow_pci(card);
1116 break;
1117#endif
1118 case ISDN_CTYPE_DYNAMIC:
1119 ret = 2;
1120 break;
1121 default:
1122 printk(KERN_WARNING
1123 "HiSax: Support for %s Card not selected\n",
1124 CardType[card->typ]);
1125 ll_unload(cs);
1126 goto outf_cs;
1127 }
1128 if (!ret) {
1129 ll_unload(cs);
1130 goto outf_cs;
1131 }
1132 if (!(cs->rcvbuf = kmalloc(MAX_DFRAME_LEN_L1, GFP_ATOMIC))) {
1133 printk(KERN_WARNING "HiSax: No memory for isac rcvbuf\n");
1134 ll_unload(cs);
1135 goto outf_cs;
1136 }
1137 cs->rcvidx = 0;
1138 cs->tx_skb = NULL;
1139 cs->tx_cnt = 0;
1140 cs->event = 0;
1141 cs->tqueue.data = cs;
1142
1143 skb_queue_head_init(&cs->rq);
1144 skb_queue_head_init(&cs->sq);
1145
1146 init_bcstate(cs, 0);
1147 init_bcstate(cs, 1);
1148
1149
1150
1151 switch (card->typ) {
1152 case ISDN_CTYPE_DYNAMIC:
1153 ret = 0;
1154 break;
1155 default:
1156 ret = init_card(cs);
1157 break;
1158 }
1159 if (ret) {
1160 closecard(cardnr);
1161 ret = 0;
1162 goto outf_cs;
1163 }
1164 init_tei(cs, cs->protocol);
1165 ret = CallcNewChan(cs);
1166 if (ret) {
1167 closecard(cardnr);
1168 ret = 0;
1169 goto outf_cs;
1170 }
1171
1172 if (!test_bit(HW_ISAR, &cs->HW_Flags))
1173 ll_run(cs, 0);
1174
1175 ret = 1;
1176 goto out;
1177
1178 outf_dlog:
1179 kfree(cs->dlog);
1180 outf_cs:
1181 kfree(cs);
1182 card->cs = NULL;
1183 out:
1184 return ret;
1185}
1186
1187void HiSax_shiftcards(int idx)
1188{
1189 int i;
1190
1191 for (i = idx; i < (HISAX_MAX_CARDS - 1); i++)
1192 memcpy(&cards[i], &cards[i + 1], sizeof(cards[i]));
1193}
1194
1195int HiSax_inithardware(int *busy_flag)
1196{
1197 int foundcards = 0;
1198 int i = 0;
1199 int t = ',';
1200 int flg = 0;
1201 char *id;
1202 char *next_id = HiSax_id;
1203 char ids[20];
1204
1205 if (strchr(HiSax_id, ','))
1206 t = ',';
1207 else if (strchr(HiSax_id, '%'))
1208 t = '%';
1209
1210 while (i < nrcards) {
1211 if (cards[i].typ < 1)
1212 break;
1213 id = next_id;
1214 if ((next_id = strchr(id, t))) {
1215 *next_id++ = 0;
1216 strcpy(ids, id);
1217 flg = i + 1;
1218 } else {
1219 next_id = id;
1220 if (flg >= i)
1221 strcpy(ids, id);
1222 else
1223 sprintf(ids, "%s%d", id, i);
1224 }
1225 if (checkcard(i, ids, busy_flag, THIS_MODULE)) {
1226 foundcards++;
1227 i++;
1228 } else {
1229
1230 if (cards[i].typ > 0 && cards[i].typ <= ISDN_CTYPE_COUNT) {
1231 printk(KERN_WARNING
1232 "HiSax: Card %s not installed !\n",
1233 CardType[cards[i].typ]);
1234 }
1235 HiSax_shiftcards(i);
1236 nrcards--;
1237 }
1238 }
1239 return foundcards;
1240}
1241
1242void HiSax_closecard(int cardnr)
1243{
1244 int i, last = nrcards - 1;
1245
1246 if (cardnr > last || cardnr < 0)
1247 return;
1248 if (cards[cardnr].cs) {
1249 ll_stop(cards[cardnr].cs);
1250 release_tei(cards[cardnr].cs);
1251 CallcFreeChan(cards[cardnr].cs);
1252
1253 closecard(cardnr);
1254 if (cards[cardnr].cs->irq)
1255 free_irq(cards[cardnr].cs->irq, cards[cardnr].cs);
1256 kfree((void *) cards[cardnr].cs);
1257 cards[cardnr].cs = NULL;
1258 }
1259 i = cardnr;
1260 while (i <= last) {
1261 cards[i] = cards[i + 1];
1262 i++;
1263 }
1264 nrcards--;
1265}
1266
1267void HiSax_reportcard(int cardnr, int sel)
1268{
1269 struct IsdnCardState *cs = cards[cardnr].cs;
1270
1271 printk(KERN_DEBUG "HiSax: reportcard No %d\n", cardnr + 1);
1272 printk(KERN_DEBUG "HiSax: Type %s\n", CardType[cs->typ]);
1273 printk(KERN_DEBUG "HiSax: debuglevel %x\n", cs->debug);
1274 printk(KERN_DEBUG "HiSax: HiSax_reportcard address 0x%lX\n",
1275 (ulong) & HiSax_reportcard);
1276 printk(KERN_DEBUG "HiSax: cs 0x%lX\n", (ulong) cs);
1277 printk(KERN_DEBUG "HiSax: HW_Flags %lx bc0 flg %lx bc1 flg %lx\n",
1278 cs->HW_Flags, cs->bcs[0].Flag, cs->bcs[1].Flag);
1279 printk(KERN_DEBUG "HiSax: bcs 0 mode %d ch%d\n",
1280 cs->bcs[0].mode, cs->bcs[0].channel);
1281 printk(KERN_DEBUG "HiSax: bcs 1 mode %d ch%d\n",
1282 cs->bcs[1].mode, cs->bcs[1].channel);
1283#ifdef ERROR_STATISTIC
1284 printk(KERN_DEBUG "HiSax: dc errors(rx,crc,tx) %d,%d,%d\n",
1285 cs->err_rx, cs->err_crc, cs->err_tx);
1286 printk(KERN_DEBUG
1287 "HiSax: bc0 errors(inv,rdo,crc,tx) %d,%d,%d,%d\n",
1288 cs->bcs[0].err_inv, cs->bcs[0].err_rdo, cs->bcs[0].err_crc,
1289 cs->bcs[0].err_tx);
1290 printk(KERN_DEBUG
1291 "HiSax: bc1 errors(inv,rdo,crc,tx) %d,%d,%d,%d\n",
1292 cs->bcs[1].err_inv, cs->bcs[1].err_rdo, cs->bcs[1].err_crc,
1293 cs->bcs[1].err_tx);
1294 if (sel == 99) {
1295 cs->err_rx = 0;
1296 cs->err_crc = 0;
1297 cs->err_tx = 0;
1298 cs->bcs[0].err_inv = 0;
1299 cs->bcs[0].err_rdo = 0;
1300 cs->bcs[0].err_crc = 0;
1301 cs->bcs[0].err_tx = 0;
1302 cs->bcs[1].err_inv = 0;
1303 cs->bcs[1].err_rdo = 0;
1304 cs->bcs[1].err_crc = 0;
1305 cs->bcs[1].err_tx = 0;
1306 }
1307#endif
1308}
1309
1310static int __init HiSax_init(void)
1311{
1312 int i, retval;
1313#ifdef MODULE
1314 int j;
1315 int nzproto = 0;
1316#endif
1317
1318 HiSaxVersion();
1319 retval = CallcNew();
1320 if (retval)
1321 goto out;
1322 retval = Isdnl3New();
1323 if (retval)
1324 goto out_callc;
1325 retval = Isdnl2New();
1326 if (retval)
1327 goto out_isdnl3;
1328 retval = TeiNew();
1329 if (retval)
1330 goto out_isdnl2;
1331 retval = Isdnl1New();
1332 if (retval)
1333 goto out_tei;
1334
1335#ifdef MODULE
1336 if (!type[0]) {
1337
1338 for (i = 0; i < HISAX_MAX_CARDS; i++)
1339 cards[i].typ = 0;
1340 return 0;
1341 }
1342#ifdef CONFIG_HISAX_ELSA
1343 if (type[0] == ISDN_CTYPE_ELSA_PCMCIA) {
1344
1345 return 0;
1346 }
1347#endif
1348#ifdef CONFIG_HISAX_SEDLBAUER
1349 if (type[0] == ISDN_CTYPE_SEDLBAUER_PCMCIA) {
1350
1351 return 0;
1352 }
1353#endif
1354#ifdef CONFIG_HISAX_AVM_A1_PCMCIA
1355 if (type[0] == ISDN_CTYPE_A1_PCMCIA) {
1356
1357 return 0;
1358 }
1359#endif
1360#ifdef CONFIG_HISAX_HFC_SX
1361 if (type[0] == ISDN_CTYPE_HFC_SP_PCMCIA) {
1362
1363 return 0;
1364 }
1365#endif
1366#endif
1367 nrcards = 0;
1368#ifdef MODULE
1369 if (id)
1370 HiSax_id = id;
1371 for (i = j = 0; j < HISAX_MAX_CARDS; i++) {
1372 cards[j].typ = type[i];
1373 if (protocol[i]) {
1374 cards[j].protocol = protocol[i];
1375 nzproto++;
1376 } else {
1377 cards[j].protocol = DEFAULT_PROTO;
1378 }
1379 switch (type[i]) {
1380 case ISDN_CTYPE_16_0:
1381 cards[j].para[0] = irq[i];
1382 cards[j].para[1] = mem[i];
1383 cards[j].para[2] = io[i];
1384 break;
1385
1386 case ISDN_CTYPE_8_0:
1387 cards[j].para[0] = irq[i];
1388 cards[j].para[1] = mem[i];
1389 break;
1390
1391#ifdef IO0_IO1
1392 case ISDN_CTYPE_PNP:
1393 case ISDN_CTYPE_NICCY:
1394 cards[j].para[0] = irq[i];
1395 cards[j].para[1] = io0[i];
1396 cards[j].para[2] = io1[i];
1397 break;
1398 case ISDN_CTYPE_COMPAQ_ISA:
1399 cards[j].para[0] = irq[i];
1400 cards[j].para[1] = io0[i];
1401 cards[j].para[2] = io1[i];
1402 cards[j].para[3] = io[i];
1403 break;
1404#endif
1405 case ISDN_CTYPE_ELSA:
1406 case ISDN_CTYPE_HFC_PCI:
1407 cards[j].para[0] = io[i];
1408 break;
1409 case ISDN_CTYPE_16_3:
1410 case ISDN_CTYPE_TELESPCMCIA:
1411 case ISDN_CTYPE_A1:
1412 case ISDN_CTYPE_A1_PCMCIA:
1413 case ISDN_CTYPE_ELSA_PNP:
1414 case ISDN_CTYPE_ELSA_PCMCIA:
1415 case ISDN_CTYPE_IX1MICROR2:
1416 case ISDN_CTYPE_DIEHLDIVA:
1417 case ISDN_CTYPE_ASUSCOM:
1418 case ISDN_CTYPE_TELEINT:
1419 case ISDN_CTYPE_SEDLBAUER:
1420 case ISDN_CTYPE_SEDLBAUER_PCMCIA:
1421 case ISDN_CTYPE_SEDLBAUER_FAX:
1422 case ISDN_CTYPE_SPORTSTER:
1423 case ISDN_CTYPE_MIC:
1424 case ISDN_CTYPE_TELES3C:
1425 case ISDN_CTYPE_ACERP10:
1426 case ISDN_CTYPE_S0BOX:
1427 case ISDN_CTYPE_FRITZPCI:
1428 case ISDN_CTYPE_HSTSAPHIR:
1429 case ISDN_CTYPE_GAZEL:
1430 case ISDN_CTYPE_HFC_SX:
1431 case ISDN_CTYPE_HFC_SP_PCMCIA:
1432 cards[j].para[0] = irq[i];
1433 cards[j].para[1] = io[i];
1434 break;
1435 case ISDN_CTYPE_ISURF:
1436 cards[j].para[0] = irq[i];
1437 cards[j].para[1] = io[i];
1438 cards[j].para[2] = mem[i];
1439 break;
1440 case ISDN_CTYPE_ELSA_PCI:
1441 case ISDN_CTYPE_NETJET_S:
1442 case ISDN_CTYPE_AMD7930:
1443 case ISDN_CTYPE_TELESPCI:
1444 case ISDN_CTYPE_W6692:
1445 case ISDN_CTYPE_NETJET_U:
1446 break;
1447 case ISDN_CTYPE_BKM_A4T:
1448 break;
1449 case ISDN_CTYPE_SCT_QUADRO:
1450 if (irq[i]) {
1451 cards[j].para[0] = irq[i];
1452 } else {
1453
1454 cards[j++].para[0] = 1;
1455
1456 if (j < HISAX_MAX_CARDS) {
1457 cards[j].typ = ISDN_CTYPE_SCT_QUADRO;
1458 cards[j].protocol = protocol[i];
1459 cards[j++].para[0] = 2;
1460 }
1461 if (j < HISAX_MAX_CARDS) {
1462 cards[j].typ = ISDN_CTYPE_SCT_QUADRO;
1463 cards[j].protocol = protocol[i];
1464 cards[j++].para[0] = 3;
1465 }
1466 if (j < HISAX_MAX_CARDS) {
1467 cards[j].typ = ISDN_CTYPE_SCT_QUADRO;
1468 cards[j].protocol = protocol[i];
1469 cards[j].para[0] = 4;
1470 }
1471 }
1472 break;
1473 }
1474 j++;
1475 }
1476 if (!nzproto) {
1477 printk(KERN_WARNING
1478 "HiSax: Warning - no protocol specified\n");
1479 printk(KERN_WARNING "HiSax: using protocol %s\n",
1480 DEFAULT_PROTO_NAME);
1481 }
1482#endif
1483 if (!HiSax_id)
1484 HiSax_id = HiSaxID;
1485 if (!HiSaxID[0])
1486 strcpy(HiSaxID, "HiSax");
1487 for (i = 0; i < HISAX_MAX_CARDS; i++)
1488 if (cards[i].typ > 0)
1489 nrcards++;
1490 printk(KERN_DEBUG "HiSax: Total %d card%s defined\n",
1491 nrcards, (nrcards > 1) ? "s" : "");
1492
1493
1494 if (!HiSax_inithardware(NULL))
1495 return -ENODEV;
1496 return 0;
1497
1498 out_tei:
1499 TeiFree();
1500 out_isdnl2:
1501 Isdnl2Free();
1502 out_isdnl3:
1503 Isdnl3Free();
1504 out_callc:
1505 CallcFree();
1506 out:
1507 return retval;
1508}
1509
1510static void __exit HiSax_exit(void)
1511{
1512 int cardnr = nrcards - 1;
1513
1514 while (cardnr >= 0)
1515 HiSax_closecard(cardnr--);
1516 Isdnl1Free();
1517 TeiFree();
1518 Isdnl2Free();
1519 Isdnl3Free();
1520 CallcFree();
1521 printk(KERN_INFO "HiSax module removed\n");
1522}
1523
1524int hisax_init_pcmcia(void *pcm_iob, int *busy_flag, struct IsdnCard *card)
1525{
1526 u_char ids[16];
1527 int ret = -1;
1528
1529 cards[nrcards] = *card;
1530 if (nrcards)
1531 sprintf(ids, "HiSax%d", nrcards);
1532 else
1533 sprintf(ids, "HiSax");
1534 if (!checkcard(nrcards, ids, busy_flag, THIS_MODULE))
1535 goto error;
1536
1537 ret = nrcards;
1538 nrcards++;
1539error:
1540 return ret;
1541}
1542
1543EXPORT_SYMBOL(hisax_init_pcmcia);
1544EXPORT_SYMBOL(HiSax_closecard);
1545
1546#include "hisax_if.h"
1547
1548EXPORT_SYMBOL(hisax_register);
1549EXPORT_SYMBOL(hisax_unregister);
1550
1551static void hisax_d_l1l2(struct hisax_if *ifc, int pr, void *arg);
1552static void hisax_b_l1l2(struct hisax_if *ifc, int pr, void *arg);
1553static void hisax_d_l2l1(struct PStack *st, int pr, void *arg);
1554static void hisax_b_l2l1(struct PStack *st, int pr, void *arg);
1555static int hisax_cardmsg(struct IsdnCardState *cs, int mt, void *arg);
1556static int hisax_bc_setstack(struct PStack *st, struct BCState *bcs);
1557static void hisax_bc_close(struct BCState *bcs);
1558static void hisax_bh(struct IsdnCardState *cs);
1559static void EChannel_proc_rcv(struct hisax_d_if *d_if);
1560
1561int hisax_register(struct hisax_d_if *hisax_d_if, struct hisax_b_if *b_if[],
1562 char *name, int protocol)
1563{
1564 int i, retval;
1565 char id[20];
1566 struct IsdnCardState *cs;
1567
1568 for (i = 0; i < HISAX_MAX_CARDS; i++) {
1569 if (!cards[i].typ)
1570 break;
1571 }
1572
1573 if (i >= HISAX_MAX_CARDS)
1574 return -EBUSY;
1575
1576 cards[i].typ = ISDN_CTYPE_DYNAMIC;
1577 cards[i].protocol = protocol;
1578 sprintf(id, "%s%d", name, i);
1579 nrcards++;
1580 retval = checkcard(i, id, NULL, hisax_d_if->owner);
1581 if (retval == 0) {
1582 cards[i].typ = 0;
1583 nrcards--;
1584 return retval;
1585 }
1586 cs = cards[i].cs;
1587 hisax_d_if->cs = cs;
1588 cs->hw.hisax_d_if = hisax_d_if;
1589 cs->cardmsg = hisax_cardmsg;
1590 INIT_WORK(&cs->tqueue, (void *)(void *)hisax_bh, cs);
1591 cs->channel[0].d_st->l2.l2l1 = hisax_d_l2l1;
1592 for (i = 0; i < 2; i++) {
1593 cs->bcs[i].BC_SetStack = hisax_bc_setstack;
1594 cs->bcs[i].BC_Close = hisax_bc_close;
1595
1596 b_if[i]->ifc.l1l2 = hisax_b_l1l2;
1597
1598 hisax_d_if->b_if[i] = b_if[i];
1599 }
1600 hisax_d_if->ifc.l1l2 = hisax_d_l1l2;
1601 skb_queue_head_init(&hisax_d_if->erq);
1602 clear_bit(0, &hisax_d_if->ph_state);
1603
1604 return 0;
1605}
1606
1607void hisax_unregister(struct hisax_d_if *hisax_d_if)
1608{
1609 cards[hisax_d_if->cs->cardnr].typ = 0;
1610 HiSax_closecard(hisax_d_if->cs->cardnr);
1611 skb_queue_purge(&hisax_d_if->erq);
1612}
1613
1614#include "isdnl1.h"
1615
1616static void hisax_sched_event(struct IsdnCardState *cs, int event)
1617{
1618 test_and_set_bit(event, &cs->event);
1619 schedule_work(&cs->tqueue);
1620}
1621
1622static void hisax_bh(struct IsdnCardState *cs)
1623{
1624 struct PStack *st;
1625 int pr;
1626
1627 if (test_and_clear_bit(D_RCVBUFREADY, &cs->event))
1628 DChannel_proc_rcv(cs);
1629 if (test_and_clear_bit(E_RCVBUFREADY, &cs->event))
1630 EChannel_proc_rcv(cs->hw.hisax_d_if);
1631 if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) {
1632 if (test_bit(0, &cs->hw.hisax_d_if->ph_state))
1633 pr = PH_ACTIVATE | INDICATION;
1634 else
1635 pr = PH_DEACTIVATE | INDICATION;
1636 for (st = cs->stlist; st; st = st->next)
1637 st->l1.l1l2(st, pr, NULL);
1638
1639 }
1640}
1641
1642static void hisax_b_sched_event(struct BCState *bcs, int event)
1643{
1644 test_and_set_bit(event, &bcs->event);
1645 schedule_work(&bcs->tqueue);
1646}
1647
1648static inline void D_L2L1(struct hisax_d_if *d_if, int pr, void *arg)
1649{
1650 struct hisax_if *ifc = (struct hisax_if *) d_if;
1651 ifc->l2l1(ifc, pr, arg);
1652}
1653
1654static inline void B_L2L1(struct hisax_b_if *b_if, int pr, void *arg)
1655{
1656 struct hisax_if *ifc = (struct hisax_if *) b_if;
1657 ifc->l2l1(ifc, pr, arg);
1658}
1659
1660static void hisax_d_l1l2(struct hisax_if *ifc, int pr, void *arg)
1661{
1662 struct hisax_d_if *d_if = (struct hisax_d_if *) ifc;
1663 struct IsdnCardState *cs = d_if->cs;
1664 struct PStack *st;
1665 struct sk_buff *skb;
1666
1667 switch (pr) {
1668 case PH_ACTIVATE | INDICATION:
1669 set_bit(0, &d_if->ph_state);
1670 hisax_sched_event(cs, D_L1STATECHANGE);
1671 break;
1672 case PH_DEACTIVATE | INDICATION:
1673 clear_bit(0, &d_if->ph_state);
1674 hisax_sched_event(cs, D_L1STATECHANGE);
1675 break;
1676 case PH_DATA | INDICATION:
1677 skb_queue_tail(&cs->rq, arg);
1678 hisax_sched_event(cs, D_RCVBUFREADY);
1679 break;
1680 case PH_DATA | CONFIRM:
1681 skb = skb_dequeue(&cs->sq);
1682 if (skb) {
1683 D_L2L1(d_if, PH_DATA | REQUEST, skb);
1684 break;
1685 }
1686 clear_bit(FLG_L1_DBUSY, &cs->HW_Flags);
1687 for (st = cs->stlist; st; st = st->next) {
1688 if (test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags)) {
1689 st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
1690 break;
1691 }
1692 }
1693 break;
1694 case PH_DATA_E | INDICATION:
1695 skb_queue_tail(&d_if->erq, arg);
1696 hisax_sched_event(cs, E_RCVBUFREADY);
1697 break;
1698 default:
1699 printk("pr %#x\n", pr);
1700 break;
1701 }
1702}
1703
1704static void hisax_b_l1l2(struct hisax_if *ifc, int pr, void *arg)
1705{
1706 struct hisax_b_if *b_if = (struct hisax_b_if *) ifc;
1707 struct BCState *bcs = b_if->bcs;
1708 struct PStack *st = bcs->st;
1709 struct sk_buff *skb;
1710
1711
1712 switch (pr) {
1713 case PH_ACTIVATE | INDICATION:
1714 st->l1.l1l2(st, pr, NULL);
1715 break;
1716 case PH_DEACTIVATE | INDICATION:
1717 st->l1.l1l2(st, pr, NULL);
1718 clear_bit(BC_FLG_BUSY, &bcs->Flag);
1719 skb_queue_purge(&bcs->squeue);
1720 bcs->hw.b_if = NULL;
1721 break;
1722 case PH_DATA | INDICATION:
1723 skb_queue_tail(&bcs->rqueue, arg);
1724 hisax_b_sched_event(bcs, B_RCVBUFREADY);
1725 break;
1726 case PH_DATA | CONFIRM:
1727 bcs->tx_cnt -= (int) arg;
1728 if (test_bit(FLG_LLI_L1WAKEUP,&bcs->st->lli.flag)) {
1729 u_long flags;
1730 spin_lock_irqsave(&bcs->aclock, flags);
1731 bcs->ackcnt += (int) arg;
1732 spin_unlock_irqrestore(&bcs->aclock, flags);
1733 schedule_event(bcs, B_ACKPENDING);
1734 }
1735 skb = skb_dequeue(&bcs->squeue);
1736 if (skb) {
1737 B_L2L1(b_if, PH_DATA | REQUEST, skb);
1738 break;
1739 }
1740 clear_bit(BC_FLG_BUSY, &bcs->Flag);
1741 if (test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags)) {
1742 st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
1743 }
1744 break;
1745 default:
1746 printk("hisax_b_l1l2 pr %#x\n", pr);
1747 break;
1748 }
1749}
1750
1751static void hisax_d_l2l1(struct PStack *st, int pr, void *arg)
1752{
1753 struct IsdnCardState *cs = st->l1.hardware;
1754 struct hisax_d_if *hisax_d_if = cs->hw.hisax_d_if;
1755 struct sk_buff *skb = arg;
1756
1757 switch (pr) {
1758 case PH_DATA | REQUEST:
1759 case PH_PULL | INDICATION:
1760 if (cs->debug & DEB_DLOG_HEX)
1761 LogFrame(cs, skb->data, skb->len);
1762 if (cs->debug & DEB_DLOG_VERBOSE)
1763 dlogframe(cs, skb, 0);
1764 Logl2Frame(cs, skb, "PH_DATA_REQ", 0);
1765
1766 if (!test_and_set_bit(FLG_L1_DBUSY, &cs->HW_Flags))
1767 D_L2L1(hisax_d_if, PH_DATA | REQUEST, skb);
1768 else
1769 skb_queue_tail(&cs->sq, skb);
1770 break;
1771 case PH_PULL | REQUEST:
1772 if (!test_bit(FLG_L1_DBUSY, &cs->HW_Flags))
1773 st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
1774 else
1775 set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
1776 break;
1777 default:
1778 D_L2L1(hisax_d_if, pr, arg);
1779 break;
1780 }
1781}
1782
1783static int hisax_cardmsg(struct IsdnCardState *cs, int mt, void *arg)
1784{
1785 return 0;
1786}
1787
1788static void hisax_b_l2l1(struct PStack *st, int pr, void *arg)
1789{
1790 struct BCState *bcs = st->l1.bcs;
1791 struct hisax_b_if *b_if = bcs->hw.b_if;
1792
1793 switch (pr) {
1794 case PH_ACTIVATE | REQUEST:
1795 B_L2L1(b_if, pr, (void *) st->l1.mode);
1796 break;
1797 case PH_DATA | REQUEST:
1798 case PH_PULL | INDICATION:
1799
1800 if (!test_and_set_bit(BC_FLG_BUSY, &bcs->Flag)) {
1801 B_L2L1(b_if, PH_DATA | REQUEST, arg);
1802 } else {
1803 skb_queue_tail(&bcs->squeue, arg);
1804 }
1805 break;
1806 case PH_PULL | REQUEST:
1807 if (!test_bit(BC_FLG_BUSY, &bcs->Flag))
1808 st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
1809 else
1810 set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
1811 break;
1812 case PH_DEACTIVATE | REQUEST:
1813 test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
1814 skb_queue_purge(&bcs->squeue);
1815 default:
1816 B_L2L1(b_if, pr, arg);
1817 break;
1818 }
1819}
1820
1821static int hisax_bc_setstack(struct PStack *st, struct BCState *bcs)
1822{
1823 struct IsdnCardState *cs = st->l1.hardware;
1824 struct hisax_d_if *hisax_d_if = cs->hw.hisax_d_if;
1825
1826 bcs->channel = st->l1.bc;
1827
1828 bcs->hw.b_if = hisax_d_if->b_if[st->l1.bc];
1829 hisax_d_if->b_if[st->l1.bc]->bcs = bcs;
1830
1831 st->l1.bcs = bcs;
1832 st->l2.l2l1 = hisax_b_l2l1;
1833 setstack_manager(st);
1834 bcs->st = st;
1835 setstack_l1_B(st);
1836 skb_queue_head_init(&bcs->rqueue);
1837 skb_queue_head_init(&bcs->squeue);
1838 return 0;
1839}
1840
1841static void hisax_bc_close(struct BCState *bcs)
1842{
1843 struct hisax_b_if *b_if = bcs->hw.b_if;
1844
1845 if (b_if)
1846 B_L2L1(b_if, PH_DEACTIVATE | REQUEST, NULL);
1847}
1848
1849static void EChannel_proc_rcv(struct hisax_d_if *d_if)
1850{
1851 struct IsdnCardState *cs = d_if->cs;
1852 u_char *ptr;
1853 struct sk_buff *skb;
1854
1855 while ((skb = skb_dequeue(&d_if->erq)) != NULL) {
1856 if (cs->debug & DEB_DLOG_HEX) {
1857 ptr = cs->dlog;
1858 if ((skb->len) < MAX_DLOG_SPACE / 3 - 10) {
1859 *ptr++ = 'E';
1860 *ptr++ = 'C';
1861 *ptr++ = 'H';
1862 *ptr++ = 'O';
1863 *ptr++ = ':';
1864 ptr += QuickHex(ptr, skb->data, skb->len);
1865 ptr--;
1866 *ptr++ = '\n';
1867 *ptr = 0;
1868 HiSax_putstatus(cs, NULL, cs->dlog);
1869 } else
1870 HiSax_putstatus(cs, "LogEcho: ",
1871 "warning Frame too big (%d)",
1872 skb->len);
1873 }
1874 dev_kfree_skb_any(skb);
1875 }
1876}
1877
1878#ifdef CONFIG_PCI
1879#include <linux/pci.h>
1880
1881static struct pci_device_id hisax_pci_tbl[] __initdata = {
1882#ifdef CONFIG_HISAX_FRITZPCI
1883 {PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_A1, PCI_ANY_ID, PCI_ANY_ID},
1884#endif
1885#ifdef CONFIG_HISAX_DIEHLDIVA
1886 {PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_DIVA20, PCI_ANY_ID, PCI_ANY_ID},
1887 {PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_DIVA20_U, PCI_ANY_ID, PCI_ANY_ID},
1888 {PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_DIVA201, PCI_ANY_ID, PCI_ANY_ID},
1889
1890 {PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_DIVA202, PCI_ANY_ID, PCI_ANY_ID},
1891
1892#endif
1893#ifdef CONFIG_HISAX_ELSA
1894 {PCI_VENDOR_ID_ELSA, PCI_DEVICE_ID_ELSA_MICROLINK, PCI_ANY_ID, PCI_ANY_ID},
1895 {PCI_VENDOR_ID_ELSA, PCI_DEVICE_ID_ELSA_QS3000, PCI_ANY_ID, PCI_ANY_ID},
1896#endif
1897#ifdef CONFIG_HISAX_GAZEL
1898 {PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_R685, PCI_ANY_ID, PCI_ANY_ID},
1899 {PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_R753, PCI_ANY_ID, PCI_ANY_ID},
1900 {PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_DJINN_ITOO, PCI_ANY_ID, PCI_ANY_ID},
1901#endif
1902#ifdef CONFIG_HISAX_QUADRO
1903 {PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, PCI_ANY_ID, PCI_ANY_ID},
1904#endif
1905#ifdef CONFIG_HISAX_NICCY
1906 {PCI_VENDOR_ID_SATSAGEM, PCI_DEVICE_ID_SATSAGEM_NICCY, PCI_ANY_ID,PCI_ANY_ID},
1907#endif
1908#ifdef CONFIG_HISAX_SEDLBAUER
1909 {PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100, PCI_ANY_ID,PCI_ANY_ID},
1910#endif
1911#if defined(CONFIG_HISAX_NETJET) || defined(CONFIG_HISAX_NETJET_U)
1912 {PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_300, PCI_ANY_ID,PCI_ANY_ID},
1913#endif
1914#if defined(CONFIG_HISAX_TELESPCI) || defined(CONFIG_HISAX_SCT_QUADRO)
1915 {PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36120, PCI_ANY_ID,PCI_ANY_ID},
1916#endif
1917#ifdef CONFIG_HISAX_W6692
1918 {PCI_VENDOR_ID_DYNALINK, PCI_DEVICE_ID_DYNALINK_IS64PH, PCI_ANY_ID,PCI_ANY_ID},
1919 {PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_6692, PCI_ANY_ID,PCI_ANY_ID},
1920#endif
1921#ifdef CONFIG_HISAX_HFC_PCI
1922 {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_2BD0, PCI_ANY_ID, PCI_ANY_ID},
1923 {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B000, PCI_ANY_ID, PCI_ANY_ID},
1924 {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B006, PCI_ANY_ID, PCI_ANY_ID},
1925 {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B007, PCI_ANY_ID, PCI_ANY_ID},
1926 {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B008, PCI_ANY_ID, PCI_ANY_ID},
1927 {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B009, PCI_ANY_ID, PCI_ANY_ID},
1928 {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00A, PCI_ANY_ID, PCI_ANY_ID},
1929 {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00B, PCI_ANY_ID, PCI_ANY_ID},
1930 {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00C, PCI_ANY_ID, PCI_ANY_ID},
1931 {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B100, PCI_ANY_ID, PCI_ANY_ID},
1932 {PCI_VENDOR_ID_ABOCOM, PCI_DEVICE_ID_ABOCOM_2BD1, PCI_ANY_ID, PCI_ANY_ID},
1933 {PCI_VENDOR_ID_ASUSTEK, PCI_DEVICE_ID_ASUSTEK_0675, PCI_ANY_ID, PCI_ANY_ID},
1934 {PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_T_CONCEPT, PCI_ANY_ID, PCI_ANY_ID},
1935 {PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_A1T, PCI_ANY_ID, PCI_ANY_ID},
1936 {PCI_VENDOR_ID_ANIGMA, PCI_DEVICE_ID_ANIGMA_MC145575, PCI_ANY_ID, PCI_ANY_ID},
1937 {PCI_VENDOR_ID_ZOLTRIX, PCI_DEVICE_ID_ZOLTRIX_2BD0, PCI_ANY_ID, PCI_ANY_ID},
1938 {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_E, PCI_ANY_ID, PCI_ANY_ID},
1939 {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_E, PCI_ANY_ID, PCI_ANY_ID},
1940 {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_A, PCI_ANY_ID, PCI_ANY_ID},
1941 {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_A, PCI_ANY_ID, PCI_ANY_ID},
1942#endif
1943 { }
1944};
1945
1946MODULE_DEVICE_TABLE(pci, hisax_pci_tbl);
1947#endif
1948
1949module_init(HiSax_init);
1950module_exit(HiSax_exit);
1951
1952EXPORT_SYMBOL(FsmNew);
1953EXPORT_SYMBOL(FsmFree);
1954EXPORT_SYMBOL(FsmEvent);
1955EXPORT_SYMBOL(FsmChangeState);
1956EXPORT_SYMBOL(FsmInitTimer);
1957EXPORT_SYMBOL(FsmDelTimer);
1958EXPORT_SYMBOL(FsmRestartTimer);
1959