Hopefully get the Kconfig PCI stuff right, finally.
[linux-2.6/linux-mips.git] / drivers / isdn / hisax / avm_pci.c
blobcba324bbf8df50a102b66a7d0ff456ba4ed4b044
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
5 * Author Karsten Keil
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>
17 #include "hisax.h"
18 #include "isac.h"
19 #include "isdnl1.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
31 #define HDLC_FIFO 0x0
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 */
79 static u8
80 ReadISAC(struct IsdnCardState *cs, u8 offset)
82 u8 idx = (offset > 0x2f) ? AVM_ISAC_REG_HIGH : AVM_ISAC_REG_LOW;
83 u8 val;
84 unsigned long flags;
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);
90 return (val);
93 static void
94 WriteISAC(struct IsdnCardState *cs, u8 offset, u8 value)
96 u8 idx = (offset > 0x2f) ? AVM_ISAC_REG_HIGH : AVM_ISAC_REG_LOW;
97 unsigned long flags;
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);
105 static void
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);
112 static void
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,
126 static inline u_int
127 ReadHDLCPCI(struct IsdnCardState *cs, int chan, u8 offset)
129 u_int idx = chan ? AVM_HDLC_2 : AVM_HDLC_1;
130 u_int val;
131 unsigned long flags;
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);
137 return (val);
140 static inline void
141 WriteHDLCPCI(struct IsdnCardState *cs, int chan, u8 offset, u_int value)
143 u_int idx = chan ? AVM_HDLC_2 : AVM_HDLC_1;
144 unsigned long flags;
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);
152 static inline u8
153 ReadHDLCPnP(struct IsdnCardState *cs, int chan, u8 offset)
155 u8 idx = chan ? AVM_HDLC_2 : AVM_HDLC_1;
156 u8 val;
157 unsigned long flags;
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);
163 return (val);
166 static inline void
167 WriteHDLCPnP(struct IsdnCardState *cs, int chan, u8 offset, u8 value)
169 u8 idx = chan ? AVM_HDLC_2 : AVM_HDLC_1;
170 unsigned long flags;
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);
178 static void
179 hdlc_read_fifo(struct IsdnCardState *cs, int hscx, u8 *data, int len)
181 u8 idx = hscx ? AVM_HDLC_2 : AVM_HDLC_1;
182 int i;
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) {
189 #ifdef __powerpc__
190 #ifdef CONFIG_APUS
191 *ptr++ = in_le32((u32 *)(cs->hw.avm.isac +_IO_BASE));
192 #else
193 *ptr++ = in_be32((u32 *)(cs->hw.avm.isac +_IO_BASE));
194 #endif /* CONFIG_APUS */
195 #else
196 *ptr++ = inl(cs->hw.avm.isac);
197 #endif /* __powerpc__ */
199 } else {
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,
211 static inline
212 struct BCState *Sel_BCS(struct IsdnCardState *cs, int channel)
214 if (cs->bcs[0].mode && (cs->bcs[0].channel == channel))
215 return(&cs->bcs[0]);
216 else if (cs->bcs[1].mode && (cs->bcs[1].channel == channel))
217 return(&cs->bcs[1]);
218 else
219 return(NULL);
222 void
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);
230 } else {
231 if (which & 4)
232 WriteHDLCPnP(bcs->cs, bcs->channel, HDLC_STATUS + 2,
233 bcs->hw.hdlc.ctrl.sr.mode);
234 if (which & 2)
235 WriteHDLCPnP(bcs->cs, bcs->channel, HDLC_STATUS + 1,
236 bcs->hw.hdlc.ctrl.sr.xml);
237 if (which & 1)
238 WriteHDLCPnP(bcs->cs, bcs->channel, HDLC_STATUS,
239 bcs->hw.hdlc.ctrl.sr.cmd);
243 void
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;
253 switch (mode) {
254 case (-1): /* used for init */
255 bcs->mode = 1;
256 bcs->channel = bc;
257 bc = 0;
258 case (L1_MODE_NULL):
259 if (bcs->mode == L1_MODE_NULL)
260 return;
261 bcs->hw.hdlc.ctrl.sr.cmd = HDLC_CMD_XRS | HDLC_CMD_RRS;
262 bcs->hw.hdlc.ctrl.sr.mode = HDLC_MODE_TRANS;
263 write_ctrl(bcs, 5);
264 bcs->mode = L1_MODE_NULL;
265 bcs->channel = bc;
266 break;
267 case (L1_MODE_TRANS):
268 bcs->mode = mode;
269 bcs->channel = bc;
270 bcs->hw.hdlc.ctrl.sr.cmd = HDLC_CMD_XRS | HDLC_CMD_RRS;
271 bcs->hw.hdlc.ctrl.sr.mode = HDLC_MODE_TRANS;
272 write_ctrl(bcs, 5);
273 bcs->hw.hdlc.ctrl.sr.cmd = HDLC_CMD_XRS;
274 write_ctrl(bcs, 1);
275 bcs->hw.hdlc.ctrl.sr.cmd = 0;
276 sched_b_event(bcs, B_XMTBUFREADY);
277 break;
278 case (L1_MODE_HDLC):
279 bcs->mode = mode;
280 bcs->channel = bc;
281 bcs->hw.hdlc.ctrl.sr.cmd = HDLC_CMD_XRS | HDLC_CMD_RRS;
282 bcs->hw.hdlc.ctrl.sr.mode = HDLC_MODE_ITF_FLG;
283 write_ctrl(bcs, 5);
284 bcs->hw.hdlc.ctrl.sr.cmd = HDLC_CMD_XRS;
285 write_ctrl(bcs, 1);
286 bcs->hw.hdlc.ctrl.sr.cmd = 0;
287 sched_b_event(bcs, B_XMTBUFREADY);
288 break;
292 static inline void
293 hdlc_empty_fifo(struct BCState *bcs, int count)
295 recv_empty_fifo_b(bcs, count);
298 static void
299 hdlc_fill_fifo(struct BCState *bcs)
301 struct IsdnCardState *cs = bcs->cs;
302 int count, more, cnt =0;
303 int fifo_size = 32;
304 unsigned char *p;
305 unsigned int *ptr;
307 p = xmit_fill_fifo_b(bcs, fifo_size, &count, &more);
308 if (!p)
309 return;
311 if (more)
312 bcs->hw.hdlc.ctrl.sr.cmd &= ~HDLC_CMD_XME;
313 else
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;
320 while (cnt<count) {
321 #ifdef __powerpc__
322 #ifdef CONFIG_APUS
323 out_le32((unsigned *)(cs->hw.avm.isac +_IO_BASE), *ptr++);
324 #else
325 out_be32((unsigned *)(cs->hw.avm.isac +_IO_BASE), *ptr++);
326 #endif /* CONFIG_APUS */
327 #else
328 outl(*ptr++, cs->hw.avm.isac);
329 #endif /* __powerpc__ */
330 cnt += 4;
332 } else {
333 while (cnt<count) {
334 outb(*p++, cs->hw.avm.isac);
335 cnt++;
340 static void
341 reset_xmit(struct BCState *bcs)
343 bcs->hw.hdlc.ctrl.sr.xml = 0;
344 bcs->hw.hdlc.ctrl.sr.cmd |= HDLC_CMD_XRS;
345 write_ctrl(bcs, 1);
346 bcs->hw.hdlc.ctrl.sr.cmd &= ~HDLC_CMD_XRS;
347 write_ctrl(bcs, 1);
348 hdlc_fill_fifo(bcs);
351 static inline void
352 HDLC_irq(struct BCState *bcs, u_int stat)
354 int len;
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");
363 else
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;
367 write_ctrl(bcs, 1);
368 bcs->hw.hdlc.ctrl.sr.cmd &= ~HDLC_CMD_RRS;
369 write_ctrl(bcs, 1);
370 bcs->rcvidx = 0;
371 } else {
372 if (!(len = (stat & HDLC_STAT_RML_MASK)>>8))
373 len = 32;
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 recv_rme_b(bcs);
379 } else {
380 if (bcs->cs->debug & L1_DEB_HSCX)
381 debugl1(bcs->cs, "invalid frame");
382 else
383 debugl1(bcs->cs, "ch%d invalid frame %#x", bcs->channel, stat);
384 bcs->rcvidx = 0;
389 if (stat & HDLC_INT_XDU) {
390 xmit_xdu_b(bcs, reset_xmit);
391 } else if (stat & HDLC_INT_XPR) {
392 xmit_xpr_b(bcs);
396 inline void
397 HDLC_irq_main(struct IsdnCardState *cs)
399 u_int stat;
400 struct BCState *bcs;
402 spin_lock(&cs->lock);
403 if (cs->subtyp == AVM_FRITZ_PCI) {
404 stat = ReadHDLCPCI(cs, 0, HDLC_STATUS);
405 } else {
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))) {
412 if (cs->debug)
413 debugl1(cs, "hdlc spurious channel 0 IRQ");
414 } else
415 HDLC_irq(bcs, stat);
417 if (cs->subtyp == AVM_FRITZ_PCI) {
418 stat = ReadHDLCPCI(cs, 1, HDLC_STATUS);
419 } else {
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))) {
426 if (cs->debug)
427 debugl1(cs, "hdlc spurious channel 1 IRQ");
428 } else
429 HDLC_irq(bcs, stat);
431 spin_unlock(&cs->lock);
434 void
435 hdlc_l2l1(struct PStack *st, int pr, void *arg)
437 struct sk_buff *skb = arg;
439 switch (pr) {
440 case (PH_DATA | REQUEST):
441 xmit_data_req_b(st->l1.bcs, skb);
442 break;
443 case (PH_PULL | INDICATION):
444 xmit_pull_ind_b(st->l1.bcs, skb);
445 break;
446 case (PH_PULL | REQUEST):
447 xmit_pull_req_b(st);
448 break;
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);
453 break;
454 case (PH_DEACTIVATE | REQUEST):
455 l1_msg_b(st, pr, arg);
456 break;
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);
462 break;
466 void
467 close_hdlcstate(struct BCState *bcs)
469 modehdlc(bcs, 0, 0);
470 bc_close(bcs);
474 open_hdlcstate(struct IsdnCardState *cs, struct BCState *bcs)
476 return bc_open(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))
485 return (-1);
486 st->l1.bcs = bcs;
487 st->l1.l2l1 = hdlc_l2l1;
488 setstack_manager(st);
489 bcs->st = st;
490 setstack_l1_B(st);
491 return (0);
494 static struct bc_l1_ops hdlc_l1_ops = {
495 .fill_fifo = hdlc_fill_fifo,
496 .open = setstack_hdlc,
497 .close = close_hdlcstate,
500 static void __init
501 inithdlc(struct IsdnCardState *cs)
503 u_int val;
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);
510 } else {
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);
533 static void
534 avm_pcipnp_interrupt(int intno, void *dev_id, struct pt_regs *regs)
536 struct IsdnCardState *cs = dev_id;
537 u8 val;
538 u8 sval;
540 if (!cs) {
541 printk(KERN_WARNING "AVM PCI: Spurious interrupt!\n");
542 return;
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 */
547 return;
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)) {
553 HDLC_irq_main(cs);
555 WriteISAC(cs, ISAC_MASK, 0xFF);
556 WriteISAC(cs, ISAC_MASK, 0x0);
559 static int
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));
571 return 0;
574 static void
575 avm_pcipnp_init(struct IsdnCardState *cs)
577 initisac(cs);
578 inithdlc(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);
585 static void
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,
599 static int __init
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);
609 static int __init
610 avm_pci_probe(struct IsdnCardState *cs, struct pci_dev *pdev)
612 int rc;
613 u32 val;
615 printk(KERN_INFO "AVM PCI: defined at %#lx IRQ %u\n",
616 pci_resource_start(pdev, 1), pdev->irq);
618 rc = -EBUSY;
619 if (pci_enable_device(pdev))
620 goto err;
622 cs->subtyp = AVM_FRITZ_PCI;
623 cs->irq = pdev->irq;
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"))
628 goto err;
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))
636 goto err;
638 return 0;
639 err:
640 hisax_release_resources(cs);
641 return rc;
644 static int __init
645 avm_pnp_probe(struct IsdnCardState *cs, struct IsdnCard *card)
647 int rc;
648 u8 val, ver;
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;
658 rc = -EBUSY;
659 if (!request_io(&cs->rs, cs->hw.avm.cfg_reg, 32, "avm PnP"))
660 goto err;
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))
667 goto err;
669 return 0;
670 err:
671 hisax_release_resources(cs);
672 return rc;
675 static struct pci_dev *dev_avm __initdata = NULL;
676 #ifdef __ISAPNP__
677 static struct pnp_card *card_avm __initdata = NULL;
678 static struct pnp_dev *pnp_avm __initdata = NULL;
679 #endif
681 int __init
682 setup_avm_pcipnp(struct IsdnCard *card)
684 char tmp[64];
686 strcpy(tmp, avm_pci_rev);
687 printk(KERN_INFO "HiSax: AVM PCI driver Rev. %s\n", HiSax_getrev(tmp));
688 if (card->para[1]) {
689 /* old manual method */
690 if (avm_pnp_probe(card->cs, card))
691 return 0;
692 return 1;
693 } else {
694 #ifdef __ISAPNP__
695 if (isapnp_present()) {
696 struct pnp_card *ba;
697 if ((ba = pnp_find_card(
698 ISAPNP_VENDOR('A', 'V', 'M'),
699 ISAPNP_FUNCTION(0x0900), card_avm))) {
700 card_avm = ba;
701 pnp_avm = NULL;
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");
707 return 0;
709 if (pnp_activate_dev(pnp_avm) < 0) {
710 printk(KERN_ERR "FritzPnP: activate failed\n");
711 pnp_device_detach(pnp_avm);
712 return 0;
714 if (!pnp_irq_valid(pnp_avm, 0)) {
715 printk(KERN_ERR "FritzPnP:No IRQ\n");
716 pnp_device_detach(pnp_avm);
717 return(0);
719 if (!pnp_port_valid(pnp_avm, 0)) {
720 printk(KERN_ERR "FritzPnP:No IO address\n");
721 pnp_device_detach(pnp_avm);
722 return(0);
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))
727 return 0;
728 return 1;
732 #endif
733 #ifdef CONFIG_PCI
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))
737 return 0;
738 return 1;
740 #endif /* CONFIG_PCI */
742 printk(KERN_WARNING "FritzPCI: No card found\n");
743 return 0;