1/*
2 * This software may be used and distributed according to the terms
3 * of the GNU General Public License, incorporated herein by reference.
4 *
5 */
6
7#include <linux/config.h>
8#include <linux/init.h>
9#include <linux/fs.h>
10#undef N_DATA
11
12#include <linux/kernel.h>
13
14#include <linux/module.h>
15#include <linux/pci.h>
16#include <linux/ioport.h>
17#include <linux/slab.h>
18#include <linux/errno.h>
19
20#include "adapter.h"
21#include "uxio.h"
22
23
24MODULE_DESCRIPTION("ISDN4Linux: Driver for Eicon Diva Server cards");
25MODULE_AUTHOR("Armin Schindler");
26MODULE_LICENSE("GPL");
27
28#ifdef MODULE
29#include "idi.h"
30void DIVA_DIDD_Write(DESCRIPTOR *, int);
31EXPORT_SYMBOL_NOVERS(DIVA_DIDD_Read);
32EXPORT_SYMBOL_NOVERS(DIVA_DIDD_Write);
33EXPORT_SYMBOL_NOVERS(DivasPrintf);
34#endif
35
36int DivasCardsDiscover(void);
37
38static int __init
39divas_init(void)
40{
41	printk(KERN_DEBUG "DIVA Server Driver - initialising\n");
42
43	printk(KERN_DEBUG "DIVA Server Driver - Version 2.0.16\n");
44
45#if !defined(CONFIG_PCI)
46	printk(KERN_WARNING "CONFIG_PCI is not defined!\n");
47	return -ENODEV;
48#endif
49
50	if (pci_present())
51	{
52		if (DivasCardsDiscover() < 0)
53		{
54			printk(KERN_WARNING "Divas: Not loaded\n");
55			return -ENODEV;
56		}
57	}
58	else
59	{
60		printk(KERN_WARNING "Divas: No PCI bus present\n");
61		return -ENODEV;
62	}
63
64    return 0;
65}
66
67static void __exit
68divas_exit(void)
69{
70	card_t *pCard;
71	word wCardIndex;
72	extern int Divas_major;
73
74	printk(KERN_DEBUG "DIVA Server Driver - unloading\n");
75
76	pCard = DivasCards;
77	for (wCardIndex = 0; wCardIndex < MAX_CARDS; wCardIndex++)
78	{
79		if ((pCard->hw) && (pCard->hw->in_use))
80		{
81
82			(*pCard->card_reset)(pCard);
83
84			UxIsrRemove(pCard->hw, pCard);
85			UxCardHandleFree(pCard->hw);
86
87			if(pCard->e_tbl != NULL)
88			{
89				kfree(pCard->e_tbl);
90			}
91
92
93			if(pCard->hw->card_type == DIA_CARD_TYPE_DIVA_SERVER_B)
94			{
95				release_region(pCard->hw->io_base,0x20);
96				release_region(pCard->hw->reset_base,0x80);
97			}
98
99			// If this is a 4BRI ...
100			if (pCard->hw->card_type == DIA_CARD_TYPE_DIVA_SERVER_Q)
101			{
102				// Skip over the next 3 virtual adapters
103				wCardIndex += 3;
104
105				// But free their handles
106				pCard++;
107				UxCardHandleFree(pCard->hw);
108
109				if(pCard->e_tbl != NULL)
110				{
111					kfree(pCard->e_tbl);
112				}
113
114				pCard++;
115				UxCardHandleFree(pCard->hw);
116
117				if(pCard->e_tbl != NULL)
118				{
119					kfree(pCard->e_tbl);
120				}
121
122				pCard++;
123				UxCardHandleFree(pCard->hw);
124
125				if(pCard->e_tbl != NULL)
126				{
127					kfree(pCard->e_tbl);
128				}
129			}
130		}
131		pCard++;
132	}
133
134	unregister_chrdev(Divas_major, "Divas");
135}
136
137module_init(divas_init);
138module_exit(divas_exit);
139
140