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