File: /usr/src/linux/drivers/isdn/act2000/module.c
1 /* $Id: module.c,v 1.14.6.3 2001/07/13 09:20:11 kai Exp $
2 *
3 * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000.
4 *
5 * Copyright 1998 by Fritz Elfert (fritz@isdn4linux.de)
6 * Thanks to Friedemann Baitinger and IBM Germany
7 *
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)
11 * any later version.
12 *
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.
17 *
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.
21 *
22 */
23
24 #include "act2000.h"
25 #include "act2000_isa.h"
26 #include "capi.h"
27 #include <linux/init.h>
28
29 static unsigned short act2000_isa_ports[] =
30 {
31 0x0200, 0x0240, 0x0280, 0x02c0, 0x0300, 0x0340, 0x0380,
32 0xcfe0, 0xcfa0, 0xcf60, 0xcf20, 0xcee0, 0xcea0, 0xce60,
33 };
34 #define ISA_NRPORTS (sizeof(act2000_isa_ports)/sizeof(unsigned short))
35
36 static act2000_card *cards = (act2000_card *) NULL;
37
38 /* Parameters to be set by insmod */
39 static int act_bus = 0;
40 static int act_port = -1; /* -1 = Autoprobe */
41 static int act_irq = -1;
42 static char *act_id = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
43
44 MODULE_DESCRIPTION( "Driver for IBM Active 2000 ISDN card");
45 MODULE_AUTHOR( "Fritz Elfert");
46 MODULE_SUPPORTED_DEVICE( "ISDN subsystem");
47 MODULE_PARM_DESC(act_bus, "BusType of first card, 1=ISA, 2=MCA, 3=PCMCIA, currently only ISA");
48 MODULE_PARM_DESC(membase, "Base port address of first card");
49 MODULE_PARM_DESC(act_irq, "IRQ of first card");
50 MODULE_PARM_DESC(act_id, "ID-String of first card");
51 MODULE_PARM(act_bus, "i");
52 MODULE_PARM(act_port, "i");
53 MODULE_PARM(act_irq, "i");
54 MODULE_PARM(act_id, "s");
55
56 static int act2000_addcard(int, int, int, char *);
57
58 static act2000_chan *
59 find_channel(act2000_card *card, int channel)
60 {
61 if ((channel >= 0) && (channel < ACT2000_BCH))
62 return &(card->bch[channel]);
63 printk(KERN_WARNING "act2000: Invalid channel %d\n", channel);
64 return NULL;
65 }
66
67 /*
68 * Free MSN list
69 */
70 static void
71 act2000_clear_msn(act2000_card *card)
72 {
73 struct msn_entry *p = card->msn_list;
74 struct msn_entry *q;
75 unsigned long flags;
76
77 save_flags(flags);
78 cli();
79 card->msn_list = NULL;
80 restore_flags(flags);
81 while (p) {
82 q = p->next;
83 kfree(p);
84 p = q;
85 }
86 }
87
88 /*
89 * Find an MSN entry in the list.
90 * If ia5 != 0, return IA5-encoded EAZ, else
91 * return a bitmask with corresponding bit set.
92 */
93 static __u16
94 act2000_find_msn(act2000_card *card, char *msn, int ia5)
95 {
96 struct msn_entry *p = card->msn_list;
97 __u8 eaz = '0';
98
99 while (p) {
100 if (!strcmp(p->msn, msn)) {
101 eaz = p->eaz;
102 break;
103 }
104 p = p->next;
105 }
106 if (!ia5)
107 return (1 << (eaz - '0'));
108 else
109 return eaz;
110 }
111
112 /*
113 * Find an EAZ entry in the list.
114 * return a string with corresponding msn.
115 */
116 char *
117 act2000_find_eaz(act2000_card *card, char eaz)
118 {
119 struct msn_entry *p = card->msn_list;
120
121 while (p) {
122 if (p->eaz == eaz)
123 return(p->msn);
124 p = p->next;
125 }
126 return("\0");
127 }
128
129 /*
130 * Add or delete an MSN to the MSN list
131 *
132 * First character of msneaz is EAZ, rest is MSN.
133 * If length of eazmsn is 1, delete that entry.
134 */
135 static int
136 act2000_set_msn(act2000_card *card, char *eazmsn)
137 {
138 struct msn_entry *p = card->msn_list;
139 struct msn_entry *q = NULL;
140 unsigned long flags;
141 int i;
142
143 if (!strlen(eazmsn))
144 return 0;
145 if (strlen(eazmsn) > 16)
146 return -EINVAL;
147 for (i = 0; i < strlen(eazmsn); i++)
148 if (!isdigit(eazmsn[i]))
149 return -EINVAL;
150 if (strlen(eazmsn) == 1) {
151 /* Delete a single MSN */
152 while (p) {
153 if (p->eaz == eazmsn[0]) {
154 save_flags(flags);
155 cli();
156 if (q)
157 q->next = p->next;
158 else
159 card->msn_list = p->next;
160 restore_flags(flags);
161 kfree(p);
162 printk(KERN_DEBUG
163 "Mapping for EAZ %c deleted\n",
164 eazmsn[0]);
165 return 0;
166 }
167 q = p;
168 p = p->next;
169 }
170 return 0;
171 }
172 /* Add a single MSN */
173 while (p) {
174 /* Found in list, replace MSN */
175 if (p->eaz == eazmsn[0]) {
176 save_flags(flags);
177 cli();
178 strcpy(p->msn, &eazmsn[1]);
179 restore_flags(flags);
180 printk(KERN_DEBUG
181 "Mapping for EAZ %c changed to %s\n",
182 eazmsn[0],
183 &eazmsn[1]);
184 return 0;
185 }
186 p = p->next;
187 }
188 /* Not found in list, add new entry */
189 p = kmalloc(sizeof(msn_entry), GFP_KERNEL);
190 if (!p)
191 return -ENOMEM;
192 p->eaz = eazmsn[0];
193 strcpy(p->msn, &eazmsn[1]);
194 p->next = card->msn_list;
195 save_flags(flags);
196 cli();
197 card->msn_list = p;
198 restore_flags(flags);
199 printk(KERN_DEBUG
200 "Mapping %c -> %s added\n",
201 eazmsn[0],
202 &eazmsn[1]);
203 return 0;
204 }
205
206 static void
207 act2000_transmit(struct act2000_card *card)
208 {
209 switch (card->bus) {
210 case ACT2000_BUS_ISA:
211 act2000_isa_send(card);
212 break;
213 case ACT2000_BUS_PCMCIA:
214 case ACT2000_BUS_MCA:
215 default:
216 printk(KERN_WARNING
217 "act2000_transmit: Illegal bustype %d\n", card->bus);
218 }
219 }
220
221 static void
222 act2000_receive(struct act2000_card *card)
223 {
224 switch (card->bus) {
225 case ACT2000_BUS_ISA:
226 act2000_isa_receive(card);
227 break;
228 case ACT2000_BUS_PCMCIA:
229 case ACT2000_BUS_MCA:
230 default:
231 printk(KERN_WARNING
232 "act2000_receive: Illegal bustype %d\n", card->bus);
233 }
234 }
235
236 static void
237 act2000_poll(unsigned long data)
238 {
239 act2000_card * card = (act2000_card *)data;
240 unsigned long flags;
241
242 act2000_receive(card);
243 save_flags(flags);
244 cli();
245 mod_timer(&card->ptimer, jiffies+3);
246 restore_flags(flags);
247 }
248
249 static int
250 act2000_command(act2000_card * card, isdn_ctrl * c)
251 {
252 ulong a;
253 act2000_chan *chan;
254 act2000_cdef cdef;
255 isdn_ctrl cmd;
256 char tmp[17];
257 int ret;
258 unsigned long flags;
259
260 switch (c->command) {
261 case ISDN_CMD_IOCTL:
262 memcpy(&a, c->parm.num, sizeof(ulong));
263 switch (c->arg) {
264 case ACT2000_IOCTL_LOADBOOT:
265 switch (card->bus) {
266 case ACT2000_BUS_ISA:
267 ret = act2000_isa_download(card,
268 (act2000_ddef *)a);
269 if (!ret) {
270 card->flags |= ACT2000_FLAGS_LOADED;
271 if (!(card->flags & ACT2000_FLAGS_IVALID)) {
272 card->ptimer.expires = jiffies + 3;
273 card->ptimer.function = act2000_poll;
274 card->ptimer.data = (unsigned long)card;
275 add_timer(&card->ptimer);
276 }
277 actcapi_manufacturer_req_errh(card);
278 }
279 break;
280 default:
281 printk(KERN_WARNING
282 "act2000: Illegal BUS type %d\n",
283 card->bus);
284 ret = -EIO;
285 }
286 return ret;
287 case ACT2000_IOCTL_SETPROTO:
288 card->ptype = a?ISDN_PTYPE_EURO:ISDN_PTYPE_1TR6;
289 if (!(card->flags & ACT2000_FLAGS_RUNNING))
290 return 0;
291 actcapi_manufacturer_req_net(card);
292 return 0;
293 case ACT2000_IOCTL_SETMSN:
294 if ((ret = copy_from_user(tmp, (char *)a, sizeof(tmp))))
295 return ret;
296 if ((ret = act2000_set_msn(card, tmp)))
297 return ret;
298 if (card->flags & ACT2000_FLAGS_RUNNING)
299 return(actcapi_manufacturer_req_msn(card));
300 return 0;
301 case ACT2000_IOCTL_ADDCARD:
302 if ((ret = copy_from_user(&cdef, (char *)a, sizeof(cdef))))
303 return ret;
304 if (act2000_addcard(cdef.bus, cdef.port, cdef.irq, cdef.id))
305 return -EIO;
306 return 0;
307 case ACT2000_IOCTL_TEST:
308 if (!(card->flags & ACT2000_FLAGS_RUNNING))
309 return -ENODEV;
310 return 0;
311 default:
312 return -EINVAL;
313 }
314 break;
315 case ISDN_CMD_DIAL:
316 if (!card->flags & ACT2000_FLAGS_RUNNING)
317 return -ENODEV;
318 if (!(chan = find_channel(card, c->arg & 0x0f)))
319 break;
320 save_flags(flags);
321 cli();
322 if (chan->fsm_state != ACT2000_STATE_NULL) {
323 restore_flags(flags);
324 printk(KERN_WARNING "Dial on channel with state %d\n",
325 chan->fsm_state);
326 return -EBUSY;
327 }
328 if (card->ptype == ISDN_PTYPE_EURO)
329 tmp[0] = act2000_find_msn(card, c->parm.setup.eazmsn, 1);
330 else
331 tmp[0] = c->parm.setup.eazmsn[0];
332 chan->fsm_state = ACT2000_STATE_OCALL;
333 chan->callref = 0xffff;
334 restore_flags(flags);
335 ret = actcapi_connect_req(card, chan, c->parm.setup.phone,
336 tmp[0], c->parm.setup.si1,
337 c->parm.setup.si2);
338 if (ret) {
339 cmd.driver = card->myid;
340 cmd.command = ISDN_STAT_DHUP;
341 cmd.arg &= 0x0f;
342 card->interface.statcallb(&cmd);
343 }
344 return ret;
345 case ISDN_CMD_ACCEPTD:
346 if (!card->flags & ACT2000_FLAGS_RUNNING)
347 return -ENODEV;
348 if (!(chan = find_channel(card, c->arg & 0x0f)))
349 break;
350 if (chan->fsm_state == ACT2000_STATE_ICALL)
351 actcapi_select_b2_protocol_req(card, chan);
352 return 0;
353 case ISDN_CMD_ACCEPTB:
354 if (!card->flags & ACT2000_FLAGS_RUNNING)
355 return -ENODEV;
356 return 0;
357 case ISDN_CMD_HANGUP:
358 if (!card->flags & ACT2000_FLAGS_RUNNING)
359 return -ENODEV;
360 if (!(chan = find_channel(card, c->arg & 0x0f)))
361 break;
362 switch (chan->fsm_state) {
363 case ACT2000_STATE_ICALL:
364 case ACT2000_STATE_BSETUP:
365 actcapi_connect_resp(card, chan, 0x15);
366 break;
367 case ACT2000_STATE_ACTIVE:
368 actcapi_disconnect_b3_req(card, chan);
369 break;
370 }
371 return 0;
372 case ISDN_CMD_SETEAZ:
373 if (!card->flags & ACT2000_FLAGS_RUNNING)
374 return -ENODEV;
375 if (!(chan = find_channel(card, c->arg & 0x0f)))
376 break;
377 if (strlen(c->parm.num)) {
378 if (card->ptype == ISDN_PTYPE_EURO) {
379 chan->eazmask = act2000_find_msn(card, c->parm.num, 0);
380 }
381 if (card->ptype == ISDN_PTYPE_1TR6) {
382 int i;
383 chan->eazmask = 0;
384 for (i = 0; i < strlen(c->parm.num); i++)
385 if (isdigit(c->parm.num[i]))
386 chan->eazmask |= (1 << (c->parm.num[i] - '0'));
387 }
388 } else
389 chan->eazmask = 0x3ff;
390 actcapi_listen_req(card);
391 return 0;
392 case ISDN_CMD_CLREAZ:
393 if (!card->flags & ACT2000_FLAGS_RUNNING)
394 return -ENODEV;
395 if (!(chan = find_channel(card, c->arg & 0x0f)))
396 break;
397 chan->eazmask = 0;
398 actcapi_listen_req(card);
399 return 0;
400 case ISDN_CMD_SETL2:
401 if (!card->flags & ACT2000_FLAGS_RUNNING)
402 return -ENODEV;
403 if (!(chan = find_channel(card, c->arg & 0x0f)))
404 break;
405 chan->l2prot = (c->arg >> 8);
406 return 0;
407 case ISDN_CMD_GETL2:
408 if (!card->flags & ACT2000_FLAGS_RUNNING)
409 return -ENODEV;
410 if (!(chan = find_channel(card, c->arg & 0x0f)))
411 break;
412 return chan->l2prot;
413 case ISDN_CMD_SETL3:
414 if (!card->flags & ACT2000_FLAGS_RUNNING)
415 return -ENODEV;
416 if ((c->arg >> 8) != ISDN_PROTO_L3_TRANS) {
417 printk(KERN_WARNING "L3 protocol unknown\n");
418 return -1;
419 }
420 if (!(chan = find_channel(card, c->arg & 0x0f)))
421 break;
422 chan->l3prot = (c->arg >> 8);
423 return 0;
424 case ISDN_CMD_GETL3:
425 if (!card->flags & ACT2000_FLAGS_RUNNING)
426 return -ENODEV;
427 if (!(chan = find_channel(card, c->arg & 0x0f)))
428 break;
429 return chan->l3prot;
430 case ISDN_CMD_GETEAZ:
431 if (!card->flags & ACT2000_FLAGS_RUNNING)
432 return -ENODEV;
433 printk(KERN_DEBUG "act2000 CMD_GETEAZ not implemented\n");
434 return 0;
435 case ISDN_CMD_SETSIL:
436 if (!card->flags & ACT2000_FLAGS_RUNNING)
437 return -ENODEV;
438 printk(KERN_DEBUG "act2000 CMD_SETSIL not implemented\n");
439 return 0;
440 case ISDN_CMD_GETSIL:
441 if (!card->flags & ACT2000_FLAGS_RUNNING)
442 return -ENODEV;
443 printk(KERN_DEBUG "act2000 CMD_GETSIL not implemented\n");
444 return 0;
445 case ISDN_CMD_LOCK:
446 MOD_INC_USE_COUNT;
447 return 0;
448 case ISDN_CMD_UNLOCK:
449 MOD_DEC_USE_COUNT;
450 return 0;
451 }
452
453 return -EINVAL;
454 }
455
456 static int
457 act2000_sendbuf(act2000_card *card, int channel, int ack, struct sk_buff *skb)
458 {
459 struct sk_buff *xmit_skb;
460 int len;
461 act2000_chan *chan;
462 actcapi_msg *msg;
463
464 if (!(chan = find_channel(card, channel)))
465 return -1;
466 if (chan->fsm_state != ACT2000_STATE_ACTIVE)
467 return -1;
468 len = skb->len;
469 if ((chan->queued + len) >= ACT2000_MAX_QUEUED)
470 return 0;
471 if (!len)
472 return 0;
473 if (skb_headroom(skb) < 19) {
474 printk(KERN_WARNING "act2000_sendbuf: Headroom only %d\n",
475 skb_headroom(skb));
476 xmit_skb = alloc_skb(len + 19, GFP_ATOMIC);
477 if (!xmit_skb) {
478 printk(KERN_WARNING "act2000_sendbuf: Out of memory\n");
479 return 0;
480 }
481 skb_reserve(xmit_skb, 19);
482 memcpy(skb_put(xmit_skb, len), skb->data, len);
483 } else {
484 xmit_skb = skb_clone(skb, GFP_ATOMIC);
485 if (!xmit_skb) {
486 printk(KERN_WARNING "act2000_sendbuf: Out of memory\n");
487 return 0;
488 }
489 }
490 dev_kfree_skb(skb);
491 msg = (actcapi_msg *)skb_push(xmit_skb, 19);
492 msg->hdr.len = 19 + len;
493 msg->hdr.applicationID = 1;
494 msg->hdr.cmd.cmd = 0x86;
495 msg->hdr.cmd.subcmd = 0x00;
496 msg->hdr.msgnum = actcapi_nextsmsg(card);
497 msg->msg.data_b3_req.datalen = len;
498 msg->msg.data_b3_req.blocknr = (msg->hdr.msgnum & 0xff);
499 msg->msg.data_b3_req.fakencci = MAKE_NCCI(chan->plci, 0, chan->ncci);
500 msg->msg.data_b3_req.flags = ack; /* Will be set to 0 on actual sending */
501 actcapi_debug_msg(xmit_skb, 1);
502 chan->queued += len;
503 skb_queue_tail(&card->sndq, xmit_skb);
504 act2000_schedule_tx(card);
505 return len;
506 }
507
508
509 /* Read the Status-replies from the Interface */
510 static int
511 act2000_readstatus(u_char * buf, int len, int user, act2000_card * card)
512 {
513 int count;
514 u_char *p;
515
516 for (p = buf, count = 0; count < len; p++, count++) {
517 if (card->status_buf_read == card->status_buf_write)
518 return count;
519 if (user)
520 put_user(*card->status_buf_read++, p);
521 else
522 *p = *card->status_buf_read++;
523 if (card->status_buf_read > card->status_buf_end)
524 card->status_buf_read = card->status_buf;
525 }
526 return count;
527 }
528
529 /*
530 * Find card with given driverId
531 */
532 static inline act2000_card *
533 act2000_findcard(int driverid)
534 {
535 act2000_card *p = cards;
536
537 while (p) {
538 if (p->myid == driverid)
539 return p;
540 p = p->next;
541 }
542 return (act2000_card *) 0;
543 }
544
545 /*
546 * Wrapper functions for interface to linklevel
547 */
548 static int
549 if_command(isdn_ctrl * c)
550 {
551 act2000_card *card = act2000_findcard(c->driver);
552
553 if (card)
554 return (act2000_command(card, c));
555 printk(KERN_ERR
556 "act2000: if_command %d called with invalid driverId %d!\n",
557 c->command, c->driver);
558 return -ENODEV;
559 }
560
561 static int
562 if_writecmd(const u_char * buf, int len, int user, int id, int channel)
563 {
564 act2000_card *card = act2000_findcard(id);
565
566 if (card) {
567 if (!card->flags & ACT2000_FLAGS_RUNNING)
568 return -ENODEV;
569 return (len);
570 }
571 printk(KERN_ERR
572 "act2000: if_writecmd called with invalid driverId!\n");
573 return -ENODEV;
574 }
575
576 static int
577 if_readstatus(u_char * buf, int len, int user, int id, int channel)
578 {
579 act2000_card *card = act2000_findcard(id);
580
581 if (card) {
582 if (!card->flags & ACT2000_FLAGS_RUNNING)
583 return -ENODEV;
584 return (act2000_readstatus(buf, len, user, card));
585 }
586 printk(KERN_ERR
587 "act2000: if_readstatus called with invalid driverId!\n");
588 return -ENODEV;
589 }
590
591 static int
592 if_sendbuf(int id, int channel, int ack, struct sk_buff *skb)
593 {
594 act2000_card *card = act2000_findcard(id);
595
596 if (card) {
597 if (!card->flags & ACT2000_FLAGS_RUNNING)
598 return -ENODEV;
599 return (act2000_sendbuf(card, channel, ack, skb));
600 }
601 printk(KERN_ERR
602 "act2000: if_sendbuf called with invalid driverId!\n");
603 return -ENODEV;
604 }
605
606
607 /*
608 * Allocate a new card-struct, initialize it
609 * link it into cards-list.
610 */
611 static void
612 act2000_alloccard(int bus, int port, int irq, char *id)
613 {
614 int i;
615 act2000_card *card;
616 if (!(card = (act2000_card *) kmalloc(sizeof(act2000_card), GFP_KERNEL))) {
617 printk(KERN_WARNING
618 "act2000: (%s) Could not allocate card-struct.\n", id);
619 return;
620 }
621 memset((char *) card, 0, sizeof(act2000_card));
622 skb_queue_head_init(&card->sndq);
623 skb_queue_head_init(&card->rcvq);
624 skb_queue_head_init(&card->ackq);
625 card->snd_tq.routine = (void *) (void *) act2000_transmit;
626 card->snd_tq.data = card;
627 card->rcv_tq.routine = (void *) (void *) actcapi_dispatch;
628 card->rcv_tq.data = card;
629 card->poll_tq.routine = (void *) (void *) act2000_receive;
630 card->poll_tq.data = card;
631 init_timer(&card->ptimer);
632 card->interface.channels = ACT2000_BCH;
633 card->interface.maxbufsize = 4000;
634 card->interface.command = if_command;
635 card->interface.writebuf_skb = if_sendbuf;
636 card->interface.writecmd = if_writecmd;
637 card->interface.readstat = if_readstatus;
638 card->interface.features =
639 ISDN_FEATURE_L2_X75I |
640 ISDN_FEATURE_L2_HDLC |
641 ISDN_FEATURE_L3_TRANS |
642 ISDN_FEATURE_P_UNKNOWN;
643 card->interface.hl_hdrlen = 20;
644 card->ptype = ISDN_PTYPE_EURO;
645 strncpy(card->interface.id, id, sizeof(card->interface.id) - 1);
646 for (i=0; i<ACT2000_BCH; i++) {
647 card->bch[i].plci = 0x8000;
648 card->bch[i].ncci = 0x8000;
649 card->bch[i].l2prot = ISDN_PROTO_L2_X75I;
650 card->bch[i].l3prot = ISDN_PROTO_L3_TRANS;
651 }
652 card->myid = -1;
653 card->bus = bus;
654 card->port = port;
655 card->irq = irq;
656 card->next = cards;
657 cards = card;
658 }
659
660 /*
661 * register card at linklevel
662 */
663 static int
664 act2000_registercard(act2000_card * card)
665 {
666 switch (card->bus) {
667 case ACT2000_BUS_ISA:
668 break;
669 case ACT2000_BUS_MCA:
670 case ACT2000_BUS_PCMCIA:
671 default:
672 printk(KERN_WARNING
673 "act2000: Illegal BUS type %d\n",
674 card->bus);
675 return -1;
676 }
677 if (!register_isdn(&card->interface)) {
678 printk(KERN_WARNING
679 "act2000: Unable to register %s\n",
680 card->interface.id);
681 return -1;
682 }
683 card->myid = card->interface.channels;
684 sprintf(card->regname, "act2000-isdn (%s)", card->interface.id);
685 return 0;
686 }
687
688 static void
689 unregister_card(act2000_card * card)
690 {
691 isdn_ctrl cmd;
692
693 cmd.command = ISDN_STAT_UNLOAD;
694 cmd.driver = card->myid;
695 card->interface.statcallb(&cmd);
696 switch (card->bus) {
697 case ACT2000_BUS_ISA:
698 act2000_isa_release(card);
699 break;
700 case ACT2000_BUS_MCA:
701 case ACT2000_BUS_PCMCIA:
702 default:
703 printk(KERN_WARNING
704 "act2000: Invalid BUS type %d\n",
705 card->bus);
706 break;
707 }
708 }
709
710 static int
711 act2000_addcard(int bus, int port, int irq, char *id)
712 {
713 act2000_card *p;
714 act2000_card *q = NULL;
715 int initialized;
716 int added = 0;
717 int failed = 0;
718 int i;
719
720 if (!bus)
721 bus = ACT2000_BUS_ISA;
722 if (port != -1) {
723 /* Port defined, do fixed setup */
724 act2000_alloccard(bus, port, irq, id);
725 } else {
726 /* No port defined, perform autoprobing.
727 * This may result in more than one card detected.
728 */
729 switch (bus) {
730 case ACT2000_BUS_ISA:
731 for (i = 0; i < ISA_NRPORTS; i++)
732 if (act2000_isa_detect(act2000_isa_ports[i])) {
733 printk(KERN_INFO
734 "act2000: Detected ISA card at port 0x%x\n",
735 act2000_isa_ports[i]);
736 act2000_alloccard(bus, act2000_isa_ports[i], irq, id);
737 }
738 break;
739 case ACT2000_BUS_MCA:
740 case ACT2000_BUS_PCMCIA:
741 default:
742 printk(KERN_WARNING
743 "act2000: addcard: Invalid BUS type %d\n",
744 bus);
745 }
746 }
747 if (!cards)
748 return 1;
749 p = cards;
750 while (p) {
751 initialized = 0;
752 if (!p->interface.statcallb) {
753 /* Not yet registered.
754 * Try to register and activate it.
755 */
756 added++;
757 switch (p->bus) {
758 case ACT2000_BUS_ISA:
759 if (act2000_isa_detect(p->port)) {
760 if (act2000_registercard(p))
761 break;
762 if (act2000_isa_config_port(p, p->port)) {
763 printk(KERN_WARNING
764 "act2000: Could not request port 0x%04x\n",
765 p->port);
766 unregister_card(p);
767 p->interface.statcallb = NULL;
768 break;
769 }
770 if (act2000_isa_config_irq(p, p->irq)) {
771 printk(KERN_INFO
772 "act2000: No IRQ available, fallback to polling\n");
773 /* Fall back to polled operation */
774 p->irq = 0;
775 }
776 printk(KERN_INFO
777 "act2000: ISA"
778 "-type card at port "
779 "0x%04x ",
780 p->port);
781 if (p->irq)
782 printk("irq %d\n", p->irq);
783 else
784 printk("polled\n");
785 initialized = 1;
786 }
787 break;
788 case ACT2000_BUS_MCA:
789 case ACT2000_BUS_PCMCIA:
790 default:
791 printk(KERN_WARNING
792 "act2000: addcard: Invalid BUS type %d\n",
793 p->bus);
794 }
795 } else
796 /* Card already initialized */
797 initialized = 1;
798 if (initialized) {
799 /* Init OK, next card ... */
800 q = p;
801 p = p->next;
802 } else {
803 /* Init failed, remove card from list, free memory */
804 printk(KERN_WARNING
805 "act2000: Initialization of %s failed\n",
806 p->interface.id);
807 if (q) {
808 q->next = p->next;
809 kfree(p);
810 p = q->next;
811 } else {
812 cards = p->next;
813 kfree(p);
814 p = cards;
815 }
816 failed++;
817 }
818 }
819 return (added - failed);
820 }
821
822 #define DRIVERNAME "IBM Active 2000 ISDN driver"
823
824 static int __init act2000_init(void)
825 {
826 printk(KERN_INFO "%s\n", DRIVERNAME);
827 if (!cards)
828 act2000_addcard(act_bus, act_port, act_irq, act_id);
829 if (!cards)
830 printk(KERN_INFO "act2000: No cards defined yet\n");
831 /* No symbols to export, hide all symbols */
832 EXPORT_NO_SYMBOLS;
833 return 0;
834 }
835
836 static void __exit act2000_exit(void)
837 {
838 act2000_card *card = cards;
839 act2000_card *last;
840 while (card) {
841 unregister_card(card);
842 del_timer(&card->ptimer);
843 card = card->next;
844 }
845 card = cards;
846 while (card) {
847 last = card;
848 card = card->next;
849 act2000_clear_msn(last);
850 kfree(last);
851 }
852 printk(KERN_INFO "%s unloaded\n", DRIVERNAME);
853 }
854
855 module_init(act2000_init);
856 module_exit(act2000_exit);
857