1 /* $Id: module.c,v 1.9 1999/04/12 13:13:56 fritz Exp $
3 * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000.
5 * Copyright 1998 by Fritz Elfert (fritz@isdn4linux.de)
6 * Thanks to Friedemann Baitinger and IBM Germany
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 * Revision 1.9 1999/04/12 13:13:56 fritz
24 * Made cards pointer static to avoid name-clash.
26 * Revision 1.8 1998/11/05 22:12:51 fritz
27 * Changed mail-address.
29 * Revision 1.7 1998/02/12 23:06:52 keil
30 * change for 2.1.86 (removing FREE_READ/FREE_WRITE from [dev]_kfree_skb()
32 * Revision 1.6 1998/01/31 22:10:42 keil
35 * Revision 1.5 1997/10/09 22:23:04 fritz
36 * New HL<->LL interface:
37 * New BSENT callback with nr. of bytes included.
38 * Sending without ACK.
40 * Revision 1.4 1997/09/25 17:25:43 fritz
41 * Support for adding cards at runtime.
42 * Support for new Firmware.
44 * Revision 1.3 1997/09/24 23:11:45 fritz
45 * Optimized IRQ load and polling-mode.
47 * Revision 1.2 1997/09/24 19:44:17 fritz
48 * Added MSN mapping support, some cleanup.
50 * Revision 1.1 1997/09/23 18:00:13 fritz
51 * New driver for IBM Active 2000.
56 #include "act2000_isa.h"
59 static unsigned short isa_ports
[] =
61 0x0200, 0x0240, 0x0280, 0x02c0, 0x0300, 0x0340, 0x0380,
62 0xcfe0, 0xcfa0, 0xcf60, 0xcf20, 0xcee0, 0xcea0, 0xce60,
64 #define ISA_NRPORTS (sizeof(isa_ports)/sizeof(unsigned short))
66 static act2000_card
*cards
= (act2000_card
*) NULL
;
68 /* Parameters to be set by insmod */
69 static int act_bus
= 0;
70 static int act_port
= -1; /* -1 = Autoprobe */
71 static int act_irq
= -1; /* -1 = Autoselect */
72 static char *act_id
= "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
74 MODULE_DESCRIPTION( "Driver for IBM Active 2000 ISDN card");
75 MODULE_AUTHOR( "Fritz Elfert");
76 MODULE_SUPPORTED_DEVICE( "ISDN subsystem");
77 MODULE_PARM_DESC(act_bus
, "BusType of first card, 1=ISA, 2=MCA, 3=PCMCIA, currently only ISA");
78 MODULE_PARM_DESC(membase
, "Base port address of first card");
79 MODULE_PARM_DESC(act_irq
, "IRQ of first card (-1 = grab next free IRQ)");
80 MODULE_PARM_DESC(act_id
, "ID-String of first card");
81 MODULE_PARM(act_bus
, "i");
82 MODULE_PARM(act_port
, "i");
83 MODULE_PARM(act_irq
, "i");
84 MODULE_PARM(act_id
, "s");
86 static int act2000_addcard(int, int, int, char *);
89 find_channel(act2000_card
*card
, int channel
)
91 if ((channel
>= 0) && (channel
< ACT2000_BCH
))
92 return &(card
->bch
[channel
]);
93 printk(KERN_WARNING
"act2000: Invalid channel %d\n", channel
);
101 act2000_clear_msn(act2000_card
*card
)
103 struct msn_entry
*p
= card
->msn_list
;
109 card
->msn_list
= NULL
;
110 restore_flags(flags
);
119 * Find an MSN entry in the list.
120 * If ia5 != 0, return IA5-encoded EAZ, else
121 * return a bitmask with corresponding bit set.
124 act2000_find_msn(act2000_card
*card
, char *msn
, int ia5
)
126 struct msn_entry
*p
= card
->msn_list
;
130 if (!strcmp(p
->msn
, msn
)) {
137 return (1 << (eaz
- '0'));
143 * Find an EAZ entry in the list.
144 * return a string with corresponding msn.
147 act2000_find_eaz(act2000_card
*card
, char eaz
)
149 struct msn_entry
*p
= card
->msn_list
;
160 * Add or delete an MSN to the MSN list
162 * First character of msneaz is EAZ, rest is MSN.
163 * If length of eazmsn is 1, delete that entry.
166 act2000_set_msn(act2000_card
*card
, char *eazmsn
)
168 struct msn_entry
*p
= card
->msn_list
;
169 struct msn_entry
*q
= NULL
;
175 if (strlen(eazmsn
) > 16)
177 for (i
= 0; i
< strlen(eazmsn
); i
++)
178 if (!isdigit(eazmsn
[i
]))
180 if (strlen(eazmsn
) == 1) {
181 /* Delete a single MSN */
183 if (p
->eaz
== eazmsn
[0]) {
189 card
->msn_list
= p
->next
;
190 restore_flags(flags
);
193 "Mapping for EAZ %c deleted\n",
202 /* Add a single MSN */
204 /* Found in list, replace MSN */
205 if (p
->eaz
== eazmsn
[0]) {
208 strcpy(p
->msn
, &eazmsn
[1]);
209 restore_flags(flags
);
211 "Mapping for EAZ %c changed to %s\n",
218 /* Not found in list, add new entry */
219 p
= kmalloc(sizeof(msn_entry
), GFP_KERNEL
);
223 strcpy(p
->msn
, &eazmsn
[1]);
224 p
->next
= card
->msn_list
;
228 restore_flags(flags
);
230 "Mapping %c -> %s added\n",
237 act2000_transmit(struct act2000_card
*card
)
240 case ACT2000_BUS_ISA
:
243 case ACT2000_BUS_PCMCIA
:
244 case ACT2000_BUS_MCA
:
247 "act2000_transmit: Illegal bustype %d\n", card
->bus
);
252 act2000_receive(struct act2000_card
*card
)
255 case ACT2000_BUS_ISA
:
258 case ACT2000_BUS_PCMCIA
:
259 case ACT2000_BUS_MCA
:
262 "act2000_receive: Illegal bustype %d\n", card
->bus
);
267 act2000_poll(unsigned long data
)
269 act2000_card
* card
= (act2000_card
*)data
;
272 act2000_receive(card
);
275 del_timer(&card
->ptimer
);
276 card
->ptimer
.expires
= jiffies
+ 3;
277 add_timer(&card
->ptimer
);
278 restore_flags(flags
);
282 act2000_command(act2000_card
* card
, isdn_ctrl
* c
)
292 switch (c
->command
) {
294 memcpy(&a
, c
->parm
.num
, sizeof(ulong
));
296 case ACT2000_IOCTL_LOADBOOT
:
298 case ACT2000_BUS_ISA
:
299 ret
= isa_download(card
,
302 card
->flags
|= ACT2000_FLAGS_LOADED
;
303 if (!(card
->flags
& ACT2000_FLAGS_IVALID
)) {
304 card
->ptimer
.expires
= jiffies
+ 3;
305 card
->ptimer
.function
= act2000_poll
;
306 card
->ptimer
.data
= (unsigned long)card
;
307 add_timer(&card
->ptimer
);
309 actcapi_manufacturer_req_errh(card
);
314 "act2000: Illegal BUS type %d\n",
319 case ACT2000_IOCTL_SETPROTO
:
320 card
->ptype
= a
?ISDN_PTYPE_EURO
:ISDN_PTYPE_1TR6
;
321 if (!(card
->flags
& ACT2000_FLAGS_RUNNING
))
323 actcapi_manufacturer_req_net(card
);
325 case ACT2000_IOCTL_SETMSN
:
326 if ((ret
= copy_from_user(tmp
, (char *)a
, sizeof(tmp
))))
328 if ((ret
= act2000_set_msn(card
, tmp
)))
330 if (card
->flags
& ACT2000_FLAGS_RUNNING
)
331 return(actcapi_manufacturer_req_msn(card
));
333 case ACT2000_IOCTL_ADDCARD
:
334 if ((ret
= copy_from_user(&cdef
, (char *)a
, sizeof(cdef
))))
336 if (act2000_addcard(cdef
.bus
, cdef
.port
, cdef
.irq
, cdef
.id
))
339 case ACT2000_IOCTL_TEST
:
340 if (!(card
->flags
& ACT2000_FLAGS_RUNNING
))
348 if (!card
->flags
& ACT2000_FLAGS_RUNNING
)
350 if (!(chan
= find_channel(card
, c
->arg
& 0x0f)))
354 if (chan
->fsm_state
!= ACT2000_STATE_NULL
) {
355 restore_flags(flags
);
356 printk(KERN_WARNING
"Dial on channel with state %d\n",
360 if (card
->ptype
== ISDN_PTYPE_EURO
)
361 tmp
[0] = act2000_find_msn(card
, c
->parm
.setup
.eazmsn
, 1);
363 tmp
[0] = c
->parm
.setup
.eazmsn
[0];
364 chan
->fsm_state
= ACT2000_STATE_OCALL
;
365 chan
->callref
= 0xffff;
366 restore_flags(flags
);
367 ret
= actcapi_connect_req(card
, chan
, c
->parm
.setup
.phone
,
368 tmp
[0], c
->parm
.setup
.si1
,
371 cmd
.driver
= card
->myid
;
372 cmd
.command
= ISDN_STAT_DHUP
;
374 card
->interface
.statcallb(&cmd
);
377 case ISDN_CMD_ACCEPTD
:
378 if (!card
->flags
& ACT2000_FLAGS_RUNNING
)
380 if (!(chan
= find_channel(card
, c
->arg
& 0x0f)))
382 if (chan
->fsm_state
== ACT2000_STATE_ICALL
)
383 actcapi_select_b2_protocol_req(card
, chan
);
385 case ISDN_CMD_ACCEPTB
:
386 if (!card
->flags
& ACT2000_FLAGS_RUNNING
)
389 case ISDN_CMD_HANGUP
:
390 if (!card
->flags
& ACT2000_FLAGS_RUNNING
)
392 if (!(chan
= find_channel(card
, c
->arg
& 0x0f)))
394 switch (chan
->fsm_state
) {
395 case ACT2000_STATE_ICALL
:
396 case ACT2000_STATE_BSETUP
:
397 actcapi_connect_resp(card
, chan
, 0x15);
399 case ACT2000_STATE_ACTIVE
:
400 actcapi_disconnect_b3_req(card
, chan
);
404 case ISDN_CMD_SETEAZ
:
405 if (!card
->flags
& ACT2000_FLAGS_RUNNING
)
407 if (!(chan
= find_channel(card
, c
->arg
& 0x0f)))
409 if (strlen(c
->parm
.num
)) {
410 if (card
->ptype
== ISDN_PTYPE_EURO
) {
411 chan
->eazmask
= act2000_find_msn(card
, c
->parm
.num
, 0);
413 if (card
->ptype
== ISDN_PTYPE_1TR6
) {
416 for (i
= 0; i
< strlen(c
->parm
.num
); i
++)
417 if (isdigit(c
->parm
.num
[i
]))
418 chan
->eazmask
|= (1 << (c
->parm
.num
[i
] - '0'));
421 chan
->eazmask
= 0x3ff;
422 actcapi_listen_req(card
);
424 case ISDN_CMD_CLREAZ
:
425 if (!card
->flags
& ACT2000_FLAGS_RUNNING
)
427 if (!(chan
= find_channel(card
, c
->arg
& 0x0f)))
430 actcapi_listen_req(card
);
433 if (!card
->flags
& ACT2000_FLAGS_RUNNING
)
435 if (!(chan
= find_channel(card
, c
->arg
& 0x0f)))
437 chan
->l2prot
= (c
->arg
>> 8);
440 if (!card
->flags
& ACT2000_FLAGS_RUNNING
)
442 if (!(chan
= find_channel(card
, c
->arg
& 0x0f)))
446 if (!card
->flags
& ACT2000_FLAGS_RUNNING
)
448 if ((c
->arg
>> 8) != ISDN_PROTO_L3_TRANS
) {
449 printk(KERN_WARNING
"L3 protocol unknown\n");
452 if (!(chan
= find_channel(card
, c
->arg
& 0x0f)))
454 chan
->l3prot
= (c
->arg
>> 8);
457 if (!card
->flags
& ACT2000_FLAGS_RUNNING
)
459 if (!(chan
= find_channel(card
, c
->arg
& 0x0f)))
462 case ISDN_CMD_GETEAZ
:
463 if (!card
->flags
& ACT2000_FLAGS_RUNNING
)
465 printk(KERN_DEBUG
"act2000 CMD_GETEAZ not implemented\n");
467 case ISDN_CMD_SETSIL
:
468 if (!card
->flags
& ACT2000_FLAGS_RUNNING
)
470 printk(KERN_DEBUG
"act2000 CMD_SETSIL not implemented\n");
472 case ISDN_CMD_GETSIL
:
473 if (!card
->flags
& ACT2000_FLAGS_RUNNING
)
475 printk(KERN_DEBUG
"act2000 CMD_GETSIL not implemented\n");
480 case ISDN_CMD_UNLOCK
:
489 act2000_sendbuf(act2000_card
*card
, int channel
, int ack
, struct sk_buff
*skb
)
491 struct sk_buff
*xmit_skb
;
496 if (!(chan
= find_channel(card
, channel
)))
498 if (chan
->fsm_state
!= ACT2000_STATE_ACTIVE
)
501 if ((chan
->queued
+ len
) >= ACT2000_MAX_QUEUED
)
505 if (skb_headroom(skb
) < 19) {
506 printk(KERN_WARNING
"act2000_sendbuf: Headroom only %d\n",
508 xmit_skb
= alloc_skb(len
+ 19, GFP_ATOMIC
);
510 printk(KERN_WARNING
"act2000_sendbuf: Out of memory\n");
513 skb_reserve(xmit_skb
, 19);
514 memcpy(skb_put(xmit_skb
, len
), skb
->data
, len
);
516 xmit_skb
= skb_clone(skb
, GFP_ATOMIC
);
518 printk(KERN_WARNING
"act2000_sendbuf: Out of memory\n");
523 msg
= (actcapi_msg
*)skb_push(xmit_skb
, 19);
524 msg
->hdr
.len
= 19 + len
;
525 msg
->hdr
.applicationID
= 1;
526 msg
->hdr
.cmd
.cmd
= 0x86;
527 msg
->hdr
.cmd
.subcmd
= 0x00;
528 msg
->hdr
.msgnum
= actcapi_nextsmsg(card
);
529 msg
->msg
.data_b3_req
.datalen
= len
;
530 msg
->msg
.data_b3_req
.blocknr
= (msg
->hdr
.msgnum
& 0xff);
531 msg
->msg
.data_b3_req
.fakencci
= MAKE_NCCI(chan
->plci
, 0, chan
->ncci
);
532 msg
->msg
.data_b3_req
.flags
= ack
; /* Will be set to 0 on actual sending */
533 actcapi_debug_msg(xmit_skb
, 1);
535 skb_queue_tail(&card
->sndq
, xmit_skb
);
536 act2000_schedule_tx(card
);
541 /* Read the Status-replies from the Interface */
543 act2000_readstatus(u_char
* buf
, int len
, int user
, act2000_card
* card
)
548 for (p
= buf
, count
= 0; count
< len
; p
++, count
++) {
549 if (card
->status_buf_read
== card
->status_buf_write
)
552 put_user(*card
->status_buf_read
++, p
);
554 *p
= *card
->status_buf_read
++;
555 if (card
->status_buf_read
> card
->status_buf_end
)
556 card
->status_buf_read
= card
->status_buf
;
562 act2000_putmsg(act2000_card
*card
, char c
)
568 *card
->status_buf_write
++ = c
;
569 if (card
->status_buf_write
== card
->status_buf_read
) {
570 if (++card
->status_buf_read
> card
->status_buf_end
)
571 card
->status_buf_read
= card
->status_buf
;
573 if (card
->status_buf_write
> card
->status_buf_end
)
574 card
->status_buf_write
= card
->status_buf
;
575 restore_flags(flags
);
579 act2000_logstat(struct act2000_card
*card
, char *str
)
585 act2000_putmsg(card
, *p
++);
586 c
.command
= ISDN_STAT_STAVAIL
;
587 c
.driver
= card
->myid
;
589 card
->interface
.statcallb(&c
);
593 * Find card with given driverId
595 static inline act2000_card
*
596 act2000_findcard(int driverid
)
598 act2000_card
*p
= cards
;
601 if (p
->myid
== driverid
)
605 return (act2000_card
*) 0;
609 * Wrapper functions for interface to linklevel
612 if_command(isdn_ctrl
* c
)
614 act2000_card
*card
= act2000_findcard(c
->driver
);
617 return (act2000_command(card
, c
));
619 "act2000: if_command %d called with invalid driverId %d!\n",
620 c
->command
, c
->driver
);
625 if_writecmd(const u_char
* buf
, int len
, int user
, int id
, int channel
)
627 act2000_card
*card
= act2000_findcard(id
);
630 if (!card
->flags
& ACT2000_FLAGS_RUNNING
)
635 "act2000: if_writecmd called with invalid driverId!\n");
640 if_readstatus(u_char
* buf
, int len
, int user
, int id
, int channel
)
642 act2000_card
*card
= act2000_findcard(id
);
645 if (!card
->flags
& ACT2000_FLAGS_RUNNING
)
647 return (act2000_readstatus(buf
, len
, user
, card
));
650 "act2000: if_readstatus called with invalid driverId!\n");
655 if_sendbuf(int id
, int channel
, int ack
, struct sk_buff
*skb
)
657 act2000_card
*card
= act2000_findcard(id
);
660 if (!card
->flags
& ACT2000_FLAGS_RUNNING
)
662 return (act2000_sendbuf(card
, channel
, ack
, skb
));
665 "act2000: if_sendbuf called with invalid driverId!\n");
671 * Allocate a new card-struct, initialize it
672 * link it into cards-list.
675 act2000_alloccard(int bus
, int port
, int irq
, char *id
)
679 if (!(card
= (act2000_card
*) kmalloc(sizeof(act2000_card
), GFP_KERNEL
))) {
681 "act2000: (%s) Could not allocate card-struct.\n", id
);
684 memset((char *) card
, 0, sizeof(act2000_card
));
685 skb_queue_head_init(&card
->sndq
);
686 skb_queue_head_init(&card
->rcvq
);
687 skb_queue_head_init(&card
->ackq
);
688 card
->snd_tq
.routine
= (void *) (void *) act2000_transmit
;
689 card
->snd_tq
.data
= card
;
690 card
->rcv_tq
.routine
= (void *) (void *) actcapi_dispatch
;
691 card
->rcv_tq
.data
= card
;
692 card
->poll_tq
.routine
= (void *) (void *) act2000_receive
;
693 card
->poll_tq
.data
= card
;
694 init_timer(&card
->ptimer
);
695 card
->interface
.channels
= ACT2000_BCH
;
696 card
->interface
.maxbufsize
= 4000;
697 card
->interface
.command
= if_command
;
698 card
->interface
.writebuf_skb
= if_sendbuf
;
699 card
->interface
.writecmd
= if_writecmd
;
700 card
->interface
.readstat
= if_readstatus
;
701 card
->interface
.features
=
702 ISDN_FEATURE_L2_X75I
|
703 ISDN_FEATURE_L2_HDLC
|
705 /* Not yet! New Firmware is on the way ... */
706 ISDN_FEATURE_L2_TRANS
|
708 ISDN_FEATURE_L3_TRANS
|
709 ISDN_FEATURE_P_UNKNOWN
;
710 card
->interface
.hl_hdrlen
= 20;
711 card
->ptype
= ISDN_PTYPE_EURO
;
712 strncpy(card
->interface
.id
, id
, sizeof(card
->interface
.id
) - 1);
713 for (i
=0; i
<ACT2000_BCH
; i
++) {
714 card
->bch
[i
].plci
= 0x8000;
715 card
->bch
[i
].ncci
= 0x8000;
716 card
->bch
[i
].l2prot
= ISDN_PROTO_L2_X75I
;
717 card
->bch
[i
].l3prot
= ISDN_PROTO_L3_TRANS
;
728 * register card at linklevel
731 act2000_registercard(act2000_card
* card
)
734 case ACT2000_BUS_ISA
:
736 case ACT2000_BUS_MCA
:
737 case ACT2000_BUS_PCMCIA
:
740 "act2000: Illegal BUS type %d\n",
744 if (!register_isdn(&card
->interface
)) {
746 "act2000: Unable to register %s\n",
750 card
->myid
= card
->interface
.channels
;
751 sprintf(card
->regname
, "act2000-isdn (%s)", card
->interface
.id
);
756 unregister_card(act2000_card
* card
)
760 cmd
.command
= ISDN_STAT_UNLOAD
;
761 cmd
.driver
= card
->myid
;
762 card
->interface
.statcallb(&cmd
);
764 case ACT2000_BUS_ISA
:
767 case ACT2000_BUS_MCA
:
768 case ACT2000_BUS_PCMCIA
:
771 "act2000: Invalid BUS type %d\n",
778 act2000_addcard(int bus
, int port
, int irq
, char *id
)
781 act2000_card
*q
= NULL
;
788 bus
= ACT2000_BUS_ISA
;
790 /* Port defined, do fixed setup */
791 act2000_alloccard(bus
, port
, irq
, id
);
793 /* No port defined, perform autoprobing.
794 * This may result in more than one card detected.
797 case ACT2000_BUS_ISA
:
798 for (i
= 0; i
< ISA_NRPORTS
; i
++)
799 if (isa_detect(isa_ports
[i
])) {
801 "act2000: Detected ISA card at port 0x%x\n",
803 act2000_alloccard(bus
, isa_ports
[i
], irq
, id
);
806 case ACT2000_BUS_MCA
:
807 case ACT2000_BUS_PCMCIA
:
810 "act2000: addcard: Invalid BUS type %d\n",
819 if (!p
->interface
.statcallb
) {
820 /* Not yet registered.
821 * Try to register and activate it.
825 case ACT2000_BUS_ISA
:
826 if (isa_detect(p
->port
)) {
827 if (act2000_registercard(p
))
829 if (isa_config_port(p
, p
->port
)) {
831 "act2000: Could not request port 0x%04x\n",
834 p
->interface
.statcallb
= NULL
;
837 if (isa_config_irq(p
, p
->irq
)) {
839 "act2000: No IRQ available, fallback to polling\n");
840 /* Fall back to polled operation */
845 "-type card at port "
849 printk("irq %d\n", p
->irq
);
855 case ACT2000_BUS_MCA
:
856 case ACT2000_BUS_PCMCIA
:
859 "act2000: addcard: Invalid BUS type %d\n",
863 /* Card already initialized */
866 /* Init OK, next card ... */
870 /* Init failed, remove card from list, free memory */
872 "act2000: Initialization of %s failed\n",
886 return (added
- failed
);
889 #define DRIVERNAME "IBM Active 2000 ISDN driver"
892 #define act2000_init init_module
898 printk(KERN_INFO
"%s\n", DRIVERNAME
);
900 act2000_addcard(act_bus
, act_port
, act_irq
, act_id
);
902 printk(KERN_INFO
"act2000: No cards defined yet\n");
903 /* No symbols to export, hide all symbols */
912 act2000_card
*card
= cards
;
915 unregister_card(card
);
916 del_timer(&card
->ptimer
);
923 act2000_clear_msn(last
);
926 printk(KERN_INFO
"%s unloaded\n", DRIVERNAME
);
931 act2000_setup(char *str
, int *ints
)
933 int i
, j
, argc
, port
, irq
, bus
;
956 act2000_addcard(bus
, port
, irq
, act_id
);