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