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