This source file includes following definitions.
- icn_new_buf
- icn_free_queue
- icn_shiftout
- icn_map_channel
- icn_lock_channel
- icn_release_channel
- icn_trymaplock_channel
- icn_maprelease_channel
- icn_pollbchan_receive
- icn_pollbchan_send
- icn_pollbchan
- icn_pollit
- icn_pollcard
- icn_sendbuf
- icn_check_loader
- icn_loadboot
- icn_loadproto
- icn_readstatus
- icn_writecmd
- icn_stopdriver
- my_atoi
- icn_command
- if_command1
- if_command2
- if_writecmd1
- if_writecmd2
- if_readstatus1
- if_readstatus2
- if_sendbuf1
- if_sendbuf2
- icn_setup
- icn_init
- cleanup_module
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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 #include "icn.h"
84
85
86
87
88
89
90 #undef BOOT_DEBUG
91
92
93
94
95 #undef MAP_DEBUG
96
97
98
99
100 #undef LOADEXTERN
101
102 static char
103 *revision = "$Revision: 1.17 $";
104
105 static void icn_pollcard(unsigned long dummy);
106
107
108 static u_char *
109 icn_new_buf(pqueue ** queue, int length)
110 {
111 pqueue *p;
112 pqueue *q;
113
114 if ((p = *queue)) {
115 while (p) {
116 q = p;
117 p = (pqueue *) p->next;
118 }
119 p = (pqueue *) kmalloc(sizeof(pqueue) + length, GFP_ATOMIC);
120 q->next = (u_char *) p;
121 } else
122 p = *queue = (pqueue *) kmalloc(sizeof(pqueue) + length, GFP_ATOMIC);
123 if (p) {
124 p->size = sizeof(pqueue) + length;
125 p->length = length;
126 p->next = NULL;
127 p->rptr = p->buffer;
128 return p->buffer;
129 } else {
130 return (u_char *) NULL;
131 }
132 }
133
134 #ifdef MODULE
135 static void icn_free_queue(pqueue ** queue)
136 {
137 pqueue *p;
138 pqueue *q;
139
140 p = *queue;
141 while (p) {
142 q = p;
143 p = (pqueue *) p->next;
144 kfree_s(q, q->size);
145 }
146 *queue = (pqueue *) 0;
147 }
148 #endif
149
150
151
152
153
154
155
156
157 static inline void icn_shiftout(unsigned short port,
158 unsigned long val,
159 int firstbit,
160 int bitcount)
161 {
162
163 register u_char s;
164 register u_char c;
165
166 for (s = firstbit, c = bitcount; c > 0; s--, c--)
167 OUTB_P((u_char) ((val >> s) & 1) ? 0xff : 0, port);
168 }
169
170
171
172
173 static inline void icn_map_channel(int channel)
174 {
175 static u_char chan2bank[] =
176 {0, 4, 8, 12};
177
178 #ifdef MAP_DEBUG
179 printk(KERN_DEBUG "icn_map_channel %d %d\n", dev->channel, channel);
180 #endif
181 if (channel == dev->channel)
182 return;
183 OUTB_P(0, ICN_MAPRAM);
184 icn_shiftout(ICN_BANK, chan2bank[channel], 3, 4);
185 OUTB_P(0xff, ICN_MAPRAM);
186 dev->channel = channel;
187 #ifdef MAP_DEBUG
188 printk(KERN_DEBUG "icn_map_channel done\n");
189 #endif
190 }
191
192 static inline int icn_lock_channel(int channel)
193 {
194 register int retval;
195 ulong flags;
196
197 #ifdef MAP_DEBUG
198 printk(KERN_DEBUG "icn_lock_channel %d\n", channel);
199 #endif
200 save_flags(flags);
201 cli();
202 if (dev->channel == channel) {
203 dev->chanlock++;
204 retval = 1;
205 #ifdef MAP_DEBUG
206 printk(KERN_DEBUG "icn_lock_channel %d OK\n", channel);
207 #endif
208 } else {
209 retval = 0;
210 #ifdef MAP_DEBUG
211 printk(KERN_DEBUG "icn_lock_channel %d FAILED, dc=%d\n", channel, dev->channel);
212 #endif
213 }
214 restore_flags(flags);
215 return retval;
216 }
217
218 static inline void icn_release_channel(void)
219 {
220 ulong flags;
221
222 #ifdef MAP_DEBUG
223 printk(KERN_DEBUG "icn_release_channel l=%d\n", dev->chanlock);
224 #endif
225 save_flags(flags);
226 cli();
227 if (dev->chanlock)
228 dev->chanlock--;
229 restore_flags(flags);
230 }
231
232 static inline int icn_trymaplock_channel(int channel)
233 {
234 ulong flags;
235
236 save_flags(flags);
237 cli();
238 #ifdef MAP_DEBUG
239 printk(KERN_DEBUG "trymaplock c=%d dc=%d l=%d\n", channel, dev->channel,
240 dev->chanlock);
241 #endif
242 if ((!dev->chanlock) || (dev->channel == channel)) {
243 dev->chanlock++;
244 icn_map_channel(channel);
245 restore_flags(flags);
246 #ifdef MAP_DEBUG
247 printk(KERN_DEBUG "trymaplock %d OK\n", channel);
248 #endif
249 return 1;
250 }
251 restore_flags(flags);
252 #ifdef MAP_DEBUG
253 printk(KERN_DEBUG "trymaplock %d FAILED\n", channel);
254 #endif
255 return 0;
256 }
257
258 static inline void icn_maprelease_channel(int channel)
259 {
260 ulong flags;
261
262 save_flags(flags);
263 cli();
264 #ifdef MAP_DEBUG
265 printk(KERN_DEBUG "map_release c=%d l=%d\n", channel, dev->chanlock);
266 #endif
267 if (dev->chanlock)
268 dev->chanlock--;
269 if (!dev->chanlock)
270 icn_map_channel(channel);
271 restore_flags(flags);
272 }
273
274
275
276
277
278
279
280 #ifdef DEBUG_RCVCALLBACK
281 static int max_pending[2] =
282 {0, 0};
283 #endif
284
285 static void icn_pollbchan_receive(int channel, icn_dev * dev)
286 {
287 int mch = channel + ((dev->secondhalf) ? 2 : 0);
288 int eflag;
289 int cnt;
290 int flags;
291 #ifdef DEBUG_RCVCALLBACK
292 int rcv_pending1;
293 int rcv_pending2;
294 int akt_pending;
295 #endif
296
297 if (icn_trymaplock_channel(mch)) {
298 while (rbavl) {
299 cnt = rbuf_l;
300 if ((dev->rcvidx[channel] + cnt) > 4000) {
301 printk(KERN_WARNING "icn: bogus packet on ch%d, dropping.\n",
302 channel + 1);
303 dev->rcvidx[channel] = 0;
304 eflag = 0;
305 } else {
306 memcpy(&dev->rcvbuf[channel][dev->rcvidx[channel]], rbuf_d, cnt);
307 dev->rcvidx[channel] += cnt;
308 eflag = rbuf_f;
309 }
310 rbnext;
311 icn_maprelease_channel(mch & 2);
312 if (!eflag) {
313 save_flags(flags);
314 cli();
315 #ifdef DEBUG_RCVCALLBACK
316 rcv_pending1 =
317 (dev->shmem->data_control.ecnr > dev->shmem->data_control.ecns) ?
318 0xf - dev->shmem->data_control.ecnr + dev->shmem->data_control.ecns :
319 dev->shmem->data_control.ecns - dev->shmem->data_control.ecnr;
320 #endif
321 dev->interface.rcvcallb(dev->myid, channel, dev->rcvbuf[channel],
322 dev->rcvidx[channel]);
323 dev->rcvidx[channel] = 0;
324 #ifdef DEBUG_RCVCALLBACK
325 rcv_pending2 =
326 (dev->shmem->data_control.ecnr > dev->shmem->data_control.ecns) ?
327 0xf - dev->shmem->data_control.ecnr + dev->shmem->data_control.ecns :
328 dev->shmem->data_control.ecns - dev->shmem->data_control.ecnr;
329 akt_pending = rcv_pending2 - rcv_pending1;
330 if (akt_pending > max_pending[channel]) {
331 max_pending[channel] = akt_pending;
332 printk(KERN_DEBUG "ICN_DEBUG: pend: %d %d\n", max_pending[0], max_pending[1]);
333 }
334 #endif
335 restore_flags(flags);
336 }
337 if (!icn_trymaplock_channel(mch))
338 break;
339 }
340 icn_maprelease_channel(mch & 2);
341 }
342 }
343
344
345
346
347
348
349
350
351 static void icn_pollbchan_send(int channel, icn_dev * dev)
352 {
353 int mch = channel + ((dev->secondhalf) ? 2 : 0);
354 int eflag = 0;
355 int cnt;
356 int left;
357 int flags;
358 pqueue *p;
359 isdn_ctrl cmd;
360
361 if (!dev->sndcount[channel])
362 return;
363 if (icn_trymaplock_channel(mch)) {
364 while (sbfree && dev->sndcount[channel]) {
365 left = dev->spqueue[channel]->length;
366 cnt =
367 (sbuf_l =
368 (left > ICN_FRAGSIZE) ? ((sbuf_f = 0xff), ICN_FRAGSIZE) : ((sbuf_f = 0), left));
369 memcpy(sbuf_d, dev->spqueue[channel]->rptr, cnt);
370 sbnext;
371 icn_maprelease_channel(mch & 2);
372 dev->spqueue[channel]->rptr += cnt;
373 eflag = ((dev->spqueue[channel]->length -= cnt) == 0);
374 save_flags(flags);
375 cli();
376 p = dev->spqueue[channel];
377 dev->sndcount[channel] -= cnt;
378 if (eflag)
379 dev->spqueue[channel] = (pqueue *) dev->spqueue[channel]->next;
380 restore_flags(flags);
381 if (eflag) {
382 kfree_s(p, p->size);
383 cmd.command = ISDN_STAT_BSENT;
384 cmd.driver = dev->myid;
385 cmd.arg = channel;
386 dev->interface.statcallb(&cmd);
387 }
388 if (!icn_trymaplock_channel(mch))
389 break;
390 }
391 icn_maprelease_channel(mch & 2);
392 }
393 }
394
395
396
397
398
399
400 static void icn_pollbchan(unsigned long dummy)
401 {
402 unsigned long flags;
403
404 dev->flags |= ICN_FLAGS_RBTIMER;
405 if (dev->flags & ICN_FLAGS_B1ACTIVE) {
406 icn_pollbchan_receive(0, dev);
407 icn_pollbchan_send(0, dev);
408 }
409 if (dev->flags & ICN_FLAGS_B2ACTIVE) {
410 icn_pollbchan_receive(1, dev);
411 icn_pollbchan_send(1, dev);
412 }
413 if (dev->doubleS0) {
414 if (dev2->flags & ICN_FLAGS_B1ACTIVE) {
415 icn_pollbchan_receive(0, dev2);
416 icn_pollbchan_send(0, dev2);
417 }
418 if (dev2->flags & ICN_FLAGS_B2ACTIVE) {
419 icn_pollbchan_receive(1, dev2);
420 icn_pollbchan_send(1, dev2);
421 }
422 }
423 if (dev->flags & (ICN_FLAGS_B1ACTIVE | ICN_FLAGS_B2ACTIVE)) {
424
425 save_flags(flags);
426 cli();
427 del_timer(&dev->rb_timer);
428 dev->rb_timer.function = icn_pollbchan;
429 dev->rb_timer.expires = jiffies + ICN_TIMER_BCREAD;
430 add_timer(&dev->rb_timer);
431 restore_flags(flags);
432 } else
433 dev->flags &= ~ICN_FLAGS_RBTIMER;
434 if (dev->doubleS0) {
435 if (dev2->flags & (ICN_FLAGS_B1ACTIVE | ICN_FLAGS_B2ACTIVE)) {
436
437 save_flags(flags);
438 cli();
439 del_timer(&dev2->rb_timer);
440 dev2->rb_timer.function = icn_pollbchan;
441 dev2->rb_timer.expires = jiffies + ICN_TIMER_BCREAD;
442 add_timer(&dev2->rb_timer);
443 restore_flags(flags);
444 } else
445 dev2->flags &= ~ICN_FLAGS_RBTIMER;
446 }
447 }
448
449 static void icn_pollit(icn_dev * dev)
450 {
451 int mch = dev->secondhalf ? 2 : 0;
452 int avail = 0;
453 int dflag = 0;
454 int left;
455 u_char c;
456 int ch;
457 int flags;
458 int i;
459 u_char *p;
460 isdn_ctrl cmd;
461
462 if (icn_trymaplock_channel(mch)) {
463 avail = msg_avail;
464 for (left = avail, i = msg_o; left > 0; i++, left--) {
465 c = dev->shmem->comm_buffers.iopc_buf[i & 0xff];
466 save_flags(flags);
467 cli();
468 *dev->msg_buf_write++ = (c == 0xff) ? '\n' : c;
469
470 if (dev->msg_buf_write > dev->msg_buf_end)
471 dev->msg_buf_write = dev->msg_buf;
472 restore_flags(flags);
473 if (c == 0xff) {
474 dev->imsg[dev->iptr] = 0;
475 dev->iptr = 0;
476 if (dev->imsg[0] == '0' && dev->imsg[1] >= '0' &&
477 dev->imsg[1] <= '2' && dev->imsg[2] == ';') {
478 ch = dev->imsg[1] - '0';
479 p = &dev->imsg[3];
480 if (!strncmp(p, "BCON_", 5)) {
481 switch (ch) {
482 case 1:
483 dev->flags |= ICN_FLAGS_B1ACTIVE;
484 break;
485 case 2:
486 dev->flags |= ICN_FLAGS_B2ACTIVE;
487 break;
488 }
489 cmd.command = ISDN_STAT_BCONN;
490 cmd.driver = dev->myid;
491 cmd.arg = ch - 1;
492 dev->interface.statcallb(&cmd);
493 continue;
494 }
495 if (!strncmp(p, "TEI OK", 6)) {
496 cmd.command = ISDN_STAT_RUN;
497 cmd.driver = dev->myid;
498 cmd.arg = ch - 1;
499 dev->interface.statcallb(&cmd);
500 continue;
501 }
502 if (!strncmp(p, "BDIS_", 5)) {
503 switch (ch) {
504 case 1:
505 dev->flags &= ~ICN_FLAGS_B1ACTIVE;
506 dflag |= 1;
507 break;
508 case 2:
509 dev->flags &= ~ICN_FLAGS_B2ACTIVE;
510 dflag |= 2;
511 break;
512 }
513 cmd.command = ISDN_STAT_BHUP;
514 cmd.arg = ch - 1;
515 cmd.driver = dev->myid;
516 dev->interface.statcallb(&cmd);
517 continue;
518 }
519 if (!strncmp(p, "DCON_", 5)) {
520 cmd.command = ISDN_STAT_DCONN;
521 cmd.arg = ch - 1;
522 cmd.driver = dev->myid;
523 dev->interface.statcallb(&cmd);
524 continue;
525 }
526 if (!strncmp(p, "DDIS_", 5)) {
527 cmd.command = ISDN_STAT_DHUP;
528 cmd.arg = ch - 1;
529 cmd.driver = dev->myid;
530 dev->interface.statcallb(&cmd);
531 continue;
532 }
533 if (!strncmp(p, "E_L1: ACT FAIL", 14)) {
534 cmd.command = ISDN_STAT_BHUP;
535 cmd.arg = 0;
536 cmd.driver = dev->myid;
537 dev->interface.statcallb(&cmd);
538 cmd.command = ISDN_STAT_DHUP;
539 cmd.arg = 0;
540 cmd.driver = dev->myid;
541 dev->interface.statcallb(&cmd);
542 continue;
543 }
544 if (!strncmp(p, "CIF", 3)) {
545 cmd.command = ISDN_STAT_CINF;
546 cmd.arg = ch - 1;
547 strncpy(cmd.num, p + 3, sizeof(cmd.num) - 1);
548 cmd.driver = dev->myid;
549 dev->interface.statcallb(&cmd);
550 continue;
551 }
552 if (!strncmp(p, "CAU", 3)) {
553 cmd.command = ISDN_STAT_CAUSE;
554 cmd.arg = ch - 1;
555 strncpy(cmd.num, p + 3, sizeof(cmd.num) - 1);
556 cmd.driver = dev->myid;
557 dev->interface.statcallb(&cmd);
558 continue;
559 }
560 if (!strncmp(p, "DCAL_I", 6)) {
561 cmd.command = ISDN_STAT_ICALL;
562 cmd.driver = dev->myid;
563 cmd.arg = ch - 1;
564 strncpy(cmd.num, p + 6, sizeof(cmd.num) - 1);
565 dev->interface.statcallb(&cmd);
566 continue;
567 }
568 if (!strncmp(p, "FCALL", 5)) {
569 cmd.command = ISDN_STAT_ICALL;
570 cmd.driver = dev->myid;
571 cmd.arg = ch - 1;
572 strcpy(cmd.num, "LEASED,07,00,1");
573 dev->interface.statcallb(&cmd);
574 continue;
575 }
576 if (!strncmp(p, "DSCA_I", 6)) {
577 cmd.command = ISDN_STAT_ICALL;
578 cmd.driver = dev->myid;
579 cmd.arg = ch - 1;
580 strncpy(cmd.num, p + 6, sizeof(cmd.num) - 1);
581 dev->interface.statcallb(&cmd);
582 continue;
583 }
584 if (!strncmp(p, "NO D-CHAN", 9)) {
585 cmd.command = ISDN_STAT_NODCH;
586 cmd.driver = dev->myid;
587 cmd.arg = ch - 1;
588 strncpy(cmd.num, p + 6, sizeof(cmd.num) - 1);
589 dev->interface.statcallb(&cmd);
590 continue;
591 }
592 } else {
593 p = dev->imsg;
594 if (!strncmp(p, "DRV1.", 5)) {
595 printk(KERN_INFO "icn: %s\n",p);
596 if (!strncmp(p + 7, "TC", 2)) {
597 dev->ptype = ISDN_PTYPE_1TR6;
598 dev->interface.features |= ISDN_FEATURE_P_1TR6;
599 printk(KERN_INFO "icn: 1TR6-Protocol loaded and running\n");
600 }
601 if (!strncmp(p + 7, "EC", 2)) {
602 dev->ptype = ISDN_PTYPE_EURO;
603 dev->interface.features |= ISDN_FEATURE_P_EURO;
604 printk(KERN_INFO "icn: Euro-Protocol loaded and running\n");
605 }
606 continue;
607 }
608 }
609 } else {
610 dev->imsg[dev->iptr] = c;
611 if (dev->iptr < 59)
612 dev->iptr++;
613 }
614 }
615 msg_o = (msg_o + avail) & 0xff;
616 icn_release_channel();
617 }
618 if (avail) {
619 cmd.command = ISDN_STAT_STAVAIL;
620 cmd.driver = dev->myid;
621 cmd.arg = avail;
622 dev->interface.statcallb(&cmd);
623 }
624 if (dflag & 1)
625 dev->interface.rcvcallb(dev->myid, 0, dev->rcvbuf[0], 0);
626 if (dflag & 2)
627 dev->interface.rcvcallb(dev->myid, 1, dev->rcvbuf[1], 0);
628 if (dev->flags & (ICN_FLAGS_B1ACTIVE | ICN_FLAGS_B2ACTIVE))
629 if (!(dev->flags & ICN_FLAGS_RBTIMER)) {
630
631 dev->flags |= ICN_FLAGS_RBTIMER;
632 save_flags(flags);
633 cli();
634 del_timer(&dev->rb_timer);
635 dev->rb_timer.function = icn_pollbchan;
636 dev->rb_timer.expires = jiffies + ICN_TIMER_BCREAD;
637 add_timer(&dev->rb_timer);
638 restore_flags(flags);
639 }
640 }
641
642
643
644
645
646
647
648
649
650
651
652 static void icn_pollcard(unsigned long dummy)
653 {
654 ulong flags;
655
656 icn_pollit(dev);
657 if (dev->doubleS0)
658 icn_pollit(dev2);
659
660 save_flags(flags);
661 cli();
662 del_timer(&dev->st_timer);
663 dev->st_timer.function = icn_pollcard;
664 dev->st_timer.expires = jiffies + ICN_TIMER_DCREAD;
665 add_timer(&dev->st_timer);
666 restore_flags(flags);
667 }
668
669
670
671
672
673
674
675
676
677
678
679
680 static int icn_sendbuf(int channel, const u_char * buffer, int len, int user, icn_dev * dev)
681 {
682 register u_char *p;
683 int flags;
684
685 if (len > 4000)
686 return -EINVAL;
687 if (len) {
688 if (dev->sndcount[channel] > ICN_MAX_SQUEUE)
689 return 0;
690 save_flags(flags);
691 cli();
692 p = icn_new_buf(&dev->spqueue[channel], len);
693 if (!p) {
694 restore_flags(flags);
695 return 0;
696 }
697 if (user) {
698 memcpy_fromfs(p, buffer, len);
699 } else {
700 memcpy(p, buffer, len);
701 }
702 dev->sndcount[channel] += len;
703 icn_pollbchan_send(channel, dev);
704 restore_flags(flags);
705 }
706 return len;
707 }
708
709 #ifndef LOADEXTERN
710 static int icn_check_loader(int cardnumber)
711 {
712 int timer = 0;
713
714 while (1) {
715 #ifdef BOOT_DEBUG
716 printk(KERN_DEBUG "Loader %d ?\n", cardnumber);
717 #endif
718 if (dev->shmem->data_control.scns ||
719 dev->shmem->data_control.scnr) {
720 if (timer++ > 5) {
721 printk(KERN_WARNING "icn: Boot-Loader %d timed out.\n", cardnumber);
722 icn_release_channel();
723 return -EIO;
724 }
725 #ifdef BOOT_DEBUG
726 printk(KERN_DEBUG "Loader %d TO?\n", cardnumber);
727 #endif
728 current->state = TASK_INTERRUPTIBLE;
729 current->timeout = jiffies + ICN_BOOT_TIMEOUT1;
730 schedule();
731 } else {
732 #ifdef BOOT_DEBUG
733 printk(KERN_DEBUG "Loader %d OK\n", cardnumber);
734 #endif
735 icn_release_channel();
736 return 0;
737 }
738 }
739 }
740
741
742
743
744
745
746
747
748
749
750 #ifdef BOOT_DEBUG
751 #define SLEEP(sec) { \
752 int slsec = sec; \
753 printk(KERN_DEBUG "SLEEP(%d)\n",slsec); \
754 while (slsec) { \
755 current->state = TASK_INTERRUPTIBLE; \
756 current->timeout = jiffies + HZ; \
757 schedule(); \
758 slsec--; \
759 } \
760 }
761 #else
762 #define SLEEP(sec)
763 #endif
764
765 static int icn_loadboot(u_char * buffer, icn_dev * dev)
766 {
767 int ret;
768 ulong flags;
769
770 #ifdef BOOT_DEBUG
771 printk(KERN_DEBUG "icn_loadboot called, buffaddr=%08lx\n", (ulong) buffer);
772 #endif
773 if ((ret = verify_area(VERIFY_READ, (void *) buffer, ICN_CODE_STAGE1)))
774 return ret;
775 save_flags(flags);
776 cli();
777 if (!dev->rvalid) {
778 if (check_region(dev->port, ICN_PORTLEN)) {
779 printk(KERN_WARNING "icn: ports 0x%03x-0x%03x in use.\n", dev->port,
780 dev->port + ICN_PORTLEN);
781 restore_flags(flags);
782 return -EBUSY;
783 }
784 request_region(dev->port, ICN_PORTLEN, regname);
785 dev->rvalid = 1;
786 }
787 if (!dev->mvalid) {
788 if (check_shmem((ulong) dev->shmem, 0x4000)) {
789 printk(KERN_WARNING "icn: memory at 0x%08lx in use.\n", (ulong) dev->shmem);
790 restore_flags(flags);
791 return -EBUSY;
792 }
793 request_shmem((ulong) dev->shmem, 0x4000, regname);
794 dev->mvalid = 1;
795 }
796 restore_flags(flags);
797 OUTB_P(0, ICN_RUN);
798 OUTB_P(0, ICN_MAPRAM);
799 icn_shiftout(ICN_CFG, 0x0f, 3, 4);
800 icn_shiftout(ICN_CFG, (unsigned long) dev->shmem, 23, 10);
801 #ifdef BOOT_DEBUG
802 printk(KERN_DEBUG "shmem=%08lx\n", (ulong) dev->shmem);
803 #endif
804 SLEEP(1);
805 save_flags(flags);
806 cli();
807 dev->channel = 1;
808 #ifdef BOOT_DEBUG
809 printk(KERN_DEBUG "Map Bank 0\n");
810 #endif
811 icn_map_channel(0);
812 icn_lock_channel(0);
813 restore_flags(flags);
814 SLEEP(1);
815 memcpy_fromfs(dev->shmem, buffer, ICN_CODE_STAGE1);
816 #ifdef BOOT_DEBUG
817 printk(KERN_DEBUG "Bootloader transfered\n");
818 #endif
819 if (dev->doubleS0) {
820 SLEEP(1);
821 save_flags(flags);
822 cli();
823 icn_release_channel();
824 #ifdef BOOT_DEBUG
825 printk(KERN_DEBUG "Map Bank 8\n");
826 #endif
827 icn_map_channel(2);
828 icn_lock_channel(2);
829 restore_flags(flags);
830 SLEEP(1);
831 memcpy_fromfs(dev->shmem, buffer, ICN_CODE_STAGE1);
832 #ifdef BOOT_DEBUG
833 printk(KERN_DEBUG "Bootloader transfered\n");
834 #endif
835 }
836 SLEEP(1);
837 OUTB_P(0xff, ICN_RUN);
838 if ((ret = icn_check_loader(dev->doubleS0 ? 2 : 1)))
839 return ret;
840 if (!dev->doubleS0)
841 return 0;
842
843 save_flags(flags);
844 cli();
845 #ifdef BOOT_DEBUG
846 printk(KERN_DEBUG "Map Bank 0\n");
847 #endif
848 icn_map_channel(0);
849 icn_lock_channel(0);
850 restore_flags(flags);
851 SLEEP(1);
852 return (icn_check_loader(1));
853 }
854
855 static int icn_loadproto(u_char * buffer, icn_dev * ldev)
856 {
857 register u_char *p = buffer;
858 uint left = ICN_CODE_STAGE2;
859 uint cnt;
860 int timer;
861 int ret;
862 unsigned long flags;
863
864 #ifdef BOOT_DEBUG
865 printk(KERN_DEBUG "icn_loadproto called\n");
866 #endif
867 if ((ret = verify_area(VERIFY_READ, (void *) buffer, ICN_CODE_STAGE2)))
868 return ret;
869 timer = 0;
870 save_flags(flags);
871 cli();
872 if (ldev->secondhalf) {
873 icn_map_channel(2);
874 icn_lock_channel(2);
875 } else {
876 icn_map_channel(0);
877 icn_lock_channel(0);
878 }
879 restore_flags(flags);
880 while (left) {
881 if (sbfree) {
882 cnt = MIN(256, left);
883 memcpy_fromfs(&sbuf_l, p, cnt);
884 sbnext;
885 p += cnt;
886 left -= cnt;
887 timer = 0;
888 } else {
889 #ifdef BOOT_DEBUG
890 printk(KERN_DEBUG "boot 2 !sbfree\n");
891 #endif
892 if (timer++ > 5) {
893 icn_maprelease_channel(0);
894 return -EIO;
895 }
896 current->state = TASK_INTERRUPTIBLE;
897 current->timeout = jiffies + 10;
898 schedule();
899 }
900 }
901 sbuf_n = 0x20;
902 timer = 0;
903 while (1) {
904 if (cmd_o || cmd_i) {
905 #ifdef BOOT_DEBUG
906 printk(KERN_DEBUG "Proto?\n");
907 #endif
908 if (timer++ > 5) {
909 printk(KERN_WARNING "icn: Protocol timed out.\n");
910 #ifdef BOOT_DEBUG
911 printk(KERN_DEBUG "Proto TO!\n");
912 #endif
913 icn_maprelease_channel(0);
914 return -EIO;
915 }
916 #ifdef BOOT_DEBUG
917 printk(KERN_DEBUG "Proto TO?\n");
918 #endif
919 current->state = TASK_INTERRUPTIBLE;
920 current->timeout = jiffies + ICN_BOOT_TIMEOUT1;
921 schedule();
922 } else {
923 if ((ldev->secondhalf) || (!dev->doubleS0)) {
924 save_flags(flags);
925 cli();
926 #ifdef BOOT_DEBUG
927 printk(KERN_DEBUG "Proto loaded, install poll-timer %d\n",
928 ldev->secondhalf);
929 #endif
930 init_timer(&dev->st_timer);
931 dev->st_timer.expires = jiffies + ICN_TIMER_DCREAD;
932 dev->st_timer.function = icn_pollcard;
933 add_timer(&dev->st_timer);
934 restore_flags(flags);
935 }
936 icn_maprelease_channel(0);
937 return 0;
938 }
939 }
940 }
941 #endif
942
943
944 static int icn_readstatus(u_char * buf, int len, int user, icn_dev * dev)
945 {
946 int count;
947 u_char *p;
948
949 for (p = buf, count = 0; count < len; p++, count++) {
950 if (user)
951 put_fs_byte(*dev->msg_buf_read++, p);
952 else
953 *p = *dev->msg_buf_read++;
954 if (dev->msg_buf_read > dev->msg_buf_end)
955 dev->msg_buf_read = dev->msg_buf;
956 }
957 return count;
958 }
959
960
961 static int icn_writecmd(const u_char * buf, int len, int user, icn_dev * dev, int waitflg)
962 {
963 int mch = dev->secondhalf ? 2 : 0;
964 int avail;
965 int pp;
966 int i;
967 int count;
968 int ocount;
969 unsigned long flags;
970 u_char *p;
971 isdn_ctrl cmd;
972 u_char msg[0x100];
973
974 while (1) {
975 if (icn_trymaplock_channel(mch)) {
976 avail = cmd_free;
977 count = MIN(avail, len);
978 if (user)
979 memcpy_fromfs(msg, buf, count);
980 else
981 memcpy(msg, buf, count);
982 save_flags(flags);
983 cli();
984 ocount = 1;
985 *dev->msg_buf_write++ = '>';
986 if (dev->msg_buf_write > dev->msg_buf_end)
987 dev->msg_buf_write = dev->msg_buf;
988 for (p = msg, pp = cmd_i, i = count; i > 0; i--, p++, pp++) {
989 dev->shmem->comm_buffers.pcio_buf[pp & 0xff] = (*p == '\n') ? 0xff : *p;
990 *dev->msg_buf_write++ = *p;
991 if ((*p == '\n') && (i > 1)) {
992 *dev->msg_buf_write++ = '>';
993 if (dev->msg_buf_write > dev->msg_buf_end)
994 dev->msg_buf_write = dev->msg_buf;
995 ocount++;
996 }
997
998 if (dev->msg_buf_write > dev->msg_buf_end)
999 dev->msg_buf_write = dev->msg_buf;
1000 ocount++;
1001 }
1002 restore_flags(flags);
1003 cmd.command = ISDN_STAT_STAVAIL;
1004 cmd.driver = dev->myid;
1005 cmd.arg = ocount;
1006 dev->interface.statcallb(&cmd);
1007 cmd_i = (cmd_i + count) & 0xff;
1008 icn_release_channel();
1009 waitflg = 0;
1010 } else
1011 count = 0;
1012 if (!waitflg)
1013 break;
1014 current->timeout = jiffies + 10;
1015 schedule();
1016 }
1017 return count;
1018 }
1019
1020 static void icn_stopdriver(icn_dev * ldev)
1021 {
1022 unsigned long flags;
1023 isdn_ctrl cmd;
1024
1025 save_flags(flags);
1026 cli();
1027 del_timer(&dev->st_timer);
1028 del_timer(&ldev->rb_timer);
1029 cmd.command = ISDN_STAT_STOP;
1030 cmd.driver = ldev->myid;
1031 ldev->interface.statcallb(&cmd);
1032 restore_flags(flags);
1033 }
1034
1035 static int my_atoi(char *s)
1036 {
1037 int i, n;
1038
1039 n = 0;
1040 if (!s)
1041 return -1;
1042 for (i = 0; *s >= '0' && *s <= '9'; i++, s++)
1043 n = 10 * n + (*s - '0');
1044 return n;
1045 }
1046
1047 static int icn_command(isdn_ctrl * c, icn_dev * ldev)
1048 {
1049 ulong a;
1050 ulong flags;
1051 int i;
1052 char cbuf[60];
1053 isdn_ctrl cmd;
1054
1055 switch (c->command) {
1056 case ISDN_CMD_IOCTL:
1057 memcpy(&a, c->num, sizeof(ulong));
1058 switch (c->arg) {
1059 case ICN_IOCTL_SETMMIO:
1060 if ((unsigned long) dev->shmem != (a & 0x0ffc000)) {
1061 if (check_shmem((ulong) (a & 0x0ffc000), 0x4000)) {
1062 printk(KERN_WARNING "icn: memory at 0x%08lx in use.\n",
1063 (ulong) (a & 0x0ffc000));
1064 return -EINVAL;
1065 }
1066 icn_stopdriver(dev);
1067 if (dev->doubleS0)
1068 icn_stopdriver(dev2);
1069 save_flags(flags);
1070 cli();
1071 if (dev->mvalid)
1072 release_shmem((ulong) dev->shmem, 0x4000);
1073 dev->mvalid = 0;
1074 dev->shmem = (icn_shmem *) (a & 0x0ffc000);
1075 if (dev->doubleS0)
1076 dev2->shmem = (icn_shmem *) (a & 0x0ffc000);
1077 restore_flags(flags);
1078 printk(KERN_INFO "icn: mmio set to 0x%08lx\n",
1079 (unsigned long) dev->shmem);
1080 }
1081 break;
1082 case ICN_IOCTL_GETMMIO:
1083 return (int) dev->shmem;
1084 case ICN_IOCTL_SETPORT:
1085 if (a == 0x300 || a == 0x310 || a == 0x320 || a == 0x330
1086 || a == 0x340 || a == 0x350 || a == 0x360 ||
1087 a == 0x308 || a == 0x318 || a == 0x328 || a == 0x338
1088 || a == 0x348 || a == 0x358 || a == 0x368) {
1089 if (dev->port != (unsigned short) a) {
1090 if (check_region((unsigned short) a, ICN_PORTLEN)) {
1091 printk(KERN_WARNING "icn: ports 0x%03x-0x%03x in use.\n",
1092 (int) a, (int) a + ICN_PORTLEN);
1093 return -EINVAL;
1094 }
1095 icn_stopdriver(dev);
1096 if (dev->doubleS0)
1097 icn_stopdriver(dev2);
1098 save_flags(flags);
1099 cli();
1100 if (dev->rvalid)
1101 release_region(dev->port, ICN_PORTLEN);
1102 dev->port = (unsigned short) a;
1103 dev->rvalid = 0;
1104 if (dev->doubleS0) {
1105 dev2->port = (unsigned short) a;
1106 dev2->rvalid = 0;
1107 }
1108 restore_flags(flags);
1109 printk(KERN_INFO "icn: port set to 0x%03x\n", dev->port);
1110 }
1111 } else
1112 return -EINVAL;
1113 break;
1114 case ICN_IOCTL_GETPORT:
1115 return (int) dev->port;
1116 case ICN_IOCTL_GETDOUBLE:
1117 return (int) dev->doubleS0;
1118 case ICN_IOCTL_DEBUGVAR:
1119 return (ulong) ldev;
1120 #ifndef LOADEXTERN
1121 case ICN_IOCTL_LOADBOOT:
1122 icn_stopdriver(dev);
1123 if (dev->doubleS0)
1124 icn_stopdriver(dev2);
1125 return (icn_loadboot((u_char *) a, dev));
1126 case ICN_IOCTL_LOADPROTO:
1127 icn_stopdriver(dev);
1128 if (dev->doubleS0)
1129 icn_stopdriver(dev2);
1130 if ((i = (icn_loadproto((u_char *) a, dev))))
1131 return i;
1132 if (dev->doubleS0)
1133 i = icn_loadproto((u_char *) (a + ICN_CODE_STAGE2), dev2);
1134 return i;
1135 #endif
1136 case ICN_IOCTL_LEASEDCFG:
1137 if (a) {
1138 if (!ldev->leased) {
1139 ldev->leased = 1;
1140 while (ldev->ptype == ISDN_PTYPE_UNKNOWN) {
1141 current->timeout = jiffies + ICN_BOOT_TIMEOUT1;
1142 schedule();
1143 }
1144 current->timeout = jiffies + ICN_BOOT_TIMEOUT1;
1145 schedule();
1146 sprintf(cbuf, "00;FV2ON\n01;EAZ1\n");
1147 i = icn_writecmd(cbuf, strlen(cbuf), 0, ldev, 1);
1148 printk(KERN_INFO "icn: Leased-line mode enabled\n");
1149 cmd.command = ISDN_STAT_RUN;
1150 cmd.driver = ldev->myid;
1151 cmd.arg = 0;
1152 ldev->interface.statcallb(&cmd);
1153 }
1154 } else {
1155 if (ldev->leased) {
1156 ldev->leased = 0;
1157 sprintf(cbuf, "00;FV2OFF\n");
1158 i = icn_writecmd(cbuf, strlen(cbuf), 0, ldev, 1);
1159 printk(KERN_INFO "icn: Leased-line mode disabled\n");
1160 cmd.command = ISDN_STAT_RUN;
1161 cmd.driver = ldev->myid;
1162 cmd.arg = 0;
1163 ldev->interface.statcallb(&cmd);
1164 }
1165 }
1166 return 0;
1167 default:
1168 return -EINVAL;
1169 }
1170 break;
1171 case ISDN_CMD_DIAL:
1172 if (ldev->leased)
1173 break;
1174 if ((c->arg & 255) < ICN_BCH) {
1175 char *p;
1176 char *p2;
1177 char dial[50];
1178 char sis[50];
1179 char dcode[4];
1180 int si1, si2;
1181
1182 a = c->arg;
1183 strcpy(sis, c->num);
1184 p = strrchr(sis, ',');
1185 *p++ = '\0';
1186 si2 = my_atoi(p);
1187 p = strrchr(sis, ',') + 1;
1188 si1 = my_atoi(p);
1189 p = c->num;
1190 if (*p == 's' || *p == 'S') {
1191
1192 p++;
1193 strcpy(dcode, "SCA");
1194 } else
1195
1196 strcpy(dcode, "CAL");
1197 strcpy(dial, p);
1198 p = strchr(dial, ',');
1199 *p++ = '\0';
1200 p2 = strchr(p, ',');
1201 *p2 = '\0';
1202 sprintf(cbuf, "%02d;D%s_R%s,%02d,%02d,%s\n", (int) (a + 1), dcode, dial, si1,
1203 si2, p);
1204 i = icn_writecmd(cbuf, strlen(cbuf), 0, ldev, 1);
1205 }
1206 break;
1207 case ISDN_CMD_ACCEPTD:
1208 if (c->arg < ICN_BCH) {
1209 a = c->arg + 1;
1210 sprintf(cbuf, "%02d;DCON_R\n", (int) a);
1211 i = icn_writecmd(cbuf, strlen(cbuf), 0, ldev, 1);
1212 }
1213 break;
1214 case ISDN_CMD_ACCEPTB:
1215 if (c->arg < ICN_BCH) {
1216 a = c->arg + 1;
1217 sprintf(cbuf, "%02d;BCON_R\n", (int) a);
1218 i = icn_writecmd(cbuf, strlen(cbuf), 0, ldev, 1);
1219 }
1220 break;
1221 case ISDN_CMD_HANGUP:
1222 if (c->arg < ICN_BCH) {
1223 a = c->arg + 1;
1224 sprintf(cbuf, "%02d;BDIS_R\n%02d;DDIS_R\n", (int) a, (int) a);
1225 i = icn_writecmd(cbuf, strlen(cbuf), 0, ldev, 1);
1226 }
1227 break;
1228 case ISDN_CMD_SETEAZ:
1229 if (ldev->leased)
1230 break;
1231 if (c->arg < ICN_BCH) {
1232 a = c->arg + 1;
1233 if (ldev->ptype == ISDN_PTYPE_EURO) {
1234 sprintf(cbuf, "%02d;MS%s%s\n", (int) a, c->num[0] ? "N" : "ALL", c->num);
1235 } else
1236 sprintf(cbuf, "%02d;EAZ%s\n", (int) a, c->num[0] ? c->num : "0123456789");
1237 i = icn_writecmd(cbuf, strlen(cbuf), 0, ldev, 1);
1238 }
1239 break;
1240 case ISDN_CMD_CLREAZ:
1241 if (ldev->leased)
1242 break;
1243 if (c->arg < ICN_BCH) {
1244 a = c->arg + 1;
1245 if (ldev->ptype == ISDN_PTYPE_EURO)
1246 sprintf(cbuf, "%02d;MSNC\n", (int) a);
1247 else
1248 sprintf(cbuf, "%02d;EAZC\n", (int) a);
1249 i = icn_writecmd(cbuf, strlen(cbuf), 0, ldev, 1);
1250 }
1251 break;
1252 case ISDN_CMD_SETL2:
1253 if ((c->arg & 255) < ICN_BCH) {
1254 a = c->arg;
1255 switch (a >> 8) {
1256 case ISDN_PROTO_L2_X75I:
1257 sprintf(cbuf, "%02d;BX75\n", (int) (a & 255) + 1);
1258 break;
1259 case ISDN_PROTO_L2_HDLC:
1260 sprintf(cbuf, "%02d;BTRA\n", (int) (a & 255) + 1);
1261 break;
1262 default:
1263 return -EINVAL;
1264 }
1265 i = icn_writecmd(cbuf, strlen(cbuf), 0, ldev, 1);
1266 ldev->l2_proto[a & 255] = (a >> 8);
1267 }
1268 break;
1269 case ISDN_CMD_GETL2:
1270 if ((c->arg & 255) < ICN_BCH)
1271 return ldev->l2_proto[c->arg & 255];
1272 else
1273 return -ENODEV;
1274 case ISDN_CMD_SETL3:
1275 return 0;
1276 case ISDN_CMD_GETL3:
1277 if ((c->arg & 255) < ICN_BCH)
1278 return ISDN_PROTO_L3_TRANS;
1279 else
1280 return -ENODEV;
1281 case ISDN_CMD_GETEAZ:
1282 break;
1283 case ISDN_CMD_SETSIL:
1284 break;
1285 case ISDN_CMD_GETSIL:
1286 break;
1287 case ISDN_CMD_LOCK:
1288 MOD_INC_USE_COUNT;
1289 break;
1290 case ISDN_CMD_UNLOCK:
1291 MOD_DEC_USE_COUNT;
1292 break;
1293 default:
1294 return -EINVAL;
1295 }
1296 return 0;
1297 }
1298
1299
1300
1301
1302 static int if_command1(isdn_ctrl * c)
1303 {
1304 return (icn_command(c, dev));
1305 }
1306
1307 static int if_command2(isdn_ctrl * c)
1308 {
1309 return (icn_command(c, dev2));
1310 }
1311
1312 static int if_writecmd1(const u_char * buf, int len, int user)
1313 {
1314 return (icn_writecmd(buf, len, user, dev, 0));
1315 }
1316
1317 static int if_writecmd2(const u_char * buf, int len, int user)
1318 {
1319 return (icn_writecmd(buf, len, user, dev2, 0));
1320 }
1321
1322 static int if_readstatus1(u_char * buf, int len, int user)
1323 {
1324 return (icn_readstatus(buf, len, user, dev));
1325 }
1326
1327 static int if_readstatus2(u_char * buf, int len, int user)
1328 {
1329 return (icn_readstatus(buf, len, user, dev2));
1330 }
1331
1332 static int if_sendbuf1(int id, int channel, const u_char * buffer, int len,
1333 int user)
1334 {
1335 return (icn_sendbuf(channel, buffer, len, user, dev));
1336 }
1337
1338 static int if_sendbuf2(int id, int channel, const u_char * buffer, int len,
1339 int user)
1340 {
1341 return (icn_sendbuf(channel, buffer, len, user, dev2));
1342 }
1343
1344 #ifdef MODULE
1345 #define icn_init init_module
1346 #else
1347 void icn_setup(char *str, int *ints)
1348 {
1349 char *p;
1350 static char sid[20];
1351 static char sid2[20];
1352
1353 if (ints[0])
1354 portbase = ints[1];
1355 if (ints[0]>1)
1356 membase = ints[2];
1357 if (strlen(str)) {
1358 strcpy(sid,str);
1359 icn_id = sid;
1360 if ((p = strchr(sid,','))) {
1361 *p++ = 0;
1362 strcpy(sid2,p);
1363 icn_id2 = sid2;
1364 }
1365 }
1366 }
1367 #endif
1368
1369 int icn_init(void)
1370 {
1371 #ifdef LOADEXTERN
1372 unsigned long flags;
1373 #endif
1374 char *p;
1375 isdn_ctrl cmd;
1376 char rev[10];
1377
1378 if (!(dev = (icn_devptr) kmalloc(sizeof(icn_dev), GFP_KERNEL))) {
1379 printk(KERN_WARNING "icn: Could not allocate device-struct.\n");
1380 return -EIO;
1381 }
1382 memset((char *) dev, 0, sizeof(icn_dev));
1383 dev->port = portbase;
1384 dev->shmem = (icn_shmem *) (membase & 0x0ffc000);
1385 if (strlen(icn_id2))
1386 dev->doubleS0 = 1;
1387 dev->interface.channels = ICN_BCH;
1388 dev->interface.maxbufsize = 4000;
1389 dev->interface.command = if_command1;
1390 dev->interface.writebuf = if_sendbuf1;
1391 dev->interface.writecmd = if_writecmd1;
1392 dev->interface.readstat = if_readstatus1;
1393 dev->interface.features = ISDN_FEATURE_L2_X75I |
1394 ISDN_FEATURE_L2_HDLC |
1395 ISDN_FEATURE_L3_TRANS |
1396 ISDN_FEATURE_P_UNKNOWN;
1397 dev->ptype = ISDN_PTYPE_UNKNOWN;
1398 strncpy(dev->interface.id, icn_id, sizeof(dev->interface.id) - 1);
1399 dev->msg_buf_write = dev->msg_buf;
1400 dev->msg_buf_read = dev->msg_buf;
1401 dev->msg_buf_end = &dev->msg_buf[sizeof(dev->msg_buf) - 1];
1402 memset((char *) dev->l2_proto, ISDN_PROTO_L2_X75I, sizeof(dev->l2_proto));
1403 if (strlen(icn_id2)) {
1404 if (!(dev2 = (icn_devptr) kmalloc(sizeof(icn_dev), GFP_KERNEL))) {
1405 printk(KERN_WARNING "icn: Could not allocate device-struct.\n");
1406 kfree(dev);
1407 kfree(dev2);
1408 return -EIO;
1409 }
1410 memcpy((char *) dev2, (char *) dev, sizeof(icn_dev));
1411 dev2->interface.command = if_command2;
1412 dev2->interface.writebuf = if_sendbuf2;
1413 dev2->interface.writecmd = if_writecmd2;
1414 dev2->interface.readstat = if_readstatus2;
1415 strncpy(dev2->interface.id, icn_id2,
1416 sizeof(dev->interface.id) - 1);
1417 dev2->msg_buf_write = dev2->msg_buf;
1418 dev2->msg_buf_read = dev2->msg_buf;
1419 dev2->msg_buf_end = &dev2->msg_buf[sizeof(dev2->msg_buf) - 1];
1420 dev2->secondhalf = 1;
1421 }
1422 if (!register_isdn(&dev->interface)) {
1423 printk(KERN_WARNING "icn: Unable to register\n");
1424 kfree(dev);
1425 if (dev->doubleS0)
1426 kfree(dev2);
1427 return -EIO;
1428 }
1429 dev->myid = dev->interface.channels;
1430 sprintf(regname, "icn-isdn (%s)", dev->interface.id);
1431 if (dev->doubleS0) {
1432 if (!register_isdn(&dev2->interface)) {
1433 printk(KERN_WARNING "icn: Unable to register\n");
1434 kfree(dev2);
1435 if (dev->doubleS0) {
1436 icn_stopdriver(dev);
1437 cmd.command = ISDN_STAT_UNLOAD;
1438 cmd.driver = dev->myid;
1439 dev->interface.statcallb(&cmd);
1440 kfree(dev);
1441 }
1442 return -EIO;
1443 }
1444 dev2->myid = dev2->interface.channels;
1445 }
1446
1447
1448 register_symtab(NULL);
1449
1450 if ((p = strchr(revision, ':'))) {
1451 strcpy(rev, p + 1);
1452 p = strchr(rev, '$');
1453 *p = 0;
1454 } else
1455 strcpy(rev, " ??? ");
1456 printk(KERN_NOTICE "ICN-ISDN-driver Rev%sport=0x%03x mmio=0x%08x id='%s'\n",
1457 rev, dev->port, (uint) dev->shmem, dev->interface.id);
1458 #ifdef LOADEXTERN
1459 save_flags(flags);
1460 cli();
1461 init_timer(&dev->st_timer);
1462 dev->st_timer.expires = jiffies + ICN_TIMER_DCREAD;
1463 dev->st_timer.function = icn_pollcard;
1464 add_timer(&dev->st_timer);
1465 restore_flags(flags);
1466 #endif
1467 return 0;
1468 }
1469
1470 #ifdef MODULE
1471 void cleanup_module(void)
1472 {
1473 isdn_ctrl cmd;
1474 int i;
1475
1476 icn_stopdriver(dev);
1477 cmd.command = ISDN_STAT_UNLOAD;
1478 cmd.driver = dev->myid;
1479 dev->interface.statcallb(&cmd);
1480 if (dev->doubleS0) {
1481 icn_stopdriver(dev2);
1482 cmd.command = ISDN_STAT_UNLOAD;
1483 cmd.driver = dev2->myid;
1484 dev2->interface.statcallb(&cmd);
1485 }
1486 if (dev->rvalid) {
1487 OUTB_P(0, ICN_RUN);
1488 OUTB_P(0, ICN_MAPRAM);
1489 release_region(dev->port, ICN_PORTLEN);
1490 }
1491 if (dev->mvalid)
1492 release_shmem((ulong) dev->shmem, 0x4000);
1493 if (dev->doubleS0) {
1494 for (i = 0; i < ICN_BCH; i++)
1495 icn_free_queue(&dev2->spqueue[1]);
1496 kfree(dev2);
1497 }
1498 for (i = 0; i < ICN_BCH; i++)
1499 icn_free_queue(&dev->spqueue[1]);
1500 kfree(dev);
1501 printk(KERN_NOTICE "ICN-ISDN-driver unloaded\n");
1502 }
1503 #endif