aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn/hardware/avm
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/isdn/hardware/avm
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'drivers/isdn/hardware/avm')
-rw-r--r--drivers/isdn/hardware/avm/Kconfig66
-rw-r--r--drivers/isdn/hardware/avm/Makefile11
-rw-r--r--drivers/isdn/hardware/avm/avm_cs.c510
-rw-r--r--drivers/isdn/hardware/avm/avmcard.h585
-rw-r--r--drivers/isdn/hardware/avm/b1.c814
-rw-r--r--drivers/isdn/hardware/avm/b1dma.c980
-rw-r--r--drivers/isdn/hardware/avm/b1isa.c245
-rw-r--r--drivers/isdn/hardware/avm/b1pci.c417
-rw-r--r--drivers/isdn/hardware/avm/b1pcmcia.c224
-rw-r--r--drivers/isdn/hardware/avm/c4.c1310
-rw-r--r--drivers/isdn/hardware/avm/t1isa.c596
-rw-r--r--drivers/isdn/hardware/avm/t1pci.c260
12 files changed, 6018 insertions, 0 deletions
diff --git a/drivers/isdn/hardware/avm/Kconfig b/drivers/isdn/hardware/avm/Kconfig
new file mode 100644
index 000000000000..29a32a8830c0
--- /dev/null
+++ b/drivers/isdn/hardware/avm/Kconfig
@@ -0,0 +1,66 @@
1#
2# ISDN AVM drivers
3#
4
5menu "Active AVM cards"
6 depends on NET && ISDN && ISDN_CAPI!=n
7
8config CAPI_AVM
9 bool "Support AVM cards"
10 help
11 Enable support for AVM active ISDN cards.
12
13config ISDN_DRV_AVMB1_B1ISA
14 tristate "AVM B1 ISA support"
15 depends on CAPI_AVM && ISDN_CAPI && ISA
16 help
17 Enable support for the ISA version of the AVM B1 card.
18
19config ISDN_DRV_AVMB1_B1PCI
20 tristate "AVM B1 PCI support"
21 depends on CAPI_AVM && ISDN_CAPI && PCI
22 help
23 Enable support for the PCI version of the AVM B1 card.
24
25config ISDN_DRV_AVMB1_B1PCIV4
26 bool "AVM B1 PCI V4 support"
27 depends on ISDN_DRV_AVMB1_B1PCI
28 help
29 Enable support for the V4 version of AVM B1 PCI card.
30
31config ISDN_DRV_AVMB1_T1ISA
32 tristate "AVM T1/T1-B ISA support"
33 depends on CAPI_AVM && ISDN_CAPI && ISA
34 help
35 Enable support for the AVM T1 T1B card.
36 Note: This is a PRI card and handle 30 B-channels.
37
38config ISDN_DRV_AVMB1_B1PCMCIA
39 tristate "AVM B1/M1/M2 PCMCIA support"
40 depends on CAPI_AVM && ISDN_CAPI
41 help
42 Enable support for the PCMCIA version of the AVM B1 card.
43
44config ISDN_DRV_AVMB1_AVM_CS
45 tristate "AVM B1/M1/M2 PCMCIA cs module"
46 depends on ISDN_DRV_AVMB1_B1PCMCIA && PCMCIA
47 help
48 Enable the PCMCIA client driver for the AVM B1/M1/M2
49 PCMCIA cards.
50
51config ISDN_DRV_AVMB1_T1PCI
52 tristate "AVM T1/T1-B PCI support"
53 depends on CAPI_AVM && ISDN_CAPI && PCI
54 help
55 Enable support for the AVM T1 T1B card.
56 Note: This is a PRI card and handle 30 B-channels.
57
58config ISDN_DRV_AVMB1_C4
59 tristate "AVM C4/C2 support"
60 depends on CAPI_AVM && ISDN_CAPI && PCI
61 help
62 Enable support for the AVM C4/C2 PCI cards.
63 These cards handle 4/2 BRI ISDN lines (8/4 channels).
64
65endmenu
66
diff --git a/drivers/isdn/hardware/avm/Makefile b/drivers/isdn/hardware/avm/Makefile
new file mode 100644
index 000000000000..b540e8f2efb6
--- /dev/null
+++ b/drivers/isdn/hardware/avm/Makefile
@@ -0,0 +1,11 @@
1# Makefile for the AVM ISDN device drivers
2
3# Each configuration option enables a list of files.
4
5obj-$(CONFIG_ISDN_DRV_AVMB1_B1ISA) += b1isa.o b1.o
6obj-$(CONFIG_ISDN_DRV_AVMB1_B1PCI) += b1pci.o b1.o b1dma.o
7obj-$(CONFIG_ISDN_DRV_AVMB1_B1PCMCIA) += b1pcmcia.o b1.o
8obj-$(CONFIG_ISDN_DRV_AVMB1_AVM_CS) += avm_cs.o
9obj-$(CONFIG_ISDN_DRV_AVMB1_T1ISA) += t1isa.o b1.o
10obj-$(CONFIG_ISDN_DRV_AVMB1_T1PCI) += t1pci.o b1.o b1dma.o
11obj-$(CONFIG_ISDN_DRV_AVMB1_C4) += c4.o b1.o
diff --git a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c
new file mode 100644
index 000000000000..dc00c85e3e35
--- /dev/null
+++ b/drivers/isdn/hardware/avm/avm_cs.c
@@ -0,0 +1,510 @@
1/* $Id: avm_cs.c,v 1.4.6.3 2001/09/23 22:24:33 kai Exp $
2 *
3 * A PCMCIA client driver for AVM B1/M1/M2
4 *
5 * Copyright 1999 by Carsten Paeth <calle@calle.de>
6 *
7 * This software may be used and distributed according to the terms
8 * of the GNU General Public License, incorporated herein by reference.
9 *
10 */
11
12#include <linux/module.h>
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/sched.h>
16#include <linux/ptrace.h>
17#include <linux/slab.h>
18#include <linux/string.h>
19#include <linux/tty.h>
20#include <linux/serial.h>
21#include <linux/major.h>
22#include <asm/io.h>
23#include <asm/system.h>
24
25#include <pcmcia/version.h>
26#include <pcmcia/cs_types.h>
27#include <pcmcia/cs.h>
28#include <pcmcia/cistpl.h>
29#include <pcmcia/ciscode.h>
30#include <pcmcia/ds.h>
31#include <pcmcia/cisreg.h>
32
33#include <linux/skbuff.h>
34#include <linux/capi.h>
35#include <linux/b1lli.h>
36#include <linux/b1pcmcia.h>
37
38/*====================================================================*/
39
40MODULE_DESCRIPTION("CAPI4Linux: PCMCIA client driver for AVM B1/M1/M2");
41MODULE_AUTHOR("Carsten Paeth");
42MODULE_LICENSE("GPL");
43
44/*====================================================================*/
45
46/*
47 The event() function is this driver's Card Services event handler.
48 It will be called by Card Services when an appropriate card status
49 event is received. The config() and release() entry points are
50 used to configure or release a socket, in response to card insertion
51 and ejection events. They are invoked from the skeleton event
52 handler.
53*/
54
55static void avmcs_config(dev_link_t *link);
56static void avmcs_release(dev_link_t *link);
57static int avmcs_event(event_t event, int priority,
58 event_callback_args_t *args);
59
60/*
61 The attach() and detach() entry points are used to create and destroy
62 "instances" of the driver, where each instance represents everything
63 needed to manage one actual PCMCIA card.
64*/
65
66static dev_link_t *avmcs_attach(void);
67static void avmcs_detach(dev_link_t *);
68
69/*
70 The dev_info variable is the "key" that is used to match up this
71 device driver with appropriate cards, through the card configuration
72 database.
73*/
74
75static dev_info_t dev_info = "avm_cs";
76
77/*
78 A linked list of "instances" of the skeleton device. Each actual
79 PCMCIA card corresponds to one device instance, and is described
80 by one dev_link_t structure (defined in ds.h).
81
82 You may not want to use a linked list for this -- for example, the
83 memory card driver uses an array of dev_link_t pointers, where minor
84 device numbers are used to derive the corresponding array index.
85*/
86
87static dev_link_t *dev_list = NULL;
88
89/*
90 A dev_link_t structure has fields for most things that are needed
91 to keep track of a socket, but there will usually be some device
92 specific information that also needs to be kept track of. The
93 'priv' pointer in a dev_link_t structure can be used to point to
94 a device-specific private data structure, like this.
95
96 A driver needs to provide a dev_node_t structure for each device
97 on a card. In some cases, there is only one device per card (for
98 example, ethernet cards, modems). In other cases, there may be
99 many actual or logical devices (SCSI adapters, memory cards with
100 multiple partitions). The dev_node_t structures need to be kept
101 in a linked list starting at the 'dev' field of a dev_link_t
102 structure. We allocate them in the card's private data structure,
103 because they generally can't be allocated dynamically.
104*/
105
106typedef struct local_info_t {
107 dev_node_t node;
108} local_info_t;
109
110/*======================================================================
111
112 avmcs_attach() creates an "instance" of the driver, allocating
113 local data structures for one device. The device is registered
114 with Card Services.
115
116 The dev_link structure is initialized, but we don't actually
117 configure the card at this point -- we wait until we receive a
118 card insertion event.
119
120======================================================================*/
121
122static dev_link_t *avmcs_attach(void)
123{
124 client_reg_t client_reg;
125 dev_link_t *link;
126 local_info_t *local;
127 int ret;
128
129 /* Initialize the dev_link_t structure */
130 link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
131 if (!link)
132 goto err;
133 memset(link, 0, sizeof(struct dev_link_t));
134
135 /* The io structure describes IO port mapping */
136 link->io.NumPorts1 = 16;
137 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
138 link->io.NumPorts2 = 0;
139
140 /* Interrupt setup */
141 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
142 link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
143
144 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
145
146 /* General socket configuration */
147 link->conf.Attributes = CONF_ENABLE_IRQ;
148 link->conf.Vcc = 50;
149 link->conf.IntType = INT_MEMORY_AND_IO;
150 link->conf.ConfigIndex = 1;
151 link->conf.Present = PRESENT_OPTION;
152
153 /* Allocate space for private device-specific data */
154 local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
155 if (!local)
156 goto err_kfree;
157 memset(local, 0, sizeof(local_info_t));
158 link->priv = local;
159
160 /* Register with Card Services */
161 link->next = dev_list;
162 dev_list = link;
163 client_reg.dev_info = &dev_info;
164 client_reg.EventMask =
165 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
166 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
167 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
168 client_reg.event_handler = &avmcs_event;
169 client_reg.Version = 0x0210;
170 client_reg.event_callback_args.client_data = link;
171 ret = pcmcia_register_client(&link->handle, &client_reg);
172 if (ret != 0) {
173 cs_error(link->handle, RegisterClient, ret);
174 avmcs_detach(link);
175 goto err;
176 }
177 return link;
178
179 err_kfree:
180 kfree(link);
181 err:
182 return NULL;
183} /* avmcs_attach */
184
185/*======================================================================
186
187 This deletes a driver "instance". The device is de-registered
188 with Card Services. If it has been released, all local data
189 structures are freed. Otherwise, the structures will be freed
190 when the device is released.
191
192======================================================================*/
193
194static void avmcs_detach(dev_link_t *link)
195{
196 dev_link_t **linkp;
197
198 /* Locate device structure */
199 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
200 if (*linkp == link) break;
201 if (*linkp == NULL)
202 return;
203
204 /*
205 If the device is currently configured and active, we won't
206 actually delete it yet. Instead, it is marked so that when
207 the release() function is called, that will trigger a proper
208 detach().
209 */
210 if (link->state & DEV_CONFIG) {
211 link->state |= DEV_STALE_LINK;
212 return;
213 }
214
215 /* Break the link with Card Services */
216 if (link->handle)
217 pcmcia_deregister_client(link->handle);
218
219 /* Unlink device structure, free pieces */
220 *linkp = link->next;
221 if (link->priv) {
222 kfree(link->priv);
223 }
224 kfree(link);
225
226} /* avmcs_detach */
227
228/*======================================================================
229
230 avmcs_config() is scheduled to run after a CARD_INSERTION event
231 is received, to configure the PCMCIA socket, and to make the
232 ethernet device available to the system.
233
234======================================================================*/
235
236static int get_tuple(client_handle_t handle, tuple_t *tuple,
237 cisparse_t *parse)
238{
239 int i = pcmcia_get_tuple_data(handle, tuple);
240 if (i != CS_SUCCESS) return i;
241 return pcmcia_parse_tuple(handle, tuple, parse);
242}
243
244static int first_tuple(client_handle_t handle, tuple_t *tuple,
245 cisparse_t *parse)
246{
247 int i = pcmcia_get_first_tuple(handle, tuple);
248 if (i != CS_SUCCESS) return i;
249 return get_tuple(handle, tuple, parse);
250}
251
252static int next_tuple(client_handle_t handle, tuple_t *tuple,
253 cisparse_t *parse)
254{
255 int i = pcmcia_get_next_tuple(handle, tuple);
256 if (i != CS_SUCCESS) return i;
257 return get_tuple(handle, tuple, parse);
258}
259
260static void avmcs_config(dev_link_t *link)
261{
262 client_handle_t handle;
263 tuple_t tuple;
264 cisparse_t parse;
265 cistpl_cftable_entry_t *cf = &parse.cftable_entry;
266 local_info_t *dev;
267 int i;
268 u_char buf[64];
269 char devname[128];
270 int cardtype;
271 int (*addcard)(unsigned int port, unsigned irq);
272
273 handle = link->handle;
274 dev = link->priv;
275
276 /*
277 This reads the card's CONFIG tuple to find its configuration
278 registers.
279 */
280 do {
281 tuple.DesiredTuple = CISTPL_CONFIG;
282 i = pcmcia_get_first_tuple(handle, &tuple);
283 if (i != CS_SUCCESS) break;
284 tuple.TupleData = buf;
285 tuple.TupleDataMax = 64;
286 tuple.TupleOffset = 0;
287 i = pcmcia_get_tuple_data(handle, &tuple);
288 if (i != CS_SUCCESS) break;
289 i = pcmcia_parse_tuple(handle, &tuple, &parse);
290 if (i != CS_SUCCESS) break;
291 link->conf.ConfigBase = parse.config.base;
292 } while (0);
293 if (i != CS_SUCCESS) {
294 cs_error(link->handle, ParseTuple, i);
295 link->state &= ~DEV_CONFIG_PENDING;
296 return;
297 }
298
299 /* Configure card */
300 link->state |= DEV_CONFIG;
301
302 do {
303
304 tuple.Attributes = 0;
305 tuple.TupleData = buf;
306 tuple.TupleDataMax = 254;
307 tuple.TupleOffset = 0;
308 tuple.DesiredTuple = CISTPL_VERS_1;
309
310 devname[0] = 0;
311 if( !first_tuple(handle, &tuple, &parse) && parse.version_1.ns > 1 ) {
312 strlcpy(devname,parse.version_1.str + parse.version_1.ofs[1],
313 sizeof(devname));
314 }
315 /*
316 * find IO port
317 */
318 tuple.TupleData = (cisdata_t *)buf;
319 tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
320 tuple.Attributes = 0;
321 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
322 i = first_tuple(handle, &tuple, &parse);
323 while (i == CS_SUCCESS) {
324 if (cf->io.nwin > 0) {
325 link->conf.ConfigIndex = cf->index;
326 link->io.BasePort1 = cf->io.win[0].base;
327 link->io.NumPorts1 = cf->io.win[0].len;
328 link->io.NumPorts2 = 0;
329 printk(KERN_INFO "avm_cs: testing i/o %#x-%#x\n",
330 link->io.BasePort1,
331 link->io.BasePort1+link->io.NumPorts1-1);
332 i = pcmcia_request_io(link->handle, &link->io);
333 if (i == CS_SUCCESS) goto found_port;
334 }
335 i = next_tuple(handle, &tuple, &parse);
336 }
337
338found_port:
339 if (i != CS_SUCCESS) {
340 cs_error(link->handle, RequestIO, i);
341 break;
342 }
343
344 /*
345 * allocate an interrupt line
346 */
347 i = pcmcia_request_irq(link->handle, &link->irq);
348 if (i != CS_SUCCESS) {
349 cs_error(link->handle, RequestIRQ, i);
350 pcmcia_release_io(link->handle, &link->io);
351 break;
352 }
353
354 /*
355 * configure the PCMCIA socket
356 */
357 i = pcmcia_request_configuration(link->handle, &link->conf);
358 if (i != CS_SUCCESS) {
359 cs_error(link->handle, RequestConfiguration, i);
360 pcmcia_release_io(link->handle, &link->io);
361 pcmcia_release_irq(link->handle, &link->irq);
362 break;
363 }
364
365 } while (0);
366
367 /* At this point, the dev_node_t structure(s) should be
368 initialized and arranged in a linked list at link->dev. */
369
370 if (devname[0]) {
371 char *s = strrchr(devname, ' ');
372 if (!s)
373 s = devname;
374 else s++;
375 strcpy(dev->node.dev_name, s);
376 if (strcmp("M1", s) == 0) {
377 cardtype = AVM_CARDTYPE_M1;
378 } else if (strcmp("M2", s) == 0) {
379 cardtype = AVM_CARDTYPE_M2;
380 } else {
381 cardtype = AVM_CARDTYPE_B1;
382 }
383 } else {
384 strcpy(dev->node.dev_name, "b1");
385 cardtype = AVM_CARDTYPE_B1;
386 }
387
388 dev->node.major = 64;
389 dev->node.minor = 0;
390 link->dev = &dev->node;
391
392 link->state &= ~DEV_CONFIG_PENDING;
393 /* If any step failed, release any partially configured state */
394 if (i != 0) {
395 avmcs_release(link);
396 return;
397 }
398
399
400 switch (cardtype) {
401 case AVM_CARDTYPE_M1: addcard = b1pcmcia_addcard_m1; break;
402 case AVM_CARDTYPE_M2: addcard = b1pcmcia_addcard_m2; break;
403 default:
404 case AVM_CARDTYPE_B1: addcard = b1pcmcia_addcard_b1; break;
405 }
406 if ((i = (*addcard)(link->io.BasePort1, link->irq.AssignedIRQ)) < 0) {
407 printk(KERN_ERR "avm_cs: failed to add AVM-%s-Controller at i/o %#x, irq %d\n",
408 dev->node.dev_name, link->io.BasePort1, link->irq.AssignedIRQ);
409 avmcs_release(link);
410 return;
411 }
412 dev->node.minor = i;
413
414} /* avmcs_config */
415
416/*======================================================================
417
418 After a card is removed, avmcs_release() will unregister the net
419 device, and release the PCMCIA configuration. If the device is
420 still open, this will be postponed until it is closed.
421
422======================================================================*/
423
424static void avmcs_release(dev_link_t *link)
425{
426 b1pcmcia_delcard(link->io.BasePort1, link->irq.AssignedIRQ);
427
428 /* Unlink the device chain */
429 link->dev = NULL;
430
431 /* Don't bother checking to see if these succeed or not */
432 pcmcia_release_configuration(link->handle);
433 pcmcia_release_io(link->handle, &link->io);
434 pcmcia_release_irq(link->handle, &link->irq);
435 link->state &= ~DEV_CONFIG;
436
437 if (link->state & DEV_STALE_LINK)
438 avmcs_detach(link);
439
440} /* avmcs_release */
441
442/*======================================================================
443
444 The card status event handler. Mostly, this schedules other
445 stuff to run after an event is received. A CARD_REMOVAL event
446 also sets some flags to discourage the net drivers from trying
447 to talk to the card any more.
448
449 When a CARD_REMOVAL event is received, we immediately set a flag
450 to block future accesses to this device. All the functions that
451 actually access the device should check this flag to make sure
452 the card is still present.
453
454======================================================================*/
455
456static int avmcs_event(event_t event, int priority,
457 event_callback_args_t *args)
458{
459 dev_link_t *link = args->client_data;
460
461 switch (event) {
462 case CS_EVENT_CARD_REMOVAL:
463 link->state &= ~DEV_PRESENT;
464 if (link->state & DEV_CONFIG)
465 avmcs_release(link);
466 break;
467 case CS_EVENT_CARD_INSERTION:
468 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
469 avmcs_config(link);
470 break;
471 case CS_EVENT_PM_SUSPEND:
472 link->state |= DEV_SUSPEND;
473 /* Fall through... */
474 case CS_EVENT_RESET_PHYSICAL:
475 if (link->state & DEV_CONFIG)
476 pcmcia_release_configuration(link->handle);
477 break;
478 case CS_EVENT_PM_RESUME:
479 link->state &= ~DEV_SUSPEND;
480 /* Fall through... */
481 case CS_EVENT_CARD_RESET:
482 if (link->state & DEV_CONFIG)
483 pcmcia_request_configuration(link->handle, &link->conf);
484 break;
485 }
486 return 0;
487} /* avmcs_event */
488
489static struct pcmcia_driver avmcs_driver = {
490 .owner = THIS_MODULE,
491 .drv = {
492 .name = "avm_cs",
493 },
494 .attach = avmcs_attach,
495 .detach = avmcs_detach,
496};
497
498static int __init avmcs_init(void)
499{
500 return pcmcia_register_driver(&avmcs_driver);
501}
502
503static void __exit avmcs_exit(void)
504{
505 pcmcia_unregister_driver(&avmcs_driver);
506 BUG_ON(dev_list != NULL);
507}
508
509module_init(avmcs_init);
510module_exit(avmcs_exit);
diff --git a/drivers/isdn/hardware/avm/avmcard.h b/drivers/isdn/hardware/avm/avmcard.h
new file mode 100644
index 000000000000..296d6a6f749f
--- /dev/null
+++ b/drivers/isdn/hardware/avm/avmcard.h
@@ -0,0 +1,585 @@
1/* $Id: avmcard.h,v 1.1.4.1.2.1 2001/12/21 15:00:17 kai Exp $
2 *
3 * Copyright 1999 by Carsten Paeth <calle@calle.de>
4 *
5 * This software may be used and distributed according to the terms
6 * of the GNU General Public License, incorporated herein by reference.
7 *
8 */
9
10#ifndef _AVMCARD_H_
11#define _AVMCARD_H_
12
13#include <linux/spinlock.h>
14#include <linux/list.h>
15#include <linux/interrupt.h>
16
17#define AVMB1_PORTLEN 0x1f
18#define AVM_MAXVERSION 8
19#define AVM_NCCI_PER_CHANNEL 4
20
21/*
22 * Versions
23 */
24
25#define VER_DRIVER 0
26#define VER_CARDTYPE 1
27#define VER_HWID 2
28#define VER_SERIAL 3
29#define VER_OPTION 4
30#define VER_PROTO 5
31#define VER_PROFILE 6
32#define VER_CAPI 7
33
34enum avmcardtype {
35 avm_b1isa,
36 avm_b1pci,
37 avm_b1pcmcia,
38 avm_m1,
39 avm_m2,
40 avm_t1isa,
41 avm_t1pci,
42 avm_c4,
43 avm_c2
44};
45
46typedef struct avmcard_dmabuf {
47 long size;
48 u8 *dmabuf;
49 dma_addr_t dmaaddr;
50} avmcard_dmabuf;
51
52typedef struct avmcard_dmainfo {
53 u32 recvlen;
54 avmcard_dmabuf recvbuf;
55
56 avmcard_dmabuf sendbuf;
57 struct sk_buff_head send_queue;
58
59 struct pci_dev *pcidev;
60} avmcard_dmainfo;
61
62typedef struct avmctrl_info {
63 char cardname[32];
64
65 int versionlen;
66 char versionbuf[1024];
67 char *version[AVM_MAXVERSION];
68
69 char infobuf[128]; /* for function procinfo */
70
71 struct avmcard *card;
72 struct capi_ctr capi_ctrl;
73
74 struct list_head ncci_head;
75} avmctrl_info;
76
77typedef struct avmcard {
78 char name[32];
79
80 spinlock_t lock;
81 unsigned int port;
82 unsigned irq;
83 unsigned long membase;
84 enum avmcardtype cardtype;
85 unsigned char revision;
86 unsigned char class;
87 int cardnr; /* for t1isa */
88
89 char msgbuf[128]; /* capimsg msg part */
90 char databuf[2048]; /* capimsg data part */
91
92 void __iomem *mbase;
93 volatile u32 csr;
94 avmcard_dmainfo *dma;
95
96 struct avmctrl_info *ctrlinfo;
97
98 u_int nr_controllers;
99 u_int nlogcontr;
100 struct list_head list;
101} avmcard;
102
103extern int b1_irq_table[16];
104
105/*
106 * LLI Messages to the ISDN-ControllerISDN Controller
107 */
108
109#define SEND_POLL 0x72 /*
110 * after load <- RECEIVE_POLL
111 */
112#define SEND_INIT 0x11 /*
113 * first message <- RECEIVE_INIT
114 * int32 NumApplications int32
115 * NumNCCIs int32 BoardNumber
116 */
117#define SEND_REGISTER 0x12 /*
118 * register an application int32
119 * ApplIDId int32 NumMessages
120 * int32 NumB3Connections int32
121 * NumB3Blocks int32 B3Size
122 *
123 * AnzB3Connection != 0 &&
124 * AnzB3Blocks >= 1 && B3Size >= 1
125 */
126#define SEND_RELEASE 0x14 /*
127 * deregister an application int32
128 * ApplID
129 */
130#define SEND_MESSAGE 0x15 /*
131 * send capi-message int32 length
132 * capi-data ...
133 */
134#define SEND_DATA_B3_REQ 0x13 /*
135 * send capi-data-message int32
136 * MsgLength capi-data ... int32
137 * B3Length data ....
138 */
139
140#define SEND_CONFIG 0x21 /*
141 */
142
143#define SEND_POLLACK 0x73 /* T1 Watchdog */
144
145/*
146 * LLI Messages from the ISDN-ControllerISDN Controller
147 */
148
149#define RECEIVE_POLL 0x32 /*
150 * <- after SEND_POLL
151 */
152#define RECEIVE_INIT 0x27 /*
153 * <- after SEND_INIT int32 length
154 * byte total length b1struct board
155 * driver revision b1struct card
156 * type b1struct reserved b1struct
157 * serial number b1struct driver
158 * capability b1struct d-channel
159 * protocol b1struct CAPI-2.0
160 * profile b1struct capi version
161 */
162#define RECEIVE_MESSAGE 0x21 /*
163 * <- after SEND_MESSAGE int32
164 * AppllID int32 Length capi-data
165 * ....
166 */
167#define RECEIVE_DATA_B3_IND 0x22 /*
168 * received data int32 AppllID
169 * int32 Length capi-data ...
170 * int32 B3Length data ...
171 */
172#define RECEIVE_START 0x23 /*
173 * Handshake
174 */
175#define RECEIVE_STOP 0x24 /*
176 * Handshake
177 */
178#define RECEIVE_NEW_NCCI 0x25 /*
179 * int32 AppllID int32 NCCI int32
180 * WindowSize
181 */
182#define RECEIVE_FREE_NCCI 0x26 /*
183 * int32 AppllID int32 NCCI
184 */
185#define RECEIVE_RELEASE 0x26 /*
186 * int32 AppllID int32 0xffffffff
187 */
188#define RECEIVE_TASK_READY 0x31 /*
189 * int32 tasknr
190 * int32 Length Taskname ...
191 */
192#define RECEIVE_DEBUGMSG 0x71 /*
193 * int32 Length message
194 *
195 */
196#define RECEIVE_POLLDWORD 0x75 /* t1pci in dword mode */
197
198#define WRITE_REGISTER 0x00
199#define READ_REGISTER 0x01
200
201/*
202 * port offsets
203 */
204
205#define B1_READ 0x00
206#define B1_WRITE 0x01
207#define B1_INSTAT 0x02
208#define B1_OUTSTAT 0x03
209#define B1_ANALYSE 0x04
210#define B1_REVISION 0x05
211#define B1_RESET 0x10
212
213
214#define B1_STAT0(cardtype) ((cardtype) == avm_m1 ? 0x81200000l : 0x80A00000l)
215#define B1_STAT1(cardtype) (0x80E00000l)
216
217/* ---------------------------------------------------------------- */
218
219static inline unsigned char b1outp(unsigned int base,
220 unsigned short offset,
221 unsigned char value)
222{
223 outb(value, base + offset);
224 return inb(base + B1_ANALYSE);
225}
226
227
228static inline int b1_rx_full(unsigned int base)
229{
230 return inb(base + B1_INSTAT) & 0x1;
231}
232
233static inline unsigned char b1_get_byte(unsigned int base)
234{
235 unsigned long stop = jiffies + 1 * HZ; /* maximum wait time 1 sec */
236 while (!b1_rx_full(base) && time_before(jiffies, stop));
237 if (b1_rx_full(base))
238 return inb(base + B1_READ);
239 printk(KERN_CRIT "b1lli(0x%x): rx not full after 1 second\n", base);
240 return 0;
241}
242
243static inline unsigned int b1_get_word(unsigned int base)
244{
245 unsigned int val = 0;
246 val |= b1_get_byte(base);
247 val |= (b1_get_byte(base) << 8);
248 val |= (b1_get_byte(base) << 16);
249 val |= (b1_get_byte(base) << 24);
250 return val;
251}
252
253static inline int b1_tx_empty(unsigned int base)
254{
255 return inb(base + B1_OUTSTAT) & 0x1;
256}
257
258static inline void b1_put_byte(unsigned int base, unsigned char val)
259{
260 while (!b1_tx_empty(base));
261 b1outp(base, B1_WRITE, val);
262}
263
264static inline int b1_save_put_byte(unsigned int base, unsigned char val)
265{
266 unsigned long stop = jiffies + 2 * HZ;
267 while (!b1_tx_empty(base) && time_before(jiffies,stop));
268 if (!b1_tx_empty(base)) return -1;
269 b1outp(base, B1_WRITE, val);
270 return 0;
271}
272
273static inline void b1_put_word(unsigned int base, unsigned int val)
274{
275 b1_put_byte(base, val & 0xff);
276 b1_put_byte(base, (val >> 8) & 0xff);
277 b1_put_byte(base, (val >> 16) & 0xff);
278 b1_put_byte(base, (val >> 24) & 0xff);
279}
280
281static inline unsigned int b1_get_slice(unsigned int base,
282 unsigned char *dp)
283{
284 unsigned int len, i;
285
286 len = i = b1_get_word(base);
287 while (i-- > 0) *dp++ = b1_get_byte(base);
288 return len;
289}
290
291static inline void b1_put_slice(unsigned int base,
292 unsigned char *dp, unsigned int len)
293{
294 unsigned i = len;
295 b1_put_word(base, i);
296 while (i-- > 0)
297 b1_put_byte(base, *dp++);
298}
299
300static void b1_wr_reg(unsigned int base,
301 unsigned int reg,
302 unsigned int value)
303{
304 b1_put_byte(base, WRITE_REGISTER);
305 b1_put_word(base, reg);
306 b1_put_word(base, value);
307}
308
309static inline unsigned int b1_rd_reg(unsigned int base,
310 unsigned int reg)
311{
312 b1_put_byte(base, READ_REGISTER);
313 b1_put_word(base, reg);
314 return b1_get_word(base);
315
316}
317
318static inline void b1_reset(unsigned int base)
319{
320 b1outp(base, B1_RESET, 0);
321 mdelay(55 * 2); /* 2 TIC's */
322
323 b1outp(base, B1_RESET, 1);
324 mdelay(55 * 2); /* 2 TIC's */
325
326 b1outp(base, B1_RESET, 0);
327 mdelay(55 * 2); /* 2 TIC's */
328}
329
330static inline unsigned char b1_disable_irq(unsigned int base)
331{
332 return b1outp(base, B1_INSTAT, 0x00);
333}
334
335/* ---------------------------------------------------------------- */
336
337static inline void b1_set_test_bit(unsigned int base,
338 enum avmcardtype cardtype,
339 int onoff)
340{
341 b1_wr_reg(base, B1_STAT0(cardtype), onoff ? 0x21 : 0x20);
342}
343
344static inline int b1_get_test_bit(unsigned int base,
345 enum avmcardtype cardtype)
346{
347 return (b1_rd_reg(base, B1_STAT0(cardtype)) & 0x01) != 0;
348}
349
350/* ---------------------------------------------------------------- */
351
352#define T1_FASTLINK 0x00
353#define T1_SLOWLINK 0x08
354
355#define T1_READ B1_READ
356#define T1_WRITE B1_WRITE
357#define T1_INSTAT B1_INSTAT
358#define T1_OUTSTAT B1_OUTSTAT
359#define T1_IRQENABLE 0x05
360#define T1_FIFOSTAT 0x06
361#define T1_RESETLINK 0x10
362#define T1_ANALYSE 0x11
363#define T1_IRQMASTER 0x12
364#define T1_IDENT 0x17
365#define T1_RESETBOARD 0x1f
366
367#define T1F_IREADY 0x01
368#define T1F_IHALF 0x02
369#define T1F_IFULL 0x04
370#define T1F_IEMPTY 0x08
371#define T1F_IFLAGS 0xF0
372
373#define T1F_OREADY 0x10
374#define T1F_OHALF 0x20
375#define T1F_OEMPTY 0x40
376#define T1F_OFULL 0x80
377#define T1F_OFLAGS 0xF0
378
379/* there are HEMA cards with 1k and 4k FIFO out */
380#define FIFO_OUTBSIZE 256
381#define FIFO_INPBSIZE 512
382
383#define HEMA_VERSION_ID 0
384#define HEMA_PAL_ID 0
385
386static inline void t1outp(unsigned int base,
387 unsigned short offset,
388 unsigned char value)
389{
390 outb(value, base + offset);
391}
392
393static inline unsigned char t1inp(unsigned int base,
394 unsigned short offset)
395{
396 return inb(base + offset);
397}
398
399static inline int t1_isfastlink(unsigned int base)
400{
401 return (inb(base + T1_IDENT) & ~0x82) == 1;
402}
403
404static inline unsigned char t1_fifostatus(unsigned int base)
405{
406 return inb(base + T1_FIFOSTAT);
407}
408
409static inline unsigned int t1_get_slice(unsigned int base,
410 unsigned char *dp)
411{
412 unsigned int len, i;
413#ifdef FASTLINK_DEBUG
414 unsigned wcnt = 0, bcnt = 0;
415#endif
416
417 len = i = b1_get_word(base);
418 if (t1_isfastlink(base)) {
419 int status;
420 while (i > 0) {
421 status = t1_fifostatus(base) & (T1F_IREADY|T1F_IHALF);
422 if (i >= FIFO_INPBSIZE) status |= T1F_IFULL;
423
424 switch (status) {
425 case T1F_IREADY|T1F_IHALF|T1F_IFULL:
426 insb(base+B1_READ, dp, FIFO_INPBSIZE);
427 dp += FIFO_INPBSIZE;
428 i -= FIFO_INPBSIZE;
429#ifdef FASTLINK_DEBUG
430 wcnt += FIFO_INPBSIZE;
431#endif
432 break;
433 case T1F_IREADY|T1F_IHALF:
434 insb(base+B1_READ,dp, i);
435#ifdef FASTLINK_DEBUG
436 wcnt += i;
437#endif
438 dp += i;
439 i = 0;
440 if (i == 0)
441 break;
442 /* fall through */
443 default:
444 *dp++ = b1_get_byte(base);
445 i--;
446#ifdef FASTLINK_DEBUG
447 bcnt++;
448#endif
449 break;
450 }
451 }
452#ifdef FASTLINK_DEBUG
453 if (wcnt)
454 printk(KERN_DEBUG "b1lli(0x%x): get_slice l=%d w=%d b=%d\n",
455 base, len, wcnt, bcnt);
456#endif
457 } else {
458 while (i-- > 0)
459 *dp++ = b1_get_byte(base);
460 }
461 return len;
462}
463
464static inline void t1_put_slice(unsigned int base,
465 unsigned char *dp, unsigned int len)
466{
467 unsigned i = len;
468 b1_put_word(base, i);
469 if (t1_isfastlink(base)) {
470 int status;
471 while (i > 0) {
472 status = t1_fifostatus(base) & (T1F_OREADY|T1F_OHALF);
473 if (i >= FIFO_OUTBSIZE) status |= T1F_OEMPTY;
474 switch (status) {
475 case T1F_OREADY|T1F_OHALF|T1F_OEMPTY:
476 outsb(base+B1_WRITE, dp, FIFO_OUTBSIZE);
477 dp += FIFO_OUTBSIZE;
478 i -= FIFO_OUTBSIZE;
479 break;
480 case T1F_OREADY|T1F_OHALF:
481 outsb(base+B1_WRITE, dp, i);
482 dp += i;
483 i = 0;
484 break;
485 default:
486 b1_put_byte(base, *dp++);
487 i--;
488 break;
489 }
490 }
491 } else {
492 while (i-- > 0)
493 b1_put_byte(base, *dp++);
494 }
495}
496
497static inline void t1_disable_irq(unsigned int base)
498{
499 t1outp(base, T1_IRQMASTER, 0x00);
500}
501
502static inline void t1_reset(unsigned int base)
503{
504 /* reset T1 Controller */
505 b1_reset(base);
506 /* disable irq on HEMA */
507 t1outp(base, B1_INSTAT, 0x00);
508 t1outp(base, B1_OUTSTAT, 0x00);
509 t1outp(base, T1_IRQMASTER, 0x00);
510 /* reset HEMA board configuration */
511 t1outp(base, T1_RESETBOARD, 0xf);
512}
513
514static inline void b1_setinterrupt(unsigned int base, unsigned irq,
515 enum avmcardtype cardtype)
516{
517 switch (cardtype) {
518 case avm_t1isa:
519 t1outp(base, B1_INSTAT, 0x00);
520 t1outp(base, B1_INSTAT, 0x02);
521 t1outp(base, T1_IRQMASTER, 0x08);
522 break;
523 case avm_b1isa:
524 b1outp(base, B1_INSTAT, 0x00);
525 b1outp(base, B1_RESET, b1_irq_table[irq]);
526 b1outp(base, B1_INSTAT, 0x02);
527 break;
528 default:
529 case avm_m1:
530 case avm_m2:
531 case avm_b1pci:
532 b1outp(base, B1_INSTAT, 0x00);
533 b1outp(base, B1_RESET, 0xf0);
534 b1outp(base, B1_INSTAT, 0x02);
535 break;
536 case avm_c4:
537 case avm_t1pci:
538 b1outp(base, B1_RESET, 0xf0);
539 break;
540 }
541}
542
543/* b1.c */
544avmcard *b1_alloc_card(int nr_controllers);
545void b1_free_card(avmcard *card);
546int b1_detect(unsigned int base, enum avmcardtype cardtype);
547void b1_getrevision(avmcard *card);
548int b1_load_t4file(avmcard *card, capiloaddatapart * t4file);
549int b1_load_config(avmcard *card, capiloaddatapart * config);
550int b1_loaded(avmcard *card);
551
552int b1_load_firmware(struct capi_ctr *ctrl, capiloaddata *data);
553void b1_reset_ctr(struct capi_ctr *ctrl);
554void b1_register_appl(struct capi_ctr *ctrl, u16 appl,
555 capi_register_params *rp);
556void b1_release_appl(struct capi_ctr *ctrl, u16 appl);
557u16 b1_send_message(struct capi_ctr *ctrl, struct sk_buff *skb);
558void b1_parse_version(avmctrl_info *card);
559irqreturn_t b1_interrupt(int interrupt, void *devptr, struct pt_regs *regs);
560
561int b1ctl_read_proc(char *page, char **start, off_t off,
562 int count, int *eof, struct capi_ctr *ctrl);
563
564avmcard_dmainfo *avmcard_dma_alloc(char *name, struct pci_dev *,
565 long rsize, long ssize);
566void avmcard_dma_free(avmcard_dmainfo *);
567
568/* b1dma.c */
569int b1pciv4_detect(avmcard *card);
570int t1pci_detect(avmcard *card);
571void b1dma_reset(avmcard *card);
572irqreturn_t b1dma_interrupt(int interrupt, void *devptr, struct pt_regs *regs);
573
574int b1dma_load_firmware(struct capi_ctr *ctrl, capiloaddata *data);
575void b1dma_reset_ctr(struct capi_ctr *ctrl);
576void b1dma_remove_ctr(struct capi_ctr *ctrl);
577void b1dma_register_appl(struct capi_ctr *ctrl,
578 u16 appl,
579 capi_register_params *rp);
580void b1dma_release_appl(struct capi_ctr *ctrl, u16 appl);
581u16 b1dma_send_message(struct capi_ctr *ctrl, struct sk_buff *skb);
582int b1dmactl_read_proc(char *page, char **start, off_t off,
583 int count, int *eof, struct capi_ctr *ctrl);
584
585#endif /* _AVMCARD_H_ */
diff --git a/drivers/isdn/hardware/avm/b1.c b/drivers/isdn/hardware/avm/b1.c
new file mode 100644
index 000000000000..0c7061d55027
--- /dev/null
+++ b/drivers/isdn/hardware/avm/b1.c
@@ -0,0 +1,814 @@
1/* $Id: b1.c,v 1.1.2.2 2004/01/16 21:09:27 keil Exp $
2 *
3 * Common module for AVM B1 cards.
4 *
5 * Copyright 1999 by Carsten Paeth <calle@calle.de>
6 *
7 * This software may be used and distributed according to the terms
8 * of the GNU General Public License, incorporated herein by reference.
9 *
10 */
11
12#include <linux/module.h>
13#include <linux/kernel.h>
14#include <linux/pci.h>
15#include <linux/skbuff.h>
16#include <linux/delay.h>
17#include <linux/mm.h>
18#include <linux/interrupt.h>
19#include <linux/ioport.h>
20#include <linux/capi.h>
21#include <linux/kernelcapi.h>
22#include <asm/io.h>
23#include <linux/init.h>
24#include <asm/uaccess.h>
25#include <linux/netdevice.h>
26#include <linux/isdn/capilli.h>
27#include "avmcard.h"
28#include <linux/isdn/capicmd.h>
29#include <linux/isdn/capiutil.h>
30
31static char *revision = "$Revision: 1.1.2.2 $";
32
33/* ------------------------------------------------------------- */
34
35MODULE_DESCRIPTION("CAPI4Linux: Common support for active AVM cards");
36MODULE_AUTHOR("Carsten Paeth");
37MODULE_LICENSE("GPL");
38
39/* ------------------------------------------------------------- */
40
41int b1_irq_table[16] =
42{0,
43 0,
44 0,
45 192, /* irq 3 */
46 32, /* irq 4 */
47 160, /* irq 5 */
48 96, /* irq 6 */
49 224, /* irq 7 */
50 0,
51 64, /* irq 9 */
52 80, /* irq 10 */
53 208, /* irq 11 */
54 48, /* irq 12 */
55 0,
56 0,
57 112, /* irq 15 */
58};
59
60/* ------------------------------------------------------------- */
61
62avmcard *b1_alloc_card(int nr_controllers)
63{
64 avmcard *card;
65 avmctrl_info *cinfo;
66 int i;
67
68 card = kmalloc(sizeof(*card), GFP_KERNEL);
69 if (!card)
70 return NULL;
71
72 memset(card, 0, sizeof(*card));
73
74 cinfo = kmalloc(sizeof(*cinfo) * nr_controllers, GFP_KERNEL);
75 if (!cinfo) {
76 kfree(card);
77 return NULL;
78 }
79 memset(cinfo, 0, sizeof(*cinfo) * nr_controllers);
80
81 card->ctrlinfo = cinfo;
82 for (i = 0; i < nr_controllers; i++) {
83 INIT_LIST_HEAD(&cinfo[i].ncci_head);
84 cinfo[i].card = card;
85 }
86 spin_lock_init(&card->lock);
87 card->nr_controllers = nr_controllers;
88
89 return card;
90}
91
92/* ------------------------------------------------------------- */
93
94void b1_free_card(avmcard *card)
95{
96 kfree(card->ctrlinfo);
97 kfree(card);
98}
99
100/* ------------------------------------------------------------- */
101
102int b1_detect(unsigned int base, enum avmcardtype cardtype)
103{
104 int onoff, i;
105
106 /*
107 * Statusregister 0000 00xx
108 */
109 if ((inb(base + B1_INSTAT) & 0xfc)
110 || (inb(base + B1_OUTSTAT) & 0xfc))
111 return 1;
112 /*
113 * Statusregister 0000 001x
114 */
115 b1outp(base, B1_INSTAT, 0x2); /* enable irq */
116 /* b1outp(base, B1_OUTSTAT, 0x2); */
117 if ((inb(base + B1_INSTAT) & 0xfe) != 0x2
118 /* || (inb(base + B1_OUTSTAT) & 0xfe) != 0x2 */)
119 return 2;
120 /*
121 * Statusregister 0000 000x
122 */
123 b1outp(base, B1_INSTAT, 0x0); /* disable irq */
124 b1outp(base, B1_OUTSTAT, 0x0);
125 if ((inb(base + B1_INSTAT) & 0xfe)
126 || (inb(base + B1_OUTSTAT) & 0xfe))
127 return 3;
128
129 for (onoff = !0, i= 0; i < 10 ; i++) {
130 b1_set_test_bit(base, cardtype, onoff);
131 if (b1_get_test_bit(base, cardtype) != onoff)
132 return 4;
133 onoff = !onoff;
134 }
135
136 if (cardtype == avm_m1)
137 return 0;
138
139 if ((b1_rd_reg(base, B1_STAT1(cardtype)) & 0x0f) != 0x01)
140 return 5;
141
142 return 0;
143}
144
145void b1_getrevision(avmcard *card)
146{
147 card->class = inb(card->port + B1_ANALYSE);
148 card->revision = inb(card->port + B1_REVISION);
149}
150
151#define FWBUF_SIZE 256
152int b1_load_t4file(avmcard *card, capiloaddatapart * t4file)
153{
154 unsigned char buf[FWBUF_SIZE];
155 unsigned char *dp;
156 int i, left;
157 unsigned int base = card->port;
158
159 dp = t4file->data;
160 left = t4file->len;
161 while (left > FWBUF_SIZE) {
162 if (t4file->user) {
163 if (copy_from_user(buf, dp, FWBUF_SIZE))
164 return -EFAULT;
165 } else {
166 memcpy(buf, dp, FWBUF_SIZE);
167 }
168 for (i = 0; i < FWBUF_SIZE; i++)
169 if (b1_save_put_byte(base, buf[i]) < 0) {
170 printk(KERN_ERR "%s: corrupted firmware file ?\n",
171 card->name);
172 return -EIO;
173 }
174 left -= FWBUF_SIZE;
175 dp += FWBUF_SIZE;
176 }
177 if (left) {
178 if (t4file->user) {
179 if (copy_from_user(buf, dp, left))
180 return -EFAULT;
181 } else {
182 memcpy(buf, dp, left);
183 }
184 for (i = 0; i < left; i++)
185 if (b1_save_put_byte(base, buf[i]) < 0) {
186 printk(KERN_ERR "%s: corrupted firmware file ?\n",
187 card->name);
188 return -EIO;
189 }
190 }
191 return 0;
192}
193
194int b1_load_config(avmcard *card, capiloaddatapart * config)
195{
196 unsigned char buf[FWBUF_SIZE];
197 unsigned char *dp;
198 unsigned int base = card->port;
199 int i, j, left;
200
201 dp = config->data;
202 left = config->len;
203 if (left) {
204 b1_put_byte(base, SEND_CONFIG);
205 b1_put_word(base, 1);
206 b1_put_byte(base, SEND_CONFIG);
207 b1_put_word(base, left);
208 }
209 while (left > FWBUF_SIZE) {
210 if (config->user) {
211 if (copy_from_user(buf, dp, FWBUF_SIZE))
212 return -EFAULT;
213 } else {
214 memcpy(buf, dp, FWBUF_SIZE);
215 }
216 for (i = 0; i < FWBUF_SIZE; ) {
217 b1_put_byte(base, SEND_CONFIG);
218 for (j=0; j < 4; j++) {
219 b1_put_byte(base, buf[i++]);
220 }
221 }
222 left -= FWBUF_SIZE;
223 dp += FWBUF_SIZE;
224 }
225 if (left) {
226 if (config->user) {
227 if (copy_from_user(buf, dp, left))
228 return -EFAULT;
229 } else {
230 memcpy(buf, dp, left);
231 }
232 for (i = 0; i < left; ) {
233 b1_put_byte(base, SEND_CONFIG);
234 for (j=0; j < 4; j++) {
235 if (i < left)
236 b1_put_byte(base, buf[i++]);
237 else
238 b1_put_byte(base, 0);
239 }
240 }
241 }
242 return 0;
243}
244
245int b1_loaded(avmcard *card)
246{
247 unsigned int base = card->port;
248 unsigned long stop;
249 unsigned char ans;
250 unsigned long tout = 2;
251
252 for (stop = jiffies + tout * HZ; time_before(jiffies, stop);) {
253 if (b1_tx_empty(base))
254 break;
255 }
256 if (!b1_tx_empty(base)) {
257 printk(KERN_ERR "%s: b1_loaded: tx err, corrupted t4 file ?\n",
258 card->name);
259 return 0;
260 }
261 b1_put_byte(base, SEND_POLL);
262 for (stop = jiffies + tout * HZ; time_before(jiffies, stop);) {
263 if (b1_rx_full(base)) {
264 if ((ans = b1_get_byte(base)) == RECEIVE_POLL) {
265 return 1;
266 }
267 printk(KERN_ERR "%s: b1_loaded: got 0x%x, firmware not running\n",
268 card->name, ans);
269 return 0;
270 }
271 }
272 printk(KERN_ERR "%s: b1_loaded: firmware not running\n", card->name);
273 return 0;
274}
275
276/* ------------------------------------------------------------- */
277
278int b1_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
279{
280 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
281 avmcard *card = cinfo->card;
282 unsigned int port = card->port;
283 unsigned long flags;
284 int retval;
285
286 b1_reset(port);
287
288 if ((retval = b1_load_t4file(card, &data->firmware))) {
289 b1_reset(port);
290 printk(KERN_ERR "%s: failed to load t4file!!\n",
291 card->name);
292 return retval;
293 }
294
295 b1_disable_irq(port);
296
297 if (data->configuration.len > 0 && data->configuration.data) {
298 if ((retval = b1_load_config(card, &data->configuration))) {
299 b1_reset(port);
300 printk(KERN_ERR "%s: failed to load config!!\n",
301 card->name);
302 return retval;
303 }
304 }
305
306 if (!b1_loaded(card)) {
307 printk(KERN_ERR "%s: failed to load t4file.\n", card->name);
308 return -EIO;
309 }
310
311 spin_lock_irqsave(&card->lock, flags);
312 b1_setinterrupt(port, card->irq, card->cardtype);
313 b1_put_byte(port, SEND_INIT);
314 b1_put_word(port, CAPI_MAXAPPL);
315 b1_put_word(port, AVM_NCCI_PER_CHANNEL*2);
316 b1_put_word(port, ctrl->cnr - 1);
317 spin_unlock_irqrestore(&card->lock, flags);
318
319 return 0;
320}
321
322void b1_reset_ctr(struct capi_ctr *ctrl)
323{
324 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
325 avmcard *card = cinfo->card;
326 unsigned int port = card->port;
327
328 b1_reset(port);
329 b1_reset(port);
330
331 memset(cinfo->version, 0, sizeof(cinfo->version));
332 capilib_release(&cinfo->ncci_head);
333 capi_ctr_reseted(ctrl);
334}
335
336void b1_register_appl(struct capi_ctr *ctrl,
337 u16 appl,
338 capi_register_params *rp)
339{
340 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
341 avmcard *card = cinfo->card;
342 unsigned int port = card->port;
343 unsigned long flags;
344 int nconn, want = rp->level3cnt;
345
346 if (want > 0) nconn = want;
347 else nconn = ctrl->profile.nbchannel * -want;
348 if (nconn == 0) nconn = ctrl->profile.nbchannel;
349
350 spin_lock_irqsave(&card->lock, flags);
351 b1_put_byte(port, SEND_REGISTER);
352 b1_put_word(port, appl);
353 b1_put_word(port, 1024 * (nconn+1));
354 b1_put_word(port, nconn);
355 b1_put_word(port, rp->datablkcnt);
356 b1_put_word(port, rp->datablklen);
357 spin_unlock_irqrestore(&card->lock, flags);
358}
359
360void b1_release_appl(struct capi_ctr *ctrl, u16 appl)
361{
362 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
363 avmcard *card = cinfo->card;
364 unsigned int port = card->port;
365 unsigned long flags;
366
367 capilib_release_appl(&cinfo->ncci_head, appl);
368
369 spin_lock_irqsave(&card->lock, flags);
370 b1_put_byte(port, SEND_RELEASE);
371 b1_put_word(port, appl);
372 spin_unlock_irqrestore(&card->lock, flags);
373}
374
375u16 b1_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
376{
377 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
378 avmcard *card = cinfo->card;
379 unsigned int port = card->port;
380 unsigned long flags;
381 u16 len = CAPIMSG_LEN(skb->data);
382 u8 cmd = CAPIMSG_COMMAND(skb->data);
383 u8 subcmd = CAPIMSG_SUBCOMMAND(skb->data);
384 u16 dlen, retval;
385
386 if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) {
387 retval = capilib_data_b3_req(&cinfo->ncci_head,
388 CAPIMSG_APPID(skb->data),
389 CAPIMSG_NCCI(skb->data),
390 CAPIMSG_MSGID(skb->data));
391 if (retval != CAPI_NOERROR)
392 return retval;
393
394 dlen = CAPIMSG_DATALEN(skb->data);
395
396 spin_lock_irqsave(&card->lock, flags);
397 b1_put_byte(port, SEND_DATA_B3_REQ);
398 b1_put_slice(port, skb->data, len);
399 b1_put_slice(port, skb->data + len, dlen);
400 spin_unlock_irqrestore(&card->lock, flags);
401 } else {
402 spin_lock_irqsave(&card->lock, flags);
403 b1_put_byte(port, SEND_MESSAGE);
404 b1_put_slice(port, skb->data, len);
405 spin_unlock_irqrestore(&card->lock, flags);
406 }
407
408 dev_kfree_skb_any(skb);
409 return CAPI_NOERROR;
410}
411
412/* ------------------------------------------------------------- */
413
414void b1_parse_version(avmctrl_info *cinfo)
415{
416 struct capi_ctr *ctrl = &cinfo->capi_ctrl;
417 avmcard *card = cinfo->card;
418 capi_profile *profp;
419 u8 *dversion;
420 u8 flag;
421 int i, j;
422
423 for (j = 0; j < AVM_MAXVERSION; j++)
424 cinfo->version[j] = "\0\0" + 1;
425 for (i = 0, j = 0;
426 j < AVM_MAXVERSION && i < cinfo->versionlen;
427 j++, i += cinfo->versionbuf[i] + 1)
428 cinfo->version[j] = &cinfo->versionbuf[i + 1];
429
430 strlcpy(ctrl->serial, cinfo->version[VER_SERIAL], sizeof(ctrl->serial));
431 memcpy(&ctrl->profile, cinfo->version[VER_PROFILE],sizeof(capi_profile));
432 strlcpy(ctrl->manu, "AVM GmbH", sizeof(ctrl->manu));
433 dversion = cinfo->version[VER_DRIVER];
434 ctrl->version.majorversion = 2;
435 ctrl->version.minorversion = 0;
436 ctrl->version.majormanuversion = (((dversion[0] - '0') & 0xf) << 4);
437 ctrl->version.majormanuversion |= ((dversion[2] - '0') & 0xf);
438 ctrl->version.minormanuversion = (dversion[3] - '0') << 4;
439 ctrl->version.minormanuversion |=
440 (dversion[5] - '0') * 10 + ((dversion[6] - '0') & 0xf);
441
442 profp = &ctrl->profile;
443
444 flag = ((u8 *)(profp->manu))[1];
445 switch (flag) {
446 case 0: if (cinfo->version[VER_CARDTYPE])
447 strcpy(cinfo->cardname, cinfo->version[VER_CARDTYPE]);
448 else strcpy(cinfo->cardname, "B1");
449 break;
450 case 3: strcpy(cinfo->cardname,"PCMCIA B"); break;
451 case 4: strcpy(cinfo->cardname,"PCMCIA M1"); break;
452 case 5: strcpy(cinfo->cardname,"PCMCIA M2"); break;
453 case 6: strcpy(cinfo->cardname,"B1 V3.0"); break;
454 case 7: strcpy(cinfo->cardname,"B1 PCI"); break;
455 default: sprintf(cinfo->cardname, "AVM?%u", (unsigned int)flag); break;
456 }
457 printk(KERN_NOTICE "%s: card %d \"%s\" ready.\n",
458 card->name, ctrl->cnr, cinfo->cardname);
459
460 flag = ((u8 *)(profp->manu))[3];
461 if (flag)
462 printk(KERN_NOTICE "%s: card %d Protocol:%s%s%s%s%s%s%s\n",
463 card->name,
464 ctrl->cnr,
465 (flag & 0x01) ? " DSS1" : "",
466 (flag & 0x02) ? " CT1" : "",
467 (flag & 0x04) ? " VN3" : "",
468 (flag & 0x08) ? " NI1" : "",
469 (flag & 0x10) ? " AUSTEL" : "",
470 (flag & 0x20) ? " ESS" : "",
471 (flag & 0x40) ? " 1TR6" : ""
472 );
473
474 flag = ((u8 *)(profp->manu))[5];
475 if (flag)
476 printk(KERN_NOTICE "%s: card %d Linetype:%s%s%s%s\n",
477 card->name,
478 ctrl->cnr,
479 (flag & 0x01) ? " point to point" : "",
480 (flag & 0x02) ? " point to multipoint" : "",
481 (flag & 0x08) ? " leased line without D-channel" : "",
482 (flag & 0x04) ? " leased line with D-channel" : ""
483 );
484}
485
486/* ------------------------------------------------------------- */
487
488irqreturn_t b1_interrupt(int interrupt, void *devptr, struct pt_regs *regs)
489{
490 avmcard *card = devptr;
491 avmctrl_info *cinfo = &card->ctrlinfo[0];
492 struct capi_ctr *ctrl = &cinfo->capi_ctrl;
493 unsigned char b1cmd;
494 struct sk_buff *skb;
495
496 unsigned ApplId;
497 unsigned MsgLen;
498 unsigned DataB3Len;
499 unsigned NCCI;
500 unsigned WindowSize;
501 unsigned long flags;
502
503 spin_lock_irqsave(&card->lock, flags);
504
505 if (!b1_rx_full(card->port)) {
506 spin_unlock_irqrestore(&card->lock, flags);
507 return IRQ_NONE;
508 }
509
510 b1cmd = b1_get_byte(card->port);
511
512 switch (b1cmd) {
513
514 case RECEIVE_DATA_B3_IND:
515
516 ApplId = (unsigned) b1_get_word(card->port);
517 MsgLen = b1_get_slice(card->port, card->msgbuf);
518 DataB3Len = b1_get_slice(card->port, card->databuf);
519 spin_unlock_irqrestore(&card->lock, flags);
520
521 if (MsgLen < 30) { /* not CAPI 64Bit */
522 memset(card->msgbuf+MsgLen, 0, 30-MsgLen);
523 MsgLen = 30;
524 CAPIMSG_SETLEN(card->msgbuf, 30);
525 }
526 if (!(skb = alloc_skb(DataB3Len + MsgLen, GFP_ATOMIC))) {
527 printk(KERN_ERR "%s: incoming packet dropped\n",
528 card->name);
529 } else {
530 memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);
531 memcpy(skb_put(skb, DataB3Len), card->databuf, DataB3Len);
532 capi_ctr_handle_message(ctrl, ApplId, skb);
533 }
534 break;
535
536 case RECEIVE_MESSAGE:
537
538 ApplId = (unsigned) b1_get_word(card->port);
539 MsgLen = b1_get_slice(card->port, card->msgbuf);
540 spin_unlock_irqrestore(&card->lock, flags);
541 if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) {
542 printk(KERN_ERR "%s: incoming packet dropped\n",
543 card->name);
544 } else {
545 memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);
546 if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_CONF)
547 capilib_data_b3_conf(&cinfo->ncci_head, ApplId,
548 CAPIMSG_NCCI(skb->data),
549 CAPIMSG_MSGID(skb->data));
550
551 capi_ctr_handle_message(ctrl, ApplId, skb);
552 }
553 break;
554
555 case RECEIVE_NEW_NCCI:
556
557 ApplId = b1_get_word(card->port);
558 NCCI = b1_get_word(card->port);
559 WindowSize = b1_get_word(card->port);
560 spin_unlock_irqrestore(&card->lock, flags);
561
562 capilib_new_ncci(&cinfo->ncci_head, ApplId, NCCI, WindowSize);
563
564 break;
565
566 case RECEIVE_FREE_NCCI:
567
568 ApplId = b1_get_word(card->port);
569 NCCI = b1_get_word(card->port);
570 spin_unlock_irqrestore(&card->lock, flags);
571
572 if (NCCI != 0xffffffff)
573 capilib_free_ncci(&cinfo->ncci_head, ApplId, NCCI);
574
575 break;
576
577 case RECEIVE_START:
578 /* b1_put_byte(card->port, SEND_POLLACK); */
579 spin_unlock_irqrestore(&card->lock, flags);
580 capi_ctr_resume_output(ctrl);
581 break;
582
583 case RECEIVE_STOP:
584 spin_unlock_irqrestore(&card->lock, flags);
585 capi_ctr_suspend_output(ctrl);
586 break;
587
588 case RECEIVE_INIT:
589
590 cinfo->versionlen = b1_get_slice(card->port, cinfo->versionbuf);
591 spin_unlock_irqrestore(&card->lock, flags);
592 b1_parse_version(cinfo);
593 printk(KERN_INFO "%s: %s-card (%s) now active\n",
594 card->name,
595 cinfo->version[VER_CARDTYPE],
596 cinfo->version[VER_DRIVER]);
597 capi_ctr_ready(ctrl);
598 break;
599
600 case RECEIVE_TASK_READY:
601 ApplId = (unsigned) b1_get_word(card->port);
602 MsgLen = b1_get_slice(card->port, card->msgbuf);
603 spin_unlock_irqrestore(&card->lock, flags);
604 card->msgbuf[MsgLen] = 0;
605 while ( MsgLen > 0
606 && ( card->msgbuf[MsgLen-1] == '\n'
607 || card->msgbuf[MsgLen-1] == '\r')) {
608 card->msgbuf[MsgLen-1] = 0;
609 MsgLen--;
610 }
611 printk(KERN_INFO "%s: task %d \"%s\" ready.\n",
612 card->name, ApplId, card->msgbuf);
613 break;
614
615 case RECEIVE_DEBUGMSG:
616 MsgLen = b1_get_slice(card->port, card->msgbuf);
617 spin_unlock_irqrestore(&card->lock, flags);
618 card->msgbuf[MsgLen] = 0;
619 while ( MsgLen > 0
620 && ( card->msgbuf[MsgLen-1] == '\n'
621 || card->msgbuf[MsgLen-1] == '\r')) {
622 card->msgbuf[MsgLen-1] = 0;
623 MsgLen--;
624 }
625 printk(KERN_INFO "%s: DEBUG: %s\n", card->name, card->msgbuf);
626 break;
627
628 case 0xff:
629 spin_unlock_irqrestore(&card->lock, flags);
630 printk(KERN_ERR "%s: card removed ?\n", card->name);
631 return IRQ_NONE;
632 default:
633 spin_unlock_irqrestore(&card->lock, flags);
634 printk(KERN_ERR "%s: b1_interrupt: 0x%x ???\n",
635 card->name, b1cmd);
636 return IRQ_HANDLED;
637 }
638 return IRQ_HANDLED;
639}
640
641/* ------------------------------------------------------------- */
642int b1ctl_read_proc(char *page, char **start, off_t off,
643 int count, int *eof, struct capi_ctr *ctrl)
644{
645 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
646 avmcard *card = cinfo->card;
647 u8 flag;
648 int len = 0;
649 char *s;
650
651 len += sprintf(page+len, "%-16s %s\n", "name", card->name);
652 len += sprintf(page+len, "%-16s 0x%x\n", "io", card->port);
653 len += sprintf(page+len, "%-16s %d\n", "irq", card->irq);
654 switch (card->cardtype) {
655 case avm_b1isa: s = "B1 ISA"; break;
656 case avm_b1pci: s = "B1 PCI"; break;
657 case avm_b1pcmcia: s = "B1 PCMCIA"; break;
658 case avm_m1: s = "M1"; break;
659 case avm_m2: s = "M2"; break;
660 case avm_t1isa: s = "T1 ISA (HEMA)"; break;
661 case avm_t1pci: s = "T1 PCI"; break;
662 case avm_c4: s = "C4"; break;
663 case avm_c2: s = "C2"; break;
664 default: s = "???"; break;
665 }
666 len += sprintf(page+len, "%-16s %s\n", "type", s);
667 if (card->cardtype == avm_t1isa)
668 len += sprintf(page+len, "%-16s %d\n", "cardnr", card->cardnr);
669 if ((s = cinfo->version[VER_DRIVER]) != 0)
670 len += sprintf(page+len, "%-16s %s\n", "ver_driver", s);
671 if ((s = cinfo->version[VER_CARDTYPE]) != 0)
672 len += sprintf(page+len, "%-16s %s\n", "ver_cardtype", s);
673 if ((s = cinfo->version[VER_SERIAL]) != 0)
674 len += sprintf(page+len, "%-16s %s\n", "ver_serial", s);
675
676 if (card->cardtype != avm_m1) {
677 flag = ((u8 *)(ctrl->profile.manu))[3];
678 if (flag)
679 len += sprintf(page+len, "%-16s%s%s%s%s%s%s%s\n",
680 "protocol",
681 (flag & 0x01) ? " DSS1" : "",
682 (flag & 0x02) ? " CT1" : "",
683 (flag & 0x04) ? " VN3" : "",
684 (flag & 0x08) ? " NI1" : "",
685 (flag & 0x10) ? " AUSTEL" : "",
686 (flag & 0x20) ? " ESS" : "",
687 (flag & 0x40) ? " 1TR6" : ""
688 );
689 }
690 if (card->cardtype != avm_m1) {
691 flag = ((u8 *)(ctrl->profile.manu))[5];
692 if (flag)
693 len += sprintf(page+len, "%-16s%s%s%s%s\n",
694 "linetype",
695 (flag & 0x01) ? " point to point" : "",
696 (flag & 0x02) ? " point to multipoint" : "",
697 (flag & 0x08) ? " leased line without D-channel" : "",
698 (flag & 0x04) ? " leased line with D-channel" : ""
699 );
700 }
701 len += sprintf(page+len, "%-16s %s\n", "cardname", cinfo->cardname);
702
703 if (off+count >= len)
704 *eof = 1;
705 if (len < off)
706 return 0;
707 *start = page + off;
708 return ((count < len-off) ? count : len-off);
709}
710
711/* ------------------------------------------------------------- */
712
713#ifdef CONFIG_PCI
714
715avmcard_dmainfo *
716avmcard_dma_alloc(char *name, struct pci_dev *pdev, long rsize, long ssize)
717{
718 avmcard_dmainfo *p;
719 void *buf;
720
721 p = kmalloc(sizeof(avmcard_dmainfo), GFP_KERNEL);
722 if (!p) {
723 printk(KERN_WARNING "%s: no memory.\n", name);
724 goto err;
725 }
726 memset(p, 0, sizeof(avmcard_dmainfo));
727
728 p->recvbuf.size = rsize;
729 buf = pci_alloc_consistent(pdev, rsize, &p->recvbuf.dmaaddr);
730 if (!buf) {
731 printk(KERN_WARNING "%s: allocation of receive dma buffer failed.\n", name);
732 goto err_kfree;
733 }
734 p->recvbuf.dmabuf = buf;
735
736 p->sendbuf.size = ssize;
737 buf = pci_alloc_consistent(pdev, ssize, &p->sendbuf.dmaaddr);
738 if (!buf) {
739 printk(KERN_WARNING "%s: allocation of send dma buffer failed.\n", name);
740 goto err_free_consistent;
741 }
742
743 p->sendbuf.dmabuf = buf;
744 skb_queue_head_init(&p->send_queue);
745
746 return p;
747
748 err_free_consistent:
749 pci_free_consistent(p->pcidev, p->recvbuf.size,
750 p->recvbuf.dmabuf, p->recvbuf.dmaaddr);
751 err_kfree:
752 kfree(p);
753 err:
754 return NULL;
755}
756
757void avmcard_dma_free(avmcard_dmainfo *p)
758{
759 pci_free_consistent(p->pcidev, p->recvbuf.size,
760 p->recvbuf.dmabuf, p->recvbuf.dmaaddr);
761 pci_free_consistent(p->pcidev, p->sendbuf.size,
762 p->sendbuf.dmabuf, p->sendbuf.dmaaddr);
763 skb_queue_purge(&p->send_queue);
764 kfree(p);
765}
766
767EXPORT_SYMBOL(avmcard_dma_alloc);
768EXPORT_SYMBOL(avmcard_dma_free);
769
770#endif
771
772EXPORT_SYMBOL(b1_irq_table);
773
774EXPORT_SYMBOL(b1_alloc_card);
775EXPORT_SYMBOL(b1_free_card);
776EXPORT_SYMBOL(b1_detect);
777EXPORT_SYMBOL(b1_getrevision);
778EXPORT_SYMBOL(b1_load_t4file);
779EXPORT_SYMBOL(b1_load_config);
780EXPORT_SYMBOL(b1_loaded);
781EXPORT_SYMBOL(b1_load_firmware);
782EXPORT_SYMBOL(b1_reset_ctr);
783EXPORT_SYMBOL(b1_register_appl);
784EXPORT_SYMBOL(b1_release_appl);
785EXPORT_SYMBOL(b1_send_message);
786
787EXPORT_SYMBOL(b1_parse_version);
788EXPORT_SYMBOL(b1_interrupt);
789
790EXPORT_SYMBOL(b1ctl_read_proc);
791
792static int __init b1_init(void)
793{
794 char *p;
795 char rev[32];
796
797 if ((p = strchr(revision, ':')) != 0 && p[1]) {
798 strlcpy(rev, p + 2, 32);
799 if ((p = strchr(rev, '$')) != 0 && p > rev)
800 *(p-1) = 0;
801 } else
802 strcpy(rev, "1.0");
803
804 printk(KERN_INFO "b1: revision %s\n", rev);
805
806 return 0;
807}
808
809static void __exit b1_exit(void)
810{
811}
812
813module_init(b1_init);
814module_exit(b1_exit);
diff --git a/drivers/isdn/hardware/avm/b1dma.c b/drivers/isdn/hardware/avm/b1dma.c
new file mode 100644
index 000000000000..55bed00ca865
--- /dev/null
+++ b/drivers/isdn/hardware/avm/b1dma.c
@@ -0,0 +1,980 @@
1/* $Id: b1dma.c,v 1.1.2.3 2004/02/10 01:07:12 keil Exp $
2 *
3 * Common module for AVM B1 cards that support dma with AMCC
4 *
5 * Copyright 2000 by Carsten Paeth <calle@calle.de>
6 *
7 * This software may be used and distributed according to the terms
8 * of the GNU General Public License, incorporated herein by reference.
9 *
10 */
11
12#include <linux/config.h>
13#include <linux/module.h>
14#include <linux/kernel.h>
15#include <linux/skbuff.h>
16#include <linux/delay.h>
17#include <linux/mm.h>
18#include <linux/interrupt.h>
19#include <linux/ioport.h>
20#include <linux/capi.h>
21#include <linux/kernelcapi.h>
22#include <asm/io.h>
23#include <linux/init.h>
24#include <asm/uaccess.h>
25#include <linux/netdevice.h>
26#include <linux/isdn/capilli.h>
27#include "avmcard.h"
28#include <linux/isdn/capicmd.h>
29#include <linux/isdn/capiutil.h>
30
31static char *revision = "$Revision: 1.1.2.3 $";
32
33#undef CONFIG_B1DMA_DEBUG
34
35/* ------------------------------------------------------------- */
36
37MODULE_DESCRIPTION("CAPI4Linux: DMA support for active AVM cards");
38MODULE_AUTHOR("Carsten Paeth");
39MODULE_LICENSE("GPL");
40
41static int suppress_pollack = 0;
42MODULE_PARM(suppress_pollack, "0-1i");
43
44/* ------------------------------------------------------------- */
45
46static void b1dma_dispatch_tx(avmcard *card);
47
48/* ------------------------------------------------------------- */
49
50/* S5933 */
51
52#define AMCC_RXPTR 0x24
53#define AMCC_RXLEN 0x28
54#define AMCC_TXPTR 0x2c
55#define AMCC_TXLEN 0x30
56
57#define AMCC_INTCSR 0x38
58# define EN_READ_TC_INT 0x00008000L
59# define EN_WRITE_TC_INT 0x00004000L
60# define EN_TX_TC_INT EN_READ_TC_INT
61# define EN_RX_TC_INT EN_WRITE_TC_INT
62# define AVM_FLAG 0x30000000L
63
64# define ANY_S5933_INT 0x00800000L
65# define READ_TC_INT 0x00080000L
66# define WRITE_TC_INT 0x00040000L
67# define TX_TC_INT READ_TC_INT
68# define RX_TC_INT WRITE_TC_INT
69# define MASTER_ABORT_INT 0x00100000L
70# define TARGET_ABORT_INT 0x00200000L
71# define BUS_MASTER_INT 0x00200000L
72# define ALL_INT 0x000C0000L
73
74#define AMCC_MCSR 0x3c
75# define A2P_HI_PRIORITY 0x00000100L
76# define EN_A2P_TRANSFERS 0x00000400L
77# define P2A_HI_PRIORITY 0x00001000L
78# define EN_P2A_TRANSFERS 0x00004000L
79# define RESET_A2P_FLAGS 0x04000000L
80# define RESET_P2A_FLAGS 0x02000000L
81
82/* ------------------------------------------------------------- */
83
84static inline void b1dma_writel(avmcard *card, u32 value, int off)
85{
86 writel(value, card->mbase + off);
87}
88
89static inline u32 b1dma_readl(avmcard *card, int off)
90{
91 return readl(card->mbase + off);
92}
93
94/* ------------------------------------------------------------- */
95
96static inline int b1dma_tx_empty(unsigned int port)
97{
98 return inb(port + 0x03) & 0x1;
99}
100
101static inline int b1dma_rx_full(unsigned int port)
102{
103 return inb(port + 0x02) & 0x1;
104}
105
106static int b1dma_tolink(avmcard *card, void *buf, unsigned int len)
107{
108 unsigned long stop = jiffies + 1 * HZ; /* maximum wait time 1 sec */
109 unsigned char *s = (unsigned char *)buf;
110 while (len--) {
111 while ( !b1dma_tx_empty(card->port)
112 && time_before(jiffies, stop));
113 if (!b1dma_tx_empty(card->port))
114 return -1;
115 t1outp(card->port, 0x01, *s++);
116 }
117 return 0;
118}
119
120static int b1dma_fromlink(avmcard *card, void *buf, unsigned int len)
121{
122 unsigned long stop = jiffies + 1 * HZ; /* maximum wait time 1 sec */
123 unsigned char *s = (unsigned char *)buf;
124 while (len--) {
125 while ( !b1dma_rx_full(card->port)
126 && time_before(jiffies, stop));
127 if (!b1dma_rx_full(card->port))
128 return -1;
129 *s++ = t1inp(card->port, 0x00);
130 }
131 return 0;
132}
133
134static int WriteReg(avmcard *card, u32 reg, u8 val)
135{
136 u8 cmd = 0x00;
137 if ( b1dma_tolink(card, &cmd, 1) == 0
138 && b1dma_tolink(card, &reg, 4) == 0) {
139 u32 tmp = val;
140 return b1dma_tolink(card, &tmp, 4);
141 }
142 return -1;
143}
144
145static u8 ReadReg(avmcard *card, u32 reg)
146{
147 u8 cmd = 0x01;
148 if ( b1dma_tolink(card, &cmd, 1) == 0
149 && b1dma_tolink(card, &reg, 4) == 0) {
150 u32 tmp;
151 if (b1dma_fromlink(card, &tmp, 4) == 0)
152 return (u8)tmp;
153 }
154 return 0xff;
155}
156
157/* ------------------------------------------------------------- */
158
159static inline void _put_byte(void **pp, u8 val)
160{
161 u8 *s = *pp;
162 *s++ = val;
163 *pp = s;
164}
165
166static inline void _put_word(void **pp, u32 val)
167{
168 u8 *s = *pp;
169 *s++ = val & 0xff;
170 *s++ = (val >> 8) & 0xff;
171 *s++ = (val >> 16) & 0xff;
172 *s++ = (val >> 24) & 0xff;
173 *pp = s;
174}
175
176static inline void _put_slice(void **pp, unsigned char *dp, unsigned int len)
177{
178 unsigned i = len;
179 _put_word(pp, i);
180 while (i-- > 0)
181 _put_byte(pp, *dp++);
182}
183
184static inline u8 _get_byte(void **pp)
185{
186 u8 *s = *pp;
187 u8 val;
188 val = *s++;
189 *pp = s;
190 return val;
191}
192
193static inline u32 _get_word(void **pp)
194{
195 u8 *s = *pp;
196 u32 val;
197 val = *s++;
198 val |= (*s++ << 8);
199 val |= (*s++ << 16);
200 val |= (*s++ << 24);
201 *pp = s;
202 return val;
203}
204
205static inline u32 _get_slice(void **pp, unsigned char *dp)
206{
207 unsigned int len, i;
208
209 len = i = _get_word(pp);
210 while (i-- > 0) *dp++ = _get_byte(pp);
211 return len;
212}
213
214/* ------------------------------------------------------------- */
215
216void b1dma_reset(avmcard *card)
217{
218 card->csr = 0x0;
219 b1dma_writel(card, card->csr, AMCC_INTCSR);
220 b1dma_writel(card, 0, AMCC_MCSR);
221 b1dma_writel(card, 0, AMCC_RXLEN);
222 b1dma_writel(card, 0, AMCC_TXLEN);
223
224 t1outp(card->port, 0x10, 0x00);
225 t1outp(card->port, 0x07, 0x00);
226
227 b1dma_writel(card, 0, AMCC_MCSR);
228 mdelay(10);
229 b1dma_writel(card, 0x0f000000, AMCC_MCSR); /* reset all */
230 mdelay(10);
231 b1dma_writel(card, 0, AMCC_MCSR);
232 if (card->cardtype == avm_t1pci)
233 mdelay(42);
234 else
235 mdelay(10);
236}
237
238/* ------------------------------------------------------------- */
239
240static int b1dma_detect(avmcard *card)
241{
242 b1dma_writel(card, 0, AMCC_MCSR);
243 mdelay(10);
244 b1dma_writel(card, 0x0f000000, AMCC_MCSR); /* reset all */
245 mdelay(10);
246 b1dma_writel(card, 0, AMCC_MCSR);
247 mdelay(42);
248
249 b1dma_writel(card, 0, AMCC_RXLEN);
250 b1dma_writel(card, 0, AMCC_TXLEN);
251 card->csr = 0x0;
252 b1dma_writel(card, card->csr, AMCC_INTCSR);
253
254 if (b1dma_readl(card, AMCC_MCSR) != 0x000000E6)
255 return 1;
256
257 b1dma_writel(card, 0xffffffff, AMCC_RXPTR);
258 b1dma_writel(card, 0xffffffff, AMCC_TXPTR);
259 if ( b1dma_readl(card, AMCC_RXPTR) != 0xfffffffc
260 || b1dma_readl(card, AMCC_TXPTR) != 0xfffffffc)
261 return 2;
262
263 b1dma_writel(card, 0x0, AMCC_RXPTR);
264 b1dma_writel(card, 0x0, AMCC_TXPTR);
265 if ( b1dma_readl(card, AMCC_RXPTR) != 0x0
266 || b1dma_readl(card, AMCC_TXPTR) != 0x0)
267 return 3;
268
269 t1outp(card->port, 0x10, 0x00);
270 t1outp(card->port, 0x07, 0x00);
271
272 t1outp(card->port, 0x02, 0x02);
273 t1outp(card->port, 0x03, 0x02);
274
275 if ( (t1inp(card->port, 0x02) & 0xFE) != 0x02
276 || t1inp(card->port, 0x3) != 0x03)
277 return 4;
278
279 t1outp(card->port, 0x02, 0x00);
280 t1outp(card->port, 0x03, 0x00);
281
282 if ( (t1inp(card->port, 0x02) & 0xFE) != 0x00
283 || t1inp(card->port, 0x3) != 0x01)
284 return 5;
285
286 return 0;
287}
288
289int t1pci_detect(avmcard *card)
290{
291 int ret;
292
293 if ((ret = b1dma_detect(card)) != 0)
294 return ret;
295
296 /* Transputer test */
297
298 if ( WriteReg(card, 0x80001000, 0x11) != 0
299 || WriteReg(card, 0x80101000, 0x22) != 0
300 || WriteReg(card, 0x80201000, 0x33) != 0
301 || WriteReg(card, 0x80301000, 0x44) != 0)
302 return 6;
303
304 if ( ReadReg(card, 0x80001000) != 0x11
305 || ReadReg(card, 0x80101000) != 0x22
306 || ReadReg(card, 0x80201000) != 0x33
307 || ReadReg(card, 0x80301000) != 0x44)
308 return 7;
309
310 if ( WriteReg(card, 0x80001000, 0x55) != 0
311 || WriteReg(card, 0x80101000, 0x66) != 0
312 || WriteReg(card, 0x80201000, 0x77) != 0
313 || WriteReg(card, 0x80301000, 0x88) != 0)
314 return 8;
315
316 if ( ReadReg(card, 0x80001000) != 0x55
317 || ReadReg(card, 0x80101000) != 0x66
318 || ReadReg(card, 0x80201000) != 0x77
319 || ReadReg(card, 0x80301000) != 0x88)
320 return 9;
321
322 return 0;
323}
324
325int b1pciv4_detect(avmcard *card)
326{
327 int ret, i;
328
329 if ((ret = b1dma_detect(card)) != 0)
330 return ret;
331
332 for (i=0; i < 5 ; i++) {
333 if (WriteReg(card, 0x80A00000, 0x21) != 0)
334 return 6;
335 if ((ReadReg(card, 0x80A00000) & 0x01) != 0x01)
336 return 7;
337 }
338 for (i=0; i < 5 ; i++) {
339 if (WriteReg(card, 0x80A00000, 0x20) != 0)
340 return 8;
341 if ((ReadReg(card, 0x80A00000) & 0x01) != 0x00)
342 return 9;
343 }
344
345 return 0;
346}
347
348static void b1dma_queue_tx(avmcard *card, struct sk_buff *skb)
349{
350 unsigned long flags;
351
352 spin_lock_irqsave(&card->lock, flags);
353
354 skb_queue_tail(&card->dma->send_queue, skb);
355
356 if (!(card->csr & EN_TX_TC_INT)) {
357 b1dma_dispatch_tx(card);
358 b1dma_writel(card, card->csr, AMCC_INTCSR);
359 }
360
361 spin_unlock_irqrestore(&card->lock, flags);
362}
363
364/* ------------------------------------------------------------- */
365
366static void b1dma_dispatch_tx(avmcard *card)
367{
368 avmcard_dmainfo *dma = card->dma;
369 struct sk_buff *skb;
370 u8 cmd, subcmd;
371 u16 len;
372 u32 txlen;
373 void *p;
374
375 skb = skb_dequeue(&dma->send_queue);
376
377 len = CAPIMSG_LEN(skb->data);
378
379 if (len) {
380 cmd = CAPIMSG_COMMAND(skb->data);
381 subcmd = CAPIMSG_SUBCOMMAND(skb->data);
382
383 p = dma->sendbuf.dmabuf;
384
385 if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) {
386 u16 dlen = CAPIMSG_DATALEN(skb->data);
387 _put_byte(&p, SEND_DATA_B3_REQ);
388 _put_slice(&p, skb->data, len);
389 _put_slice(&p, skb->data + len, dlen);
390 } else {
391 _put_byte(&p, SEND_MESSAGE);
392 _put_slice(&p, skb->data, len);
393 }
394 txlen = (u8 *)p - (u8 *)dma->sendbuf.dmabuf;
395#ifdef CONFIG_B1DMA_DEBUG
396 printk(KERN_DEBUG "tx: put msg len=%d\n", txlen);
397#endif
398 } else {
399 txlen = skb->len-2;
400#ifdef CONFIG_B1DMA_POLLDEBUG
401 if (skb->data[2] == SEND_POLLACK)
402 printk(KERN_INFO "%s: send ack\n", card->name);
403#endif
404#ifdef CONFIG_B1DMA_DEBUG
405 printk(KERN_DEBUG "tx: put 0x%x len=%d\n",
406 skb->data[2], txlen);
407#endif
408 memcpy(dma->sendbuf.dmabuf, skb->data+2, skb->len-2);
409 }
410 txlen = (txlen + 3) & ~3;
411
412 b1dma_writel(card, dma->sendbuf.dmaaddr, AMCC_TXPTR);
413 b1dma_writel(card, txlen, AMCC_TXLEN);
414
415 card->csr |= EN_TX_TC_INT;
416
417 dev_kfree_skb_any(skb);
418}
419
420/* ------------------------------------------------------------- */
421
422static void queue_pollack(avmcard *card)
423{
424 struct sk_buff *skb;
425 void *p;
426
427 skb = alloc_skb(3, GFP_ATOMIC);
428 if (!skb) {
429 printk(KERN_CRIT "%s: no memory, lost poll ack\n",
430 card->name);
431 return;
432 }
433 p = skb->data;
434 _put_byte(&p, 0);
435 _put_byte(&p, 0);
436 _put_byte(&p, SEND_POLLACK);
437 skb_put(skb, (u8 *)p - (u8 *)skb->data);
438
439 b1dma_queue_tx(card, skb);
440}
441
442/* ------------------------------------------------------------- */
443
444static void b1dma_handle_rx(avmcard *card)
445{
446 avmctrl_info *cinfo = &card->ctrlinfo[0];
447 avmcard_dmainfo *dma = card->dma;
448 struct capi_ctr *ctrl = &cinfo->capi_ctrl;
449 struct sk_buff *skb;
450 void *p = dma->recvbuf.dmabuf+4;
451 u32 ApplId, MsgLen, DataB3Len, NCCI, WindowSize;
452 u8 b1cmd = _get_byte(&p);
453
454#ifdef CONFIG_B1DMA_DEBUG
455 printk(KERN_DEBUG "rx: 0x%x %lu\n", b1cmd, (unsigned long)dma->recvlen);
456#endif
457
458 switch (b1cmd) {
459 case RECEIVE_DATA_B3_IND:
460
461 ApplId = (unsigned) _get_word(&p);
462 MsgLen = _get_slice(&p, card->msgbuf);
463 DataB3Len = _get_slice(&p, card->databuf);
464
465 if (MsgLen < 30) { /* not CAPI 64Bit */
466 memset(card->msgbuf+MsgLen, 0, 30-MsgLen);
467 MsgLen = 30;
468 CAPIMSG_SETLEN(card->msgbuf, 30);
469 }
470 if (!(skb = alloc_skb(DataB3Len+MsgLen, GFP_ATOMIC))) {
471 printk(KERN_ERR "%s: incoming packet dropped\n",
472 card->name);
473 } else {
474 memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);
475 memcpy(skb_put(skb, DataB3Len), card->databuf, DataB3Len);
476 capi_ctr_handle_message(ctrl, ApplId, skb);
477 }
478 break;
479
480 case RECEIVE_MESSAGE:
481
482 ApplId = (unsigned) _get_word(&p);
483 MsgLen = _get_slice(&p, card->msgbuf);
484 if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) {
485 printk(KERN_ERR "%s: incoming packet dropped\n",
486 card->name);
487 } else {
488 memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);
489 if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_CONF)
490 capilib_data_b3_conf(&cinfo->ncci_head, ApplId,
491 CAPIMSG_NCCI(skb->data),
492 CAPIMSG_MSGID(skb->data));
493
494 capi_ctr_handle_message(ctrl, ApplId, skb);
495 }
496 break;
497
498 case RECEIVE_NEW_NCCI:
499
500 ApplId = _get_word(&p);
501 NCCI = _get_word(&p);
502 WindowSize = _get_word(&p);
503
504 capilib_new_ncci(&cinfo->ncci_head, ApplId, NCCI, WindowSize);
505
506 break;
507
508 case RECEIVE_FREE_NCCI:
509
510 ApplId = _get_word(&p);
511 NCCI = _get_word(&p);
512
513 if (NCCI != 0xffffffff)
514 capilib_free_ncci(&cinfo->ncci_head, ApplId, NCCI);
515
516 break;
517
518 case RECEIVE_START:
519#ifdef CONFIG_B1DMA_POLLDEBUG
520 printk(KERN_INFO "%s: receive poll\n", card->name);
521#endif
522 if (!suppress_pollack)
523 queue_pollack(card);
524 capi_ctr_resume_output(ctrl);
525 break;
526
527 case RECEIVE_STOP:
528 capi_ctr_suspend_output(ctrl);
529 break;
530
531 case RECEIVE_INIT:
532
533 cinfo->versionlen = _get_slice(&p, cinfo->versionbuf);
534 b1_parse_version(cinfo);
535 printk(KERN_INFO "%s: %s-card (%s) now active\n",
536 card->name,
537 cinfo->version[VER_CARDTYPE],
538 cinfo->version[VER_DRIVER]);
539 capi_ctr_ready(ctrl);
540 break;
541
542 case RECEIVE_TASK_READY:
543 ApplId = (unsigned) _get_word(&p);
544 MsgLen = _get_slice(&p, card->msgbuf);
545 card->msgbuf[MsgLen] = 0;
546 while ( MsgLen > 0
547 && ( card->msgbuf[MsgLen-1] == '\n'
548 || card->msgbuf[MsgLen-1] == '\r')) {
549 card->msgbuf[MsgLen-1] = 0;
550 MsgLen--;
551 }
552 printk(KERN_INFO "%s: task %d \"%s\" ready.\n",
553 card->name, ApplId, card->msgbuf);
554 break;
555
556 case RECEIVE_DEBUGMSG:
557 MsgLen = _get_slice(&p, card->msgbuf);
558 card->msgbuf[MsgLen] = 0;
559 while ( MsgLen > 0
560 && ( card->msgbuf[MsgLen-1] == '\n'
561 || card->msgbuf[MsgLen-1] == '\r')) {
562 card->msgbuf[MsgLen-1] = 0;
563 MsgLen--;
564 }
565 printk(KERN_INFO "%s: DEBUG: %s\n", card->name, card->msgbuf);
566 break;
567
568 default:
569 printk(KERN_ERR "%s: b1dma_interrupt: 0x%x ???\n",
570 card->name, b1cmd);
571 return;
572 }
573}
574
575/* ------------------------------------------------------------- */
576
577static void b1dma_handle_interrupt(avmcard *card)
578{
579 u32 status;
580 u32 newcsr;
581
582 spin_lock(&card->lock);
583
584 status = b1dma_readl(card, AMCC_INTCSR);
585 if ((status & ANY_S5933_INT) == 0) {
586 spin_unlock(&card->lock);
587 return;
588 }
589
590 newcsr = card->csr | (status & ALL_INT);
591 if (status & TX_TC_INT) newcsr &= ~EN_TX_TC_INT;
592 if (status & RX_TC_INT) newcsr &= ~EN_RX_TC_INT;
593 b1dma_writel(card, newcsr, AMCC_INTCSR);
594
595 if ((status & RX_TC_INT) != 0) {
596 struct avmcard_dmainfo *dma = card->dma;
597 u32 rxlen;
598 if (card->dma->recvlen == 0) {
599 rxlen = b1dma_readl(card, AMCC_RXLEN);
600 if (rxlen == 0) {
601 dma->recvlen = *((u32 *)dma->recvbuf.dmabuf);
602 rxlen = (dma->recvlen + 3) & ~3;
603 b1dma_writel(card, dma->recvbuf.dmaaddr+4, AMCC_RXPTR);
604 b1dma_writel(card, rxlen, AMCC_RXLEN);
605#ifdef CONFIG_B1DMA_DEBUG
606 } else {
607 printk(KERN_ERR "%s: rx not complete (%d).\n",
608 card->name, rxlen);
609#endif
610 }
611 } else {
612 spin_unlock(&card->lock);
613 b1dma_handle_rx(card);
614 dma->recvlen = 0;
615 spin_lock(&card->lock);
616 b1dma_writel(card, dma->recvbuf.dmaaddr, AMCC_RXPTR);
617 b1dma_writel(card, 4, AMCC_RXLEN);
618 }
619 }
620
621 if ((status & TX_TC_INT) != 0) {
622 if (skb_queue_empty(&card->dma->send_queue))
623 card->csr &= ~EN_TX_TC_INT;
624 else
625 b1dma_dispatch_tx(card);
626 }
627 b1dma_writel(card, card->csr, AMCC_INTCSR);
628
629 spin_unlock(&card->lock);
630}
631
632irqreturn_t b1dma_interrupt(int interrupt, void *devptr, struct pt_regs *regs)
633{
634 avmcard *card = devptr;
635
636 b1dma_handle_interrupt(card);
637 return IRQ_HANDLED;
638}
639
640/* ------------------------------------------------------------- */
641
642static int b1dma_loaded(avmcard *card)
643{
644 unsigned long stop;
645 unsigned char ans;
646 unsigned long tout = 2;
647 unsigned int base = card->port;
648
649 for (stop = jiffies + tout * HZ; time_before(jiffies, stop);) {
650 if (b1_tx_empty(base))
651 break;
652 }
653 if (!b1_tx_empty(base)) {
654 printk(KERN_ERR "%s: b1dma_loaded: tx err, corrupted t4 file ?\n",
655 card->name);
656 return 0;
657 }
658 b1_put_byte(base, SEND_POLLACK);
659 for (stop = jiffies + tout * HZ; time_before(jiffies, stop);) {
660 if (b1_rx_full(base)) {
661 if ((ans = b1_get_byte(base)) == RECEIVE_POLLDWORD) {
662 return 1;
663 }
664 printk(KERN_ERR "%s: b1dma_loaded: got 0x%x, firmware not running in dword mode\n", card->name, ans);
665 return 0;
666 }
667 }
668 printk(KERN_ERR "%s: b1dma_loaded: firmware not running\n", card->name);
669 return 0;
670}
671
672/* ------------------------------------------------------------- */
673
674static void b1dma_send_init(avmcard *card)
675{
676 struct sk_buff *skb;
677 void *p;
678
679 skb = alloc_skb(15, GFP_ATOMIC);
680 if (!skb) {
681 printk(KERN_CRIT "%s: no memory, lost register appl.\n",
682 card->name);
683 return;
684 }
685 p = skb->data;
686 _put_byte(&p, 0);
687 _put_byte(&p, 0);
688 _put_byte(&p, SEND_INIT);
689 _put_word(&p, CAPI_MAXAPPL);
690 _put_word(&p, AVM_NCCI_PER_CHANNEL*30);
691 _put_word(&p, card->cardnr - 1);
692 skb_put(skb, (u8 *)p - (u8 *)skb->data);
693
694 b1dma_queue_tx(card, skb);
695}
696
697int b1dma_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
698{
699 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
700 avmcard *card = cinfo->card;
701 int retval;
702
703 b1dma_reset(card);
704
705 if ((retval = b1_load_t4file(card, &data->firmware))) {
706 b1dma_reset(card);
707 printk(KERN_ERR "%s: failed to load t4file!!\n",
708 card->name);
709 return retval;
710 }
711
712 if (data->configuration.len > 0 && data->configuration.data) {
713 if ((retval = b1_load_config(card, &data->configuration))) {
714 b1dma_reset(card);
715 printk(KERN_ERR "%s: failed to load config!!\n",
716 card->name);
717 return retval;
718 }
719 }
720
721 if (!b1dma_loaded(card)) {
722 b1dma_reset(card);
723 printk(KERN_ERR "%s: failed to load t4file.\n", card->name);
724 return -EIO;
725 }
726
727 card->csr = AVM_FLAG;
728 b1dma_writel(card, card->csr, AMCC_INTCSR);
729 b1dma_writel(card, EN_A2P_TRANSFERS|EN_P2A_TRANSFERS|A2P_HI_PRIORITY|
730 P2A_HI_PRIORITY|RESET_A2P_FLAGS|RESET_P2A_FLAGS,
731 AMCC_MCSR);
732 t1outp(card->port, 0x07, 0x30);
733 t1outp(card->port, 0x10, 0xF0);
734
735 card->dma->recvlen = 0;
736 b1dma_writel(card, card->dma->recvbuf.dmaaddr, AMCC_RXPTR);
737 b1dma_writel(card, 4, AMCC_RXLEN);
738 card->csr |= EN_RX_TC_INT;
739 b1dma_writel(card, card->csr, AMCC_INTCSR);
740
741 b1dma_send_init(card);
742
743 return 0;
744}
745
746void b1dma_reset_ctr(struct capi_ctr *ctrl)
747{
748 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
749 avmcard *card = cinfo->card;
750 unsigned long flags;
751
752 spin_lock_irqsave(&card->lock, flags);
753 b1dma_reset(card);
754 spin_unlock_irqrestore(&card->lock, flags);
755
756 memset(cinfo->version, 0, sizeof(cinfo->version));
757 capilib_release(&cinfo->ncci_head);
758 capi_ctr_reseted(ctrl);
759}
760
761/* ------------------------------------------------------------- */
762
763void b1dma_register_appl(struct capi_ctr *ctrl,
764 u16 appl,
765 capi_register_params *rp)
766{
767 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
768 avmcard *card = cinfo->card;
769 struct sk_buff *skb;
770 int want = rp->level3cnt;
771 int nconn;
772 void *p;
773
774 if (want > 0) nconn = want;
775 else nconn = ctrl->profile.nbchannel * -want;
776 if (nconn == 0) nconn = ctrl->profile.nbchannel;
777
778 skb = alloc_skb(23, GFP_ATOMIC);
779 if (!skb) {
780 printk(KERN_CRIT "%s: no memory, lost register appl.\n",
781 card->name);
782 return;
783 }
784 p = skb->data;
785 _put_byte(&p, 0);
786 _put_byte(&p, 0);
787 _put_byte(&p, SEND_REGISTER);
788 _put_word(&p, appl);
789 _put_word(&p, 1024 * (nconn+1));
790 _put_word(&p, nconn);
791 _put_word(&p, rp->datablkcnt);
792 _put_word(&p, rp->datablklen);
793 skb_put(skb, (u8 *)p - (u8 *)skb->data);
794
795 b1dma_queue_tx(card, skb);
796}
797
798/* ------------------------------------------------------------- */
799
800void b1dma_release_appl(struct capi_ctr *ctrl, u16 appl)
801{
802 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
803 avmcard *card = cinfo->card;
804 struct sk_buff *skb;
805 void *p;
806
807 capilib_release_appl(&cinfo->ncci_head, appl);
808
809 skb = alloc_skb(7, GFP_ATOMIC);
810 if (!skb) {
811 printk(KERN_CRIT "%s: no memory, lost release appl.\n",
812 card->name);
813 return;
814 }
815 p = skb->data;
816 _put_byte(&p, 0);
817 _put_byte(&p, 0);
818 _put_byte(&p, SEND_RELEASE);
819 _put_word(&p, appl);
820
821 skb_put(skb, (u8 *)p - (u8 *)skb->data);
822
823 b1dma_queue_tx(card, skb);
824}
825
826/* ------------------------------------------------------------- */
827
828u16 b1dma_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
829{
830 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
831 avmcard *card = cinfo->card;
832 u16 retval = CAPI_NOERROR;
833
834 if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) {
835 retval = capilib_data_b3_req(&cinfo->ncci_head,
836 CAPIMSG_APPID(skb->data),
837 CAPIMSG_NCCI(skb->data),
838 CAPIMSG_MSGID(skb->data));
839 }
840 if (retval == CAPI_NOERROR)
841 b1dma_queue_tx(card, skb);
842
843 return retval;
844}
845
846/* ------------------------------------------------------------- */
847
848int b1dmactl_read_proc(char *page, char **start, off_t off,
849 int count, int *eof, struct capi_ctr *ctrl)
850{
851 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
852 avmcard *card = cinfo->card;
853 u8 flag;
854 int len = 0;
855 char *s;
856 u32 txoff, txlen, rxoff, rxlen, csr;
857 unsigned long flags;
858
859 len += sprintf(page+len, "%-16s %s\n", "name", card->name);
860 len += sprintf(page+len, "%-16s 0x%x\n", "io", card->port);
861 len += sprintf(page+len, "%-16s %d\n", "irq", card->irq);
862 len += sprintf(page+len, "%-16s 0x%lx\n", "membase", card->membase);
863 switch (card->cardtype) {
864 case avm_b1isa: s = "B1 ISA"; break;
865 case avm_b1pci: s = "B1 PCI"; break;
866 case avm_b1pcmcia: s = "B1 PCMCIA"; break;
867 case avm_m1: s = "M1"; break;
868 case avm_m2: s = "M2"; break;
869 case avm_t1isa: s = "T1 ISA (HEMA)"; break;
870 case avm_t1pci: s = "T1 PCI"; break;
871 case avm_c4: s = "C4"; break;
872 case avm_c2: s = "C2"; break;
873 default: s = "???"; break;
874 }
875 len += sprintf(page+len, "%-16s %s\n", "type", s);
876 if ((s = cinfo->version[VER_DRIVER]) != 0)
877 len += sprintf(page+len, "%-16s %s\n", "ver_driver", s);
878 if ((s = cinfo->version[VER_CARDTYPE]) != 0)
879 len += sprintf(page+len, "%-16s %s\n", "ver_cardtype", s);
880 if ((s = cinfo->version[VER_SERIAL]) != 0)
881 len += sprintf(page+len, "%-16s %s\n", "ver_serial", s);
882
883 if (card->cardtype != avm_m1) {
884 flag = ((u8 *)(ctrl->profile.manu))[3];
885 if (flag)
886 len += sprintf(page+len, "%-16s%s%s%s%s%s%s%s\n",
887 "protocol",
888 (flag & 0x01) ? " DSS1" : "",
889 (flag & 0x02) ? " CT1" : "",
890 (flag & 0x04) ? " VN3" : "",
891 (flag & 0x08) ? " NI1" : "",
892 (flag & 0x10) ? " AUSTEL" : "",
893 (flag & 0x20) ? " ESS" : "",
894 (flag & 0x40) ? " 1TR6" : ""
895 );
896 }
897 if (card->cardtype != avm_m1) {
898 flag = ((u8 *)(ctrl->profile.manu))[5];
899 if (flag)
900 len += sprintf(page+len, "%-16s%s%s%s%s\n",
901 "linetype",
902 (flag & 0x01) ? " point to point" : "",
903 (flag & 0x02) ? " point to multipoint" : "",
904 (flag & 0x08) ? " leased line without D-channel" : "",
905 (flag & 0x04) ? " leased line with D-channel" : ""
906 );
907 }
908 len += sprintf(page+len, "%-16s %s\n", "cardname", cinfo->cardname);
909
910
911 spin_lock_irqsave(&card->lock, flags);
912
913 txoff = (dma_addr_t)b1dma_readl(card, AMCC_TXPTR)-card->dma->sendbuf.dmaaddr;
914 txlen = b1dma_readl(card, AMCC_TXLEN);
915
916 rxoff = (dma_addr_t)b1dma_readl(card, AMCC_RXPTR)-card->dma->recvbuf.dmaaddr;
917 rxlen = b1dma_readl(card, AMCC_RXLEN);
918
919 csr = b1dma_readl(card, AMCC_INTCSR);
920
921 spin_unlock_irqrestore(&card->lock, flags);
922
923 len += sprintf(page+len, "%-16s 0x%lx\n",
924 "csr (cached)", (unsigned long)card->csr);
925 len += sprintf(page+len, "%-16s 0x%lx\n",
926 "csr", (unsigned long)csr);
927 len += sprintf(page+len, "%-16s %lu\n",
928 "txoff", (unsigned long)txoff);
929 len += sprintf(page+len, "%-16s %lu\n",
930 "txlen", (unsigned long)txlen);
931 len += sprintf(page+len, "%-16s %lu\n",
932 "rxoff", (unsigned long)rxoff);
933 len += sprintf(page+len, "%-16s %lu\n",
934 "rxlen", (unsigned long)rxlen);
935
936 if (off+count >= len)
937 *eof = 1;
938 if (len < off)
939 return 0;
940 *start = page + off;
941 return ((count < len-off) ? count : len-off);
942}
943
944/* ------------------------------------------------------------- */
945
946EXPORT_SYMBOL(b1dma_reset);
947EXPORT_SYMBOL(t1pci_detect);
948EXPORT_SYMBOL(b1pciv4_detect);
949EXPORT_SYMBOL(b1dma_interrupt);
950
951EXPORT_SYMBOL(b1dma_load_firmware);
952EXPORT_SYMBOL(b1dma_reset_ctr);
953EXPORT_SYMBOL(b1dma_register_appl);
954EXPORT_SYMBOL(b1dma_release_appl);
955EXPORT_SYMBOL(b1dma_send_message);
956EXPORT_SYMBOL(b1dmactl_read_proc);
957
958int b1dma_init(void)
959{
960 char *p;
961 char rev[32];
962
963 if ((p = strchr(revision, ':')) != 0 && p[1]) {
964 strlcpy(rev, p + 2, sizeof(rev));
965 if ((p = strchr(rev, '$')) != 0 && p > rev)
966 *(p-1) = 0;
967 } else
968 strcpy(rev, "1.0");
969
970 printk(KERN_INFO "b1dma: revision %s\n", rev);
971
972 return 0;
973}
974
975void b1dma_exit(void)
976{
977}
978
979module_init(b1dma_init);
980module_exit(b1dma_exit);
diff --git a/drivers/isdn/hardware/avm/b1isa.c b/drivers/isdn/hardware/avm/b1isa.c
new file mode 100644
index 000000000000..38bd4dfecbd1
--- /dev/null
+++ b/drivers/isdn/hardware/avm/b1isa.c
@@ -0,0 +1,245 @@
1/* $Id: b1isa.c,v 1.1.2.3 2004/02/10 01:07:12 keil Exp $
2 *
3 * Module for AVM B1 ISA-card.
4 *
5 * Copyright 1999 by Carsten Paeth <calle@calle.de>
6 *
7 * This software may be used and distributed according to the terms
8 * of the GNU General Public License, incorporated herein by reference.
9 *
10 */
11
12#include <linux/module.h>
13#include <linux/kernel.h>
14#include <linux/skbuff.h>
15#include <linux/delay.h>
16#include <linux/mm.h>
17#include <linux/interrupt.h>
18#include <linux/ioport.h>
19#include <linux/capi.h>
20#include <linux/init.h>
21#include <linux/pci.h>
22#include <asm/io.h>
23#include <linux/isdn/capicmd.h>
24#include <linux/isdn/capiutil.h>
25#include <linux/isdn/capilli.h>
26#include "avmcard.h"
27
28/* ------------------------------------------------------------- */
29
30static char *revision = "$Revision: 1.1.2.3 $";
31
32/* ------------------------------------------------------------- */
33
34MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM B1 ISA card");
35MODULE_AUTHOR("Carsten Paeth");
36MODULE_LICENSE("GPL");
37
38/* ------------------------------------------------------------- */
39
40static void b1isa_remove(struct pci_dev *pdev)
41{
42 avmctrl_info *cinfo = pci_get_drvdata(pdev);
43 avmcard *card;
44
45 if (!cinfo)
46 return;
47
48 card = cinfo->card;
49
50 b1_reset(card->port);
51 b1_reset(card->port);
52
53 detach_capi_ctr(&cinfo->capi_ctrl);
54 free_irq(card->irq, card);
55 release_region(card->port, AVMB1_PORTLEN);
56 b1_free_card(card);
57}
58
59/* ------------------------------------------------------------- */
60
61static char *b1isa_procinfo(struct capi_ctr *ctrl);
62
63static int b1isa_probe(struct pci_dev *pdev)
64{
65 avmctrl_info *cinfo;
66 avmcard *card;
67 int retval;
68
69 card = b1_alloc_card(1);
70 if (!card) {
71 printk(KERN_WARNING "b1isa: no memory.\n");
72 retval = -ENOMEM;
73 goto err;
74 }
75
76 cinfo = card->ctrlinfo;
77
78 card->port = pci_resource_start(pdev, 0);
79 card->irq = pdev->irq;
80 card->cardtype = avm_b1isa;
81 sprintf(card->name, "b1isa-%x", card->port);
82
83 if ( card->port != 0x150 && card->port != 0x250
84 && card->port != 0x300 && card->port != 0x340) {
85 printk(KERN_WARNING "b1isa: invalid port 0x%x.\n", card->port);
86 retval = -EINVAL;
87 goto err_free;
88 }
89 if (b1_irq_table[card->irq & 0xf] == 0) {
90 printk(KERN_WARNING "b1isa: irq %d not valid.\n", card->irq);
91 retval = -EINVAL;
92 goto err_free;
93 }
94 if (!request_region(card->port, AVMB1_PORTLEN, card->name)) {
95 printk(KERN_WARNING "b1isa: ports 0x%03x-0x%03x in use.\n",
96 card->port, card->port + AVMB1_PORTLEN);
97 retval = -EBUSY;
98 goto err_free;
99 }
100 retval = request_irq(card->irq, b1_interrupt, 0, card->name, card);
101 if (retval) {
102 printk(KERN_ERR "b1isa: unable to get IRQ %d.\n", card->irq);
103 goto err_release_region;
104 }
105 b1_reset(card->port);
106 if ((retval = b1_detect(card->port, card->cardtype)) != 0) {
107 printk(KERN_NOTICE "b1isa: NO card at 0x%x (%d)\n",
108 card->port, retval);
109 retval = -ENODEV;
110 goto err_free_irq;
111 }
112 b1_reset(card->port);
113 b1_getrevision(card);
114
115 cinfo->capi_ctrl.owner = THIS_MODULE;
116 cinfo->capi_ctrl.driver_name = "b1isa";
117 cinfo->capi_ctrl.driverdata = cinfo;
118 cinfo->capi_ctrl.register_appl = b1_register_appl;
119 cinfo->capi_ctrl.release_appl = b1_release_appl;
120 cinfo->capi_ctrl.send_message = b1_send_message;
121 cinfo->capi_ctrl.load_firmware = b1_load_firmware;
122 cinfo->capi_ctrl.reset_ctr = b1_reset_ctr;
123 cinfo->capi_ctrl.procinfo = b1isa_procinfo;
124 cinfo->capi_ctrl.ctr_read_proc = b1ctl_read_proc;
125 strcpy(cinfo->capi_ctrl.name, card->name);
126
127 retval = attach_capi_ctr(&cinfo->capi_ctrl);
128 if (retval) {
129 printk(KERN_ERR "b1isa: attach controller failed.\n");
130 goto err_free_irq;
131 }
132
133 printk(KERN_INFO "b1isa: AVM B1 ISA at i/o %#x, irq %d, revision %d\n",
134 card->port, card->irq, card->revision);
135
136 pci_set_drvdata(pdev, cinfo);
137 return 0;
138
139 err_free_irq:
140 free_irq(card->irq, card);
141 err_release_region:
142 release_region(card->port, AVMB1_PORTLEN);
143 err_free:
144 b1_free_card(card);
145 err:
146 return retval;
147}
148
149static char *b1isa_procinfo(struct capi_ctr *ctrl)
150{
151 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
152
153 if (!cinfo)
154 return "";
155 sprintf(cinfo->infobuf, "%s %s 0x%x %d r%d",
156 cinfo->cardname[0] ? cinfo->cardname : "-",
157 cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-",
158 cinfo->card ? cinfo->card->port : 0x0,
159 cinfo->card ? cinfo->card->irq : 0,
160 cinfo->card ? cinfo->card->revision : 0
161 );
162 return cinfo->infobuf;
163}
164
165/* ------------------------------------------------------------- */
166
167#define MAX_CARDS 4
168static struct pci_dev isa_dev[MAX_CARDS];
169static int io[MAX_CARDS];
170static int irq[MAX_CARDS];
171
172MODULE_PARM(io, "1-" __MODULE_STRING(MAX_CARDS) "i");
173MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_CARDS) "i");
174MODULE_PARM_DESC(io, "I/O base address(es)");
175MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)");
176
177static int b1isa_add_card(struct capi_driver *driver, capicardparams *data)
178{
179 int i;
180
181 for (i = 0; i < MAX_CARDS; i++) {
182 if (isa_dev[i].resource[0].start)
183 continue;
184
185 isa_dev[i].resource[0].start = data->port;
186 isa_dev[i].irq = data->irq;
187
188 if (b1isa_probe(&isa_dev[i]) == 0)
189 return 0;
190 }
191 return -ENODEV;
192}
193
194static struct capi_driver capi_driver_b1isa = {
195 .name = "b1isa",
196 .revision = "1.0",
197 .add_card = b1isa_add_card,
198};
199
200static int __init b1isa_init(void)
201{
202 char *p;
203 char rev[32];
204 int i;
205
206 if ((p = strchr(revision, ':')) != 0 && p[1]) {
207 strlcpy(rev, p + 2, 32);
208 if ((p = strchr(rev, '$')) != 0 && p > rev)
209 *(p-1) = 0;
210 } else
211 strcpy(rev, "1.0");
212
213 for (i = 0; i < MAX_CARDS; i++) {
214 if (!io[i])
215 break;
216
217 isa_dev[i].resource[0].start = io[i];
218 isa_dev[i].irq = irq[i];
219
220 if (b1isa_probe(&isa_dev[i]) != 0)
221 return -ENODEV;
222 }
223
224 strlcpy(capi_driver_b1isa.revision, rev, 32);
225 register_capi_driver(&capi_driver_b1isa);
226 printk(KERN_INFO "b1isa: revision %s\n", rev);
227
228 return 0;
229}
230
231static void __exit b1isa_exit(void)
232{
233 int i;
234
235 for (i = 0; i < MAX_CARDS; i++) {
236 if (!io[i])
237 break;
238
239 b1isa_remove(&isa_dev[i]);
240 }
241 unregister_capi_driver(&capi_driver_b1isa);
242}
243
244module_init(b1isa_init);
245module_exit(b1isa_exit);
diff --git a/drivers/isdn/hardware/avm/b1pci.c b/drivers/isdn/hardware/avm/b1pci.c
new file mode 100644
index 000000000000..5435a6cfb5e7
--- /dev/null
+++ b/drivers/isdn/hardware/avm/b1pci.c
@@ -0,0 +1,417 @@
1/* $Id: b1pci.c,v 1.1.2.2 2004/01/16 21:09:27 keil Exp $
2 *
3 * Module for AVM B1 PCI-card.
4 *
5 * Copyright 1999 by Carsten Paeth <calle@calle.de>
6 *
7 * This software may be used and distributed according to the terms
8 * of the GNU General Public License, incorporated herein by reference.
9 *
10 */
11
12#include <linux/config.h>
13#include <linux/module.h>
14#include <linux/kernel.h>
15#include <linux/skbuff.h>
16#include <linux/delay.h>
17#include <linux/mm.h>
18#include <linux/interrupt.h>
19#include <linux/ioport.h>
20#include <linux/pci.h>
21#include <linux/capi.h>
22#include <asm/io.h>
23#include <linux/init.h>
24#include <linux/isdn/capicmd.h>
25#include <linux/isdn/capiutil.h>
26#include <linux/isdn/capilli.h>
27#include "avmcard.h"
28
29/* ------------------------------------------------------------- */
30
31static char *revision = "$Revision: 1.1.2.2 $";
32
33/* ------------------------------------------------------------- */
34
35static struct pci_device_id b1pci_pci_tbl[] = {
36 { PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_B1, PCI_ANY_ID, PCI_ANY_ID },
37 { } /* Terminating entry */
38};
39
40MODULE_DEVICE_TABLE(pci, b1pci_pci_tbl);
41MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM B1 PCI card");
42MODULE_AUTHOR("Carsten Paeth");
43MODULE_LICENSE("GPL");
44
45/* ------------------------------------------------------------- */
46
47static char *b1pci_procinfo(struct capi_ctr *ctrl)
48{
49 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
50
51 if (!cinfo)
52 return "";
53 sprintf(cinfo->infobuf, "%s %s 0x%x %d r%d",
54 cinfo->cardname[0] ? cinfo->cardname : "-",
55 cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-",
56 cinfo->card ? cinfo->card->port : 0x0,
57 cinfo->card ? cinfo->card->irq : 0,
58 cinfo->card ? cinfo->card->revision : 0
59 );
60 return cinfo->infobuf;
61}
62
63/* ------------------------------------------------------------- */
64
65static int b1pci_probe(struct capicardparams *p, struct pci_dev *pdev)
66{
67 avmcard *card;
68 avmctrl_info *cinfo;
69 int retval;
70
71 card = b1_alloc_card(1);
72 if (!card) {
73 printk(KERN_WARNING "b1pci: no memory.\n");
74 retval = -ENOMEM;
75 goto err;
76 }
77
78 cinfo = card->ctrlinfo;
79 sprintf(card->name, "b1pci-%x", p->port);
80 card->port = p->port;
81 card->irq = p->irq;
82 card->cardtype = avm_b1pci;
83
84 if (!request_region(card->port, AVMB1_PORTLEN, card->name)) {
85 printk(KERN_WARNING "b1pci: ports 0x%03x-0x%03x in use.\n",
86 card->port, card->port + AVMB1_PORTLEN);
87 retval = -EBUSY;
88 goto err_free;
89 }
90 b1_reset(card->port);
91 retval = b1_detect(card->port, card->cardtype);
92 if (retval) {
93 printk(KERN_NOTICE "b1pci: NO card at 0x%x (%d)\n",
94 card->port, retval);
95 retval = -ENODEV;
96 goto err_release_region;
97 }
98 b1_reset(card->port);
99 b1_getrevision(card);
100
101 retval = request_irq(card->irq, b1_interrupt, SA_SHIRQ, card->name, card);
102 if (retval) {
103 printk(KERN_ERR "b1pci: unable to get IRQ %d.\n", card->irq);
104 retval = -EBUSY;
105 goto err_release_region;
106 }
107
108 cinfo->capi_ctrl.driver_name = "b1pci";
109 cinfo->capi_ctrl.driverdata = cinfo;
110 cinfo->capi_ctrl.register_appl = b1_register_appl;
111 cinfo->capi_ctrl.release_appl = b1_release_appl;
112 cinfo->capi_ctrl.send_message = b1_send_message;
113 cinfo->capi_ctrl.load_firmware = b1_load_firmware;
114 cinfo->capi_ctrl.reset_ctr = b1_reset_ctr;
115 cinfo->capi_ctrl.procinfo = b1pci_procinfo;
116 cinfo->capi_ctrl.ctr_read_proc = b1ctl_read_proc;
117 strcpy(cinfo->capi_ctrl.name, card->name);
118 cinfo->capi_ctrl.owner = THIS_MODULE;
119
120 retval = attach_capi_ctr(&cinfo->capi_ctrl);
121 if (retval) {
122 printk(KERN_ERR "b1pci: attach controller failed.\n");
123 goto err_free_irq;
124 }
125
126 if (card->revision >= 4) {
127 printk(KERN_INFO "b1pci: AVM B1 PCI V4 at i/o %#x, irq %d, revision %d (no dma)\n",
128 card->port, card->irq, card->revision);
129 } else {
130 printk(KERN_INFO "b1pci: AVM B1 PCI at i/o %#x, irq %d, revision %d\n",
131 card->port, card->irq, card->revision);
132 }
133
134 pci_set_drvdata(pdev, card);
135 return 0;
136
137 err_free_irq:
138 free_irq(card->irq, card);
139 err_release_region:
140 release_region(card->port, AVMB1_PORTLEN);
141 err_free:
142 b1_free_card(card);
143 err:
144 return retval;
145}
146
147static void b1pci_remove(struct pci_dev *pdev)
148{
149 avmcard *card = pci_get_drvdata(pdev);
150 avmctrl_info *cinfo = card->ctrlinfo;
151 unsigned int port = card->port;
152
153 b1_reset(port);
154 b1_reset(port);
155
156 detach_capi_ctr(&cinfo->capi_ctrl);
157 free_irq(card->irq, card);
158 release_region(card->port, AVMB1_PORTLEN);
159 b1_free_card(card);
160}
161
162#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
163/* ------------------------------------------------------------- */
164
165static char *b1pciv4_procinfo(struct capi_ctr *ctrl)
166{
167 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
168
169 if (!cinfo)
170 return "";
171 sprintf(cinfo->infobuf, "%s %s 0x%x %d 0x%lx r%d",
172 cinfo->cardname[0] ? cinfo->cardname : "-",
173 cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-",
174 cinfo->card ? cinfo->card->port : 0x0,
175 cinfo->card ? cinfo->card->irq : 0,
176 cinfo->card ? cinfo->card->membase : 0,
177 cinfo->card ? cinfo->card->revision : 0
178 );
179 return cinfo->infobuf;
180}
181
182/* ------------------------------------------------------------- */
183
184static int b1pciv4_probe(struct capicardparams *p, struct pci_dev *pdev)
185{
186 avmcard *card;
187 avmctrl_info *cinfo;
188 int retval;
189
190 card = b1_alloc_card(1);
191 if (!card) {
192 printk(KERN_WARNING "b1pci: no memory.\n");
193 retval = -ENOMEM;
194 goto err;
195 }
196
197 card->dma = avmcard_dma_alloc("b1pci", pdev, 2048+128, 2048+128);
198 if (!card->dma) {
199 printk(KERN_WARNING "b1pci: dma alloc.\n");
200 retval = -ENOMEM;
201 goto err_free;
202 }
203
204 cinfo = card->ctrlinfo;
205 sprintf(card->name, "b1pciv4-%x", p->port);
206 card->port = p->port;
207 card->irq = p->irq;
208 card->membase = p->membase;
209 card->cardtype = avm_b1pci;
210
211 if (!request_region(card->port, AVMB1_PORTLEN, card->name)) {
212 printk(KERN_WARNING "b1pci: ports 0x%03x-0x%03x in use.\n",
213 card->port, card->port + AVMB1_PORTLEN);
214 retval = -EBUSY;
215 goto err_free_dma;
216 }
217
218 card->mbase = ioremap(card->membase, 64);
219 if (!card->mbase) {
220 printk(KERN_NOTICE "b1pci: can't remap memory at 0x%lx\n",
221 card->membase);
222 retval = -ENOMEM;
223 goto err_release_region;
224 }
225
226 b1dma_reset(card);
227
228 retval = b1pciv4_detect(card);
229 if (retval) {
230 printk(KERN_NOTICE "b1pci: NO card at 0x%x (%d)\n",
231 card->port, retval);
232 retval = -ENODEV;
233 goto err_unmap;
234 }
235 b1dma_reset(card);
236 b1_getrevision(card);
237
238 retval = request_irq(card->irq, b1dma_interrupt, SA_SHIRQ, card->name, card);
239 if (retval) {
240 printk(KERN_ERR "b1pci: unable to get IRQ %d.\n",
241 card->irq);
242 retval = -EBUSY;
243 goto err_unmap;
244 }
245
246 cinfo->capi_ctrl.owner = THIS_MODULE;
247 cinfo->capi_ctrl.driver_name = "b1pciv4";
248 cinfo->capi_ctrl.driverdata = cinfo;
249 cinfo->capi_ctrl.register_appl = b1dma_register_appl;
250 cinfo->capi_ctrl.release_appl = b1dma_release_appl;
251 cinfo->capi_ctrl.send_message = b1dma_send_message;
252 cinfo->capi_ctrl.load_firmware = b1dma_load_firmware;
253 cinfo->capi_ctrl.reset_ctr = b1dma_reset_ctr;
254 cinfo->capi_ctrl.procinfo = b1pciv4_procinfo;
255 cinfo->capi_ctrl.ctr_read_proc = b1dmactl_read_proc;
256 strcpy(cinfo->capi_ctrl.name, card->name);
257
258 retval = attach_capi_ctr(&cinfo->capi_ctrl);
259 if (retval) {
260 printk(KERN_ERR "b1pci: attach controller failed.\n");
261 goto err_free_irq;
262 }
263 card->cardnr = cinfo->capi_ctrl.cnr;
264
265 printk(KERN_INFO "b1pci: AVM B1 PCI V4 at i/o %#x, irq %d, mem %#lx, revision %d (dma)\n",
266 card->port, card->irq, card->membase, card->revision);
267
268 pci_set_drvdata(pdev, card);
269 return 0;
270
271 err_free_irq:
272 free_irq(card->irq, card);
273 err_unmap:
274 iounmap(card->mbase);
275 err_release_region:
276 release_region(card->port, AVMB1_PORTLEN);
277 err_free_dma:
278 avmcard_dma_free(card->dma);
279 err_free:
280 b1_free_card(card);
281 err:
282 return retval;
283
284}
285
286static void b1pciv4_remove(struct pci_dev *pdev)
287{
288 avmcard *card = pci_get_drvdata(pdev);
289 avmctrl_info *cinfo = card->ctrlinfo;
290
291 b1dma_reset(card);
292
293 detach_capi_ctr(&cinfo->capi_ctrl);
294 free_irq(card->irq, card);
295 iounmap(card->mbase);
296 release_region(card->port, AVMB1_PORTLEN);
297 avmcard_dma_free(card->dma);
298 b1_free_card(card);
299}
300
301#endif /* CONFIG_ISDN_DRV_AVMB1_B1PCIV4 */
302
303static int __devinit b1pci_pci_probe(struct pci_dev *pdev,
304 const struct pci_device_id *ent)
305{
306 struct capicardparams param;
307 int retval;
308
309 if (pci_enable_device(pdev) < 0) {
310 printk(KERN_ERR "b1pci: failed to enable AVM-B1\n");
311 return -ENODEV;
312 }
313 param.irq = pdev->irq;
314
315 if (pci_resource_start(pdev, 2)) { /* B1 PCI V4 */
316#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
317 pci_set_master(pdev);
318#endif
319 param.membase = pci_resource_start(pdev, 0);
320 param.port = pci_resource_start(pdev, 2);
321
322 printk(KERN_INFO "b1pci: PCI BIOS reports AVM-B1 V4 at i/o %#x, irq %d, mem %#x\n",
323 param.port, param.irq, param.membase);
324#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
325 retval = b1pciv4_probe(&param, pdev);
326#else
327 retval = b1pci_probe(&param, pdev);
328#endif
329 if (retval != 0) {
330 printk(KERN_ERR "b1pci: no AVM-B1 V4 at i/o %#x, irq %d, mem %#x detected\n",
331 param.port, param.irq, param.membase);
332 }
333 } else {
334 param.membase = 0;
335 param.port = pci_resource_start(pdev, 1);
336
337 printk(KERN_INFO "b1pci: PCI BIOS reports AVM-B1 at i/o %#x, irq %d\n",
338 param.port, param.irq);
339 retval = b1pci_probe(&param, pdev);
340 if (retval != 0) {
341 printk(KERN_ERR "b1pci: no AVM-B1 at i/o %#x, irq %d detected\n",
342 param.port, param.irq);
343 }
344 }
345 return retval;
346}
347
348static void __devexit b1pci_pci_remove(struct pci_dev *pdev)
349{
350#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
351 avmcard *card = pci_get_drvdata(pdev);
352
353 if (card->dma)
354 b1pciv4_remove(pdev);
355 else
356 b1pci_remove(pdev);
357#else
358 b1pci_remove(pdev);
359#endif
360}
361
362static struct pci_driver b1pci_pci_driver = {
363 .name = "b1pci",
364 .id_table = b1pci_pci_tbl,
365 .probe = b1pci_pci_probe,
366 .remove = __devexit_p(b1pci_pci_remove),
367};
368
369static struct capi_driver capi_driver_b1pci = {
370 .name = "b1pci",
371 .revision = "1.0",
372};
373#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
374static struct capi_driver capi_driver_b1pciv4 = {
375 .name = "b1pciv4",
376 .revision = "1.0",
377};
378#endif
379
380static int __init b1pci_init(void)
381{
382 char *p;
383 char rev[32];
384 int err;
385
386 if ((p = strchr(revision, ':')) != 0 && p[1]) {
387 strlcpy(rev, p + 2, 32);
388 if ((p = strchr(rev, '$')) != 0 && p > rev)
389 *(p-1) = 0;
390 } else
391 strcpy(rev, "1.0");
392
393
394 err = pci_register_driver(&b1pci_pci_driver);
395 if (!err) {
396 strlcpy(capi_driver_b1pci.revision, rev, 32);
397 register_capi_driver(&capi_driver_b1pci);
398#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
399 strlcpy(capi_driver_b1pciv4.revision, rev, 32);
400 register_capi_driver(&capi_driver_b1pciv4);
401#endif
402 printk(KERN_INFO "b1pci: revision %s\n", rev);
403 }
404 return err;
405}
406
407static void __exit b1pci_exit(void)
408{
409 unregister_capi_driver(&capi_driver_b1pci);
410#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
411 unregister_capi_driver(&capi_driver_b1pciv4);
412#endif
413 pci_unregister_driver(&b1pci_pci_driver);
414}
415
416module_init(b1pci_init);
417module_exit(b1pci_exit);
diff --git a/drivers/isdn/hardware/avm/b1pcmcia.c b/drivers/isdn/hardware/avm/b1pcmcia.c
new file mode 100644
index 000000000000..9746cc5ffff8
--- /dev/null
+++ b/drivers/isdn/hardware/avm/b1pcmcia.c
@@ -0,0 +1,224 @@
1/* $Id: b1pcmcia.c,v 1.1.2.2 2004/01/16 21:09:27 keil Exp $
2 *
3 * Module for AVM B1/M1/M2 PCMCIA-card.
4 *
5 * Copyright 1999 by Carsten Paeth <calle@calle.de>
6 *
7 * This software may be used and distributed according to the terms
8 * of the GNU General Public License, incorporated herein by reference.
9 *
10 */
11
12#include <linux/module.h>
13#include <linux/kernel.h>
14#include <linux/skbuff.h>
15#include <linux/delay.h>
16#include <linux/mm.h>
17#include <linux/interrupt.h>
18#include <linux/ioport.h>
19#include <linux/init.h>
20#include <asm/io.h>
21#include <linux/capi.h>
22#include <linux/b1pcmcia.h>
23#include <linux/isdn/capicmd.h>
24#include <linux/isdn/capiutil.h>
25#include <linux/isdn/capilli.h>
26#include "avmcard.h"
27
28/* ------------------------------------------------------------- */
29
30static char *revision = "$Revision: 1.1.2.2 $";
31
32/* ------------------------------------------------------------- */
33
34MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM PCMCIA cards");
35MODULE_AUTHOR("Carsten Paeth");
36MODULE_LICENSE("GPL");
37
38/* ------------------------------------------------------------- */
39
40static void b1pcmcia_remove_ctr(struct capi_ctr *ctrl)
41{
42 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
43 avmcard *card = cinfo->card;
44 unsigned int port = card->port;
45
46 b1_reset(port);
47 b1_reset(port);
48
49 detach_capi_ctr(ctrl);
50 free_irq(card->irq, card);
51 b1_free_card(card);
52}
53
54/* ------------------------------------------------------------- */
55
56static LIST_HEAD(cards);
57
58static char *b1pcmcia_procinfo(struct capi_ctr *ctrl);
59
60static int b1pcmcia_add_card(unsigned int port, unsigned irq,
61 enum avmcardtype cardtype)
62{
63 avmctrl_info *cinfo;
64 avmcard *card;
65 char *cardname;
66 int retval;
67
68 card = b1_alloc_card(1);
69 if (!card) {
70 printk(KERN_WARNING "b1pcmcia: no memory.\n");
71 retval = -ENOMEM;
72 goto err;
73 }
74 cinfo = card->ctrlinfo;
75
76 switch (cardtype) {
77 case avm_m1: sprintf(card->name, "m1-%x", port); break;
78 case avm_m2: sprintf(card->name, "m2-%x", port); break;
79 default: sprintf(card->name, "b1pcmcia-%x", port); break;
80 }
81 card->port = port;
82 card->irq = irq;
83 card->cardtype = cardtype;
84
85 retval = request_irq(card->irq, b1_interrupt, 0, card->name, card);
86 if (retval) {
87 printk(KERN_ERR "b1pcmcia: unable to get IRQ %d.\n",
88 card->irq);
89 retval = -EBUSY;
90 goto err_free;
91 }
92 b1_reset(card->port);
93 if ((retval = b1_detect(card->port, card->cardtype)) != 0) {
94 printk(KERN_NOTICE "b1pcmcia: NO card at 0x%x (%d)\n",
95 card->port, retval);
96 retval = -ENODEV;
97 goto err_free_irq;
98 }
99 b1_reset(card->port);
100 b1_getrevision(card);
101
102 cinfo->capi_ctrl.owner = THIS_MODULE;
103 cinfo->capi_ctrl.driver_name = "b1pcmcia";
104 cinfo->capi_ctrl.driverdata = cinfo;
105 cinfo->capi_ctrl.register_appl = b1_register_appl;
106 cinfo->capi_ctrl.release_appl = b1_release_appl;
107 cinfo->capi_ctrl.send_message = b1_send_message;
108 cinfo->capi_ctrl.load_firmware = b1_load_firmware;
109 cinfo->capi_ctrl.reset_ctr = b1_reset_ctr;
110 cinfo->capi_ctrl.procinfo = b1pcmcia_procinfo;
111 cinfo->capi_ctrl.ctr_read_proc = b1ctl_read_proc;
112 strcpy(cinfo->capi_ctrl.name, card->name);
113
114 retval = attach_capi_ctr(&cinfo->capi_ctrl);
115 if (retval) {
116 printk(KERN_ERR "b1pcmcia: attach controller failed.\n");
117 goto err_free_irq;
118 }
119 switch (cardtype) {
120 case avm_m1: cardname = "M1"; break;
121 case avm_m2: cardname = "M2"; break;
122 default : cardname = "B1 PCMCIA"; break;
123 }
124
125 printk(KERN_INFO "b1pcmcia: AVM %s at i/o %#x, irq %d, revision %d\n",
126 cardname, card->port, card->irq, card->revision);
127
128 list_add(&card->list, &cards);
129 return cinfo->capi_ctrl.cnr;
130
131 err_free_irq:
132 free_irq(card->irq, card);
133 err_free:
134 b1_free_card(card);
135 err:
136 return retval;
137}
138
139/* ------------------------------------------------------------- */
140
141static char *b1pcmcia_procinfo(struct capi_ctr *ctrl)
142{
143 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
144
145 if (!cinfo)
146 return "";
147 sprintf(cinfo->infobuf, "%s %s 0x%x %d r%d",
148 cinfo->cardname[0] ? cinfo->cardname : "-",
149 cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-",
150 cinfo->card ? cinfo->card->port : 0x0,
151 cinfo->card ? cinfo->card->irq : 0,
152 cinfo->card ? cinfo->card->revision : 0
153 );
154 return cinfo->infobuf;
155}
156
157/* ------------------------------------------------------------- */
158
159int b1pcmcia_addcard_b1(unsigned int port, unsigned irq)
160{
161 return b1pcmcia_add_card(port, irq, avm_b1pcmcia);
162}
163
164int b1pcmcia_addcard_m1(unsigned int port, unsigned irq)
165{
166 return b1pcmcia_add_card(port, irq, avm_m1);
167}
168
169int b1pcmcia_addcard_m2(unsigned int port, unsigned irq)
170{
171 return b1pcmcia_add_card(port, irq, avm_m2);
172}
173
174int b1pcmcia_delcard(unsigned int port, unsigned irq)
175{
176 struct list_head *l;
177 avmcard *card;
178
179 list_for_each(l, &cards) {
180 card = list_entry(l, avmcard, list);
181 if (card->port == port && card->irq == irq) {
182 b1pcmcia_remove_ctr(&card->ctrlinfo[0].capi_ctrl);
183 return 0;
184 }
185 }
186 return -ESRCH;
187}
188
189EXPORT_SYMBOL(b1pcmcia_addcard_b1);
190EXPORT_SYMBOL(b1pcmcia_addcard_m1);
191EXPORT_SYMBOL(b1pcmcia_addcard_m2);
192EXPORT_SYMBOL(b1pcmcia_delcard);
193
194static struct capi_driver capi_driver_b1pcmcia = {
195 .name = "b1pcmcia",
196 .revision = "1.0",
197};
198
199static int __init b1pcmcia_init(void)
200{
201 char *p;
202 char rev[32];
203
204 if ((p = strchr(revision, ':')) != 0 && p[1]) {
205 strlcpy(rev, p + 2, 32);
206 if ((p = strchr(rev, '$')) != 0 && p > rev)
207 *(p-1) = 0;
208 } else
209 strcpy(rev, "1.0");
210
211 strlcpy(capi_driver_b1pcmcia.revision, rev, 32);
212 register_capi_driver(&capi_driver_b1pcmcia);
213 printk(KERN_INFO "b1pci: revision %s\n", rev);
214
215 return 0;
216}
217
218static void __exit b1pcmcia_exit(void)
219{
220 unregister_capi_driver(&capi_driver_b1pcmcia);
221}
222
223module_init(b1pcmcia_init);
224module_exit(b1pcmcia_exit);
diff --git a/drivers/isdn/hardware/avm/c4.c b/drivers/isdn/hardware/avm/c4.c
new file mode 100644
index 000000000000..fa6b93b1a42d
--- /dev/null
+++ b/drivers/isdn/hardware/avm/c4.c
@@ -0,0 +1,1310 @@
1/* $Id: c4.c,v 1.1.2.2 2004/01/16 21:09:27 keil Exp $
2 *
3 * Module for AVM C4 & C2 card.
4 *
5 * Copyright 1999 by Carsten Paeth <calle@calle.de>
6 *
7 * This software may be used and distributed according to the terms
8 * of the GNU General Public License, incorporated herein by reference.
9 *
10 */
11
12#include <linux/config.h>
13#include <linux/module.h>
14#include <linux/kernel.h>
15#include <linux/skbuff.h>
16#include <linux/delay.h>
17#include <linux/mm.h>
18#include <linux/interrupt.h>
19#include <linux/ioport.h>
20#include <linux/pci.h>
21#include <linux/capi.h>
22#include <linux/kernelcapi.h>
23#include <linux/init.h>
24#include <asm/io.h>
25#include <asm/uaccess.h>
26#include <linux/netdevice.h>
27#include <linux/isdn/capicmd.h>
28#include <linux/isdn/capiutil.h>
29#include <linux/isdn/capilli.h>
30#include "avmcard.h"
31
32#undef CONFIG_C4_DEBUG
33#undef CONFIG_C4_POLLDEBUG
34
35/* ------------------------------------------------------------- */
36
37static char *revision = "$Revision: 1.1.2.2 $";
38
39/* ------------------------------------------------------------- */
40
41static int suppress_pollack;
42
43static struct pci_device_id c4_pci_tbl[] = {
44 { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21285, PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_C4, 0, 0, (unsigned long)4 },
45 { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21285, PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_C2, 0, 0, (unsigned long)2 },
46 { } /* Terminating entry */
47};
48
49MODULE_DEVICE_TABLE(pci, c4_pci_tbl);
50MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM C2/C4 cards");
51MODULE_AUTHOR("Carsten Paeth");
52MODULE_LICENSE("GPL");
53MODULE_PARM(suppress_pollack, "0-1i");
54
55/* ------------------------------------------------------------- */
56
57static void c4_dispatch_tx(avmcard *card);
58
59/* ------------------------------------------------------------- */
60
61#define DC21285_DRAM_A0MR 0x40000000
62#define DC21285_DRAM_A1MR 0x40004000
63#define DC21285_DRAM_A2MR 0x40008000
64#define DC21285_DRAM_A3MR 0x4000C000
65
66#define CAS_OFFSET 0x88
67
68#define DC21285_ARMCSR_BASE 0x42000000
69
70#define PCI_OUT_INT_STATUS 0x30
71#define PCI_OUT_INT_MASK 0x34
72#define MAILBOX_0 0x50
73#define MAILBOX_1 0x54
74#define MAILBOX_2 0x58
75#define MAILBOX_3 0x5C
76#define DOORBELL 0x60
77#define DOORBELL_SETUP 0x64
78
79#define CHAN_1_CONTROL 0x90
80#define CHAN_2_CONTROL 0xB0
81#define DRAM_TIMING 0x10C
82#define DRAM_ADDR_SIZE_0 0x110
83#define DRAM_ADDR_SIZE_1 0x114
84#define DRAM_ADDR_SIZE_2 0x118
85#define DRAM_ADDR_SIZE_3 0x11C
86#define SA_CONTROL 0x13C
87#define XBUS_CYCLE 0x148
88#define XBUS_STROBE 0x14C
89#define DBELL_PCI_MASK 0x150
90#define DBELL_SA_MASK 0x154
91
92#define SDRAM_SIZE 0x1000000
93
94/* ------------------------------------------------------------- */
95
96#define MBOX_PEEK_POKE MAILBOX_0
97
98#define DBELL_ADDR 0x01
99#define DBELL_DATA 0x02
100#define DBELL_RNWR 0x40
101#define DBELL_INIT 0x80
102
103/* ------------------------------------------------------------- */
104
105#define MBOX_UP_ADDR MAILBOX_0
106#define MBOX_UP_LEN MAILBOX_1
107#define MBOX_DOWN_ADDR MAILBOX_2
108#define MBOX_DOWN_LEN MAILBOX_3
109
110#define DBELL_UP_HOST 0x00000100
111#define DBELL_UP_ARM 0x00000200
112#define DBELL_DOWN_HOST 0x00000400
113#define DBELL_DOWN_ARM 0x00000800
114#define DBELL_RESET_HOST 0x40000000
115#define DBELL_RESET_ARM 0x80000000
116
117/* ------------------------------------------------------------- */
118
119#define DRAM_TIMING_DEF 0x001A01A5
120#define DRAM_AD_SZ_DEF0 0x00000045
121#define DRAM_AD_SZ_NULL 0x00000000
122
123#define SA_CTL_ALLRIGHT 0x64AA0271
124
125#define INIT_XBUS_CYCLE 0x100016DB
126#define INIT_XBUS_STROBE 0xF1F1F1F1
127
128/* ------------------------------------------------------------- */
129
130#define RESET_TIMEOUT (15*HZ) /* 15 sec */
131#define PEEK_POKE_TIMEOUT (HZ/10) /* 0.1 sec */
132
133/* ------------------------------------------------------------- */
134
135#define c4outmeml(addr, value) writel(value, addr)
136#define c4inmeml(addr) readl(addr)
137#define c4outmemw(addr, value) writew(value, addr)
138#define c4inmemw(addr) readw(addr)
139#define c4outmemb(addr, value) writeb(value, addr)
140#define c4inmemb(addr) readb(addr)
141
142/* ------------------------------------------------------------- */
143
144static inline int wait_for_doorbell(avmcard *card, unsigned long t)
145{
146 unsigned long stop;
147
148 stop = jiffies + t;
149 while (c4inmeml(card->mbase+DOORBELL) != 0xffffffff) {
150 if (!time_before(jiffies, stop))
151 return -1;
152 mb();
153 }
154 return 0;
155}
156
157static int c4_poke(avmcard *card, unsigned long off, unsigned long value)
158{
159
160 if (wait_for_doorbell(card, HZ/10) < 0)
161 return -1;
162
163 c4outmeml(card->mbase+MBOX_PEEK_POKE, off);
164 c4outmeml(card->mbase+DOORBELL, DBELL_ADDR);
165
166 if (wait_for_doorbell(card, HZ/10) < 0)
167 return -1;
168
169 c4outmeml(card->mbase+MBOX_PEEK_POKE, value);
170 c4outmeml(card->mbase+DOORBELL, DBELL_DATA | DBELL_ADDR);
171
172 return 0;
173}
174
175static int c4_peek(avmcard *card, unsigned long off, unsigned long *valuep)
176{
177 if (wait_for_doorbell(card, HZ/10) < 0)
178 return -1;
179
180 c4outmeml(card->mbase+MBOX_PEEK_POKE, off);
181 c4outmeml(card->mbase+DOORBELL, DBELL_RNWR | DBELL_ADDR);
182
183 if (wait_for_doorbell(card, HZ/10) < 0)
184 return -1;
185
186 *valuep = c4inmeml(card->mbase+MBOX_PEEK_POKE);
187
188 return 0;
189}
190
191/* ------------------------------------------------------------- */
192
193static int c4_load_t4file(avmcard *card, capiloaddatapart * t4file)
194{
195 u32 val;
196 unsigned char *dp;
197 u_int left;
198 u32 loadoff = 0;
199
200 dp = t4file->data;
201 left = t4file->len;
202 while (left >= sizeof(u32)) {
203 if (t4file->user) {
204 if (copy_from_user(&val, dp, sizeof(val)))
205 return -EFAULT;
206 } else {
207 memcpy(&val, dp, sizeof(val));
208 }
209 if (c4_poke(card, loadoff, val)) {
210 printk(KERN_ERR "%s: corrupted firmware file ?\n",
211 card->name);
212 return -EIO;
213 }
214 left -= sizeof(u32);
215 dp += sizeof(u32);
216 loadoff += sizeof(u32);
217 }
218 if (left) {
219 val = 0;
220 if (t4file->user) {
221 if (copy_from_user(&val, dp, left))
222 return -EFAULT;
223 } else {
224 memcpy(&val, dp, left);
225 }
226 if (c4_poke(card, loadoff, val)) {
227 printk(KERN_ERR "%s: corrupted firmware file ?\n",
228 card->name);
229 return -EIO;
230 }
231 }
232 return 0;
233}
234
235/* ------------------------------------------------------------- */
236
237static inline void _put_byte(void **pp, u8 val)
238{
239 u8 *s = *pp;
240 *s++ = val;
241 *pp = s;
242}
243
244static inline void _put_word(void **pp, u32 val)
245{
246 u8 *s = *pp;
247 *s++ = val & 0xff;
248 *s++ = (val >> 8) & 0xff;
249 *s++ = (val >> 16) & 0xff;
250 *s++ = (val >> 24) & 0xff;
251 *pp = s;
252}
253
254static inline void _put_slice(void **pp, unsigned char *dp, unsigned int len)
255{
256 unsigned i = len;
257 _put_word(pp, i);
258 while (i-- > 0)
259 _put_byte(pp, *dp++);
260}
261
262static inline u8 _get_byte(void **pp)
263{
264 u8 *s = *pp;
265 u8 val;
266 val = *s++;
267 *pp = s;
268 return val;
269}
270
271static inline u32 _get_word(void **pp)
272{
273 u8 *s = *pp;
274 u32 val;
275 val = *s++;
276 val |= (*s++ << 8);
277 val |= (*s++ << 16);
278 val |= (*s++ << 24);
279 *pp = s;
280 return val;
281}
282
283static inline u32 _get_slice(void **pp, unsigned char *dp)
284{
285 unsigned int len, i;
286
287 len = i = _get_word(pp);
288 while (i-- > 0) *dp++ = _get_byte(pp);
289 return len;
290}
291
292/* ------------------------------------------------------------- */
293
294static void c4_reset(avmcard *card)
295{
296 unsigned long stop;
297
298 c4outmeml(card->mbase+DOORBELL, DBELL_RESET_ARM);
299
300 stop = jiffies + HZ*10;
301 while (c4inmeml(card->mbase+DOORBELL) != 0xffffffff) {
302 if (!time_before(jiffies, stop))
303 return;
304 c4outmeml(card->mbase+DOORBELL, DBELL_ADDR);
305 mb();
306 }
307
308 c4_poke(card, DC21285_ARMCSR_BASE + CHAN_1_CONTROL, 0);
309 c4_poke(card, DC21285_ARMCSR_BASE + CHAN_2_CONTROL, 0);
310}
311
312/* ------------------------------------------------------------- */
313
314static int c4_detect(avmcard *card)
315{
316 unsigned long stop, dummy;
317
318 c4outmeml(card->mbase+PCI_OUT_INT_MASK, 0x0c);
319 if (c4inmeml(card->mbase+PCI_OUT_INT_MASK) != 0x0c)
320 return 1;
321
322 c4outmeml(card->mbase+DOORBELL, DBELL_RESET_ARM);
323
324 stop = jiffies + HZ*10;
325 while (c4inmeml(card->mbase+DOORBELL) != 0xffffffff) {
326 if (!time_before(jiffies, stop))
327 return 2;
328 c4outmeml(card->mbase+DOORBELL, DBELL_ADDR);
329 mb();
330 }
331
332 c4_poke(card, DC21285_ARMCSR_BASE + CHAN_1_CONTROL, 0);
333 c4_poke(card, DC21285_ARMCSR_BASE + CHAN_2_CONTROL, 0);
334
335 c4outmeml(card->mbase+MAILBOX_0, 0x55aa55aa);
336 if (c4inmeml(card->mbase+MAILBOX_0) != 0x55aa55aa) return 3;
337
338 c4outmeml(card->mbase+MAILBOX_0, 0xaa55aa55);
339 if (c4inmeml(card->mbase+MAILBOX_0) != 0xaa55aa55) return 4;
340
341 if (c4_poke(card, DC21285_ARMCSR_BASE+DBELL_SA_MASK, 0)) return 5;
342 if (c4_poke(card, DC21285_ARMCSR_BASE+DBELL_PCI_MASK, 0)) return 6;
343 if (c4_poke(card, DC21285_ARMCSR_BASE+SA_CONTROL, SA_CTL_ALLRIGHT))
344 return 7;
345 if (c4_poke(card, DC21285_ARMCSR_BASE+XBUS_CYCLE, INIT_XBUS_CYCLE))
346 return 8;
347 if (c4_poke(card, DC21285_ARMCSR_BASE+XBUS_STROBE, INIT_XBUS_STROBE))
348 return 8;
349 if (c4_poke(card, DC21285_ARMCSR_BASE+DRAM_TIMING, 0)) return 9;
350
351 mdelay(1);
352
353 if (c4_peek(card, DC21285_DRAM_A0MR, &dummy)) return 10;
354 if (c4_peek(card, DC21285_DRAM_A1MR, &dummy)) return 11;
355 if (c4_peek(card, DC21285_DRAM_A2MR, &dummy)) return 12;
356 if (c4_peek(card, DC21285_DRAM_A3MR, &dummy)) return 13;
357
358 if (c4_poke(card, DC21285_DRAM_A0MR+CAS_OFFSET, 0)) return 14;
359 if (c4_poke(card, DC21285_DRAM_A1MR+CAS_OFFSET, 0)) return 15;
360 if (c4_poke(card, DC21285_DRAM_A2MR+CAS_OFFSET, 0)) return 16;
361 if (c4_poke(card, DC21285_DRAM_A3MR+CAS_OFFSET, 0)) return 17;
362
363 mdelay(1);
364
365 if (c4_poke(card, DC21285_ARMCSR_BASE+DRAM_TIMING, DRAM_TIMING_DEF))
366 return 18;
367
368 if (c4_poke(card, DC21285_ARMCSR_BASE+DRAM_ADDR_SIZE_0,DRAM_AD_SZ_DEF0))
369 return 19;
370 if (c4_poke(card, DC21285_ARMCSR_BASE+DRAM_ADDR_SIZE_1,DRAM_AD_SZ_NULL))
371 return 20;
372 if (c4_poke(card, DC21285_ARMCSR_BASE+DRAM_ADDR_SIZE_2,DRAM_AD_SZ_NULL))
373 return 21;
374 if (c4_poke(card, DC21285_ARMCSR_BASE+DRAM_ADDR_SIZE_3,DRAM_AD_SZ_NULL))
375 return 22;
376
377 /* Transputer test */
378
379 if ( c4_poke(card, 0x000000, 0x11111111)
380 || c4_poke(card, 0x400000, 0x22222222)
381 || c4_poke(card, 0x800000, 0x33333333)
382 || c4_poke(card, 0xC00000, 0x44444444))
383 return 23;
384
385 if ( c4_peek(card, 0x000000, &dummy) || dummy != 0x11111111
386 || c4_peek(card, 0x400000, &dummy) || dummy != 0x22222222
387 || c4_peek(card, 0x800000, &dummy) || dummy != 0x33333333
388 || c4_peek(card, 0xC00000, &dummy) || dummy != 0x44444444)
389 return 24;
390
391 if ( c4_poke(card, 0x000000, 0x55555555)
392 || c4_poke(card, 0x400000, 0x66666666)
393 || c4_poke(card, 0x800000, 0x77777777)
394 || c4_poke(card, 0xC00000, 0x88888888))
395 return 25;
396
397 if ( c4_peek(card, 0x000000, &dummy) || dummy != 0x55555555
398 || c4_peek(card, 0x400000, &dummy) || dummy != 0x66666666
399 || c4_peek(card, 0x800000, &dummy) || dummy != 0x77777777
400 || c4_peek(card, 0xC00000, &dummy) || dummy != 0x88888888)
401 return 26;
402
403 return 0;
404}
405
406/* ------------------------------------------------------------- */
407
408static void c4_dispatch_tx(avmcard *card)
409{
410 avmcard_dmainfo *dma = card->dma;
411 struct sk_buff *skb;
412 u8 cmd, subcmd;
413 u16 len;
414 u32 txlen;
415 void *p;
416
417
418 if (card->csr & DBELL_DOWN_ARM) { /* tx busy */
419 return;
420 }
421
422 skb = skb_dequeue(&dma->send_queue);
423 if (!skb) {
424#ifdef CONFIG_C4_DEBUG
425 printk(KERN_DEBUG "%s: tx underrun\n", card->name);
426#endif
427 return;
428 }
429
430 len = CAPIMSG_LEN(skb->data);
431
432 if (len) {
433 cmd = CAPIMSG_COMMAND(skb->data);
434 subcmd = CAPIMSG_SUBCOMMAND(skb->data);
435
436 p = dma->sendbuf.dmabuf;
437
438 if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) {
439 u16 dlen = CAPIMSG_DATALEN(skb->data);
440 _put_byte(&p, SEND_DATA_B3_REQ);
441 _put_slice(&p, skb->data, len);
442 _put_slice(&p, skb->data + len, dlen);
443 } else {
444 _put_byte(&p, SEND_MESSAGE);
445 _put_slice(&p, skb->data, len);
446 }
447 txlen = (u8 *)p - (u8 *)dma->sendbuf.dmabuf;
448#ifdef CONFIG_C4_DEBUG
449 printk(KERN_DEBUG "%s: tx put msg len=%d\n", card->name, txlen);
450#endif
451 } else {
452 txlen = skb->len-2;
453#ifdef CONFIG_C4_POLLDEBUG
454 if (skb->data[2] == SEND_POLLACK)
455 printk(KERN_INFO "%s: ack to c4\n", card->name);
456#endif
457#ifdef CONFIG_C4_DEBUG
458 printk(KERN_DEBUG "%s: tx put 0x%x len=%d\n",
459 card->name, skb->data[2], txlen);
460#endif
461 memcpy(dma->sendbuf.dmabuf, skb->data+2, skb->len-2);
462 }
463 txlen = (txlen + 3) & ~3;
464
465 c4outmeml(card->mbase+MBOX_DOWN_ADDR, dma->sendbuf.dmaaddr);
466 c4outmeml(card->mbase+MBOX_DOWN_LEN, txlen);
467
468 card->csr |= DBELL_DOWN_ARM;
469
470 c4outmeml(card->mbase+DOORBELL, DBELL_DOWN_ARM);
471
472 dev_kfree_skb_any(skb);
473}
474
475/* ------------------------------------------------------------- */
476
477static void queue_pollack(avmcard *card)
478{
479 struct sk_buff *skb;
480 void *p;
481
482 skb = alloc_skb(3, GFP_ATOMIC);
483 if (!skb) {
484 printk(KERN_CRIT "%s: no memory, lost poll ack\n",
485 card->name);
486 return;
487 }
488 p = skb->data;
489 _put_byte(&p, 0);
490 _put_byte(&p, 0);
491 _put_byte(&p, SEND_POLLACK);
492 skb_put(skb, (u8 *)p - (u8 *)skb->data);
493
494 skb_queue_tail(&card->dma->send_queue, skb);
495 c4_dispatch_tx(card);
496}
497
498/* ------------------------------------------------------------- */
499
500static void c4_handle_rx(avmcard *card)
501{
502 avmcard_dmainfo *dma = card->dma;
503 struct capi_ctr *ctrl;
504 avmctrl_info *cinfo;
505 struct sk_buff *skb;
506 void *p = dma->recvbuf.dmabuf;
507 u32 ApplId, MsgLen, DataB3Len, NCCI, WindowSize;
508 u8 b1cmd = _get_byte(&p);
509 u32 cidx;
510
511
512#ifdef CONFIG_C4_DEBUG
513 printk(KERN_DEBUG "%s: rx 0x%x len=%lu\n", card->name,
514 b1cmd, (unsigned long)dma->recvlen);
515#endif
516
517 switch (b1cmd) {
518 case RECEIVE_DATA_B3_IND:
519
520 ApplId = (unsigned) _get_word(&p);
521 MsgLen = _get_slice(&p, card->msgbuf);
522 DataB3Len = _get_slice(&p, card->databuf);
523 cidx = CAPIMSG_CONTROLLER(card->msgbuf)-card->cardnr;
524 if (cidx >= card->nlogcontr) cidx = 0;
525 ctrl = &card->ctrlinfo[cidx].capi_ctrl;
526
527 if (MsgLen < 30) { /* not CAPI 64Bit */
528 memset(card->msgbuf+MsgLen, 0, 30-MsgLen);
529 MsgLen = 30;
530 CAPIMSG_SETLEN(card->msgbuf, 30);
531 }
532 if (!(skb = alloc_skb(DataB3Len+MsgLen, GFP_ATOMIC))) {
533 printk(KERN_ERR "%s: incoming packet dropped\n",
534 card->name);
535 } else {
536 memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);
537 memcpy(skb_put(skb, DataB3Len), card->databuf, DataB3Len);
538 capi_ctr_handle_message(ctrl, ApplId, skb);
539 }
540 break;
541
542 case RECEIVE_MESSAGE:
543
544 ApplId = (unsigned) _get_word(&p);
545 MsgLen = _get_slice(&p, card->msgbuf);
546 cidx = CAPIMSG_CONTROLLER(card->msgbuf)-card->cardnr;
547 if (cidx >= card->nlogcontr) cidx = 0;
548 cinfo = &card->ctrlinfo[cidx];
549 ctrl = &card->ctrlinfo[cidx].capi_ctrl;
550
551 if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) {
552 printk(KERN_ERR "%s: incoming packet dropped\n",
553 card->name);
554 } else {
555 memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);
556 if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_CONF)
557 capilib_data_b3_conf(&cinfo->ncci_head, ApplId,
558 CAPIMSG_NCCI(skb->data),
559 CAPIMSG_MSGID(skb->data));
560
561 capi_ctr_handle_message(ctrl, ApplId, skb);
562 }
563 break;
564
565 case RECEIVE_NEW_NCCI:
566
567 ApplId = _get_word(&p);
568 NCCI = _get_word(&p);
569 WindowSize = _get_word(&p);
570 cidx = (NCCI&0x7f) - card->cardnr;
571 if (cidx >= card->nlogcontr) cidx = 0;
572
573 capilib_new_ncci(&card->ctrlinfo[cidx].ncci_head, ApplId, NCCI, WindowSize);
574
575 break;
576
577 case RECEIVE_FREE_NCCI:
578
579 ApplId = _get_word(&p);
580 NCCI = _get_word(&p);
581
582 if (NCCI != 0xffffffff) {
583 cidx = (NCCI&0x7f) - card->cardnr;
584 if (cidx >= card->nlogcontr) cidx = 0;
585 capilib_free_ncci(&card->ctrlinfo[cidx].ncci_head, ApplId, NCCI);
586 }
587 break;
588
589 case RECEIVE_START:
590#ifdef CONFIG_C4_POLLDEBUG
591 printk(KERN_INFO "%s: poll from c4\n", card->name);
592#endif
593 if (!suppress_pollack)
594 queue_pollack(card);
595 for (cidx=0; cidx < card->nr_controllers; cidx++) {
596 ctrl = &card->ctrlinfo[cidx].capi_ctrl;
597 capi_ctr_resume_output(ctrl);
598 }
599 break;
600
601 case RECEIVE_STOP:
602 for (cidx=0; cidx < card->nr_controllers; cidx++) {
603 ctrl = &card->ctrlinfo[cidx].capi_ctrl;
604 capi_ctr_suspend_output(ctrl);
605 }
606 break;
607
608 case RECEIVE_INIT:
609
610 cidx = card->nlogcontr;
611 if (cidx >= card->nr_controllers) {
612 printk(KERN_ERR "%s: card with %d controllers ??\n",
613 card->name, cidx+1);
614 break;
615 }
616 card->nlogcontr++;
617 cinfo = &card->ctrlinfo[cidx];
618 ctrl = &cinfo->capi_ctrl;
619 cinfo->versionlen = _get_slice(&p, cinfo->versionbuf);
620 b1_parse_version(cinfo);
621 printk(KERN_INFO "%s: %s-card (%s) now active\n",
622 card->name,
623 cinfo->version[VER_CARDTYPE],
624 cinfo->version[VER_DRIVER]);
625 capi_ctr_ready(&cinfo->capi_ctrl);
626 break;
627
628 case RECEIVE_TASK_READY:
629 ApplId = (unsigned) _get_word(&p);
630 MsgLen = _get_slice(&p, card->msgbuf);
631 card->msgbuf[MsgLen] = 0;
632 while ( MsgLen > 0
633 && ( card->msgbuf[MsgLen-1] == '\n'
634 || card->msgbuf[MsgLen-1] == '\r')) {
635 card->msgbuf[MsgLen-1] = 0;
636 MsgLen--;
637 }
638 printk(KERN_INFO "%s: task %d \"%s\" ready.\n",
639 card->name, ApplId, card->msgbuf);
640 break;
641
642 case RECEIVE_DEBUGMSG:
643 MsgLen = _get_slice(&p, card->msgbuf);
644 card->msgbuf[MsgLen] = 0;
645 while ( MsgLen > 0
646 && ( card->msgbuf[MsgLen-1] == '\n'
647 || card->msgbuf[MsgLen-1] == '\r')) {
648 card->msgbuf[MsgLen-1] = 0;
649 MsgLen--;
650 }
651 printk(KERN_INFO "%s: DEBUG: %s\n", card->name, card->msgbuf);
652 break;
653
654 default:
655 printk(KERN_ERR "%s: c4_interrupt: 0x%x ???\n",
656 card->name, b1cmd);
657 return;
658 }
659}
660
661/* ------------------------------------------------------------- */
662
663static irqreturn_t c4_handle_interrupt(avmcard *card)
664{
665 unsigned long flags;
666 u32 status;
667
668 spin_lock_irqsave(&card->lock, flags);
669 status = c4inmeml(card->mbase+DOORBELL);
670
671 if (status & DBELL_RESET_HOST) {
672 u_int i;
673 c4outmeml(card->mbase+PCI_OUT_INT_MASK, 0x0c);
674 spin_unlock_irqrestore(&card->lock, flags);
675 if (card->nlogcontr == 0)
676 return IRQ_HANDLED;
677 printk(KERN_ERR "%s: unexpected reset\n", card->name);
678 for (i=0; i < card->nr_controllers; i++) {
679 avmctrl_info *cinfo = &card->ctrlinfo[i];
680 memset(cinfo->version, 0, sizeof(cinfo->version));
681 capilib_release(&cinfo->ncci_head);
682 capi_ctr_reseted(&cinfo->capi_ctrl);
683 }
684 card->nlogcontr = 0;
685 return IRQ_HANDLED;
686 }
687
688 status &= (DBELL_UP_HOST | DBELL_DOWN_HOST);
689 if (!status) {
690 spin_unlock_irqrestore(&card->lock, flags);
691 return IRQ_HANDLED;
692 }
693 c4outmeml(card->mbase+DOORBELL, status);
694
695 if ((status & DBELL_UP_HOST) != 0) {
696 card->dma->recvlen = c4inmeml(card->mbase+MBOX_UP_LEN);
697 c4outmeml(card->mbase+MBOX_UP_LEN, 0);
698 c4_handle_rx(card);
699 card->dma->recvlen = 0;
700 c4outmeml(card->mbase+MBOX_UP_LEN, card->dma->recvbuf.size);
701 c4outmeml(card->mbase+DOORBELL, DBELL_UP_ARM);
702 }
703
704 if ((status & DBELL_DOWN_HOST) != 0) {
705 card->csr &= ~DBELL_DOWN_ARM;
706 c4_dispatch_tx(card);
707 } else if (card->csr & DBELL_DOWN_HOST) {
708 if (c4inmeml(card->mbase+MBOX_DOWN_LEN) == 0) {
709 card->csr &= ~DBELL_DOWN_ARM;
710 c4_dispatch_tx(card);
711 }
712 }
713 spin_unlock_irqrestore(&card->lock, flags);
714 return IRQ_HANDLED;
715}
716
717static irqreturn_t c4_interrupt(int interrupt, void *devptr, struct pt_regs *regs)
718{
719 avmcard *card = devptr;
720
721 return c4_handle_interrupt(card);
722}
723
724/* ------------------------------------------------------------- */
725
726static void c4_send_init(avmcard *card)
727{
728 struct sk_buff *skb;
729 void *p;
730
731 skb = alloc_skb(15, GFP_ATOMIC);
732 if (!skb) {
733 printk(KERN_CRIT "%s: no memory, lost register appl.\n",
734 card->name);
735 return;
736 }
737 p = skb->data;
738 _put_byte(&p, 0);
739 _put_byte(&p, 0);
740 _put_byte(&p, SEND_INIT);
741 _put_word(&p, CAPI_MAXAPPL);
742 _put_word(&p, AVM_NCCI_PER_CHANNEL*30);
743 _put_word(&p, card->cardnr - 1);
744 skb_put(skb, (u8 *)p - (u8 *)skb->data);
745
746 skb_queue_tail(&card->dma->send_queue, skb);
747 c4_dispatch_tx(card);
748}
749
750static int queue_sendconfigword(avmcard *card, u32 val)
751{
752 struct sk_buff *skb;
753 void *p;
754
755 skb = alloc_skb(3+4, GFP_ATOMIC);
756 if (!skb) {
757 printk(KERN_CRIT "%s: no memory, send config\n",
758 card->name);
759 return -ENOMEM;
760 }
761 p = skb->data;
762 _put_byte(&p, 0);
763 _put_byte(&p, 0);
764 _put_byte(&p, SEND_CONFIG);
765 _put_word(&p, val);
766 skb_put(skb, (u8 *)p - (u8 *)skb->data);
767
768 skb_queue_tail(&card->dma->send_queue, skb);
769 c4_dispatch_tx(card);
770 return 0;
771}
772
773static int queue_sendconfig(avmcard *card, char cval[4])
774{
775 struct sk_buff *skb;
776 unsigned long flags;
777 void *p;
778
779 skb = alloc_skb(3+4, GFP_ATOMIC);
780 if (!skb) {
781 printk(KERN_CRIT "%s: no memory, send config\n",
782 card->name);
783 return -ENOMEM;
784 }
785 p = skb->data;
786 _put_byte(&p, 0);
787 _put_byte(&p, 0);
788 _put_byte(&p, SEND_CONFIG);
789 _put_byte(&p, cval[0]);
790 _put_byte(&p, cval[1]);
791 _put_byte(&p, cval[2]);
792 _put_byte(&p, cval[3]);
793 skb_put(skb, (u8 *)p - (u8 *)skb->data);
794
795 skb_queue_tail(&card->dma->send_queue, skb);
796
797 spin_lock_irqsave(&card->lock, flags);
798 c4_dispatch_tx(card);
799 spin_unlock_irqrestore(&card->lock, flags);
800 return 0;
801}
802
803static int c4_send_config(avmcard *card, capiloaddatapart * config)
804{
805 u8 val[4];
806 unsigned char *dp;
807 u_int left;
808 int retval;
809
810 if ((retval = queue_sendconfigword(card, 1)) != 0)
811 return retval;
812 if ((retval = queue_sendconfigword(card, config->len)) != 0)
813 return retval;
814
815 dp = config->data;
816 left = config->len;
817 while (left >= sizeof(u32)) {
818 if (config->user) {
819 if (copy_from_user(val, dp, sizeof(val)))
820 return -EFAULT;
821 } else {
822 memcpy(val, dp, sizeof(val));
823 }
824 if ((retval = queue_sendconfig(card, val)) != 0)
825 return retval;
826 left -= sizeof(val);
827 dp += sizeof(val);
828 }
829 if (left) {
830 memset(val, 0, sizeof(val));
831 if (config->user) {
832 if (copy_from_user(&val, dp, left))
833 return -EFAULT;
834 } else {
835 memcpy(&val, dp, left);
836 }
837 if ((retval = queue_sendconfig(card, val)) != 0)
838 return retval;
839 }
840
841 return 0;
842}
843
844static int c4_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
845{
846 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
847 avmcard *card = cinfo->card;
848 int retval;
849
850 if ((retval = c4_load_t4file(card, &data->firmware))) {
851 printk(KERN_ERR "%s: failed to load t4file!!\n",
852 card->name);
853 c4_reset(card);
854 return retval;
855 }
856
857 card->csr = 0;
858 c4outmeml(card->mbase+MBOX_UP_LEN, 0);
859 c4outmeml(card->mbase+MBOX_DOWN_LEN, 0);
860 c4outmeml(card->mbase+DOORBELL, DBELL_INIT);
861 mdelay(1);
862 c4outmeml(card->mbase+DOORBELL,
863 DBELL_UP_HOST | DBELL_DOWN_HOST | DBELL_RESET_HOST);
864
865 c4outmeml(card->mbase+PCI_OUT_INT_MASK, 0x08);
866
867 card->dma->recvlen = 0;
868 c4outmeml(card->mbase+MBOX_UP_ADDR, card->dma->recvbuf.dmaaddr);
869 c4outmeml(card->mbase+MBOX_UP_LEN, card->dma->recvbuf.size);
870 c4outmeml(card->mbase+DOORBELL, DBELL_UP_ARM);
871
872 if (data->configuration.len > 0 && data->configuration.data) {
873 retval = c4_send_config(card, &data->configuration);
874 if (retval) {
875 printk(KERN_ERR "%s: failed to set config!!\n",
876 card->name);
877 c4_reset(card);
878 return retval;
879 }
880 }
881
882 c4_send_init(card);
883
884 return 0;
885}
886
887
888void c4_reset_ctr(struct capi_ctr *ctrl)
889{
890 avmcard *card = ((avmctrl_info *)(ctrl->driverdata))->card;
891 avmctrl_info *cinfo;
892 u_int i;
893 unsigned long flags;
894
895 spin_lock_irqsave(&card->lock, flags);
896
897 c4_reset(card);
898
899 spin_unlock_irqrestore(&card->lock, flags);
900
901 for (i=0; i < card->nr_controllers; i++) {
902 cinfo = &card->ctrlinfo[i];
903 memset(cinfo->version, 0, sizeof(cinfo->version));
904 capi_ctr_reseted(&cinfo->capi_ctrl);
905 }
906 card->nlogcontr = 0;
907}
908
909static void c4_remove(struct pci_dev *pdev)
910{
911 avmcard *card = pci_get_drvdata(pdev);
912 avmctrl_info *cinfo;
913 u_int i;
914
915 if (!card)
916 return;
917
918 c4_reset(card);
919
920 for (i=0; i < card->nr_controllers; i++) {
921 cinfo = &card->ctrlinfo[i];
922 detach_capi_ctr(&cinfo->capi_ctrl);
923 }
924
925 free_irq(card->irq, card);
926 iounmap(card->mbase);
927 release_region(card->port, AVMB1_PORTLEN);
928 avmcard_dma_free(card->dma);
929 pci_set_drvdata(pdev, NULL);
930 b1_free_card(card);
931}
932
933/* ------------------------------------------------------------- */
934
935
936void c4_register_appl(struct capi_ctr *ctrl,
937 u16 appl,
938 capi_register_params *rp)
939{
940 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
941 avmcard *card = cinfo->card;
942 struct sk_buff *skb;
943 int want = rp->level3cnt;
944 unsigned long flags;
945 int nconn;
946 void *p;
947
948 if (ctrl->cnr == card->cardnr) {
949
950 if (want > 0) nconn = want;
951 else nconn = ctrl->profile.nbchannel * 4 * -want;
952 if (nconn == 0) nconn = ctrl->profile.nbchannel * 4;
953
954 skb = alloc_skb(23, GFP_ATOMIC);
955 if (!skb) {
956 printk(KERN_CRIT "%s: no memory, lost register appl.\n",
957 card->name);
958 return;
959 }
960 p = skb->data;
961 _put_byte(&p, 0);
962 _put_byte(&p, 0);
963 _put_byte(&p, SEND_REGISTER);
964 _put_word(&p, appl);
965 _put_word(&p, 1024 * (nconn+1));
966 _put_word(&p, nconn);
967 _put_word(&p, rp->datablkcnt);
968 _put_word(&p, rp->datablklen);
969 skb_put(skb, (u8 *)p - (u8 *)skb->data);
970
971 skb_queue_tail(&card->dma->send_queue, skb);
972
973 spin_lock_irqsave(&card->lock, flags);
974 c4_dispatch_tx(card);
975 spin_unlock_irqrestore(&card->lock, flags);
976 }
977}
978
979/* ------------------------------------------------------------- */
980
981void c4_release_appl(struct capi_ctr *ctrl, u16 appl)
982{
983 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
984 avmcard *card = cinfo->card;
985 unsigned long flags;
986 struct sk_buff *skb;
987 void *p;
988
989 capilib_release_appl(&cinfo->ncci_head, appl);
990
991 if (ctrl->cnr == card->cardnr) {
992 skb = alloc_skb(7, GFP_ATOMIC);
993 if (!skb) {
994 printk(KERN_CRIT "%s: no memory, lost release appl.\n",
995 card->name);
996 return;
997 }
998 p = skb->data;
999 _put_byte(&p, 0);
1000 _put_byte(&p, 0);
1001 _put_byte(&p, SEND_RELEASE);
1002 _put_word(&p, appl);
1003
1004 skb_put(skb, (u8 *)p - (u8 *)skb->data);
1005 skb_queue_tail(&card->dma->send_queue, skb);
1006 spin_lock_irqsave(&card->lock, flags);
1007 c4_dispatch_tx(card);
1008 spin_unlock_irqrestore(&card->lock, flags);
1009 }
1010}
1011
1012/* ------------------------------------------------------------- */
1013
1014
1015static u16 c4_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
1016{
1017 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
1018 avmcard *card = cinfo->card;
1019 u16 retval = CAPI_NOERROR;
1020 unsigned long flags;
1021
1022 if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) {
1023 retval = capilib_data_b3_req(&cinfo->ncci_head,
1024 CAPIMSG_APPID(skb->data),
1025 CAPIMSG_NCCI(skb->data),
1026 CAPIMSG_MSGID(skb->data));
1027 }
1028 if (retval == CAPI_NOERROR) {
1029 skb_queue_tail(&card->dma->send_queue, skb);
1030 spin_lock_irqsave(&card->lock, flags);
1031 c4_dispatch_tx(card);
1032 spin_unlock_irqrestore(&card->lock, flags);
1033 }
1034 return retval;
1035}
1036
1037/* ------------------------------------------------------------- */
1038
1039static char *c4_procinfo(struct capi_ctr *ctrl)
1040{
1041 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
1042
1043 if (!cinfo)
1044 return "";
1045 sprintf(cinfo->infobuf, "%s %s 0x%x %d 0x%lx",
1046 cinfo->cardname[0] ? cinfo->cardname : "-",
1047 cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-",
1048 cinfo->card ? cinfo->card->port : 0x0,
1049 cinfo->card ? cinfo->card->irq : 0,
1050 cinfo->card ? cinfo->card->membase : 0
1051 );
1052 return cinfo->infobuf;
1053}
1054
1055static int c4_read_proc(char *page, char **start, off_t off,
1056 int count, int *eof, struct capi_ctr *ctrl)
1057{
1058 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
1059 avmcard *card = cinfo->card;
1060 u8 flag;
1061 int len = 0;
1062 char *s;
1063
1064 len += sprintf(page+len, "%-16s %s\n", "name", card->name);
1065 len += sprintf(page+len, "%-16s 0x%x\n", "io", card->port);
1066 len += sprintf(page+len, "%-16s %d\n", "irq", card->irq);
1067 len += sprintf(page+len, "%-16s 0x%lx\n", "membase", card->membase);
1068 switch (card->cardtype) {
1069 case avm_b1isa: s = "B1 ISA"; break;
1070 case avm_b1pci: s = "B1 PCI"; break;
1071 case avm_b1pcmcia: s = "B1 PCMCIA"; break;
1072 case avm_m1: s = "M1"; break;
1073 case avm_m2: s = "M2"; break;
1074 case avm_t1isa: s = "T1 ISA (HEMA)"; break;
1075 case avm_t1pci: s = "T1 PCI"; break;
1076 case avm_c4: s = "C4"; break;
1077 case avm_c2: s = "C2"; break;
1078 default: s = "???"; break;
1079 }
1080 len += sprintf(page+len, "%-16s %s\n", "type", s);
1081 if ((s = cinfo->version[VER_DRIVER]) != 0)
1082 len += sprintf(page+len, "%-16s %s\n", "ver_driver", s);
1083 if ((s = cinfo->version[VER_CARDTYPE]) != 0)
1084 len += sprintf(page+len, "%-16s %s\n", "ver_cardtype", s);
1085 if ((s = cinfo->version[VER_SERIAL]) != 0)
1086 len += sprintf(page+len, "%-16s %s\n", "ver_serial", s);
1087
1088 if (card->cardtype != avm_m1) {
1089 flag = ((u8 *)(ctrl->profile.manu))[3];
1090 if (flag)
1091 len += sprintf(page+len, "%-16s%s%s%s%s%s%s%s\n",
1092 "protocol",
1093 (flag & 0x01) ? " DSS1" : "",
1094 (flag & 0x02) ? " CT1" : "",
1095 (flag & 0x04) ? " VN3" : "",
1096 (flag & 0x08) ? " NI1" : "",
1097 (flag & 0x10) ? " AUSTEL" : "",
1098 (flag & 0x20) ? " ESS" : "",
1099 (flag & 0x40) ? " 1TR6" : ""
1100 );
1101 }
1102 if (card->cardtype != avm_m1) {
1103 flag = ((u8 *)(ctrl->profile.manu))[5];
1104 if (flag)
1105 len += sprintf(page+len, "%-16s%s%s%s%s\n",
1106 "linetype",
1107 (flag & 0x01) ? " point to point" : "",
1108 (flag & 0x02) ? " point to multipoint" : "",
1109 (flag & 0x08) ? " leased line without D-channel" : "",
1110 (flag & 0x04) ? " leased line with D-channel" : ""
1111 );
1112 }
1113 len += sprintf(page+len, "%-16s %s\n", "cardname", cinfo->cardname);
1114
1115 if (off+count >= len)
1116 *eof = 1;
1117 if (len < off)
1118 return 0;
1119 *start = page + off;
1120 return ((count < len-off) ? count : len-off);
1121}
1122
1123/* ------------------------------------------------------------- */
1124
1125static int c4_add_card(struct capicardparams *p, struct pci_dev *dev,
1126 int nr_controllers)
1127{
1128 avmcard *card;
1129 avmctrl_info *cinfo;
1130 int retval;
1131 int i;
1132
1133 card = b1_alloc_card(nr_controllers);
1134 if (!card) {
1135 printk(KERN_WARNING "c4: no memory.\n");
1136 retval = -ENOMEM;
1137 goto err;
1138 }
1139 card->dma = avmcard_dma_alloc("c4", dev, 2048+128, 2048+128);
1140 if (!card->dma) {
1141 printk(KERN_WARNING "c4: no memory.\n");
1142 retval = -ENOMEM;
1143 goto err_free;
1144 }
1145
1146 sprintf(card->name, "c%d-%x", nr_controllers, p->port);
1147 card->port = p->port;
1148 card->irq = p->irq;
1149 card->membase = p->membase;
1150 card->cardtype = (nr_controllers == 4) ? avm_c4 : avm_c2;
1151
1152 if (!request_region(card->port, AVMB1_PORTLEN, card->name)) {
1153 printk(KERN_WARNING "c4: ports 0x%03x-0x%03x in use.\n",
1154 card->port, card->port + AVMB1_PORTLEN);
1155 retval = -EBUSY;
1156 goto err_free_dma;
1157 }
1158
1159 card->mbase = ioremap(card->membase, 128);
1160 if (card->mbase == 0) {
1161 printk(KERN_NOTICE "c4: can't remap memory at 0x%lx\n",
1162 card->membase);
1163 retval = -EIO;
1164 goto err_release_region;
1165 }
1166
1167 retval = c4_detect(card);
1168 if (retval != 0) {
1169 printk(KERN_NOTICE "c4: NO card at 0x%x error(%d)\n",
1170 card->port, retval);
1171 retval = -EIO;
1172 goto err_unmap;
1173 }
1174 c4_reset(card);
1175
1176 retval = request_irq(card->irq, c4_interrupt, SA_SHIRQ, card->name, card);
1177 if (retval) {
1178 printk(KERN_ERR "c4: unable to get IRQ %d.\n",card->irq);
1179 retval = -EBUSY;
1180 goto err_unmap;
1181 }
1182
1183 for (i=0; i < nr_controllers ; i++) {
1184 cinfo = &card->ctrlinfo[i];
1185 cinfo->capi_ctrl.owner = THIS_MODULE;
1186 cinfo->capi_ctrl.driver_name = "c4";
1187 cinfo->capi_ctrl.driverdata = cinfo;
1188 cinfo->capi_ctrl.register_appl = c4_register_appl;
1189 cinfo->capi_ctrl.release_appl = c4_release_appl;
1190 cinfo->capi_ctrl.send_message = c4_send_message;
1191 cinfo->capi_ctrl.load_firmware = c4_load_firmware;
1192 cinfo->capi_ctrl.reset_ctr = c4_reset_ctr;
1193 cinfo->capi_ctrl.procinfo = c4_procinfo;
1194 cinfo->capi_ctrl.ctr_read_proc = c4_read_proc;
1195 strcpy(cinfo->capi_ctrl.name, card->name);
1196
1197 retval = attach_capi_ctr(&cinfo->capi_ctrl);
1198 if (retval) {
1199 printk(KERN_ERR "c4: attach controller failed (%d).\n", i);
1200 for (i--; i >= 0; i--) {
1201 cinfo = &card->ctrlinfo[i];
1202 detach_capi_ctr(&cinfo->capi_ctrl);
1203 }
1204 goto err_free_irq;
1205 }
1206 if (i == 0)
1207 card->cardnr = cinfo->capi_ctrl.cnr;
1208 }
1209
1210 printk(KERN_INFO "c4: AVM C%d at i/o %#x, irq %d, mem %#lx\n",
1211 nr_controllers, card->port, card->irq,
1212 card->membase);
1213 pci_set_drvdata(dev, card);
1214 return 0;
1215
1216 err_free_irq:
1217 free_irq(card->irq, card);
1218 err_unmap:
1219 iounmap(card->mbase);
1220 err_release_region:
1221 release_region(card->port, AVMB1_PORTLEN);
1222 err_free_dma:
1223 avmcard_dma_free(card->dma);
1224 err_free:
1225 b1_free_card(card);
1226 err:
1227 return retval;
1228}
1229
1230/* ------------------------------------------------------------- */
1231
1232static int __devinit c4_probe(struct pci_dev *dev,
1233 const struct pci_device_id *ent)
1234{
1235 int nr = ent->driver_data;
1236 int retval = 0;
1237 struct capicardparams param;
1238
1239 if (pci_enable_device(dev) < 0) {
1240 printk(KERN_ERR "c4: failed to enable AVM-C%d\n", nr);
1241 return -ENODEV;
1242 }
1243 pci_set_master(dev);
1244
1245 param.port = pci_resource_start(dev, 1);
1246 param.irq = dev->irq;
1247 param.membase = pci_resource_start(dev, 0);
1248
1249 printk(KERN_INFO "c4: PCI BIOS reports AVM-C%d at i/o %#x, irq %d, mem %#x\n",
1250 nr, param.port, param.irq, param.membase);
1251
1252 retval = c4_add_card(&param, dev, nr);
1253 if (retval != 0) {
1254 printk(KERN_ERR "c4: no AVM-C%d at i/o %#x, irq %d detected, mem %#x\n",
1255 nr, param.port, param.irq, param.membase);
1256 return -ENODEV;
1257 }
1258 return 0;
1259}
1260
1261static struct pci_driver c4_pci_driver = {
1262 .name = "c4",
1263 .id_table = c4_pci_tbl,
1264 .probe = c4_probe,
1265 .remove = c4_remove,
1266};
1267
1268static struct capi_driver capi_driver_c2 = {
1269 .name = "c2",
1270 .revision = "1.0",
1271};
1272
1273static struct capi_driver capi_driver_c4 = {
1274 .name = "c4",
1275 .revision = "1.0",
1276};
1277
1278static int __init c4_init(void)
1279{
1280 char *p;
1281 char rev[32];
1282 int err;
1283
1284 if ((p = strchr(revision, ':')) != 0 && p[1]) {
1285 strlcpy(rev, p + 2, 32);
1286 if ((p = strchr(rev, '$')) != 0 && p > rev)
1287 *(p-1) = 0;
1288 } else
1289 strcpy(rev, "1.0");
1290
1291 err = pci_register_driver(&c4_pci_driver);
1292 if (!err) {
1293 strlcpy(capi_driver_c2.revision, rev, 32);
1294 register_capi_driver(&capi_driver_c2);
1295 strlcpy(capi_driver_c4.revision, rev, 32);
1296 register_capi_driver(&capi_driver_c4);
1297 printk(KERN_INFO "c4: revision %s\n", rev);
1298 }
1299 return err;
1300}
1301
1302static void __exit c4_exit(void)
1303{
1304 unregister_capi_driver(&capi_driver_c2);
1305 unregister_capi_driver(&capi_driver_c4);
1306 pci_unregister_driver(&c4_pci_driver);
1307}
1308
1309module_init(c4_init);
1310module_exit(c4_exit);
diff --git a/drivers/isdn/hardware/avm/t1isa.c b/drivers/isdn/hardware/avm/t1isa.c
new file mode 100644
index 000000000000..cb9d9cee2a64
--- /dev/null
+++ b/drivers/isdn/hardware/avm/t1isa.c
@@ -0,0 +1,596 @@
1/* $Id: t1isa.c,v 1.1.2.3 2004/02/10 01:07:12 keil Exp $
2 *
3 * Module for AVM T1 HEMA-card.
4 *
5 * Copyright 1999 by Carsten Paeth <calle@calle.de>
6 *
7 * This software may be used and distributed according to the terms
8 * of the GNU General Public License, incorporated herein by reference.
9 *
10 */
11
12#include <linux/module.h>
13#include <linux/kernel.h>
14#include <linux/skbuff.h>
15#include <linux/delay.h>
16#include <linux/mm.h>
17#include <linux/interrupt.h>
18#include <linux/ioport.h>
19#include <linux/capi.h>
20#include <linux/netdevice.h>
21#include <linux/kernelcapi.h>
22#include <linux/init.h>
23#include <linux/pci.h>
24#include <asm/io.h>
25#include <linux/isdn/capicmd.h>
26#include <linux/isdn/capiutil.h>
27#include <linux/isdn/capilli.h>
28#include "avmcard.h"
29
30/* ------------------------------------------------------------- */
31
32static char *revision = "$Revision: 1.1.2.3 $";
33
34/* ------------------------------------------------------------- */
35
36MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM T1 HEMA ISA card");
37MODULE_AUTHOR("Carsten Paeth");
38MODULE_LICENSE("GPL");
39
40/* ------------------------------------------------------------- */
41
42static int hema_irq_table[16] =
43{0,
44 0,
45 0,
46 0x80, /* irq 3 */
47 0,
48 0x90, /* irq 5 */
49 0,
50 0xA0, /* irq 7 */
51 0,
52 0xB0, /* irq 9 */
53 0xC0, /* irq 10 */
54 0xD0, /* irq 11 */
55 0xE0, /* irq 12 */
56 0,
57 0,
58 0xF0, /* irq 15 */
59};
60
61static int t1_detectandinit(unsigned int base, unsigned irq, int cardnr)
62{
63 unsigned char cregs[8];
64 unsigned char reverse_cardnr;
65 unsigned char dummy;
66 int i;
67
68 reverse_cardnr = ((cardnr & 0x01) << 3) | ((cardnr & 0x02) << 1)
69 | ((cardnr & 0x04) >> 1) | ((cardnr & 0x08) >> 3);
70 cregs[0] = (HEMA_VERSION_ID << 4) | (reverse_cardnr & 0xf);
71 cregs[1] = 0x00; /* fast & slow link connected to CON1 */
72 cregs[2] = 0x05; /* fast link 20MBit, slow link 20 MBit */
73 cregs[3] = 0;
74 cregs[4] = 0x11; /* zero wait state */
75 cregs[5] = hema_irq_table[irq & 0xf];
76 cregs[6] = 0;
77 cregs[7] = 0;
78
79 /*
80 * no one else should use the ISA bus in this moment,
81 * but no function there to prevent this :-(
82 * save_flags(flags); cli();
83 */
84
85 /* board reset */
86 t1outp(base, T1_RESETBOARD, 0xf);
87 mdelay(100);
88 dummy = t1inp(base, T1_FASTLINK+T1_OUTSTAT); /* first read */
89
90 /* write config */
91 dummy = (base >> 4) & 0xff;
92 for (i=1;i<=0xf;i++) t1outp(base, i, dummy);
93 t1outp(base, HEMA_PAL_ID & 0xf, dummy);
94 t1outp(base, HEMA_PAL_ID >> 4, cregs[0]);
95 for(i=1;i<7;i++) t1outp(base, 0, cregs[i]);
96 t1outp(base, ((base >> 4)) & 0x3, cregs[7]);
97 /* restore_flags(flags); */
98
99 mdelay(100);
100 t1outp(base, T1_FASTLINK+T1_RESETLINK, 0);
101 t1outp(base, T1_SLOWLINK+T1_RESETLINK, 0);
102 mdelay(10);
103 t1outp(base, T1_FASTLINK+T1_RESETLINK, 1);
104 t1outp(base, T1_SLOWLINK+T1_RESETLINK, 1);
105 mdelay(100);
106 t1outp(base, T1_FASTLINK+T1_RESETLINK, 0);
107 t1outp(base, T1_SLOWLINK+T1_RESETLINK, 0);
108 mdelay(10);
109 t1outp(base, T1_FASTLINK+T1_ANALYSE, 0);
110 mdelay(5);
111 t1outp(base, T1_SLOWLINK+T1_ANALYSE, 0);
112
113 if (t1inp(base, T1_FASTLINK+T1_OUTSTAT) != 0x1) /* tx empty */
114 return 1;
115 if (t1inp(base, T1_FASTLINK+T1_INSTAT) != 0x0) /* rx empty */
116 return 2;
117 if (t1inp(base, T1_FASTLINK+T1_IRQENABLE) != 0x0)
118 return 3;
119 if ((t1inp(base, T1_FASTLINK+T1_FIFOSTAT) & 0xf0) != 0x70)
120 return 4;
121 if ((t1inp(base, T1_FASTLINK+T1_IRQMASTER) & 0x0e) != 0)
122 return 5;
123 if ((t1inp(base, T1_FASTLINK+T1_IDENT) & 0x7d) != 1)
124 return 6;
125 if (t1inp(base, T1_SLOWLINK+T1_OUTSTAT) != 0x1) /* tx empty */
126 return 7;
127 if ((t1inp(base, T1_SLOWLINK+T1_IRQMASTER) & 0x0e) != 0)
128 return 8;
129 if ((t1inp(base, T1_SLOWLINK+T1_IDENT) & 0x7d) != 0)
130 return 9;
131 return 0;
132}
133
134static irqreturn_t t1isa_interrupt(int interrupt, void *devptr, struct pt_regs *regs)
135{
136 avmcard *card = devptr;
137 avmctrl_info *cinfo = &card->ctrlinfo[0];
138 struct capi_ctr *ctrl = &cinfo->capi_ctrl;
139 unsigned char b1cmd;
140 struct sk_buff *skb;
141
142 unsigned ApplId;
143 unsigned MsgLen;
144 unsigned DataB3Len;
145 unsigned NCCI;
146 unsigned WindowSize;
147 unsigned long flags;
148
149 spin_lock_irqsave(&card->lock, flags);
150
151 while (b1_rx_full(card->port)) {
152
153 b1cmd = b1_get_byte(card->port);
154
155 switch (b1cmd) {
156
157 case RECEIVE_DATA_B3_IND:
158
159 ApplId = (unsigned) b1_get_word(card->port);
160 MsgLen = t1_get_slice(card->port, card->msgbuf);
161 DataB3Len = t1_get_slice(card->port, card->databuf);
162 spin_unlock_irqrestore(&card->lock, flags);
163
164 if (MsgLen < 30) { /* not CAPI 64Bit */
165 memset(card->msgbuf+MsgLen, 0, 30-MsgLen);
166 MsgLen = 30;
167 CAPIMSG_SETLEN(card->msgbuf, 30);
168 }
169 if (!(skb = alloc_skb(DataB3Len+MsgLen, GFP_ATOMIC))) {
170 printk(KERN_ERR "%s: incoming packet dropped\n",
171 card->name);
172 } else {
173 memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);
174 memcpy(skb_put(skb, DataB3Len), card->databuf, DataB3Len);
175 capi_ctr_handle_message(ctrl, ApplId, skb);
176 }
177 break;
178
179 case RECEIVE_MESSAGE:
180
181 ApplId = (unsigned) b1_get_word(card->port);
182 MsgLen = t1_get_slice(card->port, card->msgbuf);
183 spin_unlock_irqrestore(&card->lock, flags);
184 if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) {
185 printk(KERN_ERR "%s: incoming packet dropped\n",
186 card->name);
187 } else {
188 memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);
189 if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3)
190 capilib_data_b3_conf(&cinfo->ncci_head, ApplId,
191 CAPIMSG_NCCI(skb->data),
192 CAPIMSG_MSGID(skb->data));
193
194 capi_ctr_handle_message(ctrl, ApplId, skb);
195 }
196 break;
197
198 case RECEIVE_NEW_NCCI:
199
200 ApplId = b1_get_word(card->port);
201 NCCI = b1_get_word(card->port);
202 WindowSize = b1_get_word(card->port);
203 spin_unlock_irqrestore(&card->lock, flags);
204
205 capilib_new_ncci(&cinfo->ncci_head, ApplId, NCCI, WindowSize);
206
207 break;
208
209 case RECEIVE_FREE_NCCI:
210
211 ApplId = b1_get_word(card->port);
212 NCCI = b1_get_word(card->port);
213 spin_unlock_irqrestore(&card->lock, flags);
214
215 if (NCCI != 0xffffffff)
216 capilib_free_ncci(&cinfo->ncci_head, ApplId, NCCI);
217
218 break;
219
220 case RECEIVE_START:
221 b1_put_byte(card->port, SEND_POLLACK);
222 spin_unlock_irqrestore(&card->lock, flags);
223 capi_ctr_resume_output(ctrl);
224 break;
225
226 case RECEIVE_STOP:
227 spin_unlock_irqrestore(&card->lock, flags);
228 capi_ctr_suspend_output(ctrl);
229 break;
230
231 case RECEIVE_INIT:
232
233 cinfo->versionlen = t1_get_slice(card->port, cinfo->versionbuf);
234 spin_unlock_irqrestore(&card->lock, flags);
235 b1_parse_version(cinfo);
236 printk(KERN_INFO "%s: %s-card (%s) now active\n",
237 card->name,
238 cinfo->version[VER_CARDTYPE],
239 cinfo->version[VER_DRIVER]);
240 capi_ctr_ready(ctrl);
241 break;
242
243 case RECEIVE_TASK_READY:
244 ApplId = (unsigned) b1_get_word(card->port);
245 MsgLen = t1_get_slice(card->port, card->msgbuf);
246 spin_unlock_irqrestore(&card->lock, flags);
247 card->msgbuf[MsgLen] = 0;
248 while ( MsgLen > 0
249 && ( card->msgbuf[MsgLen-1] == '\n'
250 || card->msgbuf[MsgLen-1] == '\r')) {
251 card->msgbuf[MsgLen-1] = 0;
252 MsgLen--;
253 }
254 printk(KERN_INFO "%s: task %d \"%s\" ready.\n",
255 card->name, ApplId, card->msgbuf);
256 break;
257
258 case RECEIVE_DEBUGMSG:
259 MsgLen = t1_get_slice(card->port, card->msgbuf);
260 spin_unlock_irqrestore(&card->lock, flags);
261 card->msgbuf[MsgLen] = 0;
262 while ( MsgLen > 0
263 && ( card->msgbuf[MsgLen-1] == '\n'
264 || card->msgbuf[MsgLen-1] == '\r')) {
265 card->msgbuf[MsgLen-1] = 0;
266 MsgLen--;
267 }
268 printk(KERN_INFO "%s: DEBUG: %s\n", card->name, card->msgbuf);
269 break;
270
271
272 case 0xff:
273 spin_unlock_irqrestore(&card->lock, flags);
274 printk(KERN_ERR "%s: card reseted ?\n", card->name);
275 return IRQ_HANDLED;
276 default:
277 spin_unlock_irqrestore(&card->lock, flags);
278 printk(KERN_ERR "%s: b1_interrupt: 0x%x ???\n",
279 card->name, b1cmd);
280 return IRQ_NONE;
281 }
282 }
283 return IRQ_HANDLED;
284}
285
286/* ------------------------------------------------------------- */
287
288static int t1isa_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
289{
290 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
291 avmcard *card = cinfo->card;
292 unsigned int port = card->port;
293 unsigned long flags;
294 int retval;
295
296 t1_disable_irq(port);
297 b1_reset(port);
298
299 if ((retval = b1_load_t4file(card, &data->firmware))) {
300 b1_reset(port);
301 printk(KERN_ERR "%s: failed to load t4file!!\n",
302 card->name);
303 return retval;
304 }
305
306 if (data->configuration.len > 0 && data->configuration.data) {
307 if ((retval = b1_load_config(card, &data->configuration))) {
308 b1_reset(port);
309 printk(KERN_ERR "%s: failed to load config!!\n",
310 card->name);
311 return retval;
312 }
313 }
314
315 if (!b1_loaded(card)) {
316 printk(KERN_ERR "%s: failed to load t4file.\n", card->name);
317 return -EIO;
318 }
319
320 spin_lock_irqsave(&card->lock, flags);
321 b1_setinterrupt(port, card->irq, card->cardtype);
322 b1_put_byte(port, SEND_INIT);
323 b1_put_word(port, CAPI_MAXAPPL);
324 b1_put_word(port, AVM_NCCI_PER_CHANNEL*30);
325 b1_put_word(port, ctrl->cnr - 1);
326 spin_unlock_irqrestore(&card->lock, flags);
327
328 return 0;
329}
330
331void t1isa_reset_ctr(struct capi_ctr *ctrl)
332{
333 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
334 avmcard *card = cinfo->card;
335 unsigned int port = card->port;
336
337 t1_disable_irq(port);
338 b1_reset(port);
339 b1_reset(port);
340
341 memset(cinfo->version, 0, sizeof(cinfo->version));
342 capilib_release(&cinfo->ncci_head);
343 capi_ctr_reseted(ctrl);
344}
345
346static void t1isa_remove(struct pci_dev *pdev)
347{
348 avmctrl_info *cinfo = pci_get_drvdata(pdev);
349 avmcard *card;
350
351 if (!cinfo)
352 return;
353
354 card = cinfo->card;
355
356 t1_disable_irq(card->port);
357 b1_reset(card->port);
358 b1_reset(card->port);
359 t1_reset(card->port);
360
361 detach_capi_ctr(&cinfo->capi_ctrl);
362 free_irq(card->irq, card);
363 release_region(card->port, AVMB1_PORTLEN);
364 b1_free_card(card);
365}
366
367/* ------------------------------------------------------------- */
368
369static u16 t1isa_send_message(struct capi_ctr *ctrl, struct sk_buff *skb);
370static char *t1isa_procinfo(struct capi_ctr *ctrl);
371
372static int t1isa_probe(struct pci_dev *pdev, int cardnr)
373{
374 avmctrl_info *cinfo;
375 avmcard *card;
376 int retval;
377
378 card = b1_alloc_card(1);
379 if (!card) {
380 printk(KERN_WARNING "t1isa: no memory.\n");
381 retval = -ENOMEM;
382 goto err;
383 }
384
385 cinfo = card->ctrlinfo;
386 card->port = pci_resource_start(pdev, 0);
387 card->irq = pdev->irq;
388 card->cardtype = avm_t1isa;
389 card->cardnr = cardnr;
390 sprintf(card->name, "t1isa-%x", card->port);
391
392 if (!(((card->port & 0x7) == 0) && ((card->port & 0x30) != 0x30))) {
393 printk(KERN_WARNING "t1isa: invalid port 0x%x.\n", card->port);
394 retval = -EINVAL;
395 goto err_free;
396 }
397 if (hema_irq_table[card->irq & 0xf] == 0) {
398 printk(KERN_WARNING "t1isa: irq %d not valid.\n", card->irq);
399 retval = -EINVAL;
400 goto err_free;
401 }
402 if (!request_region(card->port, AVMB1_PORTLEN, card->name)) {
403 printk(KERN_INFO "t1isa: ports 0x%03x-0x%03x in use.\n",
404 card->port, card->port + AVMB1_PORTLEN);
405 retval = -EBUSY;
406 goto err_free;
407 }
408 retval = request_irq(card->irq, t1isa_interrupt, 0, card->name, card);
409 if (retval) {
410 printk(KERN_INFO "t1isa: unable to get IRQ %d.\n", card->irq);
411 retval = -EBUSY;
412 goto err_release_region;
413 }
414
415 if ((retval = t1_detectandinit(card->port, card->irq, card->cardnr)) != 0) {
416 printk(KERN_INFO "t1isa: NO card at 0x%x (%d)\n",
417 card->port, retval);
418 retval = -ENODEV;
419 goto err_free_irq;
420 }
421 t1_disable_irq(card->port);
422 b1_reset(card->port);
423
424 cinfo->capi_ctrl.owner = THIS_MODULE;
425 cinfo->capi_ctrl.driver_name = "t1isa";
426 cinfo->capi_ctrl.driverdata = cinfo;
427 cinfo->capi_ctrl.register_appl = b1_register_appl;
428 cinfo->capi_ctrl.release_appl = b1_release_appl;
429 cinfo->capi_ctrl.send_message = t1isa_send_message;
430 cinfo->capi_ctrl.load_firmware = t1isa_load_firmware;
431 cinfo->capi_ctrl.reset_ctr = t1isa_reset_ctr;
432 cinfo->capi_ctrl.procinfo = t1isa_procinfo;
433 cinfo->capi_ctrl.ctr_read_proc = b1ctl_read_proc;
434 strcpy(cinfo->capi_ctrl.name, card->name);
435
436 retval = attach_capi_ctr(&cinfo->capi_ctrl);
437 if (retval) {
438 printk(KERN_INFO "t1isa: attach controller failed.\n");
439 goto err_free_irq;
440 }
441
442 printk(KERN_INFO "t1isa: AVM T1 ISA at i/o %#x, irq %d, card %d\n",
443 card->port, card->irq, card->cardnr);
444
445 pci_set_drvdata(pdev, cinfo);
446 return 0;
447
448 err_free_irq:
449 free_irq(card->irq, card);
450 err_release_region:
451 release_region(card->port, AVMB1_PORTLEN);
452 err_free:
453 b1_free_card(card);
454 err:
455 return retval;
456}
457
458static u16 t1isa_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
459{
460 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
461 avmcard *card = cinfo->card;
462 unsigned int port = card->port;
463 unsigned long flags;
464 u16 len = CAPIMSG_LEN(skb->data);
465 u8 cmd = CAPIMSG_COMMAND(skb->data);
466 u8 subcmd = CAPIMSG_SUBCOMMAND(skb->data);
467 u16 dlen, retval;
468
469 if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) {
470 retval = capilib_data_b3_req(&cinfo->ncci_head,
471 CAPIMSG_APPID(skb->data),
472 CAPIMSG_NCCI(skb->data),
473 CAPIMSG_MSGID(skb->data));
474 if (retval != CAPI_NOERROR)
475 return retval;
476
477 dlen = CAPIMSG_DATALEN(skb->data);
478
479 spin_lock_irqsave(&card->lock, flags);
480 b1_put_byte(port, SEND_DATA_B3_REQ);
481 t1_put_slice(port, skb->data, len);
482 t1_put_slice(port, skb->data + len, dlen);
483 spin_unlock_irqrestore(&card->lock, flags);
484 } else {
485
486 spin_lock_irqsave(&card->lock, flags);
487 b1_put_byte(port, SEND_MESSAGE);
488 t1_put_slice(port, skb->data, len);
489 spin_unlock_irqrestore(&card->lock, flags);
490 }
491
492 dev_kfree_skb_any(skb);
493 return CAPI_NOERROR;
494}
495/* ------------------------------------------------------------- */
496
497static char *t1isa_procinfo(struct capi_ctr *ctrl)
498{
499 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
500
501 if (!cinfo)
502 return "";
503 sprintf(cinfo->infobuf, "%s %s 0x%x %d %d",
504 cinfo->cardname[0] ? cinfo->cardname : "-",
505 cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-",
506 cinfo->card ? cinfo->card->port : 0x0,
507 cinfo->card ? cinfo->card->irq : 0,
508 cinfo->card ? cinfo->card->cardnr : 0
509 );
510 return cinfo->infobuf;
511}
512
513
514/* ------------------------------------------------------------- */
515
516#define MAX_CARDS 4
517static struct pci_dev isa_dev[MAX_CARDS];
518static int io[MAX_CARDS];
519static int irq[MAX_CARDS];
520static int cardnr[MAX_CARDS];
521
522MODULE_PARM(io, "1-" __MODULE_STRING(MAX_CARDS) "i");
523MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_CARDS) "i");
524MODULE_PARM(cardnr, "1-" __MODULE_STRING(MAX_CARDS) "i");
525MODULE_PARM_DESC(io, "I/O base address(es)");
526MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)");
527MODULE_PARM_DESC(cardnr, "Card number(s) (as jumpered)");
528
529static int t1isa_add_card(struct capi_driver *driver, capicardparams *data)
530{
531 int i;
532
533 for (i = 0; i < MAX_CARDS; i++) {
534 if (isa_dev[i].resource[0].start)
535 continue;
536
537 isa_dev[i].resource[0].start = data->port;
538 isa_dev[i].irq = data->irq;
539
540 if (t1isa_probe(&isa_dev[i], data->cardnr) == 0)
541 return 0;
542 }
543 return -ENODEV;
544}
545
546static struct capi_driver capi_driver_t1isa = {
547 .name = "t1isa",
548 .revision = "1.0",
549 .add_card = t1isa_add_card,
550};
551
552static int __init t1isa_init(void)
553{
554 char rev[32];
555 char *p;
556 int i;
557
558 if ((p = strchr(revision, ':')) != 0 && p[1]) {
559 strlcpy(rev, p + 2, 32);
560 if ((p = strchr(rev, '$')) != 0 && p > rev)
561 *(p-1) = 0;
562 } else
563 strcpy(rev, "1.0");
564
565 for (i = 0; i < MAX_CARDS; i++) {
566 if (!io[i])
567 break;
568
569 isa_dev[i].resource[0].start = io[i];
570 isa_dev[i].irq = irq[i];
571
572 if (t1isa_probe(&isa_dev[i], cardnr[i]) != 0)
573 return -ENODEV;
574 }
575
576 strlcpy(capi_driver_t1isa.revision, rev, 32);
577 register_capi_driver(&capi_driver_t1isa);
578 printk(KERN_INFO "t1isa: revision %s\n", rev);
579
580 return 0;
581}
582
583static void __exit t1isa_exit(void)
584{
585 int i;
586
587 for (i = 0; i < MAX_CARDS; i++) {
588 if (!io[i])
589 break;
590
591 t1isa_remove(&isa_dev[i]);
592 }
593}
594
595module_init(t1isa_init);
596module_exit(t1isa_exit);
diff --git a/drivers/isdn/hardware/avm/t1pci.c b/drivers/isdn/hardware/avm/t1pci.c
new file mode 100644
index 000000000000..2ceec8e8419f
--- /dev/null
+++ b/drivers/isdn/hardware/avm/t1pci.c
@@ -0,0 +1,260 @@
1/* $Id: t1pci.c,v 1.1.2.2 2004/01/16 21:09:27 keil Exp $
2 *
3 * Module for AVM T1 PCI-card.
4 *
5 * Copyright 1999 by Carsten Paeth <calle@calle.de>
6 *
7 * This software may be used and distributed according to the terms
8 * of the GNU General Public License, incorporated herein by reference.
9 *
10 */
11
12#include <linux/config.h>
13#include <linux/module.h>
14#include <linux/kernel.h>
15#include <linux/skbuff.h>
16#include <linux/delay.h>
17#include <linux/mm.h>
18#include <linux/interrupt.h>
19#include <linux/ioport.h>
20#include <linux/pci.h>
21#include <linux/capi.h>
22#include <linux/init.h>
23#include <asm/io.h>
24#include <linux/isdn/capicmd.h>
25#include <linux/isdn/capiutil.h>
26#include <linux/isdn/capilli.h>
27#include "avmcard.h"
28
29#undef CONFIG_T1PCI_DEBUG
30#undef CONFIG_T1PCI_POLLDEBUG
31
32/* ------------------------------------------------------------- */
33static char *revision = "$Revision: 1.1.2.2 $";
34/* ------------------------------------------------------------- */
35
36static struct pci_device_id t1pci_pci_tbl[] = {
37 { PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_T1, PCI_ANY_ID, PCI_ANY_ID },
38 { } /* Terminating entry */
39};
40
41MODULE_DEVICE_TABLE(pci, t1pci_pci_tbl);
42MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM T1 PCI card");
43MODULE_AUTHOR("Carsten Paeth");
44MODULE_LICENSE("GPL");
45
46/* ------------------------------------------------------------- */
47
48static char *t1pci_procinfo(struct capi_ctr *ctrl);
49
50static int t1pci_add_card(struct capicardparams *p, struct pci_dev *pdev)
51{
52 avmcard *card;
53 avmctrl_info *cinfo;
54 int retval;
55
56 card = b1_alloc_card(1);
57 if (!card) {
58 printk(KERN_WARNING "t1pci: no memory.\n");
59 retval = -ENOMEM;
60 goto err;
61 }
62
63 card->dma = avmcard_dma_alloc("t1pci", pdev, 2048+128, 2048+128);
64 if (!card->dma) {
65 printk(KERN_WARNING "t1pci: no memory.\n");
66 retval = -ENOMEM;
67 goto err_free;
68 }
69
70 cinfo = card->ctrlinfo;
71 sprintf(card->name, "t1pci-%x", p->port);
72 card->port = p->port;
73 card->irq = p->irq;
74 card->membase = p->membase;
75 card->cardtype = avm_t1pci;
76
77 if (!request_region(card->port, AVMB1_PORTLEN, card->name)) {
78 printk(KERN_WARNING "t1pci: ports 0x%03x-0x%03x in use.\n",
79 card->port, card->port + AVMB1_PORTLEN);
80 retval = -EBUSY;
81 goto err_free_dma;
82 }
83
84 card->mbase = ioremap(card->membase, 64);
85 if (!card->mbase) {
86 printk(KERN_NOTICE "t1pci: can't remap memory at 0x%lx\n",
87 card->membase);
88 retval = -EIO;
89 goto err_release_region;
90 }
91
92 b1dma_reset(card);
93
94 retval = t1pci_detect(card);
95 if (retval != 0) {
96 if (retval < 6)
97 printk(KERN_NOTICE "t1pci: NO card at 0x%x (%d)\n",
98 card->port, retval);
99 else
100 printk(KERN_NOTICE "t1pci: card at 0x%x, but cable not connected or T1 has no power (%d)\n",
101 card->port, retval);
102 retval = -EIO;
103 goto err_unmap;
104 }
105 b1dma_reset(card);
106
107 retval = request_irq(card->irq, b1dma_interrupt, SA_SHIRQ, card->name, card);
108 if (retval) {
109 printk(KERN_ERR "t1pci: unable to get IRQ %d.\n", card->irq);
110 retval = -EBUSY;
111 goto err_unmap;
112 }
113
114 cinfo->capi_ctrl.owner = THIS_MODULE;
115 cinfo->capi_ctrl.driver_name = "t1pci";
116 cinfo->capi_ctrl.driverdata = cinfo;
117 cinfo->capi_ctrl.register_appl = b1dma_register_appl;
118 cinfo->capi_ctrl.release_appl = b1dma_release_appl;
119 cinfo->capi_ctrl.send_message = b1dma_send_message;
120 cinfo->capi_ctrl.load_firmware = b1dma_load_firmware;
121 cinfo->capi_ctrl.reset_ctr = b1dma_reset_ctr;
122 cinfo->capi_ctrl.procinfo = t1pci_procinfo;
123 cinfo->capi_ctrl.ctr_read_proc = b1dmactl_read_proc;
124 strcpy(cinfo->capi_ctrl.name, card->name);
125
126 retval = attach_capi_ctr(&cinfo->capi_ctrl);
127 if (retval) {
128 printk(KERN_ERR "t1pci: attach controller failed.\n");
129 retval = -EBUSY;
130 goto err_free_irq;
131 }
132 card->cardnr = cinfo->capi_ctrl.cnr;
133
134 printk(KERN_INFO "t1pci: AVM T1 PCI at i/o %#x, irq %d, mem %#lx\n",
135 card->port, card->irq, card->membase);
136
137 pci_set_drvdata(pdev, card);
138 return 0;
139
140 err_free_irq:
141 free_irq(card->irq, card);
142 err_unmap:
143 iounmap(card->mbase);
144 err_release_region:
145 release_region(card->port, AVMB1_PORTLEN);
146 err_free_dma:
147 avmcard_dma_free(card->dma);
148 err_free:
149 b1_free_card(card);
150 err:
151 return retval;
152}
153
154/* ------------------------------------------------------------- */
155
156static void t1pci_remove(struct pci_dev *pdev)
157{
158 avmcard *card = pci_get_drvdata(pdev);
159 avmctrl_info *cinfo = card->ctrlinfo;
160
161 b1dma_reset(card);
162
163 detach_capi_ctr(&cinfo->capi_ctrl);
164 free_irq(card->irq, card);
165 iounmap(card->mbase);
166 release_region(card->port, AVMB1_PORTLEN);
167 avmcard_dma_free(card->dma);
168 b1_free_card(card);
169}
170
171/* ------------------------------------------------------------- */
172
173static char *t1pci_procinfo(struct capi_ctr *ctrl)
174{
175 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
176
177 if (!cinfo)
178 return "";
179 sprintf(cinfo->infobuf, "%s %s 0x%x %d 0x%lx",
180 cinfo->cardname[0] ? cinfo->cardname : "-",
181 cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-",
182 cinfo->card ? cinfo->card->port : 0x0,
183 cinfo->card ? cinfo->card->irq : 0,
184 cinfo->card ? cinfo->card->membase : 0
185 );
186 return cinfo->infobuf;
187}
188
189/* ------------------------------------------------------------- */
190
191static int __devinit t1pci_probe(struct pci_dev *dev,
192 const struct pci_device_id *ent)
193{
194 struct capicardparams param;
195 int retval;
196
197 if (pci_enable_device(dev) < 0) {
198 printk(KERN_ERR "t1pci: failed to enable AVM-T1-PCI\n");
199 return -ENODEV;
200 }
201 pci_set_master(dev);
202
203 param.port = pci_resource_start(dev, 1);
204 param.irq = dev->irq;
205 param.membase = pci_resource_start(dev, 0);
206
207 printk(KERN_INFO "t1pci: PCI BIOS reports AVM-T1-PCI at i/o %#x, irq %d, mem %#x\n",
208 param.port, param.irq, param.membase);
209
210 retval = t1pci_add_card(&param, dev);
211 if (retval != 0) {
212 printk(KERN_ERR "t1pci: no AVM-T1-PCI at i/o %#x, irq %d detected, mem %#x\n",
213 param.port, param.irq, param.membase);
214 return -ENODEV;
215 }
216 return 0;
217}
218
219static struct pci_driver t1pci_pci_driver = {
220 .name = "t1pci",
221 .id_table = t1pci_pci_tbl,
222 .probe = t1pci_probe,
223 .remove = t1pci_remove,
224};
225
226static struct capi_driver capi_driver_t1pci = {
227 .name = "t1pci",
228 .revision = "1.0",
229};
230
231static int __init t1pci_init(void)
232{
233 char *p;
234 char rev[32];
235 int err;
236
237 if ((p = strchr(revision, ':')) != 0 && p[1]) {
238 strlcpy(rev, p + 2, 32);
239 if ((p = strchr(rev, '$')) != 0 && p > rev)
240 *(p-1) = 0;
241 } else
242 strcpy(rev, "1.0");
243
244 err = pci_register_driver(&t1pci_pci_driver);
245 if (!err) {
246 strlcpy(capi_driver_t1pci.revision, rev, 32);
247 register_capi_driver(&capi_driver_t1pci);
248 printk(KERN_INFO "t1pci: revision %s\n", rev);
249 }
250 return err;
251}
252
253static void __exit t1pci_exit(void)
254{
255 unregister_capi_driver(&capi_driver_t1pci);
256 pci_unregister_driver(&t1pci_pci_driver);
257}
258
259module_init(t1pci_init);
260module_exit(t1pci_exit);