/* $Id: avm_pci.c,v 1.29.2.4 2004/02/11 13:21:32 keil Exp $
 *
 * low level stuff for AVM Fritz!PCI and ISA PnP isdn cards
 *
 * Author       Karsten Keil
 * Copyright    by Karsten Keil      <keil@isdn4linux.de>
 *
 * This software may be used and distributed according to the terms
 * of the GNU General Public License, incorporated herein by reference.
 *
 * Thanks to AVM, Berlin for information
 *
 */

#include <linux/init.h>
#include "hisax.h"
#include "isac.h"
#include "isdnl1.h"
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/isapnp.h>
#include <linux/interrupt.h>

static const char *avm_pci_rev = "$Revision: 1.29.2.4 $";

#define  AVM_FRITZ_PCI		1
#define  AVM_FRITZ_PNP		2

#define  HDLC_FIFO		0x0
#define  HDLC_STATUS		0x4

#define	 AVM_HDLC_1		0x00
#define	 AVM_HDLC_2		0x01
#define	 AVM_ISAC_FIFO		0x02
#define	 AVM_ISAC_REG_LOW	0x04
#define	 AVM_ISAC_REG_HIGH	0x06

#define  AVM_STATUS0_IRQ_ISAC	0x01
#define  AVM_STATUS0_IRQ_HDLC	0x02
#define  AVM_STATUS0_IRQ_TIMER	0x04
#define  AVM_STATUS0_IRQ_MASK	0x07

#define  AVM_STATUS0_RESET	0x01
#define  AVM_STATUS0_DIS_TIMER	0x02
#define  AVM_STATUS0_RES_TIMER	0x04
#define  AVM_STATUS0_ENA_IRQ	0x08
#define  AVM_STATUS0_TESTBIT	0x10

#define  AVM_STATUS1_INT_SEL	0x0f
#define  AVM_STATUS1_ENA_IOM	0x80

#define  HDLC_MODE_ITF_FLG	0x01
#define  HDLC_MODE_TRANS	0x02
#define  HDLC_MODE_CCR_7	0x04
#define  HDLC_MODE_CCR_16	0x08
#define  HDLC_MODE_TESTLOOP	0x80

#define  HDLC_INT_XPR		0x80
#define  HDLC_INT_XDU		0x40
#define  HDLC_INT_RPR		0x20
#define  HDLC_INT_MASK		0xE0

#define  HDLC_STAT_RME		0x01
#define  HDLC_STAT_RDO		0x10
#define  HDLC_STAT_CRCVFRRAB	0x0E
#define  HDLC_STAT_CRCVFR	0x06
#define  HDLC_STAT_RML_MASK	0x3f00

#define  HDLC_CMD_XRS		0x80
#define  HDLC_CMD_XME		0x01
#define  HDLC_CMD_RRS		0x20
#define  HDLC_CMD_XML_MASK	0x3f00


/* Interface functions */

static u_char
ReadISAC(struct IsdnCardState *cs, u_char offset)
{
	register u_char idx = (offset > 0x2f) ? AVM_ISAC_REG_HIGH : AVM_ISAC_REG_LOW;
	register u_char val;

	outb(idx, cs->hw.avm.cfg_reg + 4);
	val = inb(cs->hw.avm.isac + (offset & 0xf));
	return (val);
}

static void
WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
{
	register u_char idx = (offset > 0x2f) ? AVM_ISAC_REG_HIGH : AVM_ISAC_REG_LOW;

	outb(idx, cs->hw.avm.cfg_reg + 4);
	outb(value, cs->hw.avm.isac + (offset & 0xf));
}

static void
ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size)
{
	outb(AVM_ISAC_FIFO, cs->hw.avm.cfg_reg + 4);
	insb(cs->hw.avm.isac, data, size);
}

static void
WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size)
{
	outb(AVM_ISAC_FIFO, cs->hw.avm.cfg_reg + 4);
	outsb(cs->hw.avm.isac, data, size);
}

static inline u_int
ReadHDLCPCI(struct IsdnCardState *cs, int chan, u_char offset)
{
	register u_int idx = chan ? AVM_HDLC_2 : AVM_HDLC_1;
	register u_int val;

	outl(idx, cs->hw.avm.cfg_reg + 4);
	val = inl(cs->hw.avm.isac + offset);
	return (val);
}

static inline void
WriteHDLCPCI(struct IsdnCardState *cs, int chan, u_char offset, u_int value)
{
	register u_int idx = chan ? AVM_HDLC_2 : AVM_HDLC_1;

	outl(idx, cs->hw.avm.cfg_reg + 4);
	outl(value, cs->hw.avm.isac + offset);
}

static inline u_char
ReadHDLCPnP(struct IsdnCardState *cs, int chan, u_char offset)
{
	register u_char idx = chan ? AVM_HDLC_2 : AVM_HDLC_1;
	register u_char val;

	outb(idx, cs->hw.avm.cfg_reg + 4);
	val = inb(cs->hw.avm.isac + offset);
	return (val);
}

static inline void
WriteHDLCPnP(struct IsdnCardState *cs, int chan, u_char offset, u_char value)
{
	register u_char idx = chan ? AVM_HDLC_2 : AVM_HDLC_1;

	outb(idx, cs->hw.avm.cfg_reg + 4);
	outb(value, cs->hw.avm.isac + offset);
}

static u_char
ReadHDLC_s(struct IsdnCardState *cs, int chan, u_char offset)
{
	return (0xff & ReadHDLCPCI(cs, chan, offset));
}

static void
WriteHDLC_s(struct IsdnCardState *cs, int chan, u_char offset, u_char value)
{
	WriteHDLCPCI(cs, chan, offset, value);
}

static inline
struct BCState *Sel_BCS(struct IsdnCardState *cs, int channel)
{
	if (cs->bcs[0].mode && (cs->bcs[0].channel == channel))
		return (&cs->bcs[0]);
	else if (cs->bcs[1].mode && (cs->bcs[1].channel == channel))
		return (&cs->bcs[1]);
	else
		return (NULL);
}

static void
write_ctrl(struct BCState *bcs, int which) {

	if (bcs->cs->debug & L1_DEB_HSCX)
		debugl1(bcs->cs, "hdlc %c wr%x ctrl %x",
			'A' + bcs->channel, which, bcs->hw.hdlc.ctrl.ctrl);
	if (bcs->cs->subtyp == AVM_FRITZ_PCI) {
		WriteHDLCPCI(bcs->cs, bcs->channel, HDLC_STATUS, bcs->hw.hdlc.ctrl.ctrl);
	} else {
		if (which & 4)
			WriteHDLCPnP(bcs->cs, bcs->channel, HDLC_STATUS + 2,
				     bcs->hw.hdlc.ctrl.sr.mode);
		if (which & 2)
			WriteHDLCPnP(bcs->cs, bcs->channel, HDLC_STATUS + 1,
				     bcs->hw.hdlc.ctrl.sr.xml);
		if (which & 1)
			WriteHDLCPnP(bcs->cs, bcs->channel, HDLC_STATUS,
				     bcs->hw.hdlc.ctrl.sr.cmd);
	}
}

static void
modehdlc(struct BCState *bcs, int mode, int bc)
{
	struct IsdnCardState *cs = bcs->cs;
	int hdlc = bcs->channel;

	if (cs->debug & L1_DEB_HSCX)
		debugl1(cs, "hdlc %c mode %d --> %d ichan %d --> %d",
			'A' + hdlc, bcs->mode, mode, hdlc, bc);
	bcs->hw.hdlc.ctrl.ctrl = 0;
	switch (mode) {
	case (-1): /* used for init */
		bcs->mode = 1;
		bcs->channel = bc;
		bc = 0;
	case (L1_MODE_NULL):
		if (bcs->mode == L1_MODE_NULL)
			return;
		bcs->hw.hdlc.ctrl.sr.cmd  = HDLC_CMD_XRS | HDLC_CMD_RRS;
		bcs->hw.hdlc.ctrl.sr.mode = HDLC_MODE_TRANS;
		write_ctrl(bcs, 5);
		bcs->mode = L1_MODE_NULL;
		bcs->channel = bc;
		break;
	case (L1_MODE_TRANS):
		bcs->mode = mode;
		bcs->channel = bc;
		bcs->hw.hdlc.ctrl.sr.cmd  = HDLC_CMD_XRS | HDLC_CMD_RRS;
		bcs->hw.hdlc.ctrl.sr.mode = HDLC_MODE_TRANS;
		write_ctrl(bcs, 5);
		bcs->hw.hdlc.ctrl.sr.cmd = HDLC_CMD_XRS;
		write_ctrl(bcs, 1);
		bcs->hw.hdlc.ctrl.sr.cmd = 0;
		schedule_event(bcs, B_XMTBUFREADY);
		break;
	case (L1_MODE_HDLC):
		bcs->mode = mode;
		bcs->channel = bc;
		bcs->hw.hdlc.ctrl.sr.cmd  = HDLC_CMD_XRS | HDLC_CMD_RRS;
		bcs->hw.hdlc.ctrl.sr.mode = HDLC_MODE_ITF_FLG;
		write_ctrl(bcs, 5);
		bcs->hw.hdlc.ctrl.sr.cmd = HDLC_CMD_XRS;
		write_ctrl(bcs, 1);
		bcs->hw.hdlc.ctrl.sr.cmd = 0;
		schedule_event(bcs, B_XMTBUFREADY);
		break;
	}
}

static inline void
hdlc_empty_fifo(struct BCState *bcs, int count)
{
	register u_int *ptr;
	u_char *p;
	u_char idx = bcs->channel ? AVM_HDLC_2 : AVM_HDLC_1;
	int cnt = 0;
	struct IsdnCardState *cs = bcs->cs;

	if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
		debugl1(cs, "hdlc_empty_fifo %d", count);
	if (bcs->hw.hdlc.rcvidx + count > HSCX_BUFMAX) {
		if (cs->debug & L1_DEB_WARN)
			debugl1(cs, "hdlc_empty_fifo: incoming packet too large");
		return;
	}
	p = bcs->hw.hdlc.rcvbuf + bcs->hw.hdlc.rcvidx;
	ptr = (u_int *)p;
	bcs->hw.hdlc.rcvidx += count;
	if (cs->subtyp == AVM_FRITZ_PCI) {
		outl(idx, cs->hw.avm.cfg_reg + 4);
		while (cnt < count) {
#ifdef __powerpc__
			*ptr++ = in_be32((unsigned *)(cs->hw.avm.isac + _IO_BASE));
#else
			*ptr++ = inl(cs->hw.avm.isac);
#endif /* __powerpc__ */
			cnt += 4;
		}
	} else {
		outb(idx, cs->hw.avm.cfg_reg + 4);
		while (cnt < count) {
			*p++ = inb(cs->hw.avm.isac);
			cnt++;
		}
	}
	if (cs->debug & L1_DEB_HSCX_FIFO) {
		char *t = bcs->blog;

		if (cs->subtyp == AVM_FRITZ_PNP)
			p = (u_char *) ptr;
		t += sprintf(t, "hdlc_empty_fifo %c cnt %d",
			     bcs->channel ? 'B' : 'A', count);
		QuickHex(t, p, count);
		debugl1(cs, "%s", bcs->blog);
	}
}

static inline void
hdlc_fill_fifo(struct BCState *bcs)
{
	struct IsdnCardState *cs = bcs->cs;
	int count, cnt = 0;
	int fifo_size = 32;
	u_char *p;
	u_int *ptr;

	if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
		debugl1(cs, "hdlc_fill_fifo");
	if (!bcs->tx_skb)
		return;
	if (bcs->tx_skb->len <= 0)
		return;

	bcs->hw.hdlc.ctrl.sr.cmd &= ~HDLC_CMD_XME;
	if (bcs->tx_skb->len > fifo_size) {
		count = fifo_size;
	} else {
		count = bcs->tx_skb->len;
		if (bcs->mode != L1_MODE_TRANS)
			bcs->hw.hdlc.ctrl.sr.cmd |= HDLC_CMD_XME;
	}
	if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
		debugl1(cs, "hdlc_fill_fifo %d/%u", count, bcs->tx_skb->len);
	p = bcs->tx_skb->data;
	ptr = (u_int *)p;
	skb_pull(bcs->tx_skb, count);
	bcs->tx_cnt -= count;
	bcs->hw.hdlc.count += count;
	bcs->hw.hdlc.ctrl.sr.xml = ((count == fifo_size) ? 0 : count);
	write_ctrl(bcs, 3);  /* sets the correct index too */
	if (cs->subtyp == AVM_FRITZ_PCI) {
		while (cnt < count) {
#ifdef __powerpc__
			out_be32((unsigned *)(cs->hw.avm.isac + _IO_BASE), *ptr++);
#else
			outl(*ptr++, cs->hw.avm.isac);
#endif /* __powerpc__ */
			cnt += 4;
		}
	} else {
		while (cnt < count) {
			outb(*p++, cs->hw.avm.isac);
			cnt++;
		}
	}
	if (cs->debug & L1_DEB_HSCX_FIFO) {
		char *t = bcs->blog;

		if (cs->subtyp == AVM_FRITZ_PNP)
			p = (u_char *) ptr;
		t += sprintf(t, "hdlc_fill_fifo %c cnt %d",
			     bcs->channel ? 'B' : 'A', count);
		QuickHex(t, p, count);
		debugl1(cs, "%s", bcs->blog);
	}
}

static void
HDLC_irq(struct BCState *bcs, u_int stat) {
	int len;
	struct sk_buff *skb;

	if (bcs->cs->debug & L1_DEB_HSCX)
		debugl1(bcs->cs, "ch%d stat %#x", bcs->channel, stat);
	if (stat & HDLC_INT_RPR) {
		if (stat & HDLC_STAT_RDO) {
			if (bcs->cs->debug & L1_DEB_HSCX)
				debugl1(bcs->cs, "RDO");
			else
				debugl1(bcs->cs, "ch%d stat %#x", bcs->channel, stat);
			bcs->hw.hdlc.ctrl.sr.xml = 0;
			bcs->hw.hdlc.ctrl.sr.cmd |= HDLC_CMD_RRS;
			write_ctrl(bcs, 1);
			bcs->hw.hdlc.ctrl.sr.cmd &= ~HDLC_CMD_RRS;
			write_ctrl(bcs, 1);
			bcs->hw.hdlc.rcvidx = 0;
		} else {
			if (!(len = (stat & HDLC_STAT_RML_MASK) >> 8))
				len = 32;
			hdlc_empty_fifo(bcs, len);
			if ((stat & HDLC_STAT_RME) || (bcs->mode == L1_MODE_TRANS)) {
				if (((stat & HDLC_STAT_CRCVFRRAB) == HDLC_STAT_CRCVFR) ||
				    (bcs->mode == L1_MODE_TRANS)) {
					if (!(skb = dev_alloc_skb(bcs->hw.hdlc.rcvidx)))
						printk(KERN_WARNING "HDLC: receive out of memory\n");
					else {
						memcpy(skb_put(skb, bcs->hw.hdlc.rcvidx),
						       bcs->hw.hdlc.rcvbuf, bcs->hw.hdlc.rcvidx);
						skb_queue_tail(&bcs->rqueue, skb);
					}
					bcs->hw.hdlc.rcvidx = 0;
					schedule_event(bcs, B_RCVBUFREADY);
				} else {
					if (bcs->cs->debug & L1_DEB_HSCX)
						debugl1(bcs->cs, "invalid frame");
					else
						debugl1(bcs->cs, "ch%d invalid frame %#x", bcs->channel, stat);
					bcs->hw.hdlc.rcvidx = 0;
				}
			}
		}
	}
	if (stat & HDLC_INT_XDU) {
		/* Here we lost an TX interrupt, so
		 * restart transmitting the whole frame.
		 */
		if (bcs->tx_skb) {
			skb_push(bcs->tx_skb, bcs->hw.hdlc.count);
			bcs->tx_cnt += bcs->hw.hdlc.count;
			bcs->hw.hdlc.count = 0;
			if (bcs->cs->debug & L1_DEB_WARN)
				debugl1(bcs->cs, "ch%d XDU", bcs->channel);
		} else if (bcs->cs->debug & L1_DEB_WARN)
			debugl1(bcs->cs, "ch%d XDU without skb", bcs->channel);
		bcs->hw.hdlc.ctrl.sr.xml = 0;
		bcs->hw.hdlc.ctrl.sr.cmd |= HDLC_CMD_XRS;
		write_ctrl(bcs, 1);
		bcs->hw.hdlc.ctrl.sr.cmd &= ~HDLC_CMD_XRS;
		write_ctrl(bcs, 1);
		hdlc_fill_fifo(bcs);
	} else if (stat & HDLC_INT_XPR) {
		if (bcs->tx_skb) {
			if (bcs->tx_skb->len) {
				hdlc_fill_fifo(bcs);
				return;
			} else {
				if (test_bit(FLG_LLI_L1WAKEUP, &bcs->st->lli.flag) &&
				    (PACKET_NOACK != bcs->tx_skb->pkt_type)) {
					u_long flags;
					spin_lock_irqsave(&bcs->aclock, flags);
					bcs->ackcnt += bcs->hw.hdlc.count;
					spin_unlock_irqrestore(&bcs->aclock, flags);
					schedule_event(bcs, B_ACKPENDING);
				}
				dev_kfree_skb_irq(bcs->tx_skb);
				bcs->hw.hdlc.count = 0;
				bcs->tx_skb = NULL;
			}
		}
		if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
			bcs->hw.hdlc.count = 0;
			test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
			hdlc_fill_fifo(bcs);
		} else {
			test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
			schedule_event(bcs, B_XMTBUFREADY);
		}
	}
}

static inline void
HDLC_irq_main(struct IsdnCardState *cs)
{
	u_int stat;
	struct BCState *bcs;

	if (cs->subtyp == AVM_FRITZ_PCI) {
		stat = ReadHDLCPCI(cs, 0, HDLC_STATUS);
	} else {
		stat = ReadHDLCPnP(cs, 0, HDLC_STATUS);
		if (stat & HDLC_INT_RPR)
			stat |= (ReadHDLCPnP(cs, 0, HDLC_STATUS + 1)) << 8;
	}
	if (stat & HDLC_INT_MASK) {
		if (!(bcs = Sel_BCS(cs, 0))) {
			if (cs->debug)
				debugl1(cs, "hdlc spurious channel 0 IRQ");
		} else
			HDLC_irq(bcs, stat);
	}
	if (cs->subtyp == AVM_FRITZ_PCI) {
		stat = ReadHDLCPCI(cs, 1, HDLC_STATUS);
	} else {
		stat = ReadHDLCPnP(cs, 1, HDLC_STATUS);
		if (stat & HDLC_INT_RPR)
			stat |= (ReadHDLCPnP(cs, 1, HDLC_STATUS + 1)) << 8;
	}
	if (stat & HDLC_INT_MASK) {
		if (!(bcs = Sel_BCS(cs, 1))) {
			if (cs->debug)
				debugl1(cs, "hdlc spurious channel 1 IRQ");
		} else
			HDLC_irq(bcs, stat);
	}
}

static void
hdlc_l2l1(struct PStack *st, int pr, void *arg)
{
	struct BCState *bcs = st->l1.bcs;
	struct sk_buff *skb = arg;
	u_long flags;

	switch (pr) {
	case (PH_DATA | REQUEST):
		spin_lock_irqsave(&bcs->cs->lock, flags);
		if (bcs->tx_skb) {
			skb_queue_tail(&bcs->squeue, skb);
		} else {
			bcs->tx_skb = skb;
			test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
			bcs->hw.hdlc.count = 0;
			bcs->cs->BC_Send_Data(bcs);
		}
		spin_unlock_irqrestore(&bcs->cs->lock, flags);
		break;
	case (PH_PULL | INDICATION):
		spin_lock_irqsave(&bcs->cs->lock, flags);
		if (bcs->tx_skb) {
			printk(KERN_WARNING "hdlc_l2l1: this shouldn't happen\n");
		} else {
			test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
			bcs->tx_skb = skb;
			bcs->hw.hdlc.count = 0;
			bcs->cs->BC_Send_Data(bcs);
		}
		spin_unlock_irqrestore(&bcs->cs->lock, flags);
		break;
	case (PH_PULL | REQUEST):
		if (!bcs->tx_skb) {
			test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
			st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
		} else
			test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
		break;
	case (PH_ACTIVATE | REQUEST):
		spin_lock_irqsave(&bcs->cs->lock, flags);
		test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag);
		modehdlc(bcs, st->l1.mode, st->l1.bc);
		spin_unlock_irqrestore(&bcs->cs->lock, flags);
		l1_msg_b(st, pr, arg);
		break;
	case (PH_DEACTIVATE | REQUEST):
		l1_msg_b(st, pr, arg);
		break;
	case (PH_DEACTIVATE | CONFIRM):
		spin_lock_irqsave(&bcs->cs->lock, flags);
		test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag);
		test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
		modehdlc(bcs, 0, st->l1.bc);
		spin_unlock_irqrestore(&bcs->cs->lock, flags);
		st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
		break;
	}
}

static void
close_hdlcstate(struct BCState *bcs)
{
	modehdlc(bcs, 0, 0);
	if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
		kfree(bcs->hw.hdlc.rcvbuf);
		bcs->hw.hdlc.rcvbuf = NULL;
		kfree(bcs->blog);
		bcs->blog = NULL;
		skb_queue_purge(&bcs->rqueue);
		skb_queue_purge(&bcs->squeue);
		if (bcs->tx_skb) {
			dev_kfree_skb_any(bcs->tx_skb);
			bcs->tx_skb = NULL;
			test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
		}
	}
}

static int
open_hdlcstate(struct IsdnCardState *cs, struct BCState *bcs)
{
	if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
		if (!(bcs->hw.hdlc.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) {
			printk(KERN_WARNING
			       "HiSax: No memory for hdlc.rcvbuf\n");
			return (1);
		}
		if (!(bcs->blog = kmalloc(MAX_BLOG_SPACE, GFP_ATOMIC))) {
			printk(KERN_WARNING
			       "HiSax: No memory for bcs->blog\n");
			test_and_clear_bit(BC_FLG_INIT, &bcs->Flag);
			kfree(bcs->hw.hdlc.rcvbuf);
			bcs->hw.hdlc.rcvbuf = NULL;
			return (2);
		}
		skb_queue_head_init(&bcs->rqueue);
		skb_queue_head_init(&bcs->squeue);
	}
	bcs->tx_skb = NULL;
	test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
	bcs->event = 0;
	bcs->hw.hdlc.rcvidx = 0;
	bcs->tx_cnt = 0;
	return (0);
}

static int
setstack_hdlc(struct PStack *st, struct BCState *bcs)
{
	bcs->channel = st->l1.bc;
	if (open_hdlcstate(st->l1.hardware, bcs))
		return (-1);
	st->l1.bcs = bcs;
	st->l2.l2l1 = hdlc_l2l1;
	setstack_manager(st);
	bcs->st = st;
	setstack_l1_B(st);
	return (0);
}

#if 0
void __init
clear_pending_hdlc_ints(struct IsdnCardState *cs)
{
	u_int val;

	if (cs->subtyp == AVM_FRITZ_PCI) {
		val = ReadHDLCPCI(cs, 0, HDLC_STATUS);
		debugl1(cs, "HDLC 1 STA %x", val);
		val = ReadHDLCPCI(cs, 1, HDLC_STATUS);
		debugl1(cs, "HDLC 2 STA %x", val);
	} else {
		val = ReadHDLCPnP(cs, 0, HDLC_STATUS);
		debugl1(cs, "HDLC 1 STA %x", val);
		val = ReadHDLCPnP(cs, 0, HDLC_STATUS + 1);
		debugl1(cs, "HDLC 1 RML %x", val);
		val = ReadHDLCPnP(cs, 0, HDLC_STATUS + 2);
		debugl1(cs, "HDLC 1 MODE %x", val);
		val = ReadHDLCPnP(cs, 0, HDLC_STATUS + 3);
		debugl1(cs, "HDLC 1 VIN %x", val);
		val = ReadHDLCPnP(cs, 1, HDLC_STATUS);
		debugl1(cs, "HDLC 2 STA %x", val);
		val = ReadHDLCPnP(cs, 1, HDLC_STATUS + 1);
		debugl1(cs, "HDLC 2 RML %x", val);
		val = ReadHDLCPnP(cs, 1, HDLC_STATUS + 2);
		debugl1(cs, "HDLC 2 MODE %x", val);
		val = ReadHDLCPnP(cs, 1, HDLC_STATUS + 3);
		debugl1(cs, "HDLC 2 VIN %x", val);
	}
}
#endif  /*  0  */

static void
inithdlc(struct IsdnCardState *cs)
{
	cs->bcs[0].BC_SetStack = setstack_hdlc;
	cs->bcs[1].BC_SetStack = setstack_hdlc;
	cs->bcs[0].BC_Close = close_hdlcstate;
	cs->bcs[1].BC_Close = close_hdlcstate;
	modehdlc(cs->bcs, -1, 0);
	modehdlc(cs->bcs + 1, -1, 1);
}

static irqreturn_t
avm_pcipnp_interrupt(int intno, void *dev_id)
{
	struct IsdnCardState *cs = dev_id;
	u_long flags;
	u_char val;
	u_char sval;

	spin_lock_irqsave(&cs->lock, flags);
	sval = inb(cs->hw.avm.cfg_reg + 2);
	if ((sval & AVM_STATUS0_IRQ_MASK) == AVM_STATUS0_IRQ_MASK) {
		/* possible a shared  IRQ reqest */
		spin_unlock_irqrestore(&cs->lock, flags);
		return IRQ_NONE;
	}
	if (!(sval & AVM_STATUS0_IRQ_ISAC)) {
		val = ReadISAC(cs, ISAC_ISTA);
		isac_interrupt(cs, val);
	}
	if (!(sval & AVM_STATUS0_IRQ_HDLC)) {
		HDLC_irq_main(cs);
	}
	WriteISAC(cs, ISAC_MASK, 0xFF);
	WriteISAC(cs, ISAC_MASK, 0x0);
	spin_unlock_irqrestore(&cs->lock, flags);
	return IRQ_HANDLED;
}

static void
reset_avmpcipnp(struct IsdnCardState *cs)
{
	printk(KERN_INFO "AVM PCI/PnP: reset\n");
	outb(AVM_STATUS0_RESET | AVM_STATUS0_DIS_TIMER, cs->hw.avm.cfg_reg + 2);
	mdelay(10);
	outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER | AVM_STATUS0_ENA_IRQ, cs->hw.avm.cfg_reg + 2);
	outb(AVM_STATUS1_ENA_IOM | cs->irq, cs->hw.avm.cfg_reg + 3);
	mdelay(10);
	printk(KERN_INFO "AVM PCI/PnP: S1 %x\n", inb(cs->hw.avm.cfg_reg + 3));
}

static int
AVM_card_msg(struct IsdnCardState *cs, int mt, void *arg)
{
	u_long flags;

	switch (mt) {
	case CARD_RESET:
		spin_lock_irqsave(&cs->lock, flags);
		reset_avmpcipnp(cs);
		spin_unlock_irqrestore(&cs->lock, flags);
		return (0);
	case CARD_RELEASE:
		outb(0, cs->hw.avm.cfg_reg + 2);
		release_region(cs->hw.avm.cfg_reg, 32);
		return (0);
	case CARD_INIT:
		spin_lock_irqsave(&cs->lock, flags);
		reset_avmpcipnp(cs);
		clear_pending_isac_ints(cs);
		initisac(cs);
		inithdlc(cs);
		outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER,
		     cs->hw.avm.cfg_reg + 2);
		WriteISAC(cs, ISAC_MASK, 0);
		outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER |
		     AVM_STATUS0_ENA_IRQ, cs->hw.avm.cfg_reg + 2);
		/* RESET Receiver and Transmitter */
		WriteISAC(cs, ISAC_CMDR, 0x41);
		spin_unlock_irqrestore(&cs->lock, flags);
		return (0);
	case CARD_TEST:
		return (0);
	}
	return (0);
}

static int avm_setup_rest(struct IsdnCardState *cs)
{
	u_int val, ver;

	cs->hw.avm.isac = cs->hw.avm.cfg_reg + 0x10;
	if (!request_region(cs->hw.avm.cfg_reg, 32,
			    (cs->subtyp == AVM_FRITZ_PCI) ? "avm PCI" : "avm PnP")) {
		printk(KERN_WARNING
		       "HiSax: Fritz!PCI/PNP config port %x-%x already in use\n",
		       cs->hw.avm.cfg_reg,
		       cs->hw.avm.cfg_reg + 31);
		return (0);
	}
	switch (cs->subtyp) {
	case AVM_FRITZ_PCI:
		val = inl(cs->hw.avm.cfg_reg);
		printk(KERN_INFO "AVM PCI: stat %#x\n", val);
		printk(KERN_INFO "AVM PCI: Class %X Rev %d\n",
		       val & 0xff, (val >> 8) & 0xff);
		cs->BC_Read_Reg = &ReadHDLC_s;
		cs->BC_Write_Reg = &WriteHDLC_s;
		break;
	case AVM_FRITZ_PNP:
		val = inb(cs->hw.avm.cfg_reg);
		ver = inb(cs->hw.avm.cfg_reg + 1);
		printk(KERN_INFO "AVM PnP: Class %X Rev %d\n", val, ver);
		cs->BC_Read_Reg = &ReadHDLCPnP;
		cs->BC_Write_Reg = &WriteHDLCPnP;
		break;
	default:
		printk(KERN_WARNING "AVM unknown subtype %d\n", cs->subtyp);
		return (0);
	}
	printk(KERN_INFO "HiSax: %s config irq:%d base:0x%X\n",
	       (cs->subtyp == AVM_FRITZ_PCI) ? "AVM Fritz!PCI" : "AVM Fritz!PnP",
	       cs->irq, cs->hw.avm.cfg_reg);

	setup_isac(cs);
	cs->readisac = &ReadISAC;
	cs->writeisac = &WriteISAC;
	cs->readisacfifo = &ReadISACfifo;
	cs->writeisacfifo = &WriteISACfifo;
	cs->BC_Send_Data = &hdlc_fill_fifo;
	cs->cardmsg = &AVM_card_msg;
	cs->irq_func = &avm_pcipnp_interrupt;
	cs->writeisac(cs, ISAC_MASK, 0xFF);
	ISACVersion(cs, (cs->subtyp == AVM_FRITZ_PCI) ? "AVM PCI:" : "AVM PnP:");
	return (1);
}

#ifndef __ISAPNP__

static int avm_pnp_setup(struct IsdnCardState *cs)
{
	return (1);	/* no-op: success */
}

#else

static struct pnp_card *pnp_avm_c = NULL;

static int avm_pnp_setup(struct IsdnCardState *cs)
{
	struct pnp_dev *pnp_avm_d = NULL;

	if (!isapnp_present())
		return (1);	/* no-op: success */

	if ((pnp_avm_c = pnp_find_card(
		     ISAPNP_VENDOR('A', 'V', 'M'),
		     ISAPNP_FUNCTION(0x0900), pnp_avm_c))) {
		if ((pnp_avm_d = pnp_find_dev(pnp_avm_c,
					      ISAPNP_VENDOR('A', 'V', 'M'),
					      ISAPNP_FUNCTION(0x0900), pnp_avm_d))) {
			int err;

			pnp_disable_dev(pnp_avm_d);
			err = pnp_activate_dev(pnp_avm_d);
			if (err < 0) {
				printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n",
				       __func__, err);
				return (0);
			}
			cs->hw.avm.cfg_reg =
				pnp_port_start(pnp_avm_d, 0);
			cs->irq = pnp_irq(pnp_avm_d, 0);
			if (!cs->irq) {
				printk(KERN_ERR "FritzPnP:No IRQ\n");
				return (0);
			}
			if (!cs->hw.avm.cfg_reg) {
				printk(KERN_ERR "FritzPnP:No IO address\n");
				return (0);
			}
			cs->subtyp = AVM_FRITZ_PNP;

			return (2);	/* goto 'ready' label */
		}
	}

	return (1);
}

#endif /* __ISAPNP__ */

#ifndef CONFIG_PCI

static int avm_pci_setup(struct IsdnCardState *cs)
{
	return (1);	/* no-op: success */
}

#else

static struct pci_dev *dev_avm = NULL;

static int avm_pci_setup(struct IsdnCardState *cs)
{
	if ((dev_avm = hisax_find_pci_device(PCI_VENDOR_ID_AVM,
					     PCI_DEVICE_ID_AVM_A1, dev_avm))) {

		if (pci_enable_device(dev_avm))
			return (0);

		cs->irq = dev_avm->irq;
		if (!cs->irq) {
			printk(KERN_ERR "FritzPCI: No IRQ for PCI card found\n");
			return (0);
		}

		cs->hw.avm.cfg_reg = pci_resource_start(dev_avm, 1);
		if (!cs->hw.avm.cfg_reg) {
			printk(KERN_ERR "FritzPCI: No IO-Adr for PCI card found\n");
			return (0);
		}

		cs->subtyp = AVM_FRITZ_PCI;
	} else {
		printk(KERN_WARNING "FritzPCI: No PCI card found\n");
		return (0);
	}

	cs->irq_flags |= IRQF_SHARED;

	return (1);
}

#endif /* CONFIG_PCI */

int setup_avm_pcipnp(struct IsdnCard *card)
{
	struct IsdnCardState *cs = card->cs;
	char tmp[64];
	int rc;

	strcpy(tmp, avm_pci_rev);
	printk(KERN_INFO "HiSax: AVM PCI driver Rev. %s\n", HiSax_getrev(tmp));

	if (cs->typ != ISDN_CTYPE_FRITZPCI)
		return (0);

	if (card->para[1]) {
		/* old manual method */
		cs->hw.avm.cfg_reg = card->para[1];
		cs->irq = card->para[0];
		cs->subtyp = AVM_FRITZ_PNP;
		goto ready;
	}

	rc = avm_pnp_setup(cs);
	if (rc < 1)
		return (0);
	if (rc == 2)
		goto ready;

	rc = avm_pci_setup(cs);
	if (rc < 1)
		return (0);

ready:
	return avm_setup_rest(cs);
}
