1 /* $Id: avm_pci.c,v 1.29.2.4 2004/02/11 13:21:32 keil 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/init.h>
19 #include <linux/pci.h>
20 #include <linux/slab.h>
21 #include <linux/isapnp.h>
22 #include <linux/interrupt.h>
24 static const char *avm_pci_rev
= "$Revision: 1.29.2.4 $";
26 #define AVM_FRITZ_PCI 1
27 #define AVM_FRITZ_PNP 2
30 #define HDLC_STATUS 0x4
32 #define AVM_HDLC_1 0x00
33 #define AVM_HDLC_2 0x01
34 #define AVM_ISAC_FIFO 0x02
35 #define AVM_ISAC_REG_LOW 0x04
36 #define AVM_ISAC_REG_HIGH 0x06
38 #define AVM_STATUS0_IRQ_ISAC 0x01
39 #define AVM_STATUS0_IRQ_HDLC 0x02
40 #define AVM_STATUS0_IRQ_TIMER 0x04
41 #define AVM_STATUS0_IRQ_MASK 0x07
43 #define AVM_STATUS0_RESET 0x01
44 #define AVM_STATUS0_DIS_TIMER 0x02
45 #define AVM_STATUS0_RES_TIMER 0x04
46 #define AVM_STATUS0_ENA_IRQ 0x08
47 #define AVM_STATUS0_TESTBIT 0x10
49 #define AVM_STATUS1_INT_SEL 0x0f
50 #define AVM_STATUS1_ENA_IOM 0x80
52 #define HDLC_MODE_ITF_FLG 0x01
53 #define HDLC_MODE_TRANS 0x02
54 #define HDLC_MODE_CCR_7 0x04
55 #define HDLC_MODE_CCR_16 0x08
56 #define HDLC_MODE_TESTLOOP 0x80
58 #define HDLC_INT_XPR 0x80
59 #define HDLC_INT_XDU 0x40
60 #define HDLC_INT_RPR 0x20
61 #define HDLC_INT_MASK 0xE0
63 #define HDLC_STAT_RME 0x01
64 #define HDLC_STAT_RDO 0x10
65 #define HDLC_STAT_CRCVFRRAB 0x0E
66 #define HDLC_STAT_CRCVFR 0x06
67 #define HDLC_STAT_RML_MASK 0x3f00
69 #define HDLC_CMD_XRS 0x80
70 #define HDLC_CMD_XME 0x01
71 #define HDLC_CMD_RRS 0x20
72 #define HDLC_CMD_XML_MASK 0x3f00
75 /* Interface functions */
78 ReadISAC(struct IsdnCardState
*cs
, u_char offset
)
80 register u_char idx
= (offset
> 0x2f) ? AVM_ISAC_REG_HIGH
: AVM_ISAC_REG_LOW
;
83 outb(idx
, cs
->hw
.avm
.cfg_reg
+ 4);
84 val
= inb(cs
->hw
.avm
.isac
+ (offset
& 0xf));
89 WriteISAC(struct IsdnCardState
*cs
, u_char offset
, u_char value
)
91 register u_char idx
= (offset
> 0x2f) ? AVM_ISAC_REG_HIGH
: AVM_ISAC_REG_LOW
;
93 outb(idx
, cs
->hw
.avm
.cfg_reg
+ 4);
94 outb(value
, cs
->hw
.avm
.isac
+ (offset
& 0xf));
98 ReadISACfifo(struct IsdnCardState
*cs
, u_char
*data
, int size
)
100 outb(AVM_ISAC_FIFO
, cs
->hw
.avm
.cfg_reg
+ 4);
101 insb(cs
->hw
.avm
.isac
, data
, size
);
105 WriteISACfifo(struct IsdnCardState
*cs
, u_char
*data
, int size
)
107 outb(AVM_ISAC_FIFO
, cs
->hw
.avm
.cfg_reg
+ 4);
108 outsb(cs
->hw
.avm
.isac
, data
, size
);
112 ReadHDLCPCI(struct IsdnCardState
*cs
, int chan
, u_char offset
)
114 register u_int idx
= chan
? AVM_HDLC_2
: AVM_HDLC_1
;
117 outl(idx
, cs
->hw
.avm
.cfg_reg
+ 4);
118 val
= inl(cs
->hw
.avm
.isac
+ offset
);
123 WriteHDLCPCI(struct IsdnCardState
*cs
, int chan
, u_char offset
, u_int value
)
125 register u_int idx
= chan
? AVM_HDLC_2
: AVM_HDLC_1
;
127 outl(idx
, cs
->hw
.avm
.cfg_reg
+ 4);
128 outl(value
, cs
->hw
.avm
.isac
+ offset
);
132 ReadHDLCPnP(struct IsdnCardState
*cs
, int chan
, u_char offset
)
134 register u_char idx
= chan
? AVM_HDLC_2
: AVM_HDLC_1
;
137 outb(idx
, cs
->hw
.avm
.cfg_reg
+ 4);
138 val
= inb(cs
->hw
.avm
.isac
+ offset
);
143 WriteHDLCPnP(struct IsdnCardState
*cs
, int chan
, u_char offset
, u_char value
)
145 register u_char idx
= chan
? AVM_HDLC_2
: AVM_HDLC_1
;
147 outb(idx
, cs
->hw
.avm
.cfg_reg
+ 4);
148 outb(value
, cs
->hw
.avm
.isac
+ offset
);
152 ReadHDLC_s(struct IsdnCardState
*cs
, int chan
, u_char offset
)
154 return (0xff & ReadHDLCPCI(cs
, chan
, offset
));
158 WriteHDLC_s(struct IsdnCardState
*cs
, int chan
, u_char offset
, u_char value
)
160 WriteHDLCPCI(cs
, chan
, offset
, value
);
164 struct BCState
*Sel_BCS(struct IsdnCardState
*cs
, int channel
)
166 if (cs
->bcs
[0].mode
&& (cs
->bcs
[0].channel
== channel
))
167 return (&cs
->bcs
[0]);
168 else if (cs
->bcs
[1].mode
&& (cs
->bcs
[1].channel
== channel
))
169 return (&cs
->bcs
[1]);
175 write_ctrl(struct BCState
*bcs
, int which
) {
177 if (bcs
->cs
->debug
& L1_DEB_HSCX
)
178 debugl1(bcs
->cs
, "hdlc %c wr%x ctrl %x",
179 'A' + bcs
->channel
, which
, bcs
->hw
.hdlc
.ctrl
.ctrl
);
180 if (bcs
->cs
->subtyp
== AVM_FRITZ_PCI
) {
181 WriteHDLCPCI(bcs
->cs
, bcs
->channel
, HDLC_STATUS
, bcs
->hw
.hdlc
.ctrl
.ctrl
);
184 WriteHDLCPnP(bcs
->cs
, bcs
->channel
, HDLC_STATUS
+ 2,
185 bcs
->hw
.hdlc
.ctrl
.sr
.mode
);
187 WriteHDLCPnP(bcs
->cs
, bcs
->channel
, HDLC_STATUS
+ 1,
188 bcs
->hw
.hdlc
.ctrl
.sr
.xml
);
190 WriteHDLCPnP(bcs
->cs
, bcs
->channel
, HDLC_STATUS
,
191 bcs
->hw
.hdlc
.ctrl
.sr
.cmd
);
196 modehdlc(struct BCState
*bcs
, int mode
, int bc
)
198 struct IsdnCardState
*cs
= bcs
->cs
;
199 int hdlc
= bcs
->channel
;
201 if (cs
->debug
& L1_DEB_HSCX
)
202 debugl1(cs
, "hdlc %c mode %d --> %d ichan %d --> %d",
203 'A' + hdlc
, bcs
->mode
, mode
, hdlc
, bc
);
204 bcs
->hw
.hdlc
.ctrl
.ctrl
= 0;
206 case (-1): /* used for init */
211 if (bcs
->mode
== L1_MODE_NULL
)
213 bcs
->hw
.hdlc
.ctrl
.sr
.cmd
= HDLC_CMD_XRS
| HDLC_CMD_RRS
;
214 bcs
->hw
.hdlc
.ctrl
.sr
.mode
= HDLC_MODE_TRANS
;
216 bcs
->mode
= L1_MODE_NULL
;
219 case (L1_MODE_TRANS
):
222 bcs
->hw
.hdlc
.ctrl
.sr
.cmd
= HDLC_CMD_XRS
| HDLC_CMD_RRS
;
223 bcs
->hw
.hdlc
.ctrl
.sr
.mode
= HDLC_MODE_TRANS
;
225 bcs
->hw
.hdlc
.ctrl
.sr
.cmd
= HDLC_CMD_XRS
;
227 bcs
->hw
.hdlc
.ctrl
.sr
.cmd
= 0;
228 schedule_event(bcs
, B_XMTBUFREADY
);
233 bcs
->hw
.hdlc
.ctrl
.sr
.cmd
= HDLC_CMD_XRS
| HDLC_CMD_RRS
;
234 bcs
->hw
.hdlc
.ctrl
.sr
.mode
= HDLC_MODE_ITF_FLG
;
236 bcs
->hw
.hdlc
.ctrl
.sr
.cmd
= HDLC_CMD_XRS
;
238 bcs
->hw
.hdlc
.ctrl
.sr
.cmd
= 0;
239 schedule_event(bcs
, B_XMTBUFREADY
);
245 hdlc_empty_fifo(struct BCState
*bcs
, int count
)
249 u_char idx
= bcs
->channel
? AVM_HDLC_2
: AVM_HDLC_1
;
251 struct IsdnCardState
*cs
= bcs
->cs
;
253 if ((cs
->debug
& L1_DEB_HSCX
) && !(cs
->debug
& L1_DEB_HSCX_FIFO
))
254 debugl1(cs
, "hdlc_empty_fifo %d", count
);
255 if (bcs
->hw
.hdlc
.rcvidx
+ count
> HSCX_BUFMAX
) {
256 if (cs
->debug
& L1_DEB_WARN
)
257 debugl1(cs
, "hdlc_empty_fifo: incoming packet too large");
260 p
= bcs
->hw
.hdlc
.rcvbuf
+ bcs
->hw
.hdlc
.rcvidx
;
262 bcs
->hw
.hdlc
.rcvidx
+= count
;
263 if (cs
->subtyp
== AVM_FRITZ_PCI
) {
264 outl(idx
, cs
->hw
.avm
.cfg_reg
+ 4);
265 while (cnt
< count
) {
267 *ptr
++ = in_be32((unsigned *)(cs
->hw
.avm
.isac
+ _IO_BASE
));
269 *ptr
++ = inl(cs
->hw
.avm
.isac
);
270 #endif /* __powerpc__ */
274 outb(idx
, cs
->hw
.avm
.cfg_reg
+ 4);
275 while (cnt
< count
) {
276 *p
++ = inb(cs
->hw
.avm
.isac
);
280 if (cs
->debug
& L1_DEB_HSCX_FIFO
) {
283 if (cs
->subtyp
== AVM_FRITZ_PNP
)
285 t
+= sprintf(t
, "hdlc_empty_fifo %c cnt %d",
286 bcs
->channel
? 'B' : 'A', count
);
287 QuickHex(t
, p
, count
);
288 debugl1(cs
, "%s", bcs
->blog
);
293 hdlc_fill_fifo(struct BCState
*bcs
)
295 struct IsdnCardState
*cs
= bcs
->cs
;
301 if ((cs
->debug
& L1_DEB_HSCX
) && !(cs
->debug
& L1_DEB_HSCX_FIFO
))
302 debugl1(cs
, "hdlc_fill_fifo");
305 if (bcs
->tx_skb
->len
<= 0)
308 bcs
->hw
.hdlc
.ctrl
.sr
.cmd
&= ~HDLC_CMD_XME
;
309 if (bcs
->tx_skb
->len
> fifo_size
) {
312 count
= bcs
->tx_skb
->len
;
313 if (bcs
->mode
!= L1_MODE_TRANS
)
314 bcs
->hw
.hdlc
.ctrl
.sr
.cmd
|= HDLC_CMD_XME
;
316 if ((cs
->debug
& L1_DEB_HSCX
) && !(cs
->debug
& L1_DEB_HSCX_FIFO
))
317 debugl1(cs
, "hdlc_fill_fifo %d/%u", count
, bcs
->tx_skb
->len
);
318 p
= bcs
->tx_skb
->data
;
320 skb_pull(bcs
->tx_skb
, count
);
321 bcs
->tx_cnt
-= count
;
322 bcs
->hw
.hdlc
.count
+= count
;
323 bcs
->hw
.hdlc
.ctrl
.sr
.xml
= ((count
== fifo_size
) ? 0 : count
);
324 write_ctrl(bcs
, 3); /* sets the correct index too */
325 if (cs
->subtyp
== AVM_FRITZ_PCI
) {
326 while (cnt
< count
) {
328 out_be32((unsigned *)(cs
->hw
.avm
.isac
+ _IO_BASE
), *ptr
++);
330 outl(*ptr
++, cs
->hw
.avm
.isac
);
331 #endif /* __powerpc__ */
335 while (cnt
< count
) {
336 outb(*p
++, cs
->hw
.avm
.isac
);
340 if (cs
->debug
& L1_DEB_HSCX_FIFO
) {
343 if (cs
->subtyp
== AVM_FRITZ_PNP
)
345 t
+= sprintf(t
, "hdlc_fill_fifo %c cnt %d",
346 bcs
->channel
? 'B' : 'A', count
);
347 QuickHex(t
, p
, count
);
348 debugl1(cs
, "%s", bcs
->blog
);
353 HDLC_irq(struct BCState
*bcs
, u_int stat
) {
357 if (bcs
->cs
->debug
& L1_DEB_HSCX
)
358 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
;
370 bcs
->hw
.hdlc
.rcvidx
= 0;
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
)) {
378 if (!(skb
= dev_alloc_skb(bcs
->hw
.hdlc
.rcvidx
)))
379 printk(KERN_WARNING
"HDLC: receive out of memory\n");
383 bcs
->hw
.hdlc
.rcvidx
);
384 skb_queue_tail(&bcs
->rqueue
, skb
);
386 bcs
->hw
.hdlc
.rcvidx
= 0;
387 schedule_event(bcs
, B_RCVBUFREADY
);
389 if (bcs
->cs
->debug
& L1_DEB_HSCX
)
390 debugl1(bcs
->cs
, "invalid frame");
392 debugl1(bcs
->cs
, "ch%d invalid frame %#x", bcs
->channel
, stat
);
393 bcs
->hw
.hdlc
.rcvidx
= 0;
398 if (stat
& HDLC_INT_XDU
) {
399 /* Here we lost an TX interrupt, so
400 * restart transmitting the whole frame.
403 skb_push(bcs
->tx_skb
, bcs
->hw
.hdlc
.count
);
404 bcs
->tx_cnt
+= bcs
->hw
.hdlc
.count
;
405 bcs
->hw
.hdlc
.count
= 0;
406 if (bcs
->cs
->debug
& L1_DEB_WARN
)
407 debugl1(bcs
->cs
, "ch%d XDU", bcs
->channel
);
408 } else if (bcs
->cs
->debug
& L1_DEB_WARN
)
409 debugl1(bcs
->cs
, "ch%d XDU without skb", bcs
->channel
);
410 bcs
->hw
.hdlc
.ctrl
.sr
.xml
= 0;
411 bcs
->hw
.hdlc
.ctrl
.sr
.cmd
|= HDLC_CMD_XRS
;
413 bcs
->hw
.hdlc
.ctrl
.sr
.cmd
&= ~HDLC_CMD_XRS
;
416 } else if (stat
& HDLC_INT_XPR
) {
418 if (bcs
->tx_skb
->len
) {
422 if (test_bit(FLG_LLI_L1WAKEUP
, &bcs
->st
->lli
.flag
) &&
423 (PACKET_NOACK
!= bcs
->tx_skb
->pkt_type
)) {
425 spin_lock_irqsave(&bcs
->aclock
, flags
);
426 bcs
->ackcnt
+= bcs
->hw
.hdlc
.count
;
427 spin_unlock_irqrestore(&bcs
->aclock
, flags
);
428 schedule_event(bcs
, B_ACKPENDING
);
430 dev_kfree_skb_irq(bcs
->tx_skb
);
431 bcs
->hw
.hdlc
.count
= 0;
435 if ((bcs
->tx_skb
= skb_dequeue(&bcs
->squeue
))) {
436 bcs
->hw
.hdlc
.count
= 0;
437 test_and_set_bit(BC_FLG_BUSY
, &bcs
->Flag
);
440 test_and_clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
441 schedule_event(bcs
, B_XMTBUFREADY
);
447 HDLC_irq_main(struct IsdnCardState
*cs
)
452 if (cs
->subtyp
== AVM_FRITZ_PCI
) {
453 stat
= ReadHDLCPCI(cs
, 0, HDLC_STATUS
);
455 stat
= ReadHDLCPnP(cs
, 0, HDLC_STATUS
);
456 if (stat
& HDLC_INT_RPR
)
457 stat
|= (ReadHDLCPnP(cs
, 0, HDLC_STATUS
+ 1)) << 8;
459 if (stat
& HDLC_INT_MASK
) {
460 if (!(bcs
= Sel_BCS(cs
, 0))) {
462 debugl1(cs
, "hdlc spurious channel 0 IRQ");
466 if (cs
->subtyp
== AVM_FRITZ_PCI
) {
467 stat
= ReadHDLCPCI(cs
, 1, HDLC_STATUS
);
469 stat
= ReadHDLCPnP(cs
, 1, HDLC_STATUS
);
470 if (stat
& HDLC_INT_RPR
)
471 stat
|= (ReadHDLCPnP(cs
, 1, HDLC_STATUS
+ 1)) << 8;
473 if (stat
& HDLC_INT_MASK
) {
474 if (!(bcs
= Sel_BCS(cs
, 1))) {
476 debugl1(cs
, "hdlc spurious channel 1 IRQ");
483 hdlc_l2l1(struct PStack
*st
, int pr
, void *arg
)
485 struct BCState
*bcs
= st
->l1
.bcs
;
486 struct sk_buff
*skb
= arg
;
490 case (PH_DATA
| REQUEST
):
491 spin_lock_irqsave(&bcs
->cs
->lock
, flags
);
493 skb_queue_tail(&bcs
->squeue
, skb
);
496 test_and_set_bit(BC_FLG_BUSY
, &bcs
->Flag
);
497 bcs
->hw
.hdlc
.count
= 0;
498 bcs
->cs
->BC_Send_Data(bcs
);
500 spin_unlock_irqrestore(&bcs
->cs
->lock
, flags
);
502 case (PH_PULL
| INDICATION
):
503 spin_lock_irqsave(&bcs
->cs
->lock
, flags
);
505 printk(KERN_WARNING
"hdlc_l2l1: this shouldn't happen\n");
507 test_and_set_bit(BC_FLG_BUSY
, &bcs
->Flag
);
509 bcs
->hw
.hdlc
.count
= 0;
510 bcs
->cs
->BC_Send_Data(bcs
);
512 spin_unlock_irqrestore(&bcs
->cs
->lock
, flags
);
514 case (PH_PULL
| REQUEST
):
516 test_and_clear_bit(FLG_L1_PULL_REQ
, &st
->l1
.Flags
);
517 st
->l1
.l1l2(st
, PH_PULL
| CONFIRM
, NULL
);
519 test_and_set_bit(FLG_L1_PULL_REQ
, &st
->l1
.Flags
);
521 case (PH_ACTIVATE
| REQUEST
):
522 spin_lock_irqsave(&bcs
->cs
->lock
, flags
);
523 test_and_set_bit(BC_FLG_ACTIV
, &bcs
->Flag
);
524 modehdlc(bcs
, st
->l1
.mode
, st
->l1
.bc
);
525 spin_unlock_irqrestore(&bcs
->cs
->lock
, flags
);
526 l1_msg_b(st
, pr
, arg
);
528 case (PH_DEACTIVATE
| REQUEST
):
529 l1_msg_b(st
, pr
, arg
);
531 case (PH_DEACTIVATE
| CONFIRM
):
532 spin_lock_irqsave(&bcs
->cs
->lock
, flags
);
533 test_and_clear_bit(BC_FLG_ACTIV
, &bcs
->Flag
);
534 test_and_clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
535 modehdlc(bcs
, 0, st
->l1
.bc
);
536 spin_unlock_irqrestore(&bcs
->cs
->lock
, flags
);
537 st
->l1
.l1l2(st
, PH_DEACTIVATE
| CONFIRM
, NULL
);
543 close_hdlcstate(struct BCState
*bcs
)
546 if (test_and_clear_bit(BC_FLG_INIT
, &bcs
->Flag
)) {
547 kfree(bcs
->hw
.hdlc
.rcvbuf
);
548 bcs
->hw
.hdlc
.rcvbuf
= NULL
;
551 skb_queue_purge(&bcs
->rqueue
);
552 skb_queue_purge(&bcs
->squeue
);
554 dev_kfree_skb_any(bcs
->tx_skb
);
556 test_and_clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
562 open_hdlcstate(struct IsdnCardState
*cs
, struct BCState
*bcs
)
564 if (!test_and_set_bit(BC_FLG_INIT
, &bcs
->Flag
)) {
565 if (!(bcs
->hw
.hdlc
.rcvbuf
= kmalloc(HSCX_BUFMAX
, GFP_ATOMIC
))) {
567 "HiSax: No memory for hdlc.rcvbuf\n");
570 if (!(bcs
->blog
= kmalloc(MAX_BLOG_SPACE
, GFP_ATOMIC
))) {
572 "HiSax: No memory for bcs->blog\n");
573 test_and_clear_bit(BC_FLG_INIT
, &bcs
->Flag
);
574 kfree(bcs
->hw
.hdlc
.rcvbuf
);
575 bcs
->hw
.hdlc
.rcvbuf
= NULL
;
578 skb_queue_head_init(&bcs
->rqueue
);
579 skb_queue_head_init(&bcs
->squeue
);
582 test_and_clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
584 bcs
->hw
.hdlc
.rcvidx
= 0;
590 setstack_hdlc(struct PStack
*st
, struct BCState
*bcs
)
592 bcs
->channel
= st
->l1
.bc
;
593 if (open_hdlcstate(st
->l1
.hardware
, bcs
))
596 st
->l2
.l2l1
= hdlc_l2l1
;
597 setstack_manager(st
);
605 clear_pending_hdlc_ints(struct IsdnCardState
*cs
)
609 if (cs
->subtyp
== AVM_FRITZ_PCI
) {
610 val
= ReadHDLCPCI(cs
, 0, HDLC_STATUS
);
611 debugl1(cs
, "HDLC 1 STA %x", val
);
612 val
= ReadHDLCPCI(cs
, 1, HDLC_STATUS
);
613 debugl1(cs
, "HDLC 2 STA %x", val
);
615 val
= ReadHDLCPnP(cs
, 0, HDLC_STATUS
);
616 debugl1(cs
, "HDLC 1 STA %x", val
);
617 val
= ReadHDLCPnP(cs
, 0, HDLC_STATUS
+ 1);
618 debugl1(cs
, "HDLC 1 RML %x", val
);
619 val
= ReadHDLCPnP(cs
, 0, HDLC_STATUS
+ 2);
620 debugl1(cs
, "HDLC 1 MODE %x", val
);
621 val
= ReadHDLCPnP(cs
, 0, HDLC_STATUS
+ 3);
622 debugl1(cs
, "HDLC 1 VIN %x", val
);
623 val
= ReadHDLCPnP(cs
, 1, HDLC_STATUS
);
624 debugl1(cs
, "HDLC 2 STA %x", val
);
625 val
= ReadHDLCPnP(cs
, 1, HDLC_STATUS
+ 1);
626 debugl1(cs
, "HDLC 2 RML %x", val
);
627 val
= ReadHDLCPnP(cs
, 1, HDLC_STATUS
+ 2);
628 debugl1(cs
, "HDLC 2 MODE %x", val
);
629 val
= ReadHDLCPnP(cs
, 1, HDLC_STATUS
+ 3);
630 debugl1(cs
, "HDLC 2 VIN %x", val
);
636 inithdlc(struct IsdnCardState
*cs
)
638 cs
->bcs
[0].BC_SetStack
= setstack_hdlc
;
639 cs
->bcs
[1].BC_SetStack
= setstack_hdlc
;
640 cs
->bcs
[0].BC_Close
= close_hdlcstate
;
641 cs
->bcs
[1].BC_Close
= close_hdlcstate
;
642 modehdlc(cs
->bcs
, -1, 0);
643 modehdlc(cs
->bcs
+ 1, -1, 1);
647 avm_pcipnp_interrupt(int intno
, void *dev_id
)
649 struct IsdnCardState
*cs
= dev_id
;
654 spin_lock_irqsave(&cs
->lock
, flags
);
655 sval
= inb(cs
->hw
.avm
.cfg_reg
+ 2);
656 if ((sval
& AVM_STATUS0_IRQ_MASK
) == AVM_STATUS0_IRQ_MASK
) {
657 /* possible a shared IRQ reqest */
658 spin_unlock_irqrestore(&cs
->lock
, flags
);
661 if (!(sval
& AVM_STATUS0_IRQ_ISAC
)) {
662 val
= ReadISAC(cs
, ISAC_ISTA
);
663 isac_interrupt(cs
, val
);
665 if (!(sval
& AVM_STATUS0_IRQ_HDLC
)) {
668 WriteISAC(cs
, ISAC_MASK
, 0xFF);
669 WriteISAC(cs
, ISAC_MASK
, 0x0);
670 spin_unlock_irqrestore(&cs
->lock
, flags
);
675 reset_avmpcipnp(struct IsdnCardState
*cs
)
677 printk(KERN_INFO
"AVM PCI/PnP: reset\n");
678 outb(AVM_STATUS0_RESET
| AVM_STATUS0_DIS_TIMER
, cs
->hw
.avm
.cfg_reg
+ 2);
680 outb(AVM_STATUS0_DIS_TIMER
| AVM_STATUS0_RES_TIMER
| AVM_STATUS0_ENA_IRQ
, cs
->hw
.avm
.cfg_reg
+ 2);
681 outb(AVM_STATUS1_ENA_IOM
| cs
->irq
, cs
->hw
.avm
.cfg_reg
+ 3);
683 printk(KERN_INFO
"AVM PCI/PnP: S1 %x\n", inb(cs
->hw
.avm
.cfg_reg
+ 3));
687 AVM_card_msg(struct IsdnCardState
*cs
, int mt
, void *arg
)
693 spin_lock_irqsave(&cs
->lock
, flags
);
695 spin_unlock_irqrestore(&cs
->lock
, flags
);
698 outb(0, cs
->hw
.avm
.cfg_reg
+ 2);
699 release_region(cs
->hw
.avm
.cfg_reg
, 32);
702 spin_lock_irqsave(&cs
->lock
, flags
);
704 clear_pending_isac_ints(cs
);
707 outb(AVM_STATUS0_DIS_TIMER
| AVM_STATUS0_RES_TIMER
,
708 cs
->hw
.avm
.cfg_reg
+ 2);
709 WriteISAC(cs
, ISAC_MASK
, 0);
710 outb(AVM_STATUS0_DIS_TIMER
| AVM_STATUS0_RES_TIMER
|
711 AVM_STATUS0_ENA_IRQ
, cs
->hw
.avm
.cfg_reg
+ 2);
712 /* RESET Receiver and Transmitter */
713 WriteISAC(cs
, ISAC_CMDR
, 0x41);
714 spin_unlock_irqrestore(&cs
->lock
, flags
);
722 static int avm_setup_rest(struct IsdnCardState
*cs
)
726 cs
->hw
.avm
.isac
= cs
->hw
.avm
.cfg_reg
+ 0x10;
727 if (!request_region(cs
->hw
.avm
.cfg_reg
, 32,
728 (cs
->subtyp
== AVM_FRITZ_PCI
) ? "avm PCI" : "avm PnP")) {
730 "HiSax: Fritz!PCI/PNP config port %x-%x already in use\n",
732 cs
->hw
.avm
.cfg_reg
+ 31);
735 switch (cs
->subtyp
) {
737 val
= inl(cs
->hw
.avm
.cfg_reg
);
738 printk(KERN_INFO
"AVM PCI: stat %#x\n", val
);
739 printk(KERN_INFO
"AVM PCI: Class %X Rev %d\n",
740 val
& 0xff, (val
>> 8) & 0xff);
741 cs
->BC_Read_Reg
= &ReadHDLC_s
;
742 cs
->BC_Write_Reg
= &WriteHDLC_s
;
745 val
= inb(cs
->hw
.avm
.cfg_reg
);
746 ver
= inb(cs
->hw
.avm
.cfg_reg
+ 1);
747 printk(KERN_INFO
"AVM PnP: Class %X Rev %d\n", val
, ver
);
748 cs
->BC_Read_Reg
= &ReadHDLCPnP
;
749 cs
->BC_Write_Reg
= &WriteHDLCPnP
;
752 printk(KERN_WARNING
"AVM unknown subtype %d\n", cs
->subtyp
);
755 printk(KERN_INFO
"HiSax: %s config irq:%d base:0x%X\n",
756 (cs
->subtyp
== AVM_FRITZ_PCI
) ? "AVM Fritz!PCI" : "AVM Fritz!PnP",
757 cs
->irq
, cs
->hw
.avm
.cfg_reg
);
760 cs
->readisac
= &ReadISAC
;
761 cs
->writeisac
= &WriteISAC
;
762 cs
->readisacfifo
= &ReadISACfifo
;
763 cs
->writeisacfifo
= &WriteISACfifo
;
764 cs
->BC_Send_Data
= &hdlc_fill_fifo
;
765 cs
->cardmsg
= &AVM_card_msg
;
766 cs
->irq_func
= &avm_pcipnp_interrupt
;
767 cs
->writeisac(cs
, ISAC_MASK
, 0xFF);
768 ISACVersion(cs
, (cs
->subtyp
== AVM_FRITZ_PCI
) ? "AVM PCI:" : "AVM PnP:");
774 static int avm_pnp_setup(struct IsdnCardState
*cs
)
776 return (1); /* no-op: success */
781 static struct pnp_card
*pnp_avm_c
= NULL
;
783 static int avm_pnp_setup(struct IsdnCardState
*cs
)
785 struct pnp_dev
*pnp_avm_d
= NULL
;
787 if (!isapnp_present())
788 return (1); /* no-op: success */
790 if ((pnp_avm_c
= pnp_find_card(
791 ISAPNP_VENDOR('A', 'V', 'M'),
792 ISAPNP_FUNCTION(0x0900), pnp_avm_c
))) {
793 if ((pnp_avm_d
= pnp_find_dev(pnp_avm_c
,
794 ISAPNP_VENDOR('A', 'V', 'M'),
795 ISAPNP_FUNCTION(0x0900), pnp_avm_d
))) {
798 pnp_disable_dev(pnp_avm_d
);
799 err
= pnp_activate_dev(pnp_avm_d
);
801 printk(KERN_WARNING
"%s: pnp_activate_dev ret(%d)\n",
806 pnp_port_start(pnp_avm_d
, 0);
807 cs
->irq
= pnp_irq(pnp_avm_d
, 0);
809 printk(KERN_ERR
"FritzPnP:No IRQ\n");
812 if (!cs
->hw
.avm
.cfg_reg
) {
813 printk(KERN_ERR
"FritzPnP:No IO address\n");
816 cs
->subtyp
= AVM_FRITZ_PNP
;
818 return (2); /* goto 'ready' label */
825 #endif /* __ISAPNP__ */
829 static int avm_pci_setup(struct IsdnCardState
*cs
)
831 return (1); /* no-op: success */
836 static struct pci_dev
*dev_avm
= NULL
;
838 static int avm_pci_setup(struct IsdnCardState
*cs
)
840 if ((dev_avm
= hisax_find_pci_device(PCI_VENDOR_ID_AVM
,
841 PCI_DEVICE_ID_AVM_A1
, dev_avm
))) {
843 if (pci_enable_device(dev_avm
))
846 cs
->irq
= dev_avm
->irq
;
848 printk(KERN_ERR
"FritzPCI: No IRQ for PCI card found\n");
852 cs
->hw
.avm
.cfg_reg
= pci_resource_start(dev_avm
, 1);
853 if (!cs
->hw
.avm
.cfg_reg
) {
854 printk(KERN_ERR
"FritzPCI: No IO-Adr for PCI card found\n");
858 cs
->subtyp
= AVM_FRITZ_PCI
;
860 printk(KERN_WARNING
"FritzPCI: No PCI card found\n");
864 cs
->irq_flags
|= IRQF_SHARED
;
869 #endif /* CONFIG_PCI */
871 int setup_avm_pcipnp(struct IsdnCard
*card
)
873 struct IsdnCardState
*cs
= card
->cs
;
877 strcpy(tmp
, avm_pci_rev
);
878 printk(KERN_INFO
"HiSax: AVM PCI driver Rev. %s\n", HiSax_getrev(tmp
));
880 if (cs
->typ
!= ISDN_CTYPE_FRITZPCI
)
884 /* old manual method */
885 cs
->hw
.avm
.cfg_reg
= card
->para
[1];
886 cs
->irq
= card
->para
[0];
887 cs
->subtyp
= AVM_FRITZ_PNP
;
891 rc
= avm_pnp_setup(cs
);
897 rc
= avm_pci_setup(cs
);
902 return avm_setup_rest(cs
);