1
2
3
4
5
6
7
8
9
10
11
12
13
14#include <linux/module.h>
15#include <linux/pci.h>
16#include <linux/sched.h>
17#include <linux/tqueue.h>
18#include <linux/interrupt.h>
19#include <linux/init.h>
20#include <asm/io.h>
21
22#include "tpam.h"
23
24
25static int __devinit tpam_probe(struct pci_dev *, const struct pci_device_id *);
26static void __devexit tpam_unregister_card(tpam_card *);
27static void __devexit tpam_remove(struct pci_dev *);
28static int __init tpam_init(void);
29static void __exit tpam_exit(void);
30
31
32static tpam_card *cards;
33
34static int cards_num;
35
36static char *id = "tpam\0\0\0\0\0\0\0\0\0\0\0\0";
37
38MODULE_DESCRIPTION("ISDN4Linux: Driver for TurboPAM ISDN cards");
39MODULE_AUTHOR("Stelian Pop");
40MODULE_LICENSE("GPL");
41MODULE_PARM_DESC(id,"ID-String of the driver");
42MODULE_PARM(id,"s");
43
44
45
46
47
48
49
50
51tpam_card *tpam_findcard(int driverid) {
52 tpam_card *p = cards;
53
54 while (p) {
55 if (p->id == driverid)
56 return p;
57 p = p->next;
58 }
59 return NULL;
60}
61
62
63
64
65
66
67
68
69
70u32 tpam_findchannel(tpam_card *card, u32 ncoid) {
71 int i;
72
73 for (i = 0; i < TPAM_NBCHANNEL; ++i)
74 if (card->channels[i].ncoid == ncoid)
75 return card->channels[i].num;
76 return TPAM_CHANNEL_INVALID;
77}
78
79
80
81
82
83
84
85
86
87static int __devinit tpam_probe(struct pci_dev *dev, const struct pci_device_id *pci_id) {
88 tpam_card *card, *c;
89 int i;
90
91
92 if (!(card = (tpam_card *)kmalloc(sizeof(tpam_card), GFP_KERNEL))) {
93 printk(KERN_ERR "TurboPAM: tpam_register_card: "
94 "kmalloc failed!\n");
95 return -ENOMEM;
96 }
97
98 memset((char *)card, 0, sizeof(tpam_card));
99
100 card->irq = dev->irq;
101 card->lock = SPIN_LOCK_UNLOCKED;
102 sprintf(card->interface.id, "%s%d", id, cards_num);
103
104
105 if (request_irq(card->irq, &tpam_irq, SA_INTERRUPT | SA_SHIRQ,
106 card->interface.id, card)) {
107 printk(KERN_ERR "TurboPAM: tpam_register_card: "
108 "could not request irq %d\n", card->irq);
109 kfree(card);
110 return -EIO;
111 }
112
113
114 if (!(card->bar0 = (unsigned long) ioremap(pci_resource_start(dev, 0),
115 0x800000))) {
116 printk(KERN_ERR "TurboPAM: tpam_register_card: "
117 "unable to remap bar0\n");
118 free_irq(card->irq, card);
119 kfree(card);
120 return -EIO;
121 }
122
123
124 readl(card->bar0 + TPAM_RESETPAM_REGISTER);
125
126
127 copy_to_pam_dword(card, (void *)0x01800008, 0x00000030);
128 copy_to_pam_dword(card, (void *)0x01800010, 0x00000030);
129 copy_to_pam_dword(card, (void *)0x01800014, 0x42240822);
130 copy_to_pam_dword(card, (void *)0x01800018, 0x07114000);
131 copy_to_pam_dword(card, (void *)0x0180001c, 0x00000400);
132 copy_to_pam_dword(card, (void *)0x01840070, 0x00000010);
133
134
135 card->interface.channels = TPAM_NBCHANNEL;
136 card->interface.maxbufsize = TPAM_MAXBUFSIZE;
137 card->interface.features =
138 ISDN_FEATURE_P_EURO |
139 ISDN_FEATURE_L2_HDLC |
140 ISDN_FEATURE_L2_MODEM |
141 ISDN_FEATURE_L3_TRANS;
142 card->interface.hl_hdrlen = 0;
143 card->interface.command = tpam_command;
144 card->interface.writebuf_skb = tpam_writebuf_skb;
145 card->interface.writecmd = NULL;
146 card->interface.readstat = NULL;
147
148
149 if (!register_isdn(&card->interface)) {
150 printk(KERN_ERR "TurboPAM: tpam_register_card: "
151 "unable to register %s\n", card->interface.id);
152 free_irq(card->irq, card);
153 iounmap((void *)card->bar0);
154 kfree(card);
155 return -EIO;
156 }
157 card->id = card->interface.channels;
158
159
160 for (i = 0; i < TPAM_NBCHANNEL; ++i) {
161 card->channels[i].num = i;
162 card->channels[i].card = card;
163 card->channels[i].ncoid = TPAM_NCOID_INVALID;
164 card->channels[i].hdlc = 0;
165 card->channels[i].realhdlc = 0;
166 card->channels[i].hdlcshift = 0;
167 skb_queue_head_init(&card->channels[i].sendq);
168 }
169
170
171 card->channels_used = 0;
172 card->channels_tested = 0;
173 card->running = 0;
174 card->busy = 0;
175 card->roundrobin = 0;
176 card->loopmode = 0;
177 skb_queue_head_init(&card->sendq);
178 skb_queue_head_init(&card->recvq);
179 card->recv_tq.routine = (void *) (void *) tpam_recv_tq;
180 card->recv_tq.data = card;
181 card->send_tq.routine = (void *) (void *) tpam_send_tq;
182 card->send_tq.data = card;
183
184
185 card->next = NULL;
186 if (cards) {
187 c = cards;
188 while (c->next)
189 c = c->next;
190 c->next = card;
191 }
192 else
193 cards = card;
194
195 ++cards_num;
196 pci_set_drvdata(dev, card);
197
198 return 0;
199}
200
201
202
203
204
205
206static void __devexit tpam_unregister_card(tpam_card *card) {
207 isdn_ctrl cmd;
208
209
210 cmd.command = ISDN_STAT_UNLOAD;
211 cmd.driver = card->id;
212 (* card->interface.statcallb)(&cmd);
213
214
215 free_irq(card->irq, card);
216
217
218 iounmap((void *)card->bar0);
219}
220
221
222
223
224static void __devexit tpam_remove(struct pci_dev *pcidev) {
225 tpam_card *card = pci_get_drvdata(pcidev);
226 tpam_card *c;
227
228
229 if (card == cards)
230 cards = cards->next;
231 else {
232 c = cards;
233 while (c->next != card)
234 c = c->next;
235 c->next = c->next->next;
236 }
237
238
239 tpam_unregister_card(card);
240
241
242 kfree(card);
243}
244
245static struct pci_device_id tpam_pci_tbl[] __devinitdata = {
246 { PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_TURBOPAM,
247 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
248 { }
249};
250
251MODULE_DEVICE_TABLE(pci, tpam_pci_tbl);
252
253static struct pci_driver tpam_driver = {
254 name: "tpam",
255 id_table: tpam_pci_tbl,
256 probe: tpam_probe,
257 remove: __devexit_p(tpam_remove),
258};
259
260static int __init tpam_init(void) {
261 int ret;
262
263 ret = pci_module_init(&tpam_driver);
264 if (ret)
265 return ret;
266 printk(KERN_INFO "TurboPAM: %d card%s found, driver loaded.\n",
267 cards_num, (cards_num > 1) ? "s" : "");
268 return 0;
269}
270
271static void __exit tpam_exit(void) {
272 pci_unregister_driver(&tpam_driver);
273 printk(KERN_INFO "TurboPAM: driver unloaded\n");
274}
275
276
277module_init(tpam_init);
278module_exit(tpam_exit);
279
280