summaryrefslogtreecommitdiffstats
path: root/sys/i4b/layer1
diff options
context:
space:
mode:
authorhm <hm@FreeBSD.org>1999-08-06 14:05:10 +0000
committerhm <hm@FreeBSD.org>1999-08-06 14:05:10 +0000
commitc318ffb377724b7eab997d3ddd7f16e229f18e4d (patch)
tree4dd20754e94db3bc400654765c985e981925a884 /sys/i4b/layer1
parent29c67703e3751c283a1bdfe7764effe015c13b83 (diff)
downloadFreeBSD-src-c318ffb377724b7eab997d3ddd7f16e229f18e4d.zip
FreeBSD-src-c318ffb377724b7eab997d3ddd7f16e229f18e4d.tar.gz
updating isdn4bsd to beta version 0.83
Diffstat (limited to 'sys/i4b/layer1')
-rw-r--r--sys/i4b/layer1/i4b_asuscom_ipac.c510
-rw-r--r--sys/i4b/layer1/i4b_avm_fritz_pci.c24
-rw-r--r--sys/i4b/layer1/i4b_avm_fritz_pnp.c1268
-rw-r--r--sys/i4b/layer1/i4b_bsdi_ibc.c559
-rw-r--r--sys/i4b/layer1/i4b_dynalink.c156
-rw-r--r--sys/i4b/layer1/i4b_ipac.h8
-rw-r--r--sys/i4b/layer1/i4b_isic.c25
-rw-r--r--sys/i4b/layer1/i4b_isic_isa.c220
-rw-r--r--sys/i4b/layer1/i4b_isic_pnp.c75
-rw-r--r--sys/i4b/layer1/i4b_l1.h56
-rw-r--r--sys/i4b/layer1/i4b_siemens_isurf.c317
-rw-r--r--sys/i4b/layer1/i4b_tel_s0163.c26
-rw-r--r--sys/i4b/layer1/isa_isic.c12
13 files changed, 2550 insertions, 706 deletions
diff --git a/sys/i4b/layer1/i4b_asuscom_ipac.c b/sys/i4b/layer1/i4b_asuscom_ipac.c
new file mode 100644
index 0000000..5018e08
--- /dev/null
+++ b/sys/i4b/layer1/i4b_asuscom_ipac.c
@@ -0,0 +1,510 @@
+/*
+ * Copyright (c) 1999 Ari Suutari. All rights reserved.
+ * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *---------------------------------------------------------------------------
+ *
+ * isic - I4B Siemens ISDN Chipset Driver for Asuscom ISDNlink 128K PnP
+ * =====================================================================
+ *
+ * This driver works with Asuscom ISDNlink 128K PnP ISA adapter,
+ * which is based on Siemens IPAC chip (my card probes as ASU1690).
+ * Older Asuscom ISA cards are based on different chipset
+ * (containing two chips) - for those cards, one might want
+ * to try the Dynalink driver.
+ *
+ * This driver is heavily based on ELSA Quickstep 1000pro PCI
+ * driver written by Hellmuth Michaelis. Card initialization
+ * code is modeled after Linux i4l driver written by Karsten
+ * Keil.
+ *
+ * $Id: i4b_asuscom_ipac.c,v 1.1 1999/07/05 13:46:46 hm Exp $
+ *
+ * last edit-date: [Mon May 31 20:53:17 EEST 1999]
+ *
+ *---------------------------------------------------------------------------*/
+
+#if defined(__FreeBSD__)
+#include "isic.h"
+#include "opt_i4b.h"
+#include "pnp.h"
+#else
+#define NISIC 1
+#define NPNP 1
+#endif
+
+#if (NISIC > 0) && (NPNP > 0) && defined(ASUSCOM_IPAC)
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <net/if.h>
+
+#ifdef __FreeBSD__
+#if __FreeBSD__ >= 3
+#include <sys/ioccom.h>
+#else
+#include <sys/ioctl.h>
+#endif
+#include <machine/clock.h>
+#include <i386/isa/isa_device.h>
+#include <i386/isa/pnp.h>
+#else
+#include <machine/bus.h>
+#include <sys/device.h>
+#endif
+
+#ifdef __FreeBSD__
+#include <machine/i4b_debug.h>
+#include <machine/i4b_ioctl.h>
+#else
+#include <i4b/i4b_debug.h>
+#include <i4b/i4b_ioctl.h>
+#endif
+
+#include <i4b/include/i4b_global.h>
+#include <i4b/include/i4b_l1l2.h>
+#include <i4b/include/i4b_mbuf.h>
+
+#include <i4b/layer1/i4b_l1.h>
+#include <i4b/layer1/i4b_isac.h>
+#include <i4b/layer1/i4b_hscx.h>
+#include <i4b/layer1/i4b_ipac.h>
+
+#ifndef __FreeBSD__
+#include <i4b/layer1/pci_isic.h>
+#endif
+
+/* masks for register encoded in base addr */
+
+#define ASI_BASE_MASK 0x0ffff
+#define ASI_OFF_MASK 0xf0000
+
+/* register id's to be encoded in base addr */
+
+#define ASI_IDISAC 0x00000
+#define ASI_IDHSCXA 0x10000
+#define ASI_IDHSCXB 0x20000
+#define ASI_IDIPAC 0x40000
+
+/* offsets from base address */
+
+#define ASI_OFF_ALE 0x00
+#define ASI_OFF_RW 0x01
+
+/*---------------------------------------------------------------------------*
+ * Asuscom ISDNlink 128K PnP ISAC get fifo routine
+ *---------------------------------------------------------------------------*/
+#ifdef __FreeBSD__
+
+static void
+asi_read_fifo(void *buf, const void *base, size_t len)
+{
+ u_int asus_base;
+
+ asus_base = ((u_int) base) & ASI_BASE_MASK;
+ switch (((u_int) base) & ASI_OFF_MASK) {
+ case ASI_IDHSCXB:
+ outb(asus_base + ASI_OFF_ALE, IPAC_HSCXB_OFF);
+ insb(asus_base + ASI_OFF_RW, (u_char *)buf, (u_int)len);
+ break;
+ case ASI_IDHSCXA:
+ outb(asus_base + ASI_OFF_ALE, IPAC_HSCXA_OFF);
+ insb(asus_base + ASI_OFF_RW, (u_char *)buf, (u_int)len);
+ break;
+ case ASI_IDISAC:
+ outb(asus_base + ASI_OFF_ALE, IPAC_ISAC_OFF);
+ insb(asus_base + ASI_OFF_RW, (u_char *)buf, (u_int)len);
+ break;
+ }
+}
+
+#else
+
+static void
+asi_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size)
+{
+ bus_space_tag_t t = sc->sc_maps[1].t;
+ bus_space_handle_t h = sc->sc_maps[1].h;
+ switch (what) {
+ case ISIC_WHAT_ISAC:
+ bus_space_write_1(t, h, ASI_OFF_ALE, IPAC_ISAC_OFF);
+ bus_space_read_multi_1(t, h, ASI_OFF_RW, buf, size);
+ break;
+ case ISIC_WHAT_HSCXA:
+ bus_space_write_1(t, h, ASI_OFF_ALE, IPAC_HSCXA_OFF);
+ bus_space_read_multi_1(t, h, ASI_OFF_RW, buf, size);
+ break;
+ case ISIC_WHAT_HSCXB:
+ bus_space_write_1(t, h, ASI_OFF_ALE, IPAC_HSCXB_OFF);
+ bus_space_read_multi_1(t, h, ASI_OFF_RW, buf, size);
+ break;
+ }
+}
+
+#endif
+
+/*---------------------------------------------------------------------------*
+ * Asuscom ISDNlink 128K PnP ISAC put fifo routine
+ *---------------------------------------------------------------------------*/
+#ifdef __FreeBSD__
+
+static void
+asi_write_fifo(void *base, const void *buf, size_t len)
+{
+ u_int asus_base;
+
+ asus_base = ((u_int) base) & ASI_BASE_MASK;
+ switch (((u_int) base) & ASI_OFF_MASK) {
+ case ASI_IDHSCXB:
+ outb(asus_base + ASI_OFF_ALE, IPAC_HSCXB_OFF);
+ outsb(asus_base + ASI_OFF_RW, (u_char *)buf, (u_int)len);
+ break;
+ case ASI_IDHSCXA:
+ outb(asus_base + ASI_OFF_ALE, IPAC_HSCXA_OFF);
+ outsb(asus_base + ASI_OFF_RW, (u_char *)buf, (u_int)len);
+ break;
+ case ASI_IDISAC:
+ outb(asus_base + ASI_OFF_ALE, IPAC_ISAC_OFF);
+ outsb(asus_base + ASI_OFF_RW, (u_char *)buf, (u_int)len);
+ break;
+ }
+}
+
+#else
+
+static void
+asi_write_fifo(struct isic_softc *sc,
+ int what, const void *buf, size_t size)
+{
+ bus_space_tag_t t = sc->sc_maps[1].t;
+ bus_space_handle_t h = sc->sc_maps[1].h;
+ switch (what) {
+ case ISIC_WHAT_ISAC:
+ bus_space_write_1(t, h, ASI_OFF_ALE, IPAC_ISAC_OFF);
+ bus_space_write_multi_1(t, h, ASI_OFF_RW, (u_int8_t*)buf,size);
+ break;
+ case ISIC_WHAT_HSCXA:
+ bus_space_write_1(t, h, ASI_OFF_ALE, IPAC_HSCXA_OFF);
+ bus_space_write_multi_1(t, h, ASI_OFF_RW, (u_int8_t*)buf,size);
+ break;
+ case ISIC_WHAT_HSCXB:
+ bus_space_write_1(t, h, ASI_OFF_ALE, IPAC_HSCXB_OFF);
+ bus_space_write_multi_1(t, h, ASI_OFF_RW, (u_int8_t*)buf,size);
+ break;
+ }
+}
+#endif
+
+/*---------------------------------------------------------------------------*
+ * Asuscom ISDNlink 128K PnP ISAC put register routine
+ *---------------------------------------------------------------------------*/
+#ifdef __FreeBSD__
+
+static void
+asi_write_reg(u_char *base, u_int offset, u_int v)
+{
+ u_int asus_base;
+
+ asus_base = ((u_int) base) & ASI_BASE_MASK;
+ switch (((u_int) base) & ASI_OFF_MASK) {
+ case ASI_IDHSCXB:
+ outb(asus_base + ASI_OFF_ALE, (u_char)(offset+IPAC_HSCXB_OFF));
+ outb(asus_base + ASI_OFF_RW, (u_char)v);
+ break;
+ case ASI_IDHSCXA:
+ outb(asus_base + ASI_OFF_ALE, (u_char)(offset+IPAC_HSCXA_OFF));
+ outb(asus_base + ASI_OFF_RW, (u_char)v);
+ break;
+ case ASI_IDISAC:
+ outb(asus_base + ASI_OFF_ALE, (u_char)(offset+IPAC_ISAC_OFF));
+ outb(asus_base + ASI_OFF_RW, (u_char)v);
+ break;
+ case ASI_IDIPAC:
+ outb(asus_base + ASI_OFF_ALE, (u_char)(offset+IPAC_IPAC_OFF));
+ outb(asus_base + ASI_OFF_RW, (u_char)v);
+ break;
+ }
+}
+
+#else
+
+static void
+asi_write_reg(struct isic_softc *sc,
+ int what, bus_size_t offs, u_int8_t data)
+{
+ bus_space_tag_t t = sc->sc_maps[1].t;
+ bus_space_handle_t h = sc->sc_maps[1].h;
+ switch (what) {
+ case ISIC_WHAT_ISAC:
+ bus_space_write_1(t, h, ASI_OFF_ALE, IPAC_ISAC_OFF+offs);
+ bus_space_write_1(t, h, ASI_OFF_RW, data);
+ break;
+ case ISIC_WHAT_HSCXA:
+ bus_space_write_1(t, h, ASI_OFF_ALE, IPAC_HSCXA_OFF+offs);
+ bus_space_write_1(t, h, ASI_OFF_RW, data);
+ break;
+ case ISIC_WHAT_HSCXB:
+ bus_space_write_1(t, h, ASI_OFF_ALE, IPAC_HSCXB_OFF+offs);
+ bus_space_write_1(t, h, ASI_OFF_RW, data);
+ break;
+ case ISIC_WHAT_IPAC:
+ bus_space_write_1(t, h, ASI_OFF_ALE, IPAC_IPAC_OFF+offs);
+ bus_space_write_1(t, h, ASI_OFF_RW, data);
+ break;
+ }
+}
+#endif
+
+/*---------------------------------------------------------------------------*
+ * Asuscom ISDNlink 128K PnP ISAC get register routine
+ *---------------------------------------------------------------------------*/
+#ifdef __FreeBSD__
+
+static u_char
+asi_read_reg(u_char *base, u_int offset)
+{
+ u_int asus_base;
+
+ asus_base = ((u_int) base) & ASI_BASE_MASK;
+ switch (((u_int) base) & ASI_OFF_MASK) {
+ case ASI_IDHSCXB:
+ outb(asus_base + ASI_OFF_ALE, (u_char)(offset+IPAC_HSCXB_OFF));
+ return(inb(asus_base + ASI_OFF_RW));
+ case ASI_IDHSCXA:
+ outb(asus_base + ASI_OFF_ALE, (u_char)(offset+IPAC_HSCXA_OFF));
+ return(inb(asus_base + ASI_OFF_RW));
+ case ASI_IDISAC:
+ outb(asus_base + ASI_OFF_ALE, (u_char)(offset+IPAC_ISAC_OFF));
+ return(inb(asus_base + ASI_OFF_RW));
+ case ASI_IDIPAC:
+ outb(asus_base + ASI_OFF_ALE, (u_char)(offset+IPAC_IPAC_OFF));
+ return(inb(asus_base + ASI_OFF_RW));
+ }
+
+ return 0; /* NOTREACHED */
+}
+
+#else
+
+static u_int8_t
+asi_read_reg(struct isic_softc *sc, int what, bus_size_t offs)
+{
+ bus_space_tag_t t = sc->sc_maps[1].t;
+ bus_space_handle_t h = sc->sc_maps[1].h;
+ switch (what) {
+ case ISIC_WHAT_ISAC:
+ bus_space_write_1(t, h, ASI_OFF_ALE, IPAC_ISAC_OFF+offs);
+ return bus_space_read_1(t, h, ASI_OFF_RW);
+ case ISIC_WHAT_HSCXA:
+ bus_space_write_1(t, h, ASI_OFF_ALE, IPAC_HSCXA_OFF+offs);
+ return bus_space_read_1(t, h, ASI_OFF_RW);
+ case ISIC_WHAT_HSCXB:
+ bus_space_write_1(t, h, ASI_OFF_ALE, IPAC_HSCXB_OFF+offs);
+ return bus_space_read_1(t, h, ASI_OFF_RW);
+ case ISIC_WHAT_IPAC:
+ bus_space_write_1(t, h, ASI_OFF_ALE, IPAC_IPAC_OFF+offs);
+ return bus_space_read_1(t, h, ASI_OFF_RW);
+ }
+
+ return 0;
+}
+
+#endif
+
+/*---------------------------------------------------------------------------*
+ * isic_attach_asi - attach for Asuscom ISDNlink 128K PnP
+ *---------------------------------------------------------------------------*/
+#ifdef __FreeBSD__
+int
+isic_probe_asi(struct isa_device *dev, unsigned int iobase2)
+{
+ struct isic_softc *sc = &isic_sc[dev->id_unit];
+
+ /* check max unit range */
+
+ if(dev->id_unit >= ISIC_MAXUNIT)
+ {
+ printf("isic%d: Error, unit %d >= ISIC_MAXUNIT "
+ "for Asuscom ISDNlink 128K PnP!\n",
+ dev->id_unit, dev->id_unit);
+
+ return(0);
+ }
+ sc->sc_unit = dev->id_unit;
+
+ /* setup iobase */
+
+ if((dev->id_iobase <= 0) || (dev->id_iobase > 0xffff))
+ {
+ printf("isic%d: Error, invalid iobase 0x%x specified "
+ "for Asuscom ISDNlink 128K PnP\n",
+ dev->id_unit, iobase2);
+
+ return(0);
+ }
+
+ sc->sc_port = dev->id_iobase;
+
+ /* setup access routines */
+
+ sc->clearirq = NULL;
+ sc->readreg = asi_read_reg;
+ sc->writereg = asi_write_reg;
+
+ sc->readfifo = asi_read_fifo;
+ sc->writefifo = asi_write_fifo;
+
+ /* setup card type */
+
+ sc->sc_cardtyp = CARD_TYPEP_ASUSCOMIPAC;
+
+ /* setup IOM bus type */
+
+ sc->sc_bustyp = BUS_TYPE_IOM2;
+
+ /* setup chip type = IPAC ! */
+
+ sc->sc_ipac = 1;
+ sc->sc_bfifolen = IPAC_BFIFO_LEN;
+
+ /* setup ISAC and HSCX base addr */
+
+ ISAC_BASE = (caddr_t) ((u_int)dev->id_iobase | ASI_IDISAC);
+ HSCX_A_BASE = (caddr_t) ((u_int)dev->id_iobase | ASI_IDHSCXA);
+ HSCX_B_BASE = (caddr_t) ((u_int)dev->id_iobase | ASI_IDHSCXB);
+ IPAC_BASE = (caddr_t) ((u_int)dev->id_iobase | ASI_IDIPAC);
+
+ return (1);
+}
+
+int
+isic_attach_asi(struct isa_device *dev, unsigned int iobase2)
+{
+ struct isic_softc *sc = &isic_sc[dev->id_unit];
+ /* enable hscx/isac irq's */
+#if 0
+/*
+ * This is for ELSA driver
+ */
+ IPAC_WRITE(IPAC_MASK, (IPAC_MASK_INT1 | IPAC_MASK_INT0));
+
+ IPAC_WRITE(IPAC_ACFG, 0); /* outputs are open drain */
+ IPAC_WRITE(IPAC_AOE, /* aux 5..2 are inputs, 7, 6 outputs */
+ (IPAC_AOE_OE5 | IPAC_AOE_OE4 | IPAC_AOE_OE3 | IPAC_AOE_OE2));
+ IPAC_WRITE(IPAC_ATX, 0xff); /* set all output lines high */
+
+ outb(dev->id_iobase + 0x4c, 0x41); /* enable card interrupt */
+#endif
+/*
+ * This has been taken from Linux driver.
+ * XXX Figure out bits to use defines as original driver did.
+ */
+ IPAC_WRITE (IPAC_CONF, 0x0);
+ IPAC_WRITE (IPAC_ACFG, 0xff);
+ IPAC_WRITE (IPAC_AOE, 0x0);
+ IPAC_WRITE (IPAC_MASK, 0xc0);
+ IPAC_WRITE (IPAC_PCFG, 0x12);
+
+ return (1);
+}
+
+#else /* !FreeBSD */
+
+void
+isic_attach_asi(psc, pa)
+ struct pci_isic_softc *psc;
+ struct pci_attach_args *pa;
+{
+ struct isic_softc *sc = &psc->sc_isic;
+
+ /* setup io mappings */
+ sc->sc_num_mappings = 2;
+ MALLOC_MAPS(sc);
+ sc->sc_maps[0].size = 0;
+ if (pci_mapreg_map(pa, ASI_PORT0_MAPOFF, PCI_MAPREG_TYPE_IO, 0,
+ &sc->sc_maps[0].t, &sc->sc_maps[0].h, NULL, NULL)) {
+ printf("%s: can't map i/o space\n", sc->sc_dev.dv_xname);
+ return;
+ }
+ sc->sc_maps[1].size = 0;
+ if (pci_mapreg_map(pa, ASI_PORT1_MAPOFF, PCI_MAPREG_TYPE_IO, 0,
+ &sc->sc_maps[1].t, &sc->sc_maps[1].h, NULL, NULL)) {
+ printf("%s: can't map i/o space\n", sc->sc_dev.dv_xname);
+ return;
+ }
+
+ /* setup access routines */
+
+ sc->clearirq = NULL;
+ sc->readreg = asi_read_reg;
+ sc->writereg = asi_write_reg;
+
+ sc->readfifo = asi_read_fifo;
+ sc->writefifo = asi_write_fifo;
+
+ /* setup card type */
+
+ sc->sc_cardtyp = CARD_TYPEP_ASUSCOMIPAC;
+
+ /* setup IOM bus type */
+
+ sc->sc_bustyp = BUS_TYPE_IOM2;
+
+ /* setup chip type = IPAC ! */
+
+ sc->sc_ipac = 1;
+ sc->sc_bfifolen = IPAC_BFIFO_LEN;
+
+#if 0
+/*
+ * This for ELSA card in original driver.
+ */
+ /* enable hscx/isac irq's */
+ IPAC_WRITE(IPAC_MASK, (IPAC_MASK_INT1 | IPAC_MASK_INT0));
+
+ IPAC_WRITE(IPAC_ACFG, 0); /* outputs are open drain */
+ IPAC_WRITE(IPAC_AOE, /* aux 5..2 are inputs, 7, 6 outputs */
+ (IPAC_AOE_OE5 | IPAC_AOE_OE4 | IPAC_AOE_OE3 | IPAC_AOE_OE2));
+ IPAC_WRITE(IPAC_ATX, 0xff); /* set all output lines high */
+
+ bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, 0x4c, 0x41); /* enable card interrupt */
+#endif
+/*
+ * This has been taken from Linux driver.
+ * XXX Figure out bits to use defines as original driver did.
+ */
+ IPAC_WRITE (IPAC_CONF, 0x0);
+ IPAC_WRITE (IPAC_ACFG, 0xff);
+ IPAC_WRITE (IPAC_AOE, 0x0);
+ IPAC_WRITE (IPAC_MASK, 0xc0);
+ IPAC_WRITE (IPAC_PCFG, 0x12);
+}
+
+
+#endif
+
+#endif /* (NISIC > 0) && defined(ASUSCOM_IPAC) */
diff --git a/sys/i4b/layer1/i4b_avm_fritz_pci.c b/sys/i4b/layer1/i4b_avm_fritz_pci.c
index 2da4f89..c5f2d8a 100644
--- a/sys/i4b/layer1/i4b_avm_fritz_pci.c
+++ b/sys/i4b/layer1/i4b_avm_fritz_pci.c
@@ -35,9 +35,9 @@
* Fritz!Card PCI specific routines for isic driver
* ------------------------------------------------
*
- * $Id: i4b_avm_fritz_pci.c,v 1.5 1999/05/05 11:50:21 hm Exp $
+ * $Id: i4b_avm_fritz_pci.c,v 1.6 1999/06/01 12:10:25 hm Exp $
*
- * last edit-date: [Tue Mar 16 16:18:35 1999]
+ * last edit-date: [Tue Jun 1 14:08:01 1999]
*
*---------------------------------------------------------------------------*/
@@ -390,30 +390,31 @@ avma1pp_write_fifo(void *base, const void *buf, size_t len)
}
/* tell the board to use the ISAC fifo */
outb(sc->sc_port + ADDR_REG_OFFSET, ISAC_FIFO);
- outsb(sc->sc_port + ISAC_REG_OFFSET, (u_char *)buf, len);
+ outsb(sc->sc_port + ISAC_REG_OFFSET, (const u_char *)buf, len);
}
static void
hscx_write_fifo(int chan, const void *buf, size_t len, struct isic_softc *sc)
{
- register u_int *ip;
+ register const u_int *ip;
register size_t cnt;
isic_Bchan_t *Bchan = &sc->sc_chan[chan];
sc->avma1pp_cmd &= ~HSCX_CMD_XME;
sc->avma1pp_txl = 0;
- if (len != sc->sc_bfifolen)
+ if (Bchan->out_mbuf_cur == NULL)
{
if (Bchan->bprot != BPROT_NONE)
sc->avma1pp_cmd |= HSCX_CMD_XME;
- sc->avma1pp_txl = len;
}
-
+ if (len != sc->sc_bfifolen)
+ sc->avma1pp_txl = len;
+
cnt = 0; /* borrow cnt */
AVMA1PPSETCMDLONG(cnt);
hscx_write_reg(chan, HSCX_STAT, cnt, sc);
- ip = (u_int *)buf;
+ ip = (const u_int *)buf;
cnt = 0;
while (cnt < len)
{
@@ -450,12 +451,13 @@ hscx_write_fifo(int chan, const void *buf, size_t len, struct isic_softc *sc)
sc->avma1pp_cmd &= ~HSCX_CMD_XME;
sc->avma1pp_txl = 0;
- if (len != sc->sc_bfifolen)
+ if (Bchan->out_mbuf_cur == NULL)
{
if (Bchan->bprot != BPROT_NONE)
sc->avma1pp_cmd |= HSCX_CMD_XME;
- sc->avma1pp_txl = len;
}
+ if (len != sc->sc_bfifolen)
+ sc->avma1pp_txl = len;
cnt = 0; /* borrow cnt */
AVMA1PPSETCMDLONG(cnt);
@@ -492,7 +494,7 @@ avma1pp_write_reg(u_char *base, u_int offset, u_int v)
hscx_write_reg(0, offset, v, sc);
return;
}
- if (((int)base & IS_HSCX_MASK) == HSCX0FAKE)
+ if (((int)base & IS_HSCX_MASK) == HSCX1FAKE)
{
hscx_write_reg(1, offset, v, sc);
return;
diff --git a/sys/i4b/layer1/i4b_avm_fritz_pnp.c b/sys/i4b/layer1/i4b_avm_fritz_pnp.c
new file mode 100644
index 0000000..6da4969
--- /dev/null
+++ b/sys/i4b/layer1/i4b_avm_fritz_pnp.c
@@ -0,0 +1,1268 @@
+/*
+ * Copyright (c) 1999 Udo Schweigert. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ * 4. Altered versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software and/or documentation.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *---------------------------------------------------------------------------
+ * A lot of code was borrowed from i4b_bchan.c and i4b_hscx.c
+ * Based on AVM Fritz!PCI driver by Gary Jennejohn
+ *---------------------------------------------------------------------------
+ * In case of trouble please contact Udo Schweigert <ust@cert.siemens.de>
+ *---------------------------------------------------------------------------
+ *
+ * Fritz!Card PnP specific routines for isic driver
+ * ------------------------------------------------
+ *
+ * $Id: i4b_avm_fritz_pnp.c,v 1.3 1999/07/05 13:22:12 hm Exp $
+ *
+ * last edit-date: [Thu 10 Jun 08:50:28 CEST 1999]
+ *
+ *---------------------------------------------------------------------------*/
+
+#if defined(__FreeBSD__)
+#include "isic.h"
+#include "opt_i4b.h"
+
+#if NISIC > 0 && defined(AVM_PNP)
+
+#include <sys/param.h>
+#if defined(__FreeBSD__) && __FreeBSD__ >= 3
+#include <sys/ioccom.h>
+#else
+#include <sys/ioctl.h>
+#endif
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/mbuf.h>
+
+#include <machine/clock.h>
+#include <i386/isa/isa_device.h>
+
+#include <sys/socket.h>
+#include <net/if.h>
+
+#include <machine/i4b_debug.h>
+#include <machine/i4b_ioctl.h>
+
+#include <i4b/include/i4b_global.h>
+#include <i4b/include/i4b_l1l2.h>
+#include <i4b/include/i4b_mbuf.h>
+
+#include <i4b/layer1/i4b_l1.h>
+#include <i4b/layer1/i4b_isac.h>
+#include <i4b/layer1/i4b_hscx.h>
+
+static void hscx_write_reg(int, u_int, struct isic_softc *, int);
+static void hscx_write_reg_val(int, u_int, u_char, struct isic_softc *);
+static u_char hscx_read_reg(int, u_int, struct isic_softc *);
+static void hscx_read_fifo(int, void *, size_t, struct isic_softc *);
+static void hscx_write_fifo(int, const void *, size_t, struct isic_softc *);
+static void avm_pnp_hscx_int_handler(struct isic_softc *);
+static void avm_pnp_hscx_intr(int, int, int, struct isic_softc *);
+static void avm_pnp_init_linktab(struct isic_softc *);
+static void avm_pnp_bchannel_setup(int, int, int, int);
+static void avm_pnp_bchannel_start(int, int);
+static void avm_pnp_hscx_init(struct isic_softc *, int, int);
+static void avm_pnp_bchannel_stat(int, int, bchan_statistics_t *);
+static void avm_pnp_set_linktab(int, int, drvr_link_t *);
+static void avm_pnp_intr(int);
+static isdn_link_t * avm_pnp_ret_linktab(int, int);
+extern void isicintr_sc(struct isic_softc *);
+
+/*---------------------------------------------------------------------------*
+ * AVM PnP Fritz!Card special registers
+ *---------------------------------------------------------------------------*/
+
+/*
+ * register offsets from i/o base
+ */
+#define STAT0_OFFSET 0x02
+#define STAT1_OFFSET 0x03
+#define ADDR_REG_OFFSET 0x04
+
+/* these 2 are used to select an ISAC register set */
+#define ISAC_LO_REG_OFFSET 0x04
+#define ISAC_HI_REG_OFFSET 0x06
+
+/* offset higher than this goes to the HI register set */
+#define MAX_LO_REG_OFFSET 0x2f
+
+/* mask for the offset */
+#define ISAC_REGSET_MASK 0x0f
+
+/* the offset from the base to the ISAC registers */
+#define ISAC_REG_OFFSET 0x10
+
+/* the offset from the base to the ISAC FIFO */
+#define ISAC_FIFO 0x02
+
+/* not really the HSCX, but sort of */
+#define HSCX_FIFO 0x00
+#define HSCX_STAT 0x04
+
+/*
+ * AVM PnP Status Latch 0 read only bits
+ */
+#define ASL_IRQ_ISAC 0x01 /* ISAC interrupt, active low */
+#define ASL_IRQ_HSCX 0x02 /* HSX interrupt, active low */
+#define ASL_IRQ_TIMER 0x04 /* Timer interrupt, active low */
+#define ASL_IRQ_BCHAN ASL_IRQ_HSCX
+/* actually active LOW */
+#define ASL_IRQ_Pending 0x07
+
+/*
+ * AVM Status Latch 0 write only bits
+ */
+#define ASL_RESET_ALL 0x01 /* reset siemens IC's, active 1 */
+#define ASL_TIMERDISABLE 0x02 /* active high */
+#define ASL_TIMERRESET 0x04 /* active high */
+#define ASL_ENABLE_INT 0x08 /* active high */
+#define ASL_TESTBIT 0x10 /* active high */
+
+/*
+ * AVM Status Latch 1 write only bits
+ */
+#define ASL1_INTSEL 0x0f /* active high */
+#define ASL1_ENABLE_IOM 0x80 /* active high */
+
+/*
+ * "HSCX" mode bits
+ */
+#define HSCX_MODE_ITF_FLG 0x01
+#define HSCX_MODE_TRANS 0x02
+#define HSCX_MODE_CCR_7 0x04
+#define HSCX_MODE_CCR_16 0x08
+#define HSCX_MODE_TESTLOOP 0x80
+
+/*
+ * "HSCX" status bits
+ */
+#define HSCX_STAT_RME 0x01
+#define HSCX_STAT_RDO 0x10
+#define HSCX_STAT_CRCVFRRAB 0x0E
+#define HSCX_STAT_CRCVFR 0x06
+#define HSCX_STAT_RML_MASK 0x3f00
+
+/*
+ * "HSCX" interrupt bits
+ */
+#define HSCX_INT_XPR 0x80
+#define HSCX_INT_XDU 0x40
+#define HSCX_INT_RPR 0x20
+#define HSCX_INT_MASK 0xE0
+
+/*
+ * "HSCX" command bits
+ */
+#define HSCX_CMD_XRS 0x80
+#define HSCX_CMD_XME 0x01
+#define HSCX_CMD_RRS 0x20
+#define HSCX_CMD_XML_MASK 0x3f00
+
+/* "fake" addresses for the non-existent HSCX */
+/* note: the unit number is in the lower byte for both the ISAC and "HSCX" */
+#define HSCX0FAKE 0xfa000 /* read: fake0 */
+#define HSCX1FAKE 0xfa100 /* read: fake1 */
+#define IS_HSCX_MASK 0xfff00
+
+/*
+ * to prevent deactivating the "HSCX" when both channels are active we
+ * define an HSCX_ACTIVE flag which is or'd into the channel's state
+ * flag in avm_pnp_bchannel_setup upon active and cleared upon deactivation.
+ * It is set high to allow room for new flags.
+ */
+#define HSCX_AVMPNP_ACTIVE 0x1000
+
+/*---------------------------------------------------------------------------*
+ * AVM read fifo routines
+ *---------------------------------------------------------------------------*/
+
+static void
+avm_pnp_read_fifo(void *buf, const void *base, size_t len)
+{
+ int unit;
+ struct isic_softc *sc;
+
+ unit = (int)base & 0xff;
+ sc = &isic_sc[unit];
+
+ /* check whether the target is an HSCX */
+ if (((int)base & IS_HSCX_MASK) == HSCX0FAKE)
+ {
+ hscx_read_fifo(0, buf, len, sc);
+ return;
+ }
+ if (((int)base & IS_HSCX_MASK) == HSCX1FAKE)
+ {
+ hscx_read_fifo(1, buf, len, sc);
+ return;
+ }
+ /* tell the board to access the ISAC fifo */
+ outb(sc->sc_port + ADDR_REG_OFFSET, ISAC_FIFO);
+ insb(sc->sc_port + ISAC_REG_OFFSET, (u_char *)buf, len);
+}
+
+static void
+hscx_read_fifo(int chan, void *buf, size_t len, struct isic_softc *sc)
+{
+ u_char *ip;
+ size_t cnt;
+
+ outb(sc->sc_port + ADDR_REG_OFFSET, chan);
+ ip = (u_char *)buf;
+ cnt = 0;
+
+ while (cnt < len)
+ {
+ *ip++ = inb(sc->sc_port + ISAC_REG_OFFSET);
+ cnt++;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * AVM write fifo routines
+ *---------------------------------------------------------------------------*/
+static void
+avm_pnp_write_fifo(void *base, const void *buf, size_t len)
+{
+ int unit;
+ struct isic_softc *sc;
+
+ unit = (int)base & 0xff;
+ sc = &isic_sc[unit];
+
+ /* check whether the target is an HSCX */
+ if (((int)base & IS_HSCX_MASK) == HSCX0FAKE)
+ {
+ hscx_write_fifo(0, buf, len, sc);
+ return;
+ }
+ if (((int)base & IS_HSCX_MASK) == HSCX1FAKE)
+ {
+ hscx_write_fifo(1, buf, len, sc);
+ return;
+ }
+ /* tell the board to use the ISAC fifo */
+ outb(sc->sc_port + ADDR_REG_OFFSET, ISAC_FIFO);
+ outsb(sc->sc_port + ISAC_REG_OFFSET, (const u_char *)buf, len);
+}
+
+static void
+hscx_write_fifo(int chan, const void *buf, size_t len, struct isic_softc *sc)
+{
+ register const u_char *ip;
+ register size_t cnt;
+ isic_Bchan_t *Bchan = &sc->sc_chan[chan];
+
+ sc->avma1pp_cmd &= ~HSCX_CMD_XME;
+ sc->avma1pp_txl = 0;
+
+ if (Bchan->out_mbuf_cur == NULL && Bchan->bprot != BPROT_NONE)
+ sc->avma1pp_cmd |= HSCX_CMD_XME;
+
+ if (len != sc->sc_bfifolen)
+ sc->avma1pp_txl = len;
+
+ hscx_write_reg(chan, HSCX_STAT, sc, 3);
+
+ ip = (const u_char *)buf;
+ cnt = 0;
+ while (cnt < len)
+ {
+ outb(sc->sc_port + ISAC_REG_OFFSET, *ip++);
+ cnt++;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * AVM write register routines
+ *---------------------------------------------------------------------------*/
+static void
+avm_pnp_write_reg(u_char *base, u_int offset, u_int v)
+{
+ int unit;
+ struct isic_softc *sc;
+ u_char reg_bank;
+
+ unit = (int)base & 0xff;
+ sc = &isic_sc[unit];
+
+ /* check whether the target is an HSCX */
+ if (((int)base & IS_HSCX_MASK) == HSCX0FAKE)
+ {
+ hscx_write_reg_val(0, offset, v, sc);
+ return;
+ }
+ if (((int)base & IS_HSCX_MASK) == HSCX1FAKE)
+ {
+ hscx_write_reg_val(1, offset, v, sc);
+ return;
+ }
+ /* must be the ISAC */
+ reg_bank = (offset > MAX_LO_REG_OFFSET) ? ISAC_HI_REG_OFFSET:ISAC_LO_REG_OFFSET;
+ /* set the register bank */
+ outb(sc->sc_port + ADDR_REG_OFFSET, reg_bank);
+ outb(sc->sc_port + ISAC_REG_OFFSET + (offset & ISAC_REGSET_MASK), v);
+}
+
+static void
+hscx_write_reg(int chan, u_int off, struct isic_softc *sc, int which)
+{
+ /* HACK */
+ if (off == H_MASK)
+ return;
+ /* point at the correct channel */
+ outb(sc->sc_port + ADDR_REG_OFFSET, chan);
+ if (which & 4)
+ outb(sc->sc_port + ISAC_REG_OFFSET + off + 2, sc->avma1pp_prot);
+ if (which & 2)
+ outb(sc->sc_port + ISAC_REG_OFFSET + off + 1, sc->avma1pp_txl);
+ if (which & 1)
+ outb(sc->sc_port + ISAC_REG_OFFSET + off, sc->avma1pp_cmd);
+}
+
+static void
+hscx_write_reg_val(int chan, u_int off, u_char val, struct isic_softc *sc)
+{
+ /* HACK */
+ if (off == H_MASK)
+ return;
+ /* point at the correct channel */
+ outb(sc->sc_port + ADDR_REG_OFFSET, chan);
+ outb(sc->sc_port + ISAC_REG_OFFSET + off, val);
+}
+
+/*---------------------------------------------------------------------------*
+ * AVM read register routines
+ *---------------------------------------------------------------------------*/
+
+static u_char
+avm_pnp_read_reg(u_char *base, u_int offset)
+{
+ int unit;
+ struct isic_softc *sc;
+ u_char reg_bank;
+
+ unit = (int)base & 0xff;
+ sc = &isic_sc[unit];
+
+ /* check whether the target is an HSCX */
+ if (((int)base & IS_HSCX_MASK) == HSCX0FAKE)
+ return(hscx_read_reg(0, offset, sc));
+ if (((int)base & IS_HSCX_MASK) == HSCX1FAKE)
+ return(hscx_read_reg(1, offset, sc));
+ /* must be the ISAC */
+ reg_bank = (offset > MAX_LO_REG_OFFSET) ? ISAC_HI_REG_OFFSET:ISAC_LO_REG_OFFSET;
+ /* set the register bank */
+ outb(sc->sc_port + ADDR_REG_OFFSET, reg_bank);
+ return(inb(sc->sc_port + ISAC_REG_OFFSET +
+ (offset & ISAC_REGSET_MASK)));
+}
+
+static u_char
+hscx_read_reg(int chan, u_int off, struct isic_softc *sc)
+{
+ /* HACK */
+ if (off == H_ISTA)
+ return(0);
+ /* point at the correct channel */
+ outb(sc->sc_port + ADDR_REG_OFFSET, chan);
+ return(inb(sc->sc_port + ISAC_REG_OFFSET + off));
+}
+
+/*---------------------------------------------------------------------------*
+ * isic_probe_avm_pnp - probe Fritz!Card PnP
+ *---------------------------------------------------------------------------*/
+
+int
+isic_probe_avm_pnp(struct isa_device *dev, unsigned int iobase2)
+{
+ struct isic_softc *sc = &isic_sc[dev->id_unit];
+
+ /* check max unit range */
+
+ if(dev->id_unit >= ISIC_MAXUNIT)
+ {
+ printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for AVM Fritz! PnP\n",
+ dev->id_unit, dev->id_unit);
+ return(0);
+ }
+ sc->sc_unit = dev->id_unit;
+
+ /* check IRQ validity */
+
+ switch(ffs(dev->id_irq) - 1)
+ {
+ case 3:
+ case 4:
+ case 5:
+ case 7:
+ case 10:
+ case 11:
+ case 12:
+ case 15:
+ break;
+
+ default:
+ printf("isic%d: Error, invalid IRQ [%d] specified for AVM Fritz! PnP!\n",
+ dev->id_unit, ffs(dev->id_irq)-1);
+ return(0);
+ break;
+ }
+ sc->sc_irq = dev->id_irq;
+
+ dev->id_intr = (inthand2_t *) avm_pnp_intr;
+
+ /* check if memory addr specified */
+
+ if(dev->id_maddr)
+ {
+ printf("isic%d: Error, mem addr 0x%lx specified for AVM Fritz! PnP!\n",
+ dev->id_unit, (u_long)dev->id_maddr);
+ return(0);
+ }
+ dev->id_msize = 0;
+
+ /* check if we got an iobase */
+
+ if(!((dev->id_iobase >= 0x160) && (dev->id_iobase <= 0x360)))
+ {
+ printf("isic%d: Error, invalid iobase 0x%x specified for AVM Fritz! PnP!\n",
+ dev->id_unit, dev->id_iobase);
+ return(0);
+ }
+ sc->sc_port = dev->id_iobase;
+
+
+ /* setup access routines */
+
+ sc->clearirq = NULL;
+ sc->readreg = avm_pnp_read_reg;
+ sc->writereg = avm_pnp_write_reg;
+
+ sc->readfifo = avm_pnp_read_fifo;
+ sc->writefifo = avm_pnp_write_fifo;
+
+ /* setup card type */
+
+ sc->sc_cardtyp = CARD_TYPEP_AVM_PNP;
+
+ /* setup IOM bus type */
+
+ sc->sc_bustyp = BUS_TYPE_IOM2;
+
+ sc->sc_ipac = 0;
+ sc->sc_bfifolen = HSCX_FIFO_LEN;
+
+ /* the ISAC lives at offset 0x10, but we can't use that. */
+ /* instead, put the unit number into the lower byte - HACK */
+ ISAC_BASE = (caddr_t)((int)(dev->id_iobase & ~0xff) + dev->id_unit);
+
+ outb(sc->sc_port + STAT0_OFFSET, ASL_RESET_ALL|ASL_TIMERDISABLE);
+ ISAC_WRITE(I_MASK, 0x0);
+ outb(sc->sc_port + STAT0_OFFSET, ASL_TIMERRESET|ASL_ENABLE_INT|ASL_TIMERDISABLE);
+ ISAC_WRITE(I_MASK, 0x41);
+ return (1);
+}
+
+/*---------------------------------------------------------------------------*
+ * isic_attach_avm_pnp - attach Fritz!Card PnP
+ *---------------------------------------------------------------------------*/
+int
+isic_attach_avm_pnp(struct isa_device *dev, unsigned int iobase2)
+{
+ struct isic_softc *sc;
+ u_int v;
+ int unit;
+
+ unit = dev->id_unit;
+ sc = &isic_sc[unit];
+
+ /* this thing doesn't have an HSCX, so fake the base addresses */
+ /* put the unit number into the lower byte - HACK */
+ HSCX_A_BASE = (caddr_t)(HSCX0FAKE + unit);
+ HSCX_B_BASE = (caddr_t)(HSCX1FAKE + unit);
+
+
+ /* reset the card */
+
+ /* the Linux driver does this to clear any pending ISAC interrupts */
+ v = 0;
+ v = ISAC_READ(I_STAR);
+ v = ISAC_READ(I_MODE);
+ v = ISAC_READ(I_ADF2);
+ v = ISAC_READ(I_ISTA);
+ if (v & ISAC_ISTA_EXI)
+ {
+ v = ISAC_READ(I_EXIR);
+ }
+ v = ISAC_READ(I_CIRR);
+ ISAC_WRITE(I_MASK, 0xff);
+
+ /* the Linux driver does this to clear any pending HSCX interrupts */
+ v = hscx_read_reg(0, HSCX_STAT, sc);
+ v = hscx_read_reg(0, HSCX_STAT+1, sc);
+ v = hscx_read_reg(0, HSCX_STAT+2, sc);
+ v = hscx_read_reg(0, HSCX_STAT+3, sc);
+ v = hscx_read_reg(1, HSCX_STAT, sc);
+ v = hscx_read_reg(1, HSCX_STAT+1, sc);
+ v = hscx_read_reg(1, HSCX_STAT+2, sc);
+ v = hscx_read_reg(1, HSCX_STAT+3, sc);
+
+ outb(sc->sc_port + STAT0_OFFSET, ASL_RESET_ALL|ASL_TIMERDISABLE);
+ DELAY(SEC_DELAY/100); /* 10 ms */
+ outb(sc->sc_port + STAT0_OFFSET, ASL_TIMERRESET|ASL_ENABLE_INT|ASL_TIMERDISABLE);
+ DELAY(SEC_DELAY/100); /* 10 ms */
+ outb(sc->sc_port + STAT1_OFFSET, ASL1_ENABLE_IOM+(ffs(sc->sc_irq)-1));
+ DELAY(SEC_DELAY/100); /* 10 ms */
+
+ printf("isic%d: ISAC %s (IOM-%c)\n", unit,
+ "2085 Version A1/A2 or 2086/2186 Version 1.1",
+ sc->sc_bustyp == BUS_TYPE_IOM1 ? '1' : '2');
+
+ /* init the ISAC */
+ isic_isac_init(sc);
+
+ /* init the "HSCX" */
+ avm_pnp_bchannel_setup(sc->sc_unit, HSCX_CH_A, BPROT_NONE, 0);
+
+ avm_pnp_bchannel_setup(sc->sc_unit, HSCX_CH_B, BPROT_NONE, 0);
+
+ /* can't use the normal B-Channel stuff */
+ avm_pnp_init_linktab(sc);
+
+ /* set trace level */
+
+ sc->sc_trace = TRACE_OFF;
+
+ sc->sc_state = ISAC_IDLE;
+
+ sc->sc_ibuf = NULL;
+ sc->sc_ib = NULL;
+ sc->sc_ilen = 0;
+
+ sc->sc_obuf = NULL;
+ sc->sc_op = NULL;
+ sc->sc_ol = 0;
+ sc->sc_freeflag = 0;
+
+ sc->sc_obuf2 = NULL;
+ sc->sc_freeflag2 = 0;
+
+#if defined(__FreeBSD__) && __FreeBSD__ >=3
+ callout_handle_init(&sc->sc_T3_callout);
+ callout_handle_init(&sc->sc_T4_callout);
+#endif
+
+ /* init higher protocol layers */
+
+ MPH_Status_Ind(sc->sc_unit, STI_ATTACH, sc->sc_cardtyp);
+
+ return(0);
+}
+
+/*
+ * this is the real interrupt routine
+ */
+static void
+avm_pnp_hscx_intr(int h_chan, int stat, int cnt, struct isic_softc *sc)
+{
+ register isic_Bchan_t *chan = &sc->sc_chan[h_chan];
+ int activity = -1;
+
+ DBGL1(L1_H_IRQ, "avm_pnp_hscx_intr", ("%#x\n", stat));
+
+ if((stat & HSCX_INT_XDU) && (chan->bprot != BPROT_NONE))/* xmit data underrun */
+ {
+ chan->stat_XDU++;
+ DBGL1(L1_H_XFRERR, "avm_pnp_hscx_intr", ("xmit data underrun\n"));
+ /* abort the transmission */
+ sc->avma1pp_txl = 0;
+ sc->avma1pp_cmd |= HSCX_CMD_XRS;
+ hscx_write_reg(h_chan, HSCX_STAT, sc, 1);
+ sc->avma1pp_cmd &= ~HSCX_CMD_XRS;
+ hscx_write_reg(h_chan, HSCX_STAT, sc, 1);
+
+ if (chan->out_mbuf_head != NULL) /* don't continue to transmit this buffer */
+ {
+ i4b_Bfreembuf(chan->out_mbuf_head);
+ chan->out_mbuf_cur = chan->out_mbuf_head = NULL;
+ }
+ }
+
+ /*
+ * The following is based on examination of the Linux driver.
+ *
+ * The logic here is different than with a "real" HSCX; all kinds
+ * of information (interrupt/status bits) are in stat.
+ * HSCX_INT_RPR indicates a receive interrupt
+ * HSCX_STAT_RDO indicates an overrun condition, abort -
+ * otherwise read the bytes ((stat & HSCX_STZT_RML_MASK) >> 8)
+ * HSCX_STAT_RME indicates end-of-frame and apparently any
+ * CRC/framing errors are only reported in this state.
+ * if ((stat & HSCX_STAT_CRCVFRRAB) != HSCX_STAT_CRCVFR)
+ * CRC/framing error
+ */
+
+ if(stat & HSCX_INT_RPR)
+ {
+ register int fifo_data_len;
+ int error = 0;
+ /* always have to read the FIFO, so use a scratch buffer */
+ u_char scrbuf[HSCX_FIFO_LEN];
+
+ if(stat & HSCX_STAT_RDO)
+ {
+ chan->stat_RDO++;
+ DBGL1(L1_H_XFRERR, "avm_pnp_hscx_intr", ("receive data overflow\n"));
+ error++;
+ }
+
+ fifo_data_len = cnt;
+
+ if(fifo_data_len == 0)
+ fifo_data_len = sc->sc_bfifolen;
+
+ /* ALWAYS read data from HSCX fifo */
+
+ HSCX_RDFIFO(h_chan, scrbuf, fifo_data_len);
+ chan->rxcount += fifo_data_len;
+
+ /* all error conditions checked, now decide and take action */
+
+ if(error == 0)
+ {
+ if(chan->in_mbuf == NULL)
+ {
+ if((chan->in_mbuf = i4b_Bgetmbuf(BCH_MAX_DATALEN)) == NULL)
+ panic("L1 avm_pnp_hscx_intr: RME, cannot allocate mbuf!\n");
+ chan->in_cbptr = chan->in_mbuf->m_data;
+ chan->in_len = 0;
+ }
+
+ if((chan->in_len + fifo_data_len) <= BCH_MAX_DATALEN)
+ {
+ /* OK to copy the data */
+ bcopy(scrbuf, chan->in_cbptr, fifo_data_len);
+ chan->in_cbptr += fifo_data_len;
+ chan->in_len += fifo_data_len;
+
+ /* setup mbuf data length */
+
+ chan->in_mbuf->m_len = chan->in_len;
+ chan->in_mbuf->m_pkthdr.len = chan->in_len;
+
+
+ if(sc->sc_trace & TRACE_B_RX)
+ {
+ i4b_trace_hdr_t hdr;
+ hdr.unit = sc->sc_unit;
+ hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2);
+ hdr.dir = FROM_NT;
+ hdr.count = ++sc->sc_trace_bcount;
+ MICROTIME(hdr.time);
+ MPH_Trace_Ind(&hdr, chan->in_mbuf->m_len, chan->in_mbuf->m_data);
+ }
+
+ if (stat & HSCX_STAT_RME)
+ {
+ if((stat & HSCX_STAT_CRCVFRRAB) == HSCX_STAT_CRCVFR)
+ {
+ (*chan->drvr_linktab->bch_rx_data_ready)(chan->drvr_linktab->unit);
+ activity = ACT_RX;
+
+ /* mark buffer ptr as unused */
+
+ chan->in_mbuf = NULL;
+ chan->in_cbptr = NULL;
+ chan->in_len = 0;
+ }
+ else
+ {
+ chan->stat_CRC++;
+ DBGL1(L1_H_XFRERR, "avm_pnp_hscx_intr", ("CRC/RAB\n"));
+ if (chan->in_mbuf != NULL)
+ {
+ i4b_Bfreembuf(chan->in_mbuf);
+ chan->in_mbuf = NULL;
+ chan->in_cbptr = NULL;
+ chan->in_len = 0;
+ }
+ }
+ }
+ } /* END enough space in mbuf */
+ else
+ {
+ if(chan->bprot == BPROT_NONE)
+ {
+ /* setup mbuf data length */
+
+ chan->in_mbuf->m_len = chan->in_len;
+ chan->in_mbuf->m_pkthdr.len = chan->in_len;
+
+ if(sc->sc_trace & TRACE_B_RX)
+ {
+ i4b_trace_hdr_t hdr;
+ hdr.unit = sc->sc_unit;
+ hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2);
+ hdr.dir = FROM_NT;
+ hdr.count = ++sc->sc_trace_bcount;
+ MICROTIME(hdr.time);
+ MPH_Trace_Ind(&hdr, chan->in_mbuf->m_len, chan->in_mbuf->m_data);
+ }
+
+ /* move rx'd data to rx queue */
+
+ IF_ENQUEUE(&chan->rx_queue, chan->in_mbuf);
+
+ (*chan->drvr_linktab->bch_rx_data_ready)(chan->drvr_linktab->unit);
+
+ if(!(isic_hscx_silence(chan->in_mbuf->m_data, chan->in_mbuf->m_len)))
+ activity = ACT_RX;
+
+ /* alloc new buffer */
+
+ if((chan->in_mbuf = i4b_Bgetmbuf(BCH_MAX_DATALEN)) == NULL)
+ panic("L1 avm_pnp_hscx_intr: RPF, cannot allocate new mbuf!\n");
+
+ /* setup new data ptr */
+
+ chan->in_cbptr = chan->in_mbuf->m_data;
+
+ /* OK to copy the data */
+ bcopy(scrbuf, chan->in_cbptr, fifo_data_len);
+
+ chan->in_cbptr += fifo_data_len;
+ chan->in_len = fifo_data_len;
+
+ chan->rxcount += fifo_data_len;
+ }
+ else
+ {
+ DBGL1(L1_H_XFRERR, "avm_pnp_hscx_intr", ("RAWHDLC rx buffer overflow in RPF, in_len=%d\n", chan->in_len));
+ chan->in_cbptr = chan->in_mbuf->m_data;
+ chan->in_len = 0;
+ }
+ }
+ } /* if(error == 0) */
+ else
+ {
+ /* land here for RDO */
+ if (chan->in_mbuf != NULL)
+ {
+ i4b_Bfreembuf(chan->in_mbuf);
+ chan->in_mbuf = NULL;
+ chan->in_cbptr = NULL;
+ chan->in_len = 0;
+ }
+ sc->avma1pp_txl = 0;
+ sc->avma1pp_cmd |= HSCX_CMD_RRS;
+ hscx_write_reg(h_chan, HSCX_STAT, sc, 1);
+ sc->avma1pp_cmd &= ~HSCX_CMD_RRS;
+ hscx_write_reg(h_chan, HSCX_STAT, sc, 1);
+ }
+ }
+
+
+ /* transmit fifo empty, new data can be written to fifo */
+
+ if(stat & HSCX_INT_XPR)
+ {
+ /*
+ * for a description what is going on here, please have
+ * a look at isic_bchannel_start() in i4b_bchan.c !
+ */
+
+ DBGL1(L1_H_IRQ, "avm_pnp_hscx_intr", ("unit %d, chan %d - XPR, Tx Fifo Empty!\n", sc->sc_unit, h_chan));
+
+ if(chan->out_mbuf_cur == NULL || chan->out_mbuf_head == NULL) /* last frame is transmitted */
+ {
+ IF_DEQUEUE(&chan->tx_queue, chan->out_mbuf_head);
+
+ if(chan->out_mbuf_head == NULL)
+ {
+ chan->state &= ~HSCX_TX_ACTIVE;
+ (*chan->drvr_linktab->bch_tx_queue_empty)(chan->drvr_linktab->unit);
+ }
+ else
+ {
+ chan->state |= HSCX_TX_ACTIVE;
+ chan->out_mbuf_cur = chan->out_mbuf_head;
+ chan->out_mbuf_cur_ptr = chan->out_mbuf_cur->m_data;
+ chan->out_mbuf_cur_len = chan->out_mbuf_cur->m_len;
+
+ if(sc->sc_trace & TRACE_B_TX)
+ {
+ i4b_trace_hdr_t hdr;
+ hdr.unit = sc->sc_unit;
+ hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2);
+ hdr.dir = FROM_TE;
+ hdr.count = ++sc->sc_trace_bcount;
+ MICROTIME(hdr.time);
+ MPH_Trace_Ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data);
+ }
+ if(chan->bprot == BPROT_NONE)
+ {
+ if(!(isic_hscx_silence(chan->out_mbuf_cur->m_data, chan->out_mbuf_cur->m_len)))
+ activity = ACT_TX;
+ }
+ else
+ {
+ activity = ACT_TX;
+ }
+ }
+ }
+
+ isic_hscx_fifo(chan, sc);
+ }
+
+ /* call timeout handling routine */
+
+ if(activity == ACT_RX || activity == ACT_TX)
+ (*chan->drvr_linktab->bch_activity)(chan->drvr_linktab->unit, activity);
+}
+
+/*
+ * this is the main routine which checks each channel and then calls
+ * the real interrupt routine as appropriate
+ */
+static void
+avm_pnp_hscx_int_handler(struct isic_softc *sc)
+{
+ u_char stat = 0;
+ u_char cnt = 0;
+
+ stat = hscx_read_reg(0, HSCX_STAT, sc);
+ if (stat & HSCX_INT_RPR)
+ cnt = hscx_read_reg(0, HSCX_STAT+1, sc);
+ if (stat & HSCX_INT_MASK)
+ avm_pnp_hscx_intr(0, stat, cnt, sc);
+
+ cnt = 0;
+ stat = hscx_read_reg(1, HSCX_STAT, sc);
+ if (stat & HSCX_INT_RPR)
+ cnt = hscx_read_reg(1, HSCX_STAT+1, sc);
+ if (stat & HSCX_INT_MASK)
+ avm_pnp_hscx_intr(1, stat, cnt, sc);
+}
+
+static void
+avm_pnp_hscx_init(struct isic_softc *sc, int h_chan, int activate)
+{
+ isic_Bchan_t *chan = &sc->sc_chan[h_chan];
+
+ DBGL1(L1_BCHAN, "avm_pnp_hscx_init", ("unit=%d, channel=%d, %s\n",
+ sc->sc_unit, h_chan, activate ? "activate" : "deactivate"));
+
+ if (activate == 0)
+ {
+ /* only deactivate if both channels are idle */
+ if (sc->sc_chan[HSCX_CH_A].state != HSCX_IDLE ||
+ sc->sc_chan[HSCX_CH_B].state != HSCX_IDLE)
+ {
+ return;
+ }
+ sc->avma1pp_cmd = HSCX_CMD_XRS|HSCX_CMD_RRS;
+ sc->avma1pp_prot = HSCX_MODE_TRANS;
+ hscx_write_reg(h_chan, HSCX_STAT, sc, 5);
+ return;
+ }
+ if(chan->bprot == BPROT_RHDLC)
+ {
+ DBGL1(L1_BCHAN, "avm_pnp_hscx_init", ("BPROT_RHDLC\n"));
+
+ /* HDLC Frames, transparent mode 0 */
+ sc->avma1pp_cmd = HSCX_CMD_XRS|HSCX_CMD_RRS;
+ sc->avma1pp_prot = HSCX_MODE_ITF_FLG;
+ hscx_write_reg(h_chan, HSCX_STAT, sc, 5);
+ sc->avma1pp_cmd = HSCX_CMD_XRS;
+ hscx_write_reg(h_chan, HSCX_STAT, sc, 1);
+ sc->avma1pp_cmd = 0;
+ }
+ else
+ {
+ DBGL1(L1_BCHAN, "avm_pnp_hscx_init", ("BPROT_NONE??\n"));
+
+ /* Raw Telephony, extended transparent mode 1 */
+ sc->avma1pp_cmd = HSCX_CMD_XRS|HSCX_CMD_RRS;
+ sc->avma1pp_prot = HSCX_MODE_TRANS;
+ hscx_write_reg(h_chan, HSCX_STAT, sc, 5);
+ sc->avma1pp_cmd = HSCX_CMD_XRS;
+ hscx_write_reg(h_chan, HSCX_STAT, sc, 1);
+ sc->avma1pp_cmd = 0;
+ }
+}
+
+static void
+avm_pnp_bchannel_setup(int unit, int h_chan, int bprot, int activate)
+{
+ struct isic_softc *sc = &isic_sc[unit];
+ isic_Bchan_t *chan = &sc->sc_chan[h_chan];
+
+ int s = SPLI4B();
+
+ if(activate == 0)
+ {
+ /* deactivation */
+ chan->state &= ~HSCX_AVMPNP_ACTIVE;
+ avm_pnp_hscx_init(sc, h_chan, activate);
+ }
+
+ DBGL1(L1_BCHAN, "avm_pnp_bchannel_setup", ("unit=%d, channel=%d, %s\n",
+ sc->sc_unit, h_chan, activate ? "activate" : "deactivate"));
+
+ /* general part */
+
+ chan->unit = sc->sc_unit; /* unit number */
+ chan->channel = h_chan; /* B channel */
+ chan->bprot = bprot; /* B channel protocol */
+ chan->state = HSCX_IDLE; /* B channel state */
+
+ /* receiver part */
+
+ i4b_Bcleanifq(&chan->rx_queue); /* clean rx queue */
+
+ chan->rx_queue.ifq_maxlen = IFQ_MAXLEN;
+
+ chan->rxcount = 0; /* reset rx counter */
+
+ i4b_Bfreembuf(chan->in_mbuf); /* clean rx mbuf */
+
+ chan->in_mbuf = NULL; /* reset mbuf ptr */
+ chan->in_cbptr = NULL; /* reset mbuf curr ptr */
+ chan->in_len = 0; /* reset mbuf data len */
+
+ /* transmitter part */
+
+ i4b_Bcleanifq(&chan->tx_queue); /* clean tx queue */
+
+ chan->tx_queue.ifq_maxlen = IFQ_MAXLEN;
+
+ chan->txcount = 0; /* reset tx counter */
+
+ i4b_Bfreembuf(chan->out_mbuf_head); /* clean tx mbuf */
+
+ chan->out_mbuf_head = NULL; /* reset head mbuf ptr */
+ chan->out_mbuf_cur = NULL; /* reset current mbuf ptr */
+ chan->out_mbuf_cur_ptr = NULL; /* reset current mbuf data ptr */
+ chan->out_mbuf_cur_len = 0; /* reset current mbuf data cnt */
+
+ if(activate != 0)
+ {
+ /* activation */
+ avm_pnp_hscx_init(sc, h_chan, activate);
+ chan->state |= HSCX_AVMPNP_ACTIVE;
+ }
+
+ splx(s);
+}
+
+static void
+avm_pnp_bchannel_start(int unit, int h_chan)
+{
+ struct isic_softc *sc = &isic_sc[unit];
+ register isic_Bchan_t *chan = &sc->sc_chan[h_chan];
+ int s;
+ int activity = -1;
+
+ s = SPLI4B(); /* enter critical section */
+ if(chan->state & HSCX_TX_ACTIVE) /* already running ? */
+ {
+ splx(s);
+ return; /* yes, leave */
+ }
+
+ /* get next mbuf from queue */
+
+ IF_DEQUEUE(&chan->tx_queue, chan->out_mbuf_head);
+
+ if(chan->out_mbuf_head == NULL) /* queue empty ? */
+ {
+ splx(s); /* leave critical section */
+ return; /* yes, exit */
+ }
+
+ /* init current mbuf values */
+
+ chan->out_mbuf_cur = chan->out_mbuf_head;
+ chan->out_mbuf_cur_len = chan->out_mbuf_cur->m_len;
+ chan->out_mbuf_cur_ptr = chan->out_mbuf_cur->m_data;
+
+ /* activity indicator for timeout handling */
+
+ if(chan->bprot == BPROT_NONE)
+ {
+ if(!(isic_hscx_silence(chan->out_mbuf_cur->m_data, chan->out_mbuf_cur->m_len)))
+ activity = ACT_TX;
+ }
+ else
+ {
+ activity = ACT_TX;
+ }
+
+ chan->state |= HSCX_TX_ACTIVE; /* we start transmitting */
+
+ if(sc->sc_trace & TRACE_B_TX) /* if trace, send mbuf to trace dev */
+ {
+ i4b_trace_hdr_t hdr;
+ hdr.unit = unit;
+ hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2);
+ hdr.dir = FROM_TE;
+ hdr.count = ++sc->sc_trace_bcount;
+ MICROTIME(hdr.time);
+ MPH_Trace_Ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data);
+ }
+
+ isic_hscx_fifo(chan, sc);
+
+ /* call timeout handling routine */
+
+ if(activity == ACT_RX || activity == ACT_TX)
+ (*chan->drvr_linktab->bch_activity)(chan->drvr_linktab->unit, activity);
+
+ splx(s);
+}
+
+/*---------------------------------------------------------------------------*
+ * return the address of isic drivers linktab
+ *---------------------------------------------------------------------------*/
+static isdn_link_t *
+avm_pnp_ret_linktab(int unit, int channel)
+{
+ struct isic_softc *sc = &isic_sc[unit];
+ isic_Bchan_t *chan = &sc->sc_chan[channel];
+
+ return(&chan->isdn_linktab);
+}
+
+/*---------------------------------------------------------------------------*
+ * set the driver linktab in the b channel softc
+ *---------------------------------------------------------------------------*/
+static void
+avm_pnp_set_linktab(int unit, int channel, drvr_link_t *dlt)
+{
+ struct isic_softc *sc = &isic_sc[unit];
+ isic_Bchan_t *chan = &sc->sc_chan[channel];
+
+ chan->drvr_linktab = dlt;
+}
+
+
+/*---------------------------------------------------------------------------*
+ * initialize our local linktab
+ *---------------------------------------------------------------------------*/
+static void
+avm_pnp_init_linktab(struct isic_softc *sc)
+{
+ isic_Bchan_t *chan = &sc->sc_chan[HSCX_CH_A];
+ isdn_link_t *lt = &chan->isdn_linktab;
+
+ /* make sure the hardware driver is known to layer 4 */
+ /* avoid overwriting if already set */
+ if (ctrl_types[CTRL_PASSIVE].set_linktab == NULL)
+ {
+ ctrl_types[CTRL_PASSIVE].set_linktab = avm_pnp_set_linktab;
+ ctrl_types[CTRL_PASSIVE].get_linktab = avm_pnp_ret_linktab;
+ }
+
+ /* local setup */
+ lt->unit = sc->sc_unit;
+ lt->channel = HSCX_CH_A;
+ lt->bch_config = avm_pnp_bchannel_setup;
+ lt->bch_tx_start = avm_pnp_bchannel_start;
+ lt->bch_stat = avm_pnp_bchannel_stat;
+ lt->tx_queue = &chan->tx_queue;
+
+ /* used by non-HDLC data transfers, i.e. telephony drivers */
+ lt->rx_queue = &chan->rx_queue;
+
+ /* used by HDLC data transfers, i.e. ipr and isp drivers */
+ lt->rx_mbuf = &chan->in_mbuf;
+
+ chan = &sc->sc_chan[HSCX_CH_B];
+ lt = &chan->isdn_linktab;
+
+ lt->unit = sc->sc_unit;
+ lt->channel = HSCX_CH_B;
+ lt->bch_config = avm_pnp_bchannel_setup;
+ lt->bch_tx_start = avm_pnp_bchannel_start;
+ lt->bch_stat = avm_pnp_bchannel_stat;
+ lt->tx_queue = &chan->tx_queue;
+
+ /* used by non-HDLC data transfers, i.e. telephony drivers */
+ lt->rx_queue = &chan->rx_queue;
+
+ /* used by HDLC data transfers, i.e. ipr and isp drivers */
+ lt->rx_mbuf = &chan->in_mbuf;
+}
+
+/*
+ * use this instead of isic_bchannel_stat in i4b_bchan.c because it's static
+ */
+static void
+avm_pnp_bchannel_stat(int unit, int h_chan, bchan_statistics_t *bsp)
+{
+ struct isic_softc *sc = &isic_sc[unit];
+ isic_Bchan_t *chan = &sc->sc_chan[h_chan];
+ int s;
+
+ s = SPLI4B();
+
+ bsp->outbytes = chan->txcount;
+ bsp->inbytes = chan->rxcount;
+
+ chan->txcount = 0;
+ chan->rxcount = 0;
+
+ splx(s);
+}
+
+/*---------------------------------------------------------------------------*
+ * fill HSCX fifo with data from the current mbuf
+ * Put this here until it can go into i4b_hscx.c
+ *---------------------------------------------------------------------------*/
+int
+isic_hscx_fifo(isic_Bchan_t *chan, struct isic_softc *sc)
+{
+ int len;
+ int nextlen;
+ int i;
+ /* using a scratch buffer simplifies writing to the FIFO */
+ u_char scrbuf[HSCX_FIFO_LEN];
+
+ len = 0;
+
+ /*
+ * fill the HSCX tx fifo with data from the current mbuf. if
+ * current mbuf holds less data than HSCX fifo length, try to
+ * get the next mbuf from (a possible) mbuf chain. if there is
+ * not enough data in a single mbuf or in a chain, then this
+ * is the last mbuf and we tell the HSCX that it has to send
+ * CRC and closing flag
+ */
+
+ while(chan->out_mbuf_cur && len != sc->sc_bfifolen)
+ {
+ nextlen = min(chan->out_mbuf_cur_len, sc->sc_bfifolen - len);
+
+#ifdef NOTDEF
+ printf("i:mh=%p, mc=%p, mcp=%p, mcl=%d l=%d nl=%d # ",
+ chan->out_mbuf_head,
+ chan->out_mbuf_cur,
+ chan->out_mbuf_cur_ptr,
+ chan->out_mbuf_cur_len,
+ len,
+ nextlen);
+#endif
+
+ /* collect the data in the scratch buffer */
+ for (i = 0; i < nextlen; i++)
+ scrbuf[i + len] = chan->out_mbuf_cur_ptr[i];
+
+ len += nextlen;
+ chan->txcount += nextlen;
+
+ chan->out_mbuf_cur_ptr += nextlen;
+ chan->out_mbuf_cur_len -= nextlen;
+
+ if(chan->out_mbuf_cur_len == 0)
+ {
+ if((chan->out_mbuf_cur = chan->out_mbuf_cur->m_next) != NULL)
+ {
+ chan->out_mbuf_cur_ptr = chan->out_mbuf_cur->m_data;
+ chan->out_mbuf_cur_len = chan->out_mbuf_cur->m_len;
+
+ if(sc->sc_trace & TRACE_B_TX)
+ {
+ i4b_trace_hdr_t hdr;
+ hdr.unit = sc->sc_unit;
+ hdr.type = (chan->channel == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2);
+ hdr.dir = FROM_TE;
+ hdr.count = ++sc->sc_trace_bcount;
+ MICROTIME(hdr.time);
+ MPH_Trace_Ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data);
+ }
+ }
+ else
+ {
+ i4b_Bfreembuf(chan->out_mbuf_head);
+ chan->out_mbuf_head = NULL;
+ }
+ }
+ }
+ /* write what we have from the scratch buf to the HSCX fifo */
+ if (len != 0)
+ HSCX_WRFIFO(chan->channel, scrbuf, len);
+
+ return(0);
+}
+
+void
+avm_pnp_intr(int unit)
+{
+ struct isic_softc *sc;
+ u_char stat;
+ register u_char isac_irq_stat;
+ int was_isac = 0;
+
+ sc = &isic_sc[unit];
+
+ for(;;) {
+ stat = inb(sc->sc_port + STAT0_OFFSET);
+
+ DBGL1(L1_H_IRQ, "avm_pnp_intr", ("stat %x\n", stat));
+
+ /* was there an interrupt from this card ? */
+ if ((stat & ASL_IRQ_Pending) == ASL_IRQ_Pending)
+ break; /* no */
+
+ /* interrupts are low active */
+ if (!(stat & ASL_IRQ_TIMER))
+ DBGL1(L1_H_IRQ, "avm_pnp_intr", ("timer interrupt ???\n"));
+
+ if (!(stat & ASL_IRQ_ISAC))
+ {
+ DBGL1(L1_H_IRQ, "avm_pnp_intr", ("ISAC\n"));
+ isac_irq_stat = ISAC_READ(I_ISTA);
+ isic_isac_irq(sc, isac_irq_stat);
+ was_isac = 1;
+ }
+
+ if (!(stat & ASL_IRQ_HSCX))
+ {
+ DBGL1(L1_H_IRQ, "avm_pnp_intr", ("HSCX\n"));
+ avm_pnp_hscx_int_handler(sc);
+ }
+ }
+ if (was_isac) {
+ ISAC_WRITE(0x20, 0xFF);
+ ISAC_WRITE(0x20, 0x0);
+ }
+}
+#endif /* NISIC > 0 && defined(AVM_PNP) */
+#endif /* FreeBSD */
diff --git a/sys/i4b/layer1/i4b_bsdi_ibc.c b/sys/i4b/layer1/i4b_bsdi_ibc.c
deleted file mode 100644
index 9168815..0000000
--- a/sys/i4b/layer1/i4b_bsdi_ibc.c
+++ /dev/null
@@ -1,559 +0,0 @@
-/*
- * Copyright (c) 1998, 1999 Bert Driehuis. All rights reserved.
- *
- * Copyright (c) 1997, 1998 Hellmuth Michaelis. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *---------------------------------------------------------------------------
- *
- * i4b_bsdi_ibc.c - isdn4bsd kernel BSD/OS point to point driver
- * -------------------------------------------------------------
- *
- * $Id: i4b_bsdi_ibc.c,v 1.1 1999/04/23 08:35:07 hm Exp $
- *
- * last edit-date: [Fri Apr 23 10:27:57 1999]
- *
- *---------------------------------------------------------------------------*/
-
-#include "ibc.h"
-
-#if NIBC > 0
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/mbuf.h>
-#include <sys/socket.h>
-#include <sys/errno.h>
-#include <sys/ioccom.h>
-#include <sys/ttycom.h>
-#include <sys/sockio.h>
-#include <sys/kernel.h>
-#include <sys/protosw.h>
-
-#include <net/if.h>
-#include <net/if_types.h>
-#include <net/if_p2p.h>
-#include <net/netisr.h>
-#include <net/route.h>
-
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/in_var.h>
-#include <netinet/ip.h>
-
-#include <i4b/i4b_ioctl.h>
-#include <i4b/i4b_cause.h>
-#include <i4b/include/i4b_global.h>
-#include <i4b/include/i4b_mbuf.h>
-#include <i4b/include/i4b_l3l4.h>
-#include <i4b/layer4/i4b_l4.h>
-
-#define IFP2UNIT(ifp) (ifp)->if_unit
-
-#define IOCTL_CMD_T u_long
-
-void ibcattach(void *);
-
-#define IBCACCT 1 /* enable accounting messages */
-#define IBCACCTINTVL 2 /* accounting msg interval in secs */
-
-#define PPP_HDRLEN 4 /* 4 octets PPP header length */
-
-struct ibc_softc {
- struct p2pcom sc_p2pcom;
-
- int sc_state; /* state of the interface */
- call_desc_t *sc_cdp; /* ptr to call descriptor */
-
-#ifdef IBCACCT
- int sc_iinb; /* isdn driver # of inbytes */
- int sc_ioutb; /* isdn driver # of outbytes */
- int sc_inb; /* # of bytes rx'd */
- int sc_outb; /* # of bytes tx'd */
- int sc_linb; /* last # of bytes rx'd */
- int sc_loutb; /* last # of bytes tx'd */
- int sc_fn; /* flag, first null acct */
-#endif
-} ibc_softc[NIBC];
-
-static void ibc_init_linktab(int unit);
-
-static int ibc_start(struct ifnet *ifp);
-
-static int ibc_watchdog(int unit);
-static int ibc_mdmctl(struct p2pcom *pp, int flag);
-static int ibc_getmdm(struct p2pcom *pp, caddr_t arg);
-
-/* initialized by L4 */
-
-static drvr_link_t ibc_drvr_linktab[NIBC];
-static isdn_link_t *isdn_ibc_lt[NIBC];
-
-enum ibc_states {
- ST_IDLE, /* initialized, ready, idle */
- ST_DIALING, /* dialling out to remote */
- ST_CONNECTED, /* connected to remote */
-};
-
-int ibcdebug = 0; /* Use bpatch to set this for debug printf's */
-#define DBG(x) if (ibcdebug) printf x
-
-/*===========================================================================*
- * DEVICE DRIVER ROUTINES
- *===========================================================================*/
-
-/*---------------------------------------------------------------------------*
- * interface attach routine at kernel boot time
- *---------------------------------------------------------------------------*/
-void
-ibcattach(void *dummy)
-{
- struct ibc_softc *sc = ibc_softc;
- struct ifnet *ifp;
- int i;
-
-#ifndef HACK_NO_PSEUDO_ATTACH_MSG
- printf("ibc: %d ISDN ibc device(s) attached\n",
- NIBC);
-#endif
-
- for(i = 0; i < NIBC; sc++, i++) {
- ibc_init_linktab(i);
-
- sc->sc_p2pcom.p2p_mdmctl = ibc_mdmctl;
- sc->sc_p2pcom.p2p_getmdm = ibc_getmdm;
- sc->sc_state = ST_IDLE;
- ifp = &sc->sc_p2pcom.p2p_if;
- ifp->if_name = "ibc";
- ifp->if_next = NULL;
- ifp->if_unit = i;
- ifp->if_mtu = 1500 /*XXX*/;
- ifp->if_baudrate = 64000;
- ifp->if_flags = IFF_SIMPLEX | IFF_POINTOPOINT;
- ifp->if_type = IFT_ISDNBASIC;
- ifp->if_start = ibc_start;
- ifp->if_output = 0;
- ifp->if_ioctl = p2p_ioctl;
-
- ifp->if_hdrlen = 0;
- ifp->if_addrlen = 0;
- ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
-
- ifp->if_ipackets = 0;
- ifp->if_ierrors = 0;
- ifp->if_opackets = 0;
- ifp->if_oerrors = 0;
- ifp->if_collisions = 0;
- ifp->if_ibytes = 0;
- ifp->if_obytes = 0;
- ifp->if_imcasts = 0;
- ifp->if_omcasts = 0;
- ifp->if_iqdrops = 0;
- ifp->if_noproto = 0;
-#if IBCACCT
- ifp->if_timer = 0;
- ifp->if_watchdog = ibc_watchdog;
- sc->sc_iinb = 0;
- sc->sc_ioutb = 0;
- sc->sc_inb = 0;
- sc->sc_outb = 0;
- sc->sc_linb = 0;
- sc->sc_loutb = 0;
- sc->sc_fn = 1;
-#endif
- if_attach(ifp);
- p2p_attach(&sc->sc_p2pcom);
- }
-}
-
-static struct mbuf *
-p2p_dequeue(struct p2pcom *pp)
-{
- struct ifqueue *ifq;
- struct mbuf *m;
-
- ifq = &pp->p2p_isnd;
- m = ifq->ifq_head;
- if (m == 0) {
- ifq = &pp->p2p_if.if_snd;
- m = ifq->ifq_head;
- }
- if (m == 0)
- return 0;
- IF_DEQUEUE(ifq, m);
- return m;
-}
-
-/*---------------------------------------------------------------------------*
- * start output to ISDN B-channel
- *---------------------------------------------------------------------------*/
-static int
-ibc_start(struct ifnet *ifp)
-{
- int unit = IFP2UNIT(ifp);
- struct ibc_softc *sc = (struct ibc_softc *)&ibc_softc[unit];
- struct p2pcom *pp = &sc->sc_p2pcom;
- struct mbuf *m;
- int s;
-
- if(sc->sc_state != ST_CONNECTED) {
- DBG(("ibc%d: ibc_start called with sc_state=%d\n",
- unit, sc->sc_state));
- return 0;
- }
-
- s = SPLI4B();
-
- if (IF_QFULL(isdn_ibc_lt[unit]->tx_queue)) {
- splx(s);
- return 0;
- }
-
- m = p2p_dequeue(pp);
- if (m == NULL) {
- splx(s);
- return 0;
- }
-
- do {
- microtime(&ifp->if_lastchange);
-
- IF_ENQUEUE(isdn_ibc_lt[unit]->tx_queue, m);
-
- ifp->if_obytes += m->m_pkthdr.len;
- sc->sc_outb += m->m_pkthdr.len;
- ifp->if_opackets++;
- } while (!IF_QFULL(isdn_ibc_lt[unit]->tx_queue) &&
- (m = p2p_dequeue(pp)) != NULL);
- isdn_ibc_lt[unit]->bch_tx_start(isdn_ibc_lt[unit]->unit,
- isdn_ibc_lt[unit]->channel);
- splx(s);
- return 0;
-}
-
-#ifdef IBCACCT
-/*---------------------------------------------------------------------------*
- * watchdog routine
- *---------------------------------------------------------------------------*/
-static int
-ibc_watchdog(int unit)
-{
- struct ibc_softc *sc = &ibc_softc[unit];
- struct ifnet *ifp = &sc->sc_p2pcom.p2p_if;
- bchan_statistics_t bs;
-
- (*isdn_ibc_lt[unit]->bch_stat)
- (isdn_ibc_lt[unit]->unit, isdn_ibc_lt[unit]->channel, &bs);
-
- sc->sc_ioutb += bs.outbytes;
- sc->sc_iinb += bs.inbytes;
-
- if((sc->sc_iinb != sc->sc_linb) || (sc->sc_ioutb != sc->sc_loutb) || sc->sc_fn)
- {
- int ri = (sc->sc_iinb - sc->sc_linb)/IBCACCTINTVL;
- int ro = (sc->sc_ioutb - sc->sc_loutb)/IBCACCTINTVL;
-
- if((sc->sc_iinb == sc->sc_linb) && (sc->sc_ioutb == sc->sc_loutb))
- sc->sc_fn = 0;
- else
- sc->sc_fn = 1;
-
- sc->sc_linb = sc->sc_iinb;
- sc->sc_loutb = sc->sc_ioutb;
-
- i4b_l4_accounting(BDRV_IBC, unit, ACCT_DURING,
- sc->sc_ioutb, sc->sc_iinb, ro, ri, sc->sc_outb, sc->sc_inb);
- }
- ifp->if_timer = IBCACCTINTVL;
- return 0;
-}
-#endif /* IBCACCT */
-
-/*
- *===========================================================================*
- * P2P layer interface routines
- *===========================================================================*
- */
-
-#if 0
-/*---------------------------------------------------------------------------*
- * PPP interface phase change
- *---------------------------------------------------------------------------*
- */
-static void
-ibc_state_changed(struct sppp *sp, int new_state)
-{
- struct ibc_softc *sc = (struct ibc_softc *)sp;
-
- i4b_l4_ifstate_changed(sc->sc_cdp, new_state);
-}
-
-/*---------------------------------------------------------------------------*
- * PPP control protocol negotiation complete (run ip-up script now)
- *---------------------------------------------------------------------------*
- */
-static void
-ibc_negotiation_complete(struct sppp *sp)
-{
- struct ibc_softc *sc = (struct ibc_softc *)sp;
-
- i4b_l4_negcomplete(sc->sc_cdp);
-}
-#endif
-
-/*===========================================================================*
- * ISDN INTERFACE ROUTINES
- *===========================================================================*/
-
-/*---------------------------------------------------------------------------*
- * this routine is called from L4 handler at connect time
- *---------------------------------------------------------------------------*/
-static void
-ibc_connect(int unit, void *cdp)
-{
- struct ibc_softc *sc = &ibc_softc[unit];
- struct ifnet *ifp = &sc->sc_p2pcom.p2p_if;
- int s;
-
- DBG(("ibc%d: ibc_connect\n", unit));
-
- s = splimp();
-
- sc->sc_cdp = (call_desc_t *)cdp;
- sc->sc_state = ST_CONNECTED;
-
-#if IBCACCT
- sc->sc_iinb = 0;
- sc->sc_ioutb = 0;
- sc->sc_inb = 0;
- sc->sc_outb = 0;
- sc->sc_linb = 0;
- sc->sc_loutb = 0;
- ifp->if_timer = IBCACCTINTVL;
-#endif
-
- splx(s);
- if (sc->sc_p2pcom.p2p_modem)
- (*sc->sc_p2pcom.p2p_modem)(&sc->sc_p2pcom, 1);
-
- /* This is a lie... PPP is just starting to negociate :-) */
- i4b_l4_negcomplete(sc->sc_cdp);
-}
-
-/*---------------------------------------------------------------------------*
- * this routine is called from L4 handler at disconnect time
- *---------------------------------------------------------------------------*/
-static void
-ibc_disconnect(int unit, void *cdp)
-{
- call_desc_t *cd = (call_desc_t *)cdp;
- struct ibc_softc *sc = &ibc_softc[unit];
- struct ifnet *ifp = &sc->sc_p2pcom.p2p_if;
- int s;
-
- DBG(("ibc%d: ibc_disconnect\n", unit));
-
- s = splimp();
-
- /* new stuff to check that the active channel is being closed */
- if (cd != sc->sc_cdp)
- {
- DBG(("ibc_disconnect: ibc%d channel%d not active\n",
- cd->driver_unit, cd->channelid));
- splx(s);
- return;
- }
-
-#if IBCACCT
- ifp->if_timer = 0;
-#endif
-
- i4b_l4_accounting(BDRV_IBC, unit, ACCT_FINAL,
- sc->sc_ioutb, sc->sc_iinb, 0, 0, sc->sc_outb, sc->sc_inb);
-
- if (sc->sc_state == ST_CONNECTED)
- {
- sc->sc_cdp = (call_desc_t *)0;
- sc->sc_state = ST_IDLE;
- if (sc->sc_p2pcom.p2p_modem)
- (*sc->sc_p2pcom.p2p_modem)(&sc->sc_p2pcom, 0);
- }
-
- splx(s);
-}
-
-/*---------------------------------------------------------------------------*
- * this routine is used to give a feedback from userland demon
- * in case of dial problems
- *---------------------------------------------------------------------------*/
-static void
-ibc_dialresponse(int unit, int status)
-{
- DBG(("ibc%d: ibc_dialresponse %d\n", unit, status));
-/* struct ibc_softc *sc = &ibc_softc[unit]; */
-}
-
-/*---------------------------------------------------------------------------*
- * interface up/down
- *---------------------------------------------------------------------------*/
-static void
-ibc_updown(int unit, int updown)
-{
- DBG(("ibc%d: ibc_updown %d\n", unit, updown));
- /* could probably do something useful here */
-}
-
-/*---------------------------------------------------------------------------*
- * this routine is called from the HSCX interrupt handler
- * when a new frame (mbuf) has been received and was put on
- * the rx queue.
- *---------------------------------------------------------------------------*/
-static void
-ibc_rx_data_rdy(int unit)
-{
- struct ibc_softc *sc = &ibc_softc[unit];
- struct ifnet *ifp = &sc->sc_p2pcom.p2p_if;
- struct mbuf *m, *m0;
- char *buf;
- int s;
-
- if((m = *isdn_ibc_lt[unit]->rx_mbuf) == NULL)
- return;
-
- microtime(&ifp->if_lastchange);
- ifp->if_ipackets++;
-
- /* Walk the mbuf chain */
- s = splimp();
- for (m0 = m; m != 0; m = m->m_next) {
- if (m->m_len == 0)
- continue;
- ifp->if_ibytes += m->m_len;
-#if IBCACCT
- sc->sc_inb += m->m_len;
-#endif
- buf = mtod(m, caddr_t);
- if ((*sc->sc_p2pcom.p2p_hdrinput)(
- &sc->sc_p2pcom, buf, m->m_len) >= 0)
- (*sc->sc_p2pcom.p2p_input)(&sc->sc_p2pcom, 0);
- }
- splx(s);
- m_freem(m0);
-}
-
-/*---------------------------------------------------------------------------*
- * this routine is called from the HSCX interrupt handler
- * when the last frame has been sent out and there is no
- * further frame (mbuf) in the tx queue.
- *---------------------------------------------------------------------------*/
-static void
-ibc_tx_queue_empty(int unit)
-{
- ibc_start(&ibc_softc[unit].sc_p2pcom.p2p_if);
-}
-
-/*---------------------------------------------------------------------------*
- * this routine is called from the HSCX interrupt handler
- * each time a packet is received or transmitted. It should
- * be used to implement an activity timeout mechanism.
- *---------------------------------------------------------------------------*/
-static void
-ibc_activity(int unit, int rxtx)
-{
- ibc_softc[unit].sc_cdp->last_active_time = SECOND;
-}
-
-/*---------------------------------------------------------------------------*
- * return this drivers linktab address
- *---------------------------------------------------------------------------*/
-drvr_link_t *
-ibc_ret_linktab(int unit)
-{
- return(&ibc_drvr_linktab[unit]);
-}
-
-/*---------------------------------------------------------------------------*
- * setup the isdn_ibc_lt for this driver
- *---------------------------------------------------------------------------*/
-void
-ibc_set_linktab(int unit, isdn_link_t *ilt)
-{
- isdn_ibc_lt[unit] = ilt;
-}
-
-/*---------------------------------------------------------------------------*
- * initialize this drivers linktab
- *---------------------------------------------------------------------------*/
-static void
-ibc_init_linktab(int unit)
-{
- ibc_drvr_linktab[unit].unit = unit;
- ibc_drvr_linktab[unit].bch_rx_data_ready = ibc_rx_data_rdy;
- ibc_drvr_linktab[unit].bch_tx_queue_empty = ibc_tx_queue_empty;
- ibc_drvr_linktab[unit].bch_activity = ibc_activity;
- ibc_drvr_linktab[unit].line_connected = ibc_connect;
- ibc_drvr_linktab[unit].line_disconnected = ibc_disconnect;
- ibc_drvr_linktab[unit].dial_response = ibc_dialresponse;
- ibc_drvr_linktab[unit].updown_ind = ibc_updown;
-}
-
-/*===========================================================================*/
-
-static int
-ibc_mdmctl(pp, flag)
- struct p2pcom *pp;
- int flag;
-{
- register struct ifnet *ifp = &pp->p2p_if;
- struct ibc_softc *sc = (struct ibc_softc *)&ibc_softc[ifp->if_unit];
-
- DBG(("ibc%d: ibc_mdmctl called flags=%d\n", IFP2UNIT(ifp), flag));
-
- if (flag == 1 && sc->sc_state == ST_IDLE) {
- sc->sc_state = ST_DIALING;
- i4b_l4_dialout(BDRV_IBC, IFP2UNIT(ifp));
- } else if (flag == 0 && sc->sc_state != ST_IDLE) {
- sc->sc_state = ST_IDLE;
- i4b_l4_drvrdisc(BDRV_IBC, IFP2UNIT(ifp));
- }
- return 0;
-}
-
-static int
-ibc_getmdm(pp, arg)
- struct p2pcom *pp;
- caddr_t arg;
-{
- register struct ifnet *ifp = &pp->p2p_if;
- struct ibc_softc *sc = (struct ibc_softc *)&ibc_softc[ifp->if_unit];
-
- if (sc->sc_state == ST_CONNECTED)
- *(int *)arg = TIOCM_CAR;
- else
- *(int *)arg = 0;
- return 0;
-
- DBG(("ibc%d: ibc_getmdm called ret=%d\n", IFP2UNIT(ifp), *(int *)arg));
-}
-#endif
diff --git a/sys/i4b/layer1/i4b_dynalink.c b/sys/i4b/layer1/i4b_dynalink.c
index e316682..1f75302 100644
--- a/sys/i4b/layer1/i4b_dynalink.c
+++ b/sys/i4b/layer1/i4b_dynalink.c
@@ -33,7 +33,7 @@
* isdn4bsd layer1 driver for Dynalink IS64PH isdn TA
* ==================================================
*
- * $Id: i4b_dynalink.c,v 1.9 1999/02/14 09:44:58 hm Exp $
+ * $Id: i4b_dynalink.c,v 1.10 1999/07/26 09:03:49 hm Exp $
*
* last edit-date: [Sun Feb 14 10:26:21 1999]
*
@@ -108,6 +108,8 @@
#include <machine/clock.h>
#include <i386/isa/isa_device.h>
#include <i386/isa/pnp.h>
+#elif defined(__bsdi__)
+#include <i386/isa/pnp.h>
#else
#include <machine/bus.h>
#include <sys/device.h>
@@ -129,15 +131,21 @@
#include <i4b/layer1/i4b_isac.h>
#include <i4b/layer1/i4b_hscx.h>
-#ifdef __FreeBSD__
+#if defined(__FreeBSD__) || defined(__bsdi__)
static void dynalink_read_fifo(void *buf, const void *base, size_t len);
static void dynalink_write_fifo(void *base, const void *buf, size_t len);
static void dynalink_write_reg(u_char *base, u_int offset, u_int v);
static u_char dynalink_read_reg(u_char *base, u_int offset);
+#endif
+#ifdef __FreeBSD__
extern struct isa_driver isicdriver;
+#endif
+#ifdef __bsdi__
+extern struct cfdriver isiccd;
+#endif
-#else
+#if !defined(__FreeBSD__) && !defined(__bsdi__)
static void dynalink_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size);
static void dynalink_write_fifo(struct isic_softc *sc, int what, const void *buf, size_t size);
static void dynalink_write_reg(struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data);
@@ -158,13 +166,15 @@ void isic_attach_Dyn(struct isic_softc *sc);
#define HSCXA 0x00
#define HSCXB 0x40
-#ifdef __FreeBSD__
+#if defined(__FreeBSD__) || defined(__bsdi__)
/* base address juggling */
#define HSCXB_HACK 0x400
#define IOBASE(addr) (((int)addr)&0x3FC)
#define IOADDR(addr) (((int)addr)&0x3FF)
#define IS_HSCXB_HACK(addr) ((((int)addr)&HSCXB_HACK)?HSCXB:HSCXA)
+#endif
+#ifdef __FreeBSD__
/* ISIC probe and attach
*/
@@ -271,6 +281,136 @@ isic_attach_Dyn(struct isa_device *dev, unsigned int iobase2)
return(1);
}
+#elif defined(__bsdi__)
+
+/* ISIC probe and attach
+*/
+
+static int
+set_softc(struct isic_softc *sc, struct isa_attach_args *ia, int unit)
+{
+ if (unit >= NISIC)
+ return 0;
+ sc->sc_unit = unit;
+ switch(ffs(ia->ia_irq) - 1)
+ {
+ case 3:
+ case 4:
+ case 5:
+ case 9:
+ case 10:
+ case 11:
+ case 12:
+ case 15:
+ break;
+
+ default:
+ printf("isic%d: Error, invalid IRQ [%d] specified for Dynalink IS64PH.\n",
+ unit, ffs(ia->ia_irq)-1);
+ return(0);
+ break;
+ }
+ sc->sc_irq = ia->ia_irq;
+
+ /* check if memory addr specified */
+
+ if(ia->ia_maddr)
+ {
+ printf("isic%d: Error, mem addr 0x%lx specified for Dynalink IS64PH.\n",
+ unit, (u_long)ia->ia_maddr);
+ return (0);
+ }
+
+ /* check if we got an iobase */
+ if ( (ia->ia_iobase < 0x100) ||
+ (ia->ia_iobase > 0x3f8) ||
+ (ia->ia_iobase & 3) )
+ {
+ printf("isic%d: Error, invalid iobase 0x%x specified for Dynalink!\n", unit, ia->ia_iobase);
+ return(0);
+ }
+ sc->sc_port = ia->ia_iobase;
+
+ /* setup access routines */
+ sc->clearirq = NULL;
+ sc->readreg = dynalink_read_reg;
+ sc->writereg = dynalink_write_reg;
+ sc->readfifo = dynalink_read_fifo;
+ sc->writefifo = dynalink_write_fifo;
+
+ /* setup card type */
+ sc->sc_cardtyp = CARD_TYPEP_DYNALINK;
+
+ /* setup IOM bus type */
+ sc->sc_bustyp = BUS_TYPE_IOM2;
+
+ sc->sc_ipac = 0;
+ sc->sc_bfifolen = HSCX_FIFO_LEN;
+
+ /* setup ISAC and HSCX base addr */
+ ISAC_BASE = (caddr_t) sc->sc_port;
+ HSCX_A_BASE = (caddr_t) sc->sc_port + 1;
+ HSCX_B_BASE = (caddr_t) sc->sc_port + 1 + HSCXB_HACK;
+ return 1;
+}
+
+int
+isapnp_match_dynalink(struct device *parent, struct cfdata *cf,
+ struct isa_attach_args *ia)
+{
+ struct isic_softc dummysc, *sc = &dummysc;
+ pnp_resource_t res;
+ char *ids[] = {"ASU1688", NULL};
+ bzero(&res, sizeof res);
+ res.res_irq[0].irq_level = ia->ia_irq;
+ res.res_port[0].prt_base = ia->ia_iobase;
+ res.res_port[0].prt_length = 4;
+
+ if (!pnp_assigndev(ids, isiccd.cd_name, &res))
+ return (0);
+
+ ia->ia_irq = res.res_irq[0].irq_level;
+ ia->ia_iobase = res.res_port[0].prt_base;
+ ia->ia_iosize = res.res_port[0].prt_length;
+
+ if (set_softc(sc, ia, cf->cf_unit) == 0)
+ return 0;
+
+ /* Read HSCX A/B VSTR. Expected value is 0x05 (V2.1). */
+ if( ((HSCX_READ(0, H_VSTR) & 0xf) != 0x5) ||
+ ((HSCX_READ(1, H_VSTR) & 0xf) != 0x5) )
+ {
+ printf("isic%d: HSCX VSTR test failed for Dynalink\n",
+ cf->cf_unit);
+ printf("isic%d: HSC0: VSTR: %#x\n",
+ cf->cf_unit, HSCX_READ(0, H_VSTR));
+ printf("isic%d: HSC1: VSTR: %#x\n",
+ cf->cf_unit, HSCX_READ(1, H_VSTR));
+ return (0);
+ }
+
+ cf->cf_flags = FLAG_DYNALINK;
+ return (1);
+}
+
+int
+isic_attach_Dyn(struct device *parent, struct device *self,
+ struct isa_attach_args *ia)
+{
+ struct isic_softc *sc = (struct isic_softc *)self;
+ int unit = sc->sc_dev.dv_unit;
+
+ /* Commit the probed attachment values */
+ if (set_softc(sc, ia, unit) == 0)
+ panic("isic_attach_Dyn: set_softc");
+
+ outb((ia->ia_iobase)+ADDR, RESET);
+ DELAY(SEC_DELAY / 10);
+ outb((ia->ia_iobase)+ADDR, 0);
+ DELAY(SEC_DELAY / 10);
+ return(1);
+}
+
#else
void isic_attach_Dyn(struct isic_softc *sc)
@@ -320,7 +460,7 @@ void isic_attach_Dyn(struct isic_softc *sc)
REM: this is only true for the FreeBSD version of I4B!
*/
-#ifdef __FreeBSD__
+#if defined(__FreeBSD__) || defined(__bsdi__)
static void
dynalink_read_fifo(void *buf, const void *base, size_t len)
{
@@ -350,7 +490,7 @@ dynalink_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size)
}
#endif
-#ifdef __FreeBSD__
+#if defined(__FreeBSD__) || defined(__bsdi__)
static void
dynalink_write_fifo(void *base, const void *buf, size_t len)
{
@@ -379,7 +519,7 @@ static void dynalink_write_fifo(struct isic_softc *sc, int what, const void *buf
}
#endif
-#ifdef __FreeBSD__
+#if defined(__FreeBSD__) || defined(__bsdi__)
static void
dynalink_write_reg(u_char *base, u_int offset, u_int v)
{
@@ -408,7 +548,7 @@ static void dynalink_write_reg(struct isic_softc *sc, int what, bus_size_t offs,
}
#endif
-#ifdef __FreeBSD__
+#if defined(__FreeBSD__) || defined(__bsdi__)
static u_char
dynalink_read_reg(u_char *base, u_int offset)
{
diff --git a/sys/i4b/layer1/i4b_ipac.h b/sys/i4b/layer1/i4b_ipac.h
index d820271..e58c4b8 100644
--- a/sys/i4b/layer1/i4b_ipac.h
+++ b/sys/i4b/layer1/i4b_ipac.h
@@ -27,9 +27,9 @@
* i4b_ipac.h - definitions for the Siemens IPAC PSB2115 chip
* ==========================================================
*
- * $Id: i4b_ipac.h,v 1.5 1999/02/14 09:44:59 hm Exp $
+ * $Id: i4b_ipac.h,v 1.6 1999/06/08 08:13:00 hm Exp $
*
- * last edit-date: [Sun Feb 14 10:27:03 1999]
+ * last edit-date: [Tue Jun 8 09:53:26 1999]
*
*---------------------------------------------------------------------------
*/
@@ -44,6 +44,10 @@
#define IPAC_ISAC_OFF 0x80
#define IPAC_IPAC_OFF 0xc0
+/* chip version */
+
+#define IPAC_V11 0x01 /* IPAC Version 1.1 */
+
/*
* definitions of registers and bits for the IPAC ISDN chip.
*/
diff --git a/sys/i4b/layer1/i4b_isic.c b/sys/i4b/layer1/i4b_isic.c
index f403faf..a2361b9 100644
--- a/sys/i4b/layer1/i4b_isic.c
+++ b/sys/i4b/layer1/i4b_isic.c
@@ -27,9 +27,9 @@
* i4b_isic.c - global isic stuff
* ==============================
*
- * $Id: i4b_isic.c,v 1.47 1999/04/20 09:34:14 hm Exp $
+ * $Id: i4b_isic.c,v 1.51 1999/07/26 09:03:49 hm Exp $
*
- * last edit-date: [Sun Feb 14 10:27:20 1999]
+ * last edit-date: [Mon Jul 26 10:59:56 1999]
*
*---------------------------------------------------------------------------*/
@@ -97,6 +97,7 @@ struct cfdriver isiccd =
sizeof(struct isic_softc) };
int isa_isicmatch(struct device *parent, struct cfdata *cf, struct isa_attach_args *);
+int isapnp_isicmatch(struct device *parent, struct cfdata *cf, struct isa_attach_args *);
int isa_isicattach(struct device *parent, struct device *self, struct isa_attach_args *ia);
static int
@@ -109,8 +110,7 @@ isicmatch(struct device *parent, struct cfdata *cf, void *aux)
return 0; /* for now */
}
if (ia->ia_bustype == BUS_PNP) {
- /* return isapnp_isicmatch(parent, cf, ia); */
- return 0; /* for now */
+ return isapnp_isicmatch(parent, cf, ia);
}
return isa_isicmatch(parent, cf, ia);
}
@@ -209,6 +209,9 @@ isicintr(void *arg)
was_isac_irq = 1;
}
}
+
+#ifdef NOTDEF
+
#if !defined(amiga) && !defined(atari) /* XXX should be: #if INTS_ARE_SHARED */
#ifdef ELSA_QS1ISA
if(sc->sc_cardtyp != CARD_TYPEP_ELSAQS1ISA)
@@ -220,6 +223,8 @@ isicintr(void *arg)
}
#endif
#endif /* !AMIGA && !ATARI */
+
+#endif /* NOTDEF */
HSCX_WRITE(0, H_MASK, 0xff);
ISAC_WRITE(I_MASK, 0xff);
@@ -273,21 +278,27 @@ isicintr(void *arg)
ipac_irq_stat & IPAC_ISTA_EXB);
was_ipac_irq = 1;
}
- if(ipac_irq_stat & (IPAC_ISTA_ICD | IPAC_ISTA_EXD))
+ if(ipac_irq_stat & IPAC_ISTA_ICD)
{
/* ISAC interrupt */
isic_isac_irq(sc, ISAC_READ(I_ISTA));
was_ipac_irq = 1;
}
+ if(ipac_irq_stat & IPAC_ISTA_EXD)
+ {
+ /* force ISAC interrupt handling */
+ isic_isac_irq(sc, ISAC_ISTA_EXI);
+ was_ipac_irq = 1;
+ }
/* do as long as there are pending irqs in the chip */
if(!ipac_irq_stat)
break;
}
-
+#ifdef NOTDEF
if(was_ipac_irq == 0)
DBGL1(L1_ERROR, "isicintr", ("WARNING: unit %d, No IRQ from IPAC!\n", sc->sc_unit));
-
+#endif
IPAC_WRITE(IPAC_MASK, 0xff);
DELAY(50);
IPAC_WRITE(IPAC_MASK, 0xc0);
diff --git a/sys/i4b/layer1/i4b_isic_isa.c b/sys/i4b/layer1/i4b_isic_isa.c
index 4147355..ba927c4 100644
--- a/sys/i4b/layer1/i4b_isic_isa.c
+++ b/sys/i4b/layer1/i4b_isic_isa.c
@@ -27,9 +27,9 @@
* i4b_isic_isa.c - ISA bus interface
* ==================================
*
- * $Id: i4b_isic_isa.c,v 1.20 1999/05/10 09:37:35 hm Exp $
+ * $Id: i4b_isic_isa.c,v 1.24 1999/07/26 09:03:49 hm Exp $
*
- * last edit-date: [Tue Apr 20 11:47:59 1999]
+ * last edit-date: [Mon Jul 26 10:59:51 1999]
*
*---------------------------------------------------------------------------*/
@@ -211,6 +211,18 @@ isicprobe(struct isa_device *dev)
}
#elif defined(__bsdi__)
/*---------------------------------------------------------------------------*
+ * isic - pnp device driver probe routine
+ *---------------------------------------------------------------------------*/
+int
+isapnp_isicmatch(struct device *parent, struct cfdata *cf, struct isa_attach_args *ia)
+{
+#ifdef DYNALINK
+ if (isapnp_match_dynalink(parent, cf, ia))
+ return 1;
+#endif
+ return 0;
+}
+/*---------------------------------------------------------------------------*
* isic - non-pnp device driver probe routine
*---------------------------------------------------------------------------*/
int
@@ -305,6 +317,7 @@ isic_realattach(struct isa_device *dev, unsigned int iobase2)
*---------------------------------------------------------------------------*/
int
isa_isicattach(struct device *parent, struct device *self, struct isa_attach_args *ia)
+
#else /* ! __FreeBSD__ */
int
@@ -316,19 +329,26 @@ isicattach(int flags, struct isic_softc *sc)
char *drvid;
#ifdef __FreeBSD__
+
struct isic_softc *sc = &isic_sc[dev->id_unit];
#define PARM dev
#define PARM2 dev, iobase2
#define FLAGS dev->id_flags
+
#elif defined(__bsdi__)
+
struct isic_softc *sc = (struct isic_softc *)self;
#define PARM parent, self, ia
+#define PARM2 parent, self, ia
#define FLAGS sc->sc_flags
+
#else
+
#define PARM sc
#define PARM2 sc
#define FLAGS flags
-#endif
+
+#endif /* __FreeBSD__ */
static char *ISACversion[] = {
"2085 Version A1/A2 or 2086/2186 Version 1.1",
@@ -353,7 +373,7 @@ isicattach(int flags, struct isic_softc *sc)
#ifdef __FreeBSD__
if(dev->id_unit != next_isic_unit)
{
- printf("isicattach: Error: new unit (%d) != next_isic_unit (%d)!\n", dev->id_unit, next_isic_unit);
+/*XXX*/ printf("isicattach: Error: new unit (%d) != next_isic_unit (%d)!\n", dev->id_unit, next_isic_unit);
return(0);
}
@@ -413,9 +433,16 @@ isicattach(int flags, struct isic_softc *sc)
break;
#endif
+#ifdef amiga
+ case FLAG_BLMASTER:
+ ret = 1; /* full detection was done in caller */
+ break;
+#endif
+
/* ======================================================================
* Only P&P cards follow below!!!
*/
+
#ifdef __FreeBSD__ /* we've already splitted all non-ISA stuff
out of this ISA specific part for the other
OS */
@@ -456,15 +483,26 @@ isicattach(int flags, struct isic_softc *sc)
break;
#endif
-#endif /* __FreeBSD__ / P&P specific part */
+#ifdef AVM_PNP
+ case FLAG_AVM_PNP:
+ ret = isic_attach_avm_pnp(PARM2);
+ ret = 0;
+ break;
+#endif
-/* --- XXX - don't know how to handle this - should be removed!!!! ---- */
-#ifdef amiga
- case FLAG_BLMASTER:
- ret = 1; /* full detection was done in caller */
+#ifdef SIEMENS_ISURF2
+ case FLAG_SIEMENS_ISURF2:
+ ret = isic_attach_siemens_isurf(PARM2);
+ break;
+#endif
+
+#ifdef ASUSCOM_IPAC
+ case FLAG_ASUSCOM_IPAC:
+ ret = isic_attach_asi(PARM2);
break;
#endif
-/* ------------------------------------------------------------------- */
+
+#endif /* __FreeBSD__ / P&P specific part */
default:
break;
@@ -473,40 +511,78 @@ isicattach(int flags, struct isic_softc *sc)
if(ret == 0)
return(0);
- sc->sc_isac_version = 0;
- sc->sc_isac_version = ((ISAC_READ(I_RBCH)) >> 5) & 0x03;
-
- switch(sc->sc_isac_version)
+ if(sc->sc_ipac)
{
- case ISAC_VA:
- case ISAC_VB1:
- case ISAC_VB2:
- case ISAC_VB3:
- break;
+ ret = IPAC_READ(IPAC_ID);
- default:
- printf(ISIC_FMT "Error, ISAC version %d unknown!\n",
- ISIC_PARM, sc->sc_isac_version);
+ if(ret != IPAC_V11)
+ {
+ printf("isic%d: Error, IPAC version %d unknown!\n",
+ sc->sc_unit, ret);
return(0);
- break;
+ }
}
+ else
+ {
- sc->sc_hscx_version = HSCX_READ(0, H_VSTR) & 0xf;
+ sc->sc_isac_version = 0;
+ sc->sc_hscx_version = 0;
- switch(sc->sc_hscx_version)
+ if(sc->sc_ipac)
+ {
+ ret = IPAC_READ(IPAC_ID);
+
+ switch(ret)
+ {
+ case 0x01:
+ printf("isic%d: IPAC PSB2115 Version 1.1\n", sc->sc_unit);
+ break;
+
+ default:
+ printf("isic%d: Error, IPAC version %d unknown!\n",
+ sc->sc_unit, ret);
+ return(0);
+ break;
+ }
+ }
+ else
{
- case HSCX_VA1:
- case HSCX_VA2:
- case HSCX_VA3:
- case HSCX_V21:
- break;
-
- default:
- printf(ISIC_FMT "Error, HSCX version %d unknown!\n",
- ISIC_PARM, sc->sc_hscx_version);
- return(0);
- break;
- };
+ sc->sc_isac_version = ((ISAC_READ(I_RBCH)) >> 5) & 0x03;
+
+ switch(sc->sc_isac_version)
+ {
+ case ISAC_VA:
+ case ISAC_VB1:
+ case ISAC_VB2:
+ case ISAC_VB3:
+ break;
+
+ default:
+ printf(ISIC_FMT "Error, ISAC version %d unknown!\n",
+ ISIC_PARM, sc->sc_isac_version);
+ return(0);
+ break;
+ }
+
+ sc->sc_hscx_version = HSCX_READ(0, H_VSTR) & 0xf;
+
+ switch(sc->sc_hscx_version)
+ {
+ case HSCX_VA1:
+ case HSCX_VA2:
+ case HSCX_VA3:
+ case HSCX_V21:
+ break;
+
+ default:
+ printf(ISIC_FMT "Error, HSCX version %d unknown!\n",
+ ISIC_PARM, sc->sc_hscx_version);
+ return(0);
+ break;
+ }
+ }
+
+ }
/* ISAC setup */
@@ -614,6 +690,14 @@ isicattach(int flags, struct isic_softc *sc)
drvid = "ELSA PCC-16";
break;
+ case FLAG_ASUSCOM_IPAC:
+ drvid = "Asuscom ISDNlink 128K PnP";
+ break;
+
+ case FLAG_SIEMENS_ISURF2:
+ drvid = "Siemens I-Surf 2.0";
+ break;
+
default:
drvid = "ERROR, unknown flag used";
break;
@@ -626,42 +710,52 @@ isicattach(int flags, struct isic_softc *sc)
/* announce chip versions */
- if(sc->sc_isac_version >= ISAC_UNKN)
+ if(sc->sc_ipac)
{
- printf(ISIC_FMT "ISAC Version UNKNOWN (VN=0x%x)" TERMFMT,
- ISIC_PARM,
- sc->sc_isac_version);
- sc->sc_isac_version = ISAC_UNKN;
+ printf(ISIC_FMT "IPAC PSB2115 Version 1.1\n", ISIC_PARM);
}
else
{
- printf(ISIC_FMT "ISAC %s (IOM-%c)" TERMFMT,
- ISIC_PARM,
- ISACversion[sc->sc_isac_version],
- sc->sc_bustyp == BUS_TYPE_IOM1 ? '1' : '2');
- }
-
+ if(sc->sc_isac_version >= ISAC_UNKN)
+ {
+ printf(ISIC_FMT "ISAC Version UNKNOWN (VN=0x%x)" TERMFMT,
+ ISIC_PARM,
+ sc->sc_isac_version);
+ sc->sc_isac_version = ISAC_UNKN;
+ }
+ else
+ {
+ printf(ISIC_FMT "ISAC %s (IOM-%c)" TERMFMT,
+ ISIC_PARM,
+ ISACversion[sc->sc_isac_version],
+ sc->sc_bustyp == BUS_TYPE_IOM1 ? '1' : '2');
+ }
+
#ifdef __FreeBSD__
- printf("(Addr=0x%lx)\n", (u_long)ISAC_BASE);
+ printf("(Addr=0x%lx)\n", (u_long)ISAC_BASE);
#endif
- if(sc->sc_hscx_version >= HSCX_UNKN)
- {
- printf(ISIC_FMT "HSCX Version UNKNOWN (VN=0x%x)" TERMFMT,
- ISIC_PARM,
- sc->sc_hscx_version);
- sc->sc_hscx_version = HSCX_UNKN;
- }
- else
- {
- printf(ISIC_FMT "HSCX %s" TERMFMT,
- ISIC_PARM,
- HSCXversion[sc->sc_hscx_version]);
+ if(sc->sc_hscx_version >= HSCX_UNKN)
+ {
+ printf(ISIC_FMT "HSCX Version UNKNOWN (VN=0x%x)" TERMFMT,
+ ISIC_PARM,
+ sc->sc_hscx_version);
+ sc->sc_hscx_version = HSCX_UNKN;
+ }
+ else
+ {
+ printf(ISIC_FMT "HSCX %s" TERMFMT,
+ ISIC_PARM,
+ HSCXversion[sc->sc_hscx_version]);
+ }
+
+#ifdef __FreeBSD__
+ printf("(AddrA=0x%lx, AddrB=0x%lx)\n", (u_long)HSCX_A_BASE, (u_long)HSCX_B_BASE);
+
+#endif /* __FreeBSD__ */
}
#ifdef __FreeBSD__
- printf("(AddrA=0x%lx, AddrB=0x%lx)\n", (u_long)HSCX_A_BASE, (u_long)HSCX_B_BASE);
-
next_isic_unit++;
#if defined(__FreeBSD_version) && __FreeBSD_version >= 300003
diff --git a/sys/i4b/layer1/i4b_isic_pnp.c b/sys/i4b/layer1/i4b_isic_pnp.c
index a9f056a..0e534eb 100644
--- a/sys/i4b/layer1/i4b_isic_pnp.c
+++ b/sys/i4b/layer1/i4b_isic_pnp.c
@@ -37,9 +37,9 @@
* i4b_isic_pnp.c - i4b pnp support
* --------------------------------
*
- * $Id: i4b_isic_pnp.c,v 1.17 1999/04/20 14:28:46 hm Exp $
+ * $Id: i4b_isic_pnp.c,v 1.23 1999/07/05 14:00:04 hm Exp $
*
- * last edit-date: [Tue Apr 20 16:12:27 1999]
+ * last edit-date: [Mon Jul 5 15:57:01 1999]
*
*---------------------------------------------------------------------------*/
@@ -76,23 +76,31 @@ extern void isicintr(int unit);
#include <machine/i4b_ioctl.h>
#include <i4b/layer1/i4b_l1.h>
-#define VID_TEL163PNP 0x10212750 /* Teles 16.3 PnP */
-#define VID_CREATIXPP 0x0000980e /* Creatix S0/16 P+P */
-#define VID_DYNALINK 0x88167506 /* Dynalink */
-#define VID_SEDLBAUER 0x0100274c /* Sedlbauer WinSpeed */
-#define VID_NICCYGO 0x5001814c /* Neuhaus Niccy GO@ */
-#define VID_ELSAQS1P 0x33019315 /* ELSA Quickstep1000pro*/
+#define VID_TEL163PNP 0x10212750 /* Teles 16.3 PnP */
+#define VID_CREATIXPP 0x0000980e /* Creatix S0/16 P+P */
+#define VID_DYNALINK 0x88167506 /* Dynalink */
+#define VID_SEDLBAUER 0x0100274c /* Sedlbauer WinSpeed */
+#define VID_NICCYGO 0x5001814c /* Neuhaus Niccy GO@ */
+#define VID_ELSAQS1P 0x33019315 /* ELSA Quickstep1000pro*/
+#define VID_ITK0025 0x25008b26 /* ITK Ix1 Micro V3 */
+#define VID_AVMPNP 0x0009cd06 /* AVM Fritz! PnP */
+#define VID_SIESURF2 0x2000254d /* Siemens I-Surf 2.0 PnP*/
+#define VID_ASUSCOM_IPAC 0x90167506 /* Asuscom (with IPAC) */
static struct i4b_pnp_ids {
u_long vend_id;
char *id_str;
} i4b_pnp_ids[] = {
- { VID_TEL163PNP, "Teles 16.3 PnP" },
- { VID_CREATIXPP, "Creatix S0/16 P+P" },
- { VID_DYNALINK, "Dynalink IS64PH" },
- { VID_SEDLBAUER, "Sedlbauer WinSpeed" },
- { VID_NICCYGO, "Dr.Neuhaus Niccy Go@" },
- { VID_ELSAQS1P, "ELSA QuickStep 1000pro"},
+ { VID_TEL163PNP, "Teles 16.3 PnP" },
+ { VID_CREATIXPP, "Creatix S0/16 P+P" },
+ { VID_DYNALINK, "Dynalink IS64PH" },
+ { VID_SEDLBAUER, "Sedlbauer WinSpeed" },
+ { VID_NICCYGO, "Dr.Neuhaus Niccy Go@" },
+ { VID_ELSAQS1P, "ELSA QuickStep 1000pro" },
+ { VID_ITK0025, "ITK ix1 Micro V3.0" },
+ { VID_AVMPNP, "AVM Fritz!Card PnP" },
+ { VID_SIESURF2, "Siemens I-Surf 2.0 PnP" },
+ { VID_ASUSCOM_IPAC, "Asuscom ISDNLink 128 PnP" },
{ 0 }
};
@@ -156,7 +164,9 @@ static void
i4b_pnp_attach(u_long csn, u_long vend_id, char *name, struct isa_device *dev)
{
struct pnp_cinfo spci;
+#if !((defined(__FreeBSD_version) && __FreeBSD_version >= 400004))
struct isa_device *isa_devp;
+#endif
if(dev->id_unit != next_isic_unit)
{
@@ -211,6 +221,18 @@ i4b_pnp_attach(u_long csn, u_long vend_id, char *name, struct isa_device *dev)
case VID_ELSAQS1P:
dev->id_flags = FLAG_ELSA_QS1P_ISA;
break;
+ case VID_ITK0025:
+ dev->id_flags = FLAG_ITK_IX1;
+ break;
+ case VID_AVMPNP:
+ dev->id_flags = FLAG_AVM_PNP;
+ break;
+ case VID_SIESURF2:
+ dev->id_flags = FLAG_SIEMENS_ISURF2;
+ break;
+ case VID_ASUSCOM_IPAC:
+ dev->id_flags = FLAG_ASUSCOM_IPAC;
+ break;
}
write_pnp_parms(&spci, 0);
@@ -287,6 +309,31 @@ isic_pnpprobe(struct isa_device *dev, unsigned int iobase2)
ret = isic_probe_Eqs1pi(dev, iobase2);
break;
#endif
+
+#ifdef ITKIX1
+ case FLAG_ITK_IX1:
+ ret = isic_probe_itkix1(dev);
+ break;
+#endif
+
+#ifdef AVM_PNP
+ case FLAG_AVM_PNP:
+ ret = isic_probe_avm_pnp(dev, iobase2);
+ break;
+#endif
+
+#ifdef SIEMENS_ISURF2
+ case FLAG_SIEMENS_ISURF2:
+ ret = isic_probe_siemens_isurf(dev, iobase2);
+ break;
+#endif
+
+#ifdef ASUSCOM_IPAC
+ case FLAG_ASUSCOM_IPAC:
+ ret = isic_probe_asi(dev, iobase2);
+ break;
+#endif
+
default:
break;
}
diff --git a/sys/i4b/layer1/i4b_l1.h b/sys/i4b/layer1/i4b_l1.h
index 6b455fa..f013bbb 100644
--- a/sys/i4b/layer1/i4b_l1.h
+++ b/sys/i4b/layer1/i4b_l1.h
@@ -27,9 +27,9 @@
* i4b_l1.h - isdn4bsd layer 1 header file
* ---------------------------------------
*
- * $Id: i4b_l1.h,v 1.61 1999/04/21 07:50:31 hm Exp $
+ * $Id: i4b_l1.h,v 1.64 1999/07/05 13:46:46 hm Exp $
*
- * last edit-date: [Tue Mar 16 15:50:24 1999]
+ * last edit-date: [Mon Jul 5 15:32:02 1999]
*
*---------------------------------------------------------------------------*/
@@ -48,42 +48,36 @@
/*---------------------------------------------------------------------------
* kernel config file flags definition
*---------------------------------------------------------------------------*/
- /* XXX: we do need these only for real ISA (not even ISAPNP cards), and only
- * because we are not confident enough in the general ISA probe routine (as
- * practiced by the NetBSD variant). *And* it is completely redundant to the
- * various options enabling only a few card's support routines to be compiled
- * in. Probably the current truth is: this is usefull for anybody with more
- * than one supported real ISA card. It is not usefull in generic configs,
- * nor in typical one-controller-only configurations.
- * Further - it is identical to the CARD_TYPEP_xxx definitions in
- * ../machine/i4b_ioctl.h.
- */
#define FLAG_TELES_S0_8 1
#define FLAG_TELES_S0_16 2
#define FLAG_TELES_S0_163 3
#define FLAG_AVM_A1 4
-#define FLAG_TELES_S0_163_PnP 5 /* XXX - not needed, remove! */
-#define FLAG_CREATIX_S0_PnP 6 /* XXX - not needed, remove! */
+#define FLAG_TELES_S0_163_PnP 5
+#define FLAG_CREATIX_S0_PnP 6
#define FLAG_USR_ISDN_TA_INT 7
-#define FLAG_DRN_NGO 8 /* XXX - not needed, remove! */
-#define FLAG_SWS 9 /* XXX - not needed, remove! */
-#define FLAG_AVM_A1_PCMCIA 10 /* XXX - not needed, remove! */
-#define FLAG_DYNALINK 11 /* XXX - not needed, remove! */
+#define FLAG_DRN_NGO 8
+#define FLAG_SWS 9
+#define FLAG_AVM_A1_PCMCIA 10
+#define FLAG_DYNALINK 11
#define FLAG_BLMASTER 12
-#define FLAG_ELSA_QS1P_ISA 13 /* XXX - not needed, remove! */
-#define FLAG_ELSA_QS1P_PCI 14 /* XXX - not needed, remove! */
+#define FLAG_ELSA_QS1P_ISA 13
+#define FLAG_ELSA_QS1P_PCI 14
#define FLAG_SIEMENS_ITALK 15
-#define FLAG_ELSA_MLIMC 16 /* XXX - not needed, remove! */
-#define FLAG_ELSA_MLMCALL 17 /* XXX - not needed, remove! */
+#define FLAG_ELSA_MLIMC 16
+#define FLAG_ELSA_MLMCALL 17
#define FLAG_ITK_IX1 18
-#define FLAG_ELSA_PCC16 19
+#define FLAG_AVMA1PCI 19
+#define FLAG_ELSA_PCC16 20
+#define FLAG_AVM_PNP 21
+#define FLAG_SIEMENS_ISURF2 22
+#define FLAG_ASUSCOM_IPAC 23
-#define SEC_DELAY 1000000 /* one second DELAY for DELAY*/
+#define SEC_DELAY 1000000 /* one second DELAY for DELAY*/
-#define MAX_DFRAME_LEN 264 /* max length of a D frame */
+#define MAX_DFRAME_LEN 264 /* max length of a D frame */
#ifndef __bsdi__
-#define min(a,b) ((a)<(b)?(a):(b))
+#define min(a,b) ((a)<(b)?(a):(b))
#endif
#if !defined(__FreeBSD__) && !defined(__bsdi__)
@@ -190,7 +184,7 @@ struct isic_softc
#endif
int sc_unit; /* unit number */
- int sc_irq; /* interrupt vector */
+ int sc_irq; /* interrupt vector */
#ifdef __FreeBSD__
int sc_port; /* port base address */
@@ -205,6 +199,7 @@ struct isic_softc
u_int sc_maddr; /* "memory address" for card config register */
int sc_num_mappings; /* number of io mappings provided */
struct isic_io_map *sc_maps;
+
#define MALLOC_MAPS(sc) \
(sc)->sc_maps = (struct isic_io_map*)malloc(sizeof((sc)->sc_maps[0])*(sc)->sc_num_mappings, M_DEVBUF, 0)
#endif
@@ -266,6 +261,7 @@ struct isic_softc
#endif
int sc_I430T4; /* Timer T4 running */
+
#if defined(__FreeBSD__) && __FreeBSD__ >=3
struct callout_handle sc_T4_callout;
#endif
@@ -396,7 +392,10 @@ extern int isic_attach_itkix1 ( struct isa_device *dev );
extern int isic_attach_drnngo ( struct isa_device *dev, unsigned int iobase2);
extern int isic_attach_sws ( struct isa_device *dev );
extern int isic_attach_Eqs1pi(struct isa_device *dev, unsigned int iobase2);
+extern int isic_attach_avm_pnp(struct isa_device *dev, unsigned int iobase2);
+extern int isic_attach_siemens_isurf(struct isa_device *dev, unsigned int iobase2);
extern int isic_attach_Eqs1pp(int unit, unsigned int iobase1, unsigned int iobase2);
+extern int isic_attach_asi(struct isa_device *dev, unsigned int iobase2);
extern void isic_bchannel_setup (int unit, int hscx_channel, int bprot, int activate );
extern int isic_hscx_fifo(isic_Bchan_t *, struct isic_softc *);
extern void isic_hscx_init ( struct isic_softc *sc, int hscx_channel, int activate );
@@ -412,6 +411,8 @@ extern void isic_next_state ( struct isic_softc *sc, int event );
extern char *isic_printstate ( struct isic_softc *sc );
extern int isic_probe_avma1 ( struct isa_device *dev );
extern int isic_probe_avma1_pcmcia ( struct isa_device *dev );
+extern int isic_probe_avm_pnp ( struct isa_device *dev, unsigned int iobase2);
+extern int isic_probe_siemens_isurf ( struct isa_device *dev, unsigned int iobase2);
extern int isic_probe_Cs0P ( struct isa_device *dev, unsigned int iobase2);
extern int isic_probe_Dyn ( struct isa_device *dev, unsigned int iobase2);
extern int isic_probe_s016 ( struct isa_device *dev );
@@ -423,6 +424,7 @@ extern int isic_probe_itkix1 ( struct isa_device *dev );
extern int isic_probe_drnngo ( struct isa_device *dev, unsigned int iobase2);
extern int isic_probe_sws ( struct isa_device *dev );
extern int isic_probe_Eqs1pi(struct isa_device *dev, unsigned int iobase2);
+extern int isic_probe_asi(struct isa_device *dev, unsigned int iobase2);
#elif defined(__bsdi__)
diff --git a/sys/i4b/layer1/i4b_siemens_isurf.c b/sys/i4b/layer1/i4b_siemens_isurf.c
new file mode 100644
index 0000000..09e6f47
--- /dev/null
+++ b/sys/i4b/layer1/i4b_siemens_isurf.c
@@ -0,0 +1,317 @@
+/*
+ * Copyright (c) 1999 Udo Schweigert. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ * 4. Altered versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software and/or documentation.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *---------------------------------------------------------------------------
+ * Based on ELSA Quickstep 1000pro PCI driver (i4b_elsa_qs1p.c)
+ *---------------------------------------------------------------------------
+ * In case of trouble please contact Udo Schweigert <ust@cert.siemens.de>
+ *---------------------------------------------------------------------------
+ *
+ * Siemens I-Surf 2.0 PnP specific routines for isic driver
+ * --------------------------------------------------------
+ *
+ * $Id: i4b_siemens_isurf.c,v 1.2 1999/07/05 13:22:12 hm Exp $
+ *
+ * last edit-date: [Mon 14 Jun 16:46:27 CEST 1999]
+ *
+ *---------------------------------------------------------------------------*/
+
+#if defined(__FreeBSD__)
+#include "isic.h"
+#include "opt_i4b.h"
+
+#if NISIC > 0 && defined(SIEMENS_ISURF2)
+
+#include <sys/param.h>
+#if defined(__FreeBSD__) && __FreeBSD__ >= 3
+#include <sys/ioccom.h>
+#else
+#include <sys/ioctl.h>
+#endif
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/mbuf.h>
+
+#include <machine/clock.h>
+#include <i386/isa/isa_device.h>
+
+#include <sys/socket.h>
+#include <net/if.h>
+
+#include <machine/i4b_debug.h>
+#include <machine/i4b_ioctl.h>
+
+#include <i4b/include/i4b_global.h>
+#include <i4b/include/i4b_l1l2.h>
+#include <i4b/include/i4b_mbuf.h>
+
+#include <i4b/layer1/i4b_l1.h>
+#include <i4b/layer1/i4b_ipac.h>
+#include <i4b/layer1/i4b_isac.h>
+#include <i4b/layer1/i4b_hscx.h>
+
+/* masks for register encoded in base addr */
+
+#define SIE_ISURF_BASE_MASK 0x0ffff
+#define SIE_ISURF_OFF_MASK 0xf0000
+
+/* register id's to be encoded in base addr */
+
+#define SIE_ISURF_IDISAC 0x00000
+#define SIE_ISURF_IDHSCXA 0x10000
+#define SIE_ISURF_IDHSCXB 0x20000
+#define SIE_ISURF_IDIPAC 0x40000
+
+/* offsets from base address */
+
+#define SIE_ISURF_OFF_ALE 0x00
+#define SIE_ISURF_OFF_RW 0x01
+
+/*---------------------------------------------------------------------------*
+ * Siemens I-Surf 2.0 PnP ISAC get fifo routine
+ *---------------------------------------------------------------------------*/
+
+static void
+siemens_isurf_read_fifo(void *buf, const void *base, size_t len)
+{
+ if(((u_int)base & SIE_ISURF_OFF_MASK) == SIE_ISURF_IDHSCXB)
+ {
+ outb((u_int)((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, IPAC_HSCXB_OFF);
+ insb((((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW), (u_char *)buf, (u_int)len);
+ }
+ else if(((u_int)base & SIE_ISURF_OFF_MASK) == SIE_ISURF_IDHSCXA)
+ {
+ outb((u_int)((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, IPAC_HSCXA_OFF);
+ insb((((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW), (u_char *)buf, (u_int)len);
+ }
+ else /* if(((u_int)base & SIE_ISURF_OFF_MASK) == SIE_ISURF_IDISAC) */
+ {
+ outb((u_int)((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, IPAC_ISAC_OFF);
+ insb((((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW), (u_char *)buf, (u_int)len);
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * Siemens I-Surf 2.0 PnP ISAC put fifo routine
+ *---------------------------------------------------------------------------*/
+
+static void
+siemens_isurf_write_fifo(void *base, const void *buf, size_t len)
+{
+ if(((u_int)base & SIE_ISURF_OFF_MASK) == SIE_ISURF_IDHSCXB)
+ {
+ outb((u_int)((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, IPAC_HSCXB_OFF);
+ outsb((((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW), (const u_char *)buf, (u_int)len);
+ }
+ else if(((u_int)base & SIE_ISURF_OFF_MASK) == SIE_ISURF_IDHSCXA)
+ {
+ outb((u_int)((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, IPAC_HSCXA_OFF);
+ outsb((((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW), (const u_char *)buf, (u_int)len);
+ }
+ else /* if(((u_int)base & SIE_ISURF_OFF_MASK) == SIE_ISURF_IDISAC) */
+ {
+ outb((u_int)((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, IPAC_ISAC_OFF);
+ outsb((((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW), (const u_char *)buf, (u_int)len);
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * Siemens I-Surf 2.0 PnP ISAC put register routine
+ *---------------------------------------------------------------------------*/
+
+static void
+siemens_isurf_write_reg(u_char *base, u_int offset, u_int v)
+{
+ if(((u_int)base & SIE_ISURF_OFF_MASK) == SIE_ISURF_IDHSCXB)
+ {
+ outb(((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, (u_char)(offset+IPAC_HSCXB_OFF));
+ outb(((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW, (u_char)v);
+ }
+ else if(((u_int)base & SIE_ISURF_OFF_MASK) == SIE_ISURF_IDHSCXA)
+ {
+ outb(((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, (u_char)(offset+IPAC_HSCXA_OFF));
+ outb(((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW, (u_char)v);
+ }
+ else if(((u_int)base & SIE_ISURF_OFF_MASK) == SIE_ISURF_IDISAC)
+ {
+ outb(((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, (u_char)(offset+IPAC_ISAC_OFF));
+ outb(((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW, (u_char)v);
+ }
+ else /* IPAC */
+ {
+ outb(((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, (u_char)(offset+IPAC_IPAC_OFF));
+ outb(((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW, (u_char)v);
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * Siemens I-Surf 2.0 PnP ISAC get register routine
+ *---------------------------------------------------------------------------*/
+
+static u_char
+siemens_isurf_read_reg(u_char *base, u_int offset)
+{
+ if(((u_int)base & SIE_ISURF_OFF_MASK) == SIE_ISURF_IDHSCXB)
+ {
+ outb((u_int)((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, (u_char)(offset+IPAC_HSCXB_OFF));
+ return(inb(((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW));
+ }
+ else if(((u_int)base & SIE_ISURF_OFF_MASK) == SIE_ISURF_IDHSCXA)
+ {
+ outb((u_int)((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, (u_char)(offset+IPAC_HSCXA_OFF));
+ return(inb(((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW));
+ }
+ else if(((u_int)base & SIE_ISURF_OFF_MASK) == SIE_ISURF_IDISAC)
+ {
+ outb((u_int)((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, (u_char)(offset+IPAC_ISAC_OFF));
+ return(inb(((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW));
+ }
+ else /* IPAC */
+ {
+ outb((u_int)((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, (u_char)(offset+IPAC_IPAC_OFF));
+ return(inb(((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW));
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * isic_probe_siemens_isurf - probe for Siemens I-Surf 2.0 PnP
+ *---------------------------------------------------------------------------*/
+
+int
+isic_probe_siemens_isurf(struct isa_device *dev, unsigned int iobase2)
+{
+ struct isic_softc *sc = &isic_sc[dev->id_unit];
+
+ /* check max unit range */
+
+ if(dev->id_unit >= ISIC_MAXUNIT)
+ {
+ printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for Siemens I-Surf 2.0 PnP\n",
+ dev->id_unit, dev->id_unit);
+ return(0);
+ }
+ sc->sc_unit = dev->id_unit;
+
+ /* check IRQ validity */
+
+ switch(ffs(dev->id_irq) - 1)
+ {
+ case 3:
+ case 4:
+ case 5:
+ case 7:
+ case 10:
+ case 11:
+ case 12:
+ case 15:
+ break;
+
+ default:
+ printf("isic%d: Error, invalid IRQ [%d] specified for Siemens I-Surf 2.0 PnP!\n",
+ dev->id_unit, ffs(dev->id_irq)-1);
+ return(0);
+ break;
+ }
+ sc->sc_irq = dev->id_irq;
+
+ /* check if memory addr specified */
+
+ if(dev->id_maddr)
+ {
+ printf("isic%d: Error, mem addr 0x%lx specified for Siemens I-Surf 2.0 PnP!\n",
+ dev->id_unit, (u_long)dev->id_maddr);
+ return(0);
+ }
+ dev->id_msize = 0;
+
+ /* check if we got an iobase */
+
+ if(!((dev->id_iobase >= 0x100) && (dev->id_iobase <= 0xff0)))
+ {
+ printf("isic%d: Error, invalid iobase 0x%x specified for Siemens I-Surf 2.0 PnP!\n",
+ dev->id_unit, dev->id_iobase);
+ return(0);
+ }
+ sc->sc_port = dev->id_iobase;
+
+
+ /* setup access routines */
+
+ sc->clearirq = NULL;
+ sc->readreg = siemens_isurf_read_reg;
+ sc->writereg = siemens_isurf_write_reg;
+
+ sc->readfifo = siemens_isurf_read_fifo;
+ sc->writefifo = siemens_isurf_write_fifo;
+
+ /* setup card type */
+
+ sc->sc_cardtyp = CARD_TYPEP_SIE_ISURF2;
+
+ /* setup IOM bus type */
+
+ sc->sc_bustyp = BUS_TYPE_IOM2;
+
+ /* setup chip type = IPAC ! */
+
+ sc->sc_ipac = 1;
+ sc->sc_bfifolen = IPAC_BFIFO_LEN;
+
+
+ return (1);
+}
+
+/*---------------------------------------------------------------------------*
+ * isic_attach_siemens_isurf - attach for Siemens I-Surf 2.0 PnP
+ *---------------------------------------------------------------------------*/
+int
+isic_attach_siemens_isurf(struct isa_device *dev, unsigned int iobase2)
+{
+ struct isic_softc *sc = &isic_sc[dev->id_unit];
+
+ /* setup ISAC and HSCX base addr */
+
+ ISAC_BASE = (caddr_t) ((u_int)sc->sc_port | SIE_ISURF_IDISAC);
+ HSCX_A_BASE = (caddr_t) ((u_int)sc->sc_port | SIE_ISURF_IDHSCXA);
+ HSCX_B_BASE = (caddr_t) ((u_int)sc->sc_port | SIE_ISURF_IDHSCXB);
+ IPAC_BASE = (caddr_t) ((u_int)sc->sc_port | SIE_ISURF_IDIPAC);
+
+ /* enable hscx/isac irq's */
+ IPAC_WRITE(IPAC_MASK, (IPAC_MASK_INT1 | IPAC_MASK_INT0));
+
+ IPAC_WRITE(IPAC_ACFG, 0); /* outputs are open drain */
+ IPAC_WRITE(IPAC_AOE, /* aux 5..2 are inputs, 7, 6 outputs */
+ (IPAC_AOE_OE5 | IPAC_AOE_OE4 | IPAC_AOE_OE3 | IPAC_AOE_OE2));
+ IPAC_WRITE(IPAC_ATX, 0xff); /* set all output lines high */
+
+ return(1);
+}
+#endif /* NISIC > 0 && defined(SIEMENS_ISURF2) */
+#endif /* FreeBSD */
diff --git a/sys/i4b/layer1/i4b_tel_s0163.c b/sys/i4b/layer1/i4b_tel_s0163.c
index efe9f34..4b6f1b5 100644
--- a/sys/i4b/layer1/i4b_tel_s0163.c
+++ b/sys/i4b/layer1/i4b_tel_s0163.c
@@ -37,9 +37,9 @@
* isic - I4B Siemens ISDN Chipset Driver for Teles S0/16.3
* ========================================================
*
- * $Id: i4b_tel_s0163.c,v 1.18 1999/02/14 19:51:02 hm Exp $
+ * $Id: i4b_tel_s0163.c,v 1.19 1999/07/26 09:03:25 hm Exp $
*
- * last edit-date: [Sun Feb 14 10:28:45 1999]
+ * last edit-date: [Mon Jul 26 10:59:38 1999]
*
* -hm clean up
* -hm more cleanup
@@ -212,7 +212,7 @@ isic_probe_s0163(struct isa_device *dev)
if(dev->id_unit >= ISIC_MAXUNIT)
{
- printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for Teles S0/16.3!",
+ printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for Teles S0/16.3!\n",
dev->id_unit, dev->id_unit);
return(0);
}
@@ -232,7 +232,7 @@ isic_probe_s0163(struct isa_device *dev)
if(dev->id_maddr)
{
- printf("isic%d: Error, mem addr 0x%lx specified for Teles S0/16.3!",
+ printf("isic%d: Error, mem addr 0x%lx specified for Teles S0/16.3!\n",
dev->id_unit, (u_long)dev->id_maddr);
return(0);
}
@@ -249,7 +249,7 @@ isic_probe_s0163(struct isa_device *dev)
break;
default:
- printf("isic%d: Error, invalid iobase 0x%x specified for Teles S0/16.3!",
+ printf("isic%d: Error, invalid iobase 0x%x specified for Teles S0/16.3!\n",
dev->id_unit, dev->id_iobase);
return(0);
break;
@@ -258,21 +258,21 @@ isic_probe_s0163(struct isa_device *dev)
if(((byte = inb(sc->sc_port)) != 0x51) && (byte != 0x10))
{
- printf("isic%d: Error, signature 1 0x%x != 0x51 or 0x10 for Teles S0/16.3!",
+ printf("isic%d: Error, signature 1 0x%x != 0x51 or 0x10 for Teles S0/16.3!\n",
dev->id_unit, byte);
return(0);
}
if((byte = inb(sc->sc_port + 1)) != 0x93)
{
- printf("isic%d: Error, signature 2 0x%x != 0x93 for Teles S0/16.3!",
+ printf("isic%d: Error, signature 2 0x%x != 0x93 for Teles S0/16.3!\n",
dev->id_unit, byte);
return(0);
}
if((byte = inb(sc->sc_port + 2)) != 0x1c)
{
- printf("isic%d: Error, signature 3 0x%x != 0x1c for Teles S0/16.3!",
+ printf("isic%d: Error, signature 3 0x%x != 0x1c for Teles S0/16.3!\n",
dev->id_unit, byte);
return(0);
}
@@ -359,7 +359,7 @@ set_softc(struct isic_softc *sc, struct isa_attach_args *ia, int unit)
break;
default:
- printf("isic%d: Error, invalid iobase 0x%x specified for Teles S0/16.3!",
+ printf("isic%d: Error, invalid iobase 0x%x specified for Teles S0/16.3!\n",
unit, ia->ia_iobase);
return(0);
break;
@@ -429,7 +429,7 @@ isic_probe_s0163(struct device *dev, struct cfdata *cf,
if(ia->ia_maddr)
{
- printf("isic%d: Error, mem addr 0x%lx specified for Teles S0/16.3!",
+ printf("isic%d: Error, mem addr 0x%lx specified for Teles S0/16.3!\n",
cf->cf_unit, (u_long)ia->ia_maddr);
return 0;
}
@@ -441,21 +441,21 @@ isic_probe_s0163(struct device *dev, struct cfdata *cf,
if((byte = inb(sc->sc_port)) != 0x51)
{
- printf("isic%d: Error, signature 1 0x%x != 0x51 for Teles S0/16.3!",
+ printf("isic%d: Error, signature 1 0x%x != 0x51 for Teles S0/16.3!\n",
cf->cf_unit, byte);
return(0);
}
if((byte = inb(sc->sc_port + 1)) != 0x93)
{
- printf("isic%d: Error, signature 2 0x%x != 0x93 for Teles S0/16.3!",
+ printf("isic%d: Error, signature 2 0x%x != 0x93 for Teles S0/16.3!\n",
cf->cf_unit, byte);
return(0);
}
if((byte = inb(sc->sc_port + 2)) != 0x1c)
{
- printf("isic%d: Error, signature 3 0x%x != 0x1c for Teles S0/16.3!",
+ printf("isic%d: Error, signature 3 0x%x != 0x1c for Teles S0/16.3!\n",
cf->cf_unit, byte);
return(0);
}
diff --git a/sys/i4b/layer1/isa_isic.c b/sys/i4b/layer1/isa_isic.c
index 7165e24..bd6b8c5 100644
--- a/sys/i4b/layer1/isa_isic.c
+++ b/sys/i4b/layer1/isa_isic.c
@@ -33,9 +33,9 @@
* isa_isic.c - ISA bus frontend for i4b_isic driver
* --------------------------------------------------
*
- * $Id: isa_isic.c,v 1.21 1999/02/23 14:51:18 hm Exp $
+ * $Id: isa_isic.c,v 1.23 1999/07/19 14:40:47 hm Exp $
*
- * last edit-date: [Sun Feb 14 10:29:11 1999]
+ * last edit-date: [Mon Jul 19 16:39:02 1999]
*
* -mh original implementation
* -hm NetBSD patches from Martin
@@ -115,6 +115,10 @@ isa_isic_probe(parent, cf, aux)
struct isic_attach_args args;
int ret = 0;
+#if 0
+ printf("isic%d: enter isa_isic_probe\n", cf->cf_unit);
+#endif
+
/* check irq */
if (ia->ia_irq == IRQUNK) {
printf("isic%d: config error: no IRQ specified\n", cf->cf_unit);
@@ -314,6 +318,10 @@ done:
/* unmap resources */
args_unmap(&args.ia_num_mappings, &args.ia_maps[0]);
+#if 0
+ printf("isic%d: exit isa_isic_probe, return = %d\n", cf->cf_unit, ret);
+#endif
+
return ret;
}
OpenPOWER on IntegriCloud