1 /* $Id: avm_pci.c,v 1.22.6.6 2001/09/23 22:24:46 kai Exp $
3 * low level stuff for AVM Fritz!PCI and ISA PnP isdn cards
6 * Copyright by Karsten Keil <keil@isdn4linux.de>
8 * This software may be used and distributed according to the terms
9 * of the GNU General Public License, incorporated herein by reference.
11 * Thanks to AVM, Berlin for information
15 #include <linux/config.h>
16 #include <linux/init.h>
20 #include <linux/pci.h>
21 #include <linux/isapnp.h>
22 #include <linux/interrupt.h>
24 extern const char *CardType
[];
25 static const char *avm_pci_rev
= "$Revision: 1.22.6.6 $";
26 static spinlock_t avm_pci_lock
= SPIN_LOCK_UNLOCKED
;
28 #define AVM_FRITZ_PCI 1
29 #define AVM_FRITZ_PNP 2
32 #define HDLC_STATUS 0x4
34 #define AVM_HDLC_1 0x00
35 #define AVM_HDLC_2 0x01
36 #define AVM_ISAC_FIFO 0x02
37 #define AVM_ISAC_REG_LOW 0x04
38 #define AVM_ISAC_REG_HIGH 0x06
40 #define AVM_STATUS0_IRQ_ISAC 0x01
41 #define AVM_STATUS0_IRQ_HDLC 0x02
42 #define AVM_STATUS0_IRQ_TIMER 0x04
43 #define AVM_STATUS0_IRQ_MASK 0x07
45 #define AVM_STATUS0_RESET 0x01
46 #define AVM_STATUS0_DIS_TIMER 0x02
47 #define AVM_STATUS0_RES_TIMER 0x04
48 #define AVM_STATUS0_ENA_IRQ 0x08
49 #define AVM_STATUS0_TESTBIT 0x10
51 #define AVM_STATUS1_INT_SEL 0x0f
52 #define AVM_STATUS1_ENA_IOM 0x80
54 #define HDLC_MODE_ITF_FLG 0x01
55 #define HDLC_MODE_TRANS 0x02
56 #define HDLC_MODE_CCR_7 0x04
57 #define HDLC_MODE_CCR_16 0x08
58 #define HDLC_MODE_TESTLOOP 0x80
60 #define HDLC_INT_XPR 0x80
61 #define HDLC_INT_XDU 0x40
62 #define HDLC_INT_RPR 0x20
63 #define HDLC_INT_MASK 0xE0
65 #define HDLC_STAT_RME 0x01
66 #define HDLC_STAT_RDO 0x10
67 #define HDLC_STAT_CRCVFRRAB 0x0E
68 #define HDLC_STAT_CRCVFR 0x06
69 #define HDLC_STAT_RML_MASK 0x3f00
71 #define HDLC_CMD_XRS 0x80
72 #define HDLC_CMD_XME 0x01
73 #define HDLC_CMD_RRS 0x20
74 #define HDLC_CMD_XML_MASK 0x3f00
77 /* Interface functions */
80 ReadISAC(struct IsdnCardState
*cs
, u8 offset
)
82 u8 idx
= (offset
> 0x2f) ? AVM_ISAC_REG_HIGH
: AVM_ISAC_REG_LOW
;
86 spin_lock_irqsave(&avm_pci_lock
, flags
);
87 outb(idx
, cs
->hw
.avm
.cfg_reg
+ 4);
88 val
= inb(cs
->hw
.avm
.isac
+ (offset
& 0xf));
89 spin_unlock_irqrestore(&avm_pci_lock
, flags
);
94 WriteISAC(struct IsdnCardState
*cs
, u8 offset
, u8 value
)
96 u8 idx
= (offset
> 0x2f) ? AVM_ISAC_REG_HIGH
: AVM_ISAC_REG_LOW
;
99 spin_lock_irqsave(&avm_pci_lock
, flags
);
100 outb(idx
, cs
->hw
.avm
.cfg_reg
+ 4);
101 outb(value
, cs
->hw
.avm
.isac
+ (offset
& 0xf));
102 spin_unlock_irqrestore(&avm_pci_lock
, flags
);
106 ReadISACfifo(struct IsdnCardState
*cs
, u8
* data
, int size
)
108 outb(AVM_ISAC_FIFO
, cs
->hw
.avm
.cfg_reg
+ 4);
109 insb(cs
->hw
.avm
.isac
, data
, size
);
113 WriteISACfifo(struct IsdnCardState
*cs
, u8
* data
, int size
)
115 outb(AVM_ISAC_FIFO
, cs
->hw
.avm
.cfg_reg
+ 4);
116 outsb(cs
->hw
.avm
.isac
, data
, size
);
119 static struct dc_hw_ops isac_ops
= {
120 .read_reg
= ReadISAC
,
121 .write_reg
= WriteISAC
,
122 .read_fifo
= ReadISACfifo
,
123 .write_fifo
= WriteISACfifo
,
127 ReadHDLCPCI(struct IsdnCardState
*cs
, int chan
, u8 offset
)
129 u_int idx
= chan
? AVM_HDLC_2
: AVM_HDLC_1
;
133 spin_lock_irqsave(&avm_pci_lock
, flags
);
134 outl(idx
, cs
->hw
.avm
.cfg_reg
+ 4);
135 val
= inl(cs
->hw
.avm
.isac
+ offset
);
136 spin_unlock_irqrestore(&avm_pci_lock
, flags
);
141 WriteHDLCPCI(struct IsdnCardState
*cs
, int chan
, u8 offset
, u_int value
)
143 u_int idx
= chan
? AVM_HDLC_2
: AVM_HDLC_1
;
146 spin_lock_irqsave(&avm_pci_lock
, flags
);
147 outl(idx
, cs
->hw
.avm
.cfg_reg
+ 4);
148 outl(value
, cs
->hw
.avm
.isac
+ offset
);
149 spin_unlock_irqrestore(&avm_pci_lock
, flags
);
153 ReadHDLCPnP(struct IsdnCardState
*cs
, int chan
, u8 offset
)
155 u8 idx
= chan
? AVM_HDLC_2
: AVM_HDLC_1
;
159 spin_lock_irqsave(&avm_pci_lock
, flags
);
160 outb(idx
, cs
->hw
.avm
.cfg_reg
+ 4);
161 val
= inb(cs
->hw
.avm
.isac
+ offset
);
162 spin_unlock_irqrestore(&avm_pci_lock
, flags
);
167 WriteHDLCPnP(struct IsdnCardState
*cs
, int chan
, u8 offset
, u8 value
)
169 u8 idx
= chan
? AVM_HDLC_2
: AVM_HDLC_1
;
172 spin_lock_irqsave(&avm_pci_lock
, flags
);
173 outb(idx
, cs
->hw
.avm
.cfg_reg
+ 4);
174 outb(value
, cs
->hw
.avm
.isac
+ offset
);
175 spin_unlock_irqrestore(&avm_pci_lock
, flags
);
179 hdlc_read_fifo(struct IsdnCardState
*cs
, int hscx
, u8
*data
, int len
)
181 u8 idx
= hscx
? AVM_HDLC_2
: AVM_HDLC_1
;
184 if (cs
->subtyp
== AVM_FRITZ_PCI
) {
185 u32
*ptr
= (u32
*) data
;
187 outl(idx
, cs
->hw
.avm
.cfg_reg
+ 4);
188 for (i
= 0; i
< len
; i
+= 4) {
191 *ptr
++ = in_le32((u32
*)(cs
->hw
.avm
.isac
+_IO_BASE
));
193 *ptr
++ = in_be32((u32
*)(cs
->hw
.avm
.isac
+_IO_BASE
));
194 #endif /* CONFIG_APUS */
196 *ptr
++ = inl(cs
->hw
.avm
.isac
);
197 #endif /* __powerpc__ */
200 outb(idx
, cs
->hw
.avm
.cfg_reg
+ 4);
201 for (i
= 0; i
< len
; i
++) {
202 *data
++ = inb(cs
->hw
.avm
.isac
);
207 static struct bc_hw_ops hdlc_hw_ops
= {
208 .read_fifo
= hdlc_read_fifo
,
212 struct BCState
*Sel_BCS(struct IsdnCardState
*cs
, int channel
)
214 if (cs
->bcs
[0].mode
&& (cs
->bcs
[0].channel
== channel
))
216 else if (cs
->bcs
[1].mode
&& (cs
->bcs
[1].channel
== channel
))
223 write_ctrl(struct BCState
*bcs
, int which
) {
225 if (bcs
->cs
->debug
& L1_DEB_HSCX
)
226 debugl1(bcs
->cs
, "hdlc %c wr%x ctrl %x",
227 'A' + bcs
->channel
, which
, bcs
->hw
.hdlc
.ctrl
.ctrl
);
228 if (bcs
->cs
->subtyp
== AVM_FRITZ_PCI
) {
229 WriteHDLCPCI(bcs
->cs
, bcs
->channel
, HDLC_STATUS
, bcs
->hw
.hdlc
.ctrl
.ctrl
);
232 WriteHDLCPnP(bcs
->cs
, bcs
->channel
, HDLC_STATUS
+ 2,
233 bcs
->hw
.hdlc
.ctrl
.sr
.mode
);
235 WriteHDLCPnP(bcs
->cs
, bcs
->channel
, HDLC_STATUS
+ 1,
236 bcs
->hw
.hdlc
.ctrl
.sr
.xml
);
238 WriteHDLCPnP(bcs
->cs
, bcs
->channel
, HDLC_STATUS
,
239 bcs
->hw
.hdlc
.ctrl
.sr
.cmd
);
244 modehdlc(struct BCState
*bcs
, int mode
, int bc
)
246 struct IsdnCardState
*cs
= bcs
->cs
;
247 int hdlc
= bcs
->channel
;
249 if (cs
->debug
& L1_DEB_HSCX
)
250 debugl1(cs
, "hdlc %c mode %d --> %d ichan %d --> %d",
251 'A' + hdlc
, bcs
->mode
, mode
, hdlc
, bc
);
252 bcs
->hw
.hdlc
.ctrl
.ctrl
= 0;
254 case (-1): /* used for init */
259 if (bcs
->mode
== L1_MODE_NULL
)
261 bcs
->hw
.hdlc
.ctrl
.sr
.cmd
= HDLC_CMD_XRS
| HDLC_CMD_RRS
;
262 bcs
->hw
.hdlc
.ctrl
.sr
.mode
= HDLC_MODE_TRANS
;
264 bcs
->mode
= L1_MODE_NULL
;
267 case (L1_MODE_TRANS
):
270 bcs
->hw
.hdlc
.ctrl
.sr
.cmd
= HDLC_CMD_XRS
| HDLC_CMD_RRS
;
271 bcs
->hw
.hdlc
.ctrl
.sr
.mode
= HDLC_MODE_TRANS
;
273 bcs
->hw
.hdlc
.ctrl
.sr
.cmd
= HDLC_CMD_XRS
;
275 bcs
->hw
.hdlc
.ctrl
.sr
.cmd
= 0;
276 sched_b_event(bcs
, B_XMTBUFREADY
);
281 bcs
->hw
.hdlc
.ctrl
.sr
.cmd
= HDLC_CMD_XRS
| HDLC_CMD_RRS
;
282 bcs
->hw
.hdlc
.ctrl
.sr
.mode
= HDLC_MODE_ITF_FLG
;
284 bcs
->hw
.hdlc
.ctrl
.sr
.cmd
= HDLC_CMD_XRS
;
286 bcs
->hw
.hdlc
.ctrl
.sr
.cmd
= 0;
287 sched_b_event(bcs
, B_XMTBUFREADY
);
293 hdlc_empty_fifo(struct BCState
*bcs
, int count
)
295 recv_empty_fifo_b(bcs
, count
);
299 hdlc_fill_fifo(struct BCState
*bcs
)
301 struct IsdnCardState
*cs
= bcs
->cs
;
302 int count
, more
, cnt
=0;
307 p
= xmit_fill_fifo_b(bcs
, fifo_size
, &count
, &more
);
312 bcs
->hw
.hdlc
.ctrl
.sr
.cmd
&= ~HDLC_CMD_XME
;
314 bcs
->hw
.hdlc
.ctrl
.sr
.cmd
|= HDLC_CMD_XME
;
316 bcs
->hw
.hdlc
.ctrl
.sr
.xml
= ((count
== fifo_size
) ? 0 : count
);
317 write_ctrl(bcs
, 3); /* sets the correct index too */
318 if (cs
->subtyp
== AVM_FRITZ_PCI
) {
319 ptr
= (unsigned int *) p
;
323 out_le32((unsigned *)(cs
->hw
.avm
.isac
+_IO_BASE
), *ptr
++);
325 out_be32((unsigned *)(cs
->hw
.avm
.isac
+_IO_BASE
), *ptr
++);
326 #endif /* CONFIG_APUS */
328 outl(*ptr
++, cs
->hw
.avm
.isac
);
329 #endif /* __powerpc__ */
334 outb(*p
++, cs
->hw
.avm
.isac
);
341 reset_xmit(struct BCState
*bcs
)
343 bcs
->hw
.hdlc
.ctrl
.sr
.xml
= 0;
344 bcs
->hw
.hdlc
.ctrl
.sr
.cmd
|= HDLC_CMD_XRS
;
346 bcs
->hw
.hdlc
.ctrl
.sr
.cmd
&= ~HDLC_CMD_XRS
;
352 HDLC_irq(struct BCState
*bcs
, u_int stat
)
356 if (bcs
->cs
->debug
& L1_DEB_HSCX
)
357 debugl1(bcs
->cs
, "ch%d stat %#x", bcs
->channel
, stat
);
359 if (stat
& HDLC_INT_RPR
) {
360 if (stat
& HDLC_STAT_RDO
) {
361 if (bcs
->cs
->debug
& L1_DEB_HSCX
)
362 debugl1(bcs
->cs
, "RDO");
364 debugl1(bcs
->cs
, "ch%d stat %#x", bcs
->channel
, stat
);
365 bcs
->hw
.hdlc
.ctrl
.sr
.xml
= 0;
366 bcs
->hw
.hdlc
.ctrl
.sr
.cmd
|= HDLC_CMD_RRS
;
368 bcs
->hw
.hdlc
.ctrl
.sr
.cmd
&= ~HDLC_CMD_RRS
;
372 if (!(len
= (stat
& HDLC_STAT_RML_MASK
)>>8))
374 hdlc_empty_fifo(bcs
, len
);
375 if ((stat
& HDLC_STAT_RME
) || (bcs
->mode
== L1_MODE_TRANS
)) {
376 if (((stat
& HDLC_STAT_CRCVFRRAB
)==HDLC_STAT_CRCVFR
) ||
377 (bcs
->mode
== L1_MODE_TRANS
)) {
380 if (bcs
->cs
->debug
& L1_DEB_HSCX
)
381 debugl1(bcs
->cs
, "invalid frame");
383 debugl1(bcs
->cs
, "ch%d invalid frame %#x", bcs
->channel
, stat
);
389 if (stat
& HDLC_INT_XDU
) {
390 xmit_xdu_b(bcs
, reset_xmit
);
391 } else if (stat
& HDLC_INT_XPR
) {
397 HDLC_irq_main(struct IsdnCardState
*cs
)
402 spin_lock(&cs
->lock
);
403 if (cs
->subtyp
== AVM_FRITZ_PCI
) {
404 stat
= ReadHDLCPCI(cs
, 0, HDLC_STATUS
);
406 stat
= ReadHDLCPnP(cs
, 0, HDLC_STATUS
);
407 if (stat
& HDLC_INT_RPR
)
408 stat
|= (ReadHDLCPnP(cs
, 0, HDLC_STATUS
+1))<<8;
410 if (stat
& HDLC_INT_MASK
) {
411 if (!(bcs
= Sel_BCS(cs
, 0))) {
413 debugl1(cs
, "hdlc spurious channel 0 IRQ");
417 if (cs
->subtyp
== AVM_FRITZ_PCI
) {
418 stat
= ReadHDLCPCI(cs
, 1, HDLC_STATUS
);
420 stat
= ReadHDLCPnP(cs
, 1, HDLC_STATUS
);
421 if (stat
& HDLC_INT_RPR
)
422 stat
|= (ReadHDLCPnP(cs
, 1, HDLC_STATUS
+1))<<8;
424 if (stat
& HDLC_INT_MASK
) {
425 if (!(bcs
= Sel_BCS(cs
, 1))) {
427 debugl1(cs
, "hdlc spurious channel 1 IRQ");
431 spin_unlock(&cs
->lock
);
435 hdlc_l2l1(struct PStack
*st
, int pr
, void *arg
)
437 struct sk_buff
*skb
= arg
;
440 case (PH_DATA
| REQUEST
):
441 xmit_data_req_b(st
->l1
.bcs
, skb
);
443 case (PH_PULL
| INDICATION
):
444 xmit_pull_ind_b(st
->l1
.bcs
, skb
);
446 case (PH_PULL
| REQUEST
):
449 case (PH_ACTIVATE
| REQUEST
):
450 test_and_set_bit(BC_FLG_ACTIV
, &st
->l1
.bcs
->Flag
);
451 modehdlc(st
->l1
.bcs
, st
->l1
.mode
, st
->l1
.bc
);
452 l1_msg_b(st
, pr
, arg
);
454 case (PH_DEACTIVATE
| REQUEST
):
455 l1_msg_b(st
, pr
, arg
);
457 case (PH_DEACTIVATE
| CONFIRM
):
458 test_and_clear_bit(BC_FLG_ACTIV
, &st
->l1
.bcs
->Flag
);
459 test_and_clear_bit(BC_FLG_BUSY
, &st
->l1
.bcs
->Flag
);
460 modehdlc(st
->l1
.bcs
, 0, st
->l1
.bc
);
461 L1L2(st
, PH_DEACTIVATE
| CONFIRM
, NULL
);
467 close_hdlcstate(struct BCState
*bcs
)
474 open_hdlcstate(struct IsdnCardState
*cs
, struct BCState
*bcs
)
480 setstack_hdlc(struct PStack
*st
, struct BCState
*bcs
)
482 bcs
->channel
= st
->l1
.bc
;
483 bcs
->unit
= bcs
->channel
;
484 if (open_hdlcstate(st
->l1
.hardware
, bcs
))
487 st
->l1
.l2l1
= hdlc_l2l1
;
488 setstack_manager(st
);
494 static struct bc_l1_ops hdlc_l1_ops
= {
495 .fill_fifo
= hdlc_fill_fifo
,
496 .open
= setstack_hdlc
,
497 .close
= close_hdlcstate
,
501 inithdlc(struct IsdnCardState
*cs
)
505 if (cs
->subtyp
== AVM_FRITZ_PCI
) {
506 val
= ReadHDLCPCI(cs
, 0, HDLC_STATUS
);
507 debugl1(cs
, "HDLC 1 STA %x", val
);
508 val
= ReadHDLCPCI(cs
, 1, HDLC_STATUS
);
509 debugl1(cs
, "HDLC 2 STA %x", val
);
511 val
= ReadHDLCPnP(cs
, 0, HDLC_STATUS
);
512 debugl1(cs
, "HDLC 1 STA %x", val
);
513 val
= ReadHDLCPnP(cs
, 0, HDLC_STATUS
+ 1);
514 debugl1(cs
, "HDLC 1 RML %x", val
);
515 val
= ReadHDLCPnP(cs
, 0, HDLC_STATUS
+ 2);
516 debugl1(cs
, "HDLC 1 MODE %x", val
);
517 val
= ReadHDLCPnP(cs
, 0, HDLC_STATUS
+ 3);
518 debugl1(cs
, "HDLC 1 VIN %x", val
);
519 val
= ReadHDLCPnP(cs
, 1, HDLC_STATUS
);
520 debugl1(cs
, "HDLC 2 STA %x", val
);
521 val
= ReadHDLCPnP(cs
, 1, HDLC_STATUS
+ 1);
522 debugl1(cs
, "HDLC 2 RML %x", val
);
523 val
= ReadHDLCPnP(cs
, 1, HDLC_STATUS
+ 2);
524 debugl1(cs
, "HDLC 2 MODE %x", val
);
525 val
= ReadHDLCPnP(cs
, 1, HDLC_STATUS
+ 3);
526 debugl1(cs
, "HDLC 2 VIN %x", val
);
529 modehdlc(cs
->bcs
, -1, 0);
530 modehdlc(cs
->bcs
+ 1, -1, 1);
534 avm_pcipnp_interrupt(int intno
, void *dev_id
, struct pt_regs
*regs
)
536 struct IsdnCardState
*cs
= dev_id
;
541 printk(KERN_WARNING
"AVM PCI: Spurious interrupt!\n");
544 sval
= inb(cs
->hw
.avm
.cfg_reg
+ 2);
545 if ((sval
& AVM_STATUS0_IRQ_MASK
) == AVM_STATUS0_IRQ_MASK
)
546 /* possible a shared IRQ reqest */
548 if (!(sval
& AVM_STATUS0_IRQ_ISAC
)) {
549 val
= ReadISAC(cs
, ISAC_ISTA
);
550 isac_interrupt(cs
, val
);
552 if (!(sval
& AVM_STATUS0_IRQ_HDLC
)) {
555 WriteISAC(cs
, ISAC_MASK
, 0xFF);
556 WriteISAC(cs
, ISAC_MASK
, 0x0);
560 avm_pcipnp_reset(struct IsdnCardState
*cs
)
562 printk(KERN_INFO
"AVM PCI/PnP: reset\n");
563 outb(AVM_STATUS0_RESET
| AVM_STATUS0_DIS_TIMER
, cs
->hw
.avm
.cfg_reg
+ 2);
564 set_current_state(TASK_UNINTERRUPTIBLE
);
565 schedule_timeout((10*HZ
)/1000); /* Timeout 10ms */
566 outb(AVM_STATUS0_DIS_TIMER
| AVM_STATUS0_RES_TIMER
| AVM_STATUS0_ENA_IRQ
, cs
->hw
.avm
.cfg_reg
+ 2);
567 outb(AVM_STATUS1_ENA_IOM
| cs
->irq
, cs
->hw
.avm
.cfg_reg
+ 3);
568 set_current_state(TASK_UNINTERRUPTIBLE
);
569 schedule_timeout((10*HZ
)/1000); /* Timeout 10ms */
570 printk(KERN_INFO
"AVM PCI/PnP: S1 %x\n", inb(cs
->hw
.avm
.cfg_reg
+ 3));
575 avm_pcipnp_init(struct IsdnCardState
*cs
)
579 outb(AVM_STATUS0_DIS_TIMER
| AVM_STATUS0_RES_TIMER
,
580 cs
->hw
.avm
.cfg_reg
+ 2);
581 outb(AVM_STATUS0_DIS_TIMER
| AVM_STATUS0_RES_TIMER
|
582 AVM_STATUS0_ENA_IRQ
, cs
->hw
.avm
.cfg_reg
+ 2);
586 avm_pcipnp_release(struct IsdnCardState
*cs
)
588 outb(0, cs
->hw
.avm
.cfg_reg
+ 2);
589 hisax_release_resources(cs
);
592 static struct card_ops avm_pci_ops
= {
593 .init
= avm_pcipnp_init
,
594 .reset
= avm_pcipnp_reset
,
595 .release
= avm_pcipnp_release
,
596 .irq_func
= avm_pcipnp_interrupt
,
600 avm_pcipnp_hw_init(struct IsdnCardState
*cs
)
602 cs
->bc_hw_ops
= &hdlc_hw_ops
;
603 cs
->bc_l1_ops
= &hdlc_l1_ops
;
604 cs
->card_ops
= &avm_pci_ops
;
605 avm_pcipnp_reset(cs
);
606 return isac_setup(cs
, &isac_ops
);
610 avm_pci_probe(struct IsdnCardState
*cs
, struct pci_dev
*pdev
)
615 printk(KERN_INFO
"AVM PCI: defined at %#lx IRQ %u\n",
616 pci_resource_start(pdev
, 1), pdev
->irq
);
619 if (pci_enable_device(pdev
))
622 cs
->subtyp
= AVM_FRITZ_PCI
;
624 cs
->irq_flags
|= SA_SHIRQ
;
625 cs
->hw
.avm
.cfg_reg
= pci_resource_start(pdev
, 1);
626 cs
->hw
.avm
.isac
= cs
->hw
.avm
.cfg_reg
+ 0x10;
627 if (!request_io(&cs
->rs
, cs
->hw
.avm
.cfg_reg
, 32, "avm PCI"))
630 val
= inl(cs
->hw
.avm
.cfg_reg
);
631 printk(KERN_INFO
"AVM PCI: stat %#x\n", val
);
632 printk(KERN_INFO
"AVM PCI: Class %X Rev %d\n",
633 val
& 0xff, (val
>>8) & 0xff);
635 if (avm_pcipnp_hw_init(cs
))
640 hisax_release_resources(cs
);
645 avm_pnp_probe(struct IsdnCardState
*cs
, struct IsdnCard
*card
)
650 printk(KERN_INFO
"AVM PnP: defined at %#lx IRQ %lu\n",
651 card
->para
[1], card
->para
[0]);
653 cs
->subtyp
= AVM_FRITZ_PNP
;
654 cs
->irq
= card
->para
[0];
655 cs
->hw
.avm
.cfg_reg
= card
->para
[1];
656 cs
->hw
.avm
.isac
= cs
->hw
.avm
.cfg_reg
+ 0x10;
659 if (!request_io(&cs
->rs
, cs
->hw
.avm
.cfg_reg
, 32, "avm PnP"))
662 val
= inb(cs
->hw
.avm
.cfg_reg
);
663 ver
= inb(cs
->hw
.avm
.cfg_reg
+ 1);
664 printk(KERN_INFO
"AVM PnP: Class %X Rev %d\n", val
, ver
);
666 if (avm_pcipnp_hw_init(cs
))
671 hisax_release_resources(cs
);
675 static struct pci_dev
*dev_avm __initdata
= NULL
;
677 static struct pnp_card
*card_avm __initdata
= NULL
;
678 static struct pnp_dev
*pnp_avm __initdata
= NULL
;
682 setup_avm_pcipnp(struct IsdnCard
*card
)
686 strcpy(tmp
, avm_pci_rev
);
687 printk(KERN_INFO
"HiSax: AVM PCI driver Rev. %s\n", HiSax_getrev(tmp
));
689 /* old manual method */
690 if (avm_pnp_probe(card
->cs
, card
))
695 if (isapnp_present()) {
697 if ((ba
= pnp_find_card(
698 ISAPNP_VENDOR('A', 'V', 'M'),
699 ISAPNP_FUNCTION(0x0900), card_avm
))) {
702 if ((pnp_avm
= pnp_find_dev(card_avm
,
703 ISAPNP_VENDOR('A', 'V', 'M'),
704 ISAPNP_FUNCTION(0x0900), pnp_avm
))) {
705 if (pnp_device_attach(pnp_avm
) < 0) {
706 printk(KERN_ERR
"FritzPnP: attach failed\n");
709 if (pnp_activate_dev(pnp_avm
) < 0) {
710 printk(KERN_ERR
"FritzPnP: activate failed\n");
711 pnp_device_detach(pnp_avm
);
714 if (!pnp_irq_valid(pnp_avm
, 0)) {
715 printk(KERN_ERR
"FritzPnP:No IRQ\n");
716 pnp_device_detach(pnp_avm
);
719 if (!pnp_port_valid(pnp_avm
, 0)) {
720 printk(KERN_ERR
"FritzPnP:No IO address\n");
721 pnp_device_detach(pnp_avm
);
724 card
->para
[1] = pnp_port_start(pnp_avm
, 0);
725 card
->para
[0] = pnp_irq(pnp_avm
, 0);
726 if (avm_pnp_probe(card
->cs
, card
))
734 if ((dev_avm
= pci_find_device(PCI_VENDOR_ID_AVM
,
735 PCI_DEVICE_ID_AVM_A1
, dev_avm
))) {
736 if (avm_pci_probe(card
->cs
, dev_avm
))
740 #endif /* CONFIG_PCI */
742 printk(KERN_WARNING
"FritzPCI: No card found\n");