1 /* $Id: icn.c,v 1.59 1999/08/28 22:10:55 keil Exp $
3 * ISDN low-level module for the ICN active ISDN-Card.
5 * Copyright 1994,95,96 by Fritz Elfert (fritz@wuemaus.franken.de)
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 * Revision 1.59 1999/08/28 22:10:55 keil
23 * __setup function should be static
25 * Revision 1.58 1999/08/25 16:44:17 keil
26 * Support for new __setup function
28 * Revision 1.57 1999/07/06 16:15:30 detabc
29 * remove unused messages
31 * Revision 1.56 1999/04/12 13:15:07 fritz
34 * Revision 1.55 1999/04/12 12:34:02 fritz
35 * Changes from 2.0 tree.
37 * Revision 1.54 1999/01/05 18:29:39 he
38 * merged remaining schedule_timeout() changes from 2.1.127
40 * Revision 1.53 1998/06/17 19:51:28 he
41 * merged with 2.1.10[34] (cosmetics and udelay() -> mdelay())
42 * brute force fix to avoid Ugh's in isdn_tty_write()
43 * cleaned up some dead code
45 * Revision 1.52 1998/05/20 19:29:58 tsbogend
46 * fixed bug introduced by changes for new BSENT callback
48 * Revision 1.51 1998/03/07 22:29:55 fritz
49 * Adapted Detlef's chenges for 2.1.
51 * Revision 1.49 1998/02/13 11:14:15 keil
52 * change for 2.1.86 (removing FREE_READ/FREE_WRITE from [dev]_kfree_skb()
54 * Revision 1.48 1997/10/10 15:56:14 fritz
55 * New HL<->LL interface:
56 * New BSENT callback with nr. of bytes included.
57 * Sending without ACK.
59 * Revision 1.47 1997/10/01 09:21:51 fritz
60 * Removed old compatibility stuff for 2.0.X kernels.
61 * From now on, this code is for 2.1.X ONLY!
62 * Old stuff is still in the separate branch.
64 * Revision 1.46 1997/08/21 22:38:33 fritz
67 * Revision 1.45 1997/06/21 10:42:06 fritz
68 * Added availability to select leased mode on only one channel.
70 * Revision 1.44 1997/03/30 16:51:26 calle
71 * changed calls to copy_from_user/copy_to_user and removed verify_area
74 * Revision 1.43 1997/03/21 18:27:04 fritz
75 * Corrected parsing of incoming setup.
77 * Revision 1.42 1997/03/05 21:13:18 fritz
78 * Bugfix: sndcount was not reset on hangup.
80 * Revision 1.41 1997/02/24 23:34:29 fritz
81 * Bugfix in Layer1 error-recovery.
83 * Revision 1.40 1997/02/23 23:34:45 fritz
84 * Minor bugfixes in debugging code.
86 * Revision 1.39 1997/02/23 16:21:56 fritz
87 * Bugfix: Check for NULL pointer in icn_parse_status().
89 * Revision 1.38 1997/02/11 18:29:31 fritz
90 * Bugfix in D64S initialization.
92 * Revision 1.37 1997/02/10 22:43:20 fritz
93 * Added plan and screen elements on ISDN_STAT_ICALL
95 * Revision 1.36 1997/02/10 21:31:20 fritz
96 * Changed setup-interface (incoming and outgoing).
98 * Revision 1.35 1997/02/10 10:10:28 fritz
99 * Changes for Kernel 2.1.X compatibility.
100 * Enhanced initialization, can recover from
101 * misconfiguration by other autoprobing drivers.
103 * Revision 1.34 1997/01/29 22:34:44 fritz
104 * Cleanup, Corrected D64S setup of 2nd channel.
106 * Revision 1.33 1996/12/05 20:31:48 tsbogend
107 * added handling of L2: DATA LINK LOST messages
109 * Revision 1.32 1996/11/14 23:49:18 fritz
110 * Bugfix: copy_to_user/copy_from_user mismatch in debugging-ioctl.
112 * Revision 1.31 1996/11/13 02:36:25 fritz
113 * Fixed a race condition in writecmd.
114 * Some optimizations and cleanup.
116 * Revision 1.30 1996/10/22 23:14:09 fritz
117 * Changes for compatibility to 2.0.X and 2.1.X kernels.
119 * Revision 1.29 1996/08/29 20:34:54 fritz
120 * Bugfix in send queue management:
121 * sndcount was not updated correctly.
124 * Revision 1.28 1996/06/28 17:02:53 fritz
125 * replaced memcpy_fromfs_toio.
127 * Revision 1.27 1996/06/25 18:38:59 fritz
128 * Fixed function name in error message.
130 * Revision 1.26 1996/06/24 17:20:35 fritz
131 * Bugfixes in pollbchan_send():
132 * - Using lock field of skbuff breaks networking.
133 * - Added channel locking
134 * - changed dequeuing scheme.
135 * Eliminated misc. compiler warnings.
137 * Revision 1.25 1996/06/11 22:53:35 tsbogend
138 * fixed problem with large array on stack
139 * made the driver working on Linux/alpha
141 * Revision 1.24 1996/06/06 13:58:33 fritz
142 * Changed code to be architecture independent
144 * Revision 1.23 1996/06/03 19:59:00 fritz
147 * Revision 1.22 1996/05/17 15:46:41 fritz
148 * Removed own queue management.
149 * Changed queue management to use sk_buffs.
151 * Revision 1.21 1996/05/02 04:01:20 fritz
153 * - icn_addcard() evaluated wrong driverId.
155 * Revision 1.20 1996/05/02 00:40:27 fritz
156 * Major rewrite to support more than one card
157 * with a single module.
158 * Support for new firmware.
160 * Revision 1.19 1996/04/21 17:43:32 fritz
161 * Changes for Support of new Firmware BRV3.02
163 * Revision 1.18 1996/04/20 16:50:26 fritz
164 * Fixed status-buffer overrun.
167 * Revision 1.17 1996/02/11 02:39:04 fritz
168 * Increased Buffer for status-messages.
169 * Removed conditionals for HDLC-firmware.
171 * Revision 1.16 1996/01/22 05:01:55 fritz
174 * Revision 1.15 1996/01/10 20:57:39 fritz
175 * Bugfix: Loading firmware twice caused the device stop working.
177 * Revision 1.14 1995/12/18 18:23:37 fritz
178 * Support for ICN-2B Cards.
179 * Change for supporting user-settable service-octet.
181 * Revision 1.13 1995/10/29 21:41:07 fritz
182 * Added support for DriverId's, added Jan's patches for Kernel versions.
184 * Revision 1.12 1995/04/29 13:07:35 fritz
185 * Added support for new Euro-ISDN-firmware
187 * Revision 1.11 1995/04/23 13:40:45 fritz
188 * Added support for SPV's.
189 * Changed Dial-Command to support MSN's on DSS1-Lines.
191 * Revision 1.10 1995/03/25 23:23:24 fritz
192 * Changed configurable Ports, to allow settings for DIP-Switch Cardversions.
194 * Revision 1.9 1995/03/25 23:17:30 fritz
195 * Fixed race-condition in pollbchan_send
197 * Revision 1.8 1995/03/15 12:49:44 fritz
198 * Added support for SPV's
199 * Split pollbchan_work for calling send-routine directly
201 * Revision 1.7 1995/02/20 03:48:03 fritz
202 * Added support of new request_region-function.
205 * Revision 1.6 1995/01/31 15:48:45 fritz
206 * Added Cause-Messages to be signaled to upper layers.
207 * Added Revision-Info on load.
209 * Revision 1.5 1995/01/29 23:34:59 fritz
210 * Added stopdriver() and appropriate calls.
211 * Changed printk-statements to support loglevels.
213 * Revision 1.4 1995/01/09 07:40:46 fritz
216 * Revision 1.3 1995/01/04 05:15:18 fritz
217 * Added undocumented "bootload-finished"-command in download-code
218 * to satisfy some brain-damaged icn card-versions.
220 * Revision 1.2 1995/01/02 02:14:45 fritz
223 * Revision 1.1 1994/12/14 17:56:06 fritz
231 * Verbose bootcode- and protocol-downloading.
236 * Verbose Shmem-Mapping.
241 *revision
= "$Revision: 1.59 $";
243 static int icn_addcard(int, char *, char *);
246 * Free send-queue completely.
248 * card = pointer to card struct
249 * channel = channel number
252 icn_free_queue(icn_card
* card
, int channel
)
254 struct sk_buff_head
*queue
= &card
->spqueue
[channel
];
258 while ((skb
= skb_dequeue(queue
)))
262 card
->xlen
[channel
] = 0;
263 card
->sndcount
[channel
] = 0;
264 if ((skb
= card
->xskb
[channel
])) {
265 card
->xskb
[channel
] = NULL
;
266 restore_flags(flags
);
269 restore_flags(flags
);
272 /* Put a value into a shift-register, highest bit first.
274 * port = port for output (bit 0 is significant)
275 * val = value to be output
276 * firstbit = Bit-Number of highest bit
277 * bitcount = Number of bits to output
280 icn_shiftout(unsigned short port
,
289 for (s
= firstbit
, c
= bitcount
; c
> 0; s
--, c
--)
290 OUTB_P((u_char
) ((val
>> s
) & 1) ? 0xff : 0, port
);
294 * disable a cards shared memory
297 icn_disable_ram(icn_card
* card
)
299 OUTB_P(0, ICN_MAPRAM
);
303 * enable a cards shared memory
306 icn_enable_ram(icn_card
* card
)
308 OUTB_P(0xff, ICN_MAPRAM
);
312 * Map a cards channel0 (Bank0/Bank8) or channel1 (Bank4/Bank12)
315 icn_map_channel(icn_card
* card
, int channel
)
318 printk(KERN_DEBUG
"icn_map_channel %d %d\n", dev
.channel
, channel
);
320 if ((channel
== dev
.channel
) && (card
== dev
.mcard
))
323 icn_disable_ram(dev
.mcard
);
324 icn_shiftout(ICN_BANK
, chan2bank
[channel
], 3, 4); /* Select Bank */
325 icn_enable_ram(card
);
327 dev
.channel
= channel
;
329 printk(KERN_DEBUG
"icn_map_channel done\n");
334 * Lock a cards channel.
335 * Return 0 if requested card/channel is unmapped (failure).
336 * Return 1 on success.
339 icn_lock_channel(icn_card
* card
, int channel
)
345 printk(KERN_DEBUG
"icn_lock_channel %d\n", channel
);
349 if ((dev
.channel
== channel
) && (card
== dev
.mcard
)) {
353 printk(KERN_DEBUG
"icn_lock_channel %d OK\n", channel
);
358 printk(KERN_DEBUG
"icn_lock_channel %d FAILED, dc=%d\n", channel
, dev
.channel
);
361 restore_flags(flags
);
366 * Release current card/channel lock
369 icn_release_channel(void)
374 printk(KERN_DEBUG
"icn_release_channel l=%d\n", dev
.chanlock
);
378 if (dev
.chanlock
> 0)
380 restore_flags(flags
);
384 * Try to map and lock a cards channel.
385 * Return 1 on success, 0 on failure.
388 icn_trymaplock_channel(icn_card
* card
, int channel
)
393 printk(KERN_DEBUG
"trymaplock c=%d dc=%d l=%d\n", channel
, dev
.channel
,
398 if ((!dev
.chanlock
) ||
399 ((dev
.channel
== channel
) && (dev
.mcard
== card
))) {
401 icn_map_channel(card
, channel
);
402 restore_flags(flags
);
404 printk(KERN_DEBUG
"trymaplock %d OK\n", channel
);
408 restore_flags(flags
);
410 printk(KERN_DEBUG
"trymaplock %d FAILED\n", channel
);
416 * Release current card/channel lock,
417 * then map same or other channel without locking.
420 icn_maprelease_channel(icn_card
* card
, int channel
)
425 printk(KERN_DEBUG
"map_release c=%d l=%d\n", channel
, dev
.chanlock
);
429 if (dev
.chanlock
> 0)
432 icn_map_channel(card
, channel
);
433 restore_flags(flags
);
436 /* Get Data from the B-Channel, assemble fragmented packets and put them
437 * into receive-queue. Wake up any B-Channel-reading processes.
438 * This routine is called via timer-callback from icn_pollbchan().
442 icn_pollbchan_receive(int channel
, icn_card
* card
)
444 int mch
= channel
+ ((card
->secondhalf
) ? 2 : 0);
449 if (icn_trymaplock_channel(card
, mch
)) {
451 cnt
= readb(&rbuf_l
);
452 if ((card
->rcvidx
[channel
] + cnt
) > 4000) {
454 "icn: (%s) bogus packet on ch%d, dropping.\n",
457 card
->rcvidx
[channel
] = 0;
460 memcpy_fromio(&card
->rcvbuf
[channel
][card
->rcvidx
[channel
]],
462 card
->rcvidx
[channel
] += cnt
;
463 eflag
= readb(&rbuf_f
);
466 icn_maprelease_channel(card
, mch
& 2);
468 if ((cnt
= card
->rcvidx
[channel
])) {
469 if (!(skb
= dev_alloc_skb(cnt
))) {
470 printk(KERN_WARNING
"ïcn: receive out of memory\n");
473 memcpy(skb_put(skb
, cnt
), card
->rcvbuf
[channel
], cnt
);
474 card
->rcvidx
[channel
] = 0;
475 card
->interface
.rcvcallb_skb(card
->myid
, channel
, skb
);
478 if (!icn_trymaplock_channel(card
, mch
))
481 icn_maprelease_channel(card
, mch
& 2);
485 /* Send data-packet to B-Channel, split it up into fragments of
486 * ICN_FRAGSIZE length. If last fragment is sent out, signal
487 * success to upper layers via statcallb with ISDN_STAT_BSENT argument.
488 * This routine is called via timer-callback from icn_pollbchan() or
489 * directly from icn_sendbuf().
493 icn_pollbchan_send(int channel
, icn_card
* card
)
495 int mch
= channel
+ ((card
->secondhalf
) ? 2 : 0);
501 if (!(card
->sndcount
[channel
] || card
->xskb
[channel
] ||
502 skb_queue_len(&card
->spqueue
[channel
])))
504 if (icn_trymaplock_channel(card
, mch
)) {
506 (card
->sndcount
[channel
] ||
507 skb_queue_len(&card
->spqueue
[channel
]) ||
508 card
->xskb
[channel
])) {
511 if (card
->xmit_lock
[channel
]) {
512 restore_flags(flags
);
515 card
->xmit_lock
[channel
]++;
516 restore_flags(flags
);
517 skb
= card
->xskb
[channel
];
519 skb
= skb_dequeue(&card
->spqueue
[channel
]);
521 /* Pop ACK-flag off skb.
522 * Store length to xlen.
524 if (*(skb_pull(skb
,1)))
525 card
->xlen
[channel
] = skb
->len
;
527 card
->xlen
[channel
] = 0;
532 if (skb
->len
> ICN_FRAGSIZE
) {
533 writeb(0xff, &sbuf_f
);
536 writeb(0x0, &sbuf_f
);
539 writeb(cnt
, &sbuf_l
);
540 memcpy_toio(&sbuf_d
, skb
->data
, cnt
);
542 card
->sndcount
[channel
] -= cnt
;
543 sbnext
; /* switch to next buffer */
544 icn_maprelease_channel(card
, mch
& 2);
548 if (card
->xskb
[channel
]) {
549 card
->xskb
[channel
] = NULL
;
550 restore_flags(flags
);
553 restore_flags(flags
);
554 if (card
->xlen
[channel
]) {
555 cmd
.command
= ISDN_STAT_BSENT
;
556 cmd
.driver
= card
->myid
;
558 cmd
.parm
.length
= card
->xlen
[channel
];
559 card
->interface
.statcallb(&cmd
);
564 card
->xskb
[channel
] = skb
;
565 restore_flags(flags
);
567 card
->xmit_lock
[channel
] = 0;
568 if (!icn_trymaplock_channel(card
, mch
))
571 icn_maprelease_channel(card
, mch
& 2);
575 /* Send/Receive Data to/from the B-Channel.
576 * This routine is called via timer-callback.
577 * It schedules itself while any B-Channel is open.
581 icn_pollbchan(unsigned long data
)
583 icn_card
*card
= (icn_card
*) data
;
586 if (card
->flags
& ICN_FLAGS_B1ACTIVE
) {
587 icn_pollbchan_receive(0, card
);
588 icn_pollbchan_send(0, card
);
590 if (card
->flags
& ICN_FLAGS_B2ACTIVE
) {
591 icn_pollbchan_receive(1, card
);
592 icn_pollbchan_send(1, card
);
594 if (card
->flags
& (ICN_FLAGS_B1ACTIVE
| ICN_FLAGS_B2ACTIVE
)) {
595 /* schedule b-channel polling again */
598 del_timer(&card
->rb_timer
);
599 card
->rb_timer
.expires
= jiffies
+ ICN_TIMER_BCREAD
;
600 add_timer(&card
->rb_timer
);
601 card
->flags
|= ICN_FLAGS_RBTIMER
;
602 restore_flags(flags
);
604 card
->flags
&= ~ICN_FLAGS_RBTIMER
;
607 typedef struct icn_stat
{
613 static icn_stat icn_stat_table
[] =
615 {"BCON_", ISDN_STAT_BCONN
, 1}, /* B-Channel connected */
616 {"BDIS_", ISDN_STAT_BHUP
, 2}, /* B-Channel disconnected */
618 ** add d-channel connect and disconnect support to link-level
620 {"DCON_", ISDN_STAT_DCONN
, 10}, /* D-Channel connected */
621 {"DDIS_", ISDN_STAT_DHUP
, 11}, /* D-Channel disconnected */
622 {"DCAL_I", ISDN_STAT_ICALL
, 3}, /* Incoming call dialup-line */
623 {"DSCA_I", ISDN_STAT_ICALL
, 3}, /* Incoming call 1TR6-SPV */
624 {"FCALL", ISDN_STAT_ICALL
, 4}, /* Leased line connection up */
625 {"CIF", ISDN_STAT_CINF
, 5}, /* Charge-info, 1TR6-type */
626 {"AOC", ISDN_STAT_CINF
, 6}, /* Charge-info, DSS1-type */
627 {"CAU", ISDN_STAT_CAUSE
, 7}, /* Cause code */
628 {"TEI OK", ISDN_STAT_RUN
, 0}, /* Card connected to wallplug */
629 {"NO D-CHAN", ISDN_STAT_NODCH
, 0}, /* No D-channel available */
630 {"E_L1: ACT FAIL", ISDN_STAT_BHUP
, 8}, /* Layer-1 activation failed */
631 {"E_L2: DATA LIN", ISDN_STAT_BHUP
, 8}, /* Layer-2 data link lost */
632 {"E_L1: ACTIVATION FAILED",
633 ISDN_STAT_BHUP
, 8}, /* Layer-1 activation failed */
640 * Check Statusqueue-Pointer from isdn-cards.
641 * If there are new status-replies from the interface, check
642 * them against B-Channel-connects/disconnects and set flags accordingly.
643 * Wake-Up any processes, who are reading the status-device.
644 * If there are B-Channels open, initiate a timer-callback to
646 * This routine is called periodically via timer.
650 icn_parse_status(u_char
* status
, int channel
, icn_card
* card
)
652 icn_stat
*s
= icn_stat_table
;
658 if (!strncmp(status
, s
->statstr
, strlen(s
->statstr
))) {
659 cmd
.command
= s
->command
;
667 cmd
.driver
= card
->myid
;
673 icn_free_queue(card
,channel
);
674 card
->rcvidx
[channel
] = 0;
677 ((channel
)?ICN_FLAGS_B2ACTIVE
:ICN_FLAGS_B1ACTIVE
)) {
681 card
->flags
&= ~((channel
)?
682 ICN_FLAGS_B2ACTIVE
:ICN_FLAGS_B1ACTIVE
);
684 memset(&ncmd
, 0, sizeof(ncmd
));
686 ncmd
.driver
= card
->myid
;
688 ncmd
.command
= ISDN_STAT_BHUP
;
689 restore_flags(flags
);
690 card
->interface
.statcallb(&cmd
);
692 restore_flags(flags
);
696 icn_free_queue(card
,channel
);
697 card
->flags
|= (channel
) ?
698 ICN_FLAGS_B2ACTIVE
: ICN_FLAGS_B1ACTIVE
;
701 card
->flags
&= ~((channel
) ?
702 ICN_FLAGS_B2ACTIVE
: ICN_FLAGS_B1ACTIVE
);
703 icn_free_queue(card
, channel
);
706 card
->rcvidx
[channel
] = 0;
707 restore_flags(flags
);
711 char *t
= status
+ 6;
712 char *s
= strpbrk(t
, ",");
715 strncpy(cmd
.parm
.setup
.phone
, t
,
716 sizeof(cmd
.parm
.setup
.phone
));
717 s
= strpbrk(t
= s
, ",");
720 cmd
.parm
.setup
.si1
= 0;
723 simple_strtoul(t
, NULL
, 10);
724 s
= strpbrk(t
= s
, ",");
727 cmd
.parm
.setup
.si2
= 0;
730 simple_strtoul(t
, NULL
, 10);
731 strncpy(cmd
.parm
.setup
.eazmsn
, s
,
732 sizeof(cmd
.parm
.setup
.eazmsn
));
734 cmd
.parm
.setup
.plan
= 0;
735 cmd
.parm
.setup
.screen
= 0;
738 sprintf(cmd
.parm
.setup
.phone
, "LEASED%d", card
->myid
);
739 sprintf(cmd
.parm
.setup
.eazmsn
, "%d", channel
+ 1);
740 cmd
.parm
.setup
.si1
= 7;
741 cmd
.parm
.setup
.si2
= 0;
742 cmd
.parm
.setup
.plan
= 0;
743 cmd
.parm
.setup
.screen
= 0;
746 strncpy(cmd
.parm
.num
, status
+ 3, sizeof(cmd
.parm
.num
) - 1);
749 sprintf(cmd
.parm
.num
, "%d",
750 (int) simple_strtoul(status
+ 7, NULL
, 16));
754 if (strlen(status
) == 4)
755 sprintf(cmd
.parm
.num
, "%s%c%c",
756 status
+ 2, *status
, *(status
+ 1));
758 strncpy(cmd
.parm
.num
, status
+ 1, sizeof(cmd
.parm
.num
) - 1);
761 card
->flags
&= ~ICN_FLAGS_B1ACTIVE
;
762 icn_free_queue(card
, 0);
766 restore_flags(flags
);
768 cmd
.driver
= card
->myid
;
769 card
->interface
.statcallb(&cmd
);
770 cmd
.command
= ISDN_STAT_DHUP
;
772 cmd
.driver
= card
->myid
;
773 card
->interface
.statcallb(&cmd
);
774 cmd
.command
= ISDN_STAT_BHUP
;
775 card
->flags
&= ~ICN_FLAGS_B2ACTIVE
;
776 icn_free_queue(card
, 1);
780 restore_flags(flags
);
782 cmd
.driver
= card
->myid
;
783 card
->interface
.statcallb(&cmd
);
784 cmd
.command
= ISDN_STAT_DHUP
;
786 cmd
.driver
= card
->myid
;
789 card
->interface
.statcallb(&cmd
);
794 icn_putmsg(icn_card
* card
, unsigned char c
)
800 *card
->msg_buf_write
++ = (c
== 0xff) ? '\n' : c
;
801 if (card
->msg_buf_write
== card
->msg_buf_read
) {
802 if (++card
->msg_buf_read
> card
->msg_buf_end
)
803 card
->msg_buf_read
= card
->msg_buf
;
805 if (card
->msg_buf_write
> card
->msg_buf_end
)
806 card
->msg_buf_write
= card
->msg_buf
;
807 restore_flags(flags
);
811 icn_polldchan(unsigned long data
)
813 icn_card
*card
= (icn_card
*) data
;
814 int mch
= card
->secondhalf
? 2 : 0;
824 if (icn_trymaplock_channel(card
, mch
)) {
826 for (left
= avail
, i
= readb(&msg_o
); left
> 0; i
++, left
--) {
827 c
= readb(&dev
.shmem
->comm_buffers
.iopc_buf
[i
& 0xff]);
830 card
->imsg
[card
->iptr
] = 0;
832 if (card
->imsg
[0] == '0' && card
->imsg
[1] >= '0' &&
833 card
->imsg
[1] <= '2' && card
->imsg
[2] == ';') {
834 ch
= (card
->imsg
[1] - '0') - 1;
836 icn_parse_status(p
, ch
, card
);
839 if (!strncmp(p
, "DRV1.", 5)) {
843 printk(KERN_INFO
"icn: (%s) %s\n", CID
, p
);
844 if (!strncmp(p
+ 7, "TC", 2)) {
845 card
->ptype
= ISDN_PTYPE_1TR6
;
846 card
->interface
.features
|= ISDN_FEATURE_P_1TR6
;
848 "icn: (%s) 1TR6-Protocol loaded and running\n", CID
);
850 if (!strncmp(p
+ 7, "EC", 2)) {
851 card
->ptype
= ISDN_PTYPE_EURO
;
852 card
->interface
.features
|= ISDN_FEATURE_P_EURO
;
854 "icn: (%s) Euro-Protocol loaded and running\n", CID
);
856 p
= strstr(card
->imsg
, "BRV") + 3;
858 if (*p
>= '0' && *p
<= '9')
865 card
->fw_rev
= (int) simple_strtoul(vstr
, NULL
, 10);
871 card
->imsg
[card
->iptr
] = c
;
876 writeb((readb(&msg_o
) + avail
) & 0xff, &msg_o
);
877 icn_release_channel();
880 cmd
.command
= ISDN_STAT_STAVAIL
;
881 cmd
.driver
= card
->myid
;
883 card
->interface
.statcallb(&cmd
);
885 if (card
->flags
& (ICN_FLAGS_B1ACTIVE
| ICN_FLAGS_B2ACTIVE
))
886 if (!(card
->flags
& ICN_FLAGS_RBTIMER
)) {
887 /* schedule b-channel polling */
888 card
->flags
|= ICN_FLAGS_RBTIMER
;
891 del_timer(&card
->rb_timer
);
892 card
->rb_timer
.function
= icn_pollbchan
;
893 card
->rb_timer
.data
= (unsigned long) card
;
894 card
->rb_timer
.expires
= jiffies
+ ICN_TIMER_BCREAD
;
895 add_timer(&card
->rb_timer
);
896 restore_flags(flags
);
901 del_timer(&card
->st_timer
);
902 card
->st_timer
.expires
= jiffies
+ ICN_TIMER_DCREAD
;
903 add_timer(&card
->st_timer
);
904 restore_flags(flags
);
907 /* Append a packet to the transmit buffer-queue.
909 * channel = Number of B-channel
910 * skb = pointer to sk_buff
911 * card = pointer to card-struct
913 * Number of bytes transferred, -E??? on error
917 icn_sendbuf(int channel
, int ack
, struct sk_buff
*skb
, icn_card
* card
)
921 struct sk_buff
*nskb
;
925 "icn: Send packet too large\n");
929 if (!(card
->flags
& (channel
) ? ICN_FLAGS_B2ACTIVE
: ICN_FLAGS_B1ACTIVE
))
931 if (card
->sndcount
[channel
] > ICN_MAX_SQUEUE
)
935 nskb
= skb_clone(skb
, GFP_ATOMIC
);
937 /* Push ACK flag as one
938 * byte in front of data.
940 *(skb_push(nskb
, 1)) = ack
?1:0;
941 skb_queue_tail(&card
->spqueue
[channel
], nskb
);
945 card
->sndcount
[channel
] += len
;
946 restore_flags(flags
);
952 * Check card's status after starting the bootstrap loader.
953 * On entry, the card's shared memory has already to be mapped.
955 * 0 on success (Boot loader ready)
956 * -EIO on failure (timeout)
959 icn_check_loader(int cardnumber
)
965 printk(KERN_DEBUG
"Loader %d ?\n", cardnumber
);
967 if (readb(&dev
.shmem
->data_control
.scns
) ||
968 readb(&dev
.shmem
->data_control
.scnr
)) {
971 "icn: Boot-Loader %d timed out.\n",
973 icn_release_channel();
977 printk(KERN_DEBUG
"Loader %d TO?\n", cardnumber
);
979 current
->state
= TASK_INTERRUPTIBLE
;
980 schedule_timeout(ICN_BOOT_TIMEOUT1
);
983 printk(KERN_DEBUG
"Loader %d OK\n", cardnumber
);
985 icn_release_channel();
991 /* Load the boot-code into the interface-card's memory and start it.
992 * Always called from user-process.
995 * buffer = pointer to packet
997 * 0 if successfully loaded
1001 #define SLEEP(sec) { \
1003 printk(KERN_DEBUG "SLEEP(%d)\n",slsec); \
1005 current->state = TASK_INTERRUPTIBLE; \
1006 schedule_timeout(HZ); \
1015 icn_loadboot(u_char
* buffer
, icn_card
* card
)
1022 printk(KERN_DEBUG
"icn_loadboot called, buffaddr=%08lx\n", (ulong
) buffer
);
1024 if (!(codebuf
= kmalloc(ICN_CODE_STAGE1
, GFP_KERNEL
))) {
1025 printk(KERN_WARNING
"icn: Could not allocate code buffer\n");
1028 if ((ret
= copy_from_user(codebuf
, buffer
, ICN_CODE_STAGE1
))) {
1034 if (!card
->rvalid
) {
1035 if (check_region(card
->port
, ICN_PORTLEN
)) {
1037 "icn: (%s) ports 0x%03x-0x%03x in use.\n",
1040 card
->port
+ ICN_PORTLEN
);
1041 restore_flags(flags
);
1045 request_region(card
->port
, ICN_PORTLEN
, card
->regname
);
1048 card
->other
->rvalid
= 1;
1051 if (check_shmem((ulong
) dev
.shmem
, 0x4000)) {
1053 "icn: memory at 0x%08lx in use.\n",
1055 restore_flags(flags
);
1058 request_shmem((ulong
) dev
.shmem
, 0x4000, "icn");
1061 restore_flags(flags
);
1062 OUTB_P(0, ICN_RUN
); /* Reset Controller */
1063 OUTB_P(0, ICN_MAPRAM
); /* Disable RAM */
1064 icn_shiftout(ICN_CFG
, 0x0f, 3, 4); /* Windowsize= 16k */
1065 icn_shiftout(ICN_CFG
, (unsigned long) dev
.shmem
, 23, 10); /* Set RAM-Addr. */
1067 printk(KERN_DEBUG
"shmem=%08lx\n", (ulong
) dev
.shmem
);
1071 printk(KERN_DEBUG
"Map Bank 0\n");
1075 icn_map_channel(card
, 0); /* Select Bank 0 */
1076 icn_lock_channel(card
, 0); /* Lock Bank 0 */
1077 restore_flags(flags
);
1079 memcpy_toio(dev
.shmem
, codebuf
, ICN_CODE_STAGE1
); /* Copy code */
1081 printk(KERN_DEBUG
"Bootloader transfered\n");
1083 if (card
->doubleS0
) {
1086 printk(KERN_DEBUG
"Map Bank 8\n");
1090 icn_release_channel();
1091 icn_map_channel(card
, 2); /* Select Bank 8 */
1092 icn_lock_channel(card
, 2); /* Lock Bank 8 */
1093 restore_flags(flags
);
1095 memcpy_toio(dev
.shmem
, codebuf
, ICN_CODE_STAGE1
); /* Copy code */
1097 printk(KERN_DEBUG
"Bootloader transfered\n");
1102 OUTB_P(0xff, ICN_RUN
); /* Start Boot-Code */
1103 if ((ret
= icn_check_loader(card
->doubleS0
? 2 : 1)))
1105 if (!card
->doubleS0
)
1107 /* reached only, if we have a Double-S0-Card */
1109 printk(KERN_DEBUG
"Map Bank 0\n");
1113 icn_map_channel(card
, 0); /* Select Bank 0 */
1114 icn_lock_channel(card
, 0); /* Lock Bank 0 */
1115 restore_flags(flags
);
1117 return (icn_check_loader(1));
1121 icn_loadproto(u_char
* buffer
, icn_card
* card
)
1123 register u_char
*p
= buffer
;
1124 u_char codebuf
[256];
1125 uint left
= ICN_CODE_STAGE2
;
1129 unsigned long flags
;
1132 printk(KERN_DEBUG
"icn_loadproto called\n");
1134 if ((ret
= verify_area(VERIFY_READ
, (void *) buffer
, ICN_CODE_STAGE2
)))
1139 if (card
->secondhalf
) {
1140 icn_map_channel(card
, 2);
1141 icn_lock_channel(card
, 2);
1143 icn_map_channel(card
, 0);
1144 icn_lock_channel(card
, 0);
1146 restore_flags(flags
);
1148 if (sbfree
) { /* If there is a free buffer... */
1149 cnt
= MIN(256, left
);
1150 if (copy_from_user(codebuf
, p
, cnt
)) {
1151 icn_maprelease_channel(card
, 0);
1154 memcpy_toio(&sbuf_l
, codebuf
, cnt
); /* copy data */
1155 sbnext
; /* switch to next buffer */
1161 printk(KERN_DEBUG
"boot 2 !sbfree\n");
1164 icn_maprelease_channel(card
, 0);
1167 current
->state
= TASK_INTERRUPTIBLE
;
1168 schedule_timeout(10);
1171 writeb(0x20, &sbuf_n
);
1174 if (readb(&cmd_o
) || readb(&cmd_i
)) {
1176 printk(KERN_DEBUG
"Proto?\n");
1180 "icn: (%s) Protocol timed out.\n",
1183 printk(KERN_DEBUG
"Proto TO!\n");
1185 icn_maprelease_channel(card
, 0);
1189 printk(KERN_DEBUG
"Proto TO?\n");
1191 current
->state
= TASK_INTERRUPTIBLE
;
1192 schedule_timeout(ICN_BOOT_TIMEOUT1
);
1194 if ((card
->secondhalf
) || (!card
->doubleS0
)) {
1196 printk(KERN_DEBUG
"Proto loaded, install poll-timer %d\n",
1201 init_timer(&card
->st_timer
);
1202 card
->st_timer
.expires
= jiffies
+ ICN_TIMER_DCREAD
;
1203 card
->st_timer
.function
= icn_polldchan
;
1204 card
->st_timer
.data
= (unsigned long) card
;
1205 add_timer(&card
->st_timer
);
1206 card
->flags
|= ICN_FLAGS_RUNNING
;
1207 if (card
->doubleS0
) {
1208 init_timer(&card
->other
->st_timer
);
1209 card
->other
->st_timer
.expires
= jiffies
+ ICN_TIMER_DCREAD
;
1210 card
->other
->st_timer
.function
= icn_polldchan
;
1211 card
->other
->st_timer
.data
= (unsigned long) card
->other
;
1212 add_timer(&card
->other
->st_timer
);
1213 card
->other
->flags
|= ICN_FLAGS_RUNNING
;
1215 restore_flags(flags
);
1217 icn_maprelease_channel(card
, 0);
1223 /* Read the Status-replies from the Interface */
1225 icn_readstatus(u_char
* buf
, int len
, int user
, icn_card
* card
)
1230 for (p
= buf
, count
= 0; count
< len
; p
++, count
++) {
1231 if (card
->msg_buf_read
== card
->msg_buf_write
)
1234 put_user(*card
->msg_buf_read
++, p
);
1236 *p
= *card
->msg_buf_read
++;
1237 if (card
->msg_buf_read
> card
->msg_buf_end
)
1238 card
->msg_buf_read
= card
->msg_buf
;
1243 /* Put command-strings into the command-queue of the Interface */
1245 icn_writecmd(const u_char
* buf
, int len
, int user
, icn_card
* card
)
1247 int mch
= card
->secondhalf
? 2 : 0;
1255 unsigned long flags
;
1256 int lastmap_channel
;
1257 struct icn_card
*lastmap_card
;
1267 lastmap_card
= dev
.mcard
;
1268 lastmap_channel
= dev
.channel
;
1269 icn_map_channel(card
, mch
);
1272 count
= MIN(avail
, len
);
1274 copy_from_user(msg
, buf
, count
);
1276 memcpy(msg
, buf
, count
);
1277 icn_putmsg(card
, '>');
1278 for (p
= msg
, pp
= readb(&cmd_i
), i
= count
; i
> 0; i
--, p
++, pp
1280 writeb((*p
== '\n') ? 0xff : *p
,
1281 &dev
.shmem
->comm_buffers
.pcio_buf
[pp
& 0xff]);
1284 icn_putmsg(card
, *p
);
1285 if ((*p
== '\n') && (i
> 1)) {
1286 icn_putmsg(card
, '>');
1291 writeb((readb(&cmd_i
) + count
) & 0xff, &cmd_i
);
1293 icn_map_channel(lastmap_card
, lastmap_channel
);
1294 restore_flags(flags
);
1303 printk(KERN_WARNING
"icn: writemsg incomplete!\n");
1304 cmd
.command
= ISDN_STAT_STAVAIL
;
1305 cmd
.driver
= card
->myid
;
1307 card
->interface
.statcallb(&cmd
);
1312 * Delete card's pending timers, send STOP to linklevel
1315 icn_stopcard(icn_card
* card
)
1317 unsigned long flags
;
1322 if (card
->flags
& ICN_FLAGS_RUNNING
) {
1323 card
->flags
&= ~ICN_FLAGS_RUNNING
;
1324 del_timer(&card
->st_timer
);
1325 del_timer(&card
->rb_timer
);
1326 cmd
.command
= ISDN_STAT_STOP
;
1327 cmd
.driver
= card
->myid
;
1328 card
->interface
.statcallb(&cmd
);
1330 icn_stopcard(card
->other
);
1332 restore_flags(flags
);
1336 icn_stopallcards(void)
1338 icn_card
*p
= cards
;
1347 * Unmap all cards, because some of them may be mapped accidetly during
1348 * autoprobing of some network drivers (SMC-driver?)
1351 icn_disable_cards(void)
1353 icn_card
*card
= cards
;
1354 unsigned long flags
;
1359 if (check_region(card
->port
, ICN_PORTLEN
)) {
1361 "icn: (%s) ports 0x%03x-0x%03x in use.\n",
1364 card
->port
+ ICN_PORTLEN
);
1367 OUTB_P(0, ICN_RUN
); /* Reset Controller */
1368 OUTB_P(0, ICN_MAPRAM
); /* Disable RAM */
1372 restore_flags(flags
);
1376 icn_command(isdn_ctrl
* c
, icn_card
* card
)
1385 switch (c
->command
) {
1386 case ISDN_CMD_IOCTL
:
1387 memcpy(&a
, c
->parm
.num
, sizeof(ulong
));
1389 case ICN_IOCTL_SETMMIO
:
1390 if ((unsigned long) dev
.shmem
!= (a
& 0x0ffc000)) {
1391 if (check_shmem((ulong
) (a
& 0x0ffc000), 0x4000)) {
1393 "icn: memory at 0x%08lx in use.\n",
1394 (ulong
) (a
& 0x0ffc000));
1401 release_shmem((ulong
) dev
.shmem
, 0x4000);
1403 dev
.shmem
= (icn_shmem
*) (a
& 0x0ffc000);
1404 restore_flags(flags
);
1406 "icn: (%s) mmio set to 0x%08lx\n",
1408 (unsigned long) dev
.shmem
);
1411 case ICN_IOCTL_GETMMIO
:
1412 return (long) dev
.shmem
;
1413 case ICN_IOCTL_SETPORT
:
1414 if (a
== 0x300 || a
== 0x310 || a
== 0x320 || a
== 0x330
1415 || a
== 0x340 || a
== 0x350 || a
== 0x360 ||
1416 a
== 0x308 || a
== 0x318 || a
== 0x328 || a
== 0x338
1417 || a
== 0x348 || a
== 0x358 || a
== 0x368) {
1418 if (card
->port
!= (unsigned short) a
) {
1419 if (check_region((unsigned short) a
, ICN_PORTLEN
)) {
1421 "icn: (%s) ports 0x%03x-0x%03x in use.\n",
1422 CID
, (int) a
, (int) a
+ ICN_PORTLEN
);
1429 release_region(card
->port
, ICN_PORTLEN
);
1430 card
->port
= (unsigned short) a
;
1432 if (card
->doubleS0
) {
1433 card
->other
->port
= (unsigned short) a
;
1434 card
->other
->rvalid
= 0;
1436 restore_flags(flags
);
1438 "icn: (%s) port set to 0x%03x\n",
1444 case ICN_IOCTL_GETPORT
:
1445 return (int) card
->port
;
1446 case ICN_IOCTL_GETDOUBLE
:
1447 return (int) card
->doubleS0
;
1448 case ICN_IOCTL_DEBUGVAR
:
1449 if ((i
= copy_to_user((char *) a
,
1450 (char *) &card
, sizeof(ulong
))))
1454 ulong l
= (ulong
) & dev
;
1455 if ((i
= copy_to_user((char *) a
,
1456 (char *) &l
, sizeof(ulong
))))
1460 case ICN_IOCTL_LOADBOOT
:
1461 if (dev
.firstload
) {
1462 icn_disable_cards();
1466 return (icn_loadboot((u_char
*) a
, card
));
1467 case ICN_IOCTL_LOADPROTO
:
1469 if ((i
= (icn_loadproto((u_char
*) a
, card
))))
1472 i
= icn_loadproto((u_char
*) (a
+ ICN_CODE_STAGE2
), card
->other
);
1475 case ICN_IOCTL_ADDCARD
:
1478 if ((i
= copy_from_user((char *) &cdef
, (char *) a
, sizeof(cdef
))))
1480 return (icn_addcard(cdef
.port
, cdef
.id1
, cdef
.id2
));
1482 case ICN_IOCTL_LEASEDCFG
:
1484 if (!card
->leased
) {
1486 while (card
->ptype
== ISDN_PTYPE_UNKNOWN
) {
1487 schedule_timeout(ICN_BOOT_TIMEOUT1
);
1489 schedule_timeout(ICN_BOOT_TIMEOUT1
);
1490 sprintf(cbuf
, "00;FV2ON\n01;EAZ%c\n02;EAZ%c\n",
1491 (a
& 1)?'1':'C', (a
& 2)?'2':'C');
1492 i
= icn_writecmd(cbuf
, strlen(cbuf
), 0, card
);
1494 "icn: (%s) Leased-line mode enabled\n",
1496 cmd
.command
= ISDN_STAT_RUN
;
1497 cmd
.driver
= card
->myid
;
1499 card
->interface
.statcallb(&cmd
);
1504 sprintf(cbuf
, "00;FV2OFF\n");
1505 i
= icn_writecmd(cbuf
, strlen(cbuf
), 0, card
);
1507 "icn: (%s) Leased-line mode disabled\n",
1509 cmd
.command
= ISDN_STAT_RUN
;
1510 cmd
.driver
= card
->myid
;
1512 card
->interface
.statcallb(&cmd
);
1521 if (!card
->flags
& ICN_FLAGS_RUNNING
)
1525 if ((c
->arg
& 255) < ICN_BCH
) {
1531 p
= c
->parm
.setup
.phone
;
1532 if (*p
== 's' || *p
== 'S') {
1535 strcpy(dcode
, "SCA");
1538 strcpy(dcode
, "CAL");
1540 sprintf(cbuf
, "%02d;D%s_R%s,%02d,%02d,%s\n", (int) (a
+ 1),
1541 dcode
, dial
, c
->parm
.setup
.si1
,
1542 c
->parm
.setup
.si2
, c
->parm
.setup
.eazmsn
);
1543 i
= icn_writecmd(cbuf
, strlen(cbuf
), 0, card
);
1546 case ISDN_CMD_ACCEPTD
:
1547 if (!card
->flags
& ICN_FLAGS_RUNNING
)
1549 if (c
->arg
< ICN_BCH
) {
1551 if (card
->fw_rev
>= 300) {
1552 switch (card
->l2_proto
[a
- 1]) {
1553 case ISDN_PROTO_L2_X75I
:
1554 sprintf(cbuf
, "%02d;BX75\n", (int) a
);
1556 case ISDN_PROTO_L2_HDLC
:
1557 sprintf(cbuf
, "%02d;BTRA\n", (int) a
);
1560 i
= icn_writecmd(cbuf
, strlen(cbuf
), 0, card
);
1562 sprintf(cbuf
, "%02d;DCON_R\n", (int) a
);
1563 i
= icn_writecmd(cbuf
, strlen(cbuf
), 0, card
);
1566 case ISDN_CMD_ACCEPTB
:
1567 if (!card
->flags
& ICN_FLAGS_RUNNING
)
1569 if (c
->arg
< ICN_BCH
) {
1571 if (card
->fw_rev
>= 300)
1572 switch (card
->l2_proto
[a
- 1]) {
1573 case ISDN_PROTO_L2_X75I
:
1574 sprintf(cbuf
, "%02d;BCON_R,BX75\n", (int) a
);
1576 case ISDN_PROTO_L2_HDLC
:
1577 sprintf(cbuf
, "%02d;BCON_R,BTRA\n", (int) a
);
1580 sprintf(cbuf
, "%02d;BCON_R\n", (int) a
);
1581 i
= icn_writecmd(cbuf
, strlen(cbuf
), 0, card
);
1584 case ISDN_CMD_HANGUP
:
1585 if (!card
->flags
& ICN_FLAGS_RUNNING
)
1587 if (c
->arg
< ICN_BCH
) {
1589 sprintf(cbuf
, "%02d;BDIS_R\n%02d;DDIS_R\n", (int) a
, (int) a
);
1590 i
= icn_writecmd(cbuf
, strlen(cbuf
), 0, card
);
1593 case ISDN_CMD_SETEAZ
:
1594 if (!card
->flags
& ICN_FLAGS_RUNNING
)
1598 if (c
->arg
< ICN_BCH
) {
1600 if (card
->ptype
== ISDN_PTYPE_EURO
) {
1601 sprintf(cbuf
, "%02d;MS%s%s\n", (int) a
,
1602 c
->parm
.num
[0] ? "N" : "ALL", c
->parm
.num
);
1604 sprintf(cbuf
, "%02d;EAZ%s\n", (int) a
,
1605 c
->parm
.num
[0] ? (char *)(c
->parm
.num
) : "0123456789");
1606 i
= icn_writecmd(cbuf
, strlen(cbuf
), 0, card
);
1609 case ISDN_CMD_CLREAZ
:
1610 if (!card
->flags
& ICN_FLAGS_RUNNING
)
1614 if (c
->arg
< ICN_BCH
) {
1616 if (card
->ptype
== ISDN_PTYPE_EURO
)
1617 sprintf(cbuf
, "%02d;MSNC\n", (int) a
);
1619 sprintf(cbuf
, "%02d;EAZC\n", (int) a
);
1620 i
= icn_writecmd(cbuf
, strlen(cbuf
), 0, card
);
1623 case ISDN_CMD_SETL2
:
1624 if (!card
->flags
& ICN_FLAGS_RUNNING
)
1626 if ((c
->arg
& 255) < ICN_BCH
) {
1629 case ISDN_PROTO_L2_X75I
:
1630 sprintf(cbuf
, "%02d;BX75\n", (int) (a
& 255) + 1);
1632 case ISDN_PROTO_L2_HDLC
:
1633 sprintf(cbuf
, "%02d;BTRA\n", (int) (a
& 255) + 1);
1638 i
= icn_writecmd(cbuf
, strlen(cbuf
), 0, card
);
1639 card
->l2_proto
[a
& 255] = (a
>> 8);
1642 case ISDN_CMD_GETL2
:
1643 if (!card
->flags
& ICN_FLAGS_RUNNING
)
1645 if ((c
->arg
& 255) < ICN_BCH
)
1646 return card
->l2_proto
[c
->arg
& 255];
1649 case ISDN_CMD_SETL3
:
1650 if (!card
->flags
& ICN_FLAGS_RUNNING
)
1653 case ISDN_CMD_GETL3
:
1654 if (!card
->flags
& ICN_FLAGS_RUNNING
)
1656 if ((c
->arg
& 255) < ICN_BCH
)
1657 return ISDN_PROTO_L3_TRANS
;
1660 case ISDN_CMD_GETEAZ
:
1661 if (!card
->flags
& ICN_FLAGS_RUNNING
)
1664 case ISDN_CMD_SETSIL
:
1665 if (!card
->flags
& ICN_FLAGS_RUNNING
)
1668 case ISDN_CMD_GETSIL
:
1669 if (!card
->flags
& ICN_FLAGS_RUNNING
)
1675 case ISDN_CMD_UNLOCK
:
1685 * Find card with given driverId
1687 static inline icn_card
*
1688 icn_findcard(int driverid
)
1690 icn_card
*p
= cards
;
1693 if (p
->myid
== driverid
)
1697 return (icn_card
*) 0;
1701 * Wrapper functions for interface to linklevel
1704 if_command(isdn_ctrl
* c
)
1706 icn_card
*card
= icn_findcard(c
->driver
);
1709 return (icn_command(c
, card
));
1711 "icn: if_command %d called with invalid driverId %d!\n",
1712 c
->command
, c
->driver
);
1717 if_writecmd(const u_char
* buf
, int len
, int user
, int id
, int channel
)
1719 icn_card
*card
= icn_findcard(id
);
1722 if (!card
->flags
& ICN_FLAGS_RUNNING
)
1724 return (icn_writecmd(buf
, len
, user
, card
));
1727 "icn: if_writecmd called with invalid driverId!\n");
1732 if_readstatus(u_char
* buf
, int len
, int user
, int id
, int channel
)
1734 icn_card
*card
= icn_findcard(id
);
1737 if (!card
->flags
& ICN_FLAGS_RUNNING
)
1739 return (icn_readstatus(buf
, len
, user
, card
));
1742 "icn: if_readstatus called with invalid driverId!\n");
1747 if_sendbuf(int id
, int channel
, int ack
, struct sk_buff
*skb
)
1749 icn_card
*card
= icn_findcard(id
);
1752 if (!card
->flags
& ICN_FLAGS_RUNNING
)
1754 return (icn_sendbuf(channel
, ack
, skb
, card
));
1757 "icn: if_sendbuf called with invalid driverId!\n");
1762 * Allocate a new card-struct, initialize it
1763 * link it into cards-list and register it at linklevel.
1766 icn_initcard(int port
, char *id
)
1771 if (!(card
= (icn_card
*) kmalloc(sizeof(icn_card
), GFP_KERNEL
))) {
1773 "icn: (%s) Could not allocate card-struct.\n", id
);
1774 return (icn_card
*) 0;
1776 memset((char *) card
, 0, sizeof(icn_card
));
1778 card
->interface
.hl_hdrlen
= 1;
1779 card
->interface
.channels
= ICN_BCH
;
1780 card
->interface
.maxbufsize
= 4000;
1781 card
->interface
.command
= if_command
;
1782 card
->interface
.writebuf_skb
= if_sendbuf
;
1783 card
->interface
.writecmd
= if_writecmd
;
1784 card
->interface
.readstat
= if_readstatus
;
1785 card
->interface
.features
= ISDN_FEATURE_L2_X75I
|
1786 ISDN_FEATURE_L2_HDLC
|
1787 ISDN_FEATURE_L3_TRANS
|
1788 ISDN_FEATURE_P_UNKNOWN
;
1789 card
->ptype
= ISDN_PTYPE_UNKNOWN
;
1790 strncpy(card
->interface
.id
, id
, sizeof(card
->interface
.id
) - 1);
1791 card
->msg_buf_write
= card
->msg_buf
;
1792 card
->msg_buf_read
= card
->msg_buf
;
1793 card
->msg_buf_end
= &card
->msg_buf
[sizeof(card
->msg_buf
) - 1];
1794 for (i
= 0; i
< ICN_BCH
; i
++) {
1795 card
->l2_proto
[i
] = ISDN_PROTO_L2_X75I
;
1796 skb_queue_head_init(&card
->spqueue
[i
]);
1800 if (!register_isdn(&card
->interface
)) {
1801 cards
= cards
->next
;
1803 "icn: Unable to register %s\n", id
);
1805 return (icn_card
*) 0;
1807 card
->myid
= card
->interface
.channels
;
1808 sprintf(card
->regname
, "icn-isdn (%s)", card
->interface
.id
);
1813 icn_addcard(int port
, char *id1
, char *id2
)
1821 if (!(card
= icn_initcard(port
, id1
))) {
1822 restore_flags(flags
);
1826 restore_flags(flags
);
1828 "icn: (%s) ICN-2B, port 0x%x added\n",
1829 card
->interface
.id
, port
);
1832 if (!(card2
= icn_initcard(port
, id2
))) {
1833 restore_flags(flags
);
1835 "icn: (%s) half ICN-4B, port 0x%x added\n",
1836 card2
->interface
.id
, port
);
1840 card
->secondhalf
= 0;
1841 card
->other
= card2
;
1842 card2
->doubleS0
= 1;
1843 card2
->secondhalf
= 1;
1844 card2
->other
= card
;
1845 restore_flags(flags
);
1847 "icn: (%s and %s) ICN-4B, port 0x%x added\n",
1848 card
->interface
.id
, card2
->interface
.id
, port
);
1853 #define icn_init init_module
1855 #ifdef COMPAT_HAS_NEW_SETUP
1856 #include <linux/init.h>
1858 icn_setup(char *line
)
1862 static char sid
[20];
1863 static char sid2
[20];
1865 str
= get_options(line
, 2, ints
);
1868 icn_setup(char *str
, int *ints
)
1871 static char sid
[20];
1872 static char sid2
[20];
1881 if ((p
= strchr(sid
, ','))) {
1887 #ifdef COMPAT_HAS_NEW_SETUP
1890 __setup("icn=", icn_setup
);
1894 #endif /* MODULES */
1902 memset(&dev
, 0, sizeof(icn_dev
));
1903 dev
.shmem
= (icn_shmem
*) ((unsigned long) membase
& 0x0ffc000);
1908 /* No symbols to export, hide all symbols */
1911 if ((p
= strchr(revision
, ':'))) {
1913 p
= strchr(rev
, '$');
1916 strcpy(rev
, " ??? ");
1917 printk(KERN_NOTICE
"ICN-ISDN-driver Rev%smem=0x%08lx\n", rev
,
1919 return (icn_addcard(portbase
, icn_id
, icn_id2
));
1924 cleanup_module(void)
1927 icn_card
*card
= cards
;
1933 cmd
.command
= ISDN_STAT_UNLOAD
;
1934 cmd
.driver
= card
->myid
;
1935 card
->interface
.statcallb(&cmd
);
1937 OUTB_P(0, ICN_RUN
); /* Reset Controller */
1938 OUTB_P(0, ICN_MAPRAM
); /* Disable RAM */
1939 if (card
->secondhalf
|| (!card
->doubleS0
)) {
1940 release_region(card
->port
, ICN_PORTLEN
);
1943 for (i
= 0; i
< ICN_BCH
; i
++)
1944 icn_free_queue(card
, i
);
1955 release_shmem((ulong
) dev
.shmem
, 0x4000);
1956 printk(KERN_NOTICE
"ICN-ISDN-driver unloaded\n");