11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PCBIT-D module support
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 1996 Universidade de Lisboa
5475be4d85a274d0961593db41cf85689db1d583cJoe Perches *
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
8475be4d85a274d0961593db41cf85689db1d583cJoe Perches * This software may be used and distributed according to the terms of
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the GNU General Public License, incorporated herein by reference.
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h>
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h>
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/string.h>
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h>
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/skbuff.h>
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/isdnif.h>
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "pcbit.h"
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_DESCRIPTION("ISDN4Linux: Driver for PCBIT-T card");
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_AUTHOR("Pedro Roque Marques");
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL");
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int mem[MAX_PCBIT_CARDS];
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int irq[MAX_PCBIT_CARDS];
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_param_array(mem, int, NULL, 0);
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_param_array(irq, int, NULL, 0);
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int num_boards;
32475be4d85a274d0961593db41cf85689db1d583cJoe Perchesstruct pcbit_dev *dev_pcbit[MAX_PCBIT_CARDS];
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __init pcbit_init(void)
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int board;
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	num_boards = 0;
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
40475be4d85a274d0961593db41cf85689db1d583cJoe Perches	printk(KERN_NOTICE
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	       "PCBIT-D device driver v 0.5-fjpc0 19991204 - "
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	       "Copyright (C) 1996 Universidade de Lisboa\n");
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
44475be4d85a274d0961593db41cf85689db1d583cJoe Perches	if (mem[0] || irq[0])
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{
46475be4d85a274d0961593db41cf85689db1d583cJoe Perches		for (board = 0; board < MAX_PCBIT_CARDS && mem[board] && irq[board]; board++)
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		{
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (!mem[board])
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				mem[board] = 0xD0000;
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (!irq[board])
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				irq[board] = 5;
52475be4d85a274d0961593db41cf85689db1d583cJoe Perches
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (pcbit_init_dev(board, mem[board], irq[board]) == 0)
541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				num_boards++;
55475be4d85a274d0961593db41cf85689db1d583cJoe Perches
56475be4d85a274d0961593db41cf85689db1d583cJoe Perches			else
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			{
58475be4d85a274d0961593db41cf85689db1d583cJoe Perches				printk(KERN_WARNING
59475be4d85a274d0961593db41cf85689db1d583cJoe Perches				       "pcbit_init failed for dev %d",
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				       board + 1);
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				return -EIO;
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Hardcoded default settings detection */
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!num_boards)
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{
70475be4d85a274d0961593db41cf85689db1d583cJoe Perches		printk(KERN_INFO
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		       "Trying to detect board using default settings\n");
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (pcbit_init_dev(0, 0xD0000, 5) == 0)
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			num_boards++;
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		else
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return -EIO;
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __exit pcbit_exit(void)
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef MODULE
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int board;
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (board = 0; board < num_boards; board++)
861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		pcbit_terminate(board);
87475be4d85a274d0961593db41cf85689db1d583cJoe Perches	printk(KERN_NOTICE
881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	       "PCBIT-D module unloaded\n");
891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef MODULE
931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MAX_PARA	(MAX_PCBIT_CARDS * 2)
941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __init pcbit_setup(char *line)
951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i, j, argc;
971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char *str;
98475be4d85a274d0961593db41cf85689db1d583cJoe Perches	int ints[MAX_PARA + 1];
991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	str = get_options(line, MAX_PARA, ints);
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	argc = ints[0];
1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	i = 0;
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	j = 1;
1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
105475be4d85a274d0961593db41cf85689db1d583cJoe Perches	while (argc && (i < MAX_PCBIT_CARDS)) {
1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (argc) {
1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			mem[i]	= ints[j];
1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			j++; argc--;
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
111475be4d85a274d0961593db41cf85689db1d583cJoe Perches
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (argc) {
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			irq[i]	= ints[j];
1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			j++; argc--;
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		i++;
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
119475be4d85a274d0961593db41cf85689db1d583cJoe Perches	return (1);
1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds__setup("pcbit=", pcbit_setup);
1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_init(pcbit_init);
1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_exit(pcbit_exit);
126