1 /* $Id: module.c,v 1.14.6.4 2001/09/23 22:24:32 kai Exp $
3 * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000.
6 * Copyright by Fritz Elfert <fritz@isdn4linux.de>
8 * This software may be used and distributed according to the terms
9 * of the GNU General Public License, incorporated herein by reference.
11 * Thanks to Friedemann Baitinger and IBM Germany
16 #include "act2000_isa.h"
18 #include <linux/module.h>
19 #include <linux/init.h>
21 static unsigned short act2000_isa_ports
[] =
23 0x0200, 0x0240, 0x0280, 0x02c0, 0x0300, 0x0340, 0x0380,
24 0xcfe0, 0xcfa0, 0xcf60, 0xcf20, 0xcee0, 0xcea0, 0xce60,
26 #define ISA_NRPORTS (sizeof(act2000_isa_ports)/sizeof(unsigned short))
28 static act2000_card
*cards
= (act2000_card
*) NULL
;
30 /* Parameters to be set by insmod */
31 static int act_bus
= 0;
32 static int act_port
= -1; /* -1 = Autoprobe */
33 static int act_irq
= -1;
34 static char *act_id
= "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
36 MODULE_DESCRIPTION( "ISDN4Linux: Driver for IBM Active 2000 ISDN card");
37 MODULE_AUTHOR( "Fritz Elfert");
38 MODULE_LICENSE( "GPL");
39 MODULE_PARM_DESC(act_bus
, "BusType of first card, 1=ISA, 2=MCA, 3=PCMCIA, currently only ISA");
40 MODULE_PARM_DESC(membase
, "Base port address of first card");
41 MODULE_PARM_DESC(act_irq
, "IRQ of first card");
42 MODULE_PARM_DESC(act_id
, "ID-String of first card");
43 module_param(act_bus
, int, 0);
44 module_param(act_port
, int, 0);
45 module_param(act_irq
, int, 0);
46 module_param(act_id
, charp
, 0);
48 static int act2000_addcard(int, int, int, char *);
51 find_channel(act2000_card
*card
, int channel
)
53 if ((channel
>= 0) && (channel
< ACT2000_BCH
))
54 return &(card
->bch
[channel
]);
55 printk(KERN_WARNING
"act2000: Invalid channel %d\n", channel
);
63 act2000_clear_msn(act2000_card
*card
)
65 struct msn_entry
*p
= card
->msn_list
;
69 spin_lock_irqsave(&card
->lock
, flags
);
70 card
->msn_list
= NULL
;
71 spin_unlock_irqrestore(&card
->lock
, flags
);
80 * Find an MSN entry in the list.
81 * If ia5 != 0, return IA5-encoded EAZ, else
82 * return a bitmask with corresponding bit set.
85 act2000_find_msn(act2000_card
*card
, char *msn
, int ia5
)
87 struct msn_entry
*p
= card
->msn_list
;
91 if (!strcmp(p
->msn
, msn
)) {
98 return (1 << (eaz
- '0'));
104 * Find an EAZ entry in the list.
105 * return a string with corresponding msn.
108 act2000_find_eaz(act2000_card
*card
, char eaz
)
110 struct msn_entry
*p
= card
->msn_list
;
121 * Add or delete an MSN to the MSN list
123 * First character of msneaz is EAZ, rest is MSN.
124 * If length of eazmsn is 1, delete that entry.
127 act2000_set_msn(act2000_card
*card
, char *eazmsn
)
129 struct msn_entry
*p
= card
->msn_list
;
130 struct msn_entry
*q
= NULL
;
136 if (strlen(eazmsn
) > 16)
138 for (i
= 0; i
< strlen(eazmsn
); i
++)
139 if (!isdigit(eazmsn
[i
]))
141 if (strlen(eazmsn
) == 1) {
142 /* Delete a single MSN */
144 if (p
->eaz
== eazmsn
[0]) {
145 spin_lock_irqsave(&card
->lock
, flags
);
149 card
->msn_list
= p
->next
;
150 spin_unlock_irqrestore(&card
->lock
, flags
);
153 "Mapping for EAZ %c deleted\n",
162 /* Add a single MSN */
164 /* Found in list, replace MSN */
165 if (p
->eaz
== eazmsn
[0]) {
166 spin_lock_irqsave(&card
->lock
, flags
);
167 strcpy(p
->msn
, &eazmsn
[1]);
168 spin_unlock_irqrestore(&card
->lock
, flags
);
170 "Mapping for EAZ %c changed to %s\n",
177 /* Not found in list, add new entry */
178 p
= kmalloc(sizeof(msn_entry
), GFP_KERNEL
);
182 strcpy(p
->msn
, &eazmsn
[1]);
183 p
->next
= card
->msn_list
;
184 spin_lock_irqsave(&card
->lock
, flags
);
186 spin_unlock_irqrestore(&card
->lock
, flags
);
188 "Mapping %c -> %s added\n",
195 act2000_transmit(struct act2000_card
*card
)
198 case ACT2000_BUS_ISA
:
199 act2000_isa_send(card
);
201 case ACT2000_BUS_PCMCIA
:
202 case ACT2000_BUS_MCA
:
205 "act2000_transmit: Illegal bustype %d\n", card
->bus
);
210 act2000_receive(struct act2000_card
*card
)
213 case ACT2000_BUS_ISA
:
214 act2000_isa_receive(card
);
216 case ACT2000_BUS_PCMCIA
:
217 case ACT2000_BUS_MCA
:
220 "act2000_receive: Illegal bustype %d\n", card
->bus
);
225 act2000_poll(unsigned long data
)
227 act2000_card
* card
= (act2000_card
*)data
;
230 act2000_receive(card
);
231 spin_lock_irqsave(&card
->lock
, flags
);
232 mod_timer(&card
->ptimer
, jiffies
+3);
233 spin_unlock_irqrestore(&card
->lock
, flags
);
237 act2000_command(act2000_card
* card
, isdn_ctrl
* c
)
248 switch (c
->command
) {
250 memcpy(&a
, c
->parm
.num
, sizeof(ulong
));
251 arg
= (void __user
*)a
;
253 case ACT2000_IOCTL_LOADBOOT
:
255 case ACT2000_BUS_ISA
:
256 ret
= act2000_isa_download(card
,
259 card
->flags
|= ACT2000_FLAGS_LOADED
;
260 if (!(card
->flags
& ACT2000_FLAGS_IVALID
)) {
261 card
->ptimer
.expires
= jiffies
+ 3;
262 card
->ptimer
.function
= act2000_poll
;
263 card
->ptimer
.data
= (unsigned long)card
;
264 add_timer(&card
->ptimer
);
266 actcapi_manufacturer_req_errh(card
);
271 "act2000: Illegal BUS type %d\n",
276 case ACT2000_IOCTL_SETPROTO
:
277 card
->ptype
= a
?ISDN_PTYPE_EURO
:ISDN_PTYPE_1TR6
;
278 if (!(card
->flags
& ACT2000_FLAGS_RUNNING
))
280 actcapi_manufacturer_req_net(card
);
282 case ACT2000_IOCTL_SETMSN
:
283 if (copy_from_user(tmp
, arg
,
286 if ((ret
= act2000_set_msn(card
, tmp
)))
288 if (card
->flags
& ACT2000_FLAGS_RUNNING
)
289 return(actcapi_manufacturer_req_msn(card
));
291 case ACT2000_IOCTL_ADDCARD
:
292 if (copy_from_user(&cdef
, arg
,
295 if (act2000_addcard(cdef
.bus
, cdef
.port
, cdef
.irq
, cdef
.id
))
298 case ACT2000_IOCTL_TEST
:
299 if (!(card
->flags
& ACT2000_FLAGS_RUNNING
))
307 if (!card
->flags
& ACT2000_FLAGS_RUNNING
)
309 if (!(chan
= find_channel(card
, c
->arg
& 0x0f)))
311 spin_lock_irqsave(&card
->lock
, flags
);
312 if (chan
->fsm_state
!= ACT2000_STATE_NULL
) {
313 spin_unlock_irqrestore(&card
->lock
, flags
);
314 printk(KERN_WARNING
"Dial on channel with state %d\n",
318 if (card
->ptype
== ISDN_PTYPE_EURO
)
319 tmp
[0] = act2000_find_msn(card
, c
->parm
.setup
.eazmsn
, 1);
321 tmp
[0] = c
->parm
.setup
.eazmsn
[0];
322 chan
->fsm_state
= ACT2000_STATE_OCALL
;
323 chan
->callref
= 0xffff;
324 spin_unlock_irqrestore(&card
->lock
, flags
);
325 ret
= actcapi_connect_req(card
, chan
, c
->parm
.setup
.phone
,
326 tmp
[0], c
->parm
.setup
.si1
,
329 cmd
.driver
= card
->myid
;
330 cmd
.command
= ISDN_STAT_DHUP
;
332 card
->interface
.statcallb(&cmd
);
335 case ISDN_CMD_ACCEPTD
:
336 if (!card
->flags
& ACT2000_FLAGS_RUNNING
)
338 if (!(chan
= find_channel(card
, c
->arg
& 0x0f)))
340 if (chan
->fsm_state
== ACT2000_STATE_ICALL
)
341 actcapi_select_b2_protocol_req(card
, chan
);
343 case ISDN_CMD_ACCEPTB
:
344 if (!card
->flags
& ACT2000_FLAGS_RUNNING
)
347 case ISDN_CMD_HANGUP
:
348 if (!card
->flags
& ACT2000_FLAGS_RUNNING
)
350 if (!(chan
= find_channel(card
, c
->arg
& 0x0f)))
352 switch (chan
->fsm_state
) {
353 case ACT2000_STATE_ICALL
:
354 case ACT2000_STATE_BSETUP
:
355 actcapi_connect_resp(card
, chan
, 0x15);
357 case ACT2000_STATE_ACTIVE
:
358 actcapi_disconnect_b3_req(card
, chan
);
362 case ISDN_CMD_SETEAZ
:
363 if (!card
->flags
& ACT2000_FLAGS_RUNNING
)
365 if (!(chan
= find_channel(card
, c
->arg
& 0x0f)))
367 if (strlen(c
->parm
.num
)) {
368 if (card
->ptype
== ISDN_PTYPE_EURO
) {
369 chan
->eazmask
= act2000_find_msn(card
, c
->parm
.num
, 0);
371 if (card
->ptype
== ISDN_PTYPE_1TR6
) {
374 for (i
= 0; i
< strlen(c
->parm
.num
); i
++)
375 if (isdigit(c
->parm
.num
[i
]))
376 chan
->eazmask
|= (1 << (c
->parm
.num
[i
] - '0'));
379 chan
->eazmask
= 0x3ff;
380 actcapi_listen_req(card
);
382 case ISDN_CMD_CLREAZ
:
383 if (!card
->flags
& ACT2000_FLAGS_RUNNING
)
385 if (!(chan
= find_channel(card
, c
->arg
& 0x0f)))
388 actcapi_listen_req(card
);
391 if (!card
->flags
& ACT2000_FLAGS_RUNNING
)
393 if (!(chan
= find_channel(card
, c
->arg
& 0x0f)))
395 chan
->l2prot
= (c
->arg
>> 8);
398 if (!card
->flags
& ACT2000_FLAGS_RUNNING
)
400 if ((c
->arg
>> 8) != ISDN_PROTO_L3_TRANS
) {
401 printk(KERN_WARNING
"L3 protocol unknown\n");
404 if (!(chan
= find_channel(card
, c
->arg
& 0x0f)))
406 chan
->l3prot
= (c
->arg
>> 8);
414 act2000_sendbuf(act2000_card
*card
, int channel
, int ack
, struct sk_buff
*skb
)
416 struct sk_buff
*xmit_skb
;
421 if (!(chan
= find_channel(card
, channel
)))
423 if (chan
->fsm_state
!= ACT2000_STATE_ACTIVE
)
426 if ((chan
->queued
+ len
) >= ACT2000_MAX_QUEUED
)
430 if (skb_headroom(skb
) < 19) {
431 printk(KERN_WARNING
"act2000_sendbuf: Headroom only %d\n",
433 xmit_skb
= alloc_skb(len
+ 19, GFP_ATOMIC
);
435 printk(KERN_WARNING
"act2000_sendbuf: Out of memory\n");
438 skb_reserve(xmit_skb
, 19);
439 memcpy(skb_put(xmit_skb
, len
), skb
->data
, len
);
441 xmit_skb
= skb_clone(skb
, GFP_ATOMIC
);
443 printk(KERN_WARNING
"act2000_sendbuf: Out of memory\n");
448 msg
= (actcapi_msg
*)skb_push(xmit_skb
, 19);
449 msg
->hdr
.len
= 19 + len
;
450 msg
->hdr
.applicationID
= 1;
451 msg
->hdr
.cmd
.cmd
= 0x86;
452 msg
->hdr
.cmd
.subcmd
= 0x00;
453 msg
->hdr
.msgnum
= actcapi_nextsmsg(card
);
454 msg
->msg
.data_b3_req
.datalen
= len
;
455 msg
->msg
.data_b3_req
.blocknr
= (msg
->hdr
.msgnum
& 0xff);
456 msg
->msg
.data_b3_req
.fakencci
= MAKE_NCCI(chan
->plci
, 0, chan
->ncci
);
457 msg
->msg
.data_b3_req
.flags
= ack
; /* Will be set to 0 on actual sending */
458 actcapi_debug_msg(xmit_skb
, 1);
460 skb_queue_tail(&card
->sndq
, xmit_skb
);
461 act2000_schedule_tx(card
);
466 /* Read the Status-replies from the Interface */
468 act2000_readstatus(u_char __user
* buf
, int len
, act2000_card
* card
)
473 for (p
= buf
, count
= 0; count
< len
; p
++, count
++) {
474 if (card
->status_buf_read
== card
->status_buf_write
)
476 put_user(*card
->status_buf_read
++, p
);
477 if (card
->status_buf_read
> card
->status_buf_end
)
478 card
->status_buf_read
= card
->status_buf
;
484 * Find card with given driverId
486 static inline act2000_card
*
487 act2000_findcard(int driverid
)
489 act2000_card
*p
= cards
;
492 if (p
->myid
== driverid
)
496 return (act2000_card
*) 0;
500 * Wrapper functions for interface to linklevel
503 if_command(isdn_ctrl
* c
)
505 act2000_card
*card
= act2000_findcard(c
->driver
);
508 return (act2000_command(card
, c
));
510 "act2000: if_command %d called with invalid driverId %d!\n",
511 c
->command
, c
->driver
);
516 if_writecmd(const u_char __user
*buf
, int len
, int id
, int channel
)
518 act2000_card
*card
= act2000_findcard(id
);
521 if (!card
->flags
& ACT2000_FLAGS_RUNNING
)
526 "act2000: if_writecmd called with invalid driverId!\n");
531 if_readstatus(u_char __user
* buf
, int len
, int id
, int channel
)
533 act2000_card
*card
= act2000_findcard(id
);
536 if (!card
->flags
& ACT2000_FLAGS_RUNNING
)
538 return (act2000_readstatus(buf
, len
, card
));
541 "act2000: if_readstatus called with invalid driverId!\n");
546 if_sendbuf(int id
, int channel
, int ack
, struct sk_buff
*skb
)
548 act2000_card
*card
= act2000_findcard(id
);
551 if (!card
->flags
& ACT2000_FLAGS_RUNNING
)
553 return (act2000_sendbuf(card
, channel
, ack
, skb
));
556 "act2000: if_sendbuf called with invalid driverId!\n");
562 * Allocate a new card-struct, initialize it
563 * link it into cards-list.
566 act2000_alloccard(int bus
, int port
, int irq
, char *id
)
570 if (!(card
= (act2000_card
*) kmalloc(sizeof(act2000_card
), GFP_KERNEL
))) {
572 "act2000: (%s) Could not allocate card-struct.\n", id
);
575 memset((char *) card
, 0, sizeof(act2000_card
));
576 spin_lock_init(&card
->lock
);
577 spin_lock_init(&card
->mnlock
);
578 skb_queue_head_init(&card
->sndq
);
579 skb_queue_head_init(&card
->rcvq
);
580 skb_queue_head_init(&card
->ackq
);
581 INIT_WORK(&card
->snd_tq
, (void *) (void *) act2000_transmit
, card
);
582 INIT_WORK(&card
->rcv_tq
, (void *) (void *) actcapi_dispatch
, card
);
583 INIT_WORK(&card
->poll_tq
, (void *) (void *) act2000_receive
, card
);
584 init_timer(&card
->ptimer
);
585 card
->interface
.owner
= THIS_MODULE
;
586 card
->interface
.channels
= ACT2000_BCH
;
587 card
->interface
.maxbufsize
= 4000;
588 card
->interface
.command
= if_command
;
589 card
->interface
.writebuf_skb
= if_sendbuf
;
590 card
->interface
.writecmd
= if_writecmd
;
591 card
->interface
.readstat
= if_readstatus
;
592 card
->interface
.features
=
593 ISDN_FEATURE_L2_X75I
|
594 ISDN_FEATURE_L2_HDLC
|
595 ISDN_FEATURE_L3_TRANS
|
596 ISDN_FEATURE_P_UNKNOWN
;
597 card
->interface
.hl_hdrlen
= 20;
598 card
->ptype
= ISDN_PTYPE_EURO
;
599 strlcpy(card
->interface
.id
, id
, sizeof(card
->interface
.id
));
600 for (i
=0; i
<ACT2000_BCH
; i
++) {
601 card
->bch
[i
].plci
= 0x8000;
602 card
->bch
[i
].ncci
= 0x8000;
603 card
->bch
[i
].l2prot
= ISDN_PROTO_L2_X75I
;
604 card
->bch
[i
].l3prot
= ISDN_PROTO_L3_TRANS
;
615 * register card at linklevel
618 act2000_registercard(act2000_card
* card
)
621 case ACT2000_BUS_ISA
:
623 case ACT2000_BUS_MCA
:
624 case ACT2000_BUS_PCMCIA
:
627 "act2000: Illegal BUS type %d\n",
631 if (!register_isdn(&card
->interface
)) {
633 "act2000: Unable to register %s\n",
637 card
->myid
= card
->interface
.channels
;
638 sprintf(card
->regname
, "act2000-isdn (%s)", card
->interface
.id
);
643 unregister_card(act2000_card
* card
)
647 cmd
.command
= ISDN_STAT_UNLOAD
;
648 cmd
.driver
= card
->myid
;
649 card
->interface
.statcallb(&cmd
);
651 case ACT2000_BUS_ISA
:
652 act2000_isa_release(card
);
654 case ACT2000_BUS_MCA
:
655 case ACT2000_BUS_PCMCIA
:
658 "act2000: Invalid BUS type %d\n",
665 act2000_addcard(int bus
, int port
, int irq
, char *id
)
668 act2000_card
*q
= NULL
;
675 bus
= ACT2000_BUS_ISA
;
677 /* Port defined, do fixed setup */
678 act2000_alloccard(bus
, port
, irq
, id
);
680 /* No port defined, perform autoprobing.
681 * This may result in more than one card detected.
684 case ACT2000_BUS_ISA
:
685 for (i
= 0; i
< ISA_NRPORTS
; i
++)
686 if (act2000_isa_detect(act2000_isa_ports
[i
])) {
688 "act2000: Detected ISA card at port 0x%x\n",
689 act2000_isa_ports
[i
]);
690 act2000_alloccard(bus
, act2000_isa_ports
[i
], irq
, id
);
693 case ACT2000_BUS_MCA
:
694 case ACT2000_BUS_PCMCIA
:
697 "act2000: addcard: Invalid BUS type %d\n",
706 if (!p
->interface
.statcallb
) {
707 /* Not yet registered.
708 * Try to register and activate it.
712 case ACT2000_BUS_ISA
:
713 if (act2000_isa_detect(p
->port
)) {
714 if (act2000_registercard(p
))
716 if (act2000_isa_config_port(p
, p
->port
)) {
718 "act2000: Could not request port 0x%04x\n",
721 p
->interface
.statcallb
= NULL
;
724 if (act2000_isa_config_irq(p
, p
->irq
)) {
726 "act2000: No IRQ available, fallback to polling\n");
727 /* Fall back to polled operation */
732 "-type card at port "
736 printk("irq %d\n", p
->irq
);
742 case ACT2000_BUS_MCA
:
743 case ACT2000_BUS_PCMCIA
:
746 "act2000: addcard: Invalid BUS type %d\n",
750 /* Card already initialized */
753 /* Init OK, next card ... */
757 /* Init failed, remove card from list, free memory */
759 "act2000: Initialization of %s failed\n",
773 return (added
- failed
);
776 #define DRIVERNAME "IBM Active 2000 ISDN driver"
778 static int __init
act2000_init(void)
780 printk(KERN_INFO
"%s\n", DRIVERNAME
);
782 act2000_addcard(act_bus
, act_port
, act_irq
, act_id
);
784 printk(KERN_INFO
"act2000: No cards defined yet\n");
788 static void __exit
act2000_exit(void)
790 act2000_card
*card
= cards
;
793 unregister_card(card
);
794 del_timer(&card
->ptimer
);
801 act2000_clear_msn(last
);
804 printk(KERN_INFO
"%s unloaded\n", DRIVERNAME
);
807 module_init(act2000_init
);
808 module_exit(act2000_exit
);