2 * Driver for AVM Fritz!PCI, Fritz!PCI v2, Fritz!PnP ISDN cards
4 * Author Kai Germaschewski
5 * Copyright 2001 by Kai Germaschewski <kai.germaschewski@gmx.de>
6 * 2001 by Karsten Keil <keil@isdn4linux.de>
8 * based upon Karsten Keil's original avm_pci.c driver
10 * This software may be used and distributed according to the terms
11 * of the GNU General Public License, incorporated herein by reference.
13 * Thanks to Wizard Computersysteme GmbH, Bremervoerde and
14 * SoHaNet Technology GmbH, Berlin
15 * for supporting the development of this driver
22 * o clean up debugging
23 * o tx_skb at PH_DEACTIVATE time
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>
38 #include "hisax_fcpcipnp.h"
41 #define __debug_variable debug
42 #include "hisax_debug.h"
44 #ifdef CONFIG_HISAX_DEBUG
46 MODULE_PARM(debug, "i");
49 MODULE_AUTHOR("Kai Germaschewski <kai.germaschewski@gmx.de>/Karsten Keil <kkeil@suse.de>");
50 MODULE_DESCRIPTION("AVM Fritz!PCI/PnP ISDN driver");
52 static 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" },
59 MODULE_DEVICE_TABLE(pci, fcpci_ids);
61 static 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" },
67 MODULE_DEVICE_TABLE(isapnp, fcpnp_ids);
69 static int protocol = 2; /* EURO-ISDN Default */
70 MODULE_PARM(protocol, "i");
71 MODULE_LICENSE("GPL");
73 // ----------------------------------------------------------------------
75 #define AVM_INDEX 0x04
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
84 #define AVM_STATUS0 0x02
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
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
97 #define AVM_STATUS1 0x03
98 #define AVM_STATUS1_ENA_IOM 0x80
100 #define HDLC_FIFO 0x0
101 #define HDLC_STATUS 0x4
102 #define HDLC_CTRL 0x4
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
110 #define HDLC_INT_XPR 0x80
111 #define HDLC_INT_XDU 0x40
112 #define HDLC_INT_RPR 0x20
113 #define HDLC_INT_MASK 0xE0
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
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
126 #define AVM_HDLC_FIFO_1 0x10
127 #define AVM_HDLC_FIFO_2 0x18
129 #define AVM_HDLC_STATUS_1 0x14
130 #define AVM_HDLC_STATUS_2 0x1c
132 #define AVM_ISACSX_INDEX 0x04
133 #define AVM_ISACSX_DATA 0x08
135 // ----------------------------------------------------------------------
138 static unsigned char fcpci_read_isac(struct isac *isac, unsigned char offset)
140 struct fritz_adapter *adapter = isac->priv;
141 unsigned char idx = (offset > 0x2f) ?
142 AVM_IDX_ISAC_REG_HIGH : AVM_IDX_ISAC_REG_LOW;
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",
155 static void fcpci_write_isac(struct isac *isac, unsigned char offset,
158 struct fritz_adapter *adapter = isac->priv;
159 unsigned char idx = (offset > 0x2f) ?
160 AVM_IDX_ISAC_REG_HIGH : AVM_IDX_ISAC_REG_LOW;
163 DBG(0x1000, " port %#x, value %#x",
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);
171 static void fcpci_read_isac_fifo(struct isac *isac, unsigned char * data,
174 struct fritz_adapter *adapter = isac->priv;
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);
183 static void fcpci_write_isac_fifo(struct isac *isac, unsigned char * data,
186 struct fritz_adapter *adapter = isac->priv;
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);
195 static u32 fcpci_read_hdlc_status(struct fritz_adapter *adapter, int nr)
198 int idx = nr ? AVM_IDX_HDLC_2 : AVM_IDX_HDLC_1;
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);
208 static void __fcpci_write_ctrl(struct fritz_bcs *bcs, int which)
210 struct fritz_adapter *adapter = bcs->adapter;
211 int idx = bcs->channel ? AVM_IDX_HDLC_2 : AVM_IDX_HDLC_1;
213 DBG(0x40, "hdlc %c wr%x ctrl %x",
214 'A' + bcs->channel, which, bcs->ctrl.ctrl);
216 outl(idx, adapter->io + AVM_INDEX);
217 outl(bcs->ctrl.ctrl, adapter->io + AVM_DATA + HDLC_CTRL);
220 static void fcpci_write_ctrl(struct fritz_bcs *bcs, int which)
222 struct fritz_adapter *adapter = bcs->adapter;
225 spin_lock_irqsave(&adapter->hw_lock, flags);
226 __fcpci_write_ctrl(bcs, which);
227 spin_unlock_irqrestore(&adapter->hw_lock, flags);
230 // ----------------------------------------------------------------------
233 static unsigned char fcpci2_read_isac(struct isac *isac, unsigned char offset)
235 struct fritz_adapter *adapter = isac->priv;
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",
249 static void fcpci2_write_isac(struct isac *isac, unsigned char offset,
252 struct fritz_adapter *adapter = isac->priv;
255 DBG(0x1000, " port %#x, value %#x",
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);
263 static void fcpci2_read_isac_fifo(struct isac *isac, unsigned char * data,
266 struct fritz_adapter *adapter = isac->priv;
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);
277 static void fcpci2_write_isac_fifo(struct isac *isac, unsigned char * data,
280 struct fritz_adapter *adapter = isac->priv;
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);
291 static u32 fcpci2_read_hdlc_status(struct fritz_adapter *adapter, int nr)
293 int offset = nr ? AVM_HDLC_STATUS_2 : AVM_HDLC_STATUS_1;
295 return inl(adapter->io + offset);
298 static void fcpci2_write_ctrl(struct fritz_bcs *bcs, int which)
300 struct fritz_adapter *adapter = bcs->adapter;
301 int offset = bcs->channel ? AVM_HDLC_STATUS_2 : AVM_HDLC_STATUS_1;
303 DBG(0x40, "hdlc %c wr%x ctrl %x",
304 'A' + bcs->channel, which, bcs->ctrl.ctrl);
306 outl(bcs->ctrl.ctrl, adapter->io + offset);
309 // ----------------------------------------------------------------------
310 // Fritz!PnP (ISAC access as for Fritz!PCI)
312 static u32 fcpnp_read_hdlc_status(struct fritz_adapter *adapter, int nr)
314 unsigned char idx = nr ? AVM_IDX_HDLC_2 : AVM_IDX_HDLC_1;
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);
327 static void __fcpnp_write_ctrl(struct fritz_bcs *bcs, int which)
329 struct fritz_adapter *adapter = bcs->adapter;
330 unsigned char idx = bcs->channel ? AVM_IDX_HDLC_2 : AVM_IDX_HDLC_1;
332 DBG(0x40, "hdlc %c wr%x ctrl %x",
333 'A' + bcs->channel, which, bcs->ctrl.ctrl);
335 outb(idx, adapter->io + AVM_INDEX);
337 outb(bcs->ctrl.sr.mode,
338 adapter->io + AVM_DATA + HDLC_STATUS + 2);
340 outb(bcs->ctrl.sr.xml,
341 adapter->io + AVM_DATA + HDLC_STATUS + 1);
343 outb(bcs->ctrl.sr.cmd,
344 adapter->io + AVM_DATA + HDLC_STATUS + 0);
347 static void fcpnp_write_ctrl(struct fritz_bcs *bcs, int which)
349 struct fritz_adapter *adapter = bcs->adapter;
352 spin_lock_irqsave(&adapter->hw_lock, flags);
353 __fcpnp_write_ctrl(bcs, which);
354 spin_unlock_irqrestore(&adapter->hw_lock, flags);
357 // ----------------------------------------------------------------------
359 static inline void B_L1L2(struct fritz_bcs *bcs, int pr, void *arg)
361 struct hisax_if *ifc = (struct hisax_if *) &bcs->b_if;
363 DBG(2, "pr %#x", pr);
364 ifc->l1l2(ifc, pr, arg);
367 static void hdlc_fill_fifo(struct fritz_bcs *bcs)
369 struct fritz_adapter *adapter = bcs->adapter;
370 struct sk_buff *skb = bcs->tx_skb;
376 DBG(0x40, "hdlc_fill_fifo");
381 bcs->ctrl.sr.cmd &= ~HDLC_CMD_XME;
382 if (bcs->tx_skb->len > fifo_size) {
385 count = bcs->tx_skb->len;
386 if (bcs->mode != L1_MODE_TRANS)
387 bcs->ctrl.sr.cmd |= HDLC_CMD_XME;
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);
395 switch (adapter->type) {
397 spin_lock_irqsave(&adapter->hw_lock, flags);
398 // sets the correct AVM_INDEX, too
399 __fcpci_write_ctrl(bcs, 3);
400 outsl(adapter->io + AVM_DATA + HDLC_FIFO,
402 spin_unlock_irqrestore(&adapter->hw_lock, flags);
404 case AVM_FRITZ_PCIV2:
405 fcpci2_write_ctrl(bcs, 3);
407 (bcs->channel ? AVM_HDLC_FIFO_2 : AVM_HDLC_FIFO_1),
411 spin_lock_irqsave(&adapter->hw_lock, flags);
412 // sets the correct AVM_INDEX, too
413 __fcpnp_write_ctrl(bcs, 3);
414 outsb(adapter->io + AVM_DATA, p, count);
415 spin_unlock_irqrestore(&adapter->hw_lock, flags);
420 static inline void hdlc_empty_fifo(struct fritz_bcs *bcs, int count)
422 struct fritz_adapter *adapter = bcs->adapter;
424 unsigned char idx = bcs->channel ? AVM_IDX_HDLC_2 : AVM_IDX_HDLC_1;
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");
431 p = bcs->rcvbuf + bcs->rcvidx;
432 bcs->rcvidx += count;
433 switch (adapter->type) {
435 spin_lock(&adapter->hw_lock);
436 outl(idx, adapter->io + AVM_INDEX);
437 insl(adapter->io + AVM_DATA + HDLC_FIFO,
439 spin_unlock(&adapter->hw_lock);
441 case AVM_FRITZ_PCIV2:
443 (bcs->channel ? AVM_HDLC_FIFO_2 : AVM_HDLC_FIFO_1),
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);
455 static inline void hdlc_rpr_irq(struct fritz_bcs *bcs, u32 stat)
457 struct fritz_adapter *adapter = bcs->adapter;
461 if (stat & HDLC_STAT_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);
472 len = (stat & HDLC_STAT_RML_MASK) >> 8;
476 hdlc_empty_fifo(bcs, len);
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);
483 printk(KERN_WARNING "HDLC: receive out of memory\n");
485 memcpy(skb_put(skb, bcs->rcvidx), bcs->rcvbuf,
488 B_L1L2(bcs, PH_DATA | INDICATION, skb);
492 DBG(0x10, "ch%d invalid frame %#x",
499 static inline void hdlc_xdu_irq(struct fritz_bcs *bcs)
501 struct fritz_adapter *adapter = bcs->adapter;
503 /* Here we lost an TX interrupt, so
504 * restart transmitting the whole frame.
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);
513 DBG(0x10, "XDU without skb");
516 skb_push(bcs->tx_skb, bcs->tx_cnt);
521 static inline void hdlc_xpr_irq(struct fritz_bcs *bcs)
535 B_L1L2(bcs, PH_DATA | CONFIRM, (void *) skb->truesize);
536 dev_kfree_skb_irq(skb);
539 static void hdlc_irq_one(struct fritz_bcs *bcs, u32 stat)
541 DBG(0x10, "ch%d stat %#x", bcs->channel, stat);
542 if (stat & HDLC_INT_RPR) {
544 hdlc_rpr_irq(bcs, stat);
546 if (stat & HDLC_INT_XDU) {
550 if (stat & HDLC_INT_XPR) {
556 static inline void hdlc_irq(struct fritz_adapter *adapter)
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);
569 static void modehdlc(struct fritz_bcs *bcs, int mode)
571 struct fritz_adapter *adapter = bcs->adapter;
573 DBG(0x40, "hdlc %c mode %d --> %d",
574 'A' + bcs->channel, bcs->mode, mode);
576 if (bcs->mode == mode)
580 bcs->ctrl.sr.cmd = HDLC_CMD_XRS | HDLC_CMD_RRS;
583 bcs->ctrl.sr.mode = HDLC_MODE_TRANS;
584 adapter->write_ctrl(bcs, 5);
591 if (mode == L1_MODE_TRANS)
592 bcs->ctrl.sr.mode = HDLC_MODE_TRANS;
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;
604 static void fritz_b_l2l1(struct hisax_if *ifc, int pr, void *arg)
606 struct fritz_bcs *bcs = ifc->priv;
607 struct sk_buff *skb = arg;
610 DBG(0x10, "pr %#x", pr);
613 case PH_DATA | REQUEST:
621 case PH_ACTIVATE | REQUEST:
623 DBG(4,"B%d,PH_ACTIVATE_REQUEST %d", bcs->channel + 1, mode);
625 B_L1L2(bcs, PH_ACTIVATE | INDICATION, NULL);
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);
635 // ----------------------------------------------------------------------
637 static void fcpci2_irq(int intno, void *dev, struct pt_regs *regs)
639 struct fritz_adapter *adapter = dev;
642 val = inb(adapter->io + AVM_STATUS0);
643 if (!(val & AVM_STATUS0_IRQ_MASK))
644 /* hopefully a shared IRQ reqest */
646 DBG(2, "STATUS0 %#x", val);
647 if (val & AVM_STATUS0_IRQ_ISAC)
648 isacsx_irq(&adapter->isac);
650 if (val & AVM_STATUS0_IRQ_HDLC)
654 static void fcpci_irq(int intno, void *dev, struct pt_regs *regs)
656 struct fritz_adapter *adapter = dev;
659 sval = inb(adapter->io + 2);
660 if ((sval & AVM_STATUS0_IRQ_MASK) == AVM_STATUS0_IRQ_MASK)
661 /* possibly a shared IRQ reqest */
663 DBG(2, "sval %#x", sval);
664 if (!(sval & AVM_STATUS0_IRQ_ISAC))
665 isac_irq(&adapter->isac);
667 if (!(sval & AVM_STATUS0_IRQ_HDLC))
671 // ----------------------------------------------------------------------
673 static inline void fcpci2_init(struct fritz_adapter *adapter)
675 outb(AVM_STATUS0_RES_TIMER, adapter->io + AVM_STATUS0);
676 outb(AVM_STATUS0_ENA_IRQ, adapter->io + AVM_STATUS0);
680 static inline void fcpci_init(struct fritz_adapter *adapter)
682 outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER |
683 AVM_STATUS0_ENA_IRQ, adapter->io + AVM_STATUS0);
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); /* Timeout 50ms */
691 // ----------------------------------------------------------------------
693 static int __devinit fcpcipnp_setup(struct fritz_adapter *adapter)
700 isac_init(&adapter->isac); // FIXME is this okay now
703 if (!request_region(adapter->io, 32, "fcpcipnp"))
706 switch (adapter->type) {
707 case AVM_FRITZ_PCIV2:
708 retval = request_irq(adapter->irq, fcpci2_irq, SA_SHIRQ,
709 "fcpcipnp", adapter);
712 retval = request_irq(adapter->irq, fcpci_irq, SA_SHIRQ,
713 "fcpcipnp", adapter);
716 retval = request_irq(adapter->irq, fcpci_irq, 0,
717 "fcpcipnp", adapter);
723 switch (adapter->type) {
724 case AVM_FRITZ_PCIV2:
726 val = inl(adapter->io);
729 val = inb(adapter->io);
730 val |= inb(adapter->io + 1) << 8;
734 DBG(1, "stat %#x Class %X Rev %d",
735 val, val & 0xff, (val>>8) & 0xff);
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;
746 adapter->read_hdlc_status = &fcpci2_read_hdlc_status;
747 adapter->write_ctrl = &fcpci2_write_ctrl;
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;
755 adapter->read_hdlc_status = &fcpci_read_hdlc_status;
756 adapter->write_ctrl = &fcpci_write_ctrl;
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;
764 adapter->read_hdlc_status = &fcpnp_read_hdlc_status;
765 adapter->write_ctrl = &fcpnp_write_ctrl;
770 outb(0, adapter->io + AVM_STATUS0);
771 set_current_state(TASK_UNINTERRUPTIBLE);
772 schedule_timeout(50 * HZ / 1000); // 50 msec
773 outb(AVM_STATUS0_RESET, adapter->io + AVM_STATUS0);
774 set_current_state(TASK_UNINTERRUPTIBLE);
775 schedule_timeout(50 * HZ / 1000); // 50 msec
776 outb(0, adapter->io + AVM_STATUS0);
777 set_current_state(TASK_UNINTERRUPTIBLE);
778 schedule_timeout(10 * HZ / 1000); // 10 msec
780 switch (adapter->type) {
781 case AVM_FRITZ_PCIV2:
782 fcpci2_init(adapter);
783 isacsx_setup(&adapter->isac);
788 isac_setup(&adapter->isac);
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);
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);
804 release_region(adapter->io, 32);
809 static void __devexit fcpcipnp_release(struct fritz_adapter *adapter)
813 outb(0, adapter->io + AVM_STATUS0);
814 free_irq(adapter->irq, adapter);
815 release_region(adapter->io, 32);
818 // ----------------------------------------------------------------------
820 static struct fritz_adapter * __devinit
821 new_adapter(struct pci_dev *pdev)
823 struct fritz_adapter *adapter;
824 struct hisax_b_if *b_if[2];
827 adapter = kmalloc(sizeof(struct fritz_adapter), GFP_KERNEL);
831 memset(adapter, 0, sizeof(struct fritz_adapter));
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;
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;
844 pci_set_drvdata(pdev, adapter);
846 for (i = 0; i < 2; i++)
847 b_if[i] = &adapter->bcs[i].b_if;
849 hisax_register(&adapter->isac.hisax_d_if, b_if, "fcpcipnp", protocol);
854 static void delete_adapter(struct fritz_adapter *adapter)
856 hisax_unregister(&adapter->isac.hisax_d_if);
860 static int __devinit fcpci_probe(struct pci_dev *pdev,
861 const struct pci_device_id *ent)
863 struct fritz_adapter *adapter;
867 adapter = new_adapter(pdev);
871 if (pdev->device == PCI_DEVICE_ID_AVM_A1_V2)
872 adapter->type = AVM_FRITZ_PCIV2;
874 adapter->type = AVM_FRITZ_PCI;
876 retval = pci_enable_device(pdev);
880 adapter->io = pci_resource_start(pdev, 1);
881 adapter->irq = pdev->irq;
883 printk(KERN_INFO "hisax_fcpcipnp: found adapter %s at %s\n",
884 (char *) ent->driver_data, pdev->slot_name);
886 retval = fcpcipnp_setup(adapter);
893 delete_adapter(adapter);
898 static int __devinit fcpnp_probe(struct pci_dev *pdev,
899 const struct isapnp_device_id *ent)
901 struct fritz_adapter *adapter;
905 adapter = new_adapter(pdev);
909 adapter->type = AVM_FRITZ_PNP;
912 pdev->deactivate(pdev); // why?
913 pdev->activate(pdev);
914 adapter->io = pdev->resource[0].start;
915 adapter->irq = pdev->irq_resource[0].start;
917 printk(KERN_INFO "hisax_fcpcipnp: found adapter %s at IO %#x irq %d\n",
918 (char *) ent->driver_data, adapter->io, adapter->irq);
920 retval = fcpcipnp_setup(adapter);
927 delete_adapter(adapter);
932 static void __devexit fcpci_remove(struct pci_dev *pdev)
934 struct fritz_adapter *adapter = pci_get_drvdata(pdev);
936 fcpcipnp_release(adapter);
937 pci_disable_device(pdev);
938 delete_adapter(adapter);
941 static void __devexit fcpnp_remove(struct pci_dev *pdev)
943 struct fritz_adapter *adapter = pci_get_drvdata(pdev);
945 fcpcipnp_release(adapter);
946 pdev->deactivate(pdev);
947 delete_adapter(adapter);
950 static struct pci_driver fcpci_driver = {
953 remove: __devexit_p(fcpci_remove),
957 static struct isapnp_driver fcpnp_driver = {
960 remove: __devexit_p(fcpnp_remove),
964 static int __init hisax_fcpcipnp_init(void)
966 int retval, pci_nr_found;
968 printk(KERN_INFO "hisax_fcpcipnp: Fritz!Card PCI/PCIv2/PnP ISDN driver v0.0.1\n");
970 retval = pci_register_driver(&fcpci_driver);
973 pci_nr_found = retval;
975 retval = isapnp_register_driver(&fcpnp_driver);
977 goto out_unregister_pci;
979 #if !defined(CONFIG_HOTPLUG) || defined(MODULE)
980 if (pci_nr_found + retval == 0) {
982 goto out_unregister_isapnp;
987 #if !defined(CONFIG_HOTPLUG) || defined(MODULE)
988 out_unregister_isapnp:
989 isapnp_unregister_driver(&fcpnp_driver);
992 pci_unregister_driver(&fcpci_driver);
997 static void __exit hisax_fcpcipnp_exit(void)
999 isapnp_unregister_driver(&fcpnp_driver);
1000 pci_unregister_driver(&fcpci_driver);
1003 module_init(hisax_fcpcipnp_init);
1004 module_exit(hisax_fcpcipnp_exit);