diff options
author | hm <hm@FreeBSD.org> | 1999-05-20 10:14:57 +0000 |
---|---|---|
committer | hm <hm@FreeBSD.org> | 1999-05-20 10:14:57 +0000 |
commit | 2077acfca034178f39e3fa4e86cb8d371f44737c (patch) | |
tree | 730187a2063473cb0d2e7cac998a9a4307285426 /sys/i4b/layer1 | |
parent | 5ea75aea8a2633cc0acf9dd870c1e1db1abd6a21 (diff) | |
download | FreeBSD-src-2077acfca034178f39e3fa4e86cb8d371f44737c.zip FreeBSD-src-2077acfca034178f39e3fa4e86cb8d371f44737c.tar.gz |
upgrade isdn4bsd from version 0.71 to the just released version 0.81
Diffstat (limited to 'sys/i4b/layer1')
-rw-r--r-- | sys/i4b/layer1/i4b_avm_fritz_pci.c | 530 | ||||
-rw-r--r-- | sys/i4b/layer1/i4b_avm_fritz_pcmcia.c | 9 | ||||
-rw-r--r-- | sys/i4b/layer1/i4b_bchan.c | 2 | ||||
-rw-r--r-- | sys/i4b/layer1/i4b_bsdi_ibc.c | 559 | ||||
-rw-r--r-- | sys/i4b/layer1/i4b_elsa_qs1i.c | 10 | ||||
-rw-r--r-- | sys/i4b/layer1/i4b_elsa_qs1p.c | 13 | ||||
-rw-r--r-- | sys/i4b/layer1/i4b_hscx.c | 23 | ||||
-rw-r--r-- | sys/i4b/layer1/i4b_isic.c | 6 | ||||
-rw-r--r-- | sys/i4b/layer1/i4b_isic_isa.c | 32 | ||||
-rw-r--r-- | sys/i4b/layer1/i4b_isic_pci.c | 18 | ||||
-rw-r--r-- | sys/i4b/layer1/i4b_isic_pcmcia.c | 24 | ||||
-rw-r--r-- | sys/i4b/layer1/i4b_isic_pnp.c | 13 | ||||
-rw-r--r-- | sys/i4b/layer1/i4b_l1.h | 8 | ||||
-rw-r--r-- | sys/i4b/layer1/i4b_tel_s0P.c | 2 | ||||
-rw-r--r-- | sys/i4b/layer1/isapnp_isic.c | 12 | ||||
-rw-r--r-- | sys/i4b/layer1/isic_supio.c | 30 | ||||
-rw-r--r-- | sys/i4b/layer1/pci_isic.c | 120 | ||||
-rw-r--r-- | sys/i4b/layer1/pci_isic.h | 53 | ||||
-rw-r--r-- | sys/i4b/layer1/pcmcia_isic.c | 6 |
19 files changed, 1309 insertions, 161 deletions
diff --git a/sys/i4b/layer1/i4b_avm_fritz_pci.c b/sys/i4b/layer1/i4b_avm_fritz_pci.c index da910b6..2da4f89 100644 --- a/sys/i4b/layer1/i4b_avm_fritz_pci.c +++ b/sys/i4b/layer1/i4b_avm_fritz_pci.c @@ -29,18 +29,24 @@ * SUCH DAMAGE. * *--------------------------------------------------------------------------- + * a lot of code was borrowed from i4b_bchan.c and i4b_hscx.c + *--------------------------------------------------------------------------- * * Fritz!Card PCI specific routines for isic driver * ------------------------------------------------ * - * $Id: i4b_avm_fritz_pci.c,v 1.1 1999/02/17 14:31:42 hm Exp $ + * $Id: i4b_avm_fritz_pci.c,v 1.5 1999/05/05 11:50:21 hm Exp $ * - * last edit-date: [Wed Feb 17 15:23:28 1999] + * last edit-date: [Tue Mar 16 16:18:35 1999] * *---------------------------------------------------------------------------*/ +#if defined(__FreeBSD__) #include "isic.h" #include "opt_i4b.h" +#else +#define NISIC 1 +#endif #if NISIC > 0 && defined(AVM_A1_PCI) @@ -54,15 +60,32 @@ #include <sys/systm.h> #include <sys/mbuf.h> +#ifdef __FreeBSD__ #include <machine/clock.h> #include <i386/isa/isa_device.h> #include <pci/pcivar.h> /* for pcici_t */ +#if __FreeBSD__ < 3 +#include <pci/pcireg.h> +#include <pci/pcibus.h> +#endif /* __FreeBSD__ < 3 */ +#else +#include <machine/bus.h> +#include <sys/device.h> +#endif #include <sys/socket.h> #include <net/if.h> +#ifdef __FreeBSD__ #include <machine/i4b_debug.h> #include <machine/i4b_ioctl.h> +#else +#include <dev/pci/pcireg.h> +#include <dev/pci/pcivar.h> +#include <dev/pci/pcidevs.h> +#include <i4b/i4b_debug.h> +#include <i4b/i4b_ioctl.h> +#endif #include <i4b/include/i4b_global.h> #include <i4b/include/i4b_l1l2.h> @@ -72,7 +95,20 @@ #include <i4b/layer1/i4b_isac.h> #include <i4b/layer1/i4b_hscx.h> +#ifndef __FreeBSD__ + +#include <i4b/layer1/pci_isic.h> + +/* PCI config map to use (only one in this driver) */ +#define FRITZPCI_PORT0_MAPOFF PCI_MAPREG_START+4 + +#endif + /* prototypes */ +static void avma1pp_disable(struct isic_softc *); + +#ifdef __FreeBSD__ + static void avma1pp_intr(struct isic_softc *); static void avma1pp_disable(struct isic_softc *); void avma1pp_map_int(pcici_t , void *, unsigned *); @@ -88,11 +124,30 @@ static void avma1pp_bchannel_setup(int, int, int, int); static void avma1pp_bchannel_start(int, int); static void avma1pp_hscx_init(struct isic_softc *, int, int); static void avma1pp_bchannel_stat(int, int, bchan_statistics_t *); -static void avma1pp_fifo(isic_Bchan_t *, struct isic_softc *); static void avma1pp_set_linktab(int, int, drvr_link_t *); static isdn_link_t * avma1pp_ret_linktab(int, int); +int isic_attach_avma1pp(int, u_int, u_int); extern void isicintr_sc(struct isic_softc *); +#else + +static int avma1pp_intr(void*); +static void avma1pp_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size); +static void avma1pp_write_fifo(struct isic_softc *sc, int what, const void *buf, size_t size); +static void avma1pp_write_reg(struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data); +static u_int8_t avma1pp_read_reg(struct isic_softc *sc, int what, bus_size_t offs); +static void hscx_write_fifo(int chan, const void *buf, size_t len, struct isic_softc *sc); +static void hscx_read_fifo(int chan, void *buf, size_t len, struct isic_softc *sc); +static void hscx_write_reg(int chan, u_int off, u_int val, struct isic_softc *sc); +static u_char hscx_read_reg(int chan, u_int off, struct isic_softc *sc); +static u_int hscx_read_reg_int(int chan, u_int off, struct isic_softc *sc); +static void avma1pp_fifo(isic_Bchan_t *chan, struct isic_softc *sc); +static void avma1pp_bchannel_stat(int unit, int h_chan, bchan_statistics_t *bsp); +static void avma1pp_map_int(struct pci_isic_softc *sc, struct pci_attach_args *pa); +static void avma1pp_bchannel_setup(int unit, int h_chan, int bprot, int activate); +static void avma1pp_init_linktab(struct isic_softc *); +#endif + /*---------------------------------------------------------------------------* * AVM PCI Fritz!Card special registers *---------------------------------------------------------------------------*/ @@ -105,20 +160,27 @@ extern void isicintr_sc(struct isic_softc *); #define ADDR_REG_OFFSET 0x04 /*#define MODREG_OFFSET 0x06 #define VERREG_OFFSET 0x07*/ + /* 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 PCI Status Latch 0 read only bits */ @@ -128,6 +190,7 @@ extern void isicintr_sc(struct isic_softc *); #define ASL_IRQ_BCHAN ASL_IRQ_HSCX /* actually active LOW */ #define ASL_IRQ_Pending (ASL_IRQ_ISAC | ASL_IRQ_HSCX | ASL_IRQ_TIMER) + /* * AVM Status Latch 0 write only bits */ @@ -136,6 +199,7 @@ extern void isicintr_sc(struct isic_softc *); #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 */ @@ -195,12 +259,16 @@ extern void isicintr_sc(struct isic_softc *); #define AVMA1PPSETCMDLONG(f) (f) = ((sc->avma1pp_cmd) | (sc->avma1pp_txl << 8) \ | (sc->avma1pp_prot << 16)) +#ifdef __FreeBSD__ + /* "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 +#endif /* __FreeBSD__ */ + /* * 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 @@ -212,6 +280,8 @@ extern void isicintr_sc(struct isic_softc *); /*---------------------------------------------------------------------------* * AVM read fifo routines *---------------------------------------------------------------------------*/ + +#ifdef __FreeBSD__ static void avma1pp_read_fifo(void *buf, const void *base, size_t len) { @@ -255,9 +325,49 @@ hscx_read_fifo(int chan, void *buf, size_t len, struct isic_softc *sc) } } +#else + +static void +avma1pp_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size) +{ + switch (what) { + case ISIC_WHAT_ISAC: + bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, ADDR_REG_OFFSET, ISAC_FIFO); + bus_space_read_multi_1(sc->sc_maps[0].t, sc->sc_maps[0].h, ISAC_REG_OFFSET, buf, size); + break; + case ISIC_WHAT_HSCXA: + hscx_read_fifo(0, buf, size, sc); + break; + case ISIC_WHAT_HSCXB: + hscx_read_fifo(1, buf, size, sc); + break; + } +} + +static void +hscx_read_fifo(int chan, void *buf, size_t len, struct isic_softc *sc) +{ + u_int32_t *ip; + size_t cnt; + + bus_space_write_4(sc->sc_maps[0].t, sc->sc_maps[0].h, ADDR_REG_OFFSET, chan); + ip = (u_int32_t *)buf; + cnt = 0; + /* what if len isn't a multiple of sizeof(int) and buf is */ + /* too small ???? */ + while (cnt < len) + { + *ip++ = bus_space_read_4(sc->sc_maps[0].t, sc->sc_maps[0].h, ISAC_REG_OFFSET); + cnt += 4; + } +} + +#endif + /*---------------------------------------------------------------------------* * AVM write fifo routines *---------------------------------------------------------------------------*/ +#ifdef __FreeBSD__ static void avma1pp_write_fifo(void *base, const void *buf, size_t len) { @@ -312,9 +422,60 @@ hscx_write_fifo(int chan, const void *buf, size_t len, struct isic_softc *sc) } } +#else + +static void +avma1pp_write_fifo(struct isic_softc *sc, int what, const void *buf, size_t size) +{ + switch (what) { + case ISIC_WHAT_ISAC: + bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, ADDR_REG_OFFSET, ISAC_FIFO); + bus_space_write_multi_1(sc->sc_maps[0].t, sc->sc_maps[0].h, ISAC_REG_OFFSET, (u_int8_t*)buf, size); + break; + case ISIC_WHAT_HSCXA: + hscx_write_fifo(0, buf, size, sc); + break; + case ISIC_WHAT_HSCXB: + hscx_write_fifo(1, buf, size, sc); + break; + } +} + +static void +hscx_write_fifo(int chan, const void *buf, size_t len, struct isic_softc *sc) +{ + u_int32_t *ip; + 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->bprot != BPROT_NONE) + sc->avma1pp_cmd |= HSCX_CMD_XME; + sc->avma1pp_txl = len; + } + + cnt = 0; /* borrow cnt */ + AVMA1PPSETCMDLONG(cnt); + hscx_write_reg(chan, HSCX_STAT, cnt, sc); + + ip = (u_int32_t *)buf; + cnt = 0; + while (cnt < len) + { + bus_space_write_4(sc->sc_maps[0].t, sc->sc_maps[0].h, ISAC_REG_OFFSET, *ip); + ip++; + cnt += 4; + } +} +#endif + /*---------------------------------------------------------------------------* * AVM write register routines *---------------------------------------------------------------------------*/ +#ifdef __FreeBSD__ static void avma1pp_write_reg(u_char *base, u_int offset, u_int v) { @@ -357,9 +518,49 @@ hscx_write_reg(int chan, u_int off, u_int val, struct isic_softc *sc) outl(sc->sc_port + ISAC_REG_OFFSET + off, val); } +#else + +static void +avma1pp_write_reg(struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data) +{ + u_char reg_bank; + switch (what) { + case ISIC_WHAT_ISAC: + reg_bank = (offs > MAX_LO_REG_OFFSET) ? ISAC_HI_REG_OFFSET:ISAC_LO_REG_OFFSET; +#ifdef AVMA1PCI_DEBUG + printf("write_reg bank %d off %ld.. ", (int)reg_bank, (long)offs); +#endif + /* set the register bank */ + bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, ADDR_REG_OFFSET, reg_bank); + bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, ISAC_REG_OFFSET + (offs & ISAC_REGSET_MASK), data); + break; + case ISIC_WHAT_HSCXA: + hscx_write_reg(0, offs, data, sc); + break; + case ISIC_WHAT_HSCXB: + hscx_write_reg(1, offs, data, sc); + break; + } +} + +static void +hscx_write_reg(int chan, u_int off, u_int val, struct isic_softc *sc) +{ + /* HACK */ + if (off == H_MASK) + return; + /* point at the correct channel */ + bus_space_write_4(sc->sc_maps[0].t, sc->sc_maps[0].h, ADDR_REG_OFFSET, chan); + bus_space_write_4(sc->sc_maps[0].t, sc->sc_maps[0].h, ISAC_REG_OFFSET + off, val); +} + +#endif + /*---------------------------------------------------------------------------* * AVM read register routines *---------------------------------------------------------------------------*/ +#ifdef __FreeBSD__ + static u_char avma1pp_read_reg(u_char *base, u_int offset) { @@ -385,6 +586,29 @@ avma1pp_read_reg(u_char *base, u_int offset) return(inb(sc->sc_port + ISAC_REG_OFFSET + (offset & ISAC_REGSET_MASK))); } +#else +static u_int8_t +avma1pp_read_reg(struct isic_softc *sc, int what, bus_size_t offs) +{ + u_char reg_bank; + switch (what) { + case ISIC_WHAT_ISAC: + reg_bank = (offs > MAX_LO_REG_OFFSET) ? ISAC_HI_REG_OFFSET:ISAC_LO_REG_OFFSET; +#ifdef AVMA1PCI_DEBUG + printf("read_reg bank %d off %ld.. ", (int)reg_bank, (long)offs); +#endif + /* set the register bank */ + bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, ADDR_REG_OFFSET, reg_bank); + return(bus_space_read_1(sc->sc_maps[0].t, sc->sc_maps[0].h, ISAC_REG_OFFSET + + (offs & ISAC_REGSET_MASK))); + case ISIC_WHAT_HSCXA: + return hscx_read_reg(0, offs, sc); + case ISIC_WHAT_HSCXB: + return hscx_read_reg(1, offs, sc); + } + return 0; +} +#endif static u_char hscx_read_reg(int chan, u_int off, struct isic_softc *sc) @@ -393,7 +617,7 @@ hscx_read_reg(int chan, u_int off, struct isic_softc *sc) } /* - * need to be able to reeturn an int because the RBCH is in the 2nd + * need to be able to return an int because the RBCH is in the 2nd * byte. */ static u_int @@ -403,13 +627,19 @@ hscx_read_reg_int(int chan, u_int off, struct isic_softc *sc) if (off == H_ISTA) return(0); /* point at the correct channel */ +#ifdef __FreeBSD__ outl(sc->sc_port + ADDR_REG_OFFSET, chan); return(inl(sc->sc_port + ISAC_REG_OFFSET + off)); +#else + bus_space_write_4(sc->sc_maps[0].t, sc->sc_maps[0].h, ADDR_REG_OFFSET, chan); + return(bus_space_read_4(sc->sc_maps[0].t, sc->sc_maps[0].h, ISAC_REG_OFFSET + off)); +#endif } /*---------------------------------------------------------------------------* * isic_attach_avma1pp - attach Fritz!Card PCI *---------------------------------------------------------------------------*/ +#ifdef __FreeBSD__ int isic_attach_avma1pp(int unit, u_int iobase1, u_int iobase2) { @@ -468,7 +698,6 @@ isic_attach_avma1pp(int unit, u_int iobase1, u_int iobase2) /* reset the card */ /* the Linux driver does this to clear any pending ISAC interrupts */ - /* see if it helps any - XXXX */ v = 0; v = ISAC_READ(I_STAR); #ifdef AVMA1PCI_DEBUG @@ -523,7 +752,6 @@ isic_attach_avma1pp(int unit, u_int iobase1, u_int iobase2) /* from here to the end would normally be done in isic_pciattach */ - /* sc->sc_isac_version = ((ISAC_READ(I_RBCH)) >> 5) & 0x03; */ 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'); @@ -536,10 +764,6 @@ isic_attach_avma1pp(int unit, u_int iobase1, u_int iobase2) avma1pp_bchannel_setup(sc->sc_unit, HSCX_CH_B, BPROT_NONE, 0); - /* XXXX - try it here too */ - /* outb(sc->sc_port + STAT1_OFFSET, ASL1_ENABLE_IOM|sc->sc_irq); - DELAY(SEC_DELAY/100); */ /* 10 ms */ - /* can't use the normal B-Channel stuff */ avma1pp_init_linktab(sc); @@ -573,6 +797,150 @@ isic_attach_avma1pp(int unit, u_int iobase1, u_int iobase2) return(1); } +#else + +void +isic_attach_fritzPci(struct pci_isic_softc *psc, struct pci_attach_args *pa) +{ + struct isic_softc *sc = &psc->sc_isic; + u_int v; + + isic_sc[sc->sc_unit] = sc; /* XXX - hack! */ + + /* setup io mappings */ + sc->sc_num_mappings = 1; + MALLOC_MAPS(sc); + sc->sc_maps[0].size = 0; + if (pci_mapreg_map(pa, FRITZPCI_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; + } + + /* setup access routines */ + + sc->clearirq = NULL; + sc->readreg = avma1pp_read_reg; + sc->writereg = avma1pp_write_reg; + + sc->readfifo = avma1pp_read_fifo; + sc->writefifo = avma1pp_write_fifo; + + + /* setup card type */ + + sc->sc_cardtyp = CARD_TYPEP_AVMA1PCI; + + /* setup IOM bus type */ + + sc->sc_bustyp = BUS_TYPE_IOM2; + + /* this is no IPAC based card */ + sc->sc_ipac = 0; + sc->sc_bfifolen = HSCX_FIFO_LEN; + + /* init the card */ + /* the Linux driver does this to clear any pending ISAC interrupts */ + /* see if it helps any - XXXX */ + v = 0; + v = ISAC_READ(I_STAR); +#ifdef AVMA1PCI_DEBUG + printf("avma1pp_attach: I_STAR %x...", v); +#endif + v = ISAC_READ(I_MODE); +#ifdef AVMA1PCI_DEBUG + printf("avma1pp_attach: I_MODE %x...", v); +#endif + v = ISAC_READ(I_ADF2); +#ifdef AVMA1PCI_DEBUG + printf("avma1pp_attach: I_ADF2 %x...", v); +#endif + v = ISAC_READ(I_ISTA); +#ifdef AVMA1PCI_DEBUG + printf("avma1pp_attach: I_ISTA %x...", v); +#endif + if (v & ISAC_ISTA_EXI) + { + v = ISAC_READ(I_EXIR); +#ifdef AVMA1PCI_DEBUG + printf("avma1pp_attach: I_EXIR %x...", v); +#endif + } + v = ISAC_READ(I_CIRR); +#ifdef AVMA1PCI_DEBUG + printf("avma1pp_attach: I_CIRR %x...", v); +#endif + ISAC_WRITE(I_MASK, 0xff); + /* the Linux driver does this to clear any pending HSCX interrupts */ + v = hscx_read_reg_int(0, HSCX_STAT, sc); +#ifdef AVMA1PCI_DEBUG + printf("avma1pp_attach: 0 HSCX_STAT %x...", v); +#endif + v = hscx_read_reg_int(1, HSCX_STAT, sc); +#ifdef AVMA1PCI_DEBUG + printf("avma1pp_attach: 1 HSCX_STAT %x\n", v); +#endif + + bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, STAT0_OFFSET, ASL_RESET_ALL|ASL_TIMERDISABLE); + DELAY(SEC_DELAY/100); /* 10 ms */ + bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, STAT0_OFFSET, ASL_TIMERRESET|ASL_ENABLE_INT|ASL_TIMERDISABLE); + DELAY(SEC_DELAY/100); /* 10 ms */ +#ifdef AVMA1PCI_DEBUG + bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, STAT1_OFFSET, ASL1_ENABLE_IOM|sc->sc_irq); + DELAY(SEC_DELAY/100); /* 10 ms */ + v = bus_space_read_1(sc->sc_maps[0].t, sc->sc_maps[0].h, STAT1_OFFSET); + printf("after reset: S1 %#x\n", v); + + v = bus_space_read_4(sc->sc_maps[0].t, sc->sc_maps[0].h, 0); + printf("isic_attach_avma1pp: v %#x\n", v); +#endif + + /* setup i4b infrastructure (have to roll our own here) */ + + /* sc->sc_isac_version = ((ISAC_READ(I_RBCH)) >> 5) & 0x03; */ + printf("%s: ISAC %s (IOM-%c)\n", sc->sc_dev.dv_xname, + "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" */ + avma1pp_bchannel_setup(sc->sc_unit, HSCX_CH_A, BPROT_NONE, 0); + + avma1pp_bchannel_setup(sc->sc_unit, HSCX_CH_B, BPROT_NONE, 0); + + /* can't use the normal B-Channel stuff */ + avma1pp_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; + + /* init higher protocol layers */ + + MPH_Status_Ind(sc->sc_unit, STI_ATTACH, sc->sc_cardtyp); + + /* setup interrupt mapping */ + avma1pp_map_int(psc, pa); +} + +#endif + /* * this is the real interrupt routine */ @@ -606,8 +974,7 @@ avma1pp_hscx_intr(int h_chan, u_int stat, struct isic_softc *sc) } /* - * The following is based on examination of the Linux driver. Who - * knows whether it's entirely correct ? + * 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. @@ -658,10 +1025,10 @@ avma1pp_hscx_intr(int h_chan, u_int stat, struct isic_softc *sc) if((chan->in_len + fifo_data_len) <= BCH_MAX_DATALEN) { - /* OK to copy the 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->in_len += fifo_data_len; /* setup mbuf data length */ @@ -762,7 +1129,7 @@ avma1pp_hscx_intr(int h_chan, u_int stat, struct isic_softc *sc) } /* if(error == 0) */ else { - /* land here for RDO */ + /* land here for RDO */ if (chan->in_mbuf != NULL) { i4b_Bfreembuf(chan->in_mbuf); @@ -789,9 +1156,6 @@ avma1pp_hscx_intr(int h_chan, u_int stat, struct isic_softc *sc) * for a description what is going on here, please have * a look at isic_bchannel_start() in i4b_bchan.c ! */ - - /* int len; - int nextlen; */ DBGL1(L1_H_IRQ, "avma1pp_hscx_intr", ("unit %d, chan %d - XPR, Tx Fifo Empty!\n", sc->sc_unit, h_chan)); @@ -834,7 +1198,7 @@ avma1pp_hscx_intr(int h_chan, u_int stat, struct isic_softc *sc) } } - avma1pp_fifo(chan, sc); + isic_hscx_fifo(chan, sc); } /* call timeout handling routine */ @@ -864,19 +1228,43 @@ avma1pp_hscx_int_handler(struct isic_softc *sc) static void avma1pp_disable(struct isic_softc *sc) { +#ifdef __FreeBSD__ outb(sc->sc_port + STAT0_OFFSET, ASL_RESET_ALL|ASL_TIMERDISABLE); +#else + bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, STAT0_OFFSET, ASL_RESET_ALL|ASL_TIMERDISABLE); +#endif } +#ifdef __FreeBSD__ static void avma1pp_intr(struct isic_softc *sc) { +#define OURS /* no return value accumulated */ +#define ISICINTR(sc) isicintr_sc(sc) +#else +static int +avma1pp_intr(void * parm) +{ + struct isic_softc *sc = parm; + int ret = 0; +#define OURS ret = 1 +#define ISICINTR(sc) isicintr(sc) +#endif u_char stat; +#ifdef __FreeBSD__ stat = inb(sc->sc_port + STAT0_OFFSET); +#else + stat = bus_space_read_1(sc->sc_maps[0].t, sc->sc_maps[0].h, STAT0_OFFSET); +#endif DBGL1(L1_H_IRQ, "avma1pp_intr", ("stat %x\n", stat)); /* was there an interrupt from this card ? */ if ((stat & ASL_IRQ_Pending) == ASL_IRQ_Pending) +#ifdef __FreeBSD__ return; /* no */ +#else + return 0; /* no */ +#endif /* interrupts are low active */ if (!(stat & ASL_IRQ_TIMER)) DBGL1(L1_H_IRQ, "avma1pp_intr", ("timer interrupt ???\n")); @@ -884,21 +1272,42 @@ avma1pp_intr(struct isic_softc *sc) { DBGL1(L1_H_IRQ, "avma1pp_intr", ("HSCX\n")); avma1pp_hscx_int_handler(sc); + OURS; } if (!(stat & ASL_IRQ_ISAC)) { DBGL1(L1_H_IRQ, "avma1pp_intr", ("ISAC\n")); - isicintr_sc(sc); + ISICINTR(sc); + OURS; } +#ifndef __FreeBSD__ + return ret; +#endif } +#ifdef __FreeBSD__ void avma1pp_map_int(pcici_t config_id, void *pisc, unsigned *net_imask) { struct isic_softc *sc = (struct isic_softc *)pisc; +#ifdef AVMA1PCI_DEBUG /* may need the irq later */ +#if __FreeBSD__ < 3 + /* I'd like to call getirq here, but it is static */ + sc->sc_irq = PCI_INTERRUPT_LINE_EXTRACT( + pci_conf_read (config_id, PCI_INTERRUPT_REG)); + + if (sc->sc_irq == 0 || sc->sc_irq == 0xff) + printf ("avma1pp_map_int:int line register not set by bios\n"); + + if (sc->sc_irq >= PCI_MAX_IRQ) + printf ("avma1pp_map_int:irq %d out of bounds (must be < %d)\n", + sc->sc_irq, PCI_MAX_IRQ); +#else sc->sc_irq = config_id->intline; +#endif +#endif /* AVMA1PCI_DEBUG */ if(!(pci_map_int(config_id, (void *)avma1pp_intr, sc, net_imask))) { @@ -907,6 +1316,36 @@ avma1pp_map_int(pcici_t config_id, void *pisc, unsigned *net_imask) avma1pp_disable(sc); } } +#else +static void +avma1pp_map_int(struct pci_isic_softc *psc, struct pci_attach_args *pa) +{ + struct isic_softc *sc = &psc->sc_isic; + pci_chipset_tag_t pc = pa->pa_pc; + pci_intr_handle_t ih; + const char *intrstr; + + /* Map and establish the interrupt. */ + if (pci_intr_map(pc, pa->pa_intrtag, pa->pa_intrpin, + pa->pa_intrline, &ih)) { + printf("%s: couldn't map interrupt\n", sc->sc_dev.dv_xname); + avma1pp_disable(sc); + return; + } + intrstr = pci_intr_string(pc, ih); + psc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, avma1pp_intr, sc); + if (psc->sc_ih == NULL) { + printf("%s: couldn't establish interrupt", + sc->sc_dev.dv_xname); + if (intrstr != NULL) + printf(" at %s", intrstr); + printf("\n"); + avma1pp_disable(sc); + return; + } + printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr); +} +#endif static void avma1pp_hscx_init(struct isic_softc *sc, int h_chan, int activate) @@ -986,7 +1425,7 @@ avma1pp_bchannel_setup(int unit, int h_chan, int bprot, int activate) /* general part */ chan->unit = sc->sc_unit; /* unit number */ - chan->channel = h_chan; /* B channel */ + chan->channel = h_chan; /* B channel */ chan->bprot = bprot; /* B channel protocol */ chan->state = HSCX_IDLE; /* B channel state */ @@ -1037,19 +1476,9 @@ avma1pp_bchannel_start(int unit, int h_chan) #else struct isic_softc *sc = isic_find_sc(unit); #endif - register isic_Bchan_t *chan = &sc->sc_chan[h_chan]; - int s; int activity = -1; -#if 0 /* moved to avma1pp_fifo */ - /* the "HSCX" probably only allows writing all bytes at once */ - /* so we need a scratch buffer to collect the bytes */ - u_char scrbuf[HSCX_FIFO_LEN]; - int i; - register int next_len; - register int len; -#endif s = SPLI4B(); /* enter critical section */ if(chan->state & HSCX_TX_ACTIVE) /* already running ? */ @@ -1099,7 +1528,7 @@ avma1pp_bchannel_start(int unit, int h_chan) MPH_Trace_Ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data); } - avma1pp_fifo(chan, sc); + isic_hscx_fifo(chan, sc); /* call timeout handling routine */ @@ -1215,21 +1644,31 @@ avma1pp_bchannel_stat(int unit, int h_chan, bchan_statistics_t *bsp) splx(s); } -/* - * moved here from avma1pp_bchan_start and avma1pp_hscx_intr - */ -static void -avma1pp_fifo(isic_Bchan_t *chan, struct isic_softc *sc) +/*---------------------------------------------------------------------------* + * 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; - /* the "HSCX" probably only allows writing all bytes at once */ - /* so we need a scratch buffer to collect the bytes */ + int cmd; + /* 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); @@ -1244,9 +1683,10 @@ avma1pp_fifo(isic_Bchan_t *chan, struct isic_softc *sc) nextlen); #endif + cmd |= HSCX_CMDR_XTF; /* collect the data in the scratch buffer */ for (i = 0; i < nextlen; i++) - scrbuf[i + len] = chan->out_mbuf_cur_ptr[i]; + scrbuf[i + len] = chan->out_mbuf_cur_ptr[i]; len += nextlen; chan->txcount += nextlen; @@ -1274,15 +1714,17 @@ avma1pp_fifo(isic_Bchan_t *chan, struct isic_softc *sc) } else { + if (chan->bprot != BPROT_NONE) + cmd |= HSCX_CMDR_XME; i4b_Bfreembuf(chan->out_mbuf_head); chan->out_mbuf_head = NULL; } } } - /* write what we have from the scratch buf to the "HSCX" fifo */ - - /* HSCX_WRFIFO also sets the XME */ - HSCX_WRFIFO(chan->channel, scrbuf, len); + /* write what we have from the scratch buf to the HSCX fifo */ + if (len != 0) + HSCX_WRFIFO(chan->channel, scrbuf, len); + return(cmd); } #endif /* NISIC > 0 && defined(AVM_A1_PCI) */ diff --git a/sys/i4b/layer1/i4b_avm_fritz_pcmcia.c b/sys/i4b/layer1/i4b_avm_fritz_pcmcia.c index 03029a0..a6f0ad8 100644 --- a/sys/i4b/layer1/i4b_avm_fritz_pcmcia.c +++ b/sys/i4b/layer1/i4b_avm_fritz_pcmcia.c @@ -33,9 +33,9 @@ * Fritz!Card pcmcia specific routines for isic driver * --------------------------------------------------- * - * $Id: i4b_avm_fritz_pcmcia.c,v 1.2 1999/03/07 16:08:15 hm Exp $ + * $Id: i4b_avm_fritz_pcmcia.c,v 1.12 1999/05/03 08:48:25 hm Exp $ * - * last edit-date: [Tue Mar 16 10:49:53 1999] + * last edit-date: [Sun May 2 12:01:16 1999] * * -ap added support for AVM PCMCIA Fritz!Card * -mh split into separate file @@ -80,7 +80,6 @@ #include <i4b/i4b_ioctl.h> #include <dev/pcmcia/pcmciareg.h> #include <dev/pcmcia/pcmciavar.h> -#include <i4b/layer1/pcmcia_isic.h> #endif #include <i4b/layer1/i4b_l1.h> @@ -88,6 +87,8 @@ #include <i4b/layer1/i4b_hscx.h> #ifndef __FreeBSD__ +#include <i4b/layer1/pcmcia_isic.h> + /* PCMCIA support routines */ static u_int8_t avma1_pcmcia_read_reg __P((struct isic_softc *sc, int what, bus_size_t offs)); static void avma1_pcmcia_write_reg __P((struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data)); @@ -390,7 +391,7 @@ isic_probe_avma1_pcmcia(struct isa_device *dev) *---------------------------------------------------------------------------*/ #ifdef __FreeBSD__ int -isic_attach_fritz(struct isa_device *dev) +isic_attach_fritzpcmcia(struct isa_device *dev) { /* ResetController again just to make sure... */ diff --git a/sys/i4b/layer1/i4b_bchan.c b/sys/i4b/layer1/i4b_bchan.c index e047c93..bd9dfd0 100644 --- a/sys/i4b/layer1/i4b_bchan.c +++ b/sys/i4b/layer1/i4b_bchan.c @@ -27,7 +27,7 @@ * i4b_bchan.c - B channel handling L1 procedures * ---------------------------------------------- * - * $Id: i4b_bchan.c,v 1.30 1999/02/14 19:51:01 hm Exp $ + * $Id: i4b_bchan.c,v 1.32 1999/03/17 10:41:08 hm Exp $ * * last edit-date: [Sun Feb 14 10:25:27 1999] * diff --git a/sys/i4b/layer1/i4b_bsdi_ibc.c b/sys/i4b/layer1/i4b_bsdi_ibc.c new file mode 100644 index 0000000..9168815 --- /dev/null +++ b/sys/i4b/layer1/i4b_bsdi_ibc.c @@ -0,0 +1,559 @@ +/* + * 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_elsa_qs1i.c b/sys/i4b/layer1/i4b_elsa_qs1i.c index d43a637..573bb86 100644 --- a/sys/i4b/layer1/i4b_elsa_qs1i.c +++ b/sys/i4b/layer1/i4b_elsa_qs1i.c @@ -27,9 +27,9 @@ * isic - I4B Siemens ISDN Chipset Driver for ELSA Quickstep 1000pro ISA * ===================================================================== * - * $Id: i4b_elsa_qs1i.c,v 1.14 1999/02/14 11:02:04 hm Exp $ + * $Id: i4b_elsa_qs1i.c,v 1.15 1999/03/16 14:57:53 hm Exp $ * - * last edit-date: [Sun Feb 14 11:59:45 1999] + * last edit-date: [Tue Mar 16 15:42:10 1999] * *---------------------------------------------------------------------------*/ @@ -46,7 +46,11 @@ #endif -#if (NISIC > 0) && (NPNP > 0) && defined(ELSA_QS1ISA) +/* + * this driver works for both the ELSA QuickStep 1000 PNP and the ELSA + * PCC-16 + */ +#if (NISIC > 0) && (((NPNP > 0) && defined(ELSA_QS1ISA)) || defined(ELSA_PCC16)) #include <sys/param.h> #include <sys/kernel.h> diff --git a/sys/i4b/layer1/i4b_elsa_qs1p.c b/sys/i4b/layer1/i4b_elsa_qs1p.c index 43dd343..0cc0a01 100644 --- a/sys/i4b/layer1/i4b_elsa_qs1p.c +++ b/sys/i4b/layer1/i4b_elsa_qs1p.c @@ -27,9 +27,9 @@ * isic - I4B Siemens ISDN Chipset Driver for ELSA Quickstep 1000pro PCI * ===================================================================== * - * $Id: i4b_elsa_qs1p.c,v 1.5 1999/02/14 09:44:59 hm Exp $ + * $Id: i4b_elsa_qs1p.c,v 1.6 1999/03/16 15:21:55 hm Exp $ * - * last edit-date: [Sun Feb 14 10:26:43 1999] + * last edit-date: [Wed Mar 10 07:24:32 1999] * *---------------------------------------------------------------------------*/ @@ -86,8 +86,7 @@ #include <i4b/layer1/i4b_ipac.h> #ifndef __FreeBSD__ -/* we don't have the function prototypes in the global i4b_l1.h any more */ -void isic_attach_Eqs1pp __P((struct isic_softc *sc, struct pci_attach_args *pa)); +#include <i4b/layer1/pci_isic.h> #endif /* masks for register encoded in base addr */ @@ -400,10 +399,12 @@ isic_attach_Eqs1pp(int unit, unsigned int iobase1, unsigned int iobase2) #else /* !FreeBSD */ void -isic_attach_Eqs1pp(sc, pa) - struct isic_softc *sc; +isic_attach_Eqs1pp(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); diff --git a/sys/i4b/layer1/i4b_hscx.c b/sys/i4b/layer1/i4b_hscx.c index 29c2f40..4ddf779 100644 --- a/sys/i4b/layer1/i4b_hscx.c +++ b/sys/i4b/layer1/i4b_hscx.c @@ -27,9 +27,9 @@ * i4b - Siemens HSCX chip (B-channel) handling * -------------------------------------------- * - * $Id: i4b_hscx.c,v 1.39 1999/02/14 19:51:01 hm Exp $ + * $Id: i4b_hscx.c,v 1.42 1999/03/17 13:44:50 hm Exp $ * - * last edit-date: [Sun Feb 14 10:26:49 1999] + * last edit-date: [Wed Mar 17 11:59:05 1999] * *---------------------------------------------------------------------------*/ @@ -288,14 +288,23 @@ isic_hscx_irq(register struct isic_softc *sc, u_char ista, int h_chan, u_char ex 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); + /* silence detection */ - (*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; + + if(!(IF_QFULL(&chan->rx_queue))) + { + IF_ENQUEUE(&chan->rx_queue, chan->in_mbuf); + } + else + { + i4b_Bfreembuf(chan->in_mbuf); + } + + /* signal upper driver that data is available */ + + (*chan->drvr_linktab->bch_rx_data_ready)(chan->drvr_linktab->unit); /* alloc new buffer */ diff --git a/sys/i4b/layer1/i4b_isic.c b/sys/i4b/layer1/i4b_isic.c index 127fae2..f403faf 100644 --- a/sys/i4b/layer1/i4b_isic.c +++ b/sys/i4b/layer1/i4b_isic.c @@ -27,7 +27,7 @@ * i4b_isic.c - global isic stuff * ============================== * - * $Id: i4b_isic.c,v 1.46 1999/02/14 19:51:02 hm Exp $ + * $Id: i4b_isic.c,v 1.47 1999/04/20 09:34:14 hm Exp $ * * last edit-date: [Sun Feb 14 10:27:20 1999] * @@ -209,7 +209,7 @@ isicintr(void *arg) was_isac_irq = 1; } } -#ifndef amiga /* XXX should be: #if INTERUPTS_ARE_SHARED */ +#if !defined(amiga) && !defined(atari) /* XXX should be: #if INTS_ARE_SHARED */ #ifdef ELSA_QS1ISA if(sc->sc_cardtyp != CARD_TYPEP_ELSAQS1ISA) { @@ -219,7 +219,7 @@ isicintr(void *arg) #ifdef ELSA_QS1ISA } #endif -#endif /* AMIGA */ +#endif /* !AMIGA && !ATARI */ HSCX_WRITE(0, H_MASK, 0xff); ISAC_WRITE(I_MASK, 0xff); diff --git a/sys/i4b/layer1/i4b_isic_isa.c b/sys/i4b/layer1/i4b_isic_isa.c index aa722c0..4147355 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.2 1999/03/07 16:08:15 hm Exp $ + * $Id: i4b_isic_isa.c,v 1.20 1999/05/10 09:37:35 hm Exp $ * - * last edit-date: [Tue Mar 16 10:35:38 1999] + * last edit-date: [Tue Apr 20 11:47:59 1999] * *---------------------------------------------------------------------------*/ @@ -98,7 +98,7 @@ void isicintr ( int unit ); void isicintr_sc(struct isic_softc *sc); static int isicprobe(struct isa_device *dev); -static int isicattach(struct isa_device *dev); +int isicattach(struct isa_device *dev); struct isa_driver isicdriver = { isicprobe, @@ -198,6 +198,12 @@ isicprobe(struct isa_device *dev) break; #endif +#ifdef ELSA_PCC16 + case FLAG_ELSA_PCC16: + ret = isic_probe_Eqs1pi(dev, 0); + break; +#endif + default: break; } @@ -250,6 +256,12 @@ isa_isicmatch(struct device *parent, struct cfdata *cf, struct isa_attach_args * break; #endif +#ifdef ELSA_PCC16 + case FLAG_ELSA_PCC16: + ret = isic_probe_Eqs1pi(dev, 0); + break; +#endif + default: break; } @@ -274,7 +286,7 @@ isicprobe(struct isic_attach_args *args) /*---------------------------------------------------------------------------* * isic - non-pnp device driver attach routine *---------------------------------------------------------------------------*/ -static int +int isicattach(struct isa_device *dev) { return(isic_realattach(dev, 0)); @@ -395,6 +407,12 @@ isicattach(int flags, struct isic_softc *sc) break; #endif +#ifdef ELSA_PCC16 + case FLAG_ELSA_PCC16: + ret = isic_attach_Eqs1pi(dev, 0); + break; +#endif + /* ====================================================================== * Only P&P cards follow below!!! */ @@ -404,7 +422,7 @@ isicattach(int flags, struct isic_softc *sc) #ifdef AVM_A1_PCMCIA case FLAG_AVM_A1_PCMCIA: - ret = isic_attach_fritz(PARM); + ret = isic_attach_fritzpcmcia(PARM); break; #endif @@ -592,6 +610,10 @@ isicattach(int flags, struct isic_softc *sc) drvid = "ITK ix1 micro"; break; + case FLAG_ELSA_PCC16: + drvid = "ELSA PCC-16"; + break; + default: drvid = "ERROR, unknown flag used"; break; diff --git a/sys/i4b/layer1/i4b_isic_pci.c b/sys/i4b/layer1/i4b_isic_pci.c index c17dfc6..f732dd1 100644 --- a/sys/i4b/layer1/i4b_isic_pci.c +++ b/sys/i4b/layer1/i4b_isic_pci.c @@ -27,9 +27,9 @@ * i4b_isic_pci.c - PCI bus interface * ================================== * - * $Id: i4b_isic_pci.c,v 1.4 1999/04/24 20:24:02 peter Exp $ + * $Id: i4b_isic_pci.c,v 1.14 1999/04/28 04:12:51 hm Exp $ * - * last edit-date: [Wed Feb 17 15:19:44 1999] + * last edit-date: [Wed Apr 21 09:57:37 1999] * *---------------------------------------------------------------------------*/ @@ -88,7 +88,7 @@ #define PORT0_MAPOFF 4 #define PORT1_MAPOFF 12 -static char* i4b_pci_probe(pcici_t tag, pcidi_t type); +static const char *i4b_pci_probe(pcici_t tag, pcidi_t type); static void i4b_pci_attach(pcici_t config_id, int unit); static int isic_pciattach(int unit, u_long type, u_int iobase1, u_int iobase2); @@ -102,7 +102,15 @@ static struct pci_device i4b_pci_driver = { NULL }; +#if defined(__FreeBSD_version) && __FreeBSD_version >= 400004 +#ifndef COMPAT_PCI_DRIVER +DATA_SET (pcidevice_set, i4b_pci_driver); +#else COMPAT_PCI_DRIVER (isic_pci, i4b_pci_driver); +#endif /* COMPAT_PCI_DRIVER */ +#else /* __FreeBSD_version >= 400004 */ +DATA_SET (pcidevice_set, i4b_pci_driver); +#endif /* __FreeBSD_version >= 400004 */ static void isic_pci_intr_sc(struct isic_softc *sc); @@ -114,7 +122,7 @@ extern void avma1pp_map_int(pcici_t, void *, unsigned *); /*---------------------------------------------------------------------------* * PCI probe routine *---------------------------------------------------------------------------*/ -static char * +static const char * i4b_pci_probe(pcici_t tag, pcidi_t type) { switch(type) @@ -151,7 +159,7 @@ i4b_pci_attach(pcici_t config_id, int unit) return; } - /* IMHO the all following should be done in the low-level driver - GJ */ + /* IMHO all the following should be done in the low-level driver - GJ */ type = pci_conf_read(config_id, PCI_ID_REG); /* not all cards have their ports at the same location !!! */ diff --git a/sys/i4b/layer1/i4b_isic_pcmcia.c b/sys/i4b/layer1/i4b_isic_pcmcia.c index 47f78e4..f6ceb5d 100644 --- a/sys/i4b/layer1/i4b_isic_pcmcia.c +++ b/sys/i4b/layer1/i4b_isic_pcmcia.c @@ -35,14 +35,13 @@ * i4b_isic_pcmcia.c - i4b FreeBSD PCMCIA support * ---------------------------------------------- * - * $Id: i4b_isic_pcmcia.c,v 1.5 1999/03/16 11:07:04 hm Exp $ + * $Id: i4b_isic_pcmcia.c,v 1.9 1999/04/27 09:49:49 hm Exp $ * - * last edit-date: [Tue Mar 16 10:36:56 1999] + * last edit-date: [Mon Apr 26 10:52:57 1999] * *---------------------------------------------------------------------------*/ #ifdef __FreeBSD__ - #include "isic.h" #include "opt_i4b.h" #include "card.h" @@ -53,9 +52,9 @@ #include <sys/types.h> #include <sys/select.h> #include <sys/param.h> +#include <i386/isa/isa_device.h> #if defined(__FreeBSD__) && __FreeBSD__ >= 3 -#include <sys/module.h> #include <sys/ioccom.h> #else #include <sys/ioctl.h> @@ -89,10 +88,14 @@ #if !(defined(__FreeBSD_version)) || (defined(__FreeBSD_version) && __FreeBSD_version >= 300006) void isicintr ( int unit ); +#else +extern void isicintr(int unit); #endif #endif +extern int isicattach(struct isa_device *dev); + /* * PC-Card (PCMCIA) specific code. */ @@ -100,9 +103,7 @@ static int isic_pccard_init __P((struct pccard_devinfo *)); static void isic_unload __P((struct pccard_devinfo *)); static int isic_card_intr __P((struct pccard_devinfo *)); -#ifdef PCCARD_MODULE -PCCARD_MODULE(isic_pcmcia, isic_pccard_init, isic_unload, isic_card_intr, 0, net_imask); -#else +#if defined(__FreeBSD__) && __FreeBSD__ < 3 static struct pccard_device isic_info = { "isic", isic_pccard_init, @@ -110,11 +111,14 @@ static struct pccard_device isic_info = { isic_card_intr, 0, /* Attributes - presently unused */ &net_imask -}; - +}; + DATA_SET(pccarddrv_set, isic_info); +#else +PCCARD_MODULE(isic, isic_pccard_init, isic_unload, isic_card_intr, 0,net_imask); #endif + /* * Initialize the device - called from Slot manager. */ @@ -124,6 +128,7 @@ static int opened = 0; /* our cards status */ static int isic_pccard_init(devi) struct pccard_devinfo *devi; { +#ifdef AVM_A1_PCMCIA struct isa_device *is = &devi->isahd; if ((1 << is->id_unit) & opened) @@ -149,6 +154,7 @@ struct pccard_devinfo *devi; isic_realattach(is, 0); +#endif return(0); } diff --git a/sys/i4b/layer1/i4b_isic_pnp.c b/sys/i4b/layer1/i4b_isic_pnp.c index eddfb9d..a9f056a 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.2 1999/03/07 16:08:16 hm Exp $ + * $Id: i4b_isic_pnp.c,v 1.17 1999/04/20 14:28:46 hm Exp $ * - * last edit-date: [Sun Feb 14 10:27:52 1999] + * last edit-date: [Tue Apr 20 16:12:27 1999] * *---------------------------------------------------------------------------*/ @@ -219,7 +219,16 @@ i4b_pnp_attach(u_long csn, u_long vend_id, char *name, struct isa_device *dev) if(dev->id_driver == NULL) { dev->id_driver = &isicdriver; +#if(defined(__FreeBSD_version) && __FreeBSD_version >= 400004) dev->id_id = isa_compat_nextid(); +#else + isa_devp = find_isadev(isa_devtab_net, &isicdriver, 0); + + if(isa_devp != NULL) + { + dev->id_id = isa_devp->id_id; + } +#endif } if((dev->id_alive = isic_pnpprobe(dev, spci.port[1])) != 0) diff --git a/sys/i4b/layer1/i4b_l1.h b/sys/i4b/layer1/i4b_l1.h index f00598a..6b455fa 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.2 1999/03/07 16:08:16 hm Exp $ + * $Id: i4b_l1.h,v 1.61 1999/04/21 07:50:31 hm Exp $ * - * last edit-date: [Tue Mar 16 10:38:03 1999] + * last edit-date: [Tue Mar 16 15:50:24 1999] * *---------------------------------------------------------------------------*/ @@ -76,6 +76,7 @@ #define FLAG_ELSA_MLIMC 16 /* XXX - not needed, remove! */ #define FLAG_ELSA_MLMCALL 17 /* XXX - not needed, remove! */ #define FLAG_ITK_IX1 18 +#define FLAG_ELSA_PCC16 19 #define SEC_DELAY 1000000 /* one second DELAY for DELAY*/ @@ -383,7 +384,7 @@ extern struct isic_softc isic_sc[]; extern void isic_recover(struct isic_softc *sc); extern int isic_realattach(struct isa_device *dev, unsigned int iobase2); extern int isic_attach_avma1 ( struct isa_device *dev ); -extern int isic_attach_fritz ( struct isa_device *dev ); +extern int isic_attach_fritzpcmcia ( struct isa_device *dev ); extern int isic_attach_Cs0P ( struct isa_device *dev, unsigned int iobase2); extern int isic_attach_Dyn ( struct isa_device *dev, unsigned int iobase2); extern int isic_attach_s016 ( struct isa_device *dev ); @@ -397,6 +398,7 @@ 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_Eqs1pp(int unit, unsigned int iobase1, 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 ); extern void isic_hscx_irq ( struct isic_softc *sc, u_char ista, int hscx_channel, u_char ex_irq ); extern int isic_hscx_silence ( unsigned char *data, int len ); diff --git a/sys/i4b/layer1/i4b_tel_s0P.c b/sys/i4b/layer1/i4b_tel_s0P.c index 7ee1d06..f0315b0 100644 --- a/sys/i4b/layer1/i4b_tel_s0P.c +++ b/sys/i4b/layer1/i4b_tel_s0P.c @@ -38,7 +38,7 @@ * EXPERIMENTAL !!! * ================ * - * $Id: i4b_tel_s0P.c,v 1.2 1999/03/07 16:08:16 hm Exp $ + * $Id: i4b_tel_s0P.c,v 1.14 1999/03/16 11:12:31 hm Exp $ * * last edit-date: [Tue Mar 16 10:39:14 1999] * diff --git a/sys/i4b/layer1/isapnp_isic.c b/sys/i4b/layer1/isapnp_isic.c index c340d8f..a902995 100644 --- a/sys/i4b/layer1/isapnp_isic.c +++ b/sys/i4b/layer1/isapnp_isic.c @@ -33,9 +33,9 @@ * isapnp_isic.c - ISA-P&P bus frontend for i4b_isic driver * -------------------------------------------------------- * - * $Id: isapnp_isic.c,v 1.10 1999/02/14 09:45:00 hm Exp $ + * $Id: isapnp_isic.c,v 1.11 1999/05/03 08:48:25 hm Exp $ * - * last edit-date: [Sun Feb 14 10:29:15 1999] + * last edit-date: [Sun May 2 11:57:08 1999] * * -mh original implementation * -hm NetBSD patches from Martin @@ -92,8 +92,12 @@ typedef void (*attach_func)(struct isic_softc *sc); /* map allocators */ static void generic_pnp_mapalloc(struct isapnp_attach_args *ipa, struct isic_softc *sc); +#ifdef DRN_NGO static void ngo_pnp_mapalloc(struct isapnp_attach_args *ipa, struct isic_softc *sc); +#endif +#if defined(CRTX_S0_P) || defined(TEL_S0_16_3_P) static void tls_pnp_mapalloc(struct isapnp_attach_args *ipa, struct isic_softc *sc); +#endif /* card attach functions */ extern void isic_attach_Cs0P __P((struct isic_softc *sc)); @@ -350,6 +354,7 @@ generic_pnp_mapalloc(struct isapnp_attach_args *ipa, struct isic_softc *sc) sc->sc_maps[0].size = 0; /* foreign mapping, leave it alone */ } +#ifdef DRN_NGO static void ngo_pnp_mapalloc(struct isapnp_attach_args *ipa, struct isic_softc *sc) { @@ -362,7 +367,9 @@ ngo_pnp_mapalloc(struct isapnp_attach_args *ipa, struct isic_softc *sc) sc->sc_maps[1].h = ipa->ipa_io[1].h; sc->sc_maps[1].size = 0; } +#endif +#if defined(CRTX_S0_P) || defined(TEL_S0_16_3_P) static void tls_pnp_mapalloc(struct isapnp_attach_args *ipa, struct isic_softc *sc) { @@ -384,3 +391,4 @@ tls_pnp_mapalloc(struct isapnp_attach_args *ipa, struct isic_softc *sc) sc->sc_maps[3].h = ipa->ipa_io[1].h; sc->sc_maps[3].size = 0; } +#endif diff --git a/sys/i4b/layer1/isic_supio.c b/sys/i4b/layer1/isic_supio.c index 24cc1de..0a80fbb 100644 --- a/sys/i4b/layer1/isic_supio.c +++ b/sys/i4b/layer1/isic_supio.c @@ -33,15 +33,17 @@ * isic_supio.c - Amiga supio pseudo bus frontend for i4b_isic driver * supports: * - ISDN Blaster 5001/1 + * - ISDN MasterII 5000/1 * - ISDN Master 2092/64 - * But we attach to the supio, so just see "isic". - * ----------------------------------------------- + * But we attach to the supio, so just see "isic" or "isicII". + * ----------------------------------------------------------- * - * $Id: isic_supio.c,v 1.6 1999/02/14 09:45:00 hm Exp $ + * $Id: isic_supio.c,v 1.7 1999/03/24 10:09:03 hm Exp $ * - * last edit-date: [Sun Feb 14 10:29:19 1999] + * last edit-date: [Mon Mar 22 22:49:20 MET 1999] * - * -is original implementation + * -is ISDN Master II support added. + * -is original implementation [Sun Feb 14 10:29:19 1999] * *---------------------------------------------------------------------------*/ @@ -105,7 +107,8 @@ isic_supio_match(parent, cf, aux) struct supio_attach_args *sap = aux; /* ARGSUSED */ - return (!strcmp("isic", sap->supio_name)); + return (!strcmp("isic", sap->supio_name) || + !strcmp("isicII", sap->supio_name)); } int isic_supio_ipl = 2; @@ -124,6 +127,8 @@ isic_supio_attach(parent, self, aux) bus_space_tag_t bst; bus_space_handle_t h; + int o1, o2; + /* setup parameters */ sc->sc_cardtyp = CARD_TYPEP_BLMASTER; sc->sc_num_mappings = 3; @@ -132,25 +137,32 @@ isic_supio_attach(parent, self, aux) /* create io mappings */ MALLOC_MAPS(sc); + if (!strcmp(sap->supio_name, "isic")) { + o1 = 0x300; + o2 = 0x100; + } else /* "isic-II" */ { + o1 = 0x100; + o2 = 0x300; + } bst = sap->supio_iot; bus_space_map(bst, sap->supio_iobase, 0x400, 0, &h); /* ISAC */ sc->sc_maps[0].t = bst; sc->sc_maps[0].h = h; - sc->sc_maps[0].offset = 0x300/2; + sc->sc_maps[0].offset = o1/2; sc->sc_maps[0].size = 0; /* foreign mapping, leave it alone */ /* HSCX A */ sc->sc_maps[1].t = bst; sc->sc_maps[1].h = h; - sc->sc_maps[1].offset = 0x100/2; + sc->sc_maps[1].offset = o2/2; sc->sc_maps[1].size = 0; /* foreign mapping, leave it alone */ /* HSCX B */ sc->sc_maps[2].t = bst; sc->sc_maps[2].h = h; - sc->sc_maps[2].offset = 0x180/2; + sc->sc_maps[2].offset = (o2 + 0x80)/2; sc->sc_maps[2].size = 0; /* foreign mapping, leave it alone */ sc->clearirq = NULL; diff --git a/sys/i4b/layer1/pci_isic.c b/sys/i4b/layer1/pci_isic.c index d577592..7e0a699 100644 --- a/sys/i4b/layer1/pci_isic.c +++ b/sys/i4b/layer1/pci_isic.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998 Martin Husemann. All rights reserved. + * Copyright (c) 1998,1999 Martin Husemann. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -33,11 +33,12 @@ * pci_isic.c - pcmcia bus frontend for i4b_isic driver * ------------------------------------------------------- * - * $Id: pci_isic.c,v 1.2 1999/02/14 09:45:00 hm Exp $ + * $Id: pci_isic.c,v 1.3 1999/03/16 15:21:55 hm Exp $ * - * last edit-date: [Sun Feb 14 10:29:25 1999] + * last edit-date: [Wed Mar 10 07:22:08 1999] * * -mh original implementation + * -mh added support for Fritz! PCI card * *---------------------------------------------------------------------------*/ @@ -72,6 +73,7 @@ #include <i4b/layer1/i4b_ipac.h> #include <i4b/layer1/i4b_isac.h> #include <i4b/layer1/i4b_hscx.h> +#include <i4b/layer1/pci_isic.h> #include <i4b/include/i4b_global.h> #include <i4b/include/i4b_l1l2.h> @@ -79,15 +81,7 @@ static int pci_isic_match __P((struct device *, struct cfdata *, void *)); static void pci_isic_attach __P((struct device *, struct device *, void *)); static const struct isic_pci_product * find_matching_card __P((struct pci_attach_args *pa)); -extern void isic_attach_Eqs1pp __P((struct isic_softc *sc, struct pci_attach_args *pa)); -static int isic_pciattach __P((struct isic_softc *sc)); - -struct pci_isic_softc { - struct isic_softc sc_isic; /* parent class */ - - /* PCI-specific goo */ - void *sc_ih; /* interrupt handler */ -}; +static void isic_pciattach __P((struct pci_isic_softc *psc, struct pci_attach_args *pa)); struct cfattach pci_isic_ca = { sizeof(struct pci_isic_softc), pci_isic_match, pci_isic_attach @@ -98,16 +92,37 @@ static const struct isic_pci_product { pci_vendor_id_t npp_vendor; pci_product_id_t npp_product; int cardtype; - int flag; const char * name; - void (*attach)(struct isic_softc *sc, struct pci_attach_args *pa); + void (*attach)(struct pci_isic_softc *psc, struct pci_attach_args *pa); + void (*pciattach)(struct pci_isic_softc *psc, struct pci_attach_args *pa); } isic_pci_products[] = { - { PCI_VENDOR_ELSA, 0x1000, - CARD_TYPEP_ELSAQS1PCI, FLAG_ELSA_QS1P_PCI, + +#ifdef ELSA_QS1PCI +#ifndef PCI_PRODUCT_ELSA_QS1PCI +#define PCI_PRODUCT_ELSA_QS1PCI 0x1000 /* added to pcidevs in 1.3K, earlier versions missing it */ +#endif + { PCI_VENDOR_ELSA, PCI_PRODUCT_ELSA_QS1PCI, + CARD_TYPEP_ELSAQS1PCI, "ELSA QuickStep 1000pro/PCI", - isic_attach_Eqs1pp }, + isic_attach_Eqs1pp, /* card specific initialization */ + isic_pciattach /* generic setup for ISAC/HSCX or IPAC boards */ + }, +#endif - { 0, 0, 0, 0, NULL, NULL }, +#ifdef AVM_A1_PCI +#ifndef PCI_VENDOR_AVM +#define PCI_VENDOR_AVM 0x1244 /* earlier versions missing this */ +#define PCI_PRODUCT_AVM_FRITZ_CARD 0x0a00 +#endif + { PCI_VENDOR_AVM, PCI_PRODUCT_AVM_FRITZ_CARD, + CARD_TYPEP_AVMA1PCI, + "Fritz!Card", + isic_attach_fritzPci, + NULL /* card rolls its own setup */ + }, +#endif + + { 0, 0, 0, NULL, NULL }, }; static const struct isic_pci_product * find_matching_card(pa) @@ -151,10 +166,7 @@ pci_isic_attach(parent, self, aux) struct pci_isic_softc *psc = (void*) self; struct isic_softc *sc = &psc->sc_isic; struct pci_attach_args *pa = aux; - pci_chipset_tag_t pc = pa->pa_pc; - pci_intr_handle_t ih; const struct isic_pci_product * prod; - const char *intrstr; /* Redo probe */ prod = find_matching_card(pa); @@ -164,38 +176,24 @@ pci_isic_attach(parent, self, aux) printf(": %s\n", prod->name); /* card initilization and sc setup */ - prod->attach(sc, pa); + prod->attach(psc, pa); - /* generic setup */ - isic_pciattach(sc); - - /* Map and establish the interrupt. */ - if (pci_intr_map(pc, pa->pa_intrtag, pa->pa_intrpin, - pa->pa_intrline, &ih)) { - printf("%s: couldn't map interrupt\n", sc->sc_dev.dv_xname); - return; - } - intrstr = pci_intr_string(pc, ih); - psc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, isicintr, sc); - if (psc->sc_ih == NULL) { - printf("%s: couldn't establish interrupt", - sc->sc_dev.dv_xname); - if (intrstr != NULL) - printf(" at %s", intrstr); - printf("\n"); - return; - } - printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr); + /* generic setup, if needed for this card */ + if (prod->pciattach) prod->pciattach(psc, pa); } /*---------------------------------------------------------------------------* * isic - pci device driver attach routine *---------------------------------------------------------------------------*/ -static int -isic_pciattach(sc) - struct isic_softc *sc; +static void +isic_pciattach(psc, pa) + struct pci_isic_softc *psc; + struct pci_attach_args *pa; { - int ret = 0; + struct isic_softc *sc = &psc->sc_isic; + pci_chipset_tag_t pc = pa->pa_pc; + pci_intr_handle_t ih; + const char *intrstr; static char *ISACversion[] = { "2085 Version A1/A2 or 2086/2186 Version 1.1", @@ -222,7 +220,7 @@ isic_pciattach(sc) if(sc->sc_ipac) { - ret = IPAC_READ(IPAC_ID); + u_int ret = IPAC_READ(IPAC_ID); switch(ret) { @@ -233,8 +231,7 @@ isic_pciattach(sc) default: printf("%s: Error, IPAC version %d unknown!\n", sc->sc_dev.dv_xname, ret); - return(0); - break; + return; } } else @@ -256,8 +253,7 @@ isic_pciattach(sc) default: printf("%s: Error, ISAC version %d unknown!\n", sc->sc_dev.dv_xname, sc->sc_isac_version); - return(0); - break; + return; } sc->sc_hscx_version = HSCX_READ(0, H_VSTR) & 0xf; @@ -276,8 +272,7 @@ isic_pciattach(sc) default: printf("%s: Error, HSCX version %d unknown!\n", sc->sc_dev.dv_xname, sc->sc_hscx_version); - return(0); - break; + return; } } @@ -322,6 +317,23 @@ isic_pciattach(sc) MPH_Status_Ind(sc->sc_unit, STI_ATTACH, sc->sc_cardtyp); - return(1); + + /* Map and establish the interrupt. */ + if (pci_intr_map(pc, pa->pa_intrtag, pa->pa_intrpin, + pa->pa_intrline, &ih)) { + printf("%s: couldn't map interrupt\n", sc->sc_dev.dv_xname); + return; + } + intrstr = pci_intr_string(pc, ih); + psc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, isicintr, sc); + if (psc->sc_ih == NULL) { + printf("%s: couldn't establish interrupt", + sc->sc_dev.dv_xname); + if (intrstr != NULL) + printf(" at %s", intrstr); + printf("\n"); + return; + } + printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr); } diff --git a/sys/i4b/layer1/pci_isic.h b/sys/i4b/layer1/pci_isic.h new file mode 100644 index 0000000..0ac1918 --- /dev/null +++ b/sys/i4b/layer1/pci_isic.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 1999 Martin Husemann. 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. + * + *--------------------------------------------------------------------------- + * + * pci_isic.h - pci bus frontend for i4b_isic driver + * ------------------------------------------------- + * + * $Id: pci_isic.h,v 1.1 1999/05/03 08:52:05 hm Exp $ + * + * last edit-date: [Wed Mar 10 07:22:08 1999] + * + * -mh original implementation + * + *---------------------------------------------------------------------------*/ + +struct pci_isic_softc { + struct isic_softc sc_isic; /* parent class */ + + /* PCI-specific goo */ + void *sc_ih; /* interrupt handler */ +}; + +extern void isic_attach_Eqs1pp __P((struct pci_isic_softc *psc, struct pci_attach_args *pa)); +extern void isic_attach_fritzPci __P((struct pci_isic_softc *psc, struct pci_attach_args *pa)); + diff --git a/sys/i4b/layer1/pcmcia_isic.c b/sys/i4b/layer1/pcmcia_isic.c index 20b5478..cb6ff4c 100644 --- a/sys/i4b/layer1/pcmcia_isic.c +++ b/sys/i4b/layer1/pcmcia_isic.c @@ -33,9 +33,9 @@ * pcmcia_isic.c - pcmcia bus frontend for i4b_isic driver * ------------------------------------------------------- * - * $Id: pcmcia_isic.c,v 1.4 1999/02/14 09:45:00 hm Exp $ + * $Id: pcmcia_isic.c,v 1.5 1999/04/20 12:19:57 hm Exp $ * - * last edit-date: [Sun Feb 14 10:29:29 1999] + * last edit-date: [Tue Apr 20 14:09:16 1999] * * -mh original implementation * @@ -98,7 +98,7 @@ struct isic_pcmcia_card_entry { static const struct isic_pcmcia_card_entry card_list[] = { -#ifdef AVM_PCMCIA +#ifdef AVM_A1_PCMCIA { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID, { "AVM", "ISDN A", NULL, NULL }, "AVM Fritz!Card", PCMCIA_FUNCTION_NETWORK, |