1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26#include <linux/version.h>
27#include <linux/module.h>
28#include <linux/init.h>
29#include <linux/pci.h>
30#include <linux/isapnp.h>
31#include <linux/kmod.h>
32#include <linux/slab.h>
33#include <linux/skbuff.h>
34#include <linux/netdevice.h>
35
36#include <asm/io.h>
37
38#include "hisax_fcpcipnp.h"
39
40
41#define __debug_variable debug
42#include "hisax_debug.h"
43
44#ifdef CONFIG_HISAX_DEBUG
45static int debug = 0;
46MODULE_PARM(debug, "i");
47#endif
48
49MODULE_AUTHOR("Kai Germaschewski <kai.germaschewski@gmx.de>/Karsten Keil <kkeil@suse.de>");
50MODULE_DESCRIPTION("AVM Fritz!PCI/PnP ISDN driver");
51
52static struct pci_device_id fcpci_ids[] __devinitdata = {
53 { PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_A1 , PCI_ANY_ID, PCI_ANY_ID,
54 0, 0, (unsigned long) "Fritz!Card PCI" },
55 { PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_A1_V2, PCI_ANY_ID, PCI_ANY_ID,
56 0, 0, (unsigned long) "Fritz!Card PCI v2" },
57 { }
58};
59MODULE_DEVICE_TABLE(pci, fcpci_ids);
60
61static struct isapnp_device_id fcpnp_ids[] __devinitdata = {
62 { ISAPNP_VENDOR('A', 'V', 'M'), ISAPNP_FUNCTION(0x0900),
63 ISAPNP_VENDOR('A', 'V', 'M'), ISAPNP_FUNCTION(0x0900),
64 (unsigned long) "Fritz!Card PnP" },
65 { }
66};
67MODULE_DEVICE_TABLE(isapnp, fcpnp_ids);
68
69static int protocol = 2;
70MODULE_PARM(protocol, "i");
71MODULE_LICENSE("GPL");
72
73
74
75#define AVM_INDEX 0x04
76#define AVM_DATA 0x10
77
78#define AVM_IDX_HDLC_1 0x00
79#define AVM_IDX_HDLC_2 0x01
80#define AVM_IDX_ISAC_FIFO 0x02
81#define AVM_IDX_ISAC_REG_LOW 0x04
82#define AVM_IDX_ISAC_REG_HIGH 0x06
83
84#define AVM_STATUS0 0x02
85
86#define AVM_STATUS0_IRQ_ISAC 0x01
87#define AVM_STATUS0_IRQ_HDLC 0x02
88#define AVM_STATUS0_IRQ_TIMER 0x04
89#define AVM_STATUS0_IRQ_MASK 0x07
90
91#define AVM_STATUS0_RESET 0x01
92#define AVM_STATUS0_DIS_TIMER 0x02
93#define AVM_STATUS0_RES_TIMER 0x04
94#define AVM_STATUS0_ENA_IRQ 0x08
95#define AVM_STATUS0_TESTBIT 0x10
96
97#define AVM_STATUS1 0x03
98#define AVM_STATUS1_ENA_IOM 0x80
99
100#define HDLC_FIFO 0x0
101#define HDLC_STATUS 0x4
102#define HDLC_CTRL 0x4
103
104#define HDLC_MODE_ITF_FLG 0x01
105#define HDLC_MODE_TRANS 0x02
106#define HDLC_MODE_CCR_7 0x04
107#define HDLC_MODE_CCR_16 0x08
108#define HDLC_MODE_TESTLOOP 0x80
109
110#define HDLC_INT_XPR 0x80
111#define HDLC_INT_XDU 0x40
112#define HDLC_INT_RPR 0x20
113#define HDLC_INT_MASK 0xE0
114
115#define HDLC_STAT_RME 0x01
116#define HDLC_STAT_RDO 0x10
117#define HDLC_STAT_CRCVFRRAB 0x0E
118#define HDLC_STAT_CRCVFR 0x06
119#define HDLC_STAT_RML_MASK 0x3f00
120
121#define HDLC_CMD_XRS 0x80
122#define HDLC_CMD_XME 0x01
123#define HDLC_CMD_RRS 0x20
124#define HDLC_CMD_XML_MASK 0x3f00
125
126#define AVM_HDLC_FIFO_1 0x10
127#define AVM_HDLC_FIFO_2 0x18
128
129#define AVM_HDLC_STATUS_1 0x14
130#define AVM_HDLC_STATUS_2 0x1c
131
132#define AVM_ISACSX_INDEX 0x04
133#define AVM_ISACSX_DATA 0x08
134
135
136
137
138static unsigned char fcpci_read_isac(struct isac *isac, unsigned char offset)
139{
140 struct fritz_adapter *adapter = isac->priv;
141 unsigned char idx = (offset > 0x2f) ?
142 AVM_IDX_ISAC_REG_HIGH : AVM_IDX_ISAC_REG_LOW;
143 unsigned char val;
144 unsigned long flags;
145
146 spin_lock_irqsave(&adapter->hw_lock, flags);
147 outb(idx, adapter->io + AVM_INDEX);
148 val = inb(adapter->io + AVM_DATA + (offset & 0xf));
149 spin_unlock_irqrestore(&adapter->hw_lock, flags);
150 DBG(0x1000, " port %#x, value %#x",
151 offset, val);
152 return val;
153}
154
155static void fcpci_write_isac(struct isac *isac, unsigned char offset,
156 unsigned char value)
157{
158 struct fritz_adapter *adapter = isac->priv;
159 unsigned char idx = (offset > 0x2f) ?
160 AVM_IDX_ISAC_REG_HIGH : AVM_IDX_ISAC_REG_LOW;
161 unsigned long flags;
162
163 DBG(0x1000, " port %#x, value %#x",
164 offset, value);
165 spin_lock_irqsave(&adapter->hw_lock, flags);
166 outb(idx, adapter->io + AVM_INDEX);
167 outb(value, adapter->io + AVM_DATA + (offset & 0xf));
168 spin_unlock_irqrestore(&adapter->hw_lock, flags);
169}
170
171static void fcpci_read_isac_fifo(struct isac *isac, unsigned char * data,
172 int size)
173{
174 struct fritz_adapter *adapter = isac->priv;
175 unsigned long flags;
176
177 spin_lock_irqsave(&adapter->hw_lock, flags);
178 outb(AVM_IDX_ISAC_FIFO, adapter->io + AVM_INDEX);
179 insb(adapter->io + AVM_DATA, data, size);
180 spin_unlock_irqrestore(&adapter->hw_lock, flags);
181}
182
183static void fcpci_write_isac_fifo(struct isac *isac, unsigned char * data,
184 int size)
185{
186 struct fritz_adapter *adapter = isac->priv;
187 unsigned long flags;
188
189 spin_lock_irqsave(&adapter->hw_lock, flags);
190 outb(AVM_IDX_ISAC_FIFO, adapter->io + AVM_INDEX);
191 outsb(adapter->io + AVM_DATA, data, size);
192 spin_unlock_irqrestore(&adapter->hw_lock, flags);
193}
194
195static u32 fcpci_read_hdlc_status(struct fritz_adapter *adapter, int nr)
196{
197 u32 val;
198 int idx = nr ? AVM_IDX_HDLC_2 : AVM_IDX_HDLC_1;
199 unsigned long flags;
200
201 spin_lock_irqsave(&adapter->hw_lock, flags);
202 outl(idx, adapter->io + AVM_INDEX);
203 val = inl(adapter->io + AVM_DATA + HDLC_STATUS);
204 spin_unlock_irqrestore(&adapter->hw_lock, flags);
205 return val;
206}
207
208static void __fcpci_write_ctrl(struct fritz_bcs *bcs, int which)
209{
210 struct fritz_adapter *adapter = bcs->adapter;
211 int idx = bcs->channel ? AVM_IDX_HDLC_2 : AVM_IDX_HDLC_1;
212
213 DBG(0x40, "hdlc %c wr%x ctrl %x",
214 'A' + bcs->channel, which, bcs->ctrl.ctrl);
215
216 outl(idx, adapter->io + AVM_INDEX);
217 outl(bcs->ctrl.ctrl, adapter->io + AVM_DATA + HDLC_CTRL);
218}
219
220static void fcpci_write_ctrl(struct fritz_bcs *bcs, int which)
221{
222 struct fritz_adapter *adapter = bcs->adapter;
223 unsigned long flags;
224
225 spin_lock_irqsave(&adapter->hw_lock, flags);
226 __fcpci_write_ctrl(bcs, which);
227 spin_unlock_irqrestore(&adapter->hw_lock, flags);
228}
229
230
231
232
233static unsigned char fcpci2_read_isac(struct isac *isac, unsigned char offset)
234{
235 struct fritz_adapter *adapter = isac->priv;
236 unsigned char val;
237 unsigned long flags;
238
239 spin_lock_irqsave(&adapter->hw_lock, flags);
240 outl(offset, adapter->io + AVM_ISACSX_INDEX);
241 val = inl(adapter->io + AVM_ISACSX_DATA);
242 spin_unlock_irqrestore(&adapter->hw_lock, flags);
243 DBG(0x1000, " port %#x, value %#x",
244 offset, val);
245
246 return val;
247}
248
249static void fcpci2_write_isac(struct isac *isac, unsigned char offset,
250 unsigned char value)
251{
252 struct fritz_adapter *adapter = isac->priv;
253 unsigned long flags;
254
255 DBG(0x1000, " port %#x, value %#x",
256 offset, value);
257 spin_lock_irqsave(&adapter->hw_lock, flags);
258 outl(offset, adapter->io + AVM_ISACSX_INDEX);
259 outl(value, adapter->io + AVM_ISACSX_DATA);
260 spin_unlock_irqrestore(&adapter->hw_lock, flags);
261}
262
263static void fcpci2_read_isac_fifo(struct isac *isac, unsigned char * data,
264 int size)
265{
266 struct fritz_adapter *adapter = isac->priv;
267 int i;
268 unsigned long flags;
269
270 spin_lock_irqsave(&adapter->hw_lock, flags);
271 outl(0, adapter->io + AVM_ISACSX_INDEX);
272 for (i = 0; i < size; i++)
273 data[i] = inl(adapter->io + AVM_ISACSX_DATA);
274 spin_unlock_irqrestore(&adapter->hw_lock, flags);
275}
276
277static void fcpci2_write_isac_fifo(struct isac *isac, unsigned char * data,
278 int size)
279{
280 struct fritz_adapter *adapter = isac->priv;
281 int i;
282 unsigned long flags;
283
284 spin_lock_irqsave(&adapter->hw_lock, flags);
285 outl(0, adapter->io + AVM_ISACSX_INDEX);
286 for (i = 0; i < size; i++)
287 outl(data[i], adapter->io + AVM_ISACSX_DATA);
288 spin_unlock_irqrestore(&adapter->hw_lock, flags);
289}
290
291static u32 fcpci2_read_hdlc_status(struct fritz_adapter *adapter, int nr)
292{
293 int offset = nr ? AVM_HDLC_STATUS_2 : AVM_HDLC_STATUS_1;
294
295 return inl(adapter->io + offset);
296}
297
298static void fcpci2_write_ctrl(struct fritz_bcs *bcs, int which)
299{
300 struct fritz_adapter *adapter = bcs->adapter;
301 int offset = bcs->channel ? AVM_HDLC_STATUS_2 : AVM_HDLC_STATUS_1;
302
303 DBG(0x40, "hdlc %c wr%x ctrl %x",
304 'A' + bcs->channel, which, bcs->ctrl.ctrl);
305
306 outl(bcs->ctrl.ctrl, adapter->io + offset);
307}
308
309
310
311
312static u32 fcpnp_read_hdlc_status(struct fritz_adapter *adapter, int nr)
313{
314 unsigned char idx = nr ? AVM_IDX_HDLC_2 : AVM_IDX_HDLC_1;
315 u32 val;
316 unsigned long flags;
317
318 spin_lock_irqsave(&adapter->hw_lock, flags);
319 outb(idx, adapter->io + AVM_INDEX);
320 val = inb(adapter->io + AVM_DATA + HDLC_STATUS);
321 if (val & HDLC_INT_RPR)
322 val |= inb(adapter->io + AVM_DATA + HDLC_STATUS + 1) << 8;
323 spin_unlock_irqrestore(&adapter->hw_lock, flags);
324 return val;
325}
326
327static void __fcpnp_write_ctrl(struct fritz_bcs *bcs, int which)
328{
329 struct fritz_adapter *adapter = bcs->adapter;
330 unsigned char idx = bcs->channel ? AVM_IDX_HDLC_2 : AVM_IDX_HDLC_1;
331
332 DBG(0x40, "hdlc %c wr%x ctrl %x",
333 'A' + bcs->channel, which, bcs->ctrl.ctrl);
334
335 outb(idx, adapter->io + AVM_INDEX);
336 if (which & 4)
337 outb(bcs->ctrl.sr.mode,
338 adapter->io + AVM_DATA + HDLC_STATUS + 2);
339 if (which & 2)
340 outb(bcs->ctrl.sr.xml,
341 adapter->io + AVM_DATA + HDLC_STATUS + 1);
342 if (which & 1)
343 outb(bcs->ctrl.sr.cmd,
344 adapter->io + AVM_DATA + HDLC_STATUS + 0);
345}
346
347static void fcpnp_write_ctrl(struct fritz_bcs *bcs, int which)
348{
349 struct fritz_adapter *adapter = bcs->adapter;
350 unsigned long flags;
351
352 spin_lock_irqsave(&adapter->hw_lock, flags);
353 __fcpnp_write_ctrl(bcs, which);
354 spin_unlock_irqrestore(&adapter->hw_lock, flags);
355}
356
357
358
359static inline void B_L1L2(struct fritz_bcs *bcs, int pr, void *arg)
360{
361 struct hisax_if *ifc = (struct hisax_if *) &bcs->b_if;
362
363 DBG(2, "pr %#x", pr);
364 ifc->l1l2(ifc, pr, arg);
365}
366
367static void hdlc_fill_fifo(struct fritz_bcs *bcs)
368{
369 struct fritz_adapter *adapter = bcs->adapter;
370 struct sk_buff *skb = bcs->tx_skb;
371 int count;
372 int fifo_size = 32;
373 unsigned long flags;
374 unsigned char *p;
375
376 DBG(0x40, "hdlc_fill_fifo");
377
378 if (skb->len == 0)
379 BUG();
380
381 bcs->ctrl.sr.cmd &= ~HDLC_CMD_XME;
382 if (bcs->tx_skb->len > fifo_size) {
383 count = fifo_size;
384 } else {
385 count = bcs->tx_skb->len;
386 if (bcs->mode != L1_MODE_TRANS)
387 bcs->ctrl.sr.cmd |= HDLC_CMD_XME;
388 }
389 DBG(0x40, "hdlc_fill_fifo %d/%d", count, bcs->tx_skb->len);
390 p = bcs->tx_skb->data;
391 skb_pull(bcs->tx_skb, count);
392 bcs->tx_cnt += count;
393 bcs->ctrl.sr.xml = ((count == fifo_size) ? 0 : count);
394
395 switch (adapter->type) {
396 case AVM_FRITZ_PCI:
397 spin_lock_irqsave(&adapter->hw_lock, flags);
398
399 __fcpci_write_ctrl(bcs, 3);
400 outsl(adapter->io + AVM_DATA + HDLC_FIFO,
401 p, (count + 3) / 4);
402 spin_unlock_irqrestore(&adapter->hw_lock, flags);
403 break;
404 case AVM_FRITZ_PCIV2:
405 fcpci2_write_ctrl(bcs, 3);
406 outsl(adapter->io +
407 (bcs->channel ? AVM_HDLC_FIFO_2 : AVM_HDLC_FIFO_1),
408 p, (count + 3) / 4);
409 break;
410 case AVM_FRITZ_PNP:
411 spin_lock_irqsave(&adapter->hw_lock, flags);
412
413 __fcpnp_write_ctrl(bcs, 3);
414 outsb(adapter->io + AVM_DATA, p, count);
415 spin_unlock_irqrestore(&adapter->hw_lock, flags);
416 break;
417 }
418}
419
420static inline void hdlc_empty_fifo(struct fritz_bcs *bcs, int count)
421{
422 struct fritz_adapter *adapter = bcs->adapter;
423 unsigned char *p;
424 unsigned char idx = bcs->channel ? AVM_IDX_HDLC_2 : AVM_IDX_HDLC_1;
425
426 DBG(0x10, "hdlc_empty_fifo %d", count);
427 if (bcs->rcvidx + count > HSCX_BUFMAX) {
428 DBG(0x10, "hdlc_empty_fifo: incoming packet too large");
429 return;
430 }
431 p = bcs->rcvbuf + bcs->rcvidx;
432 bcs->rcvidx += count;
433 switch (adapter->type) {
434 case AVM_FRITZ_PCI:
435 spin_lock(&adapter->hw_lock);
436 outl(idx, adapter->io + AVM_INDEX);
437 insl(adapter->io + AVM_DATA + HDLC_FIFO,
438 p, (count + 3) / 4);
439 spin_unlock(&adapter->hw_lock);
440 break;
441 case AVM_FRITZ_PCIV2:
442 insl(adapter->io +
443 (bcs->channel ? AVM_HDLC_FIFO_2 : AVM_HDLC_FIFO_1),
444 p, (count + 3) / 4);
445 break;
446 case AVM_FRITZ_PNP:
447 spin_lock(&adapter->hw_lock);
448 outb(idx, adapter->io + AVM_INDEX);
449 insb(adapter->io + AVM_DATA, p, count);
450 spin_unlock(&adapter->hw_lock);
451 break;
452 }
453}
454
455static inline void hdlc_rpr_irq(struct fritz_bcs *bcs, u32 stat)
456{
457 struct fritz_adapter *adapter = bcs->adapter;
458 struct sk_buff *skb;
459 int len;
460
461 if (stat & HDLC_STAT_RDO) {
462 DBG(0x10, "RDO");
463 bcs->ctrl.sr.xml = 0;
464 bcs->ctrl.sr.cmd |= HDLC_CMD_RRS;
465 adapter->write_ctrl(bcs, 1);
466 bcs->ctrl.sr.cmd &= ~HDLC_CMD_RRS;
467 adapter->write_ctrl(bcs, 1);
468 bcs->rcvidx = 0;
469 return;
470 }
471
472 len = (stat & HDLC_STAT_RML_MASK) >> 8;
473 if (len == 0)
474 len = 32;
475
476 hdlc_empty_fifo(bcs, len);
477
478 if ((stat & HDLC_STAT_RME) || (bcs->mode == L1_MODE_TRANS)) {
479 if (((stat & HDLC_STAT_CRCVFRRAB)== HDLC_STAT_CRCVFR) ||
480 (bcs->mode == L1_MODE_TRANS)) {
481 skb = dev_alloc_skb(bcs->rcvidx);
482 if (!skb) {
483 printk(KERN_WARNING "HDLC: receive out of memory\n");
484 } else {
485 memcpy(skb_put(skb, bcs->rcvidx), bcs->rcvbuf,
486 bcs->rcvidx);
487 DBG_SKB(1, skb);
488 B_L1L2(bcs, PH_DATA | INDICATION, skb);
489 }
490 bcs->rcvidx = 0;
491 } else {
492 DBG(0x10, "ch%d invalid frame %#x",
493 bcs->channel, stat);
494 bcs->rcvidx = 0;
495 }
496 }
497}
498
499static inline void hdlc_xdu_irq(struct fritz_bcs *bcs)
500{
501 struct fritz_adapter *adapter = bcs->adapter;
502
503
504
505
506 bcs->ctrl.sr.xml = 0;
507 bcs->ctrl.sr.cmd |= HDLC_CMD_XRS;
508 adapter->write_ctrl(bcs, 1);
509 bcs->ctrl.sr.cmd &= ~HDLC_CMD_XRS;
510 adapter->write_ctrl(bcs, 1);
511
512 if (!bcs->tx_skb) {
513 DBG(0x10, "XDU without skb");
514 return;
515 }
516 skb_push(bcs->tx_skb, bcs->tx_cnt);
517 bcs->tx_cnt = 0;
518 hdlc_fill_fifo(bcs);
519}
520
521static inline void hdlc_xpr_irq(struct fritz_bcs *bcs)
522{
523 struct sk_buff *skb;
524
525 skb = bcs->tx_skb;
526 if (!skb)
527 return;
528
529 if (skb->len) {
530 hdlc_fill_fifo(bcs);
531 return;
532 }
533 bcs->tx_cnt = 0;
534 bcs->tx_skb = NULL;
535 B_L1L2(bcs, PH_DATA | CONFIRM, (void *) skb->truesize);
536 dev_kfree_skb_irq(skb);
537}
538
539static void hdlc_irq_one(struct fritz_bcs *bcs, u32 stat)
540{
541 DBG(0x10, "ch%d stat %#x", bcs->channel, stat);
542 if (stat & HDLC_INT_RPR) {
543 DBG(0x10, "RPR");
544 hdlc_rpr_irq(bcs, stat);
545 }
546 if (stat & HDLC_INT_XDU) {
547 DBG(0x10, "XDU");
548 hdlc_xdu_irq(bcs);
549 }
550 if (stat & HDLC_INT_XPR) {
551 DBG(0x10, "XPR");
552 hdlc_xpr_irq(bcs);
553 }
554}
555
556static inline void hdlc_irq(struct fritz_adapter *adapter)
557{
558 int nr;
559 u32 stat;
560
561 for (nr = 0; nr < 2; nr++) {
562 stat = adapter->read_hdlc_status(adapter, nr);
563 DBG(0x10, "HDLC %c stat %#x", 'A' + nr, stat);
564 if (stat & HDLC_INT_MASK)
565 hdlc_irq_one(&adapter->bcs[nr], stat);
566 }
567}
568
569static void modehdlc(struct fritz_bcs *bcs, int mode)
570{
571 struct fritz_adapter *adapter = bcs->adapter;
572
573 DBG(0x40, "hdlc %c mode %d --> %d",
574 'A' + bcs->channel, bcs->mode, mode);
575
576 if (bcs->mode == mode)
577 return;
578
579 bcs->ctrl.ctrl = 0;
580 bcs->ctrl.sr.cmd = HDLC_CMD_XRS | HDLC_CMD_RRS;
581 switch (mode) {
582 case L1_MODE_NULL:
583 bcs->ctrl.sr.mode = HDLC_MODE_TRANS;
584 adapter->write_ctrl(bcs, 5);
585 break;
586 case L1_MODE_TRANS:
587 case L1_MODE_HDLC:
588 bcs->rcvidx = 0;
589 bcs->tx_cnt = 0;
590 bcs->tx_skb = NULL;
591 if (mode == L1_MODE_TRANS)
592 bcs->ctrl.sr.mode = HDLC_MODE_TRANS;
593 else
594 bcs->ctrl.sr.mode = HDLC_MODE_ITF_FLG;
595 adapter->write_ctrl(bcs, 5);
596 bcs->ctrl.sr.cmd = HDLC_CMD_XRS;
597 adapter->write_ctrl(bcs, 1);
598 bcs->ctrl.sr.cmd = 0;
599 break;
600 }
601 bcs->mode = mode;
602}
603
604static void fritz_b_l2l1(struct hisax_if *ifc, int pr, void *arg)
605{
606 struct fritz_bcs *bcs = ifc->priv;
607 struct sk_buff *skb = arg;
608 int mode;
609
610 DBG(0x10, "pr %#x", pr);
611
612 switch (pr) {
613 case PH_DATA | REQUEST:
614 if (bcs->tx_skb)
615 BUG();
616
617 bcs->tx_skb = skb;
618 DBG_SKB(1, skb);
619 hdlc_fill_fifo(bcs);
620 break;
621 case PH_ACTIVATE | REQUEST:
622 mode = (int) arg;
623 DBG(4,"B%d,PH_ACTIVATE_REQUEST %d", bcs->channel + 1, mode);
624 modehdlc(bcs, mode);
625 B_L1L2(bcs, PH_ACTIVATE | INDICATION, NULL);
626 break;
627 case PH_DEACTIVATE | REQUEST:
628 DBG(4,"B%d,PH_DEACTIVATE_REQUEST", bcs->channel + 1);
629 modehdlc(bcs, L1_MODE_NULL);
630 B_L1L2(bcs, PH_DEACTIVATE | INDICATION, NULL);
631 break;
632 }
633}
634
635
636
637static void fcpci2_irq(int intno, void *dev, struct pt_regs *regs)
638{
639 struct fritz_adapter *adapter = dev;
640 unsigned char val;
641
642 val = inb(adapter->io + AVM_STATUS0);
643 if (!(val & AVM_STATUS0_IRQ_MASK))
644
645 return;
646 DBG(2, "STATUS0 %#x", val);
647 if (val & AVM_STATUS0_IRQ_ISAC)
648 isacsx_irq(&adapter->isac);
649
650 if (val & AVM_STATUS0_IRQ_HDLC)
651 hdlc_irq(adapter);
652}
653
654static void fcpci_irq(int intno, void *dev, struct pt_regs *regs)
655{
656 struct fritz_adapter *adapter = dev;
657 unsigned char sval;
658
659 sval = inb(adapter->io + 2);
660 if ((sval & AVM_STATUS0_IRQ_MASK) == AVM_STATUS0_IRQ_MASK)
661
662 return;
663 DBG(2, "sval %#x", sval);
664 if (!(sval & AVM_STATUS0_IRQ_ISAC))
665 isac_irq(&adapter->isac);
666
667 if (!(sval & AVM_STATUS0_IRQ_HDLC))
668 hdlc_irq(adapter);
669}
670
671
672
673static inline void fcpci2_init(struct fritz_adapter *adapter)
674{
675 outb(AVM_STATUS0_RES_TIMER, adapter->io + AVM_STATUS0);
676 outb(AVM_STATUS0_ENA_IRQ, adapter->io + AVM_STATUS0);
677
678}
679
680static inline void fcpci_init(struct fritz_adapter *adapter)
681{
682 outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER |
683 AVM_STATUS0_ENA_IRQ, adapter->io + AVM_STATUS0);
684
685 outb(AVM_STATUS1_ENA_IOM | adapter->irq,
686 adapter->io + AVM_STATUS1);
687 set_current_state(TASK_UNINTERRUPTIBLE);
688 schedule_timeout(50*HZ / 1000);
689}
690
691
692
693static int __devinit fcpcipnp_setup(struct fritz_adapter *adapter)
694{
695 u32 val = 0;
696 int retval;
697
698 DBG(1,"");
699
700 isac_init(&adapter->isac);
701
702 retval = -EBUSY;
703 if (!request_region(adapter->io, 32, "fcpcipnp"))
704 goto err;
705
706 switch (adapter->type) {
707 case AVM_FRITZ_PCIV2:
708 retval = request_irq(adapter->irq, fcpci2_irq, SA_SHIRQ,
709 "fcpcipnp", adapter);
710 break;
711 case AVM_FRITZ_PCI:
712 retval = request_irq(adapter->irq, fcpci_irq, SA_SHIRQ,
713 "fcpcipnp", adapter);
714 break;
715 case AVM_FRITZ_PNP:
716 retval = request_irq(adapter->irq, fcpci_irq, 0,
717 "fcpcipnp", adapter);
718 break;
719 }
720 if (retval)
721 goto err_region;
722
723 switch (adapter->type) {
724 case AVM_FRITZ_PCIV2:
725 case AVM_FRITZ_PCI:
726 val = inl(adapter->io);
727 break;
728 case AVM_FRITZ_PNP:
729 val = inb(adapter->io);
730 val |= inb(adapter->io + 1) << 8;
731 break;
732 }
733
734 DBG(1, "stat %#x Class %X Rev %d",
735 val, val & 0xff, (val>>8) & 0xff);
736
737 spin_lock_init(&adapter->hw_lock);
738 adapter->isac.priv = adapter;
739 switch (adapter->type) {
740 case AVM_FRITZ_PCIV2:
741 adapter->isac.read_isac = &fcpci2_read_isac;;
742 adapter->isac.write_isac = &fcpci2_write_isac;
743 adapter->isac.read_isac_fifo = &fcpci2_read_isac_fifo;
744 adapter->isac.write_isac_fifo = &fcpci2_write_isac_fifo;
745
746 adapter->read_hdlc_status = &fcpci2_read_hdlc_status;
747 adapter->write_ctrl = &fcpci2_write_ctrl;
748 break;
749 case AVM_FRITZ_PCI:
750 adapter->isac.read_isac = &fcpci_read_isac;;
751 adapter->isac.write_isac = &fcpci_write_isac;
752 adapter->isac.read_isac_fifo = &fcpci_read_isac_fifo;
753 adapter->isac.write_isac_fifo = &fcpci_write_isac_fifo;
754
755 adapter->read_hdlc_status = &fcpci_read_hdlc_status;
756 adapter->write_ctrl = &fcpci_write_ctrl;
757 break;
758 case AVM_FRITZ_PNP:
759 adapter->isac.read_isac = &fcpci_read_isac;;
760 adapter->isac.write_isac = &fcpci_write_isac;
761 adapter->isac.read_isac_fifo = &fcpci_read_isac_fifo;
762 adapter->isac.write_isac_fifo = &fcpci_write_isac_fifo;
763
764 adapter->read_hdlc_status = &fcpnp_read_hdlc_status;
765 adapter->write_ctrl = &fcpnp_write_ctrl;
766 break;
767 }
768
769
770 outb(0, adapter->io + AVM_STATUS0);
771 set_current_state(TASK_UNINTERRUPTIBLE);
772 schedule_timeout(50 * HZ / 1000);
773 outb(AVM_STATUS0_RESET, adapter->io + AVM_STATUS0);
774 set_current_state(TASK_UNINTERRUPTIBLE);
775 schedule_timeout(50 * HZ / 1000);
776 outb(0, adapter->io + AVM_STATUS0);
777 set_current_state(TASK_UNINTERRUPTIBLE);
778 schedule_timeout(10 * HZ / 1000);
779
780 switch (adapter->type) {
781 case AVM_FRITZ_PCIV2:
782 fcpci2_init(adapter);
783 isacsx_setup(&adapter->isac);
784 break;
785 case AVM_FRITZ_PCI:
786 case AVM_FRITZ_PNP:
787 fcpci_init(adapter);
788 isac_setup(&adapter->isac);
789 break;
790 }
791 val = adapter->read_hdlc_status(adapter, 0);
792 DBG(0x20, "HDLC A STA %x", val);
793 val = adapter->read_hdlc_status(adapter, 1);
794 DBG(0x20, "HDLC B STA %x", val);
795
796 adapter->bcs[0].mode = -1;
797 adapter->bcs[1].mode = -1;
798 modehdlc(&adapter->bcs[0], L1_MODE_NULL);
799 modehdlc(&adapter->bcs[1], L1_MODE_NULL);
800
801 return 0;
802
803 err_region:
804 release_region(adapter->io, 32);
805 err:
806 return retval;
807}
808
809static void __devexit fcpcipnp_release(struct fritz_adapter *adapter)
810{
811 DBG(1,"");
812
813 outb(0, adapter->io + AVM_STATUS0);
814 free_irq(adapter->irq, adapter);
815 release_region(adapter->io, 32);
816}
817
818
819
820static struct fritz_adapter * __devinit
821new_adapter(struct pci_dev *pdev)
822{
823 struct fritz_adapter *adapter;
824 struct hisax_b_if *b_if[2];
825 int i;
826
827 adapter = kmalloc(sizeof(struct fritz_adapter), GFP_KERNEL);
828 if (!adapter)
829 return NULL;
830
831 memset(adapter, 0, sizeof(struct fritz_adapter));
832
833 SET_MODULE_OWNER(&adapter->isac.hisax_d_if);
834 adapter->isac.hisax_d_if.ifc.priv = &adapter->isac;
835 adapter->isac.hisax_d_if.ifc.l2l1 = isac_d_l2l1;
836
837 for (i = 0; i < 2; i++) {
838 adapter->bcs[i].adapter = adapter;
839 adapter->bcs[i].channel = i;
840 adapter->bcs[i].b_if.ifc.priv = &adapter->bcs[i];
841 adapter->bcs[i].b_if.ifc.l2l1 = fritz_b_l2l1;
842 }
843
844 pci_set_drvdata(pdev, adapter);
845
846 for (i = 0; i < 2; i++)
847 b_if[i] = &adapter->bcs[i].b_if;
848
849 hisax_register(&adapter->isac.hisax_d_if, b_if, "fcpcipnp", protocol);
850
851 return adapter;
852}
853
854static void delete_adapter(struct fritz_adapter *adapter)
855{
856 hisax_unregister(&adapter->isac.hisax_d_if);
857 kfree(adapter);
858}
859
860static int __devinit fcpci_probe(struct pci_dev *pdev,
861 const struct pci_device_id *ent)
862{
863 struct fritz_adapter *adapter;
864 int retval;
865
866 retval = -ENOMEM;
867 adapter = new_adapter(pdev);
868 if (!adapter)
869 goto err;
870
871 if (pdev->device == PCI_DEVICE_ID_AVM_A1_V2)
872 adapter->type = AVM_FRITZ_PCIV2;
873 else
874 adapter->type = AVM_FRITZ_PCI;
875
876 retval = pci_enable_device(pdev);
877 if (retval)
878 goto err_free;
879
880 adapter->io = pci_resource_start(pdev, 1);
881 adapter->irq = pdev->irq;
882
883 printk(KERN_INFO "hisax_fcpcipnp: found adapter %s at %s\n",
884 (char *) ent->driver_data, pdev->slot_name);
885
886 retval = fcpcipnp_setup(adapter);
887 if (retval)
888 goto err_free;
889
890 return 0;
891
892 err_free:
893 delete_adapter(adapter);
894 err:
895 return retval;
896}
897
898static int __devinit fcpnp_probe(struct pci_dev *pdev,
899 const struct isapnp_device_id *ent)
900{
901 struct fritz_adapter *adapter;
902 int retval;
903
904 retval = -ENOMEM;
905 adapter = new_adapter(pdev);
906 if (!adapter)
907 goto err;
908
909 adapter->type = AVM_FRITZ_PNP;
910
911 pdev->prepare(pdev);
912 pdev->deactivate(pdev);
913 pdev->activate(pdev);
914 adapter->io = pdev->resource[0].start;
915 adapter->irq = pdev->irq_resource[0].start;
916
917 printk(KERN_INFO "hisax_fcpcipnp: found adapter %s at IO %#x irq %d\n",
918 (char *) ent->driver_data, adapter->io, adapter->irq);
919
920 retval = fcpcipnp_setup(adapter);
921 if (retval)
922 goto err_free;
923
924 return 0;
925
926 err_free:
927 delete_adapter(adapter);
928 err:
929 return retval;
930}
931
932static void __devexit fcpci_remove(struct pci_dev *pdev)
933{
934 struct fritz_adapter *adapter = pci_get_drvdata(pdev);
935
936 fcpcipnp_release(adapter);
937 pci_disable_device(pdev);
938 delete_adapter(adapter);
939}
940
941static void __devexit fcpnp_remove(struct pci_dev *pdev)
942{
943 struct fritz_adapter *adapter = pci_get_drvdata(pdev);
944
945 fcpcipnp_release(adapter);
946 pdev->deactivate(pdev);
947 delete_adapter(adapter);
948}
949
950static struct pci_driver fcpci_driver = {
951 name: "fcpci",
952 probe: fcpci_probe,
953 remove: __devexit_p(fcpci_remove),
954 id_table: fcpci_ids,
955};
956
957static struct isapnp_driver fcpnp_driver = {
958 name: "fcpnp",
959 probe: fcpnp_probe,
960 remove: __devexit_p(fcpnp_remove),
961 id_table: fcpnp_ids,
962};
963
964static int __init hisax_fcpcipnp_init(void)
965{
966 int retval, pci_nr_found;
967
968 printk(KERN_INFO "hisax_fcpcipnp: Fritz!Card PCI/PCIv2/PnP ISDN driver v0.0.1\n");
969
970 retval = pci_register_driver(&fcpci_driver);
971 if (retval < 0)
972 goto out;
973 pci_nr_found = retval;
974
975 retval = isapnp_register_driver(&fcpnp_driver);
976 if (retval < 0)
977 goto out_unregister_pci;
978
979#if !defined(CONFIG_HOTPLUG) || defined(MODULE)
980 if (pci_nr_found + retval == 0) {
981 retval = -ENODEV;
982 goto out_unregister_isapnp;
983 }
984#endif
985 return 0;
986
987#if !defined(CONFIG_HOTPLUG) || defined(MODULE)
988 out_unregister_isapnp:
989 isapnp_unregister_driver(&fcpnp_driver);
990#endif
991 out_unregister_pci:
992 pci_unregister_driver(&fcpci_driver);
993 out:
994 return retval;
995}
996
997static void __exit hisax_fcpcipnp_exit(void)
998{
999 isapnp_unregister_driver(&fcpnp_driver);
1000 pci_unregister_driver(&fcpci_driver);
1001}
1002
1003module_init(hisax_fcpcipnp_init);
1004module_exit(hisax_fcpcipnp_exit);
1005