diff options
author | hm <hm@FreeBSD.org> | 2000-10-09 13:29:00 +0000 |
---|---|---|
committer | hm <hm@FreeBSD.org> | 2000-10-09 13:29:00 +0000 |
commit | 6a1e8c89a39e745792906a17cdf08fc5bdd384f4 (patch) | |
tree | 082a43cf60a2a80e84ca74e4339fda393b01ec06 /sys/i4b | |
parent | 9fc2bc8a46f4f09ca71eaf59e5c203b5d61533fb (diff) | |
download | FreeBSD-src-6a1e8c89a39e745792906a17cdf08fc5bdd384f4.zip FreeBSD-src-6a1e8c89a39e745792906a17cdf08fc5bdd384f4.tar.gz |
update to i4b version 0.95.04
Diffstat (limited to 'sys/i4b')
67 files changed, 11422 insertions, 5562 deletions
diff --git a/sys/i4b/layer1/i4b_avm_fritz_pcmcia.c b/sys/i4b/layer1/i4b_avm_fritz_pcmcia.c deleted file mode 100644 index 575da1a..0000000 --- a/sys/i4b/layer1/i4b_avm_fritz_pcmcia.c +++ /dev/null @@ -1,501 +0,0 @@ -/* - * Copyright (c) 1998 Matthias Apitz. 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. - * - *--------------------------------------------------------------------------- - * - * Fritz!Card pcmcia specific routines for isic driver - * --------------------------------------------------- - * - * $FreeBSD$ - * - * last edit-date: [Sun May 2 12:01:16 1999] - * - * -ap added support for AVM PCMCIA Fritz!Card - * -mh split into separate file - * - *---------------------------------------------------------------------------*/ - -#if defined(__FreeBSD__) -#include "isic.h" -#include "opt_i4b.h" -#else -#define NISIC 1 -#endif - -#if NISIC > 0 && defined(AVM_A1_PCMCIA) - -#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> - -#ifdef __FreeBSD__ -#include <machine/clock.h> -#include <i386/isa/isa_device.h> -#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 <i4b/i4b_debug.h> -#include <i4b/i4b_ioctl.h> -#include <dev/pcmcia/pcmciareg.h> -#include <dev/pcmcia/pcmciavar.h> -#endif - -#include <i4b/layer1/i4b_l1.h> -#include <i4b/layer1/i4b_isac.h> -#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)); -static void avma1_pcmcia_read_fifo __P((struct isic_softc *sc, int what, void *buf, size_t size)); -static void avma1_pcmcia_write_fifo __P((struct isic_softc *sc, int what, const void *data, size_t size)); -#endif - -/*---------------------------------------------------------------------------* - * AVM PCMCIA Fritz!Card special registers - *---------------------------------------------------------------------------*/ - -/* - * register offsets from i/o base 0x140 or 0x300 - */ -#define ADDR_REG_OFFSET 0x02 -#define DATA_REG_OFFSET 0x03 -#define STAT0_OFFSET 0x04 -#define STAT1_OFFSET 0x05 -#define MODREG_OFFSET 0x06 -#define VERREG_OFFSET 0x07 -/* - * AVM PCMCIA Status Latch 0 read only bits - */ -#define ASL_IRQ_TIMER 0x10 /* Timer interrupt, active low */ -#define ASL_IRQ_ISAC 0x20 /* ISAC interrupt, active low */ -#define ASL_IRQ_HSCX 0x40 /* HSX interrupt, active low */ -#define ASL_IRQ_BCHAN ASL_IRQ_HSCX -#define ASL_IRQ_Pending (ASL_IRQ_ISAC | ASL_IRQ_HSCX | ASL_IRQ_TIMER) -/* - * 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 */ -/* - * AVM Status Latch 1 write only bits - */ -#define ASL1_LED0 0x10 /* active high */ -#define ASL1_LED1 0x20 /* active high */ - -#define ASL1_ENABLE_S0 0xc0 /* enable active S0 I/F */ - -/*----- EEpromless controller -----*/ -/* - * AVM Status Latch read/write bit - */ - -#define ASL_TESTBIT 0x80 - - -/*---------------------------------------------------------------------------* - * AVM read fifo routines - *---------------------------------------------------------------------------*/ -#ifdef __FreeBSD__ -static int PCMCIA_IO_BASE = 0; /* ap: XXX hack */ -static void -avma1_pcmcia_read_fifo(void *buf, const void *base, size_t len) -{ - outb(PCMCIA_IO_BASE + ADDR_REG_OFFSET, (int)base - 0x20); - insb(PCMCIA_IO_BASE + DATA_REG_OFFSET, (u_char *)buf, (u_int)len); -} -#else -/* offsets of the different 'what' arguments */ -static u_int8_t what_map[] = { - 0x20-0x20, /* ISIC_WHAT_ISAC */ - 0xA0-0x20, /* ISIC_WHAT_HSCXA */ - 0xE0-0x20 /* ISIC_WHAT_HSCXB */ -}; -static void -avma1_pcmcia_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size) -{ - bus_space_tag_t t = sc->sc_maps[0].t; - bus_space_handle_t h = sc->sc_maps[0].h; - bus_space_write_1(t, h, ADDR_REG_OFFSET, what_map[what]); - bus_space_read_multi_1(t, h, DATA_REG_OFFSET, buf, size); -} -#endif - -/*---------------------------------------------------------------------------* - * AVM write fifo routines - *---------------------------------------------------------------------------*/ -#ifdef __FreeBSD__ -static void -avma1_pcmcia_write_fifo(void *base, const void *buf, size_t len) -{ - outb(PCMCIA_IO_BASE + ADDR_REG_OFFSET, (int)base - 0x20); - outsb(PCMCIA_IO_BASE + DATA_REG_OFFSET, (u_char *)buf, (u_int)len); -} -#else -static void -avma1_pcmcia_write_fifo(struct isic_softc *sc, int what, const void *buf, size_t size) -{ - bus_space_tag_t t = sc->sc_maps[0].t; - bus_space_handle_t h = sc->sc_maps[0].h; - bus_space_write_1(t, h, ADDR_REG_OFFSET, what_map[what]); - bus_space_write_multi_1(t, h, DATA_REG_OFFSET, (u_int8_t*)buf, size); -} -#endif - -/*---------------------------------------------------------------------------* - * AVM write register routines - *---------------------------------------------------------------------------*/ -#ifdef __FreeBSD__ -static void -avma1_pcmcia_write_reg(u_char *base, u_int offset, u_int v) -{ - /* offset includes 0x20 FIFO ! */ - outb(PCMCIA_IO_BASE + ADDR_REG_OFFSET, (int)base+offset-0x20); - outb(PCMCIA_IO_BASE + DATA_REG_OFFSET, (u_char)v); -} -#else -static void -avma1_pcmcia_write_reg(struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data) -{ - bus_space_tag_t t = sc->sc_maps[0].t; - bus_space_handle_t h = sc->sc_maps[0].h; - bus_space_write_1(t, h, ADDR_REG_OFFSET, what_map[what]+offs); - bus_space_write_1(t, h, DATA_REG_OFFSET, data); -} -#endif - -/*---------------------------------------------------------------------------* - * AVM read register routines - *---------------------------------------------------------------------------*/ -#ifdef __FreeBSD__ -static u_char -avma1_pcmcia_read_reg(u_char *base, u_int offset) -{ - /* offset includes 0x20 FIFO ! */ - outb(PCMCIA_IO_BASE + ADDR_REG_OFFSET, (int)base+offset-0x20); - return (inb(PCMCIA_IO_BASE + DATA_REG_OFFSET)); -} -#else -static u_int8_t -avma1_pcmcia_read_reg(struct isic_softc *sc, int what, bus_size_t offs) -{ - bus_space_tag_t t = sc->sc_maps[0].t; - bus_space_handle_t h = sc->sc_maps[0].h; - bus_space_write_1(t, h, ADDR_REG_OFFSET, what_map[what]+offs); - return bus_space_read_1(t, h, DATA_REG_OFFSET); -} -#endif - -/*---------------------------------------------------------------------------* - * isic_probe_avma1_pcmcia - probe for AVM PCMCIA Fritz!Card - * This is in the bus attachemnt part on NetBSD (pcmcia_isic.c), no - * card specicfic probe is needed on direct config buses like pcmcia. - *---------------------------------------------------------------------------*/ -#ifdef __FreeBSD__ -int -isic_probe_avma1_pcmcia(struct isa_device *dev) -{ - struct isic_softc *sc = &isic_sc[dev->id_unit]; - u_char byte; - int i; - u_int cardinfo; - - /* check max unit range */ - - if(dev->id_unit > 1) - { - printf("isic%d: Error, unit %d > MAXUNIT for AVM PCMCIA Fritz!Card\n", - dev->id_unit, dev->id_unit); - return(0); - } - sc->sc_unit = dev->id_unit; - - /* - * we trust the IRQ we got from PCCARD service - */ - sc->sc_irq = dev->id_irq; - - /* check if we got an iobase */ - - switch(dev->id_iobase) - { - case 0x140: - case 0x300: - break; - default: - printf("isic%d: Error, invalid iobase 0x%x specified for AVM PCMCIA Fritz!Card.\n", - dev->id_unit, dev->id_iobase); - return(0); - break; - } - sc->sc_port = dev->id_iobase; - - /* ResetController */ - - outb(dev->id_iobase + STAT0_OFFSET, 0x00); - DELAY(SEC_DELAY / 20); - outb(dev->id_iobase + STAT0_OFFSET, 0x01); - DELAY(SEC_DELAY / 20); - outb(dev->id_iobase + STAT0_OFFSET, 0x00); - - /* - * CheckController - * The logic to check for the PCMCIA was adapted as - * described by AVM. - */ - - outb(dev->id_iobase + ADDR_REG_OFFSET, 0x21); /* ISAC STAR */ - if ( (byte=inb(dev->id_iobase + DATA_REG_OFFSET) & 0xfd) != 0x48 ) - { - printf("isic%d: Error, ISAC STAR for AVM PCMCIA is 0x%0x (should be 0x48)\n", - dev->id_unit, byte); - return(0); - } - - outb(dev->id_iobase + ADDR_REG_OFFSET, 0xa1); /* HSCX STAR */ - if ( (byte=inb(dev->id_iobase + DATA_REG_OFFSET) & 0xfd) != 0x48 ) - { - printf("isic%d: Error, HSCX STAR for AVM PCMCIA is 0x%0x (should be 0x48)\n", - dev->id_unit, byte); - return(0); - } - - byte = ASL_TESTBIT; - for (i=0; i<256; i++) { - byte = byte ? 0 : ASL_TESTBIT; - outb(dev->id_iobase + STAT0_OFFSET, byte); - if ((inb(dev->id_iobase+STAT0_OFFSET)&ASL_TESTBIT)!=byte) { - printf("isic%d: Error during toggle of AVM PCMCIA Status Latch0\n", - dev->id_unit); - return(0); - } - } - - sc->clearirq = NULL; - sc->readreg = avma1_pcmcia_read_reg; - sc->writereg = avma1_pcmcia_write_reg; - - sc->readfifo = avma1_pcmcia_read_fifo; - sc->writefifo = avma1_pcmcia_write_fifo; - - /* setup card type */ - - sc->sc_cardtyp = CARD_TYPEP_PCFRITZ; - - /* setup IOM bus type */ - - sc->sc_bustyp = BUS_TYPE_IOM2; /* ap: XXX ??? */ - - sc->sc_ipac = 0; - sc->sc_bfifolen = HSCX_FIFO_LEN; - - /* setup ISAC and HSCX base addr */ - /* - * NOTE: for PCMCIA these are no real addrs; they are - * offsets to be written into the base+ADDR_REG_OFFSET register - * to pick up the values of the bytes fro base+DATA_REG_OFFSET - * - * see also the logic in the avma1_pcmcia_* routines; - * therefore we also must have the base addr in some static - * space or struct; XXX better solution? - */ - - PCMCIA_IO_BASE = dev->id_iobase; - ISAC_BASE = (caddr_t)0x20; - - HSCX_A_BASE = (caddr_t)0xA0; - HSCX_B_BASE = (caddr_t)0xE0; - - /* - * Read HSCX A/B VSTR. - * Expected value for AVM A1 is 0x04 or 0x05 and for the - * AVM Fritz!Card is 0x05 in the least significant bits. - */ - - if( (((HSCX_READ(0, H_VSTR) & 0xf) != 0x5) && - ((HSCX_READ(0, H_VSTR) & 0xf) != 0x4)) || - (((HSCX_READ(1, H_VSTR) & 0xf) != 0x5) && - ((HSCX_READ(1, H_VSTR) & 0xf) != 0x4)) ) - { - printf("isic%d: HSCX VSTR test failed for AVM PCMCIA Fritz!Card\n", - dev->id_unit); - printf("isic%d: HSC0: VSTR: 0x%0x\n", - dev->id_unit, HSCX_READ(0, H_VSTR)); - printf("isic%d: HSC1: VSTR: 0x%0x\n", - dev->id_unit, HSCX_READ(1, H_VSTR)); - return (0); - } - - /* - * seems we really have an AVM PCMCIA Fritz!Card controller - */ - cardinfo = inb(dev->id_iobase + VERREG_OFFSET)<<8 | inb(dev->id_iobase + MODREG_OFFSET); - printf("isic%d: successfully detect AVM PCMCIA cardinfo = 0x%0x\n", - dev->id_unit, cardinfo); - dev->id_flags = FLAG_AVM_A1_PCMCIA; - return (1); -} -#endif /* __FreeBSD__ */ - - - -/*---------------------------------------------------------------------------* - * isic_attach_fritzpcmcia - attach Fritz!Card - *---------------------------------------------------------------------------*/ -#ifdef __FreeBSD__ -int -isic_attach_fritzpcmcia(struct isa_device *dev) -{ - /* ResetController again just to make sure... */ - - outb(dev->id_iobase + STAT0_OFFSET, 0x00); - DELAY(SEC_DELAY / 10); - outb(dev->id_iobase + STAT0_OFFSET, 0x01); - DELAY(SEC_DELAY / 10); - outb(dev->id_iobase + STAT0_OFFSET, 0x00); - DELAY(SEC_DELAY / 10); - - /* enable IRQ, disable counter IRQ */ - - outb(dev->id_iobase + STAT0_OFFSET, ASL_TIMERDISABLE | - ASL_TIMERRESET | ASL_ENABLE_INT); - /* DELAY(SEC_DELAY / 10); */ - - return(1); -} - -#else - -/* - * XXX - one time only! Some of this has to go into an enable - * function, with apropriate counterpart in disable, so a card - * could be removed an inserted again. But never mind for now, - * this won't work anyway for several reasons (both in NetBSD - * and in I4B). - */ -int -isic_attach_fritzpcmcia(struct pcmcia_isic_softc *psc, struct pcmcia_config_entry *cfe, struct pcmcia_attach_args *pa) -{ - struct isic_softc *sc = &psc->sc_isic; - bus_space_tag_t t; - bus_space_handle_t h; - - /* Validate config info */ - if (cfe->num_memspace != 0) - printf(": unexpected number of memory spaces %d should be 0\n", - cfe->num_memspace); - if (cfe->num_iospace != 1) - printf(": unexpected number of memory spaces %d should be 1\n", - cfe->num_iospace); - - /* Allocate pcmcia space - exactly as dictated by the card */ - if (pcmcia_io_alloc(pa->pf, cfe->iospace[0].start, cfe->iospace[0].length, - 0, &psc->sc_pcioh)) - printf(": can't allocate i/o space\n"); - - /* map them */ - if (pcmcia_io_map(pa->pf, ((cfe->flags & PCMCIA_CFE_IO16) ? - PCMCIA_WIDTH_IO16 : PCMCIA_WIDTH_IO8), 0, - cfe->iospace[0].length, &psc->sc_pcioh, &psc->sc_io_window)) { - printf(": can't map i/o space\n"); - return 0; - } - - /* Setup bus space maps */ - sc->sc_num_mappings = 1; - sc->sc_cardtyp = CARD_TYPEP_PCFRITZ; - MALLOC_MAPS(sc); - - /* Copy our handles/tags to the MI maps */ - sc->sc_maps[0].t = psc->sc_pcioh.iot; - sc->sc_maps[0].h = psc->sc_pcioh.ioh; - sc->sc_maps[0].offset = 0; - sc->sc_maps[0].size = 0; /* not our mapping */ - - t = sc->sc_maps[0].t; - h = sc->sc_maps[0].h; - - sc->clearirq = NULL; - sc->readreg = avma1_pcmcia_read_reg; - sc->writereg = avma1_pcmcia_write_reg; - - sc->readfifo = avma1_pcmcia_read_fifo; - sc->writefifo = avma1_pcmcia_write_fifo; - - /* setup card type */ - - sc->sc_cardtyp = CARD_TYPEP_PCFRITZ; - - /* setup IOM bus type */ - - sc->sc_bustyp = BUS_TYPE_IOM2; - - sc->sc_ipac = 0; - sc->sc_bfifolen = HSCX_FIFO_LEN; - - /* Reset controller again just to make sure... */ - - bus_space_write_1(t, h, STAT0_OFFSET, 0x00); - DELAY(SEC_DELAY / 10); - bus_space_write_1(t, h, STAT0_OFFSET, 0x01); - DELAY(SEC_DELAY / 10); - bus_space_write_1(t, h, STAT0_OFFSET, 0x00); - DELAY(SEC_DELAY / 10); - - /* enable IRQ, disable counter IRQ */ - - bus_space_write_1(t, h, STAT0_OFFSET, ASL_TIMERDISABLE | - ASL_TIMERRESET | ASL_ENABLE_INT); - - return 1; -} -#endif - -#endif /* NISIC > 0 && defined(AVM_A1_PCMCIA) */ diff --git a/sys/i4b/layer1/i4b_dynalink.c b/sys/i4b/layer1/i4b_dynalink.c deleted file mode 100644 index ff9d0e5..0000000 --- a/sys/i4b/layer1/i4b_dynalink.c +++ /dev/null @@ -1,578 +0,0 @@ -/* - * Copyright (c) 1998 Martijn Plak. 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. - * - *--------------------------------------------------------------------------- - * - * isdn4bsd layer1 driver for Dynalink IS64PH isdn TA - * ================================================== - * - * $FreeBSD$ - * - * last edit-date: [Sun Feb 14 10:26:21 1999] - * - * written by Martijn Plak <tigrfhur@xs4all.nl> - * - * -mp 11 jun 1998 first try, code borrowed from Creatix driver - * -mp 18 jun 1998 cleaned up code - * -hm FreeBSD PnP - * -mp 17 dec 1998 made it compile again - * - *---------------------------------------------------------------------------*/ - -/* NOTES: - - This driver was written for the Dynalink IS64PH ISDN TA, based on two - Siemens chips (HSCX 21525 and ISAC 2186). It is sold in the Netherlands. - - model numbers found on (my) card: - IS64PH, TAS100H-N, P/N:89590555, TA200S100045521 - - chips: - Siemens PSB 21525N, HSCX TE V2.1 - Siemens PSB 2186N, ISAC-S TE V1.1 - 95MS14, PNP - - plug-and-play info: - device id "ASU1688" - vendor id 0x88167506 - serial 0x00000044 - i/o port 4 byte alignment, 4 bytes requested, - 10 bit i/o decoding, 0x100-0x3f8 (?) - irq 3,4,5,9,10,11,12,15, high true, edge sensitive - - At the moment I'm writing this Dynalink is replacing this card with - one based on a single Siemens chip (IPAC). It will apparently be sold - under the same model name. - - This driver might also work for Asuscom cards. -*/ - -#ifdef __FreeBSD__ - -#include "isic.h" -#include "opt_i4b.h" - -#else - -#define NISIC 1 - -#endif - -#define NPNP 1 - -#if (NISIC > 0) && (NPNP > 0) && defined(DYNALINK) - -/* HEADERS -*/ - -#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> */ -#elif defined(__bsdi__) -#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> - -#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 - -#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); -static u_int8_t dynalink_read_reg(struct isic_softc *sc, int what, bus_size_t offs); -void isic_attach_Dyn(struct isic_softc *sc); -#endif - -/* io address mapping */ -#define ISAC 0 -#define HSCX 1 -#define ADDR 2 - -/* ADDR bits */ -#define ADDRMASK 0x7F -#define RESET 0x80 - -/* HSCX register offsets */ -#define HSCXA 0x00 -#define HSCXB 0x40 - -#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 -*/ - -int -isic_probe_Dyn(struct isa_device *dev, unsigned int iobase2) -{ - - struct isic_softc *sc = &isic_sc[dev->id_unit]; - - if(dev->id_unit >= ISIC_MAXUNIT) - { - printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for Dynalink IS64PH.\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 9: - case 10: - case 11: - case 12: - case 15: - break; - - default: - printf("isic%d: Error, invalid IRQ [%d] specified for Dynalink IS64PH.\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 Dynalink IS64PH.\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 > 0x3f8) || - (dev->id_iobase & 3) ) - { - printf("isic%d: Error, invalid iobase 0x%x specified for Dynalink!\n", dev->id_unit, dev->id_iobase); - return(0); - } - sc->sc_port = dev->id_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; - - /* 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", - dev->id_unit); - printf("isic%d: HSC0: VSTR: %#x\n", - dev->id_unit, HSCX_READ(0, H_VSTR)); - printf("isic%d: HSC1: VSTR: %#x\n", - dev->id_unit, HSCX_READ(1, H_VSTR)); - return (0); - } - - return (1); -} - -int -isic_attach_Dyn(struct isa_device *dev, unsigned int iobase2) -{ - outb((dev->id_iobase)+ADDR, RESET); - DELAY(SEC_DELAY / 10); - outb((dev->id_iobase)+ADDR, 0); - DELAY(SEC_DELAY / 10); - 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) -{ - /* 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; - - /* 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("%s: HSCX VSTR test failed for Dynalink PnP\n", - sc->sc_dev.dv_xname); - printf("%s: HSC0: VSTR: %#x\n", - sc->sc_dev.dv_xname, HSCX_READ(0, H_VSTR)); - printf("%s: HSC1: VSTR: %#x\n", - sc->sc_dev.dv_xname, HSCX_READ(1, H_VSTR)); - return; - } - - bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, ADDR, RESET); - DELAY(SEC_DELAY / 10); - bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, ADDR, 0); - DELAY(SEC_DELAY / 10); -} - -#endif /* ISIC>0 && NPNP>0 && defined(DYNALINK) */ - -/* LOW-LEVEL DEVICE ACCESS - - NOTE: The isdn4bsd code expects the two HSCX channels at different - base addresses. I'm faking this, and remap them to the same address - in the low-level routines. Search for HSCXB_HACK and IS_HSCXB_HACK. - - REM: this is only true for the FreeBSD version of I4B! -*/ - -#if defined(__FreeBSD__) || defined(__bsdi__) -static void -dynalink_read_fifo(void *buf, const void *base, size_t len) -{ - outb(IOBASE(base)+ADDR, 0+IS_HSCXB_HACK(base)); - insb(IOADDR(base), (u_char *)buf, (u_int)len); -} -#else -static void -dynalink_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size) -{ - bus_space_tag_t t = sc->sc_maps[0].t; - bus_space_handle_t h = sc->sc_maps[0].h; - switch (what) { - case ISIC_WHAT_ISAC: - bus_space_write_1(t, h, ADDR, 0); - bus_space_read_multi_1(t, h, ISAC, buf, size); - break; - case ISIC_WHAT_HSCXA: - bus_space_write_1(t, h, ADDR, HSCXA); - bus_space_read_multi_1(t, h, HSCX, buf, size); - break; - case ISIC_WHAT_HSCXB: - bus_space_write_1(t, h, ADDR, HSCXB); - bus_space_read_multi_1(t, h, HSCX, buf, size); - break; - } -} -#endif - -#if defined(__FreeBSD__) || defined(__bsdi__) -static void -dynalink_write_fifo(void *base, const void *buf, size_t len) -{ - outb(IOBASE(base)+ADDR, 0+IS_HSCXB_HACK(base)); - outsb(IOADDR(base), (u_char *)buf, (u_int)len); -} -#else -static void dynalink_write_fifo(struct isic_softc *sc, int what, const void *buf, size_t size) -{ - bus_space_tag_t t = sc->sc_maps[0].t; - bus_space_handle_t h = sc->sc_maps[0].h; - switch (what) { - case ISIC_WHAT_ISAC: - bus_space_write_1(t, h, ADDR, 0); - bus_space_write_multi_1(t, h, ISAC, (u_int8_t*)buf, size); - break; - case ISIC_WHAT_HSCXA: - bus_space_write_1(t, h, ADDR, HSCXA); - bus_space_write_multi_1(t, h, HSCX, (u_int8_t*)buf, size); - break; - case ISIC_WHAT_HSCXB: - bus_space_write_1(t, h, ADDR, HSCXB); - bus_space_write_multi_1(t, h, HSCX, (u_int8_t*)buf, size); - break; - } -} -#endif - -#if defined(__FreeBSD__) || defined(__bsdi__) -static void -dynalink_write_reg(u_char *base, u_int offset, u_int v) -{ - outb(IOBASE(base)+ADDR, (offset+IS_HSCXB_HACK(base))&ADDRMASK); - outb(IOADDR(base), (u_char)v); -} -#else -static void dynalink_write_reg(struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data) -{ - bus_space_tag_t t = sc->sc_maps[0].t; - bus_space_handle_t h = sc->sc_maps[0].h; - switch (what) { - case ISIC_WHAT_ISAC: - bus_space_write_1(t, h, ADDR, offs); - bus_space_write_1(t, h, ISAC, data); - break; - case ISIC_WHAT_HSCXA: - bus_space_write_1(t, h, ADDR, HSCXA+offs); - bus_space_write_1(t, h, HSCX, data); - break; - case ISIC_WHAT_HSCXB: - bus_space_write_1(t, h, ADDR, HSCXB+offs); - bus_space_write_1(t, h, HSCX, data); - break; - } -} -#endif - -#if defined(__FreeBSD__) || defined(__bsdi__) -static u_char -dynalink_read_reg(u_char *base, u_int offset) -{ - outb(IOBASE(base)+ADDR, (offset+IS_HSCXB_HACK(base))&ADDRMASK); - return (inb(IOADDR(base))); -} -#else -static u_int8_t dynalink_read_reg(struct isic_softc *sc, int what, bus_size_t offs) -{ - bus_space_tag_t t = sc->sc_maps[0].t; - bus_space_handle_t h = sc->sc_maps[0].h; - switch (what) { - case ISIC_WHAT_ISAC: - bus_space_write_1(t, h, ADDR, offs); - return bus_space_read_1(t, h, ISAC); - case ISIC_WHAT_HSCXA: - bus_space_write_1(t, h, ADDR, HSCXA+offs); - return bus_space_read_1(t, h, HSCX); - case ISIC_WHAT_HSCXB: - bus_space_write_1(t, h, ADDR, HSCXB+offs); - return bus_space_read_1(t, h, HSCX); - } - return 0; -} -#endif - -#endif /* (NISIC > 0) && (NPNP > 0) && defined(DYNALINK) */ diff --git a/sys/i4b/layer1/i4b_elsa_isdnmc.c b/sys/i4b/layer1/i4b_elsa_isdnmc.c deleted file mode 100644 index 2b43323..0000000 --- a/sys/i4b/layer1/i4b_elsa_isdnmc.c +++ /dev/null @@ -1,325 +0,0 @@ -/* - * Copyright (c) 1998 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. - * - *--------------------------------------------------------------------------- - * - * ELSA MicroLink ISDN/MC card specific routines - * --------------------------------------------- - * - * $FreeBSD$ - * - * last edit-date: [Sun Feb 14 10:26:25 1999] - * - * -mh added support for elsa ISDN/mc - * - *---------------------------------------------------------------------------*/ - -#ifdef __FreeBSD__ -#include "isic.h" -#include "opt_i4b.h" -#else -#define NISIC 1 -#endif - -#if NISIC > 0 && defined(ELSA_ISDNMC) - -#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> - -#ifdef __FreeBSD__ -#include <machine/clock.h> -#include <i386/isa/isa_device.h> -#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 <i4b/i4b_debug.h> -#include <i4b/i4b_ioctl.h> - -#include <dev/pcmcia/pcmciareg.h> -#include <dev/pcmcia/pcmciavar.h> -#endif - -#include <i4b/layer1/i4b_l1.h> -#include <i4b/layer1/i4b_isac.h> -#include <i4b/layer1/i4b_hscx.h> - -#include <i4b/layer1/pcmcia_isic.h> - -#ifndef __FreeBSD__ -/* PCMCIA support routines */ -static u_int8_t elsa_isdnmc_read_reg __P((struct isic_softc *sc, int what, bus_size_t offs)); -static void elsa_isdnmc_write_reg __P((struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data)); -static void elsa_isdnmc_read_fifo __P((struct isic_softc *sc, int what, void *buf, size_t size)); -static void elsa_isdnmc_write_fifo __P((struct isic_softc *sc, int what, const void *data, size_t size)); -static void elsa_isdnmc_clrirq __P((struct isic_softc *sc)); -#endif - -/* - * The ELSA MicroLink ISDN/MC uses one contigous IO region, - * mapped by the pcmcia code. - * The chip access is via three ports: - */ -#define ISAC_DATA 1 /* ISAC dataport at offset 1 */ -#define HSCX_DATA 2 /* HSCX dataport at offset 2 */ -#define ADDR_LATCH 4 /* address latch at offset 4 */ - -/* This is very similar to the ELSA QuickStep 1000 (ISA) card */ - -#ifdef __FreeBSD__ -static void -elsa_isdnmc_clrirq(void *base) -{ -} -#else -static void -elsa_isdnmc_clrirq(struct isic_softc *sc) -{ - ISAC_WRITE(I_MASK, 0xff); - HSCX_WRITE(0, H_MASK, 0xff); - HSCX_WRITE(1, H_MASK, 0xff); - ISAC_WRITE(I_MASK, ISAC_IMASK); - HSCX_WRITE(0, H_MASK, HSCX_A_IMASK); - HSCX_WRITE(1, H_MASK, HSCX_B_IMASK); -} -#endif - -/*---------------------------------------------------------------------------* - * read fifo routines - *---------------------------------------------------------------------------*/ -#ifdef __FreeBSD__ -static void -elsa_isdnmc_read_fifo(void *buf, const void *base, size_t len) -{ -} -#else -static void -elsa_isdnmc_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size) -{ - bus_space_tag_t t = sc->sc_maps[0].t; - bus_space_handle_t h = sc->sc_maps[0].h; - switch (what) { - case ISIC_WHAT_ISAC: - bus_space_write_1(t, h, ADDR_LATCH, 0); - bus_space_read_multi_1(t, h, ISAC_DATA, buf, size); - break; - case ISIC_WHAT_HSCXA: - bus_space_write_1(t, h, ADDR_LATCH, 0); - bus_space_read_multi_1(t, h, HSCX_DATA, buf, size); - break; - case ISIC_WHAT_HSCXB: - bus_space_write_1(t, h, ADDR_LATCH, 0x40); - bus_space_read_multi_1(t, h, HSCX_DATA, buf, size); - break; - } -} -#endif - -/*---------------------------------------------------------------------------* - * write fifo routines - *---------------------------------------------------------------------------*/ -#ifdef __FreeBSD__ -static void -elsa_isdnmc_write_fifo(void *base, const void *buf, size_t len) -{ -} -#else -static void -elsa_isdnmc_write_fifo(struct isic_softc *sc, int what, const void *buf, size_t size) -{ - bus_space_tag_t t = sc->sc_maps[0].t; - bus_space_handle_t h = sc->sc_maps[0].h; - switch (what) { - case ISIC_WHAT_ISAC: - bus_space_write_1(t, h, ADDR_LATCH, 0); - bus_space_write_multi_1(t, h, ISAC_DATA, (u_int8_t*)buf, size); - break; - case ISIC_WHAT_HSCXA: - bus_space_write_1(t, h, ADDR_LATCH, 0); - bus_space_write_multi_1(t, h, HSCX_DATA, (u_int8_t*)buf, size); - break; - case ISIC_WHAT_HSCXB: - bus_space_write_1(t, h, ADDR_LATCH, 0x40); - bus_space_write_multi_1(t, h, HSCX_DATA, (u_int8_t*)buf, size); - break; - } -} -#endif - -/*---------------------------------------------------------------------------* - * write register routines - *---------------------------------------------------------------------------*/ -#ifdef __FreeBSD__ -static void -elsa_isdnmc_write_reg(u_char *base, u_int offset, u_int v) -{ -} -#else -static void -elsa_isdnmc_write_reg(struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data) -{ - bus_space_tag_t t = sc->sc_maps[0].t; - bus_space_handle_t h = sc->sc_maps[0].h; - switch (what) { - case ISIC_WHAT_ISAC: - bus_space_write_1(t, h, ADDR_LATCH, offs); - bus_space_write_1(t, h, ISAC_DATA, data); - break; - case ISIC_WHAT_HSCXA: - bus_space_write_1(t, h, ADDR_LATCH, offs); - bus_space_write_1(t, h, HSCX_DATA, data); - break; - case ISIC_WHAT_HSCXB: - bus_space_write_1(t, h, ADDR_LATCH, 0x40+offs); - bus_space_write_1(t, h, HSCX_DATA, data); - break; - } -} -#endif - -/*---------------------------------------------------------------------------* - * read register routines - *---------------------------------------------------------------------------*/ -#ifdef __FreeBSD__ -static u_char -elsa_isdnmc_read_reg(u_char *base, u_int offset) -{ - return 0; -} -#else -static u_int8_t -elsa_isdnmc_read_reg(struct isic_softc *sc, int what, bus_size_t offs) -{ - bus_space_tag_t t = sc->sc_maps[0].t; - bus_space_handle_t h = sc->sc_maps[0].h; - switch (what) { - case ISIC_WHAT_ISAC: - bus_space_write_1(t, h, ADDR_LATCH, offs); - return bus_space_read_1(t, h, ISAC_DATA); - case ISIC_WHAT_HSCXA: - bus_space_write_1(t, h, ADDR_LATCH, offs); - return bus_space_read_1(t, h, HSCX_DATA); - case ISIC_WHAT_HSCXB: - bus_space_write_1(t, h, ADDR_LATCH, 0x40+offs); - return bus_space_read_1(t, h, HSCX_DATA); - } - return 0; -} -#endif - -#ifdef __FreeBSD__ -#else - -/* - * XXX - one time only! Some of this has to go into an enable - * function, with apropriate counterpart in disable, so a card - * could be removed an inserted again. But never mind for now, - * this won't work anyway for several reasons (both in NetBSD - * and in I4B). - */ -int -isic_attach_elsaisdnmc(struct pcmcia_isic_softc *psc, struct pcmcia_config_entry *cfe, struct pcmcia_attach_args *pa) -{ - struct isic_softc *sc = &psc->sc_isic; - bus_space_tag_t t; - bus_space_handle_t h; - - /* Validate config info */ - if (cfe->num_memspace != 0) - printf(": unexpected number of memory spaces %d should be 0\n", - cfe->num_memspace); - if (cfe->num_iospace != 1) - printf(": unexpected number of memory spaces %d should be 1\n", - cfe->num_iospace); - - /* Allocate pcmcia space */ - if (pcmcia_io_alloc(pa->pf, 0, cfe->iospace[0].length, - cfe->iospace[0].length, &psc->sc_pcioh)) - printf(": can't allocate i/o space\n"); - - /* map them */ - if (pcmcia_io_map(pa->pf, ((cfe->flags & PCMCIA_CFE_IO16) ? - PCMCIA_WIDTH_IO16 : PCMCIA_WIDTH_IO8), 0, - cfe->iospace[0].length, &psc->sc_pcioh, &psc->sc_io_window)) { - printf(": can't map i/o space\n"); - return 0; - } - - /* OK, this will work! */ - sc->sc_cardtyp = CARD_TYPEP_ELSAMLIMC; - - /* Setup bus space maps */ - sc->sc_num_mappings = 1; - MALLOC_MAPS(sc); - - /* Copy our handles/tags to the MI maps */ - sc->sc_maps[0].t = psc->sc_pcioh.iot; - sc->sc_maps[0].h = psc->sc_pcioh.ioh; - sc->sc_maps[0].offset = 0; - sc->sc_maps[0].size = 0; /* not our mapping */ - - t = sc->sc_maps[0].t; - h = sc->sc_maps[0].h; - - sc->clearirq = elsa_isdnmc_clrirq; - - sc->readreg = elsa_isdnmc_read_reg; - sc->writereg = elsa_isdnmc_write_reg; - - sc->readfifo = elsa_isdnmc_read_fifo; - sc->writefifo = elsa_isdnmc_write_fifo; - - /* setup IOM bus type */ - - sc->sc_bustyp = BUS_TYPE_IOM2; - - sc->sc_ipac = 0; - sc->sc_bfifolen = HSCX_FIFO_LEN; - - return 1; -} -#endif - -#endif /* ISIC > 0 */ diff --git a/sys/i4b/layer1/i4b_elsa_mcall.c b/sys/i4b/layer1/i4b_elsa_mcall.c deleted file mode 100644 index e1792e2..0000000 --- a/sys/i4b/layer1/i4b_elsa_mcall.c +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Copyright (c) 1998 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. - * - *--------------------------------------------------------------------------- - * - * ELSA MicroLink MC/all card specific routines - * -------------------------------------------- - * - * $FreeBSD$ - * - * last edit-date: [Sun Feb 14 10:26:29 1999] - * - * -mh started support for ELSA MC/all - * - *---------------------------------------------------------------------------*/ - -#ifdef __FreeBSD__ -#include "isic.h" -#include "opt_i4b.h" -#else -#define NISIC 1 -#endif - -#if NISIC > 0 && defined(ELSA_MCALL) - -#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> - -#ifdef __FreeBSD__ -#include <machine/clock.h> -#include <i386/isa/isa_device.h> -#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 <i4b/i4b_debug.h> -#include <i4b/i4b_ioctl.h> - -#include <dev/pcmcia/pcmciareg.h> -#include <dev/pcmcia/pcmciavar.h> -#endif - -#include <i4b/layer1/i4b_l1.h> -#include <i4b/layer1/i4b_isac.h> -#include <i4b/layer1/i4b_hscx.h> -#include <i4b/layer1/i4b_ipac.h> - -#include <i4b/layer1/pcmcia_isic.h> - -#ifndef __FreeBSD__ -/* PCMCIA support routines */ -static u_int8_t elsa_mcall_read_reg __P((struct isic_softc *sc, int what, bus_size_t offs)); -static void elsa_mcall_write_reg __P((struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data)); -static void elsa_mcall_read_fifo __P((struct isic_softc *sc, int what, void *buf, size_t size)); -static void elsa_mcall_write_fifo __P((struct isic_softc *sc, int what, const void *data, size_t size)); -#endif - -/*---------------------------------------------------------------------------* - * read fifo routines - *---------------------------------------------------------------------------*/ -#ifdef __FreeBSD__ -static int PCMCIA_IO_BASE = 0; /* ap: XXX hack */ -static void -elsa_mcall_read_fifo(void *buf, const void *base, size_t len) -{ -} -#else -static void -elsa_mcall_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size) -{ - /* - bus_space_tag_t t = sc->sc_maps[0].t; - bus_space_handle_t h = sc->sc_maps[0].h; - */ -} -#endif - -/*---------------------------------------------------------------------------* - * write fifo routines - *---------------------------------------------------------------------------*/ -#ifdef __FreeBSD__ -static void -elsa_mcall_write_fifo(void *base, const void *buf, size_t len) -{ -} -#else -static void -elsa_mcall_write_fifo(struct isic_softc *sc, int what, const void *buf, size_t size) -{ - /* - bus_space_tag_t t = sc->sc_maps[0].t; - bus_space_handle_t h = sc->sc_maps[0].h; - */ -} -#endif - -/*---------------------------------------------------------------------------* - * write register routines - *---------------------------------------------------------------------------*/ -#ifdef __FreeBSD__ -static void -elsa_mcall_write_reg(u_char *base, u_int offset, u_int v) -{ -} -#else -static void -elsa_mcall_write_reg(struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data) -{ - /* - bus_space_tag_t t = sc->sc_maps[0].t; - bus_space_handle_t h = sc->sc_maps[0].h; - */ -} -#endif - -/*---------------------------------------------------------------------------* - * read register routines - *---------------------------------------------------------------------------*/ -#ifdef __FreeBSD__ -static u_char -elsa_mcall_read_reg(u_char *base, u_int offset) -{ - return 0; -} -#else -static u_int8_t -elsa_mcall_read_reg(struct isic_softc *sc, int what, bus_size_t offs) -{ - /* - bus_space_tag_t t = sc->sc_maps[0].t; - bus_space_handle_t h = sc->sc_maps[0].h; - */ - return 0; -} -#endif - -#ifdef __FreeBSD__ -#else - -/* - * XXX - one time only! Some of this has to go into an enable - * function, with apropriate counterpart in disable, so a card - * could be removed an inserted again. But never mind for now, - * this won't work anyway for several reasons (both in NetBSD - * and in I4B). - */ -int -isic_attach_elsamcall(struct pcmcia_isic_softc *psc, struct pcmcia_config_entry *cfe, struct pcmcia_attach_args *pa) -{ - struct isic_softc *sc = &psc->sc_isic; - bus_space_tag_t t; - bus_space_handle_t h; - - /* Validate config info */ - if (cfe->num_memspace != 0) - printf(": unexpected number of memory spaces %d should be 0\n", - cfe->num_memspace); - if (cfe->num_iospace != 1) - printf(": unexpected number of memory spaces %d should be 1\n", - cfe->num_iospace); - - /* Allocate pcmcia space */ - if (pcmcia_io_alloc(pa->pf, 0, cfe->iospace[0].length, - cfe->iospace[0].length, &psc->sc_pcioh)) - printf(": can't allocate i/o space\n"); - - /* map them */ - if (pcmcia_io_map(pa->pf, ((cfe->flags & PCMCIA_CFE_IO16) ? - PCMCIA_WIDTH_IO16 : PCMCIA_WIDTH_IO8), 0, - cfe->iospace[0].length, &psc->sc_pcioh, &psc->sc_io_window)) { - printf(": can't map i/o space\n"); - return 0; - } - - /* setup card type */ - sc->sc_cardtyp = CARD_TYPEP_ELSAMLMCALL; - - /* Setup bus space maps */ - sc->sc_num_mappings = 1; - MALLOC_MAPS(sc); - - /* Copy our handles/tags to the MI maps */ - sc->sc_maps[0].t = psc->sc_pcioh.iot; - sc->sc_maps[0].h = psc->sc_pcioh.ioh; - sc->sc_maps[0].offset = 0; - sc->sc_maps[0].size = 0; /* not our mapping */ - - t = sc->sc_maps[0].t; - h = sc->sc_maps[0].h; - - sc->clearirq = NULL; - sc->readreg = elsa_mcall_read_reg; - sc->writereg = elsa_mcall_write_reg; - - sc->readfifo = elsa_mcall_read_fifo; - sc->writefifo = elsa_mcall_write_fifo; - - /* setup IOM bus type */ - - sc->sc_bustyp = BUS_TYPE_IOM2; - - sc->sc_ipac = 1; - sc->sc_bfifolen = IPAC_BFIFO_LEN; - - return 1; -} -#endif - -#endif /* NISIC > 0 */ diff --git a/sys/i4b/layer1/i4b_hdlc.h b/sys/i4b/layer1/i4b_hdlc.h new file mode 100644 index 0000000..a34fb03 --- /dev/null +++ b/sys/i4b/layer1/i4b_hdlc.h @@ -0,0 +1,387 @@ +/* + * Copyright (c) 2000 Hans Petter Selasky. 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_hdlc.h - software-HDLC header file + * -------------------------------------- + * + * $Id: i4b_hdlc.h,v 1.5 2000/08/28 07:41:19 hm Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Wed Jul 19 09:41:13 2000] + * + *---------------------------------------------------------------------------*/ + +#ifndef _I4B_HDLC_H_ +#define _I4B_HDLC_H_ + +/*---------------------------------------------------------------------------* + * HDLC CRC table + * + * Usage: + * crc = (HDLC_FCS_TAB[(u_char)(crc ^ byte of data)] ^ (u_char)(crc >> 8)); + * + * For more information see RFC 1662 (p. 10) + *---------------------------------------------------------------------------*/ +const u_short HDLC_FCS_TAB[256] = { 0x0000, + 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 0x8c48, + 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, 0x1081, + 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, 0x9cc9, + 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, 0x2102, + 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, 0xad4a, + 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, 0x3183, + 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, 0xbdcb, + 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, 0x4204, + 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, 0xce4c, + 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, 0x5285, + 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, 0xdecd, + 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, 0x6306, + 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, 0xef4e, + 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, 0x7387, + 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, 0xffcf, + 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, 0x8408, + 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, 0x0840, + 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, 0x9489, + 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, 0x18c1, + 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, 0xa50a, + 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, 0x2942, + 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, 0xb58b, + 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, 0x39c3, + 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, 0xc60c, + 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, 0x4a44, + 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, 0xd68d, + 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, 0x5ac5, + 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, 0xe70e, + 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, 0x6b46, + 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, 0xf78f, + 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 0x7bc7, + 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 +}; + +/*---------------------------------------------------------------------------* + * HDLC bit table + * ============== + * + * bits[0..3]: A value which tells how many set bits there are at the + * beginning of the byte. + * + * bits[4..7]: Special bytes like 0x7e, 0x7d, 0xfd ... are flagged here + * NOTE: Special bytes also means 'abort' bytes (7 or more + * continious set bits) + * + * bits[8..11]: A copy of bits[0..3] but only incremented by one. + * NOTE: 0x7e has value '8' instead of '0'. Internal reasons. + * + * bits[12..15]: A value which tells how many set bits there are at the + * end of the byte. + * NOTE: 0xff has both '8' incoming and '8' outgoing bits. + * + *---------------------------------------------------------------------------*/ +const u_short HDLC_BIT_TAB[256] = { 0x0100, + 0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0100, 0x0403, 0x0100, + 0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0100, 0x0504, 0x0100, + 0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0100, 0x0403, 0x0100, + 0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0100, 0x0605, 0x0100, + 0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0100, 0x0403, 0x0100, + 0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0100, 0x0504, 0x0100, + 0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0100, 0x0403, 0x0100, + 0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0160, 0x0706, 0x0100, + 0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0100, 0x0403, 0x0100, + 0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0100, 0x0504, 0x0100, + 0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0100, 0x0403, 0x0100, + 0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0100, 0x0605, 0x0100, + 0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0100, 0x0403, 0x0100, + 0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0100, 0x0504, 0x0100, + 0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0100, 0x0403, 0x0100, + 0x0201, 0x0100, 0x0302, 0x01a0, 0x02a1, 0x0860, 0x0807, 0x1100, + 0x1201, 0x1100, 0x1302, 0x1100, 0x1201, 0x1100, 0x1403, 0x1100, + 0x1201, 0x1100, 0x1302, 0x1100, 0x1201, 0x1100, 0x1504, 0x1100, + 0x1201, 0x1100, 0x1302, 0x1100, 0x1201, 0x1100, 0x1403, 0x1100, + 0x1201, 0x1100, 0x1302, 0x1100, 0x1201, 0x1100, 0x1605, 0x1100, + 0x1201, 0x1100, 0x1302, 0x1100, 0x1201, 0x1100, 0x1403, 0x1100, + 0x1201, 0x1100, 0x1302, 0x1100, 0x1201, 0x1100, 0x1504, 0x1100, + 0x1201, 0x1100, 0x1302, 0x1100, 0x1201, 0x1100, 0x1403, 0x1100, + 0x1201, 0x1100, 0x1302, 0x1100, 0x1201, 0x1160, 0x1706, 0x2100, + 0x2201, 0x2100, 0x2302, 0x2100, 0x2201, 0x2100, 0x2403, 0x2100, + 0x2201, 0x2100, 0x2302, 0x2100, 0x2201, 0x2100, 0x2504, 0x2100, + 0x2201, 0x2100, 0x2302, 0x2100, 0x2201, 0x2100, 0x2403, 0x2100, + 0x2201, 0x2100, 0x2302, 0x2100, 0x2201, 0x2100, 0x2605, 0x3100, + 0x3201, 0x3100, 0x3302, 0x3100, 0x3201, 0x3100, 0x3403, 0x3100, + 0x3201, 0x3100, 0x3302, 0x3100, 0x3201, 0x3100, 0x3504, 0x4100, + 0x4201, 0x4100, 0x4302, 0x4100, 0x4201, 0x4100, 0x4403, 0x5100, + 0x5201, 0x5100, 0x5302, 0x6180, 0x6281, 0x7150, 0x8908 +}; + +/*---------------------------------------------------------------------------* + * HDLC_DECODE + * =========== + * + * u_char: flag, blevel + * u_short: crc, ib, tmp, tmp2, len + * + * next: 'continue' or 'goto xxx' + * + * cfr: complet frame + * nfr: new frame + * NOTE: must setup 'len' and 'dst', so that 'dst' may be written + * at most 'len' times. + * + * rab: abort + * rdd: read data (read byte is stored in 'tmp2') + * rdo: overflow + * + * d: dummy + * + * NOTE: setting flag to '0' and len to '0' => recover from rdu + * NOTE: bits[8 .. ] of tmp2 may be used to store custom data/flags + * NOTE: these variables have to be 'suspended' / 'resumed' somehow: + * flag, blevel, crc, ib, tmp, len + * NOTE: zero is default value for all variables. + * NOTE: each time 'dst' is written, 'len' is decremented by one. + *---------------------------------------------------------------------------*/ + +#define HDLC_DECODE(dst, len, tmp, tmp2, blevel, ib, crc, flag, rddcmd, nfrcmd, \ + cfrcmd, rabcmd, rdocmd, nextcmd, d) \ + \ + rddcmd; \ + \ + ib += HDLC_BIT_TAB[(u_char)tmp2]; \ + \ + if ((u_char)ib >= 5) \ + { \ + if (ib & 0x20) /* de-stuff (msb) */ \ + { \ + if ((u_char)tmp2 == 0x7e) goto j0##d; \ + tmp2 += tmp2 & 0x7f; \ + blevel--; \ + \ + if ((ib += 0x100) & 0xc) tmp2 |= 1; /* */ \ + } \ + \ + ib &= ~0xe0; \ + \ + if ((u_char)ib == 6) /* flag seq (lsb) */ \ + { \ + j0##d: if (flag >= 2) \ + { \ + len += (4 - flag) & 3; /* remove CRC bytes */ \ + crc ^= 0xf0b8; \ + cfrcmd; \ + len = 0; \ + } \ + \ + flag = 1; \ + \ + blevel = (ib >> 8) & 0xf; \ + tmp = ((u_char)tmp2) >> blevel; \ + blevel = 8 - blevel; \ + \ + ib >>= 12; \ + \ + nextcmd; \ + } \ + if ((u_char)ib >= 7) /* abort (msb & lsb) */ \ + { \ + if (flag >= 2) \ + { \ + rabcmd; \ + len = 0; \ + } \ + \ + flag = 0; \ + \ + ib >>= 12; \ + \ + nextcmd; \ + } \ + if ((u_char)ib == 5) /* de-stuff (lsb) */ \ + { \ + tmp2 = (tmp2 | (tmp2 + 1)) & ~0x1; \ + blevel--; \ + } \ + if (blevel > 7) /* EO - bits */ \ + { \ + tmp |= (u_char)tmp2 >> (8 - (blevel &= 7)); \ + \ + ib >>= 12; \ + \ + nextcmd; \ + } \ + } \ + \ + tmp |= (u_char)tmp2 << blevel; \ + \ + if (!len--) \ + { \ + len++; \ + \ + if (!flag++) { flag--; goto j5##d;} /* hunt mode */ \ + \ + switch (flag) \ + { case 2: /* new frame */ \ + nfrcmd; \ + crc = -1; \ + if (!len--) { len++; flag++; goto j4##d; } \ + goto j3##d; \ + case 3: /* CRC (lsb's) */ \ + case 4: /* CRC (msb's) */ \ + goto j4##d; \ + case 5: /* RDO */ \ + rdocmd; \ + flag = 0; \ + break; \ + } \ + } \ + else \ + { \ + j3##d: dst = (u_char)tmp; \ + j4##d: crc = (HDLC_FCS_TAB[(u_char)(tmp ^ crc)] ^ (u_char)(crc >> 8)); \ + } \ + \ + j5##d: ib >>= 12; \ + tmp >>= 8; \ + +/*------ end of HDLC_DECODE -------------------------------------------------*/ + + +/*---------------------------------------------------------------------------* + * HDLC_ENCODE + * =========== + * + * u_char: flag, src + * u_short: tmp2, blevel, ib, crc, len + * u_int: tmp + * + * gfr: get new frame, free old, and exit if no frame + * NOTE: must setup 'len' and 'src', so that 'src' can be read + * 'len' times. + * + * wrd: write data (output = (u_char)tmp) + * + * d: dummy + * + * NOTE: setting flag to '-1' and len to '0' => abort byte will be sent + * NOTE: these variables have to be 'suspended' / 'resumed' somehow: + * flag, blevel, crc, ib, tmp, len + * NOTE: zero is default value for all variables. + * NOTE: each time 'src' is read, 'len' is decremented by one. + * NOTE: gfr must setup 'len'. + *---------------------------------------------------------------------------*/ + +#define HDLC_ENCODE(src, len, tmp, tmp2, blevel, ib, crc, flag, gfrcmd, wrdcmd, d) \ + \ + if (blevel >= 0x800) { blevel -= 0x800; goto j4##d; } \ + \ + if (!len--) \ + { \ + len++; \ + \ + switch(++flag) \ + { case 0: /* abort */ \ + tmp = blevel = 0; /* zero is default */ \ + tmp2 = 0xff; \ + goto j3##d; \ + case 1: /* 1st time FS */ \ + case 2: /* 2nd time FS */ \ + tmp2 = 0x7e; \ + goto j3##d; \ + case 3: /* get new frame */ \ + flag--; \ + gfrcmd; \ + flag++; \ + crc = -1; \ + ib = 0; \ + if (!len--) { len++; flag++; goto j0##d; } \ + goto j1##d; /* first byte */ \ + case 4: /* CRC (lsb's) */ \ + j0##d: \ + crc ^= -1; \ + case 5: /* CRC (msb's) */ \ + tmp2 = (u_char)crc; \ + crc >>= 8; \ + goto j2##d; /* CRC stuff */ \ + case 6: /* frame done */ \ + tmp2 = 0x7e; /* end FS */ \ + flag = 1; \ + goto j3##d; \ + } \ + } \ + else \ + { j1##d : \ + tmp2 = (u_char)src; \ + crc =(HDLC_FCS_TAB[(u_char)(crc ^ tmp2)] ^ (u_char)(crc >> 8)); \ + j2##d: \ + \ + ib >>= 12; \ + ib += HDLC_BIT_TAB[(u_char)tmp2]; \ + \ + if ((u_char)ib >= 5) /* stuffing */ \ + { \ + blevel &= ~0xff; \ + \ + if (ib & 0xc0) /* bit stuff (msb) */ \ + { \ + tmp2 += tmp2 & (0xff * (ib & 0xc0)); \ + ib %= 0x5000; \ + blevel++; \ + } \ + \ + ib &= ~0xf0; \ + \ + if ((u_char)ib >= 5) /* bit stuff (lsb) */ \ + { \ + tmp2 += tmp2 & ~0x1f >> ((ib - (ib >> 8) + 1) \ + & 7); \ + blevel++; \ + \ + if ((u_char)ib >= 10) /* bit stuff (msb) */ \ + { \ + tmp2 += tmp2 & ~0x7ff >> ((ib - \ + (ib >> 8) + 1) & 7); \ + blevel++; \ + } \ + if (ib & 0x8000) /* bit walk */ \ + { \ + ib = ((u_char)ib % 5) << 12; \ + } \ + } \ + \ + tmp |= tmp2 << (u_char)(blevel >> 8); \ + blevel += (u_char)blevel << 8; \ + } \ + else /* no stuffing */ \ + { \ + j3##d:tmp |= tmp2 << (u_char)(blevel >> 8); \ + } \ + } \ + \ + j4##d: wrdcmd; \ + tmp >>= 8; \ + +/*------ end of HDLC_ENCODE -------------------------------------------------*/ + + +#endif /* _I4B_HDLC_H_ */ diff --git a/sys/i4b/layer1/i4b_isic_pcmcia.c b/sys/i4b/layer1/i4b_isic_pcmcia.c deleted file mode 100644 index 466ad56..0000000 --- a/sys/i4b/layer1/i4b_isic_pcmcia.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (c) 1998 Matthias Apitz. All rights reserved. - * - * Copyright (c) 1998, 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. - * 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. - * - *--------------------------------------------------------------------------- - * - * i4b_isic_pcmcia.c - i4b FreeBSD PCMCIA support - * ---------------------------------------------- - * - * $FreeBSD$ - * - * last edit-date: [Mon Apr 26 10:52:57 1999] - * - *---------------------------------------------------------------------------*/ - -#ifdef __FreeBSD__ -#include "isic.h" -#include "opt_i4b.h" -#include "card.h" -#undef NCARD -#define NCARD 0 - -#if (NISIC > 0) && (NCARD > 0) - -#include "apm.h" -#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/ioccom.h> -#else -#include <sys/ioctl.h> -#endif - -#include <sys/kernel.h> -#include <sys/systm.h> -#include <sys/mbuf.h> -#include <sys/socket.h> -#include <net/if.h> -#include <machine/clock.h> -#include <i386/isa/isa_device.h> - -#include <pccard/cardinfo.h> -#include <pccard/driver.h> -#include <pccard/slot.h> - -#include <machine/i4b_debug.h> -#include <machine/i4b_ioctl.h> -#include <machine/i4b_trace.h> - -#include <i4b/layer1/i4b_l1.h> -#include <i4b/layer1/i4b_isac.h> -#include <i4b/layer1/i4b_hscx.h> - -#include <i4b/include/i4b_l1l2.h> -#include <i4b/include/i4b_mbuf.h> -#include <i4b/include/i4b_global.h> - -#ifdef __FreeBSD__ - -#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. - */ -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 *)); - -#if defined(__FreeBSD__) && __FreeBSD__ < 3 -static struct pccard_device isic_info = { - "isic", - isic_pccard_init, - isic_unload, - 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. - */ - -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) - return(EBUSY); - - opened |= 1 << is->id_unit; - printf("isic%d: PCMCIA init, irqmask = 0x%x (%d), iobase = 0x%x\n", - is->id_unit, is->id_irq, devi->slt->irq, is->id_iobase); - - /* - * look if there is really an AVM PCMCIA Fritz!Card and - * setup the card specific stuff - */ - isic_probe_avma1_pcmcia(is); - - /* ap: - * XXX what's to do with the return value? - */ - - /* - * try to attach the PCMCIA card as a normal A1 card - */ - - isic_realattach(is, 0); - -#endif - return(0); -} - -static void isic_unload(devi) -struct pccard_devinfo *devi; -{ - struct isa_device *is = &devi->isahd; - printf("isic%d: unloaded\n", is->id_unit); - opened &= ~(1 << is->id_unit); -} - -/* - * card_intr - Shared interrupt called from - * front end of PC-Card handler. - */ -static int isic_card_intr(devi) -struct pccard_devinfo *devi; -{ - isicintr(devi->isahd.id_unit); - return(1); -} - -#endif /* (NISIC > 0) && (NCARD > 0) */ -#endif /* __FreeBSD__ */ diff --git a/sys/i4b/layer1/i4b_l1dmux.c b/sys/i4b/layer1/i4b_l1dmux.c new file mode 100644 index 0000000..115ae3a --- /dev/null +++ b/sys/i4b/layer1/i4b_l1dmux.c @@ -0,0 +1,447 @@ +/* + * Copyright (c) 2000 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_l1dmux.c - isdn4bsd layer 1 driver multiplexer + * -------------------------------------------------- + * + * $Id: i4b_l1dmux.c,v 1.12 2000/06/02 16:14:36 hm Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Fri Jun 2 14:37:39 2000] + * + *---------------------------------------------------------------------------*/ + +#include "isic.h" +#include "iwic.h" +#include "ifpi.h" +#include "ifpnp.h" +#include "ihfc.h" + +#include <sys/param.h> +#include <sys/kernel.h> +#include <sys/systm.h> +#include <sys/mbuf.h> +#include <sys/socket.h> + +#include <net/if.h> + +#include <machine/i4b_debug.h> +#include <machine/i4b_ioctl.h> +#include <machine/i4b_trace.h> + +#include <i4b/layer1/i4b_l1.h> + +#include <i4b/include/i4b_l1l2.h> +#include <i4b/include/i4b_mbuf.h> +#include <i4b/include/i4b_global.h> + +/* + * this code is nothing but a big dynamic switch to multiplex and demultiplex + * layer 1 hardware isdn drivers to a common layer 2. + * + * when a card is successfully attached at system boot time, the driver for + * this card calls the routine i4b_l1_mph_status_ind() with status = STI_ATTACH. + * + * This command is used to setup the tables for converting a "driver unit" and + * "driver type" pair (encoded in the calls from the hardware driver to the + * routines in this source file) to a "unit number" used in layer 2 and the + * layers above (up to and including the isdnd daemon) and for converting + * layer 2 units back to calling the appropriate driver and driver unit + * number. + * + * Example: in my setup, a Winbond (iwic) card is probed first and gets + * driver unit number 0, driver type 1 in layer 1. This becomes unit + * number 0 in layer 2 and up. The second card probed is a Teles card + * (isic) and gets driver unit number 0, driver type 0 in layer 1. This + * becomes unit number 1 in layer 1 and up. + * + * To add support for a new driver, add a new driver number to i4b_l1.h: + * currently we have L1DRVR_ISIC and L1DRVR_IWIC, so you would add + * L1DRVR_FOO. More you would want to add a L0FOOUNIT to encode unit + * numbers in your driver. You then have to add a l1foounittab[] and + * add an entry to the getl1tab() routine for your driver. The only + * thing left now is to write your driver with the support functions + * for this multiplexer ;-) + */ + +unsigned int i4b_l1_debug = L1_DEBUG_DEFAULT; + +#if NISIC > 0 +static int l1isicunittab[MAXL1UNITS]; +#endif + +#if NIWIC > 0 +static int l1iwicunittab[MAXL1UNITS]; +#endif + +#if NIFPI > 0 +static int l1ifpiunittab[MAXL1UNITS]; +#endif + +#if NIHFC > 0 +static int l1ihfcunittab[MAXL1UNITS]; +#endif + +#if NIFPNP > 0 +static int l1ifpnpunittab[MAXL1UNITS]; +#endif + +static int numl1units = 0; + +static int l1drvunittab[MAXL1UNITS]; +static struct i4b_l1mux_func *l1mux_func[MAXL1DRVR]; + +static int i4b_l1_ph_data_req(int, struct mbuf *, int); +static int i4b_l1_ph_activate_req(int); + +/* from i4btrc driver i4b_trace.c */ +int get_trace_data_from_l1(int unit, int what, int len, char *buf); + +/* from layer 2 */ +int i4b_ph_data_ind(int unit, struct mbuf *m); +int i4b_ph_activate_ind(int unit); +int i4b_ph_deactivate_ind(int unit); +int i4b_mph_status_ind(int, int, int); + +/* layer 1 lme */ +int i4b_l1_mph_command_req(int, int, void *); + +/*---------------------------------------------------------------------------* + * jump table: interface function pointers L1/L2 interface + *---------------------------------------------------------------------------*/ +struct i4b_l1l2_func i4b_l1l2_func = { + + /* Layer 1 --> Layer 2 */ + + (int (*)(int, struct mbuf *)) i4b_ph_data_ind, + (int (*)(int)) i4b_ph_activate_ind, + (int (*)(int)) i4b_ph_deactivate_ind, + + /* Layer 2 --> Layer 1 */ + + (int (*)(int, struct mbuf *, int)) i4b_l1_ph_data_req, + + (int (*)(int)) i4b_l1_ph_activate_req, + + /* Layer 1 --> trace interface driver, ISDN trace data */ + + (int (*)(i4b_trace_hdr_t *, int, u_char *)) get_trace_data_from_l1, + + /* Driver control and status information */ + + (int (*)(int, int, int)) i4b_mph_status_ind, + (int (*)(int, int, void *)) i4b_l1_mph_command_req, +}; + +/*---------------------------------------------------------------------------* + * return a pointer to a layer 0 drivers unit tab + *---------------------------------------------------------------------------*/ +static __inline int * +getl1tab(int drv) +{ + switch(drv) + { +#if NISIC > 0 + case L1DRVR_ISIC: + return(l1isicunittab); + break; +#endif +#if NIWIC > 0 + case L1DRVR_IWIC: + return(l1iwicunittab); + break; +#endif +#if NIFPI > 0 + case L1DRVR_IFPI: + return(l1ifpiunittab); + break; +#endif +#if NIHFC > 0 + case L1DRVR_IHFC: + return(l1ihfcunittab); + break; +#endif +#if NIFPNP > 0 + case L1DRVR_IFPNP: + return(l1ifpnpunittab); + break; +#endif + default: + return(NULL); + break; + } +} + +/*===========================================================================* + * B - Channel (data transfer) + *===========================================================================*/ + +/*---------------------------------------------------------------------------* + * return the address of ISDN drivers linktab + *---------------------------------------------------------------------------*/ +isdn_link_t * +i4b_l1_ret_linktab(int unit, int channel) +{ + int drv_unit, ch_unit; + + drv_unit = L0DRVR(l1drvunittab[unit]); + ch_unit = L0UNIT(l1drvunittab[unit]); + + NDBGL1(L1_PRIM, "unit %d -> drv %d / drvunit %d", unit, drv_unit, ch_unit); + + if (drv_unit >= MAXL1DRVR || l1mux_func[drv_unit] == NULL + || l1mux_func[drv_unit]->ret_linktab == NULL) + panic("i4b_l1_ret_linktab: unknown driver type %d\n", drv_unit); + + return(l1mux_func[drv_unit]->ret_linktab(ch_unit, channel)); +} + +/*---------------------------------------------------------------------------* + * set the ISDN driver linktab + *---------------------------------------------------------------------------*/ +void +i4b_l1_set_linktab(int unit, int channel, drvr_link_t *dlt) +{ + int drv_unit, ch_unit; + + drv_unit = L0DRVR(l1drvunittab[unit]); + ch_unit = L0UNIT(l1drvunittab[unit]); + + NDBGL1(L1_PRIM, "unit %d -> drv %d / drvunit %d", unit, drv_unit, ch_unit); + + if (drv_unit >= MAXL1DRVR || l1mux_func[drv_unit] == NULL + || l1mux_func[drv_unit]->set_linktab == NULL) + panic("i4b_l1_set_linktab: unknown driver type %d\n", drv_unit); + + l1mux_func[drv_unit]->set_linktab(ch_unit, channel, dlt); +} + +/*===========================================================================* + * trace D- and B-Channel support + *===========================================================================*/ + +/*---------------------------------------------------------------------------* + * L0 -> L1 trace information to trace driver + *---------------------------------------------------------------------------*/ +int +i4b_l1_trace_ind(i4b_trace_hdr_t *hdr, int len, u_char *data) +{ + register int *tab; + + if((tab = getl1tab(L0DRVR(hdr->unit))) == NULL) + panic("i4b_l1_trace_ind: unknown driver type %d\n", L0DRVR(hdr->unit)); + + NDBGL1(L1_PRIM, "(drv %d / drvunit %d) -> unit %d", L0DRVR(hdr->unit), L0UNIT(hdr->unit), tab[L0UNIT(hdr->unit)]); + + hdr->unit = tab[L0UNIT(hdr->unit)]; + + return(MPH_Trace_Ind(hdr, len, data)); +} + +/*===========================================================================* + * D - Channel (signalling) + *===========================================================================*/ + +/*---------------------------------------------------------------------------* + * L0 -> L1 status indication from hardware + *---------------------------------------------------------------------------*/ +int +i4b_l1_mph_status_ind(int drv_unit, int status, int parm, struct i4b_l1mux_func *l1mux_func_p) +{ + register int *tab; + + /* + * in case the status STI_ATTACH is sent from the hardware, the + * driver has just attached itself and we need to initialize + * the tables and assorted variables. + */ + + if(status == STI_ATTACH) + { + if (l1mux_func_p == (struct i4b_l1mux_func *)0) + panic("i4b_l1_mph_status_ind: i4b_l1mux_func pointer is NULL\n"); + + if(numl1units < MAXL1UNITS) + { + if((tab = getl1tab(L0DRVR(drv_unit))) == NULL) + panic("i4b_l1_mph_status_ind: unknown driver type %d\n", L0DRVR(drv_unit)); + + tab[L0UNIT(drv_unit)] = numl1units; + + l1drvunittab[numl1units] = drv_unit; + + l1mux_func[L0DRVR(drv_unit)] = l1mux_func_p; + + switch(L0DRVR(drv_unit)) + { +#if NISIC > 0 + case L1DRVR_ISIC: + printf("isic%d: passive stack unit %d\n", L0UNIT(drv_unit), numl1units); + break; +#endif +#if NIWIC > 0 + case L1DRVR_IWIC: + printf("iwic%d: passive stack unit %d\n", L0UNIT(drv_unit), numl1units); + break; +#endif +#if NIFPI > 0 + case L1DRVR_IFPI: + printf("ifpi%d: passive stack unit %d\n", L0UNIT(drv_unit), numl1units); + break; +#endif +#if NIFPNP > 0 + case L1DRVR_IFPNP: + printf("ifpnp%d: passive stack unit %d\n", L0UNIT(drv_unit), numl1units); + break; +#endif +#if NIHFC > 0 + case L1DRVR_IHFC: + printf("ihfc%d: passive stack unit %d\n", L0UNIT(drv_unit), numl1units); +#endif + } + + NDBGL1(L1_PRIM, "ATTACH drv %d, drvunit %d -> unit %d", L0DRVR(drv_unit), L0UNIT(drv_unit), numl1units); + + numl1units++; + } + } + + if((tab = getl1tab(L0DRVR(drv_unit))) == NULL) + panic("i4b_l1_mph_status_ind: unknown driver type %d\n", L0DRVR(drv_unit)); + + NDBGL1(L1_PRIM, "(drv %d / drvunit %d) -> unit %d\n", L0DRVR(drv_unit), L0UNIT(drv_unit), tab[L0UNIT(drv_unit)]); + + return(MPH_Status_Ind(tab[L0UNIT(drv_unit)], status, parm)); +} + +/*---------------------------------------------------------------------------* + * L0 -> L1 data from hardware + *---------------------------------------------------------------------------*/ +int +i4b_l1_ph_data_ind(int drv_unit, struct mbuf *data) +{ + register int *tab; + + if((tab = getl1tab(L0DRVR(drv_unit))) == NULL) + panic("i4b_l1_ph_data_ind: unknown driver type %d\n", L0DRVR(drv_unit)); + +#if 0 + NDBGL1(L1_PRIM, "(drv %d / drvunit %d) -> unit %d", L0DRVR(drv_unit), L0UNIT(drv_unit), tab[L0UNIT(drv_unit)]); +#endif + + return(PH_Data_Ind(tab[L0UNIT(drv_unit)], data)); +} + +/*---------------------------------------------------------------------------* + * L0 -> L1 activate indication from hardware + *---------------------------------------------------------------------------*/ +int +i4b_l1_ph_activate_ind(int drv_unit) +{ + register int *tab; + + if((tab = getl1tab(L0DRVR(drv_unit))) == NULL) + panic("i4b_l1_ph_activate_ind: unknown driver type %d\n", L0DRVR(drv_unit)); + + NDBGL1(L1_PRIM, "(drv %d / drvunit %d) -> unit %d", L0DRVR(drv_unit), L0UNIT(drv_unit), tab[L0UNIT(drv_unit)]); + + return(PH_Act_Ind(tab[L0UNIT(drv_unit)])); +} + +/*---------------------------------------------------------------------------* + * L0 -> L1 deactivate indication from hardware + *---------------------------------------------------------------------------*/ +int +i4b_l1_ph_deactivate_ind(int drv_unit) +{ + register int *tab; + + if((tab = getl1tab(L0DRVR(drv_unit))) == NULL) + panic("i4b_l1_ph_deactivate_ind: unknown driver type %d\n", L0DRVR(drv_unit)); + + NDBGL1(L1_PRIM, "(drv %d / drvunit %d) -> unit %d", L0DRVR(drv_unit), L0UNIT(drv_unit), tab[L0UNIT(drv_unit)]); + + return(PH_Deact_Ind(tab[L0UNIT(drv_unit)])); +} + +/*---------------------------------------------------------------------------* + * L2 -> L1 command to hardware + *---------------------------------------------------------------------------*/ +int +i4b_l1_mph_command_req(int unit, int command, void * parm) +{ + register int drv_unit = L0DRVR(l1drvunittab[unit]); + register int ch_unit = L0UNIT(l1drvunittab[unit]); + + NDBGL1(L1_PRIM, "unit %d -> drv %d / drvunit %d", unit, drv_unit, ch_unit); + + if (drv_unit >= MAXL1DRVR || l1mux_func[drv_unit] == NULL + || l1mux_func[drv_unit]->mph_command_req == NULL) + panic("i4b_l1_mph_command_req: unknown driver type %d\n", drv_unit); + + return(l1mux_func[drv_unit]->mph_command_req(ch_unit, command, parm)); +} + +/*---------------------------------------------------------------------------* + * L2 -> L1 data to be transmitted to hardware + *---------------------------------------------------------------------------*/ +int +i4b_l1_ph_data_req(int unit, struct mbuf *data, int flag) +{ + register int drv_unit = L0DRVR(l1drvunittab[unit]); + register int ch_unit = L0UNIT(l1drvunittab[unit]); + +#if 0 + NDBGL1(L1_PRIM, "unit %d -> drv %d / drvunit %d", unit, drv_unit, ch_unit); +#endif + + if (drv_unit >= MAXL1DRVR || l1mux_func[drv_unit] == NULL + || l1mux_func[drv_unit]->ph_data_req == NULL) + panic("i4b_l1_ph_data_req: unknown driver type %d\n", drv_unit); + + return(l1mux_func[drv_unit]->ph_data_req(ch_unit, data, flag)); +} + +/*---------------------------------------------------------------------------* + * L2 -> L1 activate request to hardware + *---------------------------------------------------------------------------*/ +int +i4b_l1_ph_activate_req(int unit) +{ + register int drv_unit = L0DRVR(l1drvunittab[unit]); + register int ch_unit = L0UNIT(l1drvunittab[unit]); + + NDBGL1(L1_PRIM, "unit %d -> drv %d / drvunit %d", unit, drv_unit, ch_unit); + + if (drv_unit >= MAXL1DRVR || l1mux_func[drv_unit] == NULL + || l1mux_func[drv_unit]->ph_activate_req == NULL) + panic("i4b_l1_ph_activate_req: unknown driver type %d\n", drv_unit); + + return(l1mux_func[drv_unit]->ph_activate_req(ch_unit)); +} + +/* EOF */ diff --git a/sys/i4b/layer1/i4b_l1lib.c b/sys/i4b/layer1/i4b_l1lib.c new file mode 100644 index 0000000..e4b0cd8 --- /dev/null +++ b/sys/i4b/layer1/i4b_l1lib.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2000 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_l1lib.c - general useful L1 procedures + * ------------------------------------------ + * + * $Id: i4b_l1lib.c,v 1.3 2000/05/29 15:41:41 hm Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Mon May 29 15:24:21 2000] + * + *---------------------------------------------------------------------------*/ + +#include <sys/param.h> +#include <sys/kernel.h> +#include <sys/systm.h> +#include <sys/mbuf.h> +#include <sys/socket.h> + +#include <net/if.h> + +#include <machine/i4b_debug.h> +#include <machine/i4b_ioctl.h> +#include <machine/i4b_trace.h> + +#include <i4b/layer1/i4b_l1.h> + +#define TEL_IDLE_MIN (BCH_MAX_DATALEN/2) + +/*---------------------------------------------------------------------------* + * telephony silence detection + *---------------------------------------------------------------------------*/ +int +i4b_l1_bchan_tel_silence(unsigned char *data, int len) +{ + register int i = 0; + register int j = 0; + + /* count idle bytes */ + + for(;i < len; i++) + { + if((*data >= 0xaa) && (*data <= 0xac)) + j++; + data++; + } + +#ifdef NOTDEF + printf("i4b_l1_bchan_tel_silence: got %d silence bytes in frame\n", j); +#endif + + if(j < (TEL_IDLE_MIN)) + return(0); + else + return(1); + +} diff --git a/sys/i4b/layer1/ifpi/i4b_ifpi_ext.h b/sys/i4b/layer1/ifpi/i4b_ifpi_ext.h new file mode 100644 index 0000000..c2d4cdf --- /dev/null +++ b/sys/i4b/layer1/ifpi/i4b_ifpi_ext.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2000 Gary Jennejohn. 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_ifpi - Fritz!Card PCI for split layers + * ------------------------------------------ + * + * $Id: i4b_ifpi_ext.h,v 1.2 2000/06/02 16:14:36 hm Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Fri Jun 2 14:53:31 2000] + * + *---------------------------------------------------------------------------*/ + +#ifndef _I4B_IFPI_EXT_H_ +#define _I4B_IFPI_EXT_H_ + +#include <i4b/include/i4b_l3l4.h> + +void ifpi_set_linktab(int unit, int channel, drvr_link_t * dlt); +isdn_link_t *ifpi_ret_linktab(int unit, int channel); + +int ifpi_ph_data_req(int unit, struct mbuf *m, int freeflag); +int ifpi_ph_activate_req(int unit); +int ifpi_mph_command_req(int unit, int command, void *parm); + +void ifpi_isac_irq(struct l1_softc *sc, int ista); +void ifpi_isac_l1_cmd(struct l1_softc *sc, int command); +int ifpi_isac_init(struct l1_softc *sc); + +void ifpi_recover(struct l1_softc *sc); +char * ifpi_printstate(struct l1_softc *sc); +void ifpi_next_state(struct l1_softc *sc, int event); + +#define IFPI_MAXUNIT 4 +extern struct l1_softc *ifpi_scp[IFPI_MAXUNIT]; + +#endif /* _I4B_IFPI_EXT_H_ */ diff --git a/sys/i4b/layer1/ifpi/i4b_ifpi_isac.c b/sys/i4b/layer1/ifpi/i4b_ifpi_isac.c new file mode 100644 index 0000000..4c09daf --- /dev/null +++ b/sys/i4b/layer1/ifpi/i4b_ifpi_isac.c @@ -0,0 +1,669 @@ +/* + * Copyright (c) 1997, 2000 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_ifpi_isac.c - i4b Fritz PCI ISAC handler + * -------------------------------------------- + * + * $Id: i4b_ifpi_isac.c,v 1.3 2000/05/29 15:41:41 hm Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Mon May 29 15:22:52 2000] + * + *---------------------------------------------------------------------------*/ + +#include "ifpi.h" +#include "pci.h" + +#if (NIFPI > 0) && (NPCI > 0) + +#include "opt_i4b.h" + +#include <sys/param.h> +#include <sys/kernel.h> +#include <sys/systm.h> +#include <sys/mbuf.h> +#include <sys/socket.h> + +#include <machine/stdarg.h> +#include <machine/clock.h> + +#include <net/if.h> + +#include <machine/i4b_debug.h> +#include <machine/i4b_ioctl.h> +#include <machine/i4b_trace.h> + +#include <i4b/layer1/i4b_l1.h> + +#include <i4b/layer1/isic/i4b_isic.h> +#include <i4b/layer1/isic/i4b_isac.h> +#include <i4b/layer1/isic/i4b_hscx.h> + +#include <i4b/layer1/ifpi/i4b_ifpi_ext.h> + +#include <i4b/include/i4b_global.h> +#include <i4b/include/i4b_mbuf.h> + +static u_char ifpi_isac_exir_hdlr(register struct l1_softc *sc, u_char exir); +static void ifpi_isac_ind_hdlr(register struct l1_softc *sc, int ind); + +/*---------------------------------------------------------------------------* + * ISAC interrupt service routine + *---------------------------------------------------------------------------*/ +void +ifpi_isac_irq(struct l1_softc *sc, int ista) +{ + register u_char c = 0; + NDBGL1(L1_F_MSG, "unit %d: ista = 0x%02x", sc->sc_unit, ista); + + if(ista & ISAC_ISTA_EXI) /* extended interrupt */ + { + c |= ifpi_isac_exir_hdlr(sc, ISAC_READ(I_EXIR)); + } + + if(ista & ISAC_ISTA_RME) /* receive message end */ + { + register int rest; + u_char rsta; + + /* get rx status register */ + + rsta = ISAC_READ(I_RSTA); + + if((rsta & ISAC_RSTA_MASK) != 0x20) + { + int error = 0; + + if(!(rsta & ISAC_RSTA_CRC)) /* CRC error */ + { + error++; + NDBGL1(L1_I_ERR, "unit %d: CRC error", sc->sc_unit); + } + + if(rsta & ISAC_RSTA_RDO) /* ReceiveDataOverflow */ + { + error++; + NDBGL1(L1_I_ERR, "unit %d: Data Overrun error", sc->sc_unit); + } + + if(rsta & ISAC_RSTA_RAB) /* ReceiveABorted */ + { + error++; + NDBGL1(L1_I_ERR, "unit %d: Receive Aborted error", sc->sc_unit); + } + + if(error == 0) + NDBGL1(L1_I_ERR, "unit %d: RME unknown error, RSTA = 0x%02x!", sc->sc_unit, rsta); + + i4b_Dfreembuf(sc->sc_ibuf); + + c |= ISAC_CMDR_RMC|ISAC_CMDR_RRES; + + sc->sc_ibuf = NULL; + sc->sc_ib = NULL; + sc->sc_ilen = 0; + + ISAC_WRITE(I_CMDR, ISAC_CMDR_RMC|ISAC_CMDR_RRES); + ISACCMDRWRDELAY(); + + return; + } + + rest = (ISAC_READ(I_RBCL) & (ISAC_FIFO_LEN-1)); + + if(rest == 0) + rest = ISAC_FIFO_LEN; + + if(sc->sc_ibuf == NULL) + { + if((sc->sc_ibuf = i4b_Dgetmbuf(rest)) != NULL) + sc->sc_ib = sc->sc_ibuf->m_data; + else + panic("ifpi_isac_irq: RME, i4b_Dgetmbuf returns NULL!\n"); + sc->sc_ilen = 0; + } + + if(sc->sc_ilen <= (MAX_DFRAME_LEN - rest)) + { + ISAC_RDFIFO(sc->sc_ib, rest); + sc->sc_ilen += rest; + + sc->sc_ibuf->m_pkthdr.len = + sc->sc_ibuf->m_len = sc->sc_ilen; + + if(sc->sc_trace & TRACE_D_RX) + { + i4b_trace_hdr_t hdr; + hdr.unit = L0IFPIUNIT(sc->sc_unit); + hdr.type = TRC_CH_D; + hdr.dir = FROM_NT; + hdr.count = ++sc->sc_trace_dcount; + MICROTIME(hdr.time); + i4b_l1_trace_ind(&hdr, sc->sc_ibuf->m_len, sc->sc_ibuf->m_data); + } + + c |= ISAC_CMDR_RMC; + + if(sc->sc_enabled && + (ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S)) + { + i4b_l1_ph_data_ind(L0IFPIUNIT(sc->sc_unit), sc->sc_ibuf); + } + else + { + i4b_Dfreembuf(sc->sc_ibuf); + } + } + else + { + NDBGL1(L1_I_ERR, "RME, input buffer overflow!"); + i4b_Dfreembuf(sc->sc_ibuf); + c |= ISAC_CMDR_RMC|ISAC_CMDR_RRES; + } + + sc->sc_ibuf = NULL; + sc->sc_ib = NULL; + sc->sc_ilen = 0; + } + + if(ista & ISAC_ISTA_RPF) /* receive fifo full */ + { + if(sc->sc_ibuf == NULL) + { + if((sc->sc_ibuf = i4b_Dgetmbuf(MAX_DFRAME_LEN)) != NULL) + sc->sc_ib= sc->sc_ibuf->m_data; + else + panic("ifpi_isac_irq: RPF, i4b_Dgetmbuf returns NULL!\n"); + sc->sc_ilen = 0; + } + + if(sc->sc_ilen <= (MAX_DFRAME_LEN - ISAC_FIFO_LEN)) + { + ISAC_RDFIFO(sc->sc_ib, ISAC_FIFO_LEN); + sc->sc_ilen += ISAC_FIFO_LEN; + sc->sc_ib += ISAC_FIFO_LEN; + c |= ISAC_CMDR_RMC; + } + else + { + NDBGL1(L1_I_ERR, "RPF, input buffer overflow!"); + i4b_Dfreembuf(sc->sc_ibuf); + sc->sc_ibuf = NULL; + sc->sc_ib = NULL; + sc->sc_ilen = 0; + c |= ISAC_CMDR_RMC|ISAC_CMDR_RRES; + } + } + + if(ista & ISAC_ISTA_XPR) /* transmit fifo empty (XPR bit set) */ + { + if((sc->sc_obuf2 != NULL) && (sc->sc_obuf == NULL)) + { + sc->sc_freeflag = sc->sc_freeflag2; + sc->sc_obuf = sc->sc_obuf2; + sc->sc_op = sc->sc_obuf->m_data; + sc->sc_ol = sc->sc_obuf->m_len; + sc->sc_obuf2 = NULL; +#ifdef NOTDEF + printf("ob2=%x, op=%x, ol=%d, f=%d #", + sc->sc_obuf, + sc->sc_op, + sc->sc_ol, + sc->sc_state); +#endif + } + else + { +#ifdef NOTDEF + printf("ob=%x, op=%x, ol=%d, f=%d #", + sc->sc_obuf, + sc->sc_op, + sc->sc_ol, + sc->sc_state); +#endif + } + + if(sc->sc_obuf) + { + ISAC_WRFIFO(sc->sc_op, min(sc->sc_ol, ISAC_FIFO_LEN)); + + if(sc->sc_ol > ISAC_FIFO_LEN) /* length > 32 ? */ + { + sc->sc_op += ISAC_FIFO_LEN; /* bufferptr+32 */ + sc->sc_ol -= ISAC_FIFO_LEN; /* length - 32 */ + c |= ISAC_CMDR_XTF; /* set XTF bit */ + } + else + { + if(sc->sc_freeflag) + { + i4b_Dfreembuf(sc->sc_obuf); + sc->sc_freeflag = 0; + } + sc->sc_obuf = NULL; + sc->sc_op = NULL; + sc->sc_ol = 0; + + c |= ISAC_CMDR_XTF | ISAC_CMDR_XME; + } + } + else + { + sc->sc_state &= ~ISAC_TX_ACTIVE; + } + } + + if(ista & ISAC_ISTA_CISQ) /* channel status change CISQ */ + { + register u_char ci; + + /* get command/indication rx register*/ + + ci = ISAC_READ(I_CIRR); + + /* if S/Q IRQ, read SQC reg to clr SQC IRQ */ + + if(ci & ISAC_CIRR_SQC) + (void) ISAC_READ(I_SQRR); + + /* C/I code change IRQ (flag already cleared by CIRR read) */ + + if(ci & ISAC_CIRR_CIC0) + ifpi_isac_ind_hdlr(sc, (ci >> 2) & 0xf); + } + + if(c) + { + ISAC_WRITE(I_CMDR, c); + ISACCMDRWRDELAY(); + } +} + +/*---------------------------------------------------------------------------* + * ISAC L1 Extended IRQ handler + *---------------------------------------------------------------------------*/ +static u_char +ifpi_isac_exir_hdlr(register struct l1_softc *sc, u_char exir) +{ + u_char c = 0; + + if(exir & ISAC_EXIR_XMR) + { + NDBGL1(L1_I_ERR, "EXIRQ Tx Message Repeat"); + + c |= ISAC_CMDR_XRES; + } + + if(exir & ISAC_EXIR_XDU) + { + NDBGL1(L1_I_ERR, "EXIRQ Tx Data Underrun"); + + c |= ISAC_CMDR_XRES; + } + + if(exir & ISAC_EXIR_PCE) + { + NDBGL1(L1_I_ERR, "EXIRQ Protocol Error"); + } + + if(exir & ISAC_EXIR_RFO) + { + NDBGL1(L1_I_ERR, "EXIRQ Rx Frame Overflow"); + + c |= ISAC_CMDR_RMC|ISAC_CMDR_RRES; + } + + if(exir & ISAC_EXIR_SOV) + { + NDBGL1(L1_I_ERR, "EXIRQ Sync Xfer Overflow"); + } + + if(exir & ISAC_EXIR_MOS) + { + NDBGL1(L1_I_ERR, "EXIRQ Monitor Status"); + } + + if(exir & ISAC_EXIR_SAW) + { + /* cannot happen, STCR:TSF is set to 0 */ + + NDBGL1(L1_I_ERR, "EXIRQ Subscriber Awake"); + } + + if(exir & ISAC_EXIR_WOV) + { + /* cannot happen, STCR:TSF is set to 0 */ + + NDBGL1(L1_I_ERR, "EXIRQ Watchdog Timer Overflow"); + } + + return(c); +} + +/*---------------------------------------------------------------------------* + * ISAC L1 Indication handler + *---------------------------------------------------------------------------*/ +static void +ifpi_isac_ind_hdlr(register struct l1_softc *sc, int ind) +{ + register int event; + + switch(ind) + { + case ISAC_CIRR_IAI8: + NDBGL1(L1_I_CICO, "rx AI8 in state %s", ifpi_printstate(sc)); + if(sc->sc_bustyp == BUS_TYPE_IOM2) + ifpi_isac_l1_cmd(sc, CMD_AR8); + event = EV_INFO48; + i4b_l1_mph_status_ind(L0IFPIUNIT(sc->sc_unit), STI_L1STAT, LAYER_ACTIVE, NULL); + break; + + case ISAC_CIRR_IAI10: + NDBGL1(L1_I_CICO, "rx AI10 in state %s", ifpi_printstate(sc)); + if(sc->sc_bustyp == BUS_TYPE_IOM2) + ifpi_isac_l1_cmd(sc, CMD_AR10); + event = EV_INFO410; + i4b_l1_mph_status_ind(L0IFPIUNIT(sc->sc_unit), STI_L1STAT, LAYER_ACTIVE, NULL); + break; + + case ISAC_CIRR_IRSY: + NDBGL1(L1_I_CICO, "rx RSY in state %s", ifpi_printstate(sc)); + event = EV_RSY; + break; + + case ISAC_CIRR_IPU: + NDBGL1(L1_I_CICO, "rx PU in state %s", ifpi_printstate(sc)); + event = EV_PU; + break; + + case ISAC_CIRR_IDR: + NDBGL1(L1_I_CICO, "rx DR in state %s", ifpi_printstate(sc)); + ifpi_isac_l1_cmd(sc, CMD_DIU); + event = EV_DR; + break; + + case ISAC_CIRR_IDID: + NDBGL1(L1_I_CICO, "rx DID in state %s", ifpi_printstate(sc)); + event = EV_INFO0; + i4b_l1_mph_status_ind(L0IFPIUNIT(sc->sc_unit), STI_L1STAT, LAYER_IDLE, NULL); + break; + + case ISAC_CIRR_IDIS: + NDBGL1(L1_I_CICO, "rx DIS in state %s", ifpi_printstate(sc)); + event = EV_DIS; + break; + + case ISAC_CIRR_IEI: + NDBGL1(L1_I_CICO, "rx EI in state %s", ifpi_printstate(sc)); + ifpi_isac_l1_cmd(sc, CMD_DIU); + event = EV_EI; + break; + + case ISAC_CIRR_IARD: + NDBGL1(L1_I_CICO, "rx ARD in state %s", ifpi_printstate(sc)); + event = EV_INFO2; + break; + + case ISAC_CIRR_ITI: + NDBGL1(L1_I_CICO, "rx TI in state %s", ifpi_printstate(sc)); + event = EV_INFO0; + break; + + case ISAC_CIRR_IATI: + NDBGL1(L1_I_CICO, "rx ATI in state %s", ifpi_printstate(sc)); + event = EV_INFO0; + break; + + case ISAC_CIRR_ISD: + NDBGL1(L1_I_CICO, "rx SD in state %s", ifpi_printstate(sc)); + event = EV_INFO0; + break; + + default: + NDBGL1(L1_I_ERR, "UNKNOWN Indication 0x%x in state %s", ind, ifpi_printstate(sc)); + event = EV_INFO0; + break; + } + ifpi_next_state(sc, event); +} + +/*---------------------------------------------------------------------------* + * execute a layer 1 command + *---------------------------------------------------------------------------*/ +void +ifpi_isac_l1_cmd(struct l1_softc *sc, int command) +{ + u_char cmd; + +#ifdef I4B_SMP_WORKAROUND + + /* XXXXXXXXXXXXXXXXXXX */ + + /* + * patch from Wolfgang Helbig: + * + * Here is a patch that makes i4b work on an SMP: + * The card (TELES 16.3) didn't interrupt on an SMP machine. + * This is a gross workaround, but anyway it works *and* provides + * some information as how to finally fix this problem. + */ + + HSCX_WRITE(0, H_MASK, 0xff); + HSCX_WRITE(1, H_MASK, 0xff); + ISAC_WRITE(I_MASK, 0xff); + DELAY(100); + HSCX_WRITE(0, H_MASK, HSCX_A_IMASK); + HSCX_WRITE(1, H_MASK, HSCX_B_IMASK); + ISAC_WRITE(I_MASK, ISAC_IMASK); + + /* XXXXXXXXXXXXXXXXXXX */ + +#endif /* I4B_SMP_WORKAROUND */ + + if(command < 0 || command > CMD_ILL) + { + NDBGL1(L1_I_ERR, "illegal cmd 0x%x in state %s", command, ifpi_printstate(sc)); + return; + } + + if(sc->sc_bustyp == BUS_TYPE_IOM2) + cmd = ISAC_CIX0_LOW; + else + cmd = 0; + + switch(command) + { + case CMD_TIM: + NDBGL1(L1_I_CICO, "tx TIM in state %s", ifpi_printstate(sc)); + cmd |= (ISAC_CIXR_CTIM << 2); + break; + + case CMD_RS: + NDBGL1(L1_I_CICO, "tx RS in state %s", ifpi_printstate(sc)); + cmd |= (ISAC_CIXR_CRS << 2); + break; + + case CMD_AR8: + NDBGL1(L1_I_CICO, "tx AR8 in state %s", ifpi_printstate(sc)); + cmd |= (ISAC_CIXR_CAR8 << 2); + break; + + case CMD_AR10: + NDBGL1(L1_I_CICO, "tx AR10 in state %s", ifpi_printstate(sc)); + cmd |= (ISAC_CIXR_CAR10 << 2); + break; + + case CMD_DIU: + NDBGL1(L1_I_CICO, "tx DIU in state %s", ifpi_printstate(sc)); + cmd |= (ISAC_CIXR_CDIU << 2); + break; + } + ISAC_WRITE(I_CIXR, cmd); +} + +/*---------------------------------------------------------------------------* + * L1 ISAC initialization + *---------------------------------------------------------------------------*/ +int +ifpi_isac_init(struct l1_softc *sc) +{ + ISAC_IMASK = 0xff; /* disable all irqs */ + + ISAC_WRITE(I_MASK, ISAC_IMASK); + + if(sc->sc_bustyp != BUS_TYPE_IOM2) + { + NDBGL1(L1_I_SETUP, "configuring for IOM-1 mode"); + + /* ADF2: Select mode IOM-1 */ + ISAC_WRITE(I_ADF2, 0x00); + + /* SPCR: serial port control register: + * SPU - software power up = 0 + * SAC - SIP port high Z + * SPM - timing mode 0 + * TLP - test loop = 0 + * C1C, C2C - B1 and B2 switched to/from SPa + */ + ISAC_WRITE(I_SPCR, ISAC_SPCR_C1C1|ISAC_SPCR_C2C1); + + /* SQXR: S/Q channel xmit register: + * SQIE - S/Q IRQ enable = 0 + * SQX1-4 - Fa bits = 1 + */ + ISAC_WRITE(I_SQXR, ISAC_SQXR_SQX1|ISAC_SQXR_SQX2|ISAC_SQXR_SQX3|ISAC_SQXR_SQX4); + + /* ADF1: additional feature reg 1: + * WTC - watchdog = 0 + * TEM - test mode = 0 + * PFS - pre-filter = 0 + * CFS - IOM clock/frame always active + * FSC1/2 - polarity of 8kHz strobe + * ITF - interframe fill = idle + */ + ISAC_WRITE(I_ADF1, ISAC_ADF1_FC2); /* ADF1 */ + + /* STCR: sync transfer control reg: + * TSF - terminal secific functions = 0 + * TBA - TIC bus address = 7 + * STx/SCx = 0 + */ + ISAC_WRITE(I_STCR, ISAC_STCR_TBA2|ISAC_STCR_TBA1|ISAC_STCR_TBA0); + + /* MODE: Mode Register: + * MDSx - transparent mode 2 + * TMD - timer mode = external + * RAC - Receiver enabled + * DIMx - digital i/f mode + */ + ISAC_WRITE(I_MODE, ISAC_MODE_MDS2|ISAC_MODE_MDS1|ISAC_MODE_RAC|ISAC_MODE_DIM0); + } + else + { + NDBGL1(L1_I_SETUP, "configuring for IOM-2 mode"); + + /* ADF2: Select mode IOM-2 */ + ISAC_WRITE(I_ADF2, ISAC_ADF2_IMS); + + /* SPCR: serial port control register: + * SPU - software power up = 0 + * SPM - timing mode 0 + * TLP - test loop = 0 + * C1C, C2C - B1 + C1 and B2 + IC2 monitoring + */ + ISAC_WRITE(I_SPCR, 0x00); + + /* SQXR: S/Q channel xmit register: + * IDC - IOM direction = 0 (master) + * CFS - Config Select = 0 (clock always active) + * CI1E - C/I channel 1 IRQ enable = 0 + * SQIE - S/Q IRQ enable = 0 + * SQX1-4 - Fa bits = 1 + */ + ISAC_WRITE(I_SQXR, ISAC_SQXR_SQX1|ISAC_SQXR_SQX2|ISAC_SQXR_SQX3|ISAC_SQXR_SQX4); + + /* ADF1: additional feature reg 1: + * WTC - watchdog = 0 + * TEM - test mode = 0 + * PFS - pre-filter = 0 + * IOF - IOM i/f off = 0 + * ITF - interframe fill = idle + */ + ISAC_WRITE(I_ADF1, 0x00); + + /* STCR: sync transfer control reg: + * TSF - terminal secific functions = 0 + * TBA - TIC bus address = 7 + * STx/SCx = 0 + */ + ISAC_WRITE(I_STCR, ISAC_STCR_TBA2|ISAC_STCR_TBA1|ISAC_STCR_TBA0); + + /* MODE: Mode Register: + * MDSx - transparent mode 2 + * TMD - timer mode = external + * RAC - Receiver enabled + * DIMx - digital i/f mode + */ + ISAC_WRITE(I_MODE, ISAC_MODE_MDS2|ISAC_MODE_MDS1|ISAC_MODE_RAC|ISAC_MODE_DIM0); + } + +#ifdef NOTDEF + /* + * XXX a transmitter reset causes an ISAC tx IRQ which will not + * be serviced at attach time under some circumstances leaving + * the associated IRQ line on the ISA bus active. This prevents + * any further interrupts to be serviced because no low -> high + * transition can take place anymore. (-hm) + */ + + /* command register: + * RRES - HDLC receiver reset + * XRES - transmitter reset + */ + ISAC_WRITE(I_CMDR, ISAC_CMDR_RRES|ISAC_CMDR_XRES); + ISACCMDRWRDELAY(); +#endif + + /* enabled interrupts: + * =================== + * RME - receive message end + * RPF - receive pool full + * XPR - transmit pool ready + * CISQ - CI or S/Q channel change + * EXI - extended interrupt + */ + + ISAC_IMASK = ISAC_MASK_RSC | /* auto mode only */ + ISAC_MASK_TIN | /* timer irq */ + ISAC_MASK_SIN; /* sync xfer irq */ + + ISAC_WRITE(I_MASK, ISAC_IMASK); + + return(0); +} + +#endif /* NIFPI > 0 */ diff --git a/sys/i4b/layer1/ifpi/i4b_ifpi_l1.c b/sys/i4b/layer1/ifpi/i4b_ifpi_l1.c new file mode 100644 index 0000000..eb0aa2c --- /dev/null +++ b/sys/i4b/layer1/ifpi/i4b_ifpi_l1.c @@ -0,0 +1,248 @@ +/* + * Copyright (c) 1997, 2000 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_ifpi_l1.c - AVM Fritz PCI layer 1 handler + * --------------------------------------------- + * + * $Id: i4b_ifpi_l1.c,v 1.4 2000/06/02 16:14:36 hm Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Fri Jun 2 14:54:30 2000] + * + *---------------------------------------------------------------------------*/ + +#include "ifpi.h" +#include "pci.h" + +#if (NIFPI > 0) && (NPCI > 0) + +#include <sys/param.h> +#include <sys/kernel.h> +#include <sys/systm.h> +#include <sys/mbuf.h> +#include <sys/socket.h> + +#include <machine/stdarg.h> +#include <machine/clock.h> + +#include <net/if.h> + +#include <machine/i4b_debug.h> +#include <machine/i4b_ioctl.h> +#include <machine/i4b_trace.h> + +#include <i4b/layer1/isic/i4b_isic.h> +#include <i4b/layer1/isic/i4b_isac.h> +#include <i4b/layer1/isic/i4b_hscx.h> + +#include <i4b/layer1/ifpi/i4b_ifpi_ext.h> + +#include <i4b/layer1/i4b_l1.h> + +#include <i4b/include/i4b_mbuf.h> +#include <i4b/include/i4b_global.h> + +/*---------------------------------------------------------------------------* + * + * L2 -> L1: PH-DATA-REQUEST + * ========================= + * + * parms: + * unit physical interface unit number + * m mbuf containing L2 frame to be sent out + * freeflag MBUF_FREE: free mbuf here after having sent + * it out + * MBUF_DONTFREE: mbuf is freed by Layer 2 + * returns: + * ==0 fail, nothing sent out + * !=0 ok, frame sent out + * + *---------------------------------------------------------------------------*/ +int +ifpi_ph_data_req(int unit, struct mbuf *m, int freeflag) +{ + u_char cmd; + int s; + struct l1_softc *sc = ifpi_scp[unit]; + +#ifdef NOTDEF + NDBGL1(L1_PRIM, "PH-DATA-REQ, unit %d, freeflag=%d", unit, freeflag); +#endif + + if(m == NULL) /* failsafe */ + return (0); + + s = SPLI4B(); + + if(sc->sc_I430state == ST_F3) /* layer 1 not running ? */ + { + NDBGL1(L1_I_ERR, "still in state F3!"); + ifpi_ph_activate_req(unit); + } + + if(sc->sc_state & ISAC_TX_ACTIVE) + { + if(sc->sc_obuf2 == NULL) + { + sc->sc_obuf2 = m; /* save mbuf ptr */ + + if(freeflag) + sc->sc_freeflag2 = 1; /* IRQ must mfree */ + else + sc->sc_freeflag2 = 0; /* IRQ must not mfree */ + + NDBGL1(L1_I_MSG, "using 2nd ISAC TX buffer, state = %s", ifpi_printstate(sc)); + + if(sc->sc_trace & TRACE_D_TX) + { + i4b_trace_hdr_t hdr; + hdr.unit = L0IFPIUNIT(unit); + hdr.type = TRC_CH_D; + hdr.dir = FROM_TE; + hdr.count = ++sc->sc_trace_dcount; + MICROTIME(hdr.time); + i4b_l1_trace_ind(&hdr, m->m_len, m->m_data); + } + splx(s); + return(1); + } + + NDBGL1(L1_I_ERR, "No Space in TX FIFO, state = %s", ifpi_printstate(sc)); + + if(freeflag == MBUF_FREE) + i4b_Dfreembuf(m); + + splx(s); + return (0); + } + + if(sc->sc_trace & TRACE_D_TX) + { + i4b_trace_hdr_t hdr; + hdr.unit = L0IFPIUNIT(unit); + hdr.type = TRC_CH_D; + hdr.dir = FROM_TE; + hdr.count = ++sc->sc_trace_dcount; + MICROTIME(hdr.time); + i4b_l1_trace_ind(&hdr, m->m_len, m->m_data); + } + + sc->sc_state |= ISAC_TX_ACTIVE; /* set transmitter busy flag */ + + NDBGL1(L1_I_MSG, "ISAC_TX_ACTIVE set"); + + sc->sc_freeflag = 0; /* IRQ must NOT mfree */ + + ISAC_WRFIFO(m->m_data, min(m->m_len, ISAC_FIFO_LEN)); /* output to TX fifo */ + + if(m->m_len > ISAC_FIFO_LEN) /* message > 32 bytes ? */ + { + sc->sc_obuf = m; /* save mbuf ptr */ + sc->sc_op = m->m_data + ISAC_FIFO_LEN; /* ptr for irq hdl */ + sc->sc_ol = m->m_len - ISAC_FIFO_LEN; /* length for irq hdl */ + + if(freeflag) + sc->sc_freeflag = 1; /* IRQ must mfree */ + + cmd = ISAC_CMDR_XTF; + } + else + { + sc->sc_obuf = NULL; + sc->sc_op = NULL; + sc->sc_ol = 0; + + if(freeflag) + i4b_Dfreembuf(m); + + cmd = ISAC_CMDR_XTF | ISAC_CMDR_XME; + } + + ISAC_WRITE(I_CMDR, cmd); + ISACCMDRWRDELAY(); + + splx(s); + + return(1); +} + +/*---------------------------------------------------------------------------* + * + * L2 -> L1: PH-ACTIVATE-REQUEST + * ============================= + * + * parms: + * unit physical interface unit number + * + * returns: + * ==0 + * !=0 + * + *---------------------------------------------------------------------------*/ +int +ifpi_ph_activate_req(int unit) +{ + struct l1_softc *sc = ifpi_scp[unit]; + NDBGL1(L1_PRIM, "PH-ACTIVATE-REQ, unit %d", unit); + ifpi_next_state(sc, EV_PHAR); + return(0); +} + +/*---------------------------------------------------------------------------* + * command from the upper layers + *---------------------------------------------------------------------------*/ +int +ifpi_mph_command_req(int unit, int command, void *parm) +{ + struct l1_softc *sc = ifpi_scp[unit]; + + switch(command) + { + case CMR_DOPEN: /* daemon running */ + NDBGL1(L1_PRIM, "unit %d, command = CMR_DOPEN", unit); + sc->sc_enabled = 1; + break; + + case CMR_DCLOSE: /* daemon not running */ + NDBGL1(L1_PRIM, "unit %d, command = CMR_DCLOSE", unit); + sc->sc_enabled = 0; + break; + + case CMR_SETTRACE: + NDBGL1(L1_PRIM, "unit %d, command = CMR_SETTRACE, parm = %d", unit, (unsigned int)parm); + sc->sc_trace = (unsigned int)parm; + break; + + default: + NDBGL1(L1_ERROR, "ERROR, unknown command = %d, unit = %d, parm = %d", command, unit, (unsigned int)parm); + break; + } + + return(0); +} + +#endif /* NIFPI > 0 */ diff --git a/sys/i4b/layer1/ifpi/i4b_ifpi_l1fsm.c b/sys/i4b/layer1/ifpi/i4b_ifpi_l1fsm.c new file mode 100644 index 0000000..2605387 --- /dev/null +++ b/sys/i4b/layer1/ifpi/i4b_ifpi_l1fsm.c @@ -0,0 +1,522 @@ +/* + * Copyright (c) 1997, 2000 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_ifpi_l1fsm.c - AVM Fritz PCI layer 1 I.430 state machine + * ------------------------------------------------------------ + * + * $Id: i4b_ifpi_l1fsm.c,v 1.4 2000/05/29 15:41:41 hm Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Mon May 29 15:23:15 2000] + * + *---------------------------------------------------------------------------*/ + +#include "ifpi.h" +#include "pci.h" + +#if (NIFPI > 0) && (NPCI > 0) + +#include <sys/param.h> +#include <sys/kernel.h> +#include <sys/systm.h> +#include <sys/mbuf.h> +#include <sys/socket.h> + +#include <machine/stdarg.h> +#include <machine/clock.h> + +#include <net/if.h> + +#include <machine/i4b_debug.h> +#include <machine/i4b_ioctl.h> +#include <machine/i4b_trace.h> + +#include <i4b/layer1/isic/i4b_isic.h> +#include <i4b/layer1/isic/i4b_isac.h> +#include <i4b/layer1/isic/i4b_hscx.h> + +#include <i4b/layer1/i4b_l1.h> + +#include <i4b/include/i4b_global.h> + +#include <i4b/include/i4b_mbuf.h> + +#include <i4b/layer1/ifpi/i4b_ifpi_ext.h> + +#if DO_I4B_DEBUG +static char *state_text[N_STATES] = { + "F3 Deactivated", + "F4 Awaiting Signal", + "F5 Identifying Input", + "F6 Synchronized", + "F7 Activated", + "F8 Lost Framing", + "Illegal State" +}; + +static char *event_text[N_EVENTS] = { + "EV_PHAR PH_ACT_REQ", + "EV_T3 Timer 3 expired", + "EV_INFO0 INFO0 received", + "EV_RSY Level Detected", + "EV_INFO2 INFO2 received", + "EV_INFO48 INFO4 received", + "EV_INFO410 INFO4 received", + "EV_DR Deactivate Req", + "EV_PU Power UP", + "EV_DIS Disconnected", + "EV_EI Error Ind", + "Illegal Event" +}; +#endif + +/* Function prototypes */ + +static void timer3_expired (struct l1_softc *sc); +static void T3_start (struct l1_softc *sc); +static void T3_stop (struct l1_softc *sc); +static void F_T3ex (struct l1_softc *sc); +static void timer4_expired (struct l1_softc *sc); +static void T4_start (struct l1_softc *sc); +static void T4_stop (struct l1_softc *sc); +static void F_AI8 (struct l1_softc *sc); +static void F_AI10 (struct l1_softc *sc); +static void F_I01 (struct l1_softc *sc); +static void F_I02 (struct l1_softc *sc); +static void F_I03 (struct l1_softc *sc); +static void F_I2 (struct l1_softc *sc); +static void F_ill (struct l1_softc *sc); +static void F_NULL (struct l1_softc *sc); + +/*---------------------------------------------------------------------------* + * I.430 Timer T3 expire function + *---------------------------------------------------------------------------*/ +static void +timer3_expired(struct l1_softc *sc) +{ + if(sc->sc_I430T3) + { + NDBGL1(L1_T_ERR, "state = %s", ifpi_printstate(sc)); + sc->sc_I430T3 = 0; + + /* XXX try some recovery here XXX */ + + ifpi_recover(sc); + + sc->sc_init_tries++; /* increment retry count */ + +/*XXX*/ if(sc->sc_init_tries > 4) + { + int s = SPLI4B(); + + sc->sc_init_tries = 0; + + if(sc->sc_obuf2 != NULL) + { + i4b_Dfreembuf(sc->sc_obuf2); + sc->sc_obuf2 = NULL; + } + if(sc->sc_obuf != NULL) + { + i4b_Dfreembuf(sc->sc_obuf); + sc->sc_obuf = NULL; + sc->sc_freeflag = 0; + sc->sc_op = NULL; + sc->sc_ol = 0; + } + + splx(s); + + i4b_l1_mph_status_ind(L0IFPIUNIT(sc->sc_unit), STI_NOL1ACC, 0, NULL); + } + + ifpi_next_state(sc, EV_T3); + } + else + { + NDBGL1(L1_T_ERR, "expired without starting it ...."); + } +} + +/*---------------------------------------------------------------------------* + * I.430 Timer T3 start + *---------------------------------------------------------------------------*/ +static void +T3_start(struct l1_softc *sc) +{ + NDBGL1(L1_T_MSG, "state = %s", ifpi_printstate(sc)); + sc->sc_I430T3 = 1; + sc->sc_T3_callout = timeout((TIMEOUT_FUNC_T)timer3_expired,(struct l1_softc *)sc, 2*hz); +} + +/*---------------------------------------------------------------------------* + * I.430 Timer T3 stop + *---------------------------------------------------------------------------*/ +static void +T3_stop(struct l1_softc *sc) +{ + NDBGL1(L1_T_MSG, "state = %s", ifpi_printstate(sc)); + + sc->sc_init_tries = 0; /* init connect retry count */ + + if(sc->sc_I430T3) + { + sc->sc_I430T3 = 0; + untimeout((TIMEOUT_FUNC_T)timer3_expired,(struct l1_softc *)sc, sc->sc_T3_callout); + } +} + +/*---------------------------------------------------------------------------* + * I.430 Timer T3 expiry + *---------------------------------------------------------------------------*/ +static void +F_T3ex(struct l1_softc *sc) +{ + NDBGL1(L1_F_MSG, "FSM function F_T3ex executing"); + if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S) + i4b_l1_ph_deactivate_ind(L0IFPIUNIT(sc->sc_unit)); +} + +/*---------------------------------------------------------------------------* + * Timer T4 expire function + *---------------------------------------------------------------------------*/ +static void +timer4_expired(struct l1_softc *sc) +{ + if(sc->sc_I430T4) + { + NDBGL1(L1_T_MSG, "state = %s", ifpi_printstate(sc)); + sc->sc_I430T4 = 0; + i4b_l1_mph_status_ind(L0IFPIUNIT(sc->sc_unit), STI_PDEACT, 0, NULL); + } + else + { + NDBGL1(L1_T_ERR, "expired without starting it ...."); + } +} + +/*---------------------------------------------------------------------------* + * Timer T4 start + *---------------------------------------------------------------------------*/ +static void +T4_start(struct l1_softc *sc) +{ + NDBGL1(L1_T_MSG, "state = %s", ifpi_printstate(sc)); + sc->sc_I430T4 = 1; + sc->sc_T4_callout = timeout((TIMEOUT_FUNC_T)timer4_expired,(struct l1_softc *)sc, hz); +} + +/*---------------------------------------------------------------------------* + * Timer T4 stop + *---------------------------------------------------------------------------*/ +static void +T4_stop(struct l1_softc *sc) +{ + NDBGL1(L1_T_MSG, "state = %s", ifpi_printstate(sc)); + + if(sc->sc_I430T4) + { + sc->sc_I430T4 = 0; + untimeout((TIMEOUT_FUNC_T)timer4_expired,(struct l1_softc *)sc, sc->sc_T4_callout); + } +} + +/*---------------------------------------------------------------------------* + * FSM function: received AI8 + *---------------------------------------------------------------------------*/ +static void +F_AI8(struct l1_softc *sc) +{ + T4_stop(sc); + + NDBGL1(L1_F_MSG, "FSM function F_AI8 executing"); + + if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S) + i4b_l1_ph_activate_ind(L0IFPIUNIT(sc->sc_unit)); + + T3_stop(sc); + + if(sc->sc_trace & TRACE_I) + { + i4b_trace_hdr_t hdr; + char info = INFO4_8; + + hdr.unit = L0IFPIUNIT(sc->sc_unit); + hdr.type = TRC_CH_I; + hdr.dir = FROM_NT; + hdr.count = 0; + MICROTIME(hdr.time); + i4b_l1_trace_ind(&hdr, 1, &info); + } +} + +/*---------------------------------------------------------------------------* + * FSM function: received AI10 + *---------------------------------------------------------------------------*/ +static void +F_AI10(struct l1_softc *sc) +{ + T4_stop(sc); + + NDBGL1(L1_F_MSG, "FSM function F_AI10 executing"); + + if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S) + i4b_l1_ph_activate_ind(L0IFPIUNIT(sc->sc_unit)); + + T3_stop(sc); + + if(sc->sc_trace & TRACE_I) + { + i4b_trace_hdr_t hdr; + char info = INFO4_10; + + hdr.unit = L0IFPIUNIT(sc->sc_unit); + hdr.type = TRC_CH_I; + hdr.dir = FROM_NT; + hdr.count = 0; + MICROTIME(hdr.time); + i4b_l1_trace_ind(&hdr, 1, &info); + } +} + +/*---------------------------------------------------------------------------* + * FSM function: received INFO 0 in states F3 .. F5 + *---------------------------------------------------------------------------*/ +static void +F_I01(struct l1_softc *sc) +{ + NDBGL1(L1_F_MSG, "FSM function F_I01 executing"); + + if(sc->sc_trace & TRACE_I) + { + i4b_trace_hdr_t hdr; + char info = INFO0; + + hdr.unit = L0IFPIUNIT(sc->sc_unit); + hdr.type = TRC_CH_I; + hdr.dir = FROM_NT; + hdr.count = 0; + MICROTIME(hdr.time); + i4b_l1_trace_ind(&hdr, 1, &info); + } +} + +/*---------------------------------------------------------------------------* + * FSM function: received INFO 0 in state F6 + *---------------------------------------------------------------------------*/ +static void +F_I02(struct l1_softc *sc) +{ + NDBGL1(L1_F_MSG, "FSM function F_I02 executing"); + + if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S) + i4b_l1_ph_deactivate_ind(L0IFPIUNIT(sc->sc_unit)); + + if(sc->sc_trace & TRACE_I) + { + i4b_trace_hdr_t hdr; + char info = INFO0; + + hdr.unit = L0IFPIUNIT(sc->sc_unit); + hdr.type = TRC_CH_I; + hdr.dir = FROM_NT; + hdr.count = 0; + MICROTIME(hdr.time); + i4b_l1_trace_ind(&hdr, 1, &info); + } +} + +/*---------------------------------------------------------------------------* + * FSM function: received INFO 0 in state F7 or F8 + *---------------------------------------------------------------------------*/ +static void +F_I03(struct l1_softc *sc) +{ + NDBGL1(L1_F_MSG, "FSM function F_I03 executing"); + + if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S) + i4b_l1_ph_deactivate_ind(L0IFPIUNIT(sc->sc_unit)); + + T4_start(sc); + + if(sc->sc_trace & TRACE_I) + { + i4b_trace_hdr_t hdr; + char info = INFO0; + + hdr.unit = L0IFPIUNIT(sc->sc_unit); + hdr.type = TRC_CH_I; + hdr.dir = FROM_NT; + hdr.count = 0; + MICROTIME(hdr.time); + i4b_l1_trace_ind(&hdr, 1, &info); + } +} + +/*---------------------------------------------------------------------------* + * FSM function: activate request + *---------------------------------------------------------------------------*/ +static void +F_AR(struct l1_softc *sc) +{ + NDBGL1(L1_F_MSG, "FSM function F_AR executing"); + + if(sc->sc_trace & TRACE_I) + { + i4b_trace_hdr_t hdr; + char info = INFO1_8; + + hdr.unit = L0IFPIUNIT(sc->sc_unit); + hdr.type = TRC_CH_I; + hdr.dir = FROM_TE; + hdr.count = 0; + MICROTIME(hdr.time); + i4b_l1_trace_ind(&hdr, 1, &info); + } + + ifpi_isac_l1_cmd(sc, CMD_AR8); + + T3_start(sc); +} + +/*---------------------------------------------------------------------------* + * FSM function: received INFO2 + *---------------------------------------------------------------------------*/ +static void +F_I2(struct l1_softc *sc) +{ + NDBGL1(L1_F_MSG, "FSM function F_I2 executing"); + + if(sc->sc_trace & TRACE_I) + { + i4b_trace_hdr_t hdr; + char info = INFO2; + + hdr.unit = L0IFPIUNIT(sc->sc_unit); + hdr.type = TRC_CH_I; + hdr.dir = FROM_NT; + hdr.count = 0; + MICROTIME(hdr.time); + i4b_l1_trace_ind(&hdr, 1, &info); + } + +} + +/*---------------------------------------------------------------------------* + * illegal state default action + *---------------------------------------------------------------------------*/ +static void +F_ill(struct l1_softc *sc) +{ + NDBGL1(L1_F_ERR, "FSM function F_ill executing"); +} + +/*---------------------------------------------------------------------------* + * No action + *---------------------------------------------------------------------------*/ +static void +F_NULL(struct l1_softc *sc) +{ + NDBGL1(L1_F_MSG, "FSM function F_NULL executing"); +} + + +/*---------------------------------------------------------------------------* + * layer 1 state transition table + *---------------------------------------------------------------------------*/ +struct ifpi_state_tab { + void (*func) (struct l1_softc *sc); /* function to execute */ + int newstate; /* next state */ +} ifpi_state_tab[N_EVENTS][N_STATES] = { + +/* STATE: F3 F4 F5 F6 F7 F8 ILLEGAL STATE */ +/* -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* EV_PHAR x*/ {{F_AR, ST_F4}, {F_NULL, ST_F4}, {F_NULL, ST_F5}, {F_NULL, ST_F6}, {F_ill, ST_ILL}, {F_NULL, ST_F8}, {F_ill, ST_ILL}}, +/* EV_T3 x*/ {{F_NULL, ST_F3}, {F_T3ex, ST_F3}, {F_T3ex, ST_F3}, {F_T3ex, ST_F3}, {F_NULL, ST_F7}, {F_NULL, ST_F8}, {F_ill, ST_ILL}}, +/* EV_INFO0 */ {{F_I01, ST_F3}, {F_I01, ST_F4}, {F_I01, ST_F5}, {F_I02, ST_F3}, {F_I03, ST_F3}, {F_I03, ST_F3}, {F_ill, ST_ILL}}, +/* EV_RSY x*/ {{F_NULL, ST_F3}, {F_NULL, ST_F5}, {F_NULL, ST_F5}, {F_NULL, ST_F8}, {F_NULL, ST_F8}, {F_NULL, ST_F8}, {F_ill, ST_ILL}}, +/* EV_INFO2 */ {{F_I2, ST_F6}, {F_I2, ST_F6}, {F_I2, ST_F6}, {F_I2, ST_F6}, {F_I2, ST_F6}, {F_I2, ST_F6}, {F_ill, ST_ILL}}, +/* EV_INFO48*/ {{F_AI8, ST_F7}, {F_AI8, ST_F7}, {F_AI8, ST_F7}, {F_AI8, ST_F7}, {F_NULL, ST_F7}, {F_AI8, ST_F7}, {F_ill, ST_ILL}}, +/* EV_INFO41*/ {{F_AI10, ST_F7}, {F_AI10, ST_F7}, {F_AI10, ST_F7}, {F_AI10, ST_F7}, {F_NULL, ST_F7}, {F_AI10, ST_F7}, {F_ill, ST_ILL}}, +/* EV_DR */ {{F_NULL, ST_F3}, {F_NULL, ST_F4}, {F_NULL, ST_F5}, {F_NULL, ST_F6}, {F_NULL, ST_F7}, {F_NULL, ST_F8}, {F_ill, ST_ILL}}, +/* EV_PU */ {{F_NULL, ST_F3}, {F_NULL, ST_F4}, {F_NULL, ST_F5}, {F_NULL, ST_F6}, {F_NULL, ST_F7}, {F_NULL, ST_F8}, {F_ill, ST_ILL}}, +/* EV_DIS */ {{F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}}, +/* EV_EI */ {{F_NULL, ST_F3}, {F_NULL, ST_F3}, {F_NULL, ST_F3}, {F_NULL, ST_F3}, {F_NULL, ST_F3}, {F_NULL, ST_F3}, {F_ill, ST_ILL}}, +/* EV_ILL */ {{F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}} +}; + +/*---------------------------------------------------------------------------* + * event handler + *---------------------------------------------------------------------------*/ +void +ifpi_next_state(struct l1_softc *sc, int event) +{ + int currstate, newstate; + + if(event >= N_EVENTS) + panic("i4b_l1fsm.c: event >= N_EVENTS\n"); + + currstate = sc->sc_I430state; + + if(currstate >= N_STATES) + panic("i4b_l1fsm.c: currstate >= N_STATES\n"); + + newstate = ifpi_state_tab[event][currstate].newstate; + + if(newstate >= N_STATES) + panic("i4b_l1fsm.c: newstate >= N_STATES\n"); + + NDBGL1(L1_F_MSG, "FSM event [%s]: [%s => %s]", event_text[event], + state_text[currstate], + state_text[newstate]); + + (*ifpi_state_tab[event][currstate].func)(sc); + + if(newstate == ST_ILL) + { + newstate = ST_F3; + NDBGL1(L1_F_ERR, "FSM Illegal State ERROR, oldstate = %s, newstate = %s, event = %s!", + state_text[currstate], + state_text[newstate], + event_text[event]); + } + + sc->sc_I430state = newstate; +} + +#if DO_I4B_DEBUG +/*---------------------------------------------------------------------------* + * return pointer to current state description + *---------------------------------------------------------------------------*/ +char * +ifpi_printstate(struct l1_softc *sc) +{ + return((char *) state_text[sc->sc_I430state]); +} +#endif + +#endif /* NIFPI > 0 */ diff --git a/sys/i4b/layer1/i4b_avm_fritz_pci.c b/sys/i4b/layer1/ifpi/i4b_ifpi_pci.c index dc86c92..b1502c7 100644 --- a/sys/i4b/layer1/i4b_avm_fritz_pci.c +++ b/sys/i4b/layer1/ifpi/i4b_ifpi_pci.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Gary Jennejohn. All rights reserved. + * Copyright (c) 1999, 2000 Gary Jennejohn. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -29,26 +29,23 @@ * SUCH DAMAGE. * *--------------------------------------------------------------------------- - * a lot of code was borrowed from i4b_bchan.c and i4b_hscx.c - *--------------------------------------------------------------------------- - * - * Fritz!Card PCI specific routines for isic driver - * ------------------------------------------------ * - * New-bus'ified by Gary Jennejohn - 15 Nov 99. + * i4b_ifpi_pci.c: AVM Fritz!Card PCI hardware driver + * -------------------------------------------------- * - * $Id: i4b_avm_fritz_pci.c,v 1.3 1999/12/13 21:25:26 hm Exp $ + * $Id: i4b_ifpi_pci.c,v 1.4 2000/06/02 11:58:56 hm Exp $ * * $FreeBSD$ * - * last edit-date: [Mon Dec 13 21:59:04 1999] + * last edit-date: [Fri Jun 2 13:58:02 2000] * *---------------------------------------------------------------------------*/ -#include "isic.h" +#include "ifpi.h" #include "opt_i4b.h" +#include "pci.h" -#if NISIC > 0 && defined(AVM_A1_PCI) +#if (NIFPI > 0) && (NPCI > 0) #include <sys/param.h> #include <sys/kernel.h> @@ -70,14 +67,17 @@ #include <machine/i4b_debug.h> #include <machine/i4b_ioctl.h> +#include <machine/i4b_trace.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> +#include <i4b/layer1/isic/i4b_isic.h> +#include <i4b/layer1/isic/i4b_isac.h> +#include <i4b/layer1/isic/i4b_hscx.h> + +#include <i4b/layer1/ifpi/i4b_ifpi_ext.h> #define PCI_AVMA1_VID 0x1244 #define PCI_AVMA1_DID 0x0a00 @@ -101,12 +101,14 @@ static void avma1pp_bchannel_stat(int, int, bchan_statistics_t *); static void avma1pp_set_linktab(int, int, drvr_link_t *); static isdn_link_t * avma1pp_ret_linktab(int, int); static int avma1pp_pci_probe(device_t); -int isic_attach_avma1pp(device_t); +static int avma1pp_hscx_fifo(l1_bchan_state_t *, struct l1_softc *); +int avma1pp_attach_avma1pp(device_t); +static void ifpi_isac_intr(struct l1_softc *sc); static device_method_t avma1pp_pci_methods[] = { /* Device interface */ DEVMETHOD(device_probe, avma1pp_pci_probe), - DEVMETHOD(device_attach, isic_attach_avma1pp), + DEVMETHOD(device_attach, avma1pp_attach_avma1pp), DEVMETHOD(device_shutdown, avma1pp_disable), /* bus interface */ @@ -116,6 +118,7 @@ static device_method_t avma1pp_pci_methods[] = { { 0, 0 } }; +#if 0 /* use what's in l1_softc */ /* a minimal softc for the Fritz!Card PCI */ struct avma1pp_softc { @@ -124,21 +127,33 @@ struct avma1pp_softc void *avma1pp_intrhand; struct resource *avma1pp_irq; struct resource *avma1pp_res; - u_int8_t avma1pp_unit; /* interface number */ - /* pointer to l1_sc */ + /* pointer to ifpi_sc */ struct l1_softc *avma1pp_isc; }; +#endif static driver_t avma1pp_pci_driver = { - "isic", + "ifpi", avma1pp_pci_methods, - sizeof(struct avma1pp_softc) + sizeof(struct l1_softc) }; static devclass_t avma1pp_pci_devclass; DRIVER_MODULE(avma1pp, pci, avma1pp_pci_driver, avma1pp_pci_devclass, 0, 0); +/* jump table for multiplex routines */ + +struct i4b_l1mux_func avma1pp_l1mux_func = { + avma1pp_ret_linktab, + avma1pp_set_linktab, + ifpi_mph_command_req, + ifpi_ph_data_req, + ifpi_ph_activate_req, +}; + +struct l1_softc *ifpi_scp[IFPI_MAXUNIT]; + /*---------------------------------------------------------------------------* * AVM PCI Fritz!Card special registers *---------------------------------------------------------------------------*/ @@ -265,12 +280,13 @@ DRIVER_MODULE(avma1pp, pci, avma1pp_pci_driver, avma1pp_pci_devclass, 0, 0); static void avma1pp_read_fifo(struct l1_softc *sc, int what, void *buf, size_t size) { - struct avma1pp_softc *asc = (struct avma1pp_softc *)sc->sc_ipacbase; + bus_space_handle_t bhandle = rman_get_bushandle(sc->sc_resources.io_base[0]); + bus_space_tag_t btag = rman_get_bustag(sc->sc_resources.io_base[0]); switch (what) { case ISIC_WHAT_ISAC: - bus_space_write_1(asc->avma1pp_btag, asc->avma1pp_bhandle, ADDR_REG_OFFSET, ISAC_FIFO); - bus_space_read_multi_1(asc->avma1pp_btag, asc->avma1pp_bhandle, ISAC_REG_OFFSET, buf, size); + bus_space_write_1(btag, bhandle, ADDR_REG_OFFSET, ISAC_FIFO); + bus_space_read_multi_1(btag, bhandle, ISAC_REG_OFFSET, buf, size); break; case ISIC_WHAT_HSCXA: hscx_read_fifo(0, buf, size, sc); @@ -286,17 +302,17 @@ hscx_read_fifo(int chan, void *buf, size_t len, struct l1_softc *sc) { u_int32_t *ip; size_t cnt; - struct avma1pp_softc *asc = (struct avma1pp_softc *)sc->sc_ipacbase; - + bus_space_handle_t bhandle = rman_get_bushandle(sc->sc_resources.io_base[0]); + bus_space_tag_t btag = rman_get_bustag(sc->sc_resources.io_base[0]); - bus_space_write_4(asc->avma1pp_btag, asc->avma1pp_bhandle, ADDR_REG_OFFSET, chan); + bus_space_write_4(btag, bhandle, 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(asc->avma1pp_btag, asc->avma1pp_bhandle, ISAC_REG_OFFSET); + *ip++ = bus_space_read_4(btag, bhandle, ISAC_REG_OFFSET); cnt += 4; } } @@ -307,12 +323,13 @@ hscx_read_fifo(int chan, void *buf, size_t len, struct l1_softc *sc) static void avma1pp_write_fifo(struct l1_softc *sc, int what, void *buf, size_t size) { - struct avma1pp_softc *asc = (struct avma1pp_softc *)sc->sc_ipacbase; + bus_space_handle_t bhandle = rman_get_bushandle(sc->sc_resources.io_base[0]); + bus_space_tag_t btag = rman_get_bustag(sc->sc_resources.io_base[0]); switch (what) { case ISIC_WHAT_ISAC: - bus_space_write_1(asc->avma1pp_btag, asc->avma1pp_bhandle, ADDR_REG_OFFSET, ISAC_FIFO); - bus_space_write_multi_1(asc->avma1pp_btag, asc->avma1pp_bhandle, ISAC_REG_OFFSET, (u_int8_t*)buf, size); + bus_space_write_1(btag, bhandle, ADDR_REG_OFFSET, ISAC_FIFO); + bus_space_write_multi_1(btag, bhandle, ISAC_REG_OFFSET, (u_int8_t*)buf, size); break; case ISIC_WHAT_HSCXA: hscx_write_fifo(0, buf, size, sc); @@ -329,7 +346,8 @@ hscx_write_fifo(int chan, void *buf, size_t len, struct l1_softc *sc) u_int32_t *ip; size_t cnt; l1_bchan_state_t *Bchan = &sc->sc_chan[chan]; - struct avma1pp_softc *asc = (struct avma1pp_softc *)sc->sc_ipacbase; + bus_space_handle_t bhandle = rman_get_bushandle(sc->sc_resources.io_base[0]); + bus_space_tag_t btag = rman_get_bustag(sc->sc_resources.io_base[0]); sc->avma1pp_cmd &= ~HSCX_CMD_XME; @@ -350,7 +368,7 @@ hscx_write_fifo(int chan, void *buf, size_t len, struct l1_softc *sc) cnt = 0; while (cnt < len) { - bus_space_write_4(asc->avma1pp_btag, asc->avma1pp_bhandle, ISAC_REG_OFFSET, *ip); + bus_space_write_4(btag, bhandle, ISAC_REG_OFFSET, *ip); ip++; cnt += 4; } @@ -364,7 +382,8 @@ static void avma1pp_write_reg(struct l1_softc *sc, int what, bus_size_t offs, u_int8_t data) { u_char reg_bank; - struct avma1pp_softc *asc = (struct avma1pp_softc *)sc->sc_ipacbase; + bus_space_handle_t bhandle = rman_get_bushandle(sc->sc_resources.io_base[0]); + bus_space_tag_t btag = rman_get_bustag(sc->sc_resources.io_base[0]); switch (what) { case ISIC_WHAT_ISAC: @@ -373,8 +392,8 @@ avma1pp_write_reg(struct l1_softc *sc, int what, bus_size_t offs, u_int8_t data) printf("write_reg bank %d off %ld.. ", (int)reg_bank, (long)offs); #endif /* set the register bank */ - bus_space_write_1(asc->avma1pp_btag, asc->avma1pp_bhandle, ADDR_REG_OFFSET, reg_bank); - bus_space_write_1(asc->avma1pp_btag, asc->avma1pp_bhandle, ISAC_REG_OFFSET + (offs & ISAC_REGSET_MASK), data); + bus_space_write_1(btag, bhandle, ADDR_REG_OFFSET, reg_bank); + bus_space_write_1(btag, bhandle, ISAC_REG_OFFSET + (offs & ISAC_REGSET_MASK), data); break; case ISIC_WHAT_HSCXA: hscx_write_reg(0, offs, data, sc); @@ -388,14 +407,12 @@ avma1pp_write_reg(struct l1_softc *sc, int what, bus_size_t offs, u_int8_t data) static void hscx_write_reg(int chan, u_int off, u_int val, struct l1_softc *sc) { - struct avma1pp_softc *asc = (struct avma1pp_softc *)sc->sc_ipacbase; + bus_space_handle_t bhandle = rman_get_bushandle(sc->sc_resources.io_base[0]); + bus_space_tag_t btag = rman_get_bustag(sc->sc_resources.io_base[0]); - /* HACK */ - if (off == H_MASK) - return; /* point at the correct channel */ - bus_space_write_4(asc->avma1pp_btag, asc->avma1pp_bhandle, ADDR_REG_OFFSET, chan); - bus_space_write_4(asc->avma1pp_btag, asc->avma1pp_bhandle, ISAC_REG_OFFSET + off, val); + bus_space_write_4(btag, bhandle, ADDR_REG_OFFSET, chan); + bus_space_write_4(btag, bhandle, ISAC_REG_OFFSET + off, val); } /*---------------------------------------------------------------------------* @@ -405,7 +422,8 @@ static u_int8_t avma1pp_read_reg(struct l1_softc *sc, int what, bus_size_t offs) { u_char reg_bank; - struct avma1pp_softc *asc = (struct avma1pp_softc *)sc->sc_ipacbase; + bus_space_handle_t bhandle = rman_get_bushandle(sc->sc_resources.io_base[0]); + bus_space_tag_t btag = rman_get_bustag(sc->sc_resources.io_base[0]); switch (what) { case ISIC_WHAT_ISAC: @@ -414,8 +432,8 @@ avma1pp_read_reg(struct l1_softc *sc, int what, bus_size_t offs) printf("read_reg bank %d off %ld.. ", (int)reg_bank, (long)offs); #endif /* set the register bank */ - bus_space_write_1(asc->avma1pp_btag, asc->avma1pp_bhandle, ADDR_REG_OFFSET, reg_bank); - return(bus_space_read_1(asc->avma1pp_btag, asc->avma1pp_bhandle, ISAC_REG_OFFSET + + bus_space_write_1(btag, bhandle, ADDR_REG_OFFSET, reg_bank); + return(bus_space_read_1(btag, bhandle, ISAC_REG_OFFSET + (offs & ISAC_REGSET_MASK))); case ISIC_WHAT_HSCXA: return hscx_read_reg(0, offs, sc); @@ -438,14 +456,12 @@ hscx_read_reg(int chan, u_int off, struct l1_softc *sc) static u_int hscx_read_reg_int(int chan, u_int off, struct l1_softc *sc) { - struct avma1pp_softc *asc = (struct avma1pp_softc *)sc->sc_ipacbase; + bus_space_handle_t bhandle = rman_get_bushandle(sc->sc_resources.io_base[0]); + bus_space_tag_t btag = rman_get_bustag(sc->sc_resources.io_base[0]); - /* HACK */ - if (off == H_ISTA) - return(0); /* point at the correct channel */ - bus_space_write_4(asc->avma1pp_btag, asc->avma1pp_bhandle, ADDR_REG_OFFSET, chan); - return(bus_space_read_4(asc->avma1pp_btag, asc->avma1pp_bhandle, ISAC_REG_OFFSET + off)); + bus_space_write_4(btag, bhandle, ADDR_REG_OFFSET, chan); + return(bus_space_read_4(btag, bhandle, ISAC_REG_OFFSET + off)); } /*---------------------------------------------------------------------------* @@ -469,29 +485,31 @@ avma1pp_pci_probe(dev) } /*---------------------------------------------------------------------------* - * isic_attach_avma1pp - attach Fritz!Card PCI + * avma1pp_attach_avma1pp - attach Fritz!Card PCI *---------------------------------------------------------------------------*/ int -isic_attach_avma1pp(device_t dev) +avma1pp_attach_avma1pp(device_t dev) { struct l1_softc *sc; u_int v; - /* start of new-bus stuff */ - struct avma1pp_softc *asc; - int unit, error = 0, rid; + int unit, error = 0; int s; u_int16_t did, vid; + void *ih = 0; + bus_space_handle_t bhandle; + bus_space_tag_t btag; s = splimp(); vid = pci_get_vendor(dev); did = pci_get_device(dev); - asc = device_get_softc(dev); + sc = device_get_softc(dev); unit = device_get_unit(dev); - bzero(asc, sizeof(struct avma1pp_softc)); + bzero(sc, sizeof(struct l1_softc)); - if(unit > ISIC_MAXUNIT) { - printf("avma1pp%d: Error, unit > ISIC_MAXUNIT!\n", unit); + /* probably not really required */ + if(unit > IFPI_MAXUNIT) { + printf("avma1pp%d: Error, unit > IFPI_MAXUNIT!\n", unit); splx(s); return(ENXIO); } @@ -501,54 +519,49 @@ isic_attach_avma1pp(device_t dev) goto fail; } - asc->avma1pp_unit = unit; + ifpi_scp[unit] = sc; - rid = PCIR_MAPS+4; - asc->avma1pp_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, + sc->sc_resources.io_rid[0] = PCIR_MAPS+4; + sc->sc_resources.io_base[0] = bus_alloc_resource(dev, SYS_RES_IOPORT, + &sc->sc_resources.io_rid[0], 0, ~0, 1, RF_ACTIVE); - if (asc->avma1pp_res == NULL) { + if (sc->sc_resources.io_base[0] == NULL) { printf("avma1pp%d: couldn't map IO port\n", unit); error = ENXIO; goto fail; } - asc->avma1pp_btag = rman_get_bustag(asc->avma1pp_res); - asc->avma1pp_bhandle = rman_get_bushandle(asc->avma1pp_res); + bhandle = rman_get_bushandle(sc->sc_resources.io_base[0]); + btag = rman_get_bustag(sc->sc_resources.io_base[0]); /* Allocate interrupt */ - rid = 0; - asc->avma1pp_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, - RF_SHAREABLE | RF_ACTIVE); + sc->sc_resources.irq_rid = 0; + sc->sc_resources.irq = bus_alloc_resource(dev, SYS_RES_IRQ, + &sc->sc_resources.irq_rid, 0, ~0, 1, RF_SHAREABLE | RF_ACTIVE); - if (asc->avma1pp_irq == NULL) { - bus_release_resource(dev, SYS_RES_IOPORT, PCIR_MAPS+4, asc->avma1pp_res); + if (sc->sc_resources.irq == NULL) { + bus_release_resource(dev, SYS_RES_IOPORT, PCIR_MAPS+4, sc->sc_resources.io_base[0]); printf("avma1pp%d: couldn't map interrupt\n", unit); error = ENXIO; goto fail; } - error = bus_setup_intr(dev, asc->avma1pp_irq, INTR_TYPE_NET, avma1pp_intr, asc, &asc->avma1pp_intrhand); + error = bus_setup_intr(dev, sc->sc_resources.irq, INTR_TYPE_NET, avma1pp_intr, sc, &ih); if (error) { - bus_release_resource(dev, SYS_RES_IRQ, 0, asc->avma1pp_res); - bus_release_resource(dev, SYS_RES_IOPORT, PCIR_MAPS+4, asc->avma1pp_res); + bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_resources.irq); + bus_release_resource(dev, SYS_RES_IOPORT, PCIR_MAPS+4, sc->sc_resources.io_base[0]); printf("avma1pp%d: couldn't set up irq\n", unit); goto fail; } - sc = asc->avma1pp_isc = &l1_sc[unit]; sc->sc_unit = unit; - /* mis-use sc_ipacbase to point at avma1pp_softc */ - IPAC_BASE = (caddr_t)asc; /* end of new-bus stuff */ - /* 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)ISIC_WHAT_ISAC; - /* this thing doesn't have an HSCX, so fake the base addresses */ HSCX_A_BASE = (caddr_t)ISIC_WHAT_HSCXA; HSCX_B_BASE = (caddr_t)ISIC_WHAT_HSCXB; @@ -614,28 +627,28 @@ isic_attach_avma1pp(device_t dev) printf("avma1pp_attach: 1 HSCX_STAT %x\n", v); #endif - bus_space_write_1(asc->avma1pp_btag, asc->avma1pp_bhandle, STAT0_OFFSET, ASL_RESET_ALL|ASL_TIMERDISABLE); + bus_space_write_1(btag, bhandle, STAT0_OFFSET, ASL_RESET_ALL|ASL_TIMERDISABLE); DELAY(SEC_DELAY/100); /* 10 ms */ - bus_space_write_1(asc->avma1pp_btag, asc->avma1pp_bhandle, STAT0_OFFSET, ASL_TIMERRESET|ASL_ENABLE_INT|ASL_TIMERDISABLE); + bus_space_write_1(btag, bhandle, STAT0_OFFSET, ASL_TIMERRESET|ASL_ENABLE_INT|ASL_TIMERDISABLE); DELAY(SEC_DELAY/100); /* 10 ms */ #ifdef AVMA1PCI_DEBUG - bus_space_write_1(asc->avma1pp_btag, asc->avma1pp_bhandle, STAT1_OFFSET, ASL1_ENABLE_IOM|sc->sc_irq); + bus_space_write_1(btag, bhandle, STAT1_OFFSET, ASL1_ENABLE_IOM|sc->sc_irq); DELAY(SEC_DELAY/100); /* 10 ms */ - v = bus_space_read_1(asc->avma1pp_btag, asc->avma1pp_bhandle, STAT1_OFFSET); + v = bus_space_read_1(btag, bhandle, STAT1_OFFSET); printf("after reset: S1 %#x\n", v); - v = bus_space_read_4(asc->avma1pp_btag, asc->avma1pp_bhandle, 0); - printf("isic_attach_avma1pp: v %#x\n", v); + v = bus_space_read_4(btag, bhandle, 0); + printf("avma1pp_attach_avma1pp: v %#x\n", v); #endif /* from here to the end would normally be done in isic_pciattach */ - printf("isic%d: ISAC %s (IOM-%c)\n", unit, + printf("ifpi%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); + ifpi_isac_init(sc); /* init the "HSCX" */ avma1pp_bchannel_setup(sc->sc_unit, HSCX_CH_A, BPROT_NONE, 0); @@ -663,14 +676,6 @@ isic_attach_avma1pp(device_t dev) sc->sc_obuf2 = NULL; sc->sc_freeflag2 = 0; -#ifdef USENEWFIELDS - /* new fields */ - sc->recover = isic_recover; - sc->next_state = isic_next_state; - sc->ph_data_req = isic_isac_ph_data_req; - sc->l1_cmd = isic_isac_l1_cmd; -#endif - #if defined(__FreeBSD__) && __FreeBSD__ >=3 callout_handle_init(&sc->sc_T3_callout); callout_handle_init(&sc->sc_T4_callout); @@ -678,7 +683,7 @@ isic_attach_avma1pp(device_t dev) /* init higher protocol layers */ - MPH_Status_Ind(sc->sc_unit, STI_ATTACH, sc->sc_cardtyp); + i4b_l1_mph_status_ind(L0IFPIUNIT(sc->sc_unit), STI_ATTACH, sc->sc_cardtyp, &avma1pp_l1mux_func); fail: splx(s); @@ -695,12 +700,12 @@ avma1pp_hscx_intr(int h_chan, u_int stat, struct l1_softc *sc) int activity = -1; u_int param = 0; - DBGL1(L1_H_IRQ, "avma1pp_hscx_intr", ("%#x\n", stat)); + NDBGL1(L1_H_IRQ, "%#x", stat); if((stat & HSCX_INT_XDU) && (chan->bprot != BPROT_NONE))/* xmit data underrun */ { chan->stat_XDU++; - DBGL1(L1_H_XFRERR, "avma1pp_hscx_intr", ("xmit data underrun\n")); + NDBGL1(L1_H_XFRERR, "xmit data underrun"); /* abort the transmission */ sc->avma1pp_txl = 0; sc->avma1pp_cmd |= HSCX_CMD_XRS; @@ -741,7 +746,7 @@ avma1pp_hscx_intr(int h_chan, u_int stat, struct l1_softc *sc) if(stat & HSCX_STAT_RDO) { chan->stat_RDO++; - DBGL1(L1_H_XFRERR, "avma1pp_hscx_intr", ("receive data overflow\n")); + NDBGL1(L1_H_XFRERR, "receive data overflow"); error++; } @@ -760,7 +765,7 @@ avma1pp_hscx_intr(int h_chan, u_int stat, struct l1_softc *sc) */ if (chan->state == HSCX_IDLE) { - DBGL1(L1_H_XFRERR, "avma1pp_hscx_intr", ("toss data from %d\n", h_chan)); + NDBGL1(L1_H_XFRERR, "toss data from %d", h_chan); error++; } @@ -801,19 +806,19 @@ avma1pp_hscx_intr(int h_chan, u_int stat, struct l1_softc *sc) if(sc->sc_trace & TRACE_B_RX) { i4b_trace_hdr_t hdr; - hdr.unit = sc->sc_unit; + hdr.unit = L0IFPIUNIT(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); + i4b_l1_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); + (*chan->isic_drvr_linktab->bch_rx_data_ready)(chan->isic_drvr_linktab->unit); activity = ACT_RX; /* mark buffer ptr as unused */ @@ -825,7 +830,7 @@ avma1pp_hscx_intr(int h_chan, u_int stat, struct l1_softc *sc) else { chan->stat_CRC++; - DBGL1(L1_H_XFRERR, "avma1pp_hscx_intr", ("CRC/RAB\n")); + NDBGL1(L1_H_XFRERR, "CRC/RAB"); if (chan->in_mbuf != NULL) { i4b_Bfreembuf(chan->in_mbuf); @@ -848,15 +853,15 @@ avma1pp_hscx_intr(int h_chan, u_int stat, struct l1_softc *sc) if(sc->sc_trace & TRACE_B_RX) { i4b_trace_hdr_t hdr; - hdr.unit = sc->sc_unit; + hdr.unit = L0IFPIUNIT(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); + i4b_l1_trace_ind(&hdr, chan->in_mbuf->m_len, chan->in_mbuf->m_data); } - if(!(isic_hscx_silence(chan->in_mbuf->m_data, chan->in_mbuf->m_len))) + if(!(i4b_l1_bchan_tel_silence(chan->in_mbuf->m_data, chan->in_mbuf->m_len))) activity = ACT_RX; /* move rx'd data to rx queue */ @@ -871,7 +876,7 @@ avma1pp_hscx_intr(int h_chan, u_int stat, struct l1_softc *sc) } /* signal upper layer that data are available */ - (*chan->drvr_linktab->bch_rx_data_ready)(chan->drvr_linktab->unit); + (*chan->isic_drvr_linktab->bch_rx_data_ready)(chan->isic_drvr_linktab->unit); /* alloc new buffer */ @@ -892,7 +897,7 @@ avma1pp_hscx_intr(int h_chan, u_int stat, struct l1_softc *sc) } else { - DBGL1(L1_H_XFRERR, "avma1pp_hscx_intr", ("RAWHDLC rx buffer overflow in RPF, in_len=%d\n", chan->in_len)); + NDBGL1(L1_H_XFRERR, "RAWHDLC rx buffer overflow in RPF, in_len=%d", chan->in_len); chan->in_cbptr = chan->in_mbuf->m_data; chan->in_len = 0; } @@ -928,7 +933,7 @@ avma1pp_hscx_intr(int h_chan, u_int stat, struct l1_softc *sc) * a look at isic_bchannel_start() in i4b_bchan.c ! */ - DBGL1(L1_H_IRQ, "avma1pp_hscx_intr", ("unit %d, chan %d - XPR, Tx Fifo Empty!\n", sc->sc_unit, h_chan)); + NDBGL1(L1_H_IRQ, "unit %d, chan %d - XPR, Tx Fifo Empty!", sc->sc_unit, h_chan); if(chan->out_mbuf_cur == NULL) /* last frame is transmitted */ { @@ -937,7 +942,7 @@ avma1pp_hscx_intr(int h_chan, u_int stat, struct l1_softc *sc) if(chan->out_mbuf_head == NULL) { chan->state &= ~HSCX_TX_ACTIVE; - (*chan->drvr_linktab->bch_tx_queue_empty)(chan->drvr_linktab->unit); + (*chan->isic_drvr_linktab->bch_tx_queue_empty)(chan->isic_drvr_linktab->unit); } else { @@ -949,17 +954,17 @@ avma1pp_hscx_intr(int h_chan, u_int stat, struct l1_softc *sc) if(sc->sc_trace & TRACE_B_TX) { i4b_trace_hdr_t hdr; - hdr.unit = sc->sc_unit; + hdr.unit = L0IFPIUNIT(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); + i4b_l1_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))) + if(!(i4b_l1_bchan_tel_silence(chan->out_mbuf_cur->m_data, chan->out_mbuf_cur->m_len))) activity = ACT_TX; } else @@ -969,13 +974,13 @@ avma1pp_hscx_intr(int h_chan, u_int stat, struct l1_softc *sc) } } - isic_hscx_fifo(chan, sc); + avma1pp_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); + (*chan->isic_drvr_linktab->bch_activity)(chan->isic_drvr_linktab->unit, activity); } /* @@ -999,39 +1004,42 @@ avma1pp_hscx_int_handler(struct l1_softc *sc) static void avma1pp_disable(device_t dev) { - struct avma1pp_softc *asc = device_get_softc(dev); + struct l1_softc *sc = device_get_softc(dev); + bus_space_handle_t bhandle = rman_get_bushandle(sc->sc_resources.io_base[0]); + bus_space_tag_t btag = rman_get_bustag(sc->sc_resources.io_base[0]); - bus_space_write_1(asc->avma1pp_btag, asc->avma1pp_bhandle, STAT0_OFFSET, ASL_RESET_ALL|ASL_TIMERDISABLE); + bus_space_write_1(btag, bhandle, STAT0_OFFSET, ASL_RESET_ALL|ASL_TIMERDISABLE); } static void avma1pp_intr(void *xsc) { -#define ISICINTR(sc) isicintr(sc) u_char stat; - struct avma1pp_softc *asc; struct l1_softc *sc; + bus_space_handle_t bhandle; + bus_space_tag_t btag; - asc = xsc; - sc = asc->avma1pp_isc; + sc = xsc; + bhandle = rman_get_bushandle(sc->sc_resources.io_base[0]); + btag = rman_get_bustag(sc->sc_resources.io_base[0]); - stat = bus_space_read_1(asc->avma1pp_btag, asc->avma1pp_bhandle, STAT0_OFFSET); - DBGL1(L1_H_IRQ, "avma1pp_intr", ("stat %x\n", stat)); + stat = bus_space_read_1(btag, bhandle, STAT0_OFFSET); + NDBGL1(L1_H_IRQ, "stat %x", stat); /* was there an interrupt from this card ? */ if ((stat & ASL_IRQ_Pending) == ASL_IRQ_Pending) return; /* no */ /* interrupts are low active */ if (!(stat & ASL_IRQ_TIMER)) - DBGL1(L1_H_IRQ, "avma1pp_intr", ("timer interrupt ???\n")); + NDBGL1(L1_H_IRQ, "timer interrupt ???"); if (!(stat & ASL_IRQ_HSCX)) { - DBGL1(L1_H_IRQ, "avma1pp_intr", ("HSCX\n")); + NDBGL1(L1_H_IRQ, "HSCX"); avma1pp_hscx_int_handler(sc); } if (!(stat & ASL_IRQ_ISAC)) { - DBGL1(L1_H_IRQ, "avma1pp_intr", ("ISAC\n")); - ISICINTR(sc); + NDBGL1(L1_H_IRQ, "ISAC"); + ifpi_isac_intr(sc); } } @@ -1041,8 +1049,8 @@ avma1pp_hscx_init(struct l1_softc *sc, int h_chan, int activate) l1_bchan_state_t *chan = &sc->sc_chan[h_chan]; u_int param = 0; - DBGL1(L1_BCHAN, "avma1pp_hscx_init", ("unit=%d, channel=%d, %s\n", - sc->sc_unit, h_chan, activate ? "activate" : "deactivate")); + NDBGL1(L1_BCHAN, "unit=%d, channel=%d, %s", + sc->sc_unit, h_chan, activate ? "activate" : "deactivate"); if (activate == 0) { @@ -1060,7 +1068,7 @@ avma1pp_hscx_init(struct l1_softc *sc, int h_chan, int activate) } if(chan->bprot == BPROT_RHDLC) { - DBGL1(L1_BCHAN, "avma1pp_hscx_init", ("BPROT_RHDLC\n")); + NDBGL1(L1_BCHAN, "BPROT_RHDLC"); /* HDLC Frames, transparent mode 0 */ sc->avma1pp_cmd = HSCX_CMD_XRS|HSCX_CMD_RRS; @@ -1074,7 +1082,7 @@ avma1pp_hscx_init(struct l1_softc *sc, int h_chan, int activate) } else { - DBGL1(L1_BCHAN, "avma1pp_hscx_init", ("BPROT_NONE??\n")); + NDBGL1(L1_BCHAN, "BPROT_NONE??"); /* Raw Telephony, extended transparent mode 1 */ sc->avma1pp_cmd = HSCX_CMD_XRS|HSCX_CMD_RRS; @@ -1092,7 +1100,7 @@ static void avma1pp_bchannel_setup(int unit, int h_chan, int bprot, int activate) { #ifdef __FreeBSD__ - struct l1_softc *sc = &l1_sc[unit]; + struct l1_softc *sc = ifpi_scp[unit]; #else struct l1_softc *sc = isic_find_sc(unit); #endif @@ -1107,8 +1115,8 @@ avma1pp_bchannel_setup(int unit, int h_chan, int bprot, int activate) avma1pp_hscx_init(sc, h_chan, activate); } - DBGL1(L1_BCHAN, "avma1pp_bchannel_setup", ("unit=%d, channel=%d, %s\n", - sc->sc_unit, h_chan, activate ? "activate" : "deactivate")); + NDBGL1(L1_BCHAN, "unit=%d, channel=%d, %s", + sc->sc_unit, h_chan, activate ? "activate" : "deactivate"); /* general part */ @@ -1160,7 +1168,7 @@ static void avma1pp_bchannel_start(int unit, int h_chan) { #ifdef __FreeBSD__ - struct l1_softc *sc = &l1_sc[unit]; + struct l1_softc *sc = ifpi_scp[unit]; #else struct l1_softc *sc = isic_find_sc(unit); #endif @@ -1195,7 +1203,7 @@ avma1pp_bchannel_start(int unit, int h_chan) if(chan->bprot == BPROT_NONE) { - if(!(isic_hscx_silence(chan->out_mbuf_cur->m_data, chan->out_mbuf_cur->m_len))) + if(!(i4b_l1_bchan_tel_silence(chan->out_mbuf_cur->m_data, chan->out_mbuf_cur->m_len))) activity = ACT_TX; } else @@ -1208,20 +1216,20 @@ avma1pp_bchannel_start(int unit, int h_chan) if(sc->sc_trace & TRACE_B_TX) /* if trace, send mbuf to trace dev */ { i4b_trace_hdr_t hdr; - hdr.unit = unit; + hdr.unit = L0IFPIUNIT(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); + i4b_l1_trace_ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data); } - isic_hscx_fifo(chan, sc); + avma1pp_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); + (*chan->isic_drvr_linktab->bch_activity)(chan->isic_drvr_linktab->unit, activity); splx(s); } @@ -1233,13 +1241,13 @@ static isdn_link_t * avma1pp_ret_linktab(int unit, int channel) { #ifdef __FreeBSD__ - struct l1_softc *sc = &l1_sc[unit]; + struct l1_softc *sc = ifpi_scp[unit]; #else struct l1_softc *sc = isic_find_sc(unit); #endif l1_bchan_state_t *chan = &sc->sc_chan[channel]; - return(&chan->isdn_linktab); + return(&chan->isic_isdn_linktab); } /*---------------------------------------------------------------------------* @@ -1249,13 +1257,13 @@ static void avma1pp_set_linktab(int unit, int channel, drvr_link_t *dlt) { #ifdef __FreeBSD__ - struct l1_softc *sc = &l1_sc[unit]; + struct l1_softc *sc = ifpi_scp[unit]; #else struct l1_softc *sc = isic_find_sc(unit); #endif l1_bchan_state_t *chan = &sc->sc_chan[channel]; - chan->drvr_linktab = dlt; + chan->isic_drvr_linktab = dlt; } @@ -1266,7 +1274,7 @@ static void avma1pp_init_linktab(struct l1_softc *sc) { l1_bchan_state_t *chan = &sc->sc_chan[HSCX_CH_A]; - isdn_link_t *lt = &chan->isdn_linktab; + isdn_link_t *lt = &chan->isic_isdn_linktab; /* make sure the hardware driver is known to layer 4 */ /* avoid overwriting if already set */ @@ -1291,7 +1299,7 @@ avma1pp_init_linktab(struct l1_softc *sc) lt->rx_mbuf = &chan->in_mbuf; chan = &sc->sc_chan[HSCX_CH_B]; - lt = &chan->isdn_linktab; + lt = &chan->isic_isdn_linktab; lt->unit = sc->sc_unit; lt->channel = HSCX_CH_B; @@ -1314,7 +1322,7 @@ static void avma1pp_bchannel_stat(int unit, int h_chan, bchan_statistics_t *bsp) { #ifdef __FreeBSD__ - struct l1_softc *sc = &l1_sc[unit]; + struct l1_softc *sc = ifpi_scp[unit]; #else struct l1_softc *sc = isic_find_sc(unit); #endif @@ -1336,8 +1344,8 @@ avma1pp_bchannel_stat(int unit, int h_chan, bchan_statistics_t *bsp) * fill HSCX fifo with data from the current mbuf * Put this here until it can go into i4b_hscx.c *---------------------------------------------------------------------------*/ -int -isic_hscx_fifo(l1_bchan_state_t *chan, struct l1_softc *sc) +static int +avma1pp_hscx_fifo(l1_bchan_state_t *chan, struct l1_softc *sc) { int len; int nextlen; @@ -1392,12 +1400,12 @@ isic_hscx_fifo(l1_bchan_state_t *chan, struct l1_softc *sc) if(sc->sc_trace & TRACE_B_TX) { i4b_trace_hdr_t hdr; - hdr.unit = sc->sc_unit; + hdr.unit = L0IFPIUNIT(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); + i4b_l1_trace_ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data); } } else @@ -1415,4 +1423,65 @@ isic_hscx_fifo(l1_bchan_state_t *chan, struct l1_softc *sc) return(cmd); } -#endif /* NISIC > 0 && defined(AVM_A1_PCI) */ +/*---------------------------------------------------------------------------* + * ifpi - ISAC interrupt routine + *---------------------------------------------------------------------------*/ +static void +ifpi_isac_intr(struct l1_softc *sc) +{ + register u_char isac_irq_stat; + + for(;;) + { + /* get isac irq status */ + isac_irq_stat = ISAC_READ(I_ISTA); + + if(isac_irq_stat) + ifpi_isac_irq(sc, isac_irq_stat); /* isac handler */ + else + break; + } + + ISAC_WRITE(I_MASK, 0xff); + + DELAY(100); + + ISAC_WRITE(I_MASK, ISAC_IMASK); +} + +/*---------------------------------------------------------------------------* + * ifpi_recover - try to recover from irq lockup + *---------------------------------------------------------------------------*/ +void +ifpi_recover(struct l1_softc *sc) +{ + u_char byte; + + /* get isac irq status */ + + byte = ISAC_READ(I_ISTA); + + NDBGL1(L1_ERROR, " ISAC: ISTA = 0x%x", byte); + + if(byte & ISAC_ISTA_EXI) + NDBGL1(L1_ERROR, " ISAC: EXIR = 0x%x", (u_char)ISAC_READ(I_EXIR)); + + if(byte & ISAC_ISTA_CISQ) + { + byte = ISAC_READ(I_CIRR); + + NDBGL1(L1_ERROR, " ISAC: CISQ = 0x%x", byte); + + if(byte & ISAC_CIRR_SQC) + NDBGL1(L1_ERROR, " ISAC: SQRR = 0x%x", (u_char)ISAC_READ(I_SQRR)); + } + + NDBGL1(L1_ERROR, " ISAC: IMASK = 0x%x", ISAC_IMASK); + + ISAC_WRITE(I_MASK, 0xff); + DELAY(100); + ISAC_WRITE(I_MASK, ISAC_IMASK); +} + + +#endif /* NIFPI > 0 */ diff --git a/sys/i4b/layer1/i4b_avm_fritz_pnp.c b/sys/i4b/layer1/ifpnp/i4b_ifpnp_avm.c index 54db491..b1d3c0e 100644 --- a/sys/i4b/layer1/i4b_avm_fritz_pnp.c +++ b/sys/i4b/layer1/ifpnp/i4b_ifpnp_avm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Udo Schweigert. All rights reserved. + * Copyright (c) 1999, 2000 Udo Schweigert. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -29,73 +29,104 @@ * 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 - * ------------------------------------------------ + * i4b_ifpnp_avm.c: AVM Fritz!Card PnP hardware driver + * --------------------------------------------------- + * + * $Id: i4b_ifpnp_avm.c,v 1.3 2000/05/29 15:41:41 hm Exp $ + * $Ust: src/i4b/layer1-nb/ifpnp/i4b_ifpnp_avm.c,v 1.6 2000/04/18 08:32:32 ust Exp $ * * $FreeBSD$ * - * last edit-date: [Thu 10 Jun 08:50:28 CEST 1999] + * last edit-date: [Mon May 29 15:24:43 2000] * *---------------------------------------------------------------------------*/ -#if defined(__FreeBSD__) -#include "isic.h" +#include "ifpnp.h" #include "opt_i4b.h" -#if NISIC > 0 && defined(AVM_PNP) +#if (NIFPNP > 0) #include <sys/param.h> -#if defined(__FreeBSD__) && __FreeBSD__ >= 3 -#include <sys/ioccom.h> -#if __FreeBSD__ >= 5 -#include <sys/bus.h> -#endif -#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 <machine/clock.h> +#include <machine/bus_pio.h> +#include <machine/bus.h> +#include <machine/resource.h> +#include <sys/bus.h> +#include <sys/rman.h> + +#include <isa/isavar.h> #include <sys/socket.h> #include <net/if.h> #include <machine/i4b_debug.h> #include <machine/i4b_ioctl.h> +#include <machine/i4b_trace.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 *); +#include <i4b/layer1/isic/i4b_isic.h> +#include <i4b/layer1/isic/i4b_isac.h> +#include <i4b/layer1/isic/i4b_hscx.h> + +#include <i4b/layer1/ifpnp/i4b_ifpnp_ext.h> + +/* prototypes */ +static void avm_pnp_intr(void *); +static void hscx_write_reg(int, u_int, struct l1_softc *, u_int); +static void hscx_write_reg_val(int, u_int, u_int8_t, struct l1_softc *); +static u_int hscx_read_reg(int, u_int, struct l1_softc *); +static void hscx_read_fifo(int, void *, size_t, struct l1_softc *); +static void hscx_write_fifo(int, void *, size_t, struct l1_softc *); +static void avm_pnp_hscx_int_handler(struct l1_softc *); +static void avm_pnp_hscx_intr(int, u_int, u_int, struct l1_softc *); +static void avm_pnp_init_linktab(struct l1_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_hscx_init(struct l1_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 *); +static int avm_pnp_probe(device_t); +static int avm_pnp_hscx_fifo(l1_bchan_state_t *, struct l1_softc *); +int avm_pnp_attach(device_t); +static void ifpnp_isac_intr(struct l1_softc *sc); + +static device_method_t avm_pnp_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, avm_pnp_probe), + DEVMETHOD(device_attach, avm_pnp_attach), + { 0, 0 } +}; + +static driver_t avm_pnp_driver = { + "ifpnp", + avm_pnp_methods, + sizeof(struct l1_softc) +}; + +static devclass_t avm_pnp_devclass; + +DRIVER_MODULE(avm_pnp, isa, avm_pnp_driver, avm_pnp_devclass, 0, 0); + +/* jump table for multiplex routines */ + +struct i4b_l1mux_func avm_pnp_l1mux_func = { + avm_pnp_ret_linktab, + avm_pnp_set_linktab, + ifpnp_mph_command_req, + ifpnp_ph_data_req, + ifpnp_ph_activate_req, +}; + +struct l1_softc *ifpnp_scp[IFPNP_MAXUNIT]; /*---------------------------------------------------------------------------* * AVM PnP Fritz!Card special registers @@ -104,9 +135,13 @@ extern void isicintr_sc(struct isic_softc *); /* * register offsets from i/o base */ +#define CLASS_OFFSET 0x00 +#define REVISION_OFFSET 0x01 #define STAT0_OFFSET 0x02 #define STAT1_OFFSET 0x03 #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 @@ -136,7 +171,7 @@ extern void isicintr_sc(struct isic_softc *); #define ASL_IRQ_TIMER 0x04 /* Timer interrupt, active low */ #define ASL_IRQ_BCHAN ASL_IRQ_HSCX /* actually active LOW */ -#define ASL_IRQ_Pending 0x07 +#define ASL_IRQ_Pending (ASL_IRQ_ISAC | ASL_IRQ_HSCX | ASL_IRQ_TIMER) /* * AVM Status Latch 0 write only bits @@ -187,63 +222,52 @@ extern void isicintr_sc(struct isic_softc *); #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 +#define HSCX_AVMA1PP_ACTIVE 0x1000 /*---------------------------------------------------------------------------* * AVM read fifo routines *---------------------------------------------------------------------------*/ -static void -avm_pnp_read_fifo(void *buf, const void *base, size_t len) +static void +avm_pnp_read_fifo(struct l1_softc *sc, int what, void *buf, size_t size) { - int unit; - struct isic_softc *sc; + bus_space_handle_t bhandle = rman_get_bushandle(sc->sc_resources.io_base[0]); + bus_space_tag_t btag = rman_get_bustag(sc->sc_resources.io_base[0]); - 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; + switch (what) { + case ISIC_WHAT_ISAC: + bus_space_write_1(btag, bhandle, ADDR_REG_OFFSET, ISAC_FIFO); + bus_space_read_multi_1(btag, bhandle, 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; } - /* 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) +hscx_read_fifo(int chan, void *buf, size_t len, struct l1_softc *sc) { - u_char *ip; + u_int8_t *ip; size_t cnt; + bus_space_handle_t bhandle = rman_get_bushandle(sc->sc_resources.io_base[0]); + bus_space_tag_t btag = rman_get_bustag(sc->sc_resources.io_base[0]); - outb(sc->sc_port + ADDR_REG_OFFSET, chan); - ip = (u_char *)buf; + bus_space_write_1(btag, bhandle, ADDR_REG_OFFSET, chan); + ip = (u_int8_t *)buf; cnt = 0; - - while (cnt < len) + while (cnt++ < len) { - *ip++ = inb(sc->sc_port + ISAC_REG_OFFSET); - cnt++; + *ip++ = bus_space_read_1(btag, bhandle, ISAC_REG_OFFSET); } } @@ -251,216 +275,264 @@ hscx_read_fifo(int chan, void *buf, size_t len, struct isic_softc *sc) * AVM write fifo routines *---------------------------------------------------------------------------*/ static void -avm_pnp_write_fifo(void *base, const void *buf, size_t len) +avm_pnp_write_fifo(struct l1_softc *sc, int what, void *buf, size_t size) { - int unit; - struct isic_softc *sc; - - unit = (int)base & 0xff; - sc = &isic_sc[unit]; + bus_space_handle_t bhandle = rman_get_bushandle(sc->sc_resources.io_base[0]); + bus_space_tag_t btag = rman_get_bustag(sc->sc_resources.io_base[0]); - /* 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; + switch (what) { + case ISIC_WHAT_ISAC: + bus_space_write_1(btag, bhandle, ADDR_REG_OFFSET, ISAC_FIFO); + bus_space_write_multi_1(btag, bhandle, 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; } - /* 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) +hscx_write_fifo(int chan, void *buf, size_t len, struct l1_softc *sc) { - register const u_char *ip; - register size_t cnt; - isic_Bchan_t *Bchan = &sc->sc_chan[chan]; + u_int8_t *ip; + size_t cnt; + l1_bchan_state_t *Bchan = &sc->sc_chan[chan]; + bus_space_handle_t bhandle = rman_get_bushandle(sc->sc_resources.io_base[0]); + bus_space_tag_t btag = rman_get_bustag(sc->sc_resources.io_base[0]); 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 (Bchan->out_mbuf_cur == NULL) + { + if (Bchan->bprot != BPROT_NONE) + sc->avma1pp_cmd |= HSCX_CMD_XME; + } if (len != sc->sc_bfifolen) - sc->avma1pp_txl = len; - + sc->avma1pp_txl = len; + hscx_write_reg(chan, HSCX_STAT, sc, 3); - ip = (const u_char *)buf; + ip = (u_int8_t *)buf; cnt = 0; - while (cnt < len) + while (cnt++ < len) { - outb(sc->sc_port + ISAC_REG_OFFSET, *ip++); - cnt++; + bus_space_write_1(btag, bhandle, ISAC_REG_OFFSET, *ip++); } } /*---------------------------------------------------------------------------* * AVM write register routines *---------------------------------------------------------------------------*/ + static void -avm_pnp_write_reg(u_char *base, u_int offset, u_int v) +avm_pnp_write_reg(struct l1_softc *sc, int what, bus_size_t offs, u_int8_t data) { - 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; + bus_space_handle_t bhandle = rman_get_bushandle(sc->sc_resources.io_base[0]); + bus_space_tag_t btag = rman_get_bustag(sc->sc_resources.io_base[0]); + + switch (what) { + case ISIC_WHAT_ISAC: + reg_bank = (offs > MAX_LO_REG_OFFSET) ? ISAC_HI_REG_OFFSET:ISAC_LO_REG_OFFSET; + /* set the register bank */ + bus_space_write_1(btag, bhandle, ADDR_REG_OFFSET, reg_bank); + bus_space_write_1(btag, bhandle, ISAC_REG_OFFSET + (offs & ISAC_REGSET_MASK), data); + break; + case ISIC_WHAT_HSCXA: + hscx_write_reg_val(0, offs, data, sc); + break; + case ISIC_WHAT_HSCXB: + hscx_write_reg_val(1, offs, data, sc); + break; } - /* 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) +hscx_write_reg(int chan, u_int off, struct l1_softc *sc, u_int which) { - /* HACK */ - if (off == H_MASK) - return; + bus_space_handle_t bhandle = rman_get_bushandle(sc->sc_resources.io_base[0]); + bus_space_tag_t btag = rman_get_bustag(sc->sc_resources.io_base[0]); + /* 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); + bus_space_write_1(btag, bhandle, ADDR_REG_OFFSET, chan); + if (which & 4) + bus_space_write_1(btag, bhandle, ISAC_REG_OFFSET + off + 2, sc->avma1pp_prot); + if (which & 2) + bus_space_write_1(btag, bhandle, ISAC_REG_OFFSET + off + 1, sc->avma1pp_txl); + if (which & 1) + bus_space_write_1(btag, bhandle, 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) +hscx_write_reg_val(int chan, u_int off, u_int8_t val, struct l1_softc *sc) { - /* HACK */ - if (off == H_MASK) - return; + bus_space_handle_t bhandle = rman_get_bushandle(sc->sc_resources.io_base[0]); + bus_space_tag_t btag = rman_get_bustag(sc->sc_resources.io_base[0]); + /* point at the correct channel */ - outb(sc->sc_port + ADDR_REG_OFFSET, chan); - outb(sc->sc_port + ISAC_REG_OFFSET + off, val); + bus_space_write_1(btag, bhandle, ADDR_REG_OFFSET, chan); + bus_space_write_1(btag, bhandle, ISAC_REG_OFFSET + off, val); } /*---------------------------------------------------------------------------* * AVM read register routines *---------------------------------------------------------------------------*/ - -static u_char -avm_pnp_read_reg(u_char *base, u_int offset) +static u_int8_t +avm_pnp_read_reg(struct l1_softc *sc, int what, bus_size_t offs) { - 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))); + bus_space_handle_t bhandle = rman_get_bushandle(sc->sc_resources.io_base[0]); + bus_space_tag_t btag = rman_get_bustag(sc->sc_resources.io_base[0]); + + switch (what) { + case ISIC_WHAT_ISAC: + reg_bank = (offs > MAX_LO_REG_OFFSET) ? ISAC_HI_REG_OFFSET:ISAC_LO_REG_OFFSET; + /* set the register bank */ + bus_space_write_1(btag, bhandle, ADDR_REG_OFFSET, reg_bank); + return(bus_space_read_1(btag, bhandle, 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; } -static u_char -hscx_read_reg(int chan, u_int off, struct isic_softc *sc) +static u_int +hscx_read_reg(int chan, u_int off, struct l1_softc *sc) { - /* HACK */ - if (off == H_ISTA) - return(0); + bus_space_handle_t bhandle = rman_get_bushandle(sc->sc_resources.io_base[0]); + bus_space_tag_t btag = rman_get_bustag(sc->sc_resources.io_base[0]); + /* point at the correct channel */ - outb(sc->sc_port + ADDR_REG_OFFSET, chan); - return(inb(sc->sc_port + ISAC_REG_OFFSET + off)); + bus_space_write_1(btag, bhandle, ADDR_REG_OFFSET, chan); + return(bus_space_read_1(btag, bhandle, ISAC_REG_OFFSET + off)); } + +static struct ifpnp_ids { + u_long vend_id; + char *id_str; +} ifpnp_ids[] = { + { 0x0009cd06, "AVM Fritz!Card PnP" }, + { 0, 0 } +}; + /*---------------------------------------------------------------------------* - * isic_probe_avm_pnp - probe Fritz!Card PnP + * avm_pnp_probe - probe for a card *---------------------------------------------------------------------------*/ - -int -isic_probe_avm_pnp(struct isa_device *dev, unsigned int iobase2) +static int +avm_pnp_probe(dev) + device_t dev; { - struct isic_softc *sc = &isic_sc[dev->id_unit]; + struct ifpnp_ids *ids; /* pnp id's */ + char *string = NULL; /* the name */ + u_int32_t vend_id = isa_get_vendorid(dev); /* vendor id */ + + /* search table of knowd id's */ - /* check max unit range */ + for(ids = ifpnp_ids; ids->vend_id != 0; ids++) + { + if(vend_id == ids->vend_id) + { + string = ids->id_str; + break; + } + } - if(dev->id_unit >= ISIC_MAXUNIT) + if(string) /* set name if we have one */ + { + device_set_desc(dev, string); /* set description */ + return 0; + } + else { - 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; + return ENXIO; + } +} - /* check IRQ validity */ +/*---------------------------------------------------------------------------* + * avm_pnp_attach - attach Fritz!Card PnP + *---------------------------------------------------------------------------*/ +int +avm_pnp_attach(device_t dev) +{ + struct l1_softc *sc; + u_int v; + int unit, error = 0; + int s; + u_int16_t vid; + void *ih = 0; + bus_space_handle_t bhandle; + bus_space_tag_t btag; - 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; + s = splimp(); + + vid = isa_get_vendorid(dev); + sc = device_get_softc(dev); + unit = device_get_unit(dev); + bzero(sc, sizeof(struct l1_softc)); + + /* probably not really required */ + if(unit > IFPNP_MAXUNIT) { + printf("avm_pnp%d: Error, unit > IFPNP_MAXUNIT!\n", unit); + splx(s); + return(ENXIO); } - sc->sc_irq = dev->id_irq; - dev->id_intr = (driver_intr_t *) avm_pnp_intr; + ifpnp_scp[unit] = sc; - /* check if memory addr specified */ - if(dev->id_maddr) + /* get io_base */ + if(!(sc->sc_resources.io_base[0] = + bus_alloc_resource(dev, SYS_RES_IOPORT, + &sc->sc_resources.io_rid[0], + 0UL, ~0UL, 1, RF_ACTIVE ) )) { - printf("isic%d: Error, mem addr 0x%lx specified for AVM Fritz! PnP!\n", - dev->id_unit, (u_long)dev->id_maddr); - return(0); + printf("avm_pnp_attach: Couldn't get my io_base.\n"); + return ENXIO; } - dev->id_msize = 0; - - /* check if we got an iobase */ + if (sc->sc_resources.io_base[0] == NULL) { + printf("avm_pnp%d: couldn't map IO port\n", unit); + error = ENXIO; + goto fail; + } + + bhandle = rman_get_bushandle(sc->sc_resources.io_base[0]); + btag = rman_get_bustag(sc->sc_resources.io_base[0]); + + /* will not be used for pnp devices */ + sc->sc_port = rman_get_start(sc->sc_resources.io_base[0]); - if(!((dev->id_iobase >= 0x160) && (dev->id_iobase <= 0x360))) + /* get irq, release io_base if we don't get it */ + + if(!(sc->sc_resources.irq = + bus_alloc_resource(dev, SYS_RES_IRQ, + &sc->sc_resources.irq_rid, + 0UL, ~0UL, 1, RF_ACTIVE))) { - printf("isic%d: Error, invalid iobase 0x%x specified for AVM Fritz! PnP!\n", - dev->id_unit, dev->id_iobase); - return(0); + printf("avm_pnp%d: Could not get irq.\n",unit); + error = ENXIO; + goto fail; } - sc->sc_port = dev->id_iobase; + /* not needed */ + sc->sc_irq = rman_get_start(sc->sc_resources.irq); + bus_setup_intr(dev,sc->sc_resources.irq,INTR_TYPE_NET, + (void(*)(void*))avm_pnp_intr, sc,&ih); + sc->sc_unit = unit; + + /* end of new-bus stuff */ + + ISAC_BASE = (caddr_t)ISIC_WHAT_ISAC; + + HSCX_A_BASE = (caddr_t)ISIC_WHAT_HSCXA; + HSCX_B_BASE = (caddr_t)ISIC_WHAT_HSCXB; /* setup access routines */ @@ -479,41 +551,11 @@ isic_probe_avm_pnp(struct isa_device *dev, unsigned int iobase2) sc->sc_bustyp = BUS_TYPE_IOM2; + /* set up some other miscellaneous things */ 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); - + sc->sc_bfifolen = HSCX_FIFO_LEN; /* reset the card */ - /* the Linux driver does this to clear any pending ISAC interrupts */ v = 0; v = ISAC_READ(I_STAR); @@ -526,30 +568,28 @@ isic_attach_avm_pnp(struct isa_device *dev, unsigned int iobase2) } 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); + bus_space_write_1(btag, bhandle, 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); + bus_space_write_1(btag, bhandle, STAT1_OFFSET, ASL1_ENABLE_IOM|sc->sc_irq); DELAY(SEC_DELAY/100); /* 10 ms */ - outb(sc->sc_port + STAT1_OFFSET, ASL1_ENABLE_IOM+(ffs(sc->sc_irq)-1)); + bus_space_write_1(btag, bhandle, STAT0_OFFSET, ASL_TIMERRESET|ASL_ENABLE_INT|ASL_TIMERDISABLE); 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'); + printf("ifpnp%d: AVM Fritz!Card PnP Class %#x Revision %d \n", unit, + bus_space_read_1(btag, bhandle, CLASS_OFFSET), + bus_space_read_1(btag, bhandle, REVISION_OFFSET)); + + printf("ifpnp%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); + ifpnp_isac_init(sc); /* init the "HSCX" */ avm_pnp_bchannel_setup(sc->sc_unit, HSCX_CH_A, BPROT_NONE, 0); @@ -577,33 +617,33 @@ isic_attach_avm_pnp(struct isa_device *dev, unsigned int iobase2) 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); + i4b_l1_mph_status_ind(L0IFPNPUNIT(sc->sc_unit), STI_ATTACH, sc->sc_cardtyp, &avm_pnp_l1mux_func); - return(0); + fail: + splx(s); + return(error); } /* * this is the real interrupt routine */ static void -avm_pnp_hscx_intr(int h_chan, int stat, int cnt, struct isic_softc *sc) +avm_pnp_hscx_intr(int h_chan, u_int stat, u_int cnt, struct l1_softc *sc) { - register isic_Bchan_t *chan = &sc->sc_chan[h_chan]; + register l1_bchan_state_t *chan = &sc->sc_chan[h_chan]; int activity = -1; - DBGL1(L1_H_IRQ, "avm_pnp_hscx_intr", ("%#x\n", stat)); + NDBGL1(L1_H_IRQ, "%#x", 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")); + NDBGL1(L1_H_XFRERR, "xmit data underrun"); /* abort the transmission */ sc->avma1pp_txl = 0; sc->avma1pp_cmd |= HSCX_CMD_XRS; @@ -642,10 +682,29 @@ avm_pnp_hscx_intr(int h_chan, int stat, int cnt, struct isic_softc *sc) if(stat & HSCX_STAT_RDO) { chan->stat_RDO++; - DBGL1(L1_H_XFRERR, "avm_pnp_hscx_intr", ("receive data overflow\n")); + NDBGL1(L1_H_XFRERR, "receive data overflow"); error++; } - + + /* + * check whether we're receiving data for an inactive B-channel + * and discard it. This appears to happen for telephony when + * both B-channels are active and one is deactivated. Since + * it is not really possible to deactivate the channel in that + * case (the ASIC seems to deactivate _both_ channels), the + * "deactivated" channel keeps receiving data which can lead + * to exhaustion of mbufs and a kernel panic. + * + * This is a hack, but it's the only solution I can think of + * without having the documentation for the ASIC. + * GJ - 28 Nov 1999 + */ + if (chan->state == HSCX_IDLE) + { + NDBGL1(L1_H_XFRERR, "toss data from %d", h_chan); + error++; + } + fifo_data_len = cnt; if(fifo_data_len == 0) @@ -680,23 +739,22 @@ avm_pnp_hscx_intr(int h_chan, int stat, int cnt, struct isic_softc *sc) 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.unit = L0IFPNPUNIT(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); + i4b_l1_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); + (*chan->isic_drvr_linktab->bch_rx_data_ready)(chan->isic_drvr_linktab->unit); activity = ACT_RX; /* mark buffer ptr as unused */ @@ -708,7 +766,7 @@ avm_pnp_hscx_intr(int h_chan, int stat, int cnt, struct isic_softc *sc) else { chan->stat_CRC++; - DBGL1(L1_H_XFRERR, "avm_pnp_hscx_intr", ("CRC/RAB\n")); + NDBGL1(L1_H_XFRERR, "CRC/RAB"); if (chan->in_mbuf != NULL) { i4b_Bfreembuf(chan->in_mbuf); @@ -731,23 +789,31 @@ avm_pnp_hscx_intr(int h_chan, int stat, int cnt, struct isic_softc *sc) if(sc->sc_trace & TRACE_B_RX) { i4b_trace_hdr_t hdr; - hdr.unit = sc->sc_unit; + hdr.unit = L0IFPNPUNIT(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); + i4b_l1_trace_ind(&hdr, chan->in_mbuf->m_len, chan->in_mbuf->m_data); } + if(!(i4b_l1_bchan_tel_silence(chan->in_mbuf->m_data, chan->in_mbuf->m_len))) + activity = ACT_RX; + /* 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 (!(IF_QFULL(&chan->rx_queue))) + { + IF_ENQUEUE(&chan->rx_queue, chan->in_mbuf); + } + else + { + i4b_Bfreembuf(chan->in_mbuf); + } + + /* signal upper layer that data are available */ + (*chan->isic_drvr_linktab->bch_rx_data_ready)(chan->isic_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) @@ -767,7 +833,7 @@ avm_pnp_hscx_intr(int h_chan, int stat, int cnt, struct isic_softc *sc) } else { - DBGL1(L1_H_XFRERR, "avm_pnp_hscx_intr", ("RAWHDLC rx buffer overflow in RPF, in_len=%d\n", chan->in_len)); + NDBGL1(L1_H_XFRERR, "RAWHDLC rx buffer overflow in RPF, in_len=%d", chan->in_len); chan->in_cbptr = chan->in_mbuf->m_data; chan->in_len = 0; } @@ -801,16 +867,16 @@ avm_pnp_hscx_intr(int h_chan, int stat, int cnt, struct isic_softc *sc) * 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)); + NDBGL1(L1_H_IRQ, "unit %d, chan %d - XPR, Tx Fifo Empty!", sc->sc_unit, h_chan); - if(chan->out_mbuf_cur == NULL || chan->out_mbuf_head == NULL) /* last frame is transmitted */ + if(chan->out_mbuf_cur == 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); + (*chan->isic_drvr_linktab->bch_tx_queue_empty)(chan->isic_drvr_linktab->unit); } else { @@ -822,16 +888,17 @@ avm_pnp_hscx_intr(int h_chan, int stat, int cnt, struct isic_softc *sc) if(sc->sc_trace & TRACE_B_TX) { i4b_trace_hdr_t hdr; - hdr.unit = sc->sc_unit; + hdr.unit = L0IFPNPUNIT(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); + i4b_l1_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))) + if(!(i4b_l1_bchan_tel_silence(chan->out_mbuf_cur->m_data, chan->out_mbuf_cur->m_len))) activity = ACT_TX; } else @@ -841,13 +908,13 @@ avm_pnp_hscx_intr(int h_chan, int stat, int cnt, struct isic_softc *sc) } } - isic_hscx_fifo(chan, sc); + avm_pnp_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); + (*chan->isic_drvr_linktab->bch_activity)(chan->isic_drvr_linktab->unit, activity); } /* @@ -855,32 +922,64 @@ avm_pnp_hscx_intr(int h_chan, int stat, int cnt, struct isic_softc *sc) * the real interrupt routine as appropriate */ static void -avm_pnp_hscx_int_handler(struct isic_softc *sc) +avm_pnp_hscx_int_handler(struct l1_softc *sc) { u_char stat = 0; u_char cnt = 0; stat = hscx_read_reg(0, HSCX_STAT, sc); - if (stat & HSCX_INT_RPR) + 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) + 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) +avm_pnp_intr(void *xsc) { - isic_Bchan_t *chan = &sc->sc_chan[h_chan]; + u_char stat; + struct l1_softc *sc; + bus_space_handle_t bhandle; + bus_space_tag_t btag; + + sc = xsc; + bhandle = rman_get_bushandle(sc->sc_resources.io_base[0]); + btag = rman_get_bustag(sc->sc_resources.io_base[0]); + + stat = bus_space_read_1(btag, bhandle, STAT0_OFFSET); + NDBGL1(L1_H_IRQ, "stat %x", stat); + /* was there an interrupt from this card ? */ + if ((stat & ASL_IRQ_Pending) == ASL_IRQ_Pending) + return; /* no */ + /* interrupts are low active */ + if (!(stat & ASL_IRQ_TIMER)) + NDBGL1(L1_H_IRQ, "timer interrupt ???"); + if (!(stat & ASL_IRQ_HSCX)) + { + NDBGL1(L1_H_IRQ, "HSCX"); + avm_pnp_hscx_int_handler(sc); + } + if (!(stat & ASL_IRQ_ISAC)) + { + NDBGL1(L1_H_IRQ, "ISAC"); + ifpnp_isac_intr(sc); + } +} - DBGL1(L1_BCHAN, "avm_pnp_hscx_init", ("unit=%d, channel=%d, %s\n", - sc->sc_unit, h_chan, activate ? "activate" : "deactivate")); +static void +avm_pnp_hscx_init(struct l1_softc *sc, int h_chan, int activate) +{ + l1_bchan_state_t *chan = &sc->sc_chan[h_chan]; + + NDBGL1(L1_BCHAN, "unit=%d, channel=%d, %s", + sc->sc_unit, h_chan, activate ? "activate" : "deactivate"); if (activate == 0) { @@ -897,7 +996,7 @@ avm_pnp_hscx_init(struct isic_softc *sc, int h_chan, int activate) } if(chan->bprot == BPROT_RHDLC) { - DBGL1(L1_BCHAN, "avm_pnp_hscx_init", ("BPROT_RHDLC\n")); + NDBGL1(L1_BCHAN, "BPROT_RHDLC"); /* HDLC Frames, transparent mode 0 */ sc->avma1pp_cmd = HSCX_CMD_XRS|HSCX_CMD_RRS; @@ -909,7 +1008,7 @@ avm_pnp_hscx_init(struct isic_softc *sc, int h_chan, int activate) } else { - DBGL1(L1_BCHAN, "avm_pnp_hscx_init", ("BPROT_NONE??\n")); + NDBGL1(L1_BCHAN, "BPROT_NONE??"); /* Raw Telephony, extended transparent mode 1 */ sc->avma1pp_cmd = HSCX_CMD_XRS|HSCX_CMD_RRS; @@ -924,20 +1023,20 @@ avm_pnp_hscx_init(struct isic_softc *sc, int h_chan, int activate) 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]; + struct l1_softc *sc = ifpnp_scp[unit]; + l1_bchan_state_t *chan = &sc->sc_chan[h_chan]; int s = SPLI4B(); if(activate == 0) { /* deactivation */ - chan->state &= ~HSCX_AVMPNP_ACTIVE; + chan->state = HSCX_IDLE; 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")); + NDBGL1(L1_BCHAN, "unit=%d, channel=%d, %s", + sc->sc_unit, h_chan, activate ? "activate" : "deactivate"); /* general part */ @@ -979,7 +1078,7 @@ avm_pnp_bchannel_setup(int unit, int h_chan, int bprot, int activate) { /* activation */ avm_pnp_hscx_init(sc, h_chan, activate); - chan->state |= HSCX_AVMPNP_ACTIVE; + chan->state |= HSCX_AVMA1PP_ACTIVE; } splx(s); @@ -988,8 +1087,8 @@ avm_pnp_bchannel_setup(int unit, int h_chan, int bprot, int activate) 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]; + struct l1_softc *sc = ifpnp_scp[unit]; + register l1_bchan_state_t *chan = &sc->sc_chan[h_chan]; int s; int activity = -1; @@ -1020,7 +1119,7 @@ avm_pnp_bchannel_start(int unit, int h_chan) if(chan->bprot == BPROT_NONE) { - if(!(isic_hscx_silence(chan->out_mbuf_cur->m_data, chan->out_mbuf_cur->m_len))) + if(!(i4b_l1_bchan_tel_silence(chan->out_mbuf_cur->m_data, chan->out_mbuf_cur->m_len))) activity = ACT_TX; } else @@ -1033,20 +1132,20 @@ avm_pnp_bchannel_start(int unit, int h_chan) if(sc->sc_trace & TRACE_B_TX) /* if trace, send mbuf to trace dev */ { i4b_trace_hdr_t hdr; - hdr.unit = unit; + hdr.unit = L0IFPNPUNIT(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); + i4b_l1_trace_ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data); } - isic_hscx_fifo(chan, sc); + avm_pnp_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); + (*chan->isic_drvr_linktab->bch_activity)(chan->isic_drvr_linktab->unit, activity); splx(s); } @@ -1057,10 +1156,10 @@ avm_pnp_bchannel_start(int unit, int h_chan) 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]; + struct l1_softc *sc = ifpnp_scp[unit]; + l1_bchan_state_t *chan = &sc->sc_chan[channel]; - return(&chan->isdn_linktab); + return(&chan->isic_isdn_linktab); } /*---------------------------------------------------------------------------* @@ -1069,10 +1168,10 @@ avm_pnp_ret_linktab(int unit, int channel) 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]; + struct l1_softc *sc = ifpnp_scp[unit]; + l1_bchan_state_t *chan = &sc->sc_chan[channel]; - chan->drvr_linktab = dlt; + chan->isic_drvr_linktab = dlt; } @@ -1080,10 +1179,10 @@ avm_pnp_set_linktab(int unit, int channel, drvr_link_t *dlt) * initialize our local linktab *---------------------------------------------------------------------------*/ static void -avm_pnp_init_linktab(struct isic_softc *sc) +avm_pnp_init_linktab(struct l1_softc *sc) { - isic_Bchan_t *chan = &sc->sc_chan[HSCX_CH_A]; - isdn_link_t *lt = &chan->isdn_linktab; + l1_bchan_state_t *chan = &sc->sc_chan[HSCX_CH_A]; + isdn_link_t *lt = &chan->isic_isdn_linktab; /* make sure the hardware driver is known to layer 4 */ /* avoid overwriting if already set */ @@ -1108,7 +1207,7 @@ avm_pnp_init_linktab(struct isic_softc *sc) lt->rx_mbuf = &chan->in_mbuf; chan = &sc->sc_chan[HSCX_CH_B]; - lt = &chan->isdn_linktab; + lt = &chan->isic_isdn_linktab; lt->unit = sc->sc_unit; lt->channel = HSCX_CH_B; @@ -1130,8 +1229,8 @@ avm_pnp_init_linktab(struct isic_softc *sc) 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]; + struct l1_softc *sc = ifpnp_scp[unit]; + l1_bchan_state_t *chan = &sc->sc_chan[h_chan]; int s; s = SPLI4B(); @@ -1150,11 +1249,12 @@ avm_pnp_bchannel_stat(int unit, int h_chan, bchan_statistics_t *bsp) * Put this here until it can go into i4b_hscx.c *---------------------------------------------------------------------------*/ static int -isic_hscx_fifo(isic_Bchan_t *chan, struct isic_softc *sc) +avm_pnp_hscx_fifo(l1_bchan_state_t *chan, struct l1_softc *sc) { int len; int nextlen; int i; + int cmd = 0; /* using a scratch buffer simplifies writing to the FIFO */ u_char scrbuf[HSCX_FIFO_LEN]; @@ -1183,6 +1283,7 @@ isic_hscx_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]; @@ -1203,16 +1304,18 @@ isic_hscx_fifo(isic_Bchan_t *chan, struct isic_softc *sc) if(sc->sc_trace & TRACE_B_TX) { i4b_trace_hdr_t hdr; - hdr.unit = sc->sc_unit; + hdr.unit = L0IFPNPUNIT(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); + i4b_l1_trace_ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data); } } else { + if (chan->bprot != BPROT_NONE) + cmd |= HSCX_CMDR_XME; i4b_Bfreembuf(chan->out_mbuf_head); chan->out_mbuf_head = NULL; } @@ -1221,51 +1324,67 @@ isic_hscx_fifo(isic_Bchan_t *chan, struct isic_softc *sc) /* write what we have from the scratch buf to the HSCX fifo */ if (len != 0) HSCX_WRFIFO(chan->channel, scrbuf, len); - - return(0); + return(cmd); } -void -avm_pnp_intr(int unit) +/*---------------------------------------------------------------------------* + * ifpnp - ISAC interrupt routine + *---------------------------------------------------------------------------*/ +static void +ifpnp_isac_intr(struct l1_softc *sc) { - struct isic_softc *sc; - u_char stat; register u_char isac_irq_stat; - int was_isac = 0; - sc = &isic_sc[unit]; + for(;;) + { + /* get isac irq status */ + isac_irq_stat = ISAC_READ(I_ISTA); + + if(isac_irq_stat) + ifpnp_isac_irq(sc, isac_irq_stat); /* isac handler */ + else + break; + } + + ISAC_WRITE(I_MASK, 0xff); - for(;;) { - stat = inb(sc->sc_port + STAT0_OFFSET); + DELAY(100); - DBGL1(L1_H_IRQ, "avm_pnp_intr", ("stat %x\n", stat)); + ISAC_WRITE(I_MASK, ISAC_IMASK); +} - /* was there an interrupt from this card ? */ - if ((stat & ASL_IRQ_Pending) == ASL_IRQ_Pending) - break; /* no */ +/*---------------------------------------------------------------------------* + * ifpnp_recover - try to recover from irq lockup + *---------------------------------------------------------------------------*/ +void +ifpnp_recover(struct l1_softc *sc) +{ + u_char byte; + + /* get isac irq status */ - /* interrupts are low active */ - if (!(stat & ASL_IRQ_TIMER)) - DBGL1(L1_H_IRQ, "avm_pnp_intr", ("timer interrupt ???\n")); + byte = ISAC_READ(I_ISTA); - 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; - } + NDBGL1(L1_ERROR, " ISAC: ISTA = 0x%x", byte); + + if(byte & ISAC_ISTA_EXI) + NDBGL1(L1_ERROR, " ISAC: EXIR = 0x%x", (u_char)ISAC_READ(I_EXIR)); - if (!(stat & ASL_IRQ_HSCX)) - { - DBGL1(L1_H_IRQ, "avm_pnp_intr", ("HSCX\n")); - avm_pnp_hscx_int_handler(sc); - } + if(byte & ISAC_ISTA_CISQ) + { + byte = ISAC_READ(I_CIRR); + + NDBGL1(L1_ERROR, " ISAC: CISQ = 0x%x", byte); + + if(byte & ISAC_CIRR_SQC) + NDBGL1(L1_ERROR, " ISAC: SQRR = 0x%x", (u_char)ISAC_READ(I_SQRR)); } - if (was_isac) { - ISAC_WRITE(0x20, 0xFF); - ISAC_WRITE(0x20, 0x0); - } + + NDBGL1(L1_ERROR, " ISAC: IMASK = 0x%x", ISAC_IMASK); + + ISAC_WRITE(I_MASK, 0xff); + DELAY(100); + ISAC_WRITE(I_MASK, ISAC_IMASK); } -#endif /* NISIC > 0 && defined(AVM_PNP) */ -#endif /* FreeBSD */ + +#endif /* NIFPNP > 0 */ diff --git a/sys/i4b/layer1/ifpnp/i4b_ifpnp_ext.h b/sys/i4b/layer1/ifpnp/i4b_ifpnp_ext.h new file mode 100644 index 0000000..3b51860 --- /dev/null +++ b/sys/i4b/layer1/ifpnp/i4b_ifpnp_ext.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2000 Gary Jennejohn. 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_ifpnp - Fritz!Card PnP for split layers + * ------------------------------------------- + * + * $Id: i4b_ifpnp_ext.h,v 1.2 2000/06/02 16:14:36 hm Exp $ + * $Ust: src/i4b/layer1-nb/ifpnp/i4b_ifpnp_ext.h,v 1.4 2000/04/18 08:03:05 ust Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Fri Jun 2 14:54:57 2000] + * + *---------------------------------------------------------------------------*/ + +#ifndef _I4B_IFPNP_EXT_H_ +#define _I4B_IFPNP_EXT_H_ + +#include <i4b/include/i4b_l3l4.h> + +void ifpnp_set_linktab(int unit, int channel, drvr_link_t * dlt); +isdn_link_t *ifpnp_ret_linktab(int unit, int channel); + +int ifpnp_ph_data_req(int unit, struct mbuf *m, int freeflag); +int ifpnp_ph_activate_req(int unit); +int ifpnp_mph_command_req(int unit, int command, void *parm); + +void ifpnp_isac_irq(struct l1_softc *sc, int ista); +void ifpnp_isac_l1_cmd(struct l1_softc *sc, int command); +int ifpnp_isac_init(struct l1_softc *sc); + +void ifpnp_recover(struct l1_softc *sc); +char * ifpnp_printstate(struct l1_softc *sc); +void ifpnp_next_state(struct l1_softc *sc, int event); + +#define IFPNP_MAXUNIT 4 +extern struct l1_softc *ifpnp_scp[IFPNP_MAXUNIT]; + +#endif /* _I4B_IFPNP_EXT_H_ */ diff --git a/sys/i4b/layer1/ifpnp/i4b_ifpnp_isac.c b/sys/i4b/layer1/ifpnp/i4b_ifpnp_isac.c new file mode 100644 index 0000000..206e3f9 --- /dev/null +++ b/sys/i4b/layer1/ifpnp/i4b_ifpnp_isac.c @@ -0,0 +1,669 @@ +/* + * Copyright (c) 1997, 2000 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_ifpnp_isac.c - i4b Fritz PnP ISAC handler + * --------------------------------------------- + * + * $Id: i4b_ifpnp_isac.c,v 1.3 2000/05/29 15:41:41 hm Exp $ + * $Ust: src/i4b/layer1-nb/ifpnp/i4b_ifpnp_isac.c,v 1.4 2000/04/18 08:03:05 ust Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Mon May 29 15:24:49 2000] + * + *---------------------------------------------------------------------------*/ + +#include "ifpnp.h" + +#if (NIFPNP > 0) + +#include "opt_i4b.h" + +#include <sys/param.h> +#include <sys/kernel.h> +#include <sys/systm.h> +#include <sys/mbuf.h> +#include <sys/socket.h> + +#include <machine/stdarg.h> +#include <machine/clock.h> + +#include <net/if.h> + +#include <machine/i4b_debug.h> +#include <machine/i4b_ioctl.h> +#include <machine/i4b_trace.h> + +#include <i4b/layer1/i4b_l1.h> + +#include <i4b/layer1/isic/i4b_isic.h> +#include <i4b/layer1/isic/i4b_isac.h> +#include <i4b/layer1/isic/i4b_hscx.h> + +#include <i4b/layer1/ifpnp/i4b_ifpnp_ext.h> + +#include <i4b/include/i4b_global.h> +#include <i4b/include/i4b_mbuf.h> + +static u_char ifpnp_isac_exir_hdlr(register struct l1_softc *sc, u_char exir); +static void ifpnp_isac_ind_hdlr(register struct l1_softc *sc, int ind); + +/*---------------------------------------------------------------------------* + * ISAC interrupt service routine + *---------------------------------------------------------------------------*/ +void +ifpnp_isac_irq(struct l1_softc *sc, int ista) +{ + register u_char c = 0; + NDBGL1(L1_F_MSG, "unit %d: ista = 0x%02x", sc->sc_unit, ista); + + if(ista & ISAC_ISTA_EXI) /* extended interrupt */ + { + c |= ifpnp_isac_exir_hdlr(sc, ISAC_READ(I_EXIR)); + } + + if(ista & ISAC_ISTA_RME) /* receive message end */ + { + register int rest; + u_char rsta; + + /* get rx status register */ + + rsta = ISAC_READ(I_RSTA); + + if((rsta & ISAC_RSTA_MASK) != 0x20) + { + int error = 0; + + if(!(rsta & ISAC_RSTA_CRC)) /* CRC error */ + { + error++; + NDBGL1(L1_I_ERR, "unit %d: CRC error", sc->sc_unit); + } + + if(rsta & ISAC_RSTA_RDO) /* ReceiveDataOverflow */ + { + error++; + NDBGL1(L1_I_ERR, "unit %d: Data Overrun error", sc->sc_unit); + } + + if(rsta & ISAC_RSTA_RAB) /* ReceiveABorted */ + { + error++; + NDBGL1(L1_I_ERR, "unit %d: Receive Aborted error", sc->sc_unit); + } + + if(error == 0) + NDBGL1(L1_I_ERR, "unit %d: RME unknown error, RSTA = 0x%02x!", sc->sc_unit, rsta); + + i4b_Dfreembuf(sc->sc_ibuf); + + c |= ISAC_CMDR_RMC|ISAC_CMDR_RRES; + + sc->sc_ibuf = NULL; + sc->sc_ib = NULL; + sc->sc_ilen = 0; + + ISAC_WRITE(I_CMDR, ISAC_CMDR_RMC|ISAC_CMDR_RRES); + ISACCMDRWRDELAY(); + + return; + } + + rest = (ISAC_READ(I_RBCL) & (ISAC_FIFO_LEN-1)); + + if(rest == 0) + rest = ISAC_FIFO_LEN; + + if(sc->sc_ibuf == NULL) + { + if((sc->sc_ibuf = i4b_Dgetmbuf(rest)) != NULL) + sc->sc_ib = sc->sc_ibuf->m_data; + else + panic("ifpnp_isac_irq: RME, i4b_Dgetmbuf returns NULL!\n"); + sc->sc_ilen = 0; + } + + if(sc->sc_ilen <= (MAX_DFRAME_LEN - rest)) + { + ISAC_RDFIFO(sc->sc_ib, rest); + sc->sc_ilen += rest; + + sc->sc_ibuf->m_pkthdr.len = + sc->sc_ibuf->m_len = sc->sc_ilen; + + if(sc->sc_trace & TRACE_D_RX) + { + i4b_trace_hdr_t hdr; + hdr.unit = L0IFPNPUNIT(sc->sc_unit); + hdr.type = TRC_CH_D; + hdr.dir = FROM_NT; + hdr.count = ++sc->sc_trace_dcount; + MICROTIME(hdr.time); + i4b_l1_trace_ind(&hdr, sc->sc_ibuf->m_len, sc->sc_ibuf->m_data); + } + + c |= ISAC_CMDR_RMC; + + if(sc->sc_enabled && + (ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S)) + { + i4b_l1_ph_data_ind(L0IFPNPUNIT(sc->sc_unit), sc->sc_ibuf); + } + else + { + i4b_Dfreembuf(sc->sc_ibuf); + } + } + else + { + NDBGL1(L1_I_ERR, "RME, input buffer overflow!"); + i4b_Dfreembuf(sc->sc_ibuf); + c |= ISAC_CMDR_RMC|ISAC_CMDR_RRES; + } + + sc->sc_ibuf = NULL; + sc->sc_ib = NULL; + sc->sc_ilen = 0; + } + + if(ista & ISAC_ISTA_RPF) /* receive fifo full */ + { + if(sc->sc_ibuf == NULL) + { + if((sc->sc_ibuf = i4b_Dgetmbuf(MAX_DFRAME_LEN)) != NULL) + sc->sc_ib= sc->sc_ibuf->m_data; + else + panic("ifpnp_isac_irq: RPF, i4b_Dgetmbuf returns NULL!\n"); + sc->sc_ilen = 0; + } + + if(sc->sc_ilen <= (MAX_DFRAME_LEN - ISAC_FIFO_LEN)) + { + ISAC_RDFIFO(sc->sc_ib, ISAC_FIFO_LEN); + sc->sc_ilen += ISAC_FIFO_LEN; + sc->sc_ib += ISAC_FIFO_LEN; + c |= ISAC_CMDR_RMC; + } + else + { + NDBGL1(L1_I_ERR, "RPF, input buffer overflow!"); + i4b_Dfreembuf(sc->sc_ibuf); + sc->sc_ibuf = NULL; + sc->sc_ib = NULL; + sc->sc_ilen = 0; + c |= ISAC_CMDR_RMC|ISAC_CMDR_RRES; + } + } + + if(ista & ISAC_ISTA_XPR) /* transmit fifo empty (XPR bit set) */ + { + if((sc->sc_obuf2 != NULL) && (sc->sc_obuf == NULL)) + { + sc->sc_freeflag = sc->sc_freeflag2; + sc->sc_obuf = sc->sc_obuf2; + sc->sc_op = sc->sc_obuf->m_data; + sc->sc_ol = sc->sc_obuf->m_len; + sc->sc_obuf2 = NULL; +#ifdef NOTDEF + printf("ob2=%x, op=%x, ol=%d, f=%d #", + sc->sc_obuf, + sc->sc_op, + sc->sc_ol, + sc->sc_state); +#endif + } + else + { +#ifdef NOTDEF + printf("ob=%x, op=%x, ol=%d, f=%d #", + sc->sc_obuf, + sc->sc_op, + sc->sc_ol, + sc->sc_state); +#endif + } + + if(sc->sc_obuf) + { + ISAC_WRFIFO(sc->sc_op, min(sc->sc_ol, ISAC_FIFO_LEN)); + + if(sc->sc_ol > ISAC_FIFO_LEN) /* length > 32 ? */ + { + sc->sc_op += ISAC_FIFO_LEN; /* bufferptr+32 */ + sc->sc_ol -= ISAC_FIFO_LEN; /* length - 32 */ + c |= ISAC_CMDR_XTF; /* set XTF bit */ + } + else + { + if(sc->sc_freeflag) + { + i4b_Dfreembuf(sc->sc_obuf); + sc->sc_freeflag = 0; + } + sc->sc_obuf = NULL; + sc->sc_op = NULL; + sc->sc_ol = 0; + + c |= ISAC_CMDR_XTF | ISAC_CMDR_XME; + } + } + else + { + sc->sc_state &= ~ISAC_TX_ACTIVE; + } + } + + if(ista & ISAC_ISTA_CISQ) /* channel status change CISQ */ + { + register u_char ci; + + /* get command/indication rx register*/ + + ci = ISAC_READ(I_CIRR); + + /* if S/Q IRQ, read SQC reg to clr SQC IRQ */ + + if(ci & ISAC_CIRR_SQC) + (void) ISAC_READ(I_SQRR); + + /* C/I code change IRQ (flag already cleared by CIRR read) */ + + if(ci & ISAC_CIRR_CIC0) + ifpnp_isac_ind_hdlr(sc, (ci >> 2) & 0xf); + } + + if(c) + { + ISAC_WRITE(I_CMDR, c); + ISACCMDRWRDELAY(); + } +} + +/*---------------------------------------------------------------------------* + * ISAC L1 Extended IRQ handler + *---------------------------------------------------------------------------*/ +static u_char +ifpnp_isac_exir_hdlr(register struct l1_softc *sc, u_char exir) +{ + u_char c = 0; + + if(exir & ISAC_EXIR_XMR) + { + NDBGL1(L1_I_ERR, "EXIRQ Tx Message Repeat"); + + c |= ISAC_CMDR_XRES; + } + + if(exir & ISAC_EXIR_XDU) + { + NDBGL1(L1_I_ERR, "EXIRQ Tx Data Underrun"); + + c |= ISAC_CMDR_XRES; + } + + if(exir & ISAC_EXIR_PCE) + { + NDBGL1(L1_I_ERR, "EXIRQ Protocol Error"); + } + + if(exir & ISAC_EXIR_RFO) + { + NDBGL1(L1_I_ERR, "EXIRQ Rx Frame Overflow"); + + c |= ISAC_CMDR_RMC|ISAC_CMDR_RRES; + } + + if(exir & ISAC_EXIR_SOV) + { + NDBGL1(L1_I_ERR, "EXIRQ Sync Xfer Overflow"); + } + + if(exir & ISAC_EXIR_MOS) + { + NDBGL1(L1_I_ERR, "EXIRQ Monitor Status"); + } + + if(exir & ISAC_EXIR_SAW) + { + /* cannot happen, STCR:TSF is set to 0 */ + + NDBGL1(L1_I_ERR, "EXIRQ Subscriber Awake"); + } + + if(exir & ISAC_EXIR_WOV) + { + /* cannot happen, STCR:TSF is set to 0 */ + + NDBGL1(L1_I_ERR, "EXIRQ Watchdog Timer Overflow"); + } + + return(c); +} + +/*---------------------------------------------------------------------------* + * ISAC L1 Indication handler + *---------------------------------------------------------------------------*/ +static void +ifpnp_isac_ind_hdlr(register struct l1_softc *sc, int ind) +{ + register int event; + + switch(ind) + { + case ISAC_CIRR_IAI8: + NDBGL1(L1_I_CICO, "rx AI8 in state %s", ifpnp_printstate(sc)); + if(sc->sc_bustyp == BUS_TYPE_IOM2) + ifpnp_isac_l1_cmd(sc, CMD_AR8); + event = EV_INFO48; + i4b_l1_mph_status_ind(L0IFPNPUNIT(sc->sc_unit), STI_L1STAT, LAYER_ACTIVE, NULL); + break; + + case ISAC_CIRR_IAI10: + NDBGL1(L1_I_CICO, "rx AI10 in state %s", ifpnp_printstate(sc)); + if(sc->sc_bustyp == BUS_TYPE_IOM2) + ifpnp_isac_l1_cmd(sc, CMD_AR10); + event = EV_INFO410; + i4b_l1_mph_status_ind(L0IFPNPUNIT(sc->sc_unit), STI_L1STAT, LAYER_ACTIVE, NULL); + break; + + case ISAC_CIRR_IRSY: + NDBGL1(L1_I_CICO, "rx RSY in state %s", ifpnp_printstate(sc)); + event = EV_RSY; + break; + + case ISAC_CIRR_IPU: + NDBGL1(L1_I_CICO, "rx PU in state %s", ifpnp_printstate(sc)); + event = EV_PU; + break; + + case ISAC_CIRR_IDR: + NDBGL1(L1_I_CICO, "rx DR in state %s", ifpnp_printstate(sc)); + ifpnp_isac_l1_cmd(sc, CMD_DIU); + event = EV_DR; + break; + + case ISAC_CIRR_IDID: + NDBGL1(L1_I_CICO, "rx DID in state %s", ifpnp_printstate(sc)); + event = EV_INFO0; + i4b_l1_mph_status_ind(L0IFPNPUNIT(sc->sc_unit), STI_L1STAT, LAYER_IDLE, NULL); + break; + + case ISAC_CIRR_IDIS: + NDBGL1(L1_I_CICO, "rx DIS in state %s", ifpnp_printstate(sc)); + event = EV_DIS; + break; + + case ISAC_CIRR_IEI: + NDBGL1(L1_I_CICO, "rx EI in state %s", ifpnp_printstate(sc)); + ifpnp_isac_l1_cmd(sc, CMD_DIU); + event = EV_EI; + break; + + case ISAC_CIRR_IARD: + NDBGL1(L1_I_CICO, "rx ARD in state %s", ifpnp_printstate(sc)); + event = EV_INFO2; + break; + + case ISAC_CIRR_ITI: + NDBGL1(L1_I_CICO, "rx TI in state %s", ifpnp_printstate(sc)); + event = EV_INFO0; + break; + + case ISAC_CIRR_IATI: + NDBGL1(L1_I_CICO, "rx ATI in state %s", ifpnp_printstate(sc)); + event = EV_INFO0; + break; + + case ISAC_CIRR_ISD: + NDBGL1(L1_I_CICO, "rx SD in state %s", ifpnp_printstate(sc)); + event = EV_INFO0; + break; + + default: + NDBGL1(L1_I_ERR, "UNKNOWN Indication 0x%x in state %s", ind, ifpnp_printstate(sc)); + event = EV_INFO0; + break; + } + ifpnp_next_state(sc, event); +} + +/*---------------------------------------------------------------------------* + * execute a layer 1 command + *---------------------------------------------------------------------------*/ +void +ifpnp_isac_l1_cmd(struct l1_softc *sc, int command) +{ + u_char cmd; + +#ifdef I4B_SMP_WORKAROUND + + /* XXXXXXXXXXXXXXXXXXX */ + + /* + * patch from Wolfgang Helbig: + * + * Here is a patch that makes i4b work on an SMP: + * The card (TELES 16.3) didn't interrupt on an SMP machine. + * This is a gross workaround, but anyway it works *and* provides + * some information as how to finally fix this problem. + */ + + HSCX_WRITE(0, H_MASK, 0xff); + HSCX_WRITE(1, H_MASK, 0xff); + ISAC_WRITE(I_MASK, 0xff); + DELAY(100); + HSCX_WRITE(0, H_MASK, HSCX_A_IMASK); + HSCX_WRITE(1, H_MASK, HSCX_B_IMASK); + ISAC_WRITE(I_MASK, ISAC_IMASK); + + /* XXXXXXXXXXXXXXXXXXX */ + +#endif /* I4B_SMP_WORKAROUND */ + + if(command < 0 || command > CMD_ILL) + { + NDBGL1(L1_I_ERR, "illegal cmd 0x%x in state %s", command, ifpnp_printstate(sc)); + return; + } + + if(sc->sc_bustyp == BUS_TYPE_IOM2) + cmd = ISAC_CIX0_LOW; + else + cmd = 0; + + switch(command) + { + case CMD_TIM: + NDBGL1(L1_I_CICO, "tx TIM in state %s", ifpnp_printstate(sc)); + cmd |= (ISAC_CIXR_CTIM << 2); + break; + + case CMD_RS: + NDBGL1(L1_I_CICO, "tx RS in state %s", ifpnp_printstate(sc)); + cmd |= (ISAC_CIXR_CRS << 2); + break; + + case CMD_AR8: + NDBGL1(L1_I_CICO, "tx AR8 in state %s", ifpnp_printstate(sc)); + cmd |= (ISAC_CIXR_CAR8 << 2); + break; + + case CMD_AR10: + NDBGL1(L1_I_CICO, "tx AR10 in state %s", ifpnp_printstate(sc)); + cmd |= (ISAC_CIXR_CAR10 << 2); + break; + + case CMD_DIU: + NDBGL1(L1_I_CICO, "tx DIU in state %s", ifpnp_printstate(sc)); + cmd |= (ISAC_CIXR_CDIU << 2); + break; + } + ISAC_WRITE(I_CIXR, cmd); +} + +/*---------------------------------------------------------------------------* + * L1 ISAC initialization + *---------------------------------------------------------------------------*/ +int +ifpnp_isac_init(struct l1_softc *sc) +{ + ISAC_IMASK = 0xff; /* disable all irqs */ + + ISAC_WRITE(I_MASK, ISAC_IMASK); + + if(sc->sc_bustyp != BUS_TYPE_IOM2) + { + NDBGL1(L1_I_SETUP, "configuring for IOM-1 mode"); + + /* ADF2: Select mode IOM-1 */ + ISAC_WRITE(I_ADF2, 0x00); + + /* SPCR: serial port control register: + * SPU - software power up = 0 + * SAC - SIP port high Z + * SPM - timing mode 0 + * TLP - test loop = 0 + * C1C, C2C - B1 and B2 switched to/from SPa + */ + ISAC_WRITE(I_SPCR, ISAC_SPCR_C1C1|ISAC_SPCR_C2C1); + + /* SQXR: S/Q channel xmit register: + * SQIE - S/Q IRQ enable = 0 + * SQX1-4 - Fa bits = 1 + */ + ISAC_WRITE(I_SQXR, ISAC_SQXR_SQX1|ISAC_SQXR_SQX2|ISAC_SQXR_SQX3|ISAC_SQXR_SQX4); + + /* ADF1: additional feature reg 1: + * WTC - watchdog = 0 + * TEM - test mode = 0 + * PFS - pre-filter = 0 + * CFS - IOM clock/frame always active + * FSC1/2 - polarity of 8kHz strobe + * ITF - interframe fill = idle + */ + ISAC_WRITE(I_ADF1, ISAC_ADF1_FC2); /* ADF1 */ + + /* STCR: sync transfer control reg: + * TSF - terminal secific functions = 0 + * TBA - TIC bus address = 7 + * STx/SCx = 0 + */ + ISAC_WRITE(I_STCR, ISAC_STCR_TBA2|ISAC_STCR_TBA1|ISAC_STCR_TBA0); + + /* MODE: Mode Register: + * MDSx - transparent mode 2 + * TMD - timer mode = external + * RAC - Receiver enabled + * DIMx - digital i/f mode + */ + ISAC_WRITE(I_MODE, ISAC_MODE_MDS2|ISAC_MODE_MDS1|ISAC_MODE_RAC|ISAC_MODE_DIM0); + } + else + { + NDBGL1(L1_I_SETUP, "configuring for IOM-2 mode"); + + /* ADF2: Select mode IOM-2 */ + ISAC_WRITE(I_ADF2, ISAC_ADF2_IMS); + + /* SPCR: serial port control register: + * SPU - software power up = 0 + * SPM - timing mode 0 + * TLP - test loop = 0 + * C1C, C2C - B1 + C1 and B2 + IC2 monitoring + */ + ISAC_WRITE(I_SPCR, 0x00); + + /* SQXR: S/Q channel xmit register: + * IDC - IOM direction = 0 (master) + * CFS - Config Select = 0 (clock always active) + * CI1E - C/I channel 1 IRQ enable = 0 + * SQIE - S/Q IRQ enable = 0 + * SQX1-4 - Fa bits = 1 + */ + ISAC_WRITE(I_SQXR, ISAC_SQXR_SQX1|ISAC_SQXR_SQX2|ISAC_SQXR_SQX3|ISAC_SQXR_SQX4); + + /* ADF1: additional feature reg 1: + * WTC - watchdog = 0 + * TEM - test mode = 0 + * PFS - pre-filter = 0 + * IOF - IOM i/f off = 0 + * ITF - interframe fill = idle + */ + ISAC_WRITE(I_ADF1, 0x00); + + /* STCR: sync transfer control reg: + * TSF - terminal secific functions = 0 + * TBA - TIC bus address = 7 + * STx/SCx = 0 + */ + ISAC_WRITE(I_STCR, ISAC_STCR_TBA2|ISAC_STCR_TBA1|ISAC_STCR_TBA0); + + /* MODE: Mode Register: + * MDSx - transparent mode 2 + * TMD - timer mode = external + * RAC - Receiver enabled + * DIMx - digital i/f mode + */ + ISAC_WRITE(I_MODE, ISAC_MODE_MDS2|ISAC_MODE_MDS1|ISAC_MODE_RAC|ISAC_MODE_DIM0); + } + +#ifdef NOTDEF + /* + * XXX a transmitter reset causes an ISAC tx IRQ which will not + * be serviced at attach time under some circumstances leaving + * the associated IRQ line on the ISA bus active. This prevents + * any further interrupts to be serviced because no low -> high + * transition can take place anymore. (-hm) + */ + + /* command register: + * RRES - HDLC receiver reset + * XRES - transmitter reset + */ + ISAC_WRITE(I_CMDR, ISAC_CMDR_RRES|ISAC_CMDR_XRES); + ISACCMDRWRDELAY(); +#endif + + /* enabled interrupts: + * =================== + * RME - receive message end + * RPF - receive pool full + * XPR - transmit pool ready + * CISQ - CI or S/Q channel change + * EXI - extended interrupt + */ + + ISAC_IMASK = ISAC_MASK_RSC | /* auto mode only */ + ISAC_MASK_TIN | /* timer irq */ + ISAC_MASK_SIN; /* sync xfer irq */ + + ISAC_WRITE(I_MASK, ISAC_IMASK); + + return(0); +} + +#endif /* NIFPNP > 0 */ diff --git a/sys/i4b/layer1/ifpnp/i4b_ifpnp_l1.c b/sys/i4b/layer1/ifpnp/i4b_ifpnp_l1.c new file mode 100644 index 0000000..3a90224 --- /dev/null +++ b/sys/i4b/layer1/ifpnp/i4b_ifpnp_l1.c @@ -0,0 +1,248 @@ +/* + * Copyright (c) 1997, 2000 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_ifpnp_l1.c - AVM Fritz PnP layer 1 handler + * ---------------------------------------------- + * + * $Id: i4b_ifpnp_l1.c,v 1.4 2000/06/02 16:14:36 hm Exp $ + * $Ust: src/i4b/layer1-nb/ifpnp/i4b_ifpnp_l1.c,v 1.4 2000/04/18 08:03:05 ust Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Fri Jun 2 14:55:49 2000] + * + *---------------------------------------------------------------------------*/ + +#include "ifpnp.h" + +#if (NIFPNP > 0) + +#include <sys/param.h> +#include <sys/kernel.h> +#include <sys/systm.h> +#include <sys/mbuf.h> +#include <sys/socket.h> + +#include <machine/stdarg.h> +#include <machine/clock.h> + +#include <net/if.h> + +#include <machine/i4b_debug.h> +#include <machine/i4b_ioctl.h> +#include <machine/i4b_trace.h> + +#include <i4b/layer1/isic/i4b_isic.h> +#include <i4b/layer1/isic/i4b_isac.h> +#include <i4b/layer1/isic/i4b_hscx.h> + +#include <i4b/layer1/ifpnp/i4b_ifpnp_ext.h> + +#include <i4b/layer1/i4b_l1.h> + +#include <i4b/include/i4b_mbuf.h> +#include <i4b/include/i4b_global.h> + +/*---------------------------------------------------------------------------* + * + * L2 -> L1: PH-DATA-REQUEST + * ========================= + * + * parms: + * unit physical interface unit number + * m mbuf containing L2 frame to be sent out + * freeflag MBUF_FREE: free mbuf here after having sent + * it out + * MBUF_DONTFREE: mbuf is freed by Layer 2 + * returns: + * ==0 fail, nothing sent out + * !=0 ok, frame sent out + * + *---------------------------------------------------------------------------*/ +int +ifpnp_ph_data_req(int unit, struct mbuf *m, int freeflag) +{ + u_char cmd; + int s; + struct l1_softc *sc = ifpnp_scp[unit]; + +#ifdef NOTDEF + NDBGL1(L1_PRIM, "PH-DATA-REQ, unit %d, freeflag=%d", unit, freeflag); +#endif + + if(m == NULL) /* failsafe */ + return (0); + + s = SPLI4B(); + + if(sc->sc_I430state == ST_F3) /* layer 1 not running ? */ + { + NDBGL1(L1_I_ERR, "still in state F3!"); + ifpnp_ph_activate_req(unit); + } + + if(sc->sc_state & ISAC_TX_ACTIVE) + { + if(sc->sc_obuf2 == NULL) + { + sc->sc_obuf2 = m; /* save mbuf ptr */ + + if(freeflag) + sc->sc_freeflag2 = 1; /* IRQ must mfree */ + else + sc->sc_freeflag2 = 0; /* IRQ must not mfree */ + + NDBGL1(L1_I_MSG, "using 2nd ISAC TX buffer, state = %s", ifpnp_printstate(sc)); + + if(sc->sc_trace & TRACE_D_TX) + { + i4b_trace_hdr_t hdr; + hdr.unit = L0IFPNPUNIT(unit); + hdr.type = TRC_CH_D; + hdr.dir = FROM_TE; + hdr.count = ++sc->sc_trace_dcount; + MICROTIME(hdr.time); + i4b_l1_trace_ind(&hdr, m->m_len, m->m_data); + } + splx(s); + return(1); + } + + NDBGL1(L1_I_ERR, "No Space in TX FIFO, state = %s", ifpnp_printstate(sc)); + + if(freeflag == MBUF_FREE) + i4b_Dfreembuf(m); + + splx(s); + return (0); + } + + if(sc->sc_trace & TRACE_D_TX) + { + i4b_trace_hdr_t hdr; + hdr.unit = L0IFPNPUNIT(unit); + hdr.type = TRC_CH_D; + hdr.dir = FROM_TE; + hdr.count = ++sc->sc_trace_dcount; + MICROTIME(hdr.time); + i4b_l1_trace_ind(&hdr, m->m_len, m->m_data); + } + + sc->sc_state |= ISAC_TX_ACTIVE; /* set transmitter busy flag */ + + NDBGL1(L1_I_MSG, "ISAC_TX_ACTIVE set"); + + sc->sc_freeflag = 0; /* IRQ must NOT mfree */ + + ISAC_WRFIFO(m->m_data, min(m->m_len, ISAC_FIFO_LEN)); /* output to TX fifo */ + + if(m->m_len > ISAC_FIFO_LEN) /* message > 32 bytes ? */ + { + sc->sc_obuf = m; /* save mbuf ptr */ + sc->sc_op = m->m_data + ISAC_FIFO_LEN; /* ptr for irq hdl */ + sc->sc_ol = m->m_len - ISAC_FIFO_LEN; /* length for irq hdl */ + + if(freeflag) + sc->sc_freeflag = 1; /* IRQ must mfree */ + + cmd = ISAC_CMDR_XTF; + } + else + { + sc->sc_obuf = NULL; + sc->sc_op = NULL; + sc->sc_ol = 0; + + if(freeflag) + i4b_Dfreembuf(m); + + cmd = ISAC_CMDR_XTF | ISAC_CMDR_XME; + } + + ISAC_WRITE(I_CMDR, cmd); + ISACCMDRWRDELAY(); + + splx(s); + + return(1); +} + +/*---------------------------------------------------------------------------* + * + * L2 -> L1: PH-ACTIVATE-REQUEST + * ============================= + * + * parms: + * unit physical interface unit number + * + * returns: + * ==0 + * !=0 + * + *---------------------------------------------------------------------------*/ +int +ifpnp_ph_activate_req(int unit) +{ + struct l1_softc *sc = ifpnp_scp[unit]; + NDBGL1(L1_PRIM, "PH-ACTIVATE-REQ, unit %d\n", unit); + ifpnp_next_state(sc, EV_PHAR); + return(0); +} + +/*---------------------------------------------------------------------------* + * command from the upper layers + *---------------------------------------------------------------------------*/ +int +ifpnp_mph_command_req(int unit, int command, void *parm) +{ + struct l1_softc *sc = ifpnp_scp[unit]; + + switch(command) + { + case CMR_DOPEN: /* daemon running */ + NDBGL1(L1_PRIM, "unit %d, command = CMR_DOPEN", unit); + sc->sc_enabled = 1; + break; + + case CMR_DCLOSE: /* daemon not running */ + NDBGL1(L1_PRIM, "unit %d, command = CMR_DCLOSE", unit); + sc->sc_enabled = 0; + break; + + case CMR_SETTRACE: + NDBGL1(L1_PRIM, "unit %d, command = CMR_SETTRACE, parm = %d", unit, (unsigned int)parm); + sc->sc_trace = (unsigned int)parm; + break; + + default: + NDBGL1(L1_ERROR, "ERROR, unknown command = %d, unit = %d, parm = %d", command, unit, (unsigned int)parm); + break; + } + + return(0); +} + +#endif /* NIFPNP > 0 */ diff --git a/sys/i4b/layer1/ifpnp/i4b_ifpnp_l1fsm.c b/sys/i4b/layer1/ifpnp/i4b_ifpnp_l1fsm.c new file mode 100644 index 0000000..c3bc5e9 --- /dev/null +++ b/sys/i4b/layer1/ifpnp/i4b_ifpnp_l1fsm.c @@ -0,0 +1,522 @@ +/* + * Copyright (c) 1997, 2000 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_ifpnp_l1fsm.c - AVM Fritz PnP layer 1 I.430 state machine + * ------------------------------------------------------------- + * + * $Id: i4b_ifpnp_l1fsm.c,v 1.4 2000/05/29 15:41:41 hm Exp $ + * $Ust: src/i4b/layer1-nb/ifpnp/i4b_ifpnp_l1fsm.c,v 1.4 2000/04/18 08:03:05 ust Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Mon May 29 15:25:04 2000] + * + *---------------------------------------------------------------------------*/ + +#include "ifpnp.h" + +#if (NIFPNP > 0) + +#include <sys/param.h> +#include <sys/kernel.h> +#include <sys/systm.h> +#include <sys/mbuf.h> +#include <sys/socket.h> + +#include <machine/stdarg.h> +#include <machine/clock.h> + +#include <net/if.h> + +#include <machine/i4b_debug.h> +#include <machine/i4b_ioctl.h> +#include <machine/i4b_trace.h> + +#include <i4b/layer1/isic/i4b_isic.h> +#include <i4b/layer1/isic/i4b_isac.h> +#include <i4b/layer1/isic/i4b_hscx.h> + +#include <i4b/layer1/i4b_l1.h> + +#include <i4b/include/i4b_global.h> + +#include <i4b/include/i4b_mbuf.h> + +#include <i4b/layer1/ifpnp/i4b_ifpnp_ext.h> + +#if DO_I4B_DEBUG +static char *state_text[N_STATES] = { + "F3 Deactivated", + "F4 Awaiting Signal", + "F5 Identifying Input", + "F6 Synchronized", + "F7 Activated", + "F8 Lost Framing", + "Illegal State" +}; + +static char *event_text[N_EVENTS] = { + "EV_PHAR PH_ACT_REQ", + "EV_T3 Timer 3 expired", + "EV_INFO0 INFO0 received", + "EV_RSY Level Detected", + "EV_INFO2 INFO2 received", + "EV_INFO48 INFO4 received", + "EV_INFO410 INFO4 received", + "EV_DR Deactivate Req", + "EV_PU Power UP", + "EV_DIS Disconnected", + "EV_EI Error Ind", + "Illegal Event" +}; +#endif + +/* Function prototypes */ + +static void timer3_expired (struct l1_softc *sc); +static void T3_start (struct l1_softc *sc); +static void T3_stop (struct l1_softc *sc); +static void F_T3ex (struct l1_softc *sc); +static void timer4_expired (struct l1_softc *sc); +static void T4_start (struct l1_softc *sc); +static void T4_stop (struct l1_softc *sc); +static void F_AI8 (struct l1_softc *sc); +static void F_AI10 (struct l1_softc *sc); +static void F_I01 (struct l1_softc *sc); +static void F_I02 (struct l1_softc *sc); +static void F_I03 (struct l1_softc *sc); +static void F_I2 (struct l1_softc *sc); +static void F_ill (struct l1_softc *sc); +static void F_NULL (struct l1_softc *sc); + +/*---------------------------------------------------------------------------* + * I.430 Timer T3 expire function + *---------------------------------------------------------------------------*/ +static void +timer3_expired(struct l1_softc *sc) +{ + if(sc->sc_I430T3) + { + NDBGL1(L1_T_ERR, "state = %s", ifpnp_printstate(sc)); + sc->sc_I430T3 = 0; + + /* XXX try some recovery here XXX */ + + ifpnp_recover(sc); + + sc->sc_init_tries++; /* increment retry count */ + +/*XXX*/ if(sc->sc_init_tries > 4) + { + int s = SPLI4B(); + + sc->sc_init_tries = 0; + + if(sc->sc_obuf2 != NULL) + { + i4b_Dfreembuf(sc->sc_obuf2); + sc->sc_obuf2 = NULL; + } + if(sc->sc_obuf != NULL) + { + i4b_Dfreembuf(sc->sc_obuf); + sc->sc_obuf = NULL; + sc->sc_freeflag = 0; + sc->sc_op = NULL; + sc->sc_ol = 0; + } + + splx(s); + + i4b_l1_mph_status_ind(L0IFPNPUNIT(sc->sc_unit), STI_NOL1ACC, 0, NULL); + } + + ifpnp_next_state(sc, EV_T3); + } + else + { + NDBGL1(L1_T_ERR, "expired without starting it ...."); + } +} + +/*---------------------------------------------------------------------------* + * I.430 Timer T3 start + *---------------------------------------------------------------------------*/ +static void +T3_start(struct l1_softc *sc) +{ + NDBGL1(L1_T_MSG, "state = %s", ifpnp_printstate(sc)); + sc->sc_I430T3 = 1; + sc->sc_T3_callout = timeout((TIMEOUT_FUNC_T)timer3_expired,(struct l1_softc *)sc, 2*hz); +} + +/*---------------------------------------------------------------------------* + * I.430 Timer T3 stop + *---------------------------------------------------------------------------*/ +static void +T3_stop(struct l1_softc *sc) +{ + NDBGL1(L1_T_MSG, "state = %s", ifpnp_printstate(sc)); + + sc->sc_init_tries = 0; /* init connect retry count */ + + if(sc->sc_I430T3) + { + sc->sc_I430T3 = 0; + untimeout((TIMEOUT_FUNC_T)timer3_expired,(struct l1_softc *)sc, sc->sc_T3_callout); + } +} + +/*---------------------------------------------------------------------------* + * I.430 Timer T3 expiry + *---------------------------------------------------------------------------*/ +static void +F_T3ex(struct l1_softc *sc) +{ + NDBGL1(L1_F_MSG, "FSM function F_T3ex executing"); + if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S) + i4b_l1_ph_deactivate_ind(L0IFPNPUNIT(sc->sc_unit)); +} + +/*---------------------------------------------------------------------------* + * Timer T4 expire function + *---------------------------------------------------------------------------*/ +static void +timer4_expired(struct l1_softc *sc) +{ + if(sc->sc_I430T4) + { + NDBGL1(L1_T_MSG, "state = %s", ifpnp_printstate(sc)); + sc->sc_I430T4 = 0; + i4b_l1_mph_status_ind(L0IFPNPUNIT(sc->sc_unit), STI_PDEACT, 0, NULL); + } + else + { + NDBGL1(L1_T_ERR, "expired without starting it ...."); + } +} + +/*---------------------------------------------------------------------------* + * Timer T4 start + *---------------------------------------------------------------------------*/ +static void +T4_start(struct l1_softc *sc) +{ + NDBGL1(L1_T_MSG, "state = %s", ifpnp_printstate(sc)); + sc->sc_I430T4 = 1; + sc->sc_T4_callout = timeout((TIMEOUT_FUNC_T)timer4_expired,(struct l1_softc *)sc, hz); +} + +/*---------------------------------------------------------------------------* + * Timer T4 stop + *---------------------------------------------------------------------------*/ +static void +T4_stop(struct l1_softc *sc) +{ + NDBGL1(L1_T_MSG, "state = %s", ifpnp_printstate(sc)); + + if(sc->sc_I430T4) + { + sc->sc_I430T4 = 0; + untimeout((TIMEOUT_FUNC_T)timer4_expired,(struct l1_softc *)sc, sc->sc_T4_callout); + } +} + +/*---------------------------------------------------------------------------* + * FSM function: received AI8 + *---------------------------------------------------------------------------*/ +static void +F_AI8(struct l1_softc *sc) +{ + T4_stop(sc); + + NDBGL1(L1_F_MSG, "FSM function F_AI8 executing"); + + if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S) + i4b_l1_ph_activate_ind(L0IFPNPUNIT(sc->sc_unit)); + + T3_stop(sc); + + if(sc->sc_trace & TRACE_I) + { + i4b_trace_hdr_t hdr; + char info = INFO4_8; + + hdr.unit = L0IFPNPUNIT(sc->sc_unit); + hdr.type = TRC_CH_I; + hdr.dir = FROM_NT; + hdr.count = 0; + MICROTIME(hdr.time); + i4b_l1_trace_ind(&hdr, 1, &info); + } +} + +/*---------------------------------------------------------------------------* + * FSM function: received AI10 + *---------------------------------------------------------------------------*/ +static void +F_AI10(struct l1_softc *sc) +{ + T4_stop(sc); + + NDBGL1(L1_F_MSG, "FSM function F_AI10 executing"); + + if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S) + i4b_l1_ph_activate_ind(L0IFPNPUNIT(sc->sc_unit)); + + T3_stop(sc); + + if(sc->sc_trace & TRACE_I) + { + i4b_trace_hdr_t hdr; + char info = INFO4_10; + + hdr.unit = L0IFPNPUNIT(sc->sc_unit); + hdr.type = TRC_CH_I; + hdr.dir = FROM_NT; + hdr.count = 0; + MICROTIME(hdr.time); + i4b_l1_trace_ind(&hdr, 1, &info); + } +} + +/*---------------------------------------------------------------------------* + * FSM function: received INFO 0 in states F3 .. F5 + *---------------------------------------------------------------------------*/ +static void +F_I01(struct l1_softc *sc) +{ + NDBGL1(L1_F_MSG, "FSM function F_I01 executing"); + + if(sc->sc_trace & TRACE_I) + { + i4b_trace_hdr_t hdr; + char info = INFO0; + + hdr.unit = L0IFPNPUNIT(sc->sc_unit); + hdr.type = TRC_CH_I; + hdr.dir = FROM_NT; + hdr.count = 0; + MICROTIME(hdr.time); + i4b_l1_trace_ind(&hdr, 1, &info); + } +} + +/*---------------------------------------------------------------------------* + * FSM function: received INFO 0 in state F6 + *---------------------------------------------------------------------------*/ +static void +F_I02(struct l1_softc *sc) +{ + NDBGL1(L1_F_MSG, "FSM function F_I02 executing"); + + if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S) + i4b_l1_ph_deactivate_ind(L0IFPNPUNIT(sc->sc_unit)); + + if(sc->sc_trace & TRACE_I) + { + i4b_trace_hdr_t hdr; + char info = INFO0; + + hdr.unit = L0IFPNPUNIT(sc->sc_unit); + hdr.type = TRC_CH_I; + hdr.dir = FROM_NT; + hdr.count = 0; + MICROTIME(hdr.time); + i4b_l1_trace_ind(&hdr, 1, &info); + } +} + +/*---------------------------------------------------------------------------* + * FSM function: received INFO 0 in state F7 or F8 + *---------------------------------------------------------------------------*/ +static void +F_I03(struct l1_softc *sc) +{ + NDBGL1(L1_F_MSG, "FSM function F_I03 executing"); + + if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S) + i4b_l1_ph_deactivate_ind(L0IFPNPUNIT(sc->sc_unit)); + + T4_start(sc); + + if(sc->sc_trace & TRACE_I) + { + i4b_trace_hdr_t hdr; + char info = INFO0; + + hdr.unit = L0IFPNPUNIT(sc->sc_unit); + hdr.type = TRC_CH_I; + hdr.dir = FROM_NT; + hdr.count = 0; + MICROTIME(hdr.time); + i4b_l1_trace_ind(&hdr, 1, &info); + } +} + +/*---------------------------------------------------------------------------* + * FSM function: activate request + *---------------------------------------------------------------------------*/ +static void +F_AR(struct l1_softc *sc) +{ + NDBGL1(L1_F_MSG, "FSM function F_AR executing"); + + if(sc->sc_trace & TRACE_I) + { + i4b_trace_hdr_t hdr; + char info = INFO1_8; + + hdr.unit = L0IFPNPUNIT(sc->sc_unit); + hdr.type = TRC_CH_I; + hdr.dir = FROM_TE; + hdr.count = 0; + MICROTIME(hdr.time); + i4b_l1_trace_ind(&hdr, 1, &info); + } + + ifpnp_isac_l1_cmd(sc, CMD_AR8); + + T3_start(sc); +} + +/*---------------------------------------------------------------------------* + * FSM function: received INFO2 + *---------------------------------------------------------------------------*/ +static void +F_I2(struct l1_softc *sc) +{ + NDBGL1(L1_F_MSG, "FSM function F_I2 executing"); + + if(sc->sc_trace & TRACE_I) + { + i4b_trace_hdr_t hdr; + char info = INFO2; + + hdr.unit = L0IFPNPUNIT(sc->sc_unit); + hdr.type = TRC_CH_I; + hdr.dir = FROM_NT; + hdr.count = 0; + MICROTIME(hdr.time); + i4b_l1_trace_ind(&hdr, 1, &info); + } + +} + +/*---------------------------------------------------------------------------* + * illegal state default action + *---------------------------------------------------------------------------*/ +static void +F_ill(struct l1_softc *sc) +{ + NDBGL1(L1_F_ERR, "FSM function F_ill executing"); +} + +/*---------------------------------------------------------------------------* + * No action + *---------------------------------------------------------------------------*/ +static void +F_NULL(struct l1_softc *sc) +{ + NDBGL1(L1_F_MSG, "FSM function F_NULL executing"); +} + + +/*---------------------------------------------------------------------------* + * layer 1 state transition table + *---------------------------------------------------------------------------*/ +struct ifpnp_state_tab { + void (*func) (struct l1_softc *sc); /* function to execute */ + int newstate; /* next state */ +} ifpnp_state_tab[N_EVENTS][N_STATES] = { + +/* STATE: F3 F4 F5 F6 F7 F8 ILLEGAL STATE */ +/* -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* EV_PHAR x*/ {{F_AR, ST_F4}, {F_NULL, ST_F4}, {F_NULL, ST_F5}, {F_NULL, ST_F6}, {F_ill, ST_ILL}, {F_NULL, ST_F8}, {F_ill, ST_ILL}}, +/* EV_T3 x*/ {{F_NULL, ST_F3}, {F_T3ex, ST_F3}, {F_T3ex, ST_F3}, {F_T3ex, ST_F3}, {F_NULL, ST_F7}, {F_NULL, ST_F8}, {F_ill, ST_ILL}}, +/* EV_INFO0 */ {{F_I01, ST_F3}, {F_I01, ST_F4}, {F_I01, ST_F5}, {F_I02, ST_F3}, {F_I03, ST_F3}, {F_I03, ST_F3}, {F_ill, ST_ILL}}, +/* EV_RSY x*/ {{F_NULL, ST_F3}, {F_NULL, ST_F5}, {F_NULL, ST_F5}, {F_NULL, ST_F8}, {F_NULL, ST_F8}, {F_NULL, ST_F8}, {F_ill, ST_ILL}}, +/* EV_INFO2 */ {{F_I2, ST_F6}, {F_I2, ST_F6}, {F_I2, ST_F6}, {F_I2, ST_F6}, {F_I2, ST_F6}, {F_I2, ST_F6}, {F_ill, ST_ILL}}, +/* EV_INFO48*/ {{F_AI8, ST_F7}, {F_AI8, ST_F7}, {F_AI8, ST_F7}, {F_AI8, ST_F7}, {F_NULL, ST_F7}, {F_AI8, ST_F7}, {F_ill, ST_ILL}}, +/* EV_INFO41*/ {{F_AI10, ST_F7}, {F_AI10, ST_F7}, {F_AI10, ST_F7}, {F_AI10, ST_F7}, {F_NULL, ST_F7}, {F_AI10, ST_F7}, {F_ill, ST_ILL}}, +/* EV_DR */ {{F_NULL, ST_F3}, {F_NULL, ST_F4}, {F_NULL, ST_F5}, {F_NULL, ST_F6}, {F_NULL, ST_F7}, {F_NULL, ST_F8}, {F_ill, ST_ILL}}, +/* EV_PU */ {{F_NULL, ST_F3}, {F_NULL, ST_F4}, {F_NULL, ST_F5}, {F_NULL, ST_F6}, {F_NULL, ST_F7}, {F_NULL, ST_F8}, {F_ill, ST_ILL}}, +/* EV_DIS */ {{F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}}, +/* EV_EI */ {{F_NULL, ST_F3}, {F_NULL, ST_F3}, {F_NULL, ST_F3}, {F_NULL, ST_F3}, {F_NULL, ST_F3}, {F_NULL, ST_F3}, {F_ill, ST_ILL}}, +/* EV_ILL */ {{F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}} +}; + +/*---------------------------------------------------------------------------* + * event handler + *---------------------------------------------------------------------------*/ +void +ifpnp_next_state(struct l1_softc *sc, int event) +{ + int currstate, newstate; + + if(event >= N_EVENTS) + panic("i4b_l1fsm.c: event >= N_EVENTS\n"); + + currstate = sc->sc_I430state; + + if(currstate >= N_STATES) + panic("i4b_l1fsm.c: currstate >= N_STATES\n"); + + newstate = ifpnp_state_tab[event][currstate].newstate; + + if(newstate >= N_STATES) + panic("i4b_l1fsm.c: newstate >= N_STATES\n"); + + NDBGL1(L1_F_MSG, "FSM event [%s]: [%s => %s]", event_text[event], + state_text[currstate], + state_text[newstate]); + + (*ifpnp_state_tab[event][currstate].func)(sc); + + if(newstate == ST_ILL) + { + newstate = ST_F3; + NDBGL1(L1_F_ERR, "FSM Illegal State ERROR, oldstate = %s, newstate = %s, event = %s!", + state_text[currstate], + state_text[newstate], + event_text[event]); + } + + sc->sc_I430state = newstate; +} + +#if DO_I4B_DEBUG +/*---------------------------------------------------------------------------* + * return pointer to current state description + *---------------------------------------------------------------------------*/ +char * +ifpnp_printstate(struct l1_softc *sc) +{ + return((char *) state_text[sc->sc_I430state]); +} +#endif + +#endif /* NIFPNP > 0 */ diff --git a/sys/i4b/layer1/ihfc/i4b_ihfc.h b/sys/i4b/layer1/ihfc/i4b_ihfc.h new file mode 100644 index 0000000..1036636 --- /dev/null +++ b/sys/i4b/layer1/ihfc/i4b_ihfc.h @@ -0,0 +1,337 @@ +/* + * Copyright (c) 2000 Hans Petter Selasky. 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_ihfc.h - ihfc common header file + * ------------------------------------ + * + * last edit-date: [Wed Jul 19 09:40:45 2000] + * + * $Id: i4b_ihfc.h,v 1.9 2000/09/19 13:50:36 hm Exp $ + * + * $FreeBSD$ + * + *---------------------------------------------------------------------------*/ + +#ifndef _I4B_IHFC_H_ +#define _I4B_IHFC_H_ + +#include <i4b/include/i4b_l3l4.h> + +/*---------------------------------------------------------------------------* + * global stuff (HFC-1/S/SP) + *---------------------------------------------------------------------------*/ +#define DCH_MAX_LEN 264 /* max length of a D frame */ + +#define IHFC_ACTIVATION_TIMEOUT 3*hz /* S0-bus must activate before this time */ + +#define IHFC_IO_BASES 1 + +#define IHFC_DISBUSYTO 500 /* do at least 500 inb's before giving up */ +#define IHFC_NONBUSYTO 8000 /* do at least 8000 inb's before giving up */ + +#define IHFC_NTMODE 0 /* use TE-mode as default */ +#define IHFC_DLP 0 /* use (8/9) priority as default */ + +#define IHFC_MAXUNIT 4 + +/* #define IHFC_DEBUG internal debugging enabled * + * #undef IHFC_DEBUG internal debugging disabled */ + +/* chan: * + * 0 - D1 (tx) * + * 1 - D1 (rx) * + * 2 - B1 (tx) * + * 3 - B1 (rx) * + * 4 - B2 (tx) * + * 5 - B2 (rx) */ + +#define HFC_1 0x01 /* HFC 2B */ +#define HFC_S 0x02 /* HFC - S 2BDS0 */ +#define HFC_SP 0x04 /* HFC - SP 2BDS0 */ +#define HFC_SPCI 0x08 /* HFC - SPCI 2BDS0 X */ +#define HFC_S2M 0x10 /* HFC - S2M 2BDS0 X */ +#define HFC_USB 0x20 /* HFC - USB 2BDS0 X */ + +/*---------------------------------------------------------------------------* + * "Help Fix Corruption" macros (HFC-1/S/SP) + * + * NOTE: If the code does not run at splhigh, we will sporadically + * lose bytes. On fast PC's (200 Mhz), this is very little noticable. + *---------------------------------------------------------------------------*/ +#define HFC_VAR int _s_ /* declare variable */ +#define HFC_BEG _s_ = splhigh() /* save spl */ +#define HFC_END splx(_s_) /* restore spl */ + +/*---------------------------------------------------------------------------* + * macros related to i4b linking (HFC-1/S/SP) + *---------------------------------------------------------------------------*/ +#define S_BLINK sc->sc_blinktab[(chan > 3) ? 1 : 0] +#define S_BDRVLINK sc->sc_bdrvlinktab[(chan > 3) ? 1 : 0] + +/*---------------------------------------------------------------------------* + * macros related to ihfc_sc (HFC-1/S/SP) + *---------------------------------------------------------------------------*/ + +/* statemachine */ + +#define S_IOM2 (sc->sc_config.i_adf2 & 0x80) + /* 0x80: IOM2 mode selected */ + +#define S_DLP (sc->sc_config.dlp) +#define S_NTMODE (sc->sc_config.ntmode) +#define S_STDEL (sc->sc_config.stdel) + +#define S_PHSTATE sc->sc_statemachine.state +#define S_STM_T3 sc->sc_statemachine.T3 +#define S_STM_T3CALLOUT sc->sc_statemachine.T3callout + +/* unitnumbers */ + +#define S_UNIT sc->sc_unit +#define S_FLAG sc->sc_flag +#define S_I4BUNIT sc->sc_i4bunit +#define S_I4BFLAG sc->sc_i4bflag + +/* ISA bus setup */ + +#define S_IOBASE sc->sc_resources.io_base +#define S_IORID sc->sc_resources.io_rid +#define S_IRQ sc->sc_resources.irq +#define S_IRQRID sc->sc_resources.irq_rid + +/* hardware setup */ + +#define S_HFC sc->sc_config.chiptype +#define S_IIO sc->sc_config.iio +#define S_IIRQ sc->sc_config.iirq + +/* registers of the HFC-S/SP (write only) */ + +#define S_HFC_CONFIG sc->sc_config.cirm + +#define S_CIRM sc->sc_config.cirm +#define S_CTMT sc->sc_config.ctmt +#define S_TEST sc->sc_config.test +#define S_SCTRL sc->sc_config.sctrl +#define S_CLKDEL sc->sc_config.clkdel +#define S_INT_M1 sc->sc_config.int_m1 +#define S_INT_M2 sc->sc_config.int_m2 +#define S_CONNECT sc->sc_config.connect +#define S_SCTRL_R sc->sc_config.sctrl_r +#define S_MST_MODE sc->sc_config.mst_mode + +/* registers of the HFC-S/SP (read only) */ + +#define S_INT_S1 sc->sc_config.int_s1 + +/* registers of the ISAC (write only) */ + +#define S_ISAC_CONFIG sc->sc_config.i_adf2 + +#define S_ADF1 sc->sc_config.i_adf1 +#define S_ADF2 sc->sc_config.i_adf2 +#define S_MASK sc->sc_config.i_mask +#define S_MODE sc->sc_config.i_mode +#define S_SPCR sc->sc_config.i_spcr +#define S_SQXR sc->sc_config.i_sqxr +#define S_STCR sc->sc_config.i_stcr +#define S_STAR2 sc->sc_config.i_star2 + +/* registers of the ISAC (read only) */ + +#define S_ISTA sc->sc_config.i_ista + +/* state of the softc */ + +#define S_ENABLED sc->sc_enabled +#define S_INTR_ACTIVE sc->sc_intr_active + +/* SOFT-HDLC */ + +#define S_HDLC_IB sc->sc_fifo.chan[chan].hdlc.ib /* u_short */ +#define S_HDLC_CRC sc->sc_fifo.chan[chan].hdlc.crc /* u_short */ +#define S_HDLC_TMP sc->sc_fifo.chan[chan].hdlc.tmp /* u_int */ +#define S_HDLC_FLAG sc->sc_fifo.chan[chan].hdlc.flag /* u_char */ +#define S_HDLC_BLEVEL sc->sc_fifo.chan[chan].hdlc.blevel /* u_short */ + +/* stats */ + +#define S_BYTES sc->sc_fifo.chan[chan].bytes + +/* "Z"-values */ + +#define S_HDLC_DZ_TAB sc->sc_fifo.dztable + +/* filters */ + +#define S_PROT sc->sc_fifo.chan[chan].prot +#define S_FILTER sc->sc_fifo.chan[chan].filter +#define S_ACTIVITY sc->sc_fifo.chan[chan].activity +#define S_LAST_CHAN sc->sc_fifo.last_chan + +/* soft reset */ + +#define RESET_SOFT_CHAN(sc, chan) bzero(&sc->sc_fifo.chan[chan], sizeof(sc->sc_fifo.chan[0])) + +/* trace */ + +#define S_TRACE sc->sc_trace +#define S_DTRACECOUNT sc->sc_Dtracecount +#define S_BTRACECOUNT sc->sc_Btracecount + +/* mbuf */ + +#define S_MBUF sc->sc_fifo.chan[chan].buffer.mbuf +#define S_MBUFDUMMY sc->sc_fifo.chan[chan].buffer.mbufdummy +#define S_MBUFLEN sc->sc_fifo.chan[chan].buffer.mbuf->m_len +#define S_MBUFPKTHDR sc->sc_fifo.chan[chan].buffer.mbuf->m_pkthdr +#define S_MBUFDATA sc->sc_fifo.chan[chan].buffer.mbuf->m_data +#define S_MBUFDAT sc->sc_fifo.chan[chan].buffer.mbuf->m_dat + +#define S_IFQUEUE sc->sc_fifo.chan[chan].buffer.ifqueue + +/* hfc control */ + +#define HFC_INIT ihfc_init +#define HFC_INTR ((S_HFC & HFC_1) ? ihfc_intr1 : ihfc_intr2) +#define HFC_FSM ihfc_fsm +#define HFC_CONTROL ihfc_control + +/* softc parts */ + +struct ihfc_sc; + +struct sc_resources { + struct resource * io_base[IHFC_IO_BASES]; + int io_rid [IHFC_IO_BASES]; + struct resource * irq; + int irq_rid; +}; + +struct hdlc { + u_char flag; + u_short blevel; + u_short crc; + u_short ib; + u_int tmp; +}; + +struct buffer { + struct ifqueue ifqueue; /* data queue */ + struct mbuf *mbuf; /* current mbuf */ + struct mbuf *mbufdummy; /* temporary */ +}; + +struct chan { + struct hdlc hdlc; + u_int bytes; + u_int prot; + struct buffer buffer; + void (*filter)(struct ihfc_sc *sc, u_char chan); +}; + +struct sc_fifo { + struct chan chan[6]; + u_short dztable[16]; + u_char last_chan; +}; + +struct sc_config { + /* software only: */ + + u_short chiptype; /* chiptype (eg. HFC_1) */ + u_char dlp; /* D-priority */ + u_short iio; /* internal IO */ + u_char iirq; /* internal IRQ */ + u_char ntmode; /* mode */ + u_char stdel; /* S/T delay */ + + /* write only: */ + u_char cirm; + u_char ctmt; + u_char int_m1; + u_char int_m2; + u_char mst_mode; + u_char clkdel; + u_char sctrl; + u_char connect; + u_char test; + u_char sctrl_r; + + /* isac write only - hfc-1: */ + u_char i_adf2; + u_char i_spcr; + u_char i_sqxr; + u_char i_adf1; + u_char i_stcr; + u_char i_mode; + u_char i_mask; + u_char i_star2; + + /* read only: */ + u_char int_s1; + + /* isac read only - hfc-1: */ + u_char i_ista; +}; + +struct sc_statemachine { + u_char state; /* see i4b_ihfc_drv.h */ + u_char usync; + u_char T3; /* T3 running */ + struct callout_handle T3callout; +}; + +/*---------------------------------------------------------------------------* + * HFC softc + *---------------------------------------------------------------------------*/ +typedef struct ihfc_sc +{ int sc_unit; + int sc_flag; + + int sc_i4bunit; /* L0IHFCUNIT(sc_unit) */ + int sc_i4bflag; /* FLAG_TEL_S0_16_3C .. */ + + u_char sc_enabled; /* daemon running if set */ + u_char sc_intr_active; /* interrupt is active */ + + int sc_trace; + u_int sc_Btracecount; + u_int sc_Dtracecount; + + struct sc_config sc_config; + struct sc_resources sc_resources; + struct sc_statemachine sc_statemachine; + + isdn_link_t sc_blinktab[2]; + drvr_link_t *sc_bdrvlinktab[2]; + + struct sc_fifo sc_fifo; +} ihfc_sc_t; + +extern ihfc_sc_t ihfc_softc[]; + +#endif /* _I4B_IHFC_H_ */ diff --git a/sys/i4b/layer1/ihfc/i4b_ihfc_drv.c b/sys/i4b/layer1/ihfc/i4b_ihfc_drv.c new file mode 100644 index 0000000..bd56be2 --- /dev/null +++ b/sys/i4b/layer1/ihfc/i4b_ihfc_drv.c @@ -0,0 +1,1743 @@ +/* + * Copyright (c) 2000 Hans Petter Selasky. 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_ihfc_drv.c - ihfc ISA PnP-bus interface + * ------------------------------------------- + * + * Everything which has got anything to do with the + * HFC-1/S/SP chips has been put here. + * + * last edit-date: [Wed Jul 19 09:39:42 2000] + * + * $Id: i4b_ihfc_drv.c,v 1.11 2000/09/19 13:50:36 hm Exp $ + * + * $FreeBSD$ + * + *---------------------------------------------------------------------------*/ + +#include "ihfc.h" + +#if (NIHFC > 0) + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/socket.h> +#include <net/if.h> + +#include <sys/mbuf.h> +#include <machine/clock.h> + +#include <i4b/include/i4b_global.h> +#include <i4b/include/i4b_mbuf.h> +#include <i4b/include/i4b_l1l2.h> + +#include <machine/i4b_debug.h> +#include <machine/i4b_ioctl.h> +#include <machine/i4b_trace.h> + +#include <i4b/layer1/i4b_l1.h> +#include <i4b/layer1/i4b_hdlc.h> +#include <i4b/layer1/ihfc/i4b_ihfc.h> +#include <i4b/layer1/ihfc/i4b_ihfc_ext.h> +#include <i4b/layer1/ihfc/i4b_ihfc_drv.h> + +#include <machine/bus.h> +#include <machine/resource.h> +#include <sys/bus.h> +#include <sys/rman.h> + +#include <isa/isavar.h> + +/*---------------------------------------------------------------------------* + * Local prototypes + *---------------------------------------------------------------------------*/ + void ihfc_loadconfig (ihfc_sc_t *sc); + +static void ihfc_trans_Bread (ihfc_sc_t *sc, u_char chan); +static void ihfc_trans_Bwrite (ihfc_sc_t *sc, u_char chan); +static void ihfc_hdlc_Bread (ihfc_sc_t *sc, u_char chan); +static void ihfc_hdlc_Bwrite (ihfc_sc_t *sc, u_char chan); +static void ihfc_hdlc_Dread (ihfc_sc_t *sc, u_char chan); +static void ihfc_hdlc_Dwrite (ihfc_sc_t *sc, u_char chan); + +static void ihfc_isac_Dread (ihfc_sc_t *sc, u_char chan); +static void ihfc_isac_Dwrite (ihfc_sc_t *sc, u_char chan); + + void ihfc_cmdr_hdlr (ihfc_sc_t *sc, u_char cmdr); + void ihfc_exir_hdlr (ihfc_sc_t *sc, u_char exir); + + void ihfc_sq (ihfc_sc_t *sc); + +static void ihfc_test_Bread (ihfc_sc_t *sc, u_char chan); +static void ihfc_test_Bwrite (ihfc_sc_t *sc, u_char chan); + +u_short ihfc_Bsel_fifo (ihfc_sc_t *sc, u_char chan, u_char flag); +u_int32_t ihfc_Dsel_fifo (ihfc_sc_t *sc, u_char chan, u_char flag); + + +/*---------------------------------------------------------------------------* + * Commonly used ISA bus commands + *---------------------------------------------------------------------------*/ +#define IHFC_DATA_OFFSET 0 +#define IHFC_REG_OFFSET 1 + +#define BUS_VAR bus_space_handle_t h = rman_get_bushandle(S_IOBASE[0]); \ + bus_space_tag_t t = rman_get_bustag (S_IOBASE[0]) + +#define SET_REG(reg) bus_space_write_1(t,h, IHFC_REG_OFFSET, reg) +#define GET_STAT bus_space_read_1 (t,h, IHFC_REG_OFFSET) + +#define READ_DATA_1 bus_space_read_1 (t,h, IHFC_DATA_OFFSET) +#define READ_BOTH_2 bus_space_read_2 (t,h, IHFC_DATA_OFFSET) + +#define WRITE_DATA_1(data) bus_space_write_1(t,h, IHFC_DATA_OFFSET, data) +#define WRITE_BOTH_2(data) bus_space_write_2(t,h, IHFC_DATA_OFFSET, data) + +#define DISBUSY(okcmd, tocmd) \ +{ \ + if (GET_STAT & 1) \ + { \ + register u_char a; \ + register u_int to = IHFC_DISBUSYTO; \ + \ + while(((a = GET_STAT) & 1) && --to); \ + \ + if (!to) \ + { \ + NDBGL1(L1_ERROR, "DISBUSY-TIMEOUT! (a=%04x, " \ + "unit=%d)", a, S_UNIT); \ + tocmd; \ + } \ + else \ + { \ + okcmd; \ + } \ + } \ + else \ + { \ + okcmd; \ + } \ +} + +#define WAITBUSY_2(okcmd, tocmd) \ + { \ + register u_short a; \ + register u_int to = IHFC_NONBUSYTO; \ + \ + while((~(a = READ_BOTH_2) & 0x100) && --to); \ + \ + if (!to) \ + { \ + NDBGL1(L1_ERROR, "NONBUSY-TIMEOUT! (a=%04x, " \ + "unit=%d)", a, S_UNIT); \ + tocmd; \ + } \ + else \ + { \ + okcmd; \ + } \ + } + +/*---------------------------------------------------------------------------* + * Control function (HFC-1/S/SP) + * + * Flag: + * 1: reset and unlock chip (at boot only) + * 2: prepare for shutdown (at shutdown only) + * 3: reset and resume + * 4: select TE-mode (boot default) + * 5: select NT-mode (only HFC-S/SP/PCI) + * + * Returns != 0 on errornous chip + *---------------------------------------------------------------------------*/ +int +ihfc_control(ihfc_sc_t *sc, int flag) +{ + BUS_VAR; + + if (flag == 3) goto reset0; + if (flag == 4) + { + S_NTMODE = 0; + goto mode0; + } + if (flag == 5) + { + S_NTMODE = 1; + goto mode0; + } + if (flag == 1) + { + WRITE_BOTH_2(0x5400 | S_IIO); /* enable IO (HFC-1/S) */ + + S_LAST_CHAN = -1; + + /* HFC-S/SP configuration */ + + S_CIRM = S_IIRQ|0x10; /* IRQ, 8K fifo mode */ + S_CLKDEL = 0x00; /* 12.288mhz */ + S_CTMT = 0x03; /* transperant mode */ + S_CONNECT = 0x00; /* B channel data flow */ + S_INT_M1 = 0x40; /* interrupt mask */ + S_INT_M2 = 0x08; /* enable interrupt output */ + S_MST_MODE = 0x01; /* master mode */ + S_SCTRL = 0x50; /* S/Q on, non cap. line mode */ + S_SCTRL_R = 0x00; /* B channel receive disable */ + S_TEST = 0x00; /* no need for awake enable */ + + if (S_HFC & (HFC_1 | HFC_S)) /* configure timer (50ms) */ + { + S_CTMT |= 0x08; + } + else + { + S_CTMT |= 0x14; + } + + /* HFC-1 ISAC configuration (IOM-2 mode) */ + + S_ADF1 = 0x00; /* */ + S_ADF2 = 0x80; /* select mode IOM-2 */ + S_SPCR = 0x00; /* B channel send disable (0x10 for test loop) */ + S_MASK = 0xfb; /* enable CISQ */ + S_MODE = 0xc9; /* receiver enabled */ + S_SQXR = 0x0f; /* master, clock always active */ + S_STCR = 0x70; /* TIC bus address = 7 */ + S_STAR2 = 0x04; /* enable S/Q */ + + mode0: + if (S_NTMODE) /* configure NT- or TE-mode */ + { + S_SCTRL |= 0x04; /* NT mode */ + S_CLKDEL &= ~0x7f; /* clear delay */ + S_CLKDEL |= 0x6c; /* set delay */ + } + else + { + S_SCTRL &= ~0x04; /* TE mode */ + S_CLKDEL &= ~0x7f; /* clear delay */ + S_CLKDEL |= S_STDEL; /* set delay */ + } + if (S_DLP) /* configure D-priority */ + { + S_SCTRL |= 0x08; /* (10/11) */ + } + else + { + S_SCTRL &= ~0x08; /* (8/9) */ + } + + reset0: + /* chip reset (HFC-1/S/SP) */ + + if (S_HFC & HFC_1) + { + SET_REG((S_CIRM | 0xc8) & 0xdf); + + DELAY(10); /* HFC-2B manual recommends a 4 * + * clock cycle delay after CIRM * + * write with reset=1. A 1us * + * delay, should do for 7.68mhz,* + * but just in case I make that * + * 10us. */ + + SET_REG((S_CIRM | 0xc0) & 0xdf); + + DELAY(250); /* ISAC manual says reset pulse * + * length is 125us. Accessing * + * ISAC before those 125us, we * + * may risk chip corruption and * + * irq failure. The HFC-2B also * + * needs some delay to recover, * + * so we add some us. */ + } + else + { + SET_REG(0x18); + + WRITE_DATA_1(S_CIRM | 8); + + DELAY(10); /* HFC-2BDS0 manual recommends * + * a 4 clock cycle delay after * + * CIRM write with reset=1. * + * A 1us delay, should do for * + * 12.288mhz, but just in case * + * I make that 10us. */ + + WRITE_DATA_1(S_CIRM); + + DELAY(25); /* HFC-2BDS0 needs some time to * + * recover after CIRM write * + * with reset=0. Experiments * + * show this delay should be * + * 8-9us. Just in case we make * + * that 25us. */ + } + + { + /* HFC-1/S/SP chip test * + * * + * NOTE: after reset the HFC-1/S/SP should be * + * in a mode where it is always non-busy/non- * + * processing, and bit[0] of STATUS/DISBUSY * + * register, should always return binary '0' * + * until we configure the chips for normal * + * operation. */ +#ifdef IHFC_DEBUG + printf("ihfc: GET_STAT value is: 0x%x\n", GET_STAT); +#endif + SET_REG(0x30); + + if ((GET_STAT & 1) || (READ_DATA_1 & 0xf)) goto f0; + } + + ihfc_loadconfig(sc); + + if (S_HFC & HFC_1) ihfc_cmdr_hdlr(sc, 0x41); /* rres, xres */ + + S_PHSTATE = 0; + HFC_FSM(sc, 0); + } + + if (flag == 2) + { + if (S_HFC & HFC_1) S_CIRM &= ~0x03; /* disable interrupt */ + + S_SQXR |= 0x40; /* power down */ + + S_SPCR &= ~0x0f; /* send 1's only */ + S_SCTRL &= ~0x83; /* send 1's only + enable oscillator */ + + ihfc_loadconfig(sc); + } + + return(0); /* success */ + + f0: + return(1); /* failure */ +} + +/*---------------------------------------------------------------------------* + * Softc initializer and hardware setup (HFC-1/S/SP) + * + * Returns: 0 on success + * 1 on failure + *---------------------------------------------------------------------------*/ +int +ihfc_init (ihfc_sc_t *sc, u_char chan, int prot, int activate) +{ + if (chan > 5) goto f0; + + chan &= ~1; + + do + { if (chan < 2) /* D-Channel */ + { + i4b_Dfreembuf(S_MBUF); + i4b_Dcleanifq(&S_IFQUEUE); + + RESET_SOFT_CHAN(sc, chan); + + S_IFQUEUE.ifq_maxlen = IFQ_MAXLEN; + + if (!activate) continue; + + if (S_HFC & HFC_1) + { + S_FILTER = (chan & 1) ? ihfc_isac_Dread : + ihfc_isac_Dwrite; + } + else + { + S_FILTER = (chan & 1) ? ihfc_hdlc_Dread : + ihfc_hdlc_Dwrite; + } + } + else /* B-Channel */ + { + i4b_Bfreembuf(S_MBUF); + i4b_Bcleanifq(&S_IFQUEUE); + + RESET_SOFT_CHAN(sc, chan); + + S_PROT = prot; + S_IFQUEUE.ifq_maxlen = IFQ_MAXLEN; + + if (!activate) continue; + + switch(prot) + { case(BPROT_NONE): + S_FILTER = (chan & 1) ? + ihfc_trans_Bread : + ihfc_trans_Bwrite; + break; + case(BPROT_RHDLC): + S_FILTER = (chan & 1) ? + ihfc_hdlc_Bread : + ihfc_hdlc_Bwrite; + break; + case(5): + S_FILTER = (chan & 1) ? + ihfc_test_Bread : + ihfc_test_Bwrite; + break; + } + } + } while (++chan & 1); + + S_MASK |= 0xfb; /* disable all, but CISQ interrupt (ISAC) */ + S_INT_M1 &= 0x40; /* disable all, but TE/NT state machine (HFC) */ + S_SCTRL &= ~0x03; /* B1/B2 send disable (HFC) */ + S_SPCR &= ~0x0f; /* B1/B2 send disable (ISAC) */ + S_SCTRL_R &= ~0x03; /* B1/B2 receive disable (HFC) */ + + chan = 0; + if (S_FILTER) /* D-Channel active */ + { + S_MASK &= 0x2e; /* enable RME, RPF, XPR, EXI */ + S_INT_M1 |= 0x24; /* enable D-receive, D-transmit */ + } + + chan = 2; + if (S_FILTER) /* B1-Channel active */ + { + S_SCTRL |= 1; /* send enable (HFC) */ + S_SPCR |= 8; /* send enable (ISAC) */ + S_SCTRL_R |= 1; /* receive enable (HFC) */ + S_INT_M1 |= 0x80; /* timer enable (HFC) */ + S_INT_M1 &= ~0x04; /* let D-channel use timer too */ + } + + chan = 4; + if (S_FILTER) /* B2-Channel active */ + { + S_SCTRL |= 2; /* send enable (HFC) */ + S_SPCR |= 2; /* send enable (ISAC) */ + S_SCTRL_R |= 2; /* receive enable (HFC) */ + S_INT_M1 |= 0x80; /* timer enable (HFC) */ + S_INT_M1 &= ~0x04; /* let D-channel use timer too */ + } + + ihfc_loadconfig(sc); + + /* XXX reset timer? */ + + return 0; /* success */ + f0: + return 1; /* failure */ +} + +/*---------------------------------------------------------------------------* + * Load configuration data (HFC-1/S/SP) + *---------------------------------------------------------------------------*/ +void +ihfc_loadconfig(ihfc_sc_t *sc) +{ + BUS_VAR; + + if (S_HFC & HFC_1) + { + /* HFC-1 chips w/ISAC: */ + + const u_char *src = (void *)&S_ISAC_CONFIG; + const u_char *dst = (void *)&isac_configtable; + + SET_REG((S_CIRM | 0xc0) & 0xdf); + + S_CTMT = (S_CTMT & ~0x14) | ((S_INT_M1 >> 5) & 0x4); + + SET_REG((S_CTMT | 0xe0) & 0xff); + + while(*dst) + { + SET_REG(*dst++); /* set register */ + + /* write configuration */ + DISBUSY(WRITE_DATA_1(*src++), break); + } + } + else + { + /* HFC-S/SP chips: */ + + const u_char *src = (void *)&S_HFC_CONFIG; + const u_char *dst = (void *)&ihfc_configtable; + + while(*dst) + { + SET_REG(*dst++); /* set register */ + WRITE_DATA_1(*src++); /* write configuration */ + } + } +} + +/*---------------------------------------------------------------------------* + * Function State Machine handler (PH layer) (HFC-1/S/SP) + * + * Flag: 0 = Refresh softc S_PHSTATE + take hints + * 1 = Activate + * 2 = Deactivate + * + * NOTE: HFC-1 only supports TE mode. + *---------------------------------------------------------------------------*/ +void +ihfc_fsm(ihfc_sc_t *sc, int flag) +{ + const struct ihfc_FSMtable *fsmtab; + u_char ihfc_cmd = 0; + u_char isac_cmd = 0; + u_char tmp; + BUS_VAR; + + /* get current state (rx/downstream) */ + + if (S_HFC & HFC_1) + { + SET_REG(0x31); DISBUSY(tmp = (READ_DATA_1 >> 2) & 0xf, return); + + fsmtab = (S_NTMODE) ? &ihfc_TEtable2[tmp]: + &ihfc_TEtable2[tmp]; + } + else + { + SET_REG(0x30); tmp = READ_DATA_1 & 0xf; + + fsmtab = (S_NTMODE) ? &ihfc_NTtable[tmp]: + &ihfc_TEtable[tmp]; + } + + if (fsmtab->string) + { + NDBGL1(L1_I_CICO, "%s (ind=0x%x, flag=%d, unit=%d).", + fsmtab->string, tmp, flag, S_UNIT); + } + else + { + NDBGL1(L1_I_ERR, "Illegal indicatation (ind=0x%x, " + "flag=%d, unit=%d).", tmp, flag, S_UNIT); + } + + /* indication machine / state change * + * * + * Whenever the state of the S0-line changes, we check to see in which * + * direction the change went. Generally upwards means activate, and * + * downwards means deactivate. * + * The test signal is used to ensure proper syncronization. */ + + if (fsmtab->state == 0) /* deactivated indication */ + { + if (S_PHSTATE != 0) + { + isac_cmd = 0x3c; /* deactivate DUI */ + + i4b_l1_ph_deactivate_ind(S_I4BUNIT); + } + } + if (fsmtab->state == 2) /* syncronized indication */ + { + if (S_PHSTATE != 2) + { + if (S_NTMODE) ihfc_cmd = 0x80; + } + } + if (fsmtab->state == 3) /* activated indication */ + { + if (S_PHSTATE != 3) + { + isac_cmd = (S_DLP) ? 0x24 /* activate AR10 */ + : 0x20; /* activate AR8 */ + + i4b_l1_ph_activate_ind(S_I4BUNIT); + } + } + if (fsmtab->state == 4) /* error indication */ + { + if (S_PHSTATE < 4) + { + isac_cmd = 0x3c; /* deactivate DUI */ + } + } + + S_PHSTATE = fsmtab->state; + + if ((flag == 1) && (fsmtab->state != 3)) + { + isac_cmd = (S_DLP) ? 0x24 : 0x20; + ihfc_cmd = 0x60; + } + if ((flag == 2) && (fsmtab->state != 0)) + { + isac_cmd = 0x3c; + ihfc_cmd = 0x40; + } + + /* set new state (tx / upstream) * + * * + * NOTE: HFC-S/SP and ISAC transmitters are always active when * + * activated state is reached. The bytes sent to the S0-bus are all * + * high impedance, so they do not disturb. * + * The HFC-1 has a seperate SIEMENS S0-device. */ + + if (S_HFC & HFC_1) + { + if (isac_cmd) + { + if (S_IOM2) isac_cmd |= 3; + + SET_REG(0x31); DISBUSY(WRITE_DATA_1(isac_cmd), ); + + NDBGL1(L1_I_CICO, "(isac_cmd=0x%x, unit=%d).", + isac_cmd, S_UNIT); + } + } + else + { + if (ihfc_cmd || (fsmtab->state == 5)) + { + SET_REG(0x30); WRITE_DATA_1(ihfc_cmd); + + NDBGL1(L1_I_CICO, "(ihfc_cmd=0x%x, unit=%d).", + ihfc_cmd, S_UNIT); + } + } +} + +/*---------------------------------------------------------------------------* + * S/Q - channel handler (read) (HFC-S/SP) + *---------------------------------------------------------------------------*/ +void +ihfc_sq (ihfc_sc_t *sc) +{ + const struct ihfc_SQtable *SQtab; + register u_char a = 0; + BUS_VAR; + + if (S_HFC & HFC_1) + { + SET_REG(0x31); + DISBUSY(a = READ_DATA_1, a = 0); + + if (a & 0x80) + { + SET_REG(0x3b); + DISBUSY(a = READ_DATA_1, a = 0); + } + } + else + { + SET_REG(0x34); + a = READ_DATA_1; + } + + SQtab = (S_NTMODE) ? &ihfc_Qtable[a & 7]: + &ihfc_Stable[a & 7]; + + if (a & 0x10) + { + if (SQtab->string) + { + NDBGL1(L1_I_CICO, "%s (unit=%d, int=%x)", + SQtab->string, S_UNIT, S_INT_S1); + } + else + { + NDBGL1(L1_ERROR, "Unknown indication = %x (unit=%d)", + a & 7, S_UNIT); + } + } +} + +/*---------------------------------------------------------------------------* + * Interrupt handler (HFC-1) + *---------------------------------------------------------------------------*/ +void +ihfc_intr1 (ihfc_sc_t *sc) +{ + u_char chan; + u_char tmp; + BUS_VAR; + HFC_VAR; + + HFC_BEG; + + SET_REG(0x20); tmp = GET_STAT; DISBUSY(S_ISTA |= READ_DATA_1, ); + + if (S_ISTA & 0x04) /* CIRQ */ + { + HFC_FSM(sc, 0); + + ihfc_sq(sc); + } + + S_INTR_ACTIVE = 1; + + if (S_ISTA & 0xc0) /* RPF or RME */ + { + chan = 1; + if (S_FILTER) S_FILTER(sc, chan); + } + if (S_ISTA & 0x10) /* XPR */ + { + chan = 0; + if (S_FILTER) S_FILTER(sc, chan); + } + if (tmp & 0x04) /* Timer elapsed (50ms) */ + { + SET_REG((S_CTMT | 0xf0) & 0xff); + + chan = 6; + while(chan--) + { + if (chan == 1) break; + if (S_FILTER) S_FILTER(sc, chan); + } + } + + S_INTR_ACTIVE = 0; + + if (S_ISTA & 0x01) /* EXIR */ + { + SET_REG(0x24); DISBUSY(ihfc_exir_hdlr(sc, READ_DATA_1), ); + } + + S_ISTA &= ~(0x1 | 0x4); + + HFC_END; +} + +/*---------------------------------------------------------------------------* + * Interrupt handler (HFC-S/SP) + *---------------------------------------------------------------------------*/ +void +ihfc_intr2 (ihfc_sc_t *sc) +{ + u_char chan; + BUS_VAR; + HFC_VAR; + + HFC_BEG; + + SET_REG(0x1e); S_INT_S1 = READ_DATA_1; /* this will enable new interrupts! */ + + if (S_INT_S1 & 0x40) + { + HFC_FSM(sc, 0); /* statemachine changed */ + + ihfc_sq(sc); + } + + S_INTR_ACTIVE = 1; + + if (S_INT_S1 & 0x20) /* D-Channel frame (rx) */ + { + chan = 1; + if (S_FILTER) S_FILTER(sc, chan); + } + if (S_INT_S1 & 0x04) /* D-Channel frame (tx) */ + { + chan = 0; + if (S_FILTER && (~S_INT_S1 & 0x80)) S_FILTER(sc, chan); + } + if (S_INT_S1 & 0x80) /* Timer elapsed (50ms) */ + { + chan = 6; + while(chan--) + { + if (chan == 1) continue; + if (S_FILTER) S_FILTER(sc, chan); + } + } + + S_INTR_ACTIVE = 0; + + HFC_END; +} + +/*---------------------------------------------------------------------------* + * Select a Bfifo (HFC-1/S/SP) + * and return bytes in FIFO + * + * (this code is optimized) + *---------------------------------------------------------------------------*/ +u_short +ihfc_Bsel_fifo(ihfc_sc_t *sc, u_char chan, u_char flag) +{ + register u_char reg = 0x7e + chan; + register u_short tmp = 0x100; + register u_short z1; + register u_short z2; + + BUS_VAR; + + if (S_HFC & (HFC_1 | HFC_S)) + { + if (S_LAST_CHAN != chan) + { + SET_REG(reg); + DISBUSY(WAITBUSY_2( , return 0), return 0); + + S_LAST_CHAN = chan; + } + } + else + { + SET_REG(0x10); + WRITE_DATA_1(chan - 2); + DISBUSY( , return 0); + } + +#define FAST_READ (u_char)(tmp = READ_BOTH_2) +#define FAST_STAT if (tmp & 0x100) DISBUSY( , return 0); + + SET_REG(reg ); FAST_STAT; z1 = FAST_READ; + SET_REG(reg += 4); FAST_STAT; z1 |= FAST_READ << 8; + SET_REG(reg += 4); FAST_STAT; z2 = FAST_READ; + SET_REG(reg += 4); FAST_STAT; z2 |= READ_DATA_1 << 8; + +#undef FAST_READ +#undef FAST_STAT + + z1 &= 0x1fff; + z2 &= 0x1fff; + + z1 = 0x5ff - (z2 = z1 - z2 + ((z2 <= z1) ? 0 : 0x600)); + + if (chan & 1) + return(z2); /* receive channel */ + else + return(z1); /* transmit channel */ +} + +/*---------------------------------------------------------------------------* + * Select a Dfifo (HFC-S/SP) + * and return bytes, and frames in FIFO + * + * Flag values: + * 0x00: select new fifo + update counters + * 0x10: increment f1 + update counters + * 0x20: increment f2 + update counters + * + * NOTE: The upper 16bits holds the number of frames in the FIFO. + * NOTE: FIFO has to be selected before you can use flags 0x10/0x20. + *---------------------------------------------------------------------------*/ +u_int32_t +ihfc_Dsel_fifo(ihfc_sc_t *sc, u_char chan, u_char flag) +{ + register u_char reg = 0x90 + chan; + register u_short tmp = 0x100; + register u_char f1; + register u_char f2; + register u_short z1; + register u_short z2; + + BUS_VAR; + + if (S_HFC & (HFC_1 | HFC_S)) + { + switch(flag) + { + case(0x10): + case(0x20): + SET_REG(reg); + if (~GET_STAT & 1) + WAITBUSY_2( , return 0); + + SET_REG(0xa2 - (flag & 0x10) + chan); + DISBUSY(READ_DATA_1, return 0); + + SET_REG(reg); + if (~GET_STAT & 1) + WAITBUSY_2( , return 0); + break; + + default: + if (S_LAST_CHAN != chan) + { + SET_REG(reg); + DISBUSY(WAITBUSY_2( , return 0), return 0); + + S_LAST_CHAN = chan; + } + break; + } + } + else + { + switch(flag) + { + case(0x10): + case(0x20): + SET_REG(0xb8 - (flag & 0x10) + chan); + READ_DATA_1; + + DISBUSY( , return 0); + + if (chan & 1) + { + /* Before reading a FIFO a change * + * FIFO operation must be done. * + * (see HFC-SP manual p.38) */ + + SET_REG(0x10); + WRITE_DATA_1(chan | 4); + + DISBUSY( , return 0); + } + break; + + default: + SET_REG(0x10); + WRITE_DATA_1(chan | 4); + + DISBUSY( , return 0); + break; + } + } + +#define FAST_READ (u_char)(tmp = READ_BOTH_2) +#define FAST_STAT if (tmp & 0x100) DISBUSY( , return 0); + + if (S_HFC & HFC_SP) reg = 0x80 + chan; + + SET_REG(reg ); FAST_STAT; z1 = FAST_READ; + SET_REG(reg += 4); FAST_STAT; z1 |= FAST_READ << 8; + SET_REG(reg += 4); FAST_STAT; z2 = FAST_READ; + SET_REG(reg += 4); FAST_STAT; z2 |= FAST_READ << 8; + + if (S_HFC & HFC_SP) reg += 0x26; + + SET_REG(reg -= 2); FAST_STAT; f1 = FAST_READ; + SET_REG(reg += 4); FAST_STAT; f2 = READ_DATA_1; + +#undef FAST_READ +#undef FAST_STAT + + if (~chan & 1) + { /* XXX was Z1 */ + S_HDLC_DZ_TAB[f1 & 0xf] = z2; /* We keep track of the 'Z' * + * values for D-channel (tx),* + * so we may calculate the # * + * of FIFO bytes free when * + * f1 != f2. */ + z2 = S_HDLC_DZ_TAB[f2 & 0xf]; + } + + z1 = 0x1ff - (z2 = (z1 - z2) & 0x1ff); + f1 = 0xf - (f2 = (f1 - f2) & 0xf); + + if (chan & 1) + return(z2 | (f2 << 16)); /* receive channel */ + else + return(z1 | (f1 << 16)); /* transmit channel */ +} + + +/*---------------------------------------------------------------------------* + * Data handler for D channel(write) - chan 0 (HFC-S/SP) + *---------------------------------------------------------------------------*/ +void +ihfc_hdlc_Dwrite (ihfc_sc_t *sc, u_char chan) +{ + register u_int32_t sendlen; + register u_short len; + register u_char * src; + + BUS_VAR; + + if (!S_MBUF && IF_QEMPTY(&S_IFQUEUE)) return; + + sendlen = ihfc_Dsel_fifo(sc, chan, 0); /* select new fifo * + * NOTE: the 16 higher bits * + * contain the # of frame- * + * etries free in the FIFO */ + while (sendlen & ~0xffff) + { + if (!S_MBUF) + { + if (!(S_MBUF = ihfc_getmbuf(sc, chan))) goto j1; + } + + src = S_MBUFDATA; + len = S_MBUFLEN; + + if (len >= 0x1ff) goto j0; /* frame is too big: skip! */ + + sendlen &= 0xffff; /* only keep # of * + * bytes free */ + + SET_REG((S_HFC & HFC_SP) ? 0xac : 0x96); + + while (sendlen--) + { + if (!len--) break; + + DISBUSY(WRITE_DATA_1(*src++), sendlen = -1; len++; break); + } + + if (!++sendlen) /* out of fifo: suspend */ + { + S_MBUFDATA = src; + S_MBUFLEN = len; + break; + } + + sendlen = ihfc_Dsel_fifo(sc, chan, 0x10); /* inc F1 */ + j0: + i4b_Dfreembuf(S_MBUF); + S_MBUF = NULL; + } + j1: +} + +/*---------------------------------------------------------------------------* + * Data handler for D channel(read) - chan 1 (HFC-S/SP) + * + * NOTE: Max framelength is (511 - 3) = 508 bytes, when only one frame + * is received at a time. + *---------------------------------------------------------------------------*/ +void +ihfc_hdlc_Dread (ihfc_sc_t *sc, u_char chan) +{ + register u_char tmp = -1; + register u_char to = 15; + register u_int32_t reclen; + register u_short crc; + register u_short len; + register u_char * dst; + + BUS_VAR; + + reclen = ihfc_Dsel_fifo(sc, chan, 0); /* select new fifo * + * NOTE: the higher 16 bits * + * contain the # of frames * + * to receive. */ + while ((reclen & ~0xffff) && to--) + { + reclen &= 0xffff; /* only keep # of * + * bytes to receive */ + + if (!(S_MBUF = i4b_Dgetmbuf(DCH_MAX_LEN))) + panic("ihfc_hdlc_Dread: No mbufs(unit=%d)!\n", S_UNIT); + + SET_REG((S_HFC & HFC_SP) ? 0xbd : 0xa7); + + if ((reclen > 2) && (reclen <= (DCH_MAX_LEN+2))) + { + dst = S_MBUFDATA; + len = S_MBUFLEN = (reclen += 1) - 3; + } + else + { + len = 0; + dst = NULL; + } + + crc = -1; /* NOTE: after a "F1" or "Z1" hardware overflow * + * it appears not to be necessary to reset the * + * HFC-1/S or SP chips to continue proper * + * operation, only and only, if we always read * + * "Z1-Z2+1" bytes when F1!=F2 followed by a * + * F2-counter increment. The bi-effect of doing * + * this is the "STAT" field may say frame is ok * + * when the frame is actually bad. * + * The simple solution is to re-CRC the frame * + * including "STAT" field to see if we get * + * CRC == 0x3933. Then we're 99% sure all * + * frames received are good. */ + + while(reclen--) + { + DISBUSY(tmp = READ_DATA_1, break); + if (len) { len--; *dst++ = tmp; } + + crc = (HDLC_FCS_TAB[(u_char)(tmp ^ crc)] ^ (u_char)(crc >> 8)); + } + + crc ^= 0x3933; + + if (!tmp && !crc) + { + ihfc_putmbuf(sc, chan, S_MBUF); + S_MBUF = NULL; + } + else + { + NDBGL1(L1_ERROR, "Frame error (len=%d, stat=0x%x, " + "crc=0x%x, unit=%d)", S_MBUFLEN, (u_char)tmp, crc, + S_UNIT); + + i4b_Dfreembuf(S_MBUF); + S_MBUF = NULL; + } + + reclen = ihfc_Dsel_fifo(sc, chan, 0x20); + } +} + +/*---------------------------------------------------------------------------* + * EXIR error handler - ISAC (D - channel) (HFC-1) + *---------------------------------------------------------------------------*/ +void +ihfc_exir_hdlr (ihfc_sc_t *sc, u_char exir) +{ + register u_char a; + register u_char cmd; + + for (a = 0, cmd = 0; exir; a++, exir >>= 1) + { + if (exir & 1) + { + NDBGL1(L1_I_ERR, "%s. (unit=%d)", + ihfc_EXIRtable[a].string, S_UNIT); + cmd |= ihfc_EXIRtable[a].cmd; + } + } + + if (cmd) ihfc_cmdr_hdlr(sc, cmd); +} + +/*---------------------------------------------------------------------------* + * CMDR handler - ISAC (D - channel) (HFC-1) + *---------------------------------------------------------------------------*/ +void +ihfc_cmdr_hdlr (ihfc_sc_t *sc, u_char cmdr) +{ + BUS_VAR; + + SET_REG(0x21); DISBUSY(WRITE_DATA_1(cmdr); DELAY(30), ); +} + +/*---------------------------------------------------------------------------* + * Data handler for D channel(write) - chan 0 (HFC-1) + *---------------------------------------------------------------------------*/ +void +ihfc_isac_Dwrite (ihfc_sc_t *sc, u_char chan) +{ + register u_char sendlen = 32; + register u_char cmd = 0; + register u_short len; + register u_char * src; + + BUS_VAR; + + if (~S_ISTA & 0x10) goto j0; + + if (!S_MBUF) + if (!(S_MBUF = ihfc_getmbuf(sc, chan))) goto j0; + + len = S_MBUFLEN; + src = S_MBUFDATA; + + SET_REG(0x00); + + while(sendlen--) /* write data */ + { + if (!len--) break; + DISBUSY(WRITE_DATA_1(*src++), goto a0); + } + + cmd |= 0x08; + + if (!++sendlen) /* suspend */ + { + S_MBUFLEN = len; + S_MBUFDATA = src; + } + else + { + a0: + i4b_Dfreembuf(S_MBUF); + S_MBUF = NULL; + + cmd |= 0x02; + } + + if (cmd) ihfc_cmdr_hdlr(sc, cmd); + + S_ISTA &= ~0x10; + j0: +} + +/*---------------------------------------------------------------------------* + * Data handler for D channel(read) - chan 1 (HFC-1) + *---------------------------------------------------------------------------*/ +void +ihfc_isac_Dread (ihfc_sc_t *sc, u_char chan) +{ + register u_char cmd = 0; + register u_char reclen; + register u_short tmp; + register u_short len; + register u_char * dst; + + BUS_VAR; + + if (!(S_ISTA & 0xc0)) goto j1; /* only receive data * + * on interrupt */ + + if (!S_MBUF) + { + if (!(S_MBUF = i4b_Dgetmbuf(DCH_MAX_LEN))) + panic("ihfc%d: (D) Out of mbufs!\n", S_UNIT); + } + + len = S_MBUFLEN; + dst = S_MBUFDATA + (DCH_MAX_LEN - len); + + if (S_ISTA & 0x80) /* RME */ + { + SET_REG(0x27); DISBUSY(tmp = (READ_DATA_1 ^ 0x20), goto j0); + + if (tmp & 0x70) goto j0; /* error */ + + SET_REG(0x25); DISBUSY(tmp = (READ_DATA_1 & 0x1f), goto j0); + + reclen = (tmp) ? tmp : 32; + } + else /* RPF */ + { + reclen = 32; + } + + if ((len -= reclen) <= DCH_MAX_LEN) /* get data */ + { + SET_REG(0x00); + + while(reclen--) + { + DISBUSY(*dst++ = READ_DATA_1, goto j0); + } + } + else /* soft rdo or error */ + { + j0: i4b_Dfreembuf(S_MBUF); + S_MBUF = NULL; + + cmd |= 0x40; + + NDBGL1(L1_I_ERR, "Frame error (unit=%d)", S_UNIT); + } + + if (S_ISTA & 0x80) /* frame complete */ + { + if (S_MBUF) + { + S_MBUFLEN = (DCH_MAX_LEN - len); + ihfc_putmbuf(sc, chan, S_MBUF); + S_MBUF = NULL; + } + } + + if (S_MBUF) /* suspend */ + { + S_MBUFLEN = len; + } + + ihfc_cmdr_hdlr(sc, cmd | 0x80); + + S_ISTA &= ~0xc0; + j1: +} + +/*---------------------------------------------------------------------------* + * Data handler for B channel(write) - chan 2 and 4 (HFC-1/S/SP) + * + * NOTE: No XDU checking! + *---------------------------------------------------------------------------*/ +void +ihfc_trans_Bwrite (ihfc_sc_t *sc, u_char chan) +{ + register u_short sendlen; + register u_short len; + register u_char * src; + + BUS_VAR; + + if (!S_MBUF && IF_QEMPTY(&S_IFQUEUE)) return; + + sendlen = (u_short)ihfc_Bsel_fifo(sc, chan, 0); + + SET_REG(0xaa + chan); + + while (1) + { + if (!S_MBUF) + { + S_MBUF = ihfc_getmbuf(sc, chan); + if (!S_MBUF) break; + } + + src = S_MBUFDATA; + len = S_MBUFLEN; + + while (sendlen--) + { + if (!len--) break; + + DISBUSY(WRITE_DATA_1(*src++), sendlen = -1; len++; break); + } + + if (!++sendlen) /* out of fifo: Suspend */ + { + S_MBUFDATA = src; + S_MBUFLEN = len; + break; + } + + i4b_Dfreembuf(S_MBUF); + S_MBUF = NULL; + } +} + +/*---------------------------------------------------------------------------* + * Data handler for B channel(read) - chan 3 and 5 (HFC-1/S/SP) + * (this code is optimized) + *---------------------------------------------------------------------------*/ +void +ihfc_trans_Bread (ihfc_sc_t *sc, u_char chan) +{ + register u_short reclen; + register u_short tmp; + register u_short len; + register u_char * dst; + + BUS_VAR; + + reclen = (u_short)ihfc_Bsel_fifo(sc, chan, 0); + + while (1) + { + SET_REG(0xba + chan); + + tmp = 0x100; + + if (!S_MBUF) + if (!(S_MBUF = i4b_Bgetmbuf(BCH_MAX_DATALEN))) + panic("ihfc%d: (B) Out of mbufs!\n", S_UNIT); + + len = S_MBUFLEN; + dst = S_MBUFDATA + (BCH_MAX_DATALEN - len); + + while (reclen--) + { + if (!len--) break; + + if (tmp & 0x100) DISBUSY( , reclen = -1; len++; break); + *dst++ = (u_char)(tmp = READ_BOTH_2); + } + + if (~tmp & 0x100) + { + SET_REG(0x30); + READ_DATA_1; /* a read to the data port * + * will disable the internal * + * disbusy signal for HFC-1/S * + * chips. This is neccessary * + * to avvoid data loss. */ + } + + if (!++reclen) /* out of fifo: suspend */ + { + S_MBUFLEN = len; + break; + } + + S_MBUFLEN = (BCH_MAX_DATALEN - ++len); + + ihfc_putmbuf(sc, chan, S_MBUF); + + S_MBUF = NULL; + } +} + +/*---------------------------------------------------------------------------* + * Data handler for B channel(write) - chan 2 and 4 (HFC-1/S/SP) + * + * NOTE: Software HDLC encoding! + *---------------------------------------------------------------------------*/ +void +ihfc_hdlc_Bwrite (ihfc_sc_t *sc, u_char chan) +{ + register u_short blevel = S_HDLC_BLEVEL; + register u_char flag = S_HDLC_FLAG; + register u_int tmp = S_HDLC_TMP; + register u_short crc = S_HDLC_CRC; + register u_short ib = S_HDLC_IB; + register u_char * src = NULL; + register u_short len = 0; + register u_short sendlen; + register u_short tmp2; + + BUS_VAR; + + if (!S_MBUF && IF_QEMPTY(&S_IFQUEUE) && (flag == 2)) return; + + sendlen = (u_short)ihfc_Bsel_fifo(sc, chan, 0); + + SET_REG(0xaa + chan); + + if (S_MBUF) + { + /* resume */ + + src = S_MBUFDATA; + len = S_MBUFLEN; + + if (sendlen == 0x5ff) + { + /* XDU */ + + flag = -1; + len = 0; + + NDBGL1(L1_S_ERR, "XDU (unit=%d)", S_UNIT); + } + } + + while (sendlen--) + { + HDLC_ENCODE(*src++, len, tmp, tmp2, blevel, ib, crc, flag, + {/* gfr */ + i4b_Bfreembuf(S_MBUF); + S_MBUF = ihfc_getmbuf(sc, chan); + + if (!S_MBUF) goto d0; + + src = S_MBUFDATA; + len = S_MBUFLEN; + }, + {/* wrd */ + + DISBUSY(WRITE_DATA_1((u_char)tmp), sendlen = 0); + }, + d ); + } + + if (S_MBUF) /* suspend */ + { + S_MBUFDATA = src; + S_MBUFLEN = len; + } + + d0: + S_HDLC_IB = ib; + S_HDLC_BLEVEL = blevel; + S_HDLC_TMP = tmp; + S_HDLC_FLAG = flag; + S_HDLC_CRC = crc; +} + +/*---------------------------------------------------------------------------* + * Data handler for B channel(read) - chan 3 and 5 (HFC-1/S/SP) + * + * NOTE: Software HDLC decoding! + *---------------------------------------------------------------------------*/ +void +ihfc_hdlc_Bread (ihfc_sc_t *sc, u_char chan) +{ + register u_char blevel = S_HDLC_BLEVEL; + u_char flag = S_HDLC_FLAG; + register u_short crc = S_HDLC_CRC; + register u_int tmp = S_HDLC_TMP; + register u_short ib = S_HDLC_IB; + register u_char * dst = NULL; + register u_short tmp2 = 0x100; + register u_short len = 0; + register u_short reclen; + + BUS_VAR; + + if (S_MBUF) + { + /* resume */ + + len = S_MBUFLEN; + dst = S_MBUFDATA + (BCH_MAX_DATALEN - len); + } + + reclen = (u_short)ihfc_Bsel_fifo(sc, chan, 0); + + SET_REG(0xba + chan); + + while (reclen--) + { + HDLC_DECODE(*dst++, len, tmp, tmp2, blevel, ib, crc, flag, + {/* rdd */ + /* if (tmp2 & 0x100) while (GET_STAT & 1); + * tmp2 = READ_BOTH_2; + */ + + DISBUSY(tmp2 = READ_DATA_1, reclen = 0; tmp2 = 0); + }, + {/* nfr */ + if (!(S_MBUF = i4b_Bgetmbuf(BCH_MAX_DATALEN))) + panic("ihfc:(B) Out of mbufs!\n"); + + dst = S_MBUFDATA; + len = BCH_MAX_DATALEN; + }, + {/* cfr */ + len = (BCH_MAX_DATALEN - len); + + if ((!len) || (len > BCH_MAX_DATALEN)) + { + /* NOTE: frames without any data, * + * only crc field, should be silently discared. */ + + i4b_Bfreembuf(S_MBUF); + NDBGL1(L1_S_MSG, "Bad frame (len=%d, unit=%d)", len, S_UNIT); + goto s0; + } + + if (crc) + { i4b_Bfreembuf(S_MBUF); + NDBGL1(L1_S_ERR, "CRC (crc=0x%04x, len=%d, unit=%d)", crc, len, S_UNIT); + goto s0; + } + + S_MBUFLEN = len; + + ihfc_putmbuf(sc, chan, S_MBUF); + s0: + S_MBUF = NULL; + }, + {/* rab */ + i4b_Bfreembuf(S_MBUF); + S_MBUF = NULL; + + NDBGL1(L1_S_MSG, "Read Abort (unit=%d)", S_UNIT); + }, + {/* rdo */ + i4b_Bfreembuf(S_MBUF); + S_MBUF = NULL; + + NDBGL1(L1_S_ERR, "RDO (unit=%d)", S_UNIT); + }, + continue, + d); + } + + /* SET_REG(0x30); + * if (~tmp2 & 0x100) READ_DATA_1; kill disbusy signal + */ + + if (S_MBUF) S_MBUFLEN = len; /* suspend */ + + S_HDLC_IB = ib; + S_HDLC_CRC = crc; + S_HDLC_TMP = tmp; + S_HDLC_FLAG = flag; + S_HDLC_BLEVEL = blevel; +} + +/*---------------------------------------------------------------------------* + * Data handler for B channel(write) - chan 2 and 4 (HFC-1/S/SP) + * + * This filter generates a pattern which is recognized + * and examinated and verified by ihfc_test_Bread. + * + * NOTE: This filter is only for testing purpose. + *---------------------------------------------------------------------------*/ +void +ihfc_test_Bwrite (ihfc_sc_t *sc, u_char chan) +{ + struct mbuf *m; + + register u_char fb; + register u_short sendlen, tlen; + register u_short xlen = S_HDLC_IB; + BUS_VAR; + + goto j0; + + while((m = ihfc_getmbuf(sc, chan))) /* internal loop */ + { + if (chan == 2) + ihfc_putmbuf(sc, 5, m); + else + ihfc_putmbuf(sc, 3, m); + } + + j0: + + sendlen = (u_short)ihfc_Bsel_fifo(sc, chan, 0); + + if (sendlen == 0x5ff) printf("(send empty)"); + + SET_REG(0xaa + chan); + + S_BYTES += sendlen; + + tlen = S_HDLC_CRC; + + if (sendlen > 0x400) printf("(slow: %d)", sendlen); + + fb = 0x80; + + while (sendlen--) + { + if (!tlen--) fb |= 0x20; + + if (!xlen--) + { + while(GET_STAT & 1); + WRITE_DATA_1(0x3e); + xlen = 200; + } + else + { + while(GET_STAT & 1); + WRITE_DATA_1((xlen + 1) & 0xef); + } + + fb = 0; + } + + S_HDLC_IB = xlen; +} + +/*---------------------------------------------------------------------------* + * Data handler for B channel(read) - chan 3 and 5 (HFC-1/S/SP) + * + * This filter examins and verifies the pattern + * generated by ihfc_test_Bwrite. + * + * NOTE: This filter is only for testing purpose. + *---------------------------------------------------------------------------*/ +void +ihfc_test_Bread (ihfc_sc_t *sc, u_char chan) +{ + static u_short toterrors = 0; + + register u_short reclen, len, tlen; + register u_char fb, tmp; + + register u_short xlen = S_HDLC_IB; + register u_char *dst = NULL; + register u_char error = S_HDLC_TMP; + register u_char ecount = S_HDLC_FLAG; + + BUS_VAR; + + if (S_UNIT != 0) return; + + reclen = (u_short)ihfc_Bsel_fifo(sc, chan, 0); + + S_BYTES += reclen; + + tlen = S_HDLC_CRC; + + fb = 0x40; + + if (S_MBUF) + { + len = S_MBUFLEN; + dst = S_MBUFDATA + (BCH_MAX_DATALEN - len); + } + else + { + len = 0; + } + + SET_REG(0xba + chan); + + while (reclen--) + { +/* if (tmp2 & 0x100) while(GET_STAT & 1); + * tmp = (u_char)(tmp2 = READ_BOTH_2); + */ + if (GET_STAT & 1) + { + /* if (!(++busy % 4)) reclen++; */ + while(GET_STAT & 1); + } + + tmp = READ_DATA_1; + + if ((tmp & 0x3f) == 0x3e) + { + if ((BCH_MAX_DATALEN - len) != 201) error |= 4; + + if ((S_MBUF) && (error)) + { + if (len) { len--; *dst++ = error; } + if (len) { len--; *dst++ = xlen+1; } + if (len) { len--; *dst++ = ecount; } + + S_MBUFLEN = BCH_MAX_DATALEN - len; + + if (S_TRACE & TRACE_B_RX) + ihfc_putmbuf(sc, chan, S_MBUF); + else + i4b_Bfreembuf(S_MBUF); + + S_MBUF = NULL; + printf("(error%d, %d, %d)", S_UNIT, ecount, toterrors++); + } + + i4b_Bfreembuf(S_MBUF); + S_MBUF = i4b_Bgetmbuf(BCH_MAX_DATALEN); + + dst = S_MBUFDATA; + len = BCH_MAX_DATALEN; + + xlen = 200; + error = 0; + ecount = 0; + + /* SET_REG(0xba + chan); */ + } + else + { + if (!xlen) error |= 2; + if ((tmp ^ xlen--) & 0xef) { error |= 1; ecount++; } + } + if (!tlen--) fb |= 0x20; + + if (len--) + { + *dst++ = (tmp | fb); + } + else + { + len++; + } + + fb = 0; + } + + if (S_MBUF) + { + S_MBUFLEN = len; + } + + S_HDLC_IB = xlen; + S_HDLC_TMP = error; + S_HDLC_FLAG = ecount; +} + +#endif /* NIHFC > 0 */ diff --git a/sys/i4b/layer1/ihfc/i4b_ihfc_drv.h b/sys/i4b/layer1/ihfc/i4b_ihfc_drv.h new file mode 100644 index 0000000..d0456ad --- /dev/null +++ b/sys/i4b/layer1/ihfc/i4b_ihfc_drv.h @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2000 Hans Petter Selasky. 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_ihfc_drv.h - include file for the HFC-1/S/SP driver + * ------------------------------------------------------- + * + * last edit-date: [Wed Jul 19 09:40:55 2000] + * + * $Id: i4b_ihfc_drv.h,v 1.7 2000/09/19 13:50:36 hm Exp $ + * + * $FreeBSD$ + * + *---------------------------------------------------------------------------*/ +#ifndef I4B_IHFC_DRV_H_ +#define I4B_IHFC_DRV_H_ + +/*---------------------------------------------------------------------------* + * Ramptables related fifo (HFC-1/S/SP) + * + * The HFC-SP chip only uses ihfc_xxx[2] values for D-channel! + * NOTE: These tables are not used anymore. + *---------------------------------------------------------------------------* + * + * w - write, r - read: D1_w D1_r B1_w B1_r B2_w B2_r + * const u_char ihfc_readtable[6] = {0xa6, 0xa7, 0xbc, 0xbd, 0xbe, 0xbf}; + * const u_char ihfc_writetable[6] = {0x96, 0x97, 0xac, 0xad, 0xae, 0xaf}; + * const u_char ihfc_f1inctable[6] = {0x92, 0x93, 0xa8, 0xa9, 0xaa, 0xab}; + * const u_char ihfc_f2inctable[6] = {0xa2, 0xa3, 0xb8, 0xb9, 0xba, 0xbb}; + * + * const struct { u_char z1L, z1H, z2L, z2H, f1, f2, dummy; } + * ihfc_countertable[6] = { + * {0x90, 0x94, 0x98, 0x9c, 0x9a, 0x9e, 0x00}, D1_w + * {0x91, 0x95, 0x99, 0x9d, 0x9b, 0x9f, 0x00}, D1_r + * {0x80, 0x84, 0x88, 0x8c, 0xb0, 0xb4, 0x00}, B1_w + * {0x81, 0x85, 0x89, 0x8d, 0xb1, 0xb5, 0x00}, B1_r + * {0x82, 0x86, 0x8a, 0x8e, 0xb2, 0xb6, 0x00}, B2_w + * {0x83, 0x87, 0x8b, 0x8f, 0xb3, 0xb7, 0x00} B2_r + * }; + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + * Ramptables related to configuration (HFC-1/S/SP) + * + * NOTE: Write registers only + *---------------------------------------------------------------------------*/ +const u_char ihfc_configtable[11] = +{ + 0x18, 0x19, 0x1a, /* cirm, ctmt, int_m1 */ + 0x1b, 0x2e, 0x37, /* int_m2, mst_mode, clkdel */ + 0x31, 0x2f, 0x32, /* sctrl, connect, test/sctrl_e */ + 0x33, 0x00 /* sctrl_r */ +}; +const u_char isac_configtable[9] = +{ + 0x39, 0x30, 0x3b, /* adf2, spcr, sqxr */ + 0x38, 0x37, 0x22, /* adf1, stcr, mode */ + 0x20, 0x2b, 0x00 /* mask, star2 */ +}; + +/*---------------------------------------------------------------------------* + * Ramptables related to statemachine (HFC-1/S/SP) + * + * state: + * 0 = deactivated + * 1 = pending + * 2 = syncronized + * 3 = activated + * 4 = error + * 5 = reset + * -1 = illegal + *---------------------------------------------------------------------------*/ + +const struct ihfc_FSMtable { u_char state, *string; } + + ihfc_TEtable[16] = /* HFC-S/SP - TE */ +{ + { 0x05 ,"Reset" }, + { 0xff , 0 }, + { 0x01 ,"Sensing" }, + { 0x00 ,"Deactivated" }, + { 0x01 ,"Awaiting signal" }, + { 0x01 ,"Identifying input" }, + { 0x02 ,"Syncronized" }, + { 0x03 ,"Activated" }, + { 0x04 ,"Lost framing" }, + { 0xff , 0 }, + { 0xff , 0 }, + { 0xff , 0 }, + { 0xff , 0 }, + { 0xff , 0 }, + { 0xff , 0 }, + { 0xff , 0 } +}, + ihfc_NTtable[16] = /* HFC-S/SP - NT */ +{ + { 0x05 ,"Reset" }, + { 0x00 ,"Deactive" }, + { 0x02 ,"Pending activation" }, + { 0x03 ,"Active" }, + { 0x01 ,"Pending deactivation" }, + { 0xff , 0 }, + { 0xff , 0 }, + { 0xff , 0 }, + { 0xff , 0 }, + { 0xff , 0 }, + { 0xff , 0 }, + { 0xff , 0 }, + { 0xff , 0 }, + { 0xff , 0 }, + { 0xff , 0 }, + { 0xff , 0 } +}, + ihfc_TEtable2[16] = /* HFC-1/ISAC - TE */ +{ + { 0x00 ,"Deactivate request" }, + { 0xff , 0 }, + { 0xff , 0 }, + { 0xff , 0 }, + { 0x01 ,"Level detected" }, + { 0xff , 0 }, + { 0x04 ,"Error indication" }, + { 0x00 ,"Power-up" }, + { 0x02 ,"Activate request downstream" }, + { 0xff , 0 }, + { 0x00 ,"Test indication" }, + { 0x00 ,"Awake test indication" }, + { 0x03 ,"Activate ind. with priority class 8" }, + { 0x03 ,"Activate ind. with priority class 10" }, + { 0xff , 0 }, + { 0x00 ,"Deactivate indication downstream" } +}; + +/*---------------------------------------------------------------------------* + * Ramptable related to ISAC EXIR (HFC-1) + * + * cmd: command to execute, if any. + * + *---------------------------------------------------------------------------*/ +const struct ihfc_EXIRtable { u_char cmd, *string; } + + ihfc_EXIRtable[8] = +{ + { 0x00 ,"Watchdog Timer Overflow" }, + { 0x00 ,"Subscriber Awake" }, + { 0x00 ,"Monitor Status" }, + { 0x00 ,"Rx Sync Xfer Overflow" }, + { 0xc0 ,"Rx Frame Overflow" }, /* RMC + RRES */ + { 0x00 ,"Protocol Error" }, + { 0x01 ,"Tx Data Underrun" }, /* XRES */ + { 0x01 ,"Tx Message Repeat" }, /* XRES */ +}; + +/*---------------------------------------------------------------------------* + * Ramptables related to S/Q - channel (HFC-1/S/SP) + * + * From TE's viewpoint: + * Q: commands to NT + * S: indications from NT + * + * From NT's viewpoint: + * Q: indications from TE + * S: commands to TE + * + * cmd: not used + *---------------------------------------------------------------------------*/ +const struct ihfc_SQtable { u_char cmd, *string; } + + ihfc_Qtable[16] = +{ + { 0x00, "Loss of Power indication" }, + { 0x00, "ST request" }, + { 0x00, 0 }, + { 0x00, "LoopBack request (B1/B2)" }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, "LoopBack request (B1)" }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, 0 }, + { 0x00, "LoopBack request (B2)" }, + { 0x00, "V-DCE slave mode" }, + { 0x00, "V-DTE slave mode" }, + { 0x00, 0 }, + { 0x00, "Idle" } +}, + ihfc_Stable[16] = +{ + { 0x00, "Idle" }, + { 0x00, "ST Fail" }, + { 0x00, "ST Pass" }, + { 0x00, "Disruptive Operation Indication" }, + { 0x00, "DTSE-OUT" }, + { 0x00, "V-DCE master mode" }, + { 0x00, "ST Indication" }, + { 0x00, "DTSE-IN" }, + { 0x00, "LoopBack indication (B1/B2)" }, + { 0x00, "Loss of Received Signal indication" }, + { 0x00, "LoopBack indication (B2)" }, + { 0x00, "DTSE-IN and OUT" }, + { 0x00, "LoopBack indication (B1)" }, + { 0x00, "Loss of power indication" } +}; + + +#endif /* I4B_IHFC_DRV_H_ */ + diff --git a/sys/i4b/layer1/ihfc/i4b_ihfc_ext.h b/sys/i4b/layer1/ihfc/i4b_ihfc_ext.h new file mode 100644 index 0000000..0d1ee44 --- /dev/null +++ b/sys/i4b/layer1/ihfc/i4b_ihfc_ext.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2000 Hans Petter Selasky. 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_ihfc_ext.h - ihfc common prototypes + * --------------------------------------- + * + * last edit-date: [Wed Jul 19 09:40:59 2000] + * + * $Id: i4b_ihfc_ext.h,v 1.6 2000/08/20 07:14:08 hm Exp $ + * + * $FreeBSD$ + * + *---------------------------------------------------------------------------*/ + +#ifndef I4B_IHFC_EXT_H_ +#define I4B_IHFC_EXT_H_ + +#include <i4b/include/i4b_l3l4.h> + + +/* prototypes from i4b_ihfc_l1if.c */ + +extern struct i4b_l1mux_func ihfc_l1mux_func; + +void ihfc_B_linkinit (ihfc_sc_t *sc); +struct mbuf * ihfc_getmbuf (ihfc_sc_t *sc, u_char chan); +void ihfc_putmbuf (ihfc_sc_t *sc, u_char chan, struct mbuf *m); + + +/* prototypes from i4b_ihfc_drv.c */ + +void ihfc_intr1 (ihfc_sc_t *sc); +void ihfc_intr2 (ihfc_sc_t *sc); + +int ihfc_control (ihfc_sc_t *sc, int flag); +void ihfc_fsm (ihfc_sc_t *sc, int flag); +int ihfc_init (ihfc_sc_t *sc, u_char chan, int prot, int activate); + +#endif /* I4B_IHFC_EXT_H_ */ diff --git a/sys/i4b/layer1/ihfc/i4b_ihfc_l1if.c b/sys/i4b/layer1/ihfc/i4b_ihfc_l1if.c new file mode 100644 index 0000000..4f9f4e9 --- /dev/null +++ b/sys/i4b/layer1/ihfc/i4b_ihfc_l1if.c @@ -0,0 +1,517 @@ +/* + * Copyright (c) 2000 Hans Petter Selasky. 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_ihfc_l1.c - hfc layer 1 handler + * ----------------------------------- + * + * The idea of this file is to seperate hfcs/sp/pci data/signal + * handling and the I4B data/signal handling. + * + * Everything which has got anything to do with I4B has been put here! + * + * last edit-date: [Wed Jul 19 09:41:03 2000] + * + * $Id: i4b_ihfc_l1if.c,v 1.10 2000/09/19 13:50:36 hm Exp $ + * + * $FreeBSD$ + * + *---------------------------------------------------------------------------*/ + +#include "ihfc.h" + +#if (NIHFC > 0) + +#include <sys/param.h> +#include <sys/kernel.h> +#include <sys/systm.h> +#include <sys/mbuf.h> +#include <sys/socket.h> + +#include <machine/stdarg.h> +#include <machine/clock.h> + +#include <net/if.h> + +#include <machine/i4b_debug.h> +#include <machine/i4b_ioctl.h> +#include <machine/i4b_trace.h> + +#include <i4b/include/i4b_mbuf.h> +#include <i4b/include/i4b_global.h> +#include <i4b/include/i4b_l1l2.h> + +#include <i4b/layer1/i4b_l1.h> +#include <i4b/layer1/ihfc/i4b_ihfc.h> +#include <i4b/layer1/ihfc/i4b_ihfc_ext.h> + +/*---------------------------------------------------------------------------* + * Local prototypes + * + * NOTE: The prototypes for get/putmbuf and B_linkinit + * have been put in i4b_hfc_ext.h for global hfc use. + * + * NOTE: channel != chan + *---------------------------------------------------------------------------*/ +static +isdn_link_t * ihfc_B_ret_linktab (int unit, int channel); +static void ihfc_B_set_linktab (int unit, int channel, drvr_link_t *B_linktab); + +static void ihfc_B_start (int unit, int chan); +static void ihfc_B_stat (int unit, int chan, bchan_statistics_t *bsp); + void ihfc_B_setup (int unit, int chan, int bprot, int activate); + +static int ihfc_mph_command_req (int unit, int command, void *parm); + +static int ihfc_ph_activate_req (int unit); +static int ihfc_ph_data_req (int unit, struct mbuf *m, int freeflag); + +static void ihfc_T3_expired (ihfc_sc_t *sc); + +/*---------------------------------------------------------------------------* + * Our I4B L1 mulitplexer link + *---------------------------------------------------------------------------*/ +struct i4b_l1mux_func ihfc_l1mux_func = { + ihfc_B_ret_linktab, + ihfc_B_set_linktab, + ihfc_mph_command_req, + ihfc_ph_data_req, + ihfc_ph_activate_req, +}; + +/*---------------------------------------------------------------------------* + * L2 -> L1: PH-DATA-REQUEST (D-Channel) + * + * NOTE: We may get called here from ihfc_hdlc_Dread or isac_hdlc_Dread + * via the upper layers. + *---------------------------------------------------------------------------*/ +int +ihfc_ph_data_req(int unit, struct mbuf *m, int freeflag) +{ + ihfc_sc_t *sc = &ihfc_softc[unit]; + u_char chan = 0; + HFC_VAR; + + if (!m) return 0; + + HFC_BEG; + + if(S_PHSTATE != 3) + { + NDBGL1(L1_PRIM, "L1 was not running: " + "ihfc_ph_activate_req(unit = %d)!", unit); + + ihfc_ph_activate_req(unit); + } + + /* "Allow" I-frames (-hp) */ + + if (freeflag == MBUF_DONTFREE) m = m_copypacket(m, M_DONTWAIT); + + if (!IF_QFULL(&S_IFQUEUE) && m) + { + IF_ENQUEUE(&S_IFQUEUE, m); + + ihfc_B_start(unit, chan); /* (recycling) */ + } + else + { + NDBGL1(L1_ERROR, "No frame out (unit = %d)", unit); + i4b_Dfreembuf(m); + } + + if (S_INTR_ACTIVE) S_INT_S1 |= 0x04; + + HFC_END; + + return 1; +} + +/*---------------------------------------------------------------------------* + * L2 -> L1: PH-ACTIVATE-REQUEST (B-channel and D-channel) + *---------------------------------------------------------------------------*/ +int +ihfc_ph_activate_req(int unit) +{ + ihfc_sc_t *sc = &ihfc_softc[unit]; + HFC_VAR; + + HFC_BEG; + + if ((!S_STM_T3) && (S_PHSTATE != 3)) + { + HFC_FSM(sc, 1); + + S_STM_T3 = 1; + S_STM_T3CALLOUT = timeout((TIMEOUT_FUNC_T) + ihfc_T3_expired, (ihfc_sc_t *)sc, + IHFC_ACTIVATION_TIMEOUT); + } + + HFC_END; + return 0; +} +/*---------------------------------------------------------------------------* + * T3 timeout - persistant deactivation + *---------------------------------------------------------------------------*/ +void +ihfc_T3_expired(ihfc_sc_t *sc) +{ + u_char chan = 0; + HFC_VAR; + + HFC_BEG; + + S_STM_T3 = 0; + + if (S_PHSTATE != 3) /* line was not activated */ + { + i4b_Dcleanifq(&S_IFQUEUE); + i4b_l1_ph_deactivate_ind(S_I4BUNIT); + + i4b_l1_mph_status_ind(S_I4BUNIT, STI_PDEACT, 0, 0); + + HFC_FSM(sc, 2); /* L1 deactivate */ + } + + HFC_END; +} + +/*---------------------------------------------------------------------------* + * Command from the upper layers (B-channel and D-channel) + *---------------------------------------------------------------------------*/ +int +ihfc_mph_command_req(int unit, int command, void *parm) +{ + ihfc_sc_t *sc = &ihfc_softc[unit]; + + switch(command) + { + case CMR_DOPEN: /* daemon running */ + NDBGL1(L1_PRIM, + "unit %d, command = CMR_DOPEN", unit); + S_ENABLED = 1; + break; + + case CMR_DCLOSE: /* daemon not running */ + NDBGL1(L1_PRIM, + "unit %d, command = CMR_DCLOSE", unit); + S_ENABLED = 0; + break; + + case CMR_SETTRACE: /* set new trace mask */ + NDBGL1(L1_PRIM, + "unit %d, command = CMR_SETTRACE, parm = %d", + unit, (unsigned int)parm); + S_TRACE = (unsigned int)parm; + break; + + case CMR_GCST: /* get chip statistic */ + NDBGL1(L1_PRIM, + "unit %d, command = CMR_GCST, parm = %d", + unit, (unsigned int)parm); + + #define CST ((struct chipstat *)parm) + + CST->driver_type = L1DRVR_IHFC; + + /* XXX CST->xxxx_stat = xxx; */ + + #undef CST + break; + + default: + NDBGL1(L1_ERROR, + "ERROR, unknown command = %d, unit = %d, parm = %d", + command, unit, (unsigned int)parm); + break; + } + + return 0; +} + +/*---------------------------------------------------------------------------* + * Data source switch for Read channels - 1, 3 and 5 (B and D-Channel) + *---------------------------------------------------------------------------*/ +void +ihfc_putmbuf (ihfc_sc_t *sc, u_char chan, struct mbuf *m) +{ + i4b_trace_hdr_t hdr; + + if (chan < 2) + { + if(S_TRACE & TRACE_D_RX) + { + hdr.count = ++S_DTRACECOUNT; + hdr.dir = FROM_NT; + hdr.type = TRC_CH_D; + hdr.unit = S_I4BUNIT; + + MICROTIME(hdr.time); + + i4b_l1_trace_ind(&hdr, m->m_len, m->m_data); + } + + if (!S_ENABLED) { i4b_Dfreembuf(m); return; } + + m->m_pkthdr.len = m->m_len; + + i4b_l1_ph_data_ind(S_I4BUNIT, m); + } + else + { + if(S_TRACE & TRACE_B_RX) + { + hdr.count = ++S_BTRACECOUNT; + hdr.dir = FROM_NT; + hdr.type = (chan < 4) ? TRC_CH_B1 : TRC_CH_B2; + hdr.unit = S_I4BUNIT; + + MICROTIME(hdr.time); + + i4b_l1_trace_ind(&hdr, m->m_len, m->m_data); + } + + if (!S_ENABLED) { i4b_Bfreembuf(m); return; } + + if (S_PROT == BPROT_NONE) + { + if(!i4b_l1_bchan_tel_silence(m->m_data, m->m_len)) + { + S_BDRVLINK->bch_activity(S_BDRVLINK->unit, ACT_RX); + } + + if (!IF_QFULL(&S_IFQUEUE)) + { + S_BYTES += m->m_len; + IF_ENQUEUE(&S_IFQUEUE, m); + S_BDRVLINK->bch_rx_data_ready(S_BDRVLINK->unit); + } + + return; + } + + if (S_PROT == BPROT_RHDLC) + { + S_MBUFDUMMY = m; + S_BYTES += m->m_pkthdr.len = m->m_len; + S_BDRVLINK->bch_rx_data_ready(S_BDRVLINK->unit); + S_MBUFDUMMY = NULL; + + return; + } + + NDBGL1(L1_ERROR, "Unknown protocol: %d", S_PROT); + } +} + +/*---------------------------------------------------------------------------* + * Data destinator switch for write channels - 0, 2 and 4 + *---------------------------------------------------------------------------*/ +struct mbuf * +ihfc_getmbuf (ihfc_sc_t *sc, u_char chan) +{ + register struct mbuf *m; + i4b_trace_hdr_t hdr; + + if (chan < 2) + { + IF_DEQUEUE(&S_IFQUEUE, m); + + if((S_TRACE & TRACE_D_TX) && m) + { + hdr.count = ++S_DTRACECOUNT; + hdr.dir = FROM_TE; + hdr.type = TRC_CH_D; + hdr.unit = S_I4BUNIT; + + MICROTIME(hdr.time); + + i4b_l1_trace_ind(&hdr, m->m_len, m->m_data); + } + } + else + { + IF_DEQUEUE(&S_IFQUEUE, m); + + if (!m) + { + S_BDRVLINK->bch_tx_queue_empty(S_BDRVLINK->unit); + + IF_DEQUEUE(&S_IFQUEUE, m); + } + if (m) + { + if(!i4b_l1_bchan_tel_silence(m->m_data, m->m_len)) + { + S_BDRVLINK->bch_activity(S_BDRVLINK->unit, ACT_TX); + } + + S_BYTES += m->m_len; + + if(S_TRACE & TRACE_B_TX) + { + hdr.count = ++S_BTRACECOUNT; + hdr.dir = FROM_TE; + hdr.type = (chan < 4) ? TRC_CH_B1 : TRC_CH_B2; + hdr.unit = S_I4BUNIT; + + MICROTIME(hdr.time); + + i4b_l1_trace_ind(&hdr, m->m_len, m->m_data); + } + } + } + + return(m); +} + +/*---------------------------------------------------------------------------* + * Initialize rx/tx data structures (B-channel) + *---------------------------------------------------------------------------*/ +void +ihfc_B_setup(int unit, int chan, int bprot, int activate) +{ + ihfc_sc_t *sc = &ihfc_softc[unit]; + HFC_VAR; + + if (((u_int)chan > 5) || ((u_int)chan < 2)) return; + + HFC_BEG; + + HFC_INIT(sc, chan, bprot, activate); + + HFC_END; +} + +/*---------------------------------------------------------------------------* + * Start transmission (B-channel or D-channel tx) + * NOTE: if "chan" variable is corrupted, it will not cause any harm, + * but data may be lost and there may be software sync. errors. + *---------------------------------------------------------------------------*/ +void +ihfc_B_start(int unit, int chan) +{ + ihfc_sc_t *sc = &ihfc_softc[unit]; + HFC_VAR; + + if ((u_int)chan > 5) return; + + HFC_BEG; + + if (S_FILTER && !S_MBUF && !S_INTR_ACTIVE) + { + S_INTR_ACTIVE |= 2; /* never know what * + * they put in the * + * L2 code */ + + S_FILTER(sc, chan); /* quick tx */ + + S_INTR_ACTIVE &= ~2; + } + + HFC_END; +} + +/*---------------------------------------------------------------------------* + * Fill statistics struct (B-channel) + *---------------------------------------------------------------------------*/ +void +ihfc_B_stat(int unit, int chan, bchan_statistics_t *bsp) +{ + ihfc_sc_t *sc = &ihfc_softc[unit]; + HFC_VAR; + + if ((u_int)chan > 5) return; + + chan &= ~1; + + HFC_BEG; + + bsp->inbytes = S_BYTES; S_BYTES = 0; + + chan++; + + bsp->outbytes = S_BYTES; S_BYTES = 0; + + HFC_END; +} + +/*---------------------------------------------------------------------------* + * Return the address of IHFC linktab to I4B (B-channel) + *---------------------------------------------------------------------------*/ +isdn_link_t * +ihfc_B_ret_linktab(int unit, int channel) +{ + ihfc_sc_t *sc = &ihfc_softc[unit]; + + if (channel < 2) + return(&sc->sc_blinktab[channel]); + else + return 0; +} + +/*---------------------------------------------------------------------------* + * Set the I4B driver linktab for IHFC use (B-channel) + *---------------------------------------------------------------------------*/ +void +ihfc_B_set_linktab(int unit, int channel, drvr_link_t *B_linktab) +{ + ihfc_sc_t *sc = &ihfc_softc[unit]; + + if (channel < 2) + sc->sc_bdrvlinktab[channel] = B_linktab; +} + +/*---------------------------------------------------------------------------* + * Initialize linktab for I4B use (B-channel) + *---------------------------------------------------------------------------*/ +void +ihfc_B_linkinit(ihfc_sc_t *sc) +{ + u_char chan; + + /* make sure the hardware driver is known to layer 4 */ + ctrl_types[CTRL_PASSIVE].set_linktab = i4b_l1_set_linktab; + ctrl_types[CTRL_PASSIVE].get_linktab = i4b_l1_ret_linktab; + + for (chan = 2; chan < 6; chan++) + { + S_BLINK.unit = S_UNIT; + S_BLINK.channel = chan; /* point to tx-chan */ + S_BLINK.bch_config = ihfc_B_setup; + S_BLINK.bch_tx_start = ihfc_B_start; + S_BLINK.bch_stat = ihfc_B_stat; + + /* This is a transmit channel (even) */ + S_BLINK.tx_queue = &S_IFQUEUE; + chan++; + /* This is a receive channel (odd) */ + S_BLINK.rx_queue = &S_IFQUEUE; + S_BLINK.rx_mbuf = &S_MBUFDUMMY; + } +} + +#endif /* NIHFC > 0 */ diff --git a/sys/i4b/layer1/ihfc/i4b_ihfc_pnp.c b/sys/i4b/layer1/ihfc/i4b_ihfc_pnp.c new file mode 100644 index 0000000..f8fb9af --- /dev/null +++ b/sys/i4b/layer1/ihfc/i4b_ihfc_pnp.c @@ -0,0 +1,421 @@ +/* + * Copyright (c) 2000 Hans Petter Selasky. 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_ihfc_pnp.c - common hfc ISA PnP-bus interface + * ------------------------------------------------- + * + * - Everything which has got anything to to with "PnP" bus setup has + * been put here. + * + * + * last edit-date: [Wed Jul 19 09:41:07 2000] + * + * $Id: i4b_ihfc_pnp.c,v 1.9 2000/09/19 13:50:36 hm Exp $ + * + * $FreeBSD$ + * + *---------------------------------------------------------------------------*/ + +#include "ihfc.h" + +#if (NIHFC > 0) + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/socket.h> +#include <net/if.h> + +#include <sys/mbuf.h> +#include <machine/clock.h> + +#include <i4b/include/i4b_global.h> +#include <i4b/include/i4b_mbuf.h> +#include <i4b/include/i4b_l1l2.h> + +#include <machine/i4b_ioctl.h> +#include <machine/i4b_trace.h> + +#include <i4b/layer1/i4b_l1.h> +#include <i4b/layer1/ihfc/i4b_ihfc.h> +#include <i4b/layer1/ihfc/i4b_ihfc_ext.h> + +#include <machine/bus.h> +#include <machine/resource.h> +#include <sys/bus.h> +#include <sys/rman.h> + +#include <isa/isavar.h> + +/*---------------------------------------------------------------------------* + * Softc + *---------------------------------------------------------------------------*/ +ihfc_sc_t ihfc_softc[IHFC_MAXUNIT]; + +/*---------------------------------------------------------------------------* + * Prototypes + *---------------------------------------------------------------------------*/ +static int ihfc_isa_probe (device_t dev); +static int ihfc_pnp_probe (device_t dev); +static int ihfc_pnp_attach (device_t dev); +static int ihfc_pnp_detach (device_t dev, u_int flag); +static int ihfc_pnp_shutdown (device_t dev); + +const struct ihfc_pnp_ids +{ + u_long vid; /* vendor id */ + int flag; /* */ + u_char hfc; /* chip type */ + u_char iirq; /* internal irq */ + u_short iio; /* internal io-address */ + u_char stdel; /* S/T delay compensation */ +} + ihfc_pnp_ids[] = +{ + { 0x10262750, FLAG_TELES_S0_163C, HFC_S , 2, 0x200 , 0xd}, + { 0x20262750, FLAG_TELES_S0_163C, HFC_SP, 0, 0x000 , 0xf}, + { 0x1411d805, FLAG_ACER_P10 , HFC_S , 1, 0x300 , 0xe}, + { 0 } +}; + +typedef const struct ihfc_pnp_ids ihfc_id_t; + +/*---------------------------------------------------------------------------* + * PCB layout + * + * IIRQx: Internal IRQ cross reference for a card + * IRQx : Supported IRQ's for a card + * IOx : Supported IO-bases for a card + * + * IO0, IRQ0, IIRQ0: TELEINT ISDN SPEED No. 1 + * IIRQ3: Teles 16.3c PnP (B version) + *---------------------------------------------------------------------------*/ + /* IRQ -> 0 1 2 3 4 5 6 7 8 9 a b c d e f */ +#define IIRQ0 ((const u_char []){ 0, 0, 0, 1, 2, 3, 0, 4, 0, 0, 5, 6, 0, 0, 0, 0 }) +#define IRQ0 ((const u_char []){ 3, 4, 5, 7, 0xa, 0xb, 0 }) + +#define IO0 ((const u_long []){ 0x300, 0x330, 0x278, 0x2e8, 0 }) + +#define IIRQ3 ((const u_char []){ 0, 0, 0, 7, 0, 1, 0, 0, 0, 2, 3, 4, 5, 0, 0, 6 }) + +/*---------------------------------------------------------------------------* + * ISA PnP setup + *---------------------------------------------------------------------------*/ +static device_method_t ihfc_pnp_methods[] = +{ + DEVMETHOD(device_probe, ihfc_pnp_probe), + DEVMETHOD(device_attach, ihfc_pnp_attach), + DEVMETHOD(device_shutdown, ihfc_pnp_shutdown), + { 0, 0 } +}; + +static driver_t ihfc_pnp_driver = +{ + "ihfc", + ihfc_pnp_methods, + 0, +}; + +static devclass_t ihfc_devclass; + +DRIVER_MODULE(ihfcpnp, isa, ihfc_pnp_driver, ihfc_devclass, 0, 0); + +/*---------------------------------------------------------------------------* + * probe for ISA "PnP" card + *---------------------------------------------------------------------------*/ +int +ihfc_pnp_probe(device_t dev) +{ + u_int unit = device_get_unit(dev); /* get unit */ + u_int32_t vid = isa_get_vendorid(dev); /* vendor id */ + ihfc_id_t *ids = &ihfc_pnp_ids[0]; /* ids ptr */ + ihfc_sc_t *sc = &ihfc_softc[unit]; /* softc */ + + HFC_VAR; + + if (unit >= IHFC_MAXUNIT) + { + printf("ihfc%d: Error, unit %d >= IHFC_MAXUNIT", unit, unit); + return ENXIO; + } + + if (!vid) return ihfc_isa_probe(dev); + + HFC_BEG; + + for ( ;(ids->vid); ids++) + { + if (ids->vid == vid) + { + bzero(sc, sizeof(ihfc_sc_t)); /* reset data structure */ + + S_IOBASE[0] = bus_alloc_resource( + dev, SYS_RES_IOPORT, &S_IORID[0], + 0UL, ~0UL, 2, RF_ACTIVE + ); + + S_IRQ = bus_alloc_resource( + dev, SYS_RES_IRQ, &S_IRQRID, + 0UL, ~0UL, 1, RF_ACTIVE + ); + + S_DLP = IHFC_DLP; /* set D-priority */ + S_HFC = ids->hfc; /* set chip type */ + S_I4BFLAG = ids->flag; /* set flag */ + S_NTMODE = IHFC_NTMODE; /* set mode */ + S_STDEL = ids->stdel; /* set delay */ + + S_I4BUNIT = L0IHFCUNIT(unit); /* set "i4b" unit */ + S_TRACE = TRACE_OFF; /* set trace mask */ + S_UNIT = unit; /* set up unit numbers */ + + if (S_IOBASE[0] && S_IRQ) + { + if (ids->iio) + { + S_IIO = ids->iio; + S_IIRQ = ids->iirq; + } + else + { + S_IIO = rman_get_start(S_IOBASE[0]) & 0x3ff; + S_IIRQ = IIRQ3[rman_get_start(S_IRQ) & 0xf]; + } + + if (!HFC_CONTROL(sc, 1)) + { + HFC_END; + return 0; /* success */ + } + else + { + printf("ihfc%d: Chip seems corrupted. " + "Please hard reboot your computer!\n", + unit); + } + } + + ihfc_pnp_detach(dev, 0); + } + } + + HFC_END; + return ENXIO; /* failure */ +} + +/*---------------------------------------------------------------------------* + * probe for "ISA" cards + *---------------------------------------------------------------------------*/ +int +ihfc_isa_probe(device_t dev) +{ + u_int unit = device_get_unit(dev); /* get unit */ + ihfc_sc_t *sc = &ihfc_softc[unit]; /* softc */ + const u_char *irq = &IRQ0[0]; /* irq's to try */ + const u_long *iobase = &IO0[0]; /* iobases to try */ + + HFC_VAR; + + bzero(sc, sizeof(ihfc_sc_t)); /* reset data structure * + * We must reset the * + * datastructure here, * + * else we risk zero-out * + * our gotten resources. */ + HFC_BEG; + + j0: while(*irq) /* get supported IRQ */ + { + if ((S_IRQ = bus_alloc_resource( + dev, SYS_RES_IRQ, &S_IRQRID, + *irq, *irq, 1, RF_ACTIVE + ) + )) + break; + else + irq++; + } + + while(*iobase) /* get supported IO-PORT */ + { + if ((S_IOBASE[0] = bus_alloc_resource( + dev, SYS_RES_IOPORT, &S_IORID[0], + *iobase, *iobase, 2, RF_ACTIVE + ) + )) + break; + else + iobase++; + } + + if (*irq && *iobase) /* we got our resources, now test chip */ + { + S_DLP = IHFC_DLP; /* set D-priority */ + S_HFC = HFC_1; /* set chip type */ + S_I4BFLAG = FLAG_TELEINT_NO_1; /* set flag */ + S_NTMODE = IHFC_NTMODE; /* set mode */ + S_STDEL = 0x00; /* set delay (not used) */ + + S_I4BUNIT = L0IHFCUNIT(unit); /* set "i4b" unit */ + S_TRACE = TRACE_OFF; /* set trace mask */ + S_UNIT = unit; /* set up unit numbers */ + + S_IIRQ = IIRQ0[*irq]; /* set internal irq */ + S_IIO = *iobase; /* set internal iobase */ + + if (!HFC_CONTROL(sc, 1)) + { + device_set_desc(dev, "TELEINT ISDN SPEED No. 1"); + + HFC_END; + return 0; /* success */ + } + } + + ihfc_pnp_detach(dev, 0); + + if (*irq && *++iobase) goto j0; /* try again */ + + HFC_END; + + printf("ihfc%d: Chip not found. " + "A hard reboot may help!\n", unit); + + return ENXIO; /* failure */ +} + +/*---------------------------------------------------------------------------* + * attach ISA "PnP" card + *---------------------------------------------------------------------------*/ +int +ihfc_pnp_attach(device_t dev) +{ + u_int unit = device_get_unit(dev); /* get unit */ + ihfc_sc_t *sc = &ihfc_softc[unit]; /* softc */ + void *dummy = 0; /* a dummy */ + HFC_VAR; + + HFC_BEG; + + ihfc_B_linkinit(sc); /* Setup B-Channel linktabs */ + + i4b_l1_mph_status_ind(S_I4BUNIT, STI_ATTACH, S_I4BFLAG, &ihfc_l1mux_func); + + HFC_INIT(sc, 0, 0, 1); /* Setup D - Channel */ + + HFC_INIT(sc, 2, 0, 0); /* Init B1 - Channel */ + HFC_INIT(sc, 4, 0, 0); /* Init B2 - Channel */ + + bus_setup_intr(dev, S_IRQ, INTR_TYPE_NET, (void(*)(void*)) + HFC_INTR, sc, &dummy); + + HFC_END; + return 0; /* success */ + + HFC_END; + return ENXIO; /* failure */ +} + +/*---------------------------------------------------------------------------* + * shutdown for our ISA PnP card + *---------------------------------------------------------------------------*/ +int +ihfc_pnp_shutdown(device_t dev) +{ + u_int unit = device_get_unit(dev); /* get unit */ + ihfc_sc_t *sc = &ihfc_softc[unit]; /* softc */ + HFC_VAR; + + HFC_BEG; + + if (unit >= IHFC_MAXUNIT) + { + printf("ihfc%d: Error, unit %d >= IHFC_MAXUNIT", unit, unit); + goto f0; + } + + HFC_CONTROL(sc, 2); /* shutdown chip */ + + HFC_END; + return 0; + f0: + HFC_END; + return ENXIO; + +} + +/*---------------------------------------------------------------------------* + * detach for our ISA PnP card + * + * flag: bit[0] set: teardown interrupt handler too + *---------------------------------------------------------------------------*/ +int +ihfc_pnp_detach (device_t dev, u_int flag) +{ + u_int unit = device_get_unit(dev); /* get unit */ + ihfc_sc_t *sc = &ihfc_softc[unit]; /* softc */ + u_char i; + + if (unit >= IHFC_MAXUNIT) + { + printf("ihfc%d: Error, unit %d >= IHFC_MAXUNIT", unit, unit); + return 0; + } + + /* free interrupt resources */ + + if(S_IRQ) + { + if (flag & 1) + { + /* tear down interrupt handler */ + bus_teardown_intr(dev, S_IRQ, (void(*)(void *))HFC_INTR); + } + + /* free irq */ + bus_release_resource(dev, SYS_RES_IRQ, S_IRQRID, S_IRQ); + + S_IRQRID = 0; + S_IRQ = 0; + } + + + /* free iobases */ + + for (i = IHFC_IO_BASES; i--;) + { + if(S_IOBASE[i]) + { + bus_release_resource(dev, SYS_RES_IOPORT, + S_IORID[i], S_IOBASE[i]); + S_IORID[i] = 0; + S_IOBASE[i] = 0; + } + } + + return 0; +} + +#endif /* NIHFC > 0 */ diff --git a/sys/i4b/layer1/isa_isic.c b/sys/i4b/layer1/isa_isic.c deleted file mode 100644 index c89bb5d..0000000 --- a/sys/i4b/layer1/isa_isic.c +++ /dev/null @@ -1,836 +0,0 @@ -/* - * Copyright (c) 1997, 1998 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. - * - *--------------------------------------------------------------------------- - * - * isa_isic.c - ISA bus frontend for i4b_isic driver - * -------------------------------------------------- - * - * $FreeBSD$ - * - * last edit-date: [Mon Jul 19 16:39:02 1999] - * - * -mh original implementation - * -hm NetBSD patches from Martin - * - *---------------------------------------------------------------------------*/ - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/errno.h> -#include <sys/syslog.h> -#include <sys/device.h> -#include <sys/socket.h> -#include <net/if.h> -#include <sys/systm.h> -#include <sys/malloc.h> - -#include <machine/cpu.h> -#include <machine/intr.h> -#include <machine/bus.h> - -#include <dev/isa/isavar.h> - -#ifdef __FreeBSD__ -#include <machine/i4b_ioctl.h> -#else -#include <i4b/i4b_ioctl.h> -#endif - -#include <i4b/layer1/i4b_l1.h> - -#if defined(__OpenBSD__) -#define __BROKEN_INDIRECT_CONFIG -#endif - -/* local functions */ -#ifdef __BROKEN_INDIRECT_CONFIG -static int isa_isic_probe __P((struct device *, void *, void *)); -#else -static int isa_isic_probe __P((struct device *, struct cfdata *, void *)); -#endif - -static void isa_isic_attach __P((struct device *, struct device *, void *)); -static int setup_io_map __P((int flags, bus_space_tag_t iot, - bus_space_tag_t memt, bus_size_t iobase, bus_size_t maddr, - int *num_mappings, struct isic_io_map *maps, int *iosize, - int *msize)); -static void args_unmap __P((int *num_mappings, struct isic_io_map *maps)); - -struct cfattach isa_isic_ca = { - sizeof(struct isic_softc), isa_isic_probe, isa_isic_attach -}; - - -/* - * Probe card - */ -static int -#ifdef __BROKEN_INDIRECT_CONFIG -isa_isic_probe(parent, match, aux) -#else -isa_isic_probe(parent, cf, aux) -#endif - struct device *parent; -#ifdef __BROKEN_INDIRECT_CONFIG - void *match; -#else - struct cfdata *cf; -#endif - void *aux; -{ -#ifdef __BROKEN_INDIRECT_CONFIG - struct cfdata *cf = ((struct device*)match)->dv_cfdata; -#endif - struct isa_attach_args *ia = aux; - bus_space_tag_t memt = ia->ia_memt, iot = ia->ia_iot; - int flags = cf->cf_flags; - 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); - return 0; - } - - /* setup MI attach args */ - bzero(&args, sizeof(args)); - args.ia_flags = flags; - - /* if card type specified setup io map for that card */ - switch(flags) - { - case FLAG_TELES_S0_8: - case FLAG_TELES_S0_16: - case FLAG_TELES_S0_163: - case FLAG_AVM_A1: - case FLAG_USR_ISDN_TA_INT: - case FLAG_ITK_IX1: - if (setup_io_map(flags, iot, memt, ia->ia_iobase, ia->ia_maddr, - &args.ia_num_mappings, &args.ia_maps[0], - &(ia->ia_iosize), &ia->ia_msize)) { - ret = 0; - goto done; - } - break; - - default: - /* no io map now, will figure card type later */ - break; - } - - /* probe card */ - switch(flags) - { -#ifdef DYNALINK - case FLAG_DYNALINK: - ret = isic_probe_Dyn(&args); - break; -#endif - -#ifdef TEL_S0_8 - case FLAG_TELES_S0_8: - ret = isic_probe_s08(&args); - break; -#endif - -#ifdef TEL_S0_16 - case FLAG_TELES_S0_16: - ret = isic_probe_s016(&args); - break; -#endif - -#ifdef TEL_S0_16_3 - case FLAG_TELES_S0_163: - ret = isic_probe_s0163(&args); - break; -#endif - -#ifdef AVM_A1 - case FLAG_AVM_A1: - ret = isic_probe_avma1(&args); - break; -#endif - -#ifdef USR_STI - case FLAG_USR_ISDN_TA_INT: - ret = isic_probe_usrtai(&args); - break; -#endif - -#ifdef ITKIX1 - case FLAG_ITK_IX1: - ret = isic_probe_itkix1(&args); - break; -#endif - - default: - /* No card type given, try to figure ... */ - if (ia->ia_iobase == IOBASEUNK) { - ret = 0; -#ifdef TEL_S0_8 - /* only Teles S0/8 will work without IO */ - args.ia_flags = FLAG_TELES_S0_8; - if (setup_io_map(args.ia_flags, iot, memt, ia->ia_iobase, ia->ia_maddr, - &args.ia_num_mappings, &args.ia_maps[0], - &(ia->ia_iosize), &(ia->ia_msize)) == 0) - { - ret = isic_probe_s08(&args); - } -#endif /* TEL_S0_8 */ - } else if (ia->ia_maddr == MADDRUNK) { - ret = 0; -#ifdef TEL_S0_16_3 - /* no shared memory, only a 16.3 based card, - AVM A1, the usr sportster or an ITK would work */ - args.ia_flags = FLAG_TELES_S0_163; - if (setup_io_map(args.ia_flags, iot, memt, ia->ia_iobase, ia->ia_maddr, - &args.ia_num_mappings, &args.ia_maps[0], - &(ia->ia_iosize), &(ia->ia_msize)) == 0) - { - ret = isic_probe_s0163(&args); - if (ret) - break; - } -#endif /* TEL_S0_16_3 */ -#ifdef AVM_A1 - args_unmap(&args.ia_num_mappings, &args.ia_maps[0]); - args.ia_flags = FLAG_AVM_A1; - if (setup_io_map(args.ia_flags, iot, memt, ia->ia_iobase, ia->ia_maddr, - &args.ia_num_mappings, &args.ia_maps[0], - &(ia->ia_iosize), &(ia->ia_msize)) == 0) - { - ret = isic_probe_avma1(&args); - if (ret) - break; - } -#endif /* AVM_A1 */ -#ifdef USR_STI - args_unmap(&args.ia_num_mappings, &args.ia_maps[0]); - args.ia_flags = FLAG_USR_ISDN_TA_INT; - if (setup_io_map(args.ia_flags, iot, memt, ia->ia_iobase, ia->ia_maddr, - &args.ia_num_mappings, &args.ia_maps[0], - &(ia->ia_iosize), &(ia->ia_msize)) == 0) - { - ret = isic_probe_usrtai(&args); - if (ret) - break; - } -#endif /* USR_STI */ - -#ifdef ITKIX1 - args_unmap(&args.ia_num_mappings, &args.ia_maps[0]); - args.ia_flags = FLAG_ITK_IX1; - if (setup_io_map(args.ia_flags, iot, memt, ia->ia_iobase, ia->ia_maddr, - &args.ia_num_mappings, &args.ia_maps[0], - &(ia->ia_iosize), &(ia->ia_msize)) == 0) - { - ret = isic_probe_itkix1(&args); - if (ret) - break; - } -#endif /* ITKIX1 */ - - } else { -#ifdef TEL_S0_16_3 - /* could be anything */ - args.ia_flags = FLAG_TELES_S0_163; - if (setup_io_map(args.ia_flags, iot, memt, ia->ia_iobase, ia->ia_maddr, - &args.ia_num_mappings, &args.ia_maps[0], - &(ia->ia_iosize), &(ia->ia_msize)) == 0) - { - ret = isic_probe_s0163(&args); - if (ret) - break; - } -#endif /* TEL_S0_16_3 */ -#ifdef TEL_S0_16 - args_unmap(&args.ia_num_mappings, &args.ia_maps[0]); - args.ia_flags = FLAG_TELES_S0_16; - if (setup_io_map(args.ia_flags, iot, memt, ia->ia_iobase, ia->ia_maddr, - &args.ia_num_mappings, &args.ia_maps[0], - &(ia->ia_iosize), &(ia->ia_msize)) == 0) - { - ret = isic_probe_s016(&args); - if (ret) - break; - } -#endif /* TEL_S0_16 */ -#ifdef AVM_A1 - args_unmap(&args.ia_num_mappings, &args.ia_maps[0]); - args.ia_flags = FLAG_AVM_A1; - if (setup_io_map(args.ia_flags, iot, memt, ia->ia_iobase, ia->ia_maddr, - &args.ia_num_mappings, &args.ia_maps[0], - &(ia->ia_iosize), &(ia->ia_msize)) == 0) - { - ret = isic_probe_avma1(&args); - if (ret) - break; - } -#endif /* AVM_A1 */ -#ifdef TEL_S0_8 - args_unmap(&args.ia_num_mappings, &args.ia_maps[0]); - args.ia_flags = FLAG_TELES_S0_8; - if (setup_io_map(args.ia_flags, iot, memt, ia->ia_iobase, ia->ia_maddr, - &args.ia_num_mappings, &args.ia_maps[0], - &(ia->ia_iosize), &(ia->ia_msize)) == 0) - { - ret = isic_probe_s08(&args); - } -#endif /* TEL_S0_8 */ - } - break; - } - -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; -} - -/* - * Attach the card - */ -static void -isa_isic_attach(parent, self, aux) - struct device *parent, *self; - void *aux; -{ - struct isic_softc *sc = (void *)self; - struct isa_attach_args *ia = aux; - int flags = sc->sc_dev.dv_cfdata->cf_flags; - int ret = 0; - struct isic_attach_args args; - - /* Setup parameters */ - sc->sc_unit = sc->sc_dev.dv_unit; - sc->sc_irq = ia->ia_irq; - sc->sc_maddr = ia->ia_maddr; - sc->sc_num_mappings = 0; - sc->sc_maps = NULL; - switch(flags) - { - case FLAG_TELES_S0_8: - case FLAG_TELES_S0_16: - case FLAG_TELES_S0_163: - case FLAG_AVM_A1: - case FLAG_USR_ISDN_TA_INT: - setup_io_map(flags, ia->ia_iot, ia->ia_memt, ia->ia_iobase, ia->ia_maddr, - &(sc->sc_num_mappings), NULL, NULL, NULL); - MALLOC_MAPS(sc); - setup_io_map(flags, ia->ia_iot, ia->ia_memt, ia->ia_iobase, ia->ia_maddr, - &(sc->sc_num_mappings), &(sc->sc_maps[0]), NULL, NULL); - break; - - default: - /* No card type given, try to figure ... */ - - /* setup MI attach args */ - bzero(&args, sizeof(args)); - args.ia_flags = flags; - - /* Probe cards */ - if (ia->ia_iobase == IOBASEUNK) { - ret = 0; -#ifdef TEL_S0_8 - /* only Teles S0/8 will work without IO */ - args.ia_flags = FLAG_TELES_S0_8; - setup_io_map(args.ia_flags, ia->ia_iot, ia->ia_memt, ia->ia_iobase, ia->ia_maddr, - &args.ia_num_mappings, &args.ia_maps[0], NULL, NULL); - ret = isic_probe_s08(&args); - if (ret) - goto found; - args_unmap(&args.ia_num_mappings, &args.ia_maps[0]); -#endif /* TEL_S0_8 */ - } else if (ia->ia_maddr == MADDRUNK) { - /* no shared memory, only a 16.3 based card, - AVM A1, the usr sportster or an ITK would work */ - ret = 0; -#ifdef TEL_S0_16_3 - args.ia_flags = FLAG_TELES_S0_163; - setup_io_map(args.ia_flags, ia->ia_iot, ia->ia_memt, ia->ia_iobase, ia->ia_maddr, - &args.ia_num_mappings, &args.ia_maps[0], NULL, NULL); - ret = isic_probe_s0163(&args); - if (ret) - goto found; - args_unmap(&args.ia_num_mappings, &args.ia_maps[0]); -#endif /* TEL_S0_16_3 */ -#ifdef AVM_A1 - args.ia_flags = FLAG_AVM_A1; - setup_io_map(args.ia_flags, ia->ia_iot, ia->ia_memt, ia->ia_iobase, ia->ia_maddr, - &args.ia_num_mappings, &args.ia_maps[0], NULL, NULL); - ret = isic_probe_avma1(&args); - if (ret) - goto found; - args_unmap(&args.ia_num_mappings, &args.ia_maps[0]); -#endif /* AVM_A1 */ -#ifdef USR_STI - args.ia_flags = FLAG_USR_ISDN_TA_INT; - setup_io_map(args.ia_flags, ia->ia_iot, ia->ia_memt, ia->ia_iobase, ia->ia_maddr, - &args.ia_num_mappings, &args.ia_maps[0], NULL, NULL); - ret = isic_probe_usrtai(&args); - if (ret) - goto found; - args_unmap(&args.ia_num_mappings, &args.ia_maps[0]); -#endif /* USR_STI */ -#ifdef ITKIX1 - args.ia_flags = FLAG_ITK_IX1; - setup_io_map(args.ia_flags, ia->ia_iot, ia->ia_memt, ia->ia_iobase, ia->ia_maddr, - &args.ia_num_mappings, &args.ia_maps[0], NULL, NULL); - ret = isic_probe_itkix1(&args); - if (ret) - goto found; - args_unmap(&args.ia_num_mappings, &args.ia_maps[0]); -#endif /* ITKIX1 */ - } else { - /* could be anything */ - ret = 0; -#ifdef TEL_S0_16_3 - args.ia_flags = FLAG_TELES_S0_163; - setup_io_map(args.ia_flags, ia->ia_iot, ia->ia_memt, ia->ia_iobase, ia->ia_maddr, - &args.ia_num_mappings, &args.ia_maps[0], NULL, NULL); - ret = isic_probe_s0163(&args); - if (ret) - goto found; - args_unmap(&args.ia_num_mappings, &args.ia_maps[0]); -#endif /* TEL_S0_16_3 */ -#ifdef TEL_S0_16 - args.ia_flags = FLAG_TELES_S0_16; - setup_io_map(args.ia_flags, ia->ia_iot, ia->ia_memt, ia->ia_iobase, ia->ia_maddr, - &args.ia_num_mappings, &args.ia_maps[0], NULL, NULL); - ret = isic_probe_s016(&args); - if (ret) - goto found; - args_unmap(&args.ia_num_mappings, &args.ia_maps[0]); -#endif /* TEL_S0_16 */ -#ifdef AVM_A1 - args.ia_flags = FLAG_AVM_A1; - setup_io_map(args.ia_flags, ia->ia_iot, ia->ia_memt, ia->ia_iobase, ia->ia_maddr, - &args.ia_num_mappings, &args.ia_maps[0], NULL, NULL); - ret = isic_probe_avma1(&args); - if (ret) - goto found; - args_unmap(&args.ia_num_mappings, &args.ia_maps[0]); -#endif /* AVM_A1 */ -#ifdef TEL_S0_8 - args.ia_flags = FLAG_TELES_S0_8; - setup_io_map(args.ia_flags, ia->ia_iot, ia->ia_memt, ia->ia_iobase, ia->ia_maddr, - &args.ia_num_mappings, &args.ia_maps[0], NULL, NULL); - ret = isic_probe_s08(&args); - if (ret) - goto found; - args_unmap(&args.ia_num_mappings, &args.ia_maps[0]); -#endif /* TEL_S0_8 */ - } - break; - - found: - flags = args.ia_flags; - sc->sc_num_mappings = args.ia_num_mappings; - args_unmap(&args.ia_num_mappings, &args.ia_maps[0]); - if (ret) { - MALLOC_MAPS(sc); - setup_io_map(flags, ia->ia_iot, ia->ia_memt, ia->ia_iobase, ia->ia_maddr, - &(sc->sc_num_mappings), &(sc->sc_maps[0]), NULL, NULL); - } else { - printf(": could not determine card type - not configured!\n"); - return; - } - break; - } - -#if defined(__OpenBSD__) - isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE, - IPL_NET, isicintr, sc, sc->sc_dev.dv_xname); - - /* MI initialization of card */ - isicattach(flags, sc); - -#else - - /* MI initialization of card */ - isicattach(flags, sc); - - /* - * Try to get a level-triggered interrupt first. If that doesn't - * work (like on NetBSD/Atari, try to establish an edge triggered - * interrupt. - */ - if (isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_LEVEL, - IPL_NET, isicintr, sc) == NULL) { - if(isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE, - IPL_NET, isicintr, sc) == NULL) { - args_unmap(&(sc->sc_num_mappings), &(sc->sc_maps[0])); - free((sc)->sc_maps, M_DEVBUF); - } - else { - /* - * XXX: This is a hack that probably needs to be - * solved by setting an interrupt type in the sc - * structure. I don't feel familiar enough with the - * code to do this currently. Feel free to contact - * me about it (leo@netbsd.org). - */ - isicintr(sc); - } - } -#endif -} - -/* - * Setup card specific io mapping. Return 0 on success, - * any other value on config error. - * Be prepared to get NULL as maps array. - * Make sure to keep *num_mappings in sync with the real - * mappings already setup when returning! - */ -static int -setup_io_map(flags, iot, memt, iobase, maddr, num_mappings, maps, iosize, msize) - int flags, *num_mappings, *iosize, *msize; - bus_size_t iobase, maddr; - bus_space_tag_t iot, memt; - struct isic_io_map *maps; -{ - /* nothing mapped yet */ - *num_mappings = 0; - - /* which resources do we need? */ - switch(flags) - { - case FLAG_TELES_S0_8: - if (maddr == MADDRUNK) { - printf("isic: config error: no shared memory specified for Teles S0/8!\n"); - return 1; - } - if (iosize) *iosize = 0; /* no i/o ports */ - if (msize) *msize = 0x1000; /* shared memory size */ - - /* this card uses a single memory mapping */ - if (maps == NULL) { - *num_mappings = 1; - return 0; - } - *num_mappings = 0; - maps[0].t = memt; - maps[0].offset = 0; - maps[0].size = 0x1000; - if (bus_space_map(maps[0].t, maddr, - maps[0].size, 0, &maps[0].h)) { - return 1; - } - (*num_mappings)++; - break; - - case FLAG_TELES_S0_16: - if (iobase == IOBASEUNK) { - printf("isic: config error: no i/o address specified for Teles S0/16!\n"); - return 1; - } - if (maddr == MADDRUNK) { - printf("isic: config error: no shared memory specified for Teles S0/16!\n"); - return 1; - } - if (iosize) *iosize = 8; /* i/o ports */ - if (msize) *msize = 0x1000; /* shared memory size */ - - /* one io and one memory mapping */ - if (maps == NULL) { - *num_mappings = 2; - return 0; - } - *num_mappings = 0; - maps[0].t = iot; - maps[0].offset = 0; - maps[0].size = 8; - if (bus_space_map(maps[0].t, iobase, - maps[0].size, 0, &maps[0].h)) { - return 1; - } - (*num_mappings)++; - maps[1].t = memt; - maps[1].offset = 0; - maps[1].size = 0x1000; - if (bus_space_map(maps[1].t, maddr, - maps[1].size, 0, &maps[1].h)) { - return 1; - } - (*num_mappings)++; - break; - - case FLAG_TELES_S0_163: - if (iobase == IOBASEUNK) { - printf("isic: config error: no i/o address specified for Teles S0/16!\n"); - return 1; - } - if (iosize) *iosize = 8; /* only some i/o ports shown */ - if (msize) *msize = 0; /* no shared memory */ - - /* Four io mappings: config, isac, 2 * hscx */ - if (maps == NULL) { - *num_mappings = 4; - return 0; - } - *num_mappings = 0; - maps[0].t = iot; - maps[0].offset = 0; - maps[0].size = 8; - if (bus_space_map(maps[0].t, iobase, - maps[0].size, 0, &maps[0].h)) { - return 1; - } - (*num_mappings)++; - maps[1].t = iot; - maps[1].offset = 0; - maps[1].size = 0x40; /* XXX - ??? */ - if ((iobase - 0xd80 + 0x980) < 0 || (iobase - 0xd80 + 0x980) > 0x0ffff) - return 1; - if (bus_space_map(maps[1].t, iobase - 0xd80 + 0x980, - maps[1].size, 0, &maps[1].h)) { - return 1; - } - (*num_mappings)++; - maps[2].t = iot; - maps[2].offset = 0; - maps[2].size = 0x40; /* XXX - ??? */ - if ((iobase - 0xd80 + 0x180) < 0 || (iobase - 0xd80 + 0x180) > 0x0ffff) - return 1; - if (bus_space_map(maps[2].t, iobase - 0xd80 + 0x180, - maps[2].size, 0, &maps[2].h)) { - return 1; - } - (*num_mappings)++; - maps[3].t = iot; - maps[3].offset = 0; - maps[3].size = 0x40; /* XXX - ??? */ - if ((iobase - 0xd80 + 0x580) < 0 || (iobase - 0xd80 + 0x580) > 0x0ffff) - return 1; - if (bus_space_map(maps[3].t, iobase - 0xd80 + 0x580, - maps[3].size, 0, &maps[3].h)) { - return 1; - } - (*num_mappings)++; - break; - - case FLAG_AVM_A1: - if (iobase == IOBASEUNK) { - printf("isic: config error: no i/o address specified for AVM A1/Fritz! card!\n"); - return 1; - } - if (iosize) *iosize = 8; /* only some i/o ports shown */ - if (msize) *msize = 0; /* no shared memory */ - - /* Seven io mappings: config, isac, 2 * hscx, - isac-fifo, 2 * hscx-fifo */ - if (maps == NULL) { - *num_mappings = 7; - return 0; - } - *num_mappings = 0; - maps[0].t = iot; /* config */ - maps[0].offset = 0; - maps[0].size = 8; - if ((iobase + 0x1800) < 0 || (iobase + 0x1800) > 0x0ffff) - return 1; - if (bus_space_map(maps[0].t, iobase + 0x1800, maps[0].size, 0, &maps[0].h)) - return 1; - (*num_mappings)++; - maps[1].t = iot; /* isac */ - maps[1].offset = 0; - maps[1].size = 0x80; /* XXX - ??? */ - if ((iobase + 0x1400 - 0x20) < 0 || (iobase + 0x1400 - 0x20) > 0x0ffff) - return 1; - if (bus_space_map(maps[1].t, iobase + 0x1400 - 0x20, maps[1].size, 0, &maps[1].h)) - return 1; - (*num_mappings)++; - maps[2].t = iot; /* hscx 0 */ - maps[2].offset = 0; - maps[2].size = 0x40; /* XXX - ??? */ - if ((iobase + 0x400 - 0x20) < 0 || (iobase + 0x400 - 0x20) > 0x0ffff) - return 1; - if (bus_space_map(maps[2].t, iobase + 0x400 - 0x20, maps[2].size, 0, &maps[2].h)) - return 1; - (*num_mappings)++; - maps[3].t = iot; /* hscx 1 */ - maps[3].offset = 0; - maps[3].size = 0x40; /* XXX - ??? */ - if ((iobase + 0xc00 - 0x20) < 0 || (iobase + 0xc00 - 0x20) > 0x0ffff) - return 1; - if (bus_space_map(maps[3].t, iobase + 0xc00 - 0x20, maps[3].size, 0, &maps[3].h)) - return 1; - (*num_mappings)++; - maps[4].t = iot; /* isac-fifo */ - maps[4].offset = 0; - maps[4].size = 1; - if ((iobase + 0x1400 - 0x20 -0x3e0) < 0 || (iobase + 0x1400 - 0x20 -0x3e0) > 0x0ffff) - return 1; - if (bus_space_map(maps[4].t, iobase + 0x1400 - 0x20 -0x3e0, maps[4].size, 0, &maps[4].h)) - return 1; - (*num_mappings)++; - maps[5].t = iot; /* hscx 0 fifo */ - maps[5].offset = 0; - maps[5].size = 1; - if ((iobase + 0x400 - 0x20 -0x3e0) < 0 || (iobase + 0x400 - 0x20 -0x3e0) > 0x0ffff) - return 1; - if (bus_space_map(maps[5].t, iobase + 0x400 - 0x20 -0x3e0, maps[5].size, 0, &maps[5].h)) - return 1; - (*num_mappings)++; - maps[6].t = iot; /* hscx 1 fifo */ - maps[6].offset = 0; - maps[6].size = 1; - if ((iobase + 0xc00 - 0x20 -0x3e0) < 0 || (iobase + 0xc00 - 0x20 -0x3e0) > 0x0ffff) - return 1; - if (bus_space_map(maps[6].t, iobase + 0xc00 - 0x20 -0x3e0, maps[6].size, 0, &maps[6].h)) - return 1; - (*num_mappings)++; - break; - - case FLAG_USR_ISDN_TA_INT: - if (iobase == IOBASEUNK) { - printf("isic: config error: no I/O base specified for USR Sportster TA intern!\n"); - return 1; - } - if (iosize) *iosize = 8; /* scattered ports, only some shown */ - if (msize) *msize = 0; /* no shared memory */ - - /* 49 io mappings: 1 config and 48x8 registers */ - if (maps == NULL) { - *num_mappings = 49; - return 0; - } - *num_mappings = 0; - { - int i, num; - bus_size_t base; - - /* config at offset 0x8000 */ - base = iobase + 0x8000; - maps[0].size = 1; - maps[0].t = iot; - maps[0].offset = 0; - if (base < 0 || base > 0x0ffff) - return 1; - if (bus_space_map(iot, base, 1, 0, &maps[0].h)) { - return 1; - } - *num_mappings = num = 1; - - /* HSCX A at offset 0 */ - base = iobase; - for (i = 0; i < 16; i++) { - maps[num].size = 8; - maps[num].offset = 0; - maps[num].t = iot; - if (base+i*1024 < 0 || base+i*1024+8 > 0x0ffff) - return 1; - if (bus_space_map(iot, base+i*1024, 8, 0, &maps[num].h)) { - return 1; - } - *num_mappings = ++num; - } - /* HSCX B at offset 0x4000 */ - base = iobase + 0x4000; - for (i = 0; i < 16; i++) { - maps[num].size = 8; - maps[num].offset = 0; - maps[num].t = iot; - if (base+i*1024 < 0 || base+i*1024+8 > 0x0ffff) - return 1; - if (bus_space_map(iot, base+i*1024, 8, 0, &maps[num].h)) { - return 1; - } - *num_mappings = ++num; - } - /* ISAC at offset 0xc000 */ - base = iobase + 0xc000; - for (i = 0; i < 16; i++) { - maps[num].size = 8; - maps[num].offset = 0; - maps[num].t = iot; - if (base+i*1024 < 0 || base+i*1024+8 > 0x0ffff) - return 1; - if (bus_space_map(iot, base+i*1024, 8, 0, &maps[num].h)) { - return 1; - } - *num_mappings = ++num; - } - } - break; - - case FLAG_ITK_IX1: - if (iobase == IOBASEUNK) { - printf("isic: config error: no I/O base specified for ITK ix1 micro!\n"); - return 1; - } - if (iosize) *iosize = 4; - if (msize) *msize = 0; - if (maps == NULL) { - *num_mappings = 1; - return 0; - } - *num_mappings = 0; - maps[0].size = 4; - maps[0].t = iot; - maps[0].offset = 0; - if (bus_space_map(iot, iobase, 4, 0, &maps[0].h)) { - return 1; - } - *num_mappings = 1; - break; - - default: - printf("isic: config error: flags do not specify any known card!\n"); - return 1; - break; - } - - return 0; -} - -static void -args_unmap(num_mappings, maps) - int *num_mappings; - struct isic_io_map *maps; -{ - int i, n; - for (i = 0, n = *num_mappings; i < n; i++) - if (maps[i].size) - bus_space_unmap(maps[i].t, maps[i].h, maps[i].size); - *num_mappings = 0; -} diff --git a/sys/i4b/layer1/isapnp_isic.c b/sys/i4b/layer1/isapnp_isic.c deleted file mode 100644 index a72189b..0000000 --- a/sys/i4b/layer1/isapnp_isic.c +++ /dev/null @@ -1,394 +0,0 @@ -/* - * Copyright (c) 1997, 1998 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. - * - *--------------------------------------------------------------------------- - * - * isapnp_isic.c - ISA-P&P bus frontend for i4b_isic driver - * -------------------------------------------------------- - * - * $FreeBSD$ - * - * last edit-date: [Sun May 2 11:57:08 1999] - * - * -mh original implementation - * -hm NetBSD patches from Martin - * - *---------------------------------------------------------------------------*/ - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/errno.h> -#include <sys/syslog.h> -#include <sys/device.h> -#include <sys/socket.h> -#include <net/if.h> -#include <sys/systm.h> -#include <sys/malloc.h> - -#include <machine/cpu.h> -#include <machine/intr.h> -#include <machine/bus.h> - -#include <dev/isa/isavar.h> -#include <dev/isapnp/isapnpreg.h> -#include <dev/isapnp/isapnpvar.h> - -#ifdef __FreeBSD__ -#include <machine/i4b_ioctl.h> -#include <machine/i4b_trace.h> -#else -#include <i4b/i4b_ioctl.h> -#include <i4b/i4b_trace.h> -#endif - -#include <i4b/layer1/i4b_l1.h> -#include <i4b/layer1/i4b_ipac.h> -#include <i4b/layer1/i4b_isac.h> -#include <i4b/layer1/i4b_hscx.h> - -#include <i4b/include/i4b_l1l2.h> -#include <i4b/include/i4b_global.h> - -#ifdef __BROKEN_INDIRECT_CONFIG -static int isapnp_isic_probe __P((struct device *, void *, void *)); -#else -static int isapnp_isic_probe __P((struct device *, struct cfdata *, void *)); -#endif -static void isapnp_isic_attach __P((struct device *, struct device *, void *)); - -struct cfattach isapnp_isic_ca = { - sizeof(struct isic_softc), isapnp_isic_probe, isapnp_isic_attach -}; - -typedef void (*allocmaps_func)(struct isapnp_attach_args *ipa, struct isic_softc *sc); -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)); -extern void isic_attach_Dyn __P((struct isic_softc *sc)); -extern void isic_attach_s0163P __P((struct isic_softc *sc)); -extern void isic_attach_drnngo __P((struct isic_softc *sc)); -extern void isic_attach_sws __P((struct isic_softc *sc)); -extern void isic_attach_Eqs1pi __P((struct isic_softc *sc)); - -struct isapnp_isic_card_desc { - char *devlogic; /* ISAPNP logical device ID */ - char *name; /* Name of the card */ - int card_type; /* isic card type identifier */ - allocmaps_func allocmaps; /* map allocator function */ - attach_func attach; /* card attach and init function */ -}; -static const struct isapnp_isic_card_desc -isapnp_isic_descriptions[] = -{ -#ifdef CRTX_S0_P - { "CTX0000", "Creatix ISDN S0-16 P&P", CARD_TYPEP_CS0P, - tls_pnp_mapalloc, isic_attach_Cs0P }, -#endif -#ifdef TEL_S0_16_3_P - { "TAG2110", "Teles S0/PnP", CARD_TYPEP_163P, - tls_pnp_mapalloc, isic_attach_s0163P }, -#endif -#ifdef DRN_NGO - { "SDA0150", "Dr. Neuhaus NICCY GO@", CARD_TYPEP_DRNNGO, - ngo_pnp_mapalloc, isic_attach_drnngo }, -#endif -#ifdef ELSA_QS1ISA - { "ELS0133", "Elsa QuickStep 1000 (ISA)", CARD_TYPEP_ELSAQS1ISA, - generic_pnp_mapalloc, isic_attach_Eqs1pi }, -#endif -#ifdef SEDLBAUER - { "SAG0001", "Sedlbauer WinSpeed", CARD_TYPEP_SWS, - generic_pnp_mapalloc, isic_attach_sws }, -#endif -#ifdef DYNALINK - { "ASU1688", "Dynalink IS64PH", CARD_TYPEP_DYNALINK, - generic_pnp_mapalloc, isic_attach_Dyn }, -#endif -}; -#define NUM_DESCRIPTIONS (sizeof(isapnp_isic_descriptions)/sizeof(isapnp_isic_descriptions[0])) - -/* - * Probe card - */ -static int -#ifdef __BROKEN_INDIRECT_CONFIG -isapnp_isic_probe(parent, match, aux) -#else -isapnp_isic_probe(parent, cf, aux) -#endif - struct device *parent; -#ifdef __BROKEN_INDIRECT_CONFIG - void *match; -#else - struct cfdata *cf; -#endif - void *aux; -{ - struct isapnp_attach_args *ipa = aux; - const struct isapnp_isic_card_desc *desc = isapnp_isic_descriptions; - int i; - - for (i = 0; i < NUM_DESCRIPTIONS; i++, desc++) - if (strcmp(ipa->ipa_devlogic, desc->devlogic) == 0) - return 1; - - return 0; -} - - -/*---------------------------------------------------------------------------* - * card independend attach for ISA P&P cards - *---------------------------------------------------------------------------*/ - -/* parameter and format for message producing e.g. "isic0: " */ - -#ifdef __FreeBSD__ -#define ISIC_FMT "isic%d: " -#define ISIC_PARM dev->id_unit -#define TERMFMT " " -#else -#define ISIC_FMT "%s: " -#define ISIC_PARM sc->sc_dev.dv_xname -#define TERMFMT "\n" -#endif - -static void -isapnp_isic_attach(parent, self, aux) - struct device *parent, *self; - void *aux; -{ - static char *ISACversion[] = { - "2085 Version A1/A2 or 2086/2186 Version 1.1", - "2085 Version B1", - "2085 Version B2", - "2085 Version V2.3 (B3)", - "Unknown Version" - }; - - static char *HSCXversion[] = { - "82525 Version A1", - "Unknown (0x01)", - "82525 Version A2", - "Unknown (0x03)", - "82525 Version A3", - "82525 or 21525 Version 2.1", - "Unknown Version" - }; - - struct isic_softc *sc = (void *)self; - struct isapnp_attach_args *ipa = aux; - const struct isapnp_isic_card_desc *desc = isapnp_isic_descriptions; - int i; - - for (i = 0; i < NUM_DESCRIPTIONS; i++, desc++) - if (strcmp(ipa->ipa_devlogic, desc->devlogic) == 0) - break; - if (i >= NUM_DESCRIPTIONS) - panic("could not identify isic PnP device"); - - /* setup parameters */ - sc->sc_cardtyp = desc->card_type; - sc->sc_unit = sc->sc_dev.dv_unit; - sc->sc_irq = ipa->ipa_irq[0].num; - desc->allocmaps(ipa, sc); - - /* announce card name */ - printf(": %s\n", desc->name); - - /* establish interrupt handler */ - isa_intr_establish(ipa->ipa_ic, ipa->ipa_irq[0].num, IST_EDGE, - IPL_NET, isicintr, sc); - - /* init card */ - isic_sc[sc->sc_unit] = sc; - desc->attach(sc); - - /* announce chip versions */ - sc->sc_isac_version = 0; - 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; - 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; - break; - }; - - /* ISAC setup */ - - isic_isac_init(sc); - - /* HSCX setup */ - - isic_bchannel_setup(sc->sc_unit, HSCX_CH_A, BPROT_NONE, 0); - - isic_bchannel_setup(sc->sc_unit, HSCX_CH_B, BPROT_NONE, 0); - - /* setup linktab */ - - isic_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); - - /* announce chip versions */ - - 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'); - } - - 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]); - } -} - -static void -generic_pnp_mapalloc(struct isapnp_attach_args *ipa, struct isic_softc *sc) -{ - sc->sc_num_mappings = 1; /* most cards have just one mapping */ - MALLOC_MAPS(sc); /* malloc the maps */ - sc->sc_maps[0].t = ipa->ipa_iot; /* copy the access handles */ - sc->sc_maps[0].h = ipa->ipa_io[0].h; - 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) -{ - sc->sc_num_mappings = 2; /* one data, one address mapping */ - MALLOC_MAPS(sc); /* malloc the maps */ - sc->sc_maps[0].t = ipa->ipa_iot; /* copy the access handles */ - sc->sc_maps[0].h = ipa->ipa_io[0].h; - sc->sc_maps[0].size = 0; /* foreign mapping, leave it alone */ - sc->sc_maps[1].t = ipa->ipa_iot; - 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) -{ - sc->sc_num_mappings = 4; /* config, isac, 2 * hscx */ - MALLOC_MAPS(sc); /* malloc the maps */ - sc->sc_maps[0].t = ipa->ipa_iot; /* copy the access handles */ - sc->sc_maps[0].h = ipa->ipa_io[0].h; - sc->sc_maps[0].size = 0; /* foreign mapping, leave it alone */ - sc->sc_maps[1].t = ipa->ipa_iot; - sc->sc_maps[1].h = ipa->ipa_io[0].h; - sc->sc_maps[1].size = 0; - sc->sc_maps[1].offset = - 0x20; - sc->sc_maps[2].t = ipa->ipa_iot; - sc->sc_maps[2].offset = - 0x20; - sc->sc_maps[2].h = ipa->ipa_io[1].h; - sc->sc_maps[2].size = 0; - sc->sc_maps[3].t = ipa->ipa_iot; - sc->sc_maps[3].offset = 0; - sc->sc_maps[3].h = ipa->ipa_io[1].h; - sc->sc_maps[3].size = 0; -} -#endif diff --git a/sys/i4b/layer1/i4b_asuscom_ipac.c b/sys/i4b/layer1/isic/i4b_asuscom_ipac.c index 73639b5..5d696c1 100644 --- a/sys/i4b/layer1/i4b_asuscom_ipac.c +++ b/sys/i4b/layer1/isic/i4b_asuscom_ipac.c @@ -1,6 +1,7 @@ /* * Copyright (c) 1999 Ari Suutari. All rights reserved. - * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved. + * + * Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -39,11 +40,11 @@ * code is modeled after Linux i4l driver written by Karsten * Keil. * - * $Id: i4b_asuscom_ipac.c,v 1.4 1999/12/13 21:25:26 hm Exp $ + * $Id: i4b_asuscom_ipac.c,v 1.3 2000/05/29 15:41:41 hm Exp $ * * $FreeBSD$ * - * last edit-date: [Mon Dec 13 21:58:27 1999] + * last edit-date: [Mon May 29 16:41:56 2000] * *---------------------------------------------------------------------------*/ @@ -53,7 +54,6 @@ #if (NISIC > 0) && defined (ASUSCOM_IPAC) #include <sys/param.h> -#include <sys/ioccom.h> #include <sys/kernel.h> #include <sys/systm.h> #include <sys/mbuf.h> @@ -67,13 +67,13 @@ #include <machine/i4b_ioctl.h> #include <i4b/include/i4b_global.h> -#include <i4b/include/i4b_l1l2.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> +#include <i4b/layer1/isic/i4b_isic.h> +#include <i4b/layer1/isic/i4b_ipac.h> +#include <i4b/layer1/isic/i4b_isac.h> +#include <i4b/layer1/isic/i4b_hscx.h> /* masks for register encoded in base addr */ diff --git a/sys/i4b/layer1/i4b_avm_a1.c b/sys/i4b/layer1/isic/i4b_avm_a1.c index 5553907..ee076f0 100644 --- a/sys/i4b/layer1/i4b_avm_a1.c +++ b/sys/i4b/layer1/isic/i4b_avm_a1.c @@ -1,7 +1,7 @@ /* * Copyright (c) 1996 Andrew Gordon. All rights reserved. * - * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved. + * Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -35,11 +35,11 @@ * i4b_avm_a1.c - AVM A1/Fritz passive card driver for isdn4bsd * ------------------------------------------------------------ * - * $Id: i4b_avm_a1.c,v 1.2 1999/12/13 21:25:26 hm Exp $ + * $Id: i4b_avm_a1.c,v 1.3 2000/05/29 15:41:41 hm Exp $ * * $FreeBSD$ * - * last edit-date: [Mon Dec 13 21:58:36 1999] + * last edit-date: [Mon May 29 16:42:06 2000] * *---------------------------------------------------------------------------*/ @@ -49,6 +49,7 @@ #if NISIC > 0 && defined(AVM_A1) #include <sys/param.h> +#include <sys/kernel.h> #include <sys/systm.h> #include <sys/mbuf.h> #include <sys/socket.h> @@ -62,9 +63,9 @@ #include <i4b/include/i4b_global.h> -#include <i4b/layer1/i4b_l1.h> -#include <i4b/layer1/i4b_isac.h> -#include <i4b/layer1/i4b_hscx.h> +#include <i4b/layer1/isic/i4b_isic.h> +#include <i4b/layer1/isic/i4b_isac.h> +#include <i4b/layer1/isic/i4b_hscx.h> /*---------------------------------------------------------------------------* * AVM A1 and AVM Fritz! Card special registers diff --git a/sys/i4b/layer1/i4b_bchan.c b/sys/i4b/layer1/isic/i4b_bchan.c index d2a1a7c..1fb6cc6 100644 --- a/sys/i4b/layer1/i4b_bchan.c +++ b/sys/i4b/layer1/isic/i4b_bchan.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved. + * Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,11 +27,11 @@ * i4b_bchan.c - B channel handling L1 procedures * ---------------------------------------------- * - * $Id: i4b_bchan.c,v 1.2 1999/12/13 21:25:26 hm Exp $ + * $Id: i4b_bchan.c,v 1.6 2000/05/29 15:41:41 hm Exp $ * * $FreeBSD$ * - * last edit-date: [Mon Dec 13 21:59:11 1999] + * last edit-date: [Mon May 29 16:42:26 2000] * *---------------------------------------------------------------------------*/ @@ -40,6 +40,7 @@ #if NISIC > 0 #include <sys/param.h> +#include <sys/kernel.h> #include <sys/systm.h> #include <sys/mbuf.h> #include <machine/stdarg.h> @@ -54,17 +55,16 @@ #include <machine/i4b_trace.h> #include <i4b/layer1/i4b_l1.h> -#include <i4b/layer1/i4b_isac.h> -#include <i4b/layer1/i4b_hscx.h> -#include <i4b/include/i4b_l1l2.h> +#include <i4b/layer1/isic/i4b_isic.h> +#include <i4b/layer1/isic/i4b_isac.h> +#include <i4b/layer1/isic/i4b_hscx.h> + #include <i4b/include/i4b_mbuf.h> #include <i4b/include/i4b_global.h> static void isic_bchannel_start(int unit, int h_chan); static void isic_bchannel_stat(int unit, int h_chan, bchan_statistics_t *bsp); -static void isic_set_linktab(int unit, int channel, drvr_link_t *dlt); -static isdn_link_t *isic_ret_linktab(int unit, int channel); /*---------------------------------------------------------------------------* * initialize one B channels rx/tx data structures and init/deinit HSCX @@ -83,8 +83,8 @@ isic_bchannel_setup(int unit, int h_chan, int bprot, int activate) isic_hscx_init(sc, h_chan, activate); } - DBGL1(L1_BCHAN, "isic_bchannel_setup", ("unit=%d, channel=%d, %s\n", - sc->sc_unit, h_chan, activate ? "activate" : "deactivate")); + NDBGL1(L1_BCHAN, "unit=%d, channel=%d, %s", + sc->sc_unit, h_chan, activate ? "activate" : "deactivate"); /* general part */ @@ -173,7 +173,7 @@ isic_bchannel_start(int unit, int h_chan) if(chan->bprot == BPROT_NONE) { - if(!(isic_hscx_silence(chan->out_mbuf_cur->m_data, chan->out_mbuf_cur->m_len))) + if(!(i4b_l1_bchan_tel_silence(chan->out_mbuf_cur->m_data, chan->out_mbuf_cur->m_len))) activity = ACT_TX; } else @@ -186,12 +186,12 @@ isic_bchannel_start(int unit, int h_chan) if(sc->sc_trace & TRACE_B_TX) /* if trace, send mbuf to trace dev */ { i4b_trace_hdr_t hdr; - hdr.unit = unit; + hdr.unit = L0ISICUNIT(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); + i4b_l1_trace_ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data); } len = 0; /* # of chars put into HSCX tx fifo this time */ @@ -256,12 +256,12 @@ isic_bchannel_start(int unit, int h_chan) if(sc->sc_trace & TRACE_B_TX) { i4b_trace_hdr_t hdr; - hdr.unit = unit; + hdr.unit = L0ISICUNIT(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); + i4b_l1_trace_ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data); } } } @@ -305,7 +305,7 @@ isic_bchannel_start(int unit, int h_chan) /* call timeout handling routine */ if(activity == ACT_RX || activity == ACT_TX) - (*chan->drvr_linktab->bch_activity)(chan->drvr_linktab->unit, activity); + (*chan->isic_drvr_linktab->bch_activity)(chan->isic_drvr_linktab->unit, activity); if(cmd) isic_hscx_cmd(sc, h_chan, cmd); @@ -337,25 +337,25 @@ isic_bchannel_stat(int unit, int h_chan, bchan_statistics_t *bsp) /*---------------------------------------------------------------------------* * return the address of isic drivers linktab *---------------------------------------------------------------------------*/ -static isdn_link_t * +isdn_link_t * isic_ret_linktab(int unit, int channel) { struct l1_softc *sc = &l1_sc[unit]; l1_bchan_state_t *chan = &sc->sc_chan[channel]; - return(&chan->isdn_linktab); + return(&chan->isic_isdn_linktab); } /*---------------------------------------------------------------------------* * set the driver linktab in the b channel softc *---------------------------------------------------------------------------*/ -static void +void isic_set_linktab(int unit, int channel, drvr_link_t *dlt) { struct l1_softc *sc = &l1_sc[unit]; l1_bchan_state_t *chan = &sc->sc_chan[channel]; - chan->drvr_linktab = dlt; + chan->isic_drvr_linktab = dlt; } /*---------------------------------------------------------------------------* @@ -365,11 +365,11 @@ void isic_init_linktab(struct l1_softc *sc) { l1_bchan_state_t *chan = &sc->sc_chan[HSCX_CH_A]; - isdn_link_t *lt = &chan->isdn_linktab; + isdn_link_t *lt = &chan->isic_isdn_linktab; /* make sure the hardware driver is known to layer 4 */ - ctrl_types[CTRL_PASSIVE].set_linktab = isic_set_linktab; - ctrl_types[CTRL_PASSIVE].get_linktab = isic_ret_linktab; + ctrl_types[CTRL_PASSIVE].set_linktab = i4b_l1_set_linktab; + ctrl_types[CTRL_PASSIVE].get_linktab = i4b_l1_ret_linktab; /* local setup */ lt->unit = sc->sc_unit; @@ -386,7 +386,7 @@ isic_init_linktab(struct l1_softc *sc) lt->rx_mbuf = &chan->in_mbuf; chan = &sc->sc_chan[HSCX_CH_B]; - lt = &chan->isdn_linktab; + lt = &chan->isic_isdn_linktab; lt->unit = sc->sc_unit; lt->channel = HSCX_CH_B; @@ -401,37 +401,5 @@ isic_init_linktab(struct l1_softc *sc) /* used by HDLC data transfers, i.e. ipr and isp drivers */ lt->rx_mbuf = &chan->in_mbuf; } - -/*---------------------------------------------------------------------------* - * telephony silence detection - *---------------------------------------------------------------------------*/ - -#define TEL_IDLE_MIN (BCH_MAX_DATALEN/2) - -int -isic_hscx_silence(unsigned char *data, int len) -{ - register int i = 0; - register int j = 0; - - /* count idle bytes */ - - for(;i < len; i++) - { - if((*data >= 0xaa) && (*data <= 0xac)) - j++; - data++; - } - -#ifdef NOTDEF - printf("isic_hscx_silence: got %d silence bytes in frame\n", j); -#endif - - if(j < (TEL_IDLE_MIN)) - return(0); - else - return(1); - -} #endif /* NISIC > 0 */ diff --git a/sys/i4b/layer1/i4b_ctx_s0P.c b/sys/i4b/layer1/isic/i4b_ctx_s0P.c index 9597780..c58b691 100644 --- a/sys/i4b/layer1/i4b_ctx_s0P.c +++ b/sys/i4b/layer1/isic/i4b_ctx_s0P.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved. + * Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,11 +27,11 @@ * isic - I4B Siemens ISDN Chipset Driver for Creatix/Teles PnP * ============================================================ * - * $Id: i4b_ctx_s0P.c,v 1.4 1999/12/13 21:25:26 hm Exp $ + * $Id: i4b_ctx_s0P.c,v 1.4 2000/08/22 11:30:04 hm Exp $ * * $FreeBSD$ * - * last edit-date: [Mon Dec 13 21:59:23 1999] + * last edit-date: [Tue Aug 22 11:35:00 2000] * * Note: this driver works for the Creatix ISDN S0-16 P+P and * for the Teles S0/16.3 PnP card. Although they are not @@ -48,6 +48,7 @@ #if (NISIC > 0) && (defined(CRTX_S0_P) || defined(TEL_S0_16_3_P)) #include <sys/param.h> +#include <sys/kernel.h> #include <sys/systm.h> #include <sys/mbuf.h> #include <sys/socket.h> @@ -61,11 +62,11 @@ #include <i4b/include/i4b_global.h> -#include <i4b/layer1/i4b_l1.h> -#include <i4b/layer1/i4b_isac.h> -#include <i4b/layer1/i4b_hscx.h> +#include <i4b/layer1/isic/i4b_isic.h> +#include <i4b/layer1/isic/i4b_isac.h> +#include <i4b/layer1/isic/i4b_hscx.h> -#include <i4b/include/i4b_l1l2.h> +/* #include <i4b/include/i4b_l1l2.h> */ #include <i4b/include/i4b_mbuf.h> /*---------------------------------------------------------------------------* @@ -190,7 +191,11 @@ isic_attach_Cs0P(device_t dev) * overlapping each other. */ +#if 0 bus_set_resource(dev, SYS_RES_IOPORT, 3, iobase2-0x20, 0x20); +#else + bus_set_resource(dev, SYS_RES_IOPORT, 3, iobase2-0x20, 0x10); +#endif if(!(sc->sc_resources.io_base[3] = bus_alloc_resource(dev,SYS_RES_IOPORT, diff --git a/sys/i4b/layer1/i4b_drn_ngo.c b/sys/i4b/layer1/isic/i4b_drn_ngo.c index 99592ec..042dbb2 100644 --- a/sys/i4b/layer1/i4b_drn_ngo.c +++ b/sys/i4b/layer1/isic/i4b_drn_ngo.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved. + * Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,11 +27,11 @@ * i4b_drn_ngo.c - Dr. Neuhaus Niccy GO@ and SAGEM Cybermod * -------------------------------------------------------- * - * $Id: i4b_drn_ngo.c,v 1.3 1999/12/13 21:25:26 hm Exp $ + * $Id: i4b_drn_ngo.c,v 1.3 2000/05/29 15:41:41 hm Exp $ * * $FreeBSD$ * - * last edit-date: [Mon Dec 13 21:59:30 1999] + * last edit-date: [Mon May 29 16:43:21 2000] * *---------------------------------------------------------------------------*/ @@ -41,6 +41,7 @@ #if (NISIC > 0) && defined(DRN_NGO) #include <sys/param.h> +#include <sys/kernel.h> #include <sys/systm.h> #include <sys/mbuf.h> #include <sys/socket.h> @@ -54,9 +55,9 @@ #include <i4b/include/i4b_global.h> -#include <i4b/layer1/i4b_l1.h> -#include <i4b/layer1/i4b_isac.h> -#include <i4b/layer1/i4b_hscx.h> +#include <i4b/layer1/isic/i4b_isic.h> +#include <i4b/layer1/isic/i4b_isac.h> +#include <i4b/layer1/isic/i4b_hscx.h> /*---------------------------------------------------------------------------* * Niccy GO@ definitions diff --git a/sys/i4b/layer1/isic/i4b_dynalink.c b/sys/i4b/layer1/isic/i4b_dynalink.c new file mode 100644 index 0000000..67e6bbe --- /dev/null +++ b/sys/i4b/layer1/isic/i4b_dynalink.c @@ -0,0 +1,239 @@ +/* + * Copyright (c) 1998 Martijn Plak. 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. + * + *--------------------------------------------------------------------------- + * + * isdn4bsd layer1 driver for Dynalink IS64PH isdn TA + * ================================================== + * + * $Id: i4b_dynalink.c,v 1.1 2000/09/04 09:17:26 hm Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Mon Sep 4 09:47:18 2000] + * + *---------------------------------------------------------------------------*/ + +/* NOTES: + + This driver was written for the Dynalink IS64PH ISDN TA, based on two + Siemens chips (HSCX 21525 and ISAC 2186). It is sold in the Netherlands. + + model numbers found on (my) card: + IS64PH, TAS100H-N, P/N:89590555, TA200S100045521 + + chips: + Siemens PSB 21525N, HSCX TE V2.1 + Siemens PSB 2186N, ISAC-S TE V1.1 + 95MS14, PNP + + plug-and-play info: + device id "ASU1688" + vendor id 0x88167506 + serial 0x00000044 + i/o port 4 byte alignment, 4 bytes requested, + 10 bit i/o decoding, 0x100-0x3f8 (?) + irq 3,4,5,9,10,11,12,15, high true, edge sensitive + + At the moment I'm writing this Dynalink is replacing this card with + one based on a single Siemens chip (IPAC). It will apparently be sold + under the same model name. + + This driver might also work for Asuscom cards. +*/ + +#include "isic.h" +#include "opt_i4b.h" + +#if (NISIC > 0) && defined(DYNALINK) + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/mbuf.h> +#include <sys/socket.h> + +#include <machine/clock.h> + +#include <net/if.h> + +#include <machine/i4b_debug.h> +#include <machine/i4b_ioctl.h> + +#include <i4b/layer1/isic/i4b_isic.h> +#include <i4b/layer1/isic/i4b_isac.h> +#include <i4b/layer1/isic/i4b_hscx.h> + +/* io address mapping */ +#define ISAC 0 +#define HSCX 1 +#define ADDR 2 + +/* ADDR bits */ +#define ADDRMASK 0x7F +#define RESET 0x80 + +/* HSCX register offsets */ +#define HSCXA 0x00 +#define HSCXB 0x40 + +/* LOW-LEVEL DEVICE ACCESS +*/ + +static void +dynalink_read_fifo(struct l1_softc *sc, int what, void *buf, size_t size) +{ + bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[0]); + bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]); + + switch (what) { + case ISIC_WHAT_ISAC: + bus_space_write_1(t, h, ADDR, 0); + bus_space_read_multi_1(t, h, ISAC, buf, size); + break; + case ISIC_WHAT_HSCXA: + bus_space_write_1(t, h, ADDR, HSCXA); + bus_space_read_multi_1(t, h, HSCX, buf, size); + break; + case ISIC_WHAT_HSCXB: + bus_space_write_1(t, h, ADDR, HSCXB); + bus_space_read_multi_1(t, h, HSCX, buf, size); + break; + } +} + +static void +dynalink_write_fifo(struct l1_softc *sc, int what, void *buf, size_t size) +{ + bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[0]); + bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]); + + switch (what) { + case ISIC_WHAT_ISAC: + bus_space_write_1(t, h, ADDR, 0); + bus_space_write_multi_1(t, h, ISAC, (u_int8_t*)buf, size); + break; + case ISIC_WHAT_HSCXA: + bus_space_write_1(t, h, ADDR, HSCXA); + bus_space_write_multi_1(t, h, HSCX, (u_int8_t*)buf, size); + break; + case ISIC_WHAT_HSCXB: + bus_space_write_1(t, h, ADDR, HSCXB); + bus_space_write_multi_1(t, h, HSCX, (u_int8_t*)buf, size); + break; + } +} + +static void +dynalink_write_reg(struct l1_softc *sc, int what, bus_size_t reg, u_int8_t data) +{ + bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[0]); + bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]); + + switch (what) { + case ISIC_WHAT_ISAC: + bus_space_write_1(t, h, ADDR, reg); + bus_space_write_1(t, h, ISAC, data); + break; + case ISIC_WHAT_HSCXA: + bus_space_write_1(t, h, ADDR, HSCXA+reg); + bus_space_write_1(t, h, HSCX, data); + break; + case ISIC_WHAT_HSCXB: + bus_space_write_1(t, h, ADDR, HSCXB+reg); + bus_space_write_1(t, h, HSCX, data); + break; + } +} + +static u_int8_t +dynalink_read_reg(struct l1_softc *sc, int what, bus_size_t reg) +{ + bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[0]); + bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]); + + switch (what) { + case ISIC_WHAT_ISAC: + bus_space_write_1(t, h, ADDR, reg); + return bus_space_read_1(t, h, ISAC); + case ISIC_WHAT_HSCXA: + bus_space_write_1(t, h, ADDR, HSCXA+reg); + return bus_space_read_1(t, h, HSCX); + case ISIC_WHAT_HSCXB: + bus_space_write_1(t, h, ADDR, HSCXB+reg); + return bus_space_read_1(t, h, HSCX); + } + return 0; +} + +/* attach callback routine */ +int +isic_attach_Dyn(device_t dev) +{ + int unit = device_get_unit(dev); /* get unit */ + struct l1_softc *sc = &l1_sc[unit]; /* pointer to softc */ + + struct i4b_info * info = &(sc->sc_resources); + bus_space_tag_t t = rman_get_bustag(info->io_base[0]); + bus_space_handle_t h = rman_get_bushandle(info->io_base[0]); + + /* fill in l1_softc structure */ + sc->readreg = dynalink_read_reg; + sc->writereg = dynalink_write_reg; + sc->readfifo = dynalink_read_fifo; + sc->writefifo = dynalink_write_fifo; + sc->clearirq = NULL; + sc->sc_cardtyp = CARD_TYPEP_DYNALINK; + sc->sc_bustyp = BUS_TYPE_IOM2; + sc->sc_ipac = 0; + sc->sc_bfifolen = HSCX_FIFO_LEN; + + /* 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", + sc->sc_unit); + printf("isic%d: HSC0: VSTR: %#x\n", + sc->sc_unit, HSCX_READ(0, H_VSTR)); + printf("isic%d: HSC1: VSTR: %#x\n", + sc->sc_unit, HSCX_READ(1, H_VSTR)); + return ENXIO; + } + + /* reset card */ + bus_space_write_1(t,h,ADDR,RESET); + DELAY(SEC_DELAY / 10); + bus_space_write_1(t,h,ADDR,0); + DELAY(SEC_DELAY / 10); + + return 0; +} + +#endif /* (NISIC > 0) && defined(DYNALINK) */ diff --git a/sys/i4b/layer1/i4b_elsa_pcc16.c b/sys/i4b/layer1/isic/i4b_elsa_pcc16.c index 5f1df77..ef8786a 100644 --- a/sys/i4b/layer1/i4b_elsa_pcc16.c +++ b/sys/i4b/layer1/isic/i4b_elsa_pcc16.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Hellmuth Michaelis. All rights reserved. + * Copyright (c) 1999, 2000 Hellmuth Michaelis. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,11 +27,13 @@ * isic - I4B Siemens ISDN Chipset Driver for ELSA MicroLink ISDN/PCC-16 * ===================================================================== * - * $Id: i4b_elsa_pcc16.c,v 1.2 1999/12/13 21:25:26 hm Exp $ + * This should now also work for an ELSA PCFpro. + * + * $Id: i4b_elsa_pcc16.c,v 1.4 2000/07/19 07:51:22 hm Exp $ * * $FreeBSD$ * - * last edit-date: [Mon Dec 13 21:59:36 1999] + * last edit-date: [Wed Jul 19 09:53:35 2000] * *---------------------------------------------------------------------------*/ @@ -41,6 +43,7 @@ #if (NISIC > 0) && defined(ELSA_PCC16) #include <sys/param.h> +#include <sys/kernel.h> #include <sys/systm.h> #include <sys/mbuf.h> #include <sys/socket.h> @@ -52,12 +55,12 @@ #include <machine/i4b_ioctl.h> #include <i4b/include/i4b_global.h> -#include <i4b/include/i4b_l1l2.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/isic/i4b_isic.h> +#include <i4b/layer1/isic/i4b_isac.h> +#include <i4b/layer1/isic/i4b_hscx.h> static void i4b_epcc16_clrirq(struct l1_softc *sc); @@ -308,15 +311,30 @@ isic_probe_Epcc16(device_t dev) if( ((HSCX_READ(0, H_VSTR) & 0xf) != 0x5) || ((HSCX_READ(1, H_VSTR) & 0xf) != 0x5) ) { - printf("isic%d: HSCX VSTR test failed for ELSA MicroLink ISDN/PCC-16\n", - unit); - printf("isic%d: HSC0: VSTR: %#x\n", - unit, HSCX_READ(0, H_VSTR)); - printf("isic%d: HSC1: VSTR: %#x\n", - unit, HSCX_READ(1, H_VSTR)); - isic_detach_Epcc16(dev); - return (ENXIO); - } + /* patch from "Doobee R . Tzeck" <drt@ailis.de>: + * I own an ELSA PCFpro. To my knowledge, the ELSA PCC16 is + * a stripped down Version on the PCFpro. By patching the + * card detection routine for the PPC16 I was able to use + * the PPC16 driver for the PCFpro. + */ + if( ((HSCX_READ(0, H_VSTR) & 0xf) != 0x85) || + ((HSCX_READ(1, H_VSTR) & 0xf) != 0x85) ) + { + printf("isic%d: HSCX VSTR test failed for ELSA MicroLink ISDN/PCC-16\n", + unit); + isic_detach_Epcc16(dev); + printf("isic%d: HSC0: VSTR: %#x\n", + unit, HSCX_READ(0, H_VSTR)); + printf("isic%d: HSC1: VSTR: %#x\n", + unit, HSCX_READ(1, H_VSTR)); + return (ENXIO); + } + else + { + printf("isic%d: ELSA MicroLink ISDN/PCFpro found, going to tread it as PCC-16\n", + unit); + } + } /* get our irq */ diff --git a/sys/i4b/layer1/i4b_elsa_qs1i.c b/sys/i4b/layer1/isic/i4b_elsa_qs1i.c index 8a767d6..40d4705 100644 --- a/sys/i4b/layer1/i4b_elsa_qs1i.c +++ b/sys/i4b/layer1/isic/i4b_elsa_qs1i.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved. + * Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,11 +27,11 @@ * isic - I4B Siemens ISDN Chipset Driver for ELSA Quickstep 1000pro ISA * ===================================================================== * - * $Id: i4b_elsa_qs1i.c,v 1.3 1999/12/13 21:25:26 hm Exp $ + * $Id: i4b_elsa_qs1i.c,v 1.3 2000/05/29 15:41:41 hm Exp $ * * $FreeBSD$ * - * last edit-date: [Mon Dec 13 21:59:44 1999] + * last edit-date: [Mon May 29 16:44:08 2000] * *---------------------------------------------------------------------------*/ @@ -41,6 +41,7 @@ #if (NISIC > 0) && defined(ELSA_QS1ISA) #include <sys/param.h> +#include <sys/kernel.h> #include <sys/systm.h> #include <sys/mbuf.h> #include <sys/socket.h> @@ -52,12 +53,12 @@ #include <machine/i4b_ioctl.h> #include <i4b/include/i4b_global.h> -#include <i4b/include/i4b_l1l2.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/isic/i4b_isic.h> +#include <i4b/layer1/isic/i4b_isac.h> +#include <i4b/layer1/isic/i4b_hscx.h> static void i4b_eq1i_clrirq(struct l1_softc *sc); diff --git a/sys/i4b/layer1/i4b_elsa_qs1p.c b/sys/i4b/layer1/isic/i4b_elsa_qs1p.c index aac277c..9a94422 100644 --- a/sys/i4b/layer1/i4b_elsa_qs1p.c +++ b/sys/i4b/layer1/isic/i4b_elsa_qs1p.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved. + * Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,11 +27,11 @@ * isic - I4B Siemens ISDN Chipset Driver for ELSA MicroLink ISDN/PCI * ================================================================== * - * $Id: i4b_elsa_qs1p.c,v 1.2 1999/12/13 21:25:26 hm Exp $ + * $Id: i4b_elsa_qs1p.c,v 1.4 2000/06/02 11:58:56 hm Exp $ * * $FreeBSD$ * - * last edit-date: [Mon Dec 13 21:59:51 1999] + * last edit-date: [Fri Jun 2 13:57:26 2000] * * Note: ELSA Quickstep 1000pro PCI = ELSA MicroLink ISDN/PCI * @@ -64,13 +64,13 @@ #include <machine/i4b_ioctl.h> #include <i4b/include/i4b_global.h> -#include <i4b/include/i4b_l1l2.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> +#include <i4b/layer1/isic/i4b_isic.h> +#include <i4b/layer1/isic/i4b_isac.h> +#include <i4b/layer1/isic/i4b_hscx.h> +#include <i4b/layer1/isic/i4b_ipac.h> #define MEM0_MAPOFF 0 #define PORT0_MAPOFF 4 diff --git a/sys/i4b/layer1/i4b_hscx.c b/sys/i4b/layer1/isic/i4b_hscx.c index 825316f..7731cb2 100644 --- a/sys/i4b/layer1/i4b_hscx.c +++ b/sys/i4b/layer1/isic/i4b_hscx.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved. + * Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,11 +27,11 @@ * i4b - Siemens HSCX chip (B-channel) handling * -------------------------------------------- * - * $Id: i4b_hscx.c,v 1.2 1999/12/13 21:25:26 hm Exp $ + * $Id: i4b_hscx.c,v 1.7 2000/05/29 15:41:41 hm Exp $ * * $FreeBSD$ * - * last edit-date: [Mon Dec 13 21:59:58 1999] + * last edit-date: [Mon May 29 16:44:50 2000] * *---------------------------------------------------------------------------*/ @@ -40,6 +40,7 @@ #if NISIC > 0 #include <sys/param.h> +#include <sys/kernel.h> #include <sys/systm.h> #include <sys/mbuf.h> #include <sys/socket.h> @@ -53,11 +54,12 @@ #include <machine/i4b_ioctl.h> #include <machine/i4b_trace.h> +#include <i4b/layer1/isic/i4b_isic.h> +#include <i4b/layer1/isic/i4b_isac.h> +#include <i4b/layer1/isic/i4b_hscx.h> + #include <i4b/layer1/i4b_l1.h> -#include <i4b/layer1/i4b_isac.h> -#include <i4b/layer1/i4b_hscx.h> -#include <i4b/include/i4b_l1l2.h> #include <i4b/include/i4b_global.h> #include <i4b/include/i4b_mbuf.h> @@ -71,8 +73,8 @@ isic_hscx_irq(register struct l1_softc *sc, u_char ista, int h_chan, u_char ex_i u_char exir = 0; int activity = -1; u_char cmd = 0; - - DBGL1(L1_H_IRQ, "isic_hscx_irq", ("%#x\n", ista)); + + NDBGL1(L1_H_IRQ, "%#x", ista); if(ex_irq) { @@ -83,13 +85,13 @@ isic_hscx_irq(register struct l1_softc *sc, u_char ista, int h_chan, u_char ex_i if(exir & HSCX_EXIR_RFO) { chan->stat_RFO++; - DBGL1(L1_H_XFRERR, "isic_hscx_irq", ("ex_irq: receive data overflow\n")); + NDBGL1(L1_H_XFRERR, "ex_irq: receive data overflow"); } if((exir & HSCX_EXIR_XDU) && (chan->bprot != BPROT_NONE))/* xmit data underrun */ { chan->stat_XDU++; - DBGL1(L1_H_XFRERR, "isic_hscx_irq", ("ex_irq: xmit data underrun\n")); + NDBGL1(L1_H_XFRERR, "ex_irq: xmit data underrun"); isic_hscx_cmd(sc, h_chan, HSCX_CMDR_XRES); if (chan->out_mbuf_head != NULL) /* don't continue to transmit this buffer */ @@ -117,14 +119,14 @@ isic_hscx_irq(register struct l1_softc *sc, u_char ista, int h_chan, u_char ex_i { chan->stat_VFR++; cmd |= (HSCX_CMDR_RHR); - DBGL1(L1_H_XFRERR, "isic_hscx_irq", ("received invalid Frame\n")); + NDBGL1(L1_H_XFRERR, "received invalid Frame"); error++; } if(rsta & HSCX_RSTA_RDO) { chan->stat_RDO++; - DBGL1(L1_H_XFRERR, "isic_hscx_irq", ("receive data overflow\n")); + NDBGL1(L1_H_XFRERR, "receive data overflow"); error++; } @@ -132,14 +134,14 @@ isic_hscx_irq(register struct l1_softc *sc, u_char ista, int h_chan, u_char ex_i { chan->stat_CRC++; cmd |= (HSCX_CMDR_RHR); - DBGL1(L1_H_XFRERR, "isic_hscx_irq", ("CRC check failed\n")); + NDBGL1(L1_H_XFRERR, "CRC check failed"); error++; } if(rsta & HSCX_RSTA_RAB) { chan->stat_RAB++; - DBGL1(L1_H_XFRERR, "isic_hscx_irq", ("Receive message aborted\n")); + NDBGL1(L1_H_XFRERR, "Receive message aborted"); error++; } } @@ -185,15 +187,15 @@ isic_hscx_irq(register struct l1_softc *sc, u_char ista, int h_chan, u_char ex_i if(sc->sc_trace & TRACE_B_RX) { i4b_trace_hdr_t hdr; - hdr.unit = sc->sc_unit; + hdr.unit = L0ISICUNIT(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); + i4b_l1_trace_ind(&hdr, chan->in_mbuf->m_len, chan->in_mbuf->m_data); } - (*chan->drvr_linktab->bch_rx_data_ready)(chan->drvr_linktab->unit); + (*chan->isic_drvr_linktab->bch_rx_data_ready)(chan->isic_drvr_linktab->unit); activity = ACT_RX; @@ -205,7 +207,7 @@ isic_hscx_irq(register struct l1_softc *sc, u_char ista, int h_chan, u_char ex_i } else { - DBGL1(L1_H_XFRERR, "isic_hscx_irq", ("RAWHDLC rx buffer overflow in RME, in_len=%d, fifolen=%d\n", chan->in_len, fifo_data_len)); + NDBGL1(L1_H_XFRERR, "RAWHDLC rx buffer overflow in RME, in_len=%d, fifolen=%d", chan->in_len, fifo_data_len); chan->in_cbptr = chan->in_mbuf->m_data; chan->in_len = 0; cmd |= (HSCX_CMDR_RHR | HSCX_CMDR_RMC); @@ -259,17 +261,17 @@ isic_hscx_irq(register struct l1_softc *sc, u_char ista, int h_chan, u_char ex_i if(sc->sc_trace & TRACE_B_RX) { i4b_trace_hdr_t hdr; - hdr.unit = sc->sc_unit; + hdr.unit = L0ISICUNIT(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); + i4b_l1_trace_ind(&hdr, chan->in_mbuf->m_len, chan->in_mbuf->m_data); } /* silence detection */ - if(!(isic_hscx_silence(chan->in_mbuf->m_data, chan->in_mbuf->m_len))) + if(!(i4b_l1_bchan_tel_silence(chan->in_mbuf->m_data, chan->in_mbuf->m_len))) activity = ACT_RX; if(!(IF_QFULL(&chan->rx_queue))) @@ -283,7 +285,7 @@ isic_hscx_irq(register struct l1_softc *sc, u_char ista, int h_chan, u_char ex_i /* signal upper driver that data is available */ - (*chan->drvr_linktab->bch_rx_data_ready)(chan->drvr_linktab->unit); + (*chan->isic_drvr_linktab->bch_rx_data_ready)(chan->isic_drvr_linktab->unit); /* alloc new buffer */ @@ -305,7 +307,7 @@ isic_hscx_irq(register struct l1_softc *sc, u_char ista, int h_chan, u_char ex_i } else { - DBGL1(L1_H_XFRERR, "isic_hscx_irq", ("RAWHDLC rx buffer overflow in RPF, in_len=%d\n", chan->in_len)); + NDBGL1(L1_H_XFRERR, "RAWHDLC rx buffer overflow in RPF, in_len=%d", chan->in_len); chan->in_cbptr = chan->in_mbuf->m_data; chan->in_len = 0; cmd |= (HSCX_CMDR_RHR); @@ -330,7 +332,7 @@ isic_hscx_irq(register struct l1_softc *sc, u_char ista, int h_chan, u_char ex_i int len; int nextlen; - DBGL1(L1_H_IRQ, "isic_hscx_irq", ("unit %d, chan %d - XPR, Tx Fifo Empty!\n", sc->sc_unit, h_chan)); + NDBGL1(L1_H_IRQ, "unit %d, chan %d - XPR, Tx Fifo Empty!", sc->sc_unit, h_chan); if(chan->out_mbuf_cur == NULL) /* last frame is transmitted */ { @@ -339,7 +341,7 @@ isic_hscx_irq(register struct l1_softc *sc, u_char ista, int h_chan, u_char ex_i if(chan->out_mbuf_head == NULL) { chan->state &= ~HSCX_TX_ACTIVE; - (*chan->drvr_linktab->bch_tx_queue_empty)(chan->drvr_linktab->unit); + (*chan->isic_drvr_linktab->bch_tx_queue_empty)(chan->isic_drvr_linktab->unit); } else { @@ -351,17 +353,17 @@ isic_hscx_irq(register struct l1_softc *sc, u_char ista, int h_chan, u_char ex_i if(sc->sc_trace & TRACE_B_TX) { i4b_trace_hdr_t hdr; - hdr.unit = sc->sc_unit; + hdr.unit = L0ISICUNIT(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); + i4b_l1_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))) + if(!(i4b_l1_bchan_tel_silence(chan->out_mbuf_cur->m_data, chan->out_mbuf_cur->m_len))) activity = ACT_TX; } else @@ -408,12 +410,12 @@ isic_hscx_irq(register struct l1_softc *sc, u_char ista, int h_chan, u_char ex_i if(sc->sc_trace & TRACE_B_TX) { i4b_trace_hdr_t hdr; - hdr.unit = sc->sc_unit; + hdr.unit = L0ISICUNIT(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); + i4b_l1_trace_ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data); } } else @@ -436,7 +438,7 @@ isic_hscx_irq(register struct l1_softc *sc, u_char ista, int h_chan, u_char ex_i /* call timeout handling routine */ if(activity == ACT_RX || activity == ACT_TX) - (*chan->drvr_linktab->bch_activity)(chan->drvr_linktab->unit, activity); + (*chan->isic_drvr_linktab->bch_activity)(chan->isic_drvr_linktab->unit, activity); } /*---------------------------------------------------------------------------* @@ -541,8 +543,11 @@ isic_hscx_init(struct l1_softc *sc, int h_chan, int activate) HSCX_WRITE(h_chan, H_MODE, HSCX_MODE_MDS1|HSCX_MODE_MDS0|HSCX_MODE_ADM|HSCX_MODE_RTS); } - +#if 0 isic_hscx_cmd(sc, h_chan, HSCX_CMDR_RHR|HSCX_CMDR_XRES); +#else + isic_hscx_cmd(sc, h_chan, HSCX_CMDR_RHR); +#endif } else { @@ -625,7 +630,7 @@ isic_hscx_cmd(struct l1_softc *sc, int h_chan, unsigned char cmd) if(timeout == 0) { - DBGL1(L1_H_ERR, "isic_hscx_cmd", ("HSCX wait for CEC timeout!\n")); + NDBGL1(L1_H_ERR, "HSCX wait for CEC timeout!"); } HSCX_WRITE(h_chan, H_CMDR, cmd); @@ -651,11 +656,11 @@ isic_hscx_waitxfw(struct l1_softc *sc, int h_chan) if(timeout == 0) { - DBGL1(L1_H_ERR, "isic_hscx_waitxfw", ("HSCX wait for XFW timeout!\n")); + NDBGL1(L1_H_ERR, "HSCX wait for XFW timeout!"); } else if (timeout != WAITTO) { - DBGL1(L1_H_XFRERR, "isic_hscx_waitxfw", ("HSCX wait for XFW time: %d uS\n", (WAITTO-timeout)*50)); + NDBGL1(L1_H_XFRERR, "HSCX wait for XFW time: %d uS", (WAITTO-timeout)*50); } } diff --git a/sys/i4b/layer1/i4b_hscx.h b/sys/i4b/layer1/isic/i4b_hscx.h index e642698..b4a9197 100644 --- a/sys/i4b/layer1/i4b_hscx.h +++ b/sys/i4b/layer1/isic/i4b_hscx.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 1998 Gary Jennejohn. All rights reserved. + * Copyright (c) 1996, 2000 Gary Jennejohn. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -30,7 +30,7 @@ * *--------------------------------------------------------------------------- * - * $Id: i4b_hscx.h,v 1.2 1999/12/13 21:25:26 hm Exp $ + * $Id: i4b_hscx.h,v 1.2 2000/03/09 16:12:51 hm Exp $ * * $FreeBSD$ * diff --git a/sys/i4b/layer1/i4b_ipac.h b/sys/i4b/layer1/isic/i4b_ipac.h index 73683d3..623092d 100644 --- a/sys/i4b/layer1/i4b_ipac.h +++ b/sys/i4b/layer1/isic/i4b_ipac.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved. + * Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,7 +27,7 @@ * i4b_ipac.h - definitions for the Siemens IPAC PSB2115 chip * ========================================================== * - * $Id: i4b_ipac.h,v 1.2 1999/12/13 21:25:26 hm Exp $ + * $Id: i4b_ipac.h,v 1.1 2000/03/07 14:12:26 hm Exp $ * * $FreeBSD$ * @@ -49,6 +49,7 @@ /* chip version */ #define IPAC_V11 0x01 /* IPAC Version 1.1 */ +#define IPAC_V12 0x02 /* IPAC Version 1.2 */ /* * definitions of registers and bits for the IPAC ISDN chip. diff --git a/sys/i4b/layer1/i4b_isac.c b/sys/i4b/layer1/isic/i4b_isac.c index 8c5cb15..792d46b 100644 --- a/sys/i4b/layer1/i4b_isac.c +++ b/sys/i4b/layer1/isic/i4b_isac.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved. + * Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,11 +27,11 @@ * i4b_isac.c - i4b siemens isdn chipset driver ISAC handler * --------------------------------------------------------- * - * $Id: i4b_isac.c,v 1.2 1999/12/13 21:25:26 hm Exp $ + * $Id: i4b_isac.c,v 1.7 2000/05/29 15:41:41 hm Exp $ * * $FreeBSD$ * - * last edit-date: [Mon Dec 13 22:01:05 1999] + * last edit-date: [Mon May 29 16:45:08 2000] * *---------------------------------------------------------------------------*/ @@ -42,6 +42,7 @@ #include "opt_i4b.h" #include <sys/param.h> +#include <sys/kernel.h> #include <sys/systm.h> #include <sys/mbuf.h> #include <sys/socket.h> @@ -56,11 +57,12 @@ #include <machine/i4b_trace.h> #include <i4b/layer1/i4b_l1.h> -#include <i4b/layer1/i4b_isac.h> -#include <i4b/layer1/i4b_hscx.h> + +#include <i4b/layer1/isic/i4b_isic.h> +#include <i4b/layer1/isic/i4b_isac.h> +#include <i4b/layer1/isic/i4b_hscx.h> #include <i4b/include/i4b_global.h> -#include <i4b/include/i4b_l1l2.h> #include <i4b/include/i4b_mbuf.h> static u_char isic_isac_exir_hdlr(register struct l1_softc *sc, u_char exir); @@ -73,7 +75,7 @@ void isic_isac_irq(struct l1_softc *sc, int ista) { register u_char c = 0; - DBGL1(L1_F_MSG, "isic_isac_irq", ("unit %d: ista = 0x%02x\n", sc->sc_unit, ista)); + NDBGL1(L1_F_MSG, "unit %d: ista = 0x%02x", sc->sc_unit, ista); if(ista & ISAC_ISTA_EXI) /* extended interrupt */ { @@ -96,23 +98,23 @@ isic_isac_irq(struct l1_softc *sc, int ista) if(!(rsta & ISAC_RSTA_CRC)) /* CRC error */ { error++; - DBGL1(L1_I_ERR, "isic_isac_irq", ("unit %d: CRC error\n", sc->sc_unit)); + NDBGL1(L1_I_ERR, "unit %d: CRC error", sc->sc_unit); } if(rsta & ISAC_RSTA_RDO) /* ReceiveDataOverflow */ { error++; - DBGL1(L1_I_ERR, "isic_isac_irq", ("unit %d: Data Overrun error\n", sc->sc_unit)); + NDBGL1(L1_I_ERR, "unit %d: Data Overrun error", sc->sc_unit); } if(rsta & ISAC_RSTA_RAB) /* ReceiveABorted */ { error++; - DBGL1(L1_I_ERR, "isic_isac_irq", ("unit %d: Receive Aborted error\n", sc->sc_unit)); + NDBGL1(L1_I_ERR, "unit %d: Receive Aborted error", sc->sc_unit); } if(error == 0) - DBGL1(L1_I_ERR, "isic_isac_irq", ("unit %d: RME unknown error, RSTA = 0x%02x!\n", sc->sc_unit, rsta)); + NDBGL1(L1_I_ERR, "unit %d: RME unknown error, RSTA = 0x%02x!", sc->sc_unit, rsta); i4b_Dfreembuf(sc->sc_ibuf); @@ -153,12 +155,12 @@ isic_isac_irq(struct l1_softc *sc, int ista) if(sc->sc_trace & TRACE_D_RX) { i4b_trace_hdr_t hdr; - hdr.unit = sc->sc_unit; + hdr.unit = L0ISICUNIT(sc->sc_unit); hdr.type = TRC_CH_D; hdr.dir = FROM_NT; hdr.count = ++sc->sc_trace_dcount; MICROTIME(hdr.time); - MPH_Trace_Ind(&hdr, sc->sc_ibuf->m_len, sc->sc_ibuf->m_data); + i4b_l1_trace_ind(&hdr, sc->sc_ibuf->m_len, sc->sc_ibuf->m_data); } c |= ISAC_CMDR_RMC; @@ -166,7 +168,7 @@ isic_isac_irq(struct l1_softc *sc, int ista) if(sc->sc_enabled && (ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S)) { - PH_Data_Ind(sc->sc_unit, sc->sc_ibuf); + i4b_l1_ph_data_ind(L0ISICUNIT(sc->sc_unit), sc->sc_ibuf); } else { @@ -175,7 +177,7 @@ isic_isac_irq(struct l1_softc *sc, int ista) } else { - DBGL1(L1_I_ERR, "isic_isac_irq", ("RME, input buffer overflow!\n")); + NDBGL1(L1_I_ERR, "RME, input buffer overflow!"); i4b_Dfreembuf(sc->sc_ibuf); c |= ISAC_CMDR_RMC|ISAC_CMDR_RRES; } @@ -205,7 +207,7 @@ isic_isac_irq(struct l1_softc *sc, int ista) } else { - DBGL1(L1_I_ERR, "isic_isac_irq", ("RPF, input buffer overflow!\n")); + NDBGL1(L1_I_ERR, "RPF, input buffer overflow!"); i4b_Dfreembuf(sc->sc_ibuf); sc->sc_ibuf = NULL; sc->sc_ib = NULL; @@ -308,52 +310,52 @@ isic_isac_exir_hdlr(register struct l1_softc *sc, u_char exir) if(exir & ISAC_EXIR_XMR) { - DBGL1(L1_I_ERR, "isic_isac_exir_hdlr", ("EXIRQ Tx Message Repeat\n")); + NDBGL1(L1_I_ERR, "EXIRQ Tx Message Repeat"); c |= ISAC_CMDR_XRES; } if(exir & ISAC_EXIR_XDU) { - DBGL1(L1_I_ERR, "isic_isac_exir_hdlr", ("EXIRQ Tx Data Underrun\n")); + NDBGL1(L1_I_ERR, "EXIRQ Tx Data Underrun"); c |= ISAC_CMDR_XRES; } if(exir & ISAC_EXIR_PCE) { - DBGL1(L1_I_ERR, "isic_isac_exir_hdlr", ("EXIRQ Protocol Error\n")); + NDBGL1(L1_I_ERR, "EXIRQ Protocol Error"); } if(exir & ISAC_EXIR_RFO) { - DBGL1(L1_I_ERR, "isic_isac_exir_hdlr", ("EXIRQ Rx Frame Overflow\n")); + NDBGL1(L1_I_ERR, "EXIRQ Rx Frame Overflow"); c |= ISAC_CMDR_RMC|ISAC_CMDR_RRES; } if(exir & ISAC_EXIR_SOV) { - DBGL1(L1_I_ERR, "isic_isac_exir_hdlr", ("EXIRQ Sync Xfer Overflow\n")); + NDBGL1(L1_I_ERR, "EXIRQ Sync Xfer Overflow"); } if(exir & ISAC_EXIR_MOS) { - DBGL1(L1_I_ERR, "L1 isic_isac_exir_hdlr", ("EXIRQ Monitor Status\n")); + NDBGL1(L1_I_ERR, "EXIRQ Monitor Status"); } if(exir & ISAC_EXIR_SAW) { /* cannot happen, STCR:TSF is set to 0 */ - DBGL1(L1_I_ERR, "isic_isac_exir_hdlr", ("EXIRQ Subscriber Awake\n")); + NDBGL1(L1_I_ERR, "EXIRQ Subscriber Awake"); } if(exir & ISAC_EXIR_WOV) { /* cannot happen, STCR:TSF is set to 0 */ - DBGL1(L1_I_ERR, "isic_isac_exir_hdlr", ("EXIRQ Watchdog Timer Overflow\n")); + NDBGL1(L1_I_ERR, "EXIRQ Watchdog Timer Overflow"); } return(c); @@ -370,76 +372,76 @@ isic_isac_ind_hdlr(register struct l1_softc *sc, int ind) switch(ind) { case ISAC_CIRR_IAI8: - DBGL1(L1_I_CICO, "isic_isac_ind_hdlr", ("rx AI8 in state %s\n", isic_printstate(sc))); + NDBGL1(L1_I_CICO, "rx AI8 in state %s", isic_printstate(sc)); if(sc->sc_bustyp == BUS_TYPE_IOM2) isic_isac_l1_cmd(sc, CMD_AR8); event = EV_INFO48; - MPH_Status_Ind(sc->sc_unit, STI_L1STAT, LAYER_ACTIVE); + i4b_l1_mph_status_ind(L0ISICUNIT(sc->sc_unit), STI_L1STAT, LAYER_ACTIVE, NULL); break; case ISAC_CIRR_IAI10: - DBGL1(L1_I_CICO, "isic_isac_ind_hdlr", ("rx AI10 in state %s\n", isic_printstate(sc))); + NDBGL1(L1_I_CICO, "rx AI10 in state %s", isic_printstate(sc)); if(sc->sc_bustyp == BUS_TYPE_IOM2) isic_isac_l1_cmd(sc, CMD_AR10); event = EV_INFO410; - MPH_Status_Ind(sc->sc_unit, STI_L1STAT, LAYER_ACTIVE); + i4b_l1_mph_status_ind(L0ISICUNIT(sc->sc_unit), STI_L1STAT, LAYER_ACTIVE, NULL); break; case ISAC_CIRR_IRSY: - DBGL1(L1_I_CICO, "isic_isac_ind_hdlr", ("rx RSY in state %s\n", isic_printstate(sc))); + NDBGL1(L1_I_CICO, "rx RSY in state %s", isic_printstate(sc)); event = EV_RSY; break; case ISAC_CIRR_IPU: - DBGL1(L1_I_CICO, "isic_isac_ind_hdlr", ("rx PU in state %s\n", isic_printstate(sc))); + NDBGL1(L1_I_CICO, "rx PU in state %s", isic_printstate(sc)); event = EV_PU; break; case ISAC_CIRR_IDR: - DBGL1(L1_I_CICO, "isic_isac_ind_hdlr", ("rx DR in state %s\n", isic_printstate(sc))); + NDBGL1(L1_I_CICO, "rx DR in state %s", isic_printstate(sc)); isic_isac_l1_cmd(sc, CMD_DIU); event = EV_DR; break; case ISAC_CIRR_IDID: - DBGL1(L1_I_CICO, "isic_isac_ind_hdlr", ("rx DID in state %s\n", isic_printstate(sc))); + NDBGL1(L1_I_CICO, "rx DID in state %s", isic_printstate(sc)); event = EV_INFO0; - MPH_Status_Ind(sc->sc_unit, STI_L1STAT, LAYER_IDLE); + i4b_l1_mph_status_ind(L0ISICUNIT(sc->sc_unit), STI_L1STAT, LAYER_IDLE, NULL); break; case ISAC_CIRR_IDIS: - DBGL1(L1_I_CICO, "isic_isac_ind_hdlr", ("rx DIS in state %s\n", isic_printstate(sc))); + NDBGL1(L1_I_CICO, "rx DIS in state %s", isic_printstate(sc)); event = EV_DIS; break; case ISAC_CIRR_IEI: - DBGL1(L1_I_CICO, "isic_isac_ind_hdlr", ("rx EI in state %s\n", isic_printstate(sc))); + NDBGL1(L1_I_CICO, "rx EI in state %s", isic_printstate(sc)); isic_isac_l1_cmd(sc, CMD_DIU); event = EV_EI; break; case ISAC_CIRR_IARD: - DBGL1(L1_I_CICO, "isic_isac_ind_hdlr", ("rx ARD in state %s\n", isic_printstate(sc))); + NDBGL1(L1_I_CICO, "rx ARD in state %s", isic_printstate(sc)); event = EV_INFO2; break; case ISAC_CIRR_ITI: - DBGL1(L1_I_CICO, "isic_isac_ind_hdlr", ("rx TI in state %s\n", isic_printstate(sc))); + NDBGL1(L1_I_CICO, "rx TI in state %s", isic_printstate(sc)); event = EV_INFO0; break; case ISAC_CIRR_IATI: - DBGL1(L1_I_CICO, "isic_isac_ind_hdlr", ("rx ATI in state %s\n", isic_printstate(sc))); + NDBGL1(L1_I_CICO, "rx ATI in state %s", isic_printstate(sc)); event = EV_INFO0; break; case ISAC_CIRR_ISD: - DBGL1(L1_I_CICO, "isic_isac_ind_hdlr", ("rx SD in state %s\n", isic_printstate(sc))); + NDBGL1(L1_I_CICO, "rx SD in state %s", isic_printstate(sc)); event = EV_INFO0; break; default: - DBGL1(L1_I_ERR, "isic_isac_ind_hdlr", ("UNKNOWN Indication 0x%x in state %s\n", ind, isic_printstate(sc))); + NDBGL1(L1_I_ERR, "UNKNOWN Indication 0x%x in state %s", ind, isic_printstate(sc)); event = EV_INFO0; break; } @@ -481,7 +483,7 @@ isic_isac_l1_cmd(struct l1_softc *sc, int command) if(command < 0 || command > CMD_ILL) { - DBGL1(L1_I_ERR, "isic_isac_l1_cmd", ("illegal cmd 0x%x in state %s\n", command, isic_printstate(sc))); + NDBGL1(L1_I_ERR, "illegal cmd 0x%x in state %s", command, isic_printstate(sc)); return; } @@ -493,27 +495,27 @@ isic_isac_l1_cmd(struct l1_softc *sc, int command) switch(command) { case CMD_TIM: - DBGL1(L1_I_CICO, "isic_isac_l1_cmd", ("tx TIM in state %s\n", isic_printstate(sc))); + NDBGL1(L1_I_CICO, "tx TIM in state %s", isic_printstate(sc)); cmd |= (ISAC_CIXR_CTIM << 2); break; case CMD_RS: - DBGL1(L1_I_CICO, "isic_isac_l1_cmd", ("tx RS in state %s\n", isic_printstate(sc))); + NDBGL1(L1_I_CICO, "tx RS in state %s", isic_printstate(sc)); cmd |= (ISAC_CIXR_CRS << 2); break; case CMD_AR8: - DBGL1(L1_I_CICO, "isic_isac_l1_cmd", ("tx AR8 in state %s\n", isic_printstate(sc))); + NDBGL1(L1_I_CICO, "tx AR8 in state %s", isic_printstate(sc)); cmd |= (ISAC_CIXR_CAR8 << 2); break; case CMD_AR10: - DBGL1(L1_I_CICO, "isic_isac_l1_cmd", ("tx AR10 in state %s\n", isic_printstate(sc))); + NDBGL1(L1_I_CICO, "tx AR10 in state %s", isic_printstate(sc)); cmd |= (ISAC_CIXR_CAR10 << 2); break; case CMD_DIU: - DBGL1(L1_I_CICO, "isic_isac_l1_cmd", ("tx DIU in state %s\n", isic_printstate(sc))); + NDBGL1(L1_I_CICO, "tx DIU in state %s", isic_printstate(sc)); cmd |= (ISAC_CIXR_CDIU << 2); break; } @@ -532,7 +534,7 @@ isic_isac_init(struct l1_softc *sc) if(sc->sc_bustyp != BUS_TYPE_IOM2) { - DBGL1(L1_I_SETUP, "isic_isac_setup", ("configuring for IOM-1 mode\n")); + NDBGL1(L1_I_SETUP, "configuring for IOM-1 mode"); /* ADF2: Select mode IOM-1 */ ISAC_WRITE(I_ADF2, 0x00); @@ -579,7 +581,7 @@ isic_isac_init(struct l1_softc *sc) } else { - DBGL1(L1_I_SETUP, "isic_isac_setup", ("configuring for IOM-2 mode\n")); + NDBGL1(L1_I_SETUP, "configuring for IOM-2 mode"); /* ADF2: Select mode IOM-2 */ ISAC_WRITE(I_ADF2, ISAC_ADF2_IMS); diff --git a/sys/i4b/layer1/i4b_isac.h b/sys/i4b/layer1/isic/i4b_isac.h index 83fa1db..2d92d000 100644 --- a/sys/i4b/layer1/i4b_isac.h +++ b/sys/i4b/layer1/isic/i4b_isac.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 1998 Gary Jennejohn. All rights reserved. + * Copyright (c) 1996, 2000 Gary Jennejohn. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -30,7 +30,7 @@ * *--------------------------------------------------------------------------- * - * $Id: i4b_isac.h,v 1.2 1999/12/13 21:25:26 hm Exp $ + * $Id: i4b_isac.h,v 1.2 2000/03/09 16:12:51 hm Exp $ * * $FreeBSD$ * diff --git a/sys/i4b/layer1/i4b_isic.c b/sys/i4b/layer1/isic/i4b_isic.c index d3d5ca8..97cbf73 100644 --- a/sys/i4b/layer1/i4b_isic.c +++ b/sys/i4b/layer1/isic/i4b_isic.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved. + * Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,11 +27,11 @@ * i4b_isic.c - global isic stuff * ============================== * - * $Id: i4b_isic.c,v 1.3 1999/12/13 21:25:26 hm Exp $ + * $Id: i4b_isic.c,v 1.6 2000/05/29 15:41:41 hm Exp $ * * $FreeBSD$ * - * last edit-date: [Mon Dec 13 22:01:33 1999] + * last edit-date: [Mon May 29 16:45:24 2000] * *---------------------------------------------------------------------------*/ @@ -41,6 +41,7 @@ #if NISIC > 0 #include <sys/param.h> +#include <sys/kernel.h> #include <sys/systm.h> #include <sys/mbuf.h> #include <sys/socket.h> @@ -53,17 +54,16 @@ #include <machine/i4b_trace.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> -#include <i4b/include/i4b_l1l2.h> +#include <i4b/layer1/isic/i4b_isic.h> +#include <i4b/layer1/isic/i4b_isic_ext.h> +#include <i4b/layer1/isic/i4b_ipac.h> +#include <i4b/layer1/isic/i4b_isac.h> +#include <i4b/layer1/isic/i4b_hscx.h> + #include <i4b/include/i4b_mbuf.h> #include <i4b/include/i4b_global.h> -void isic_settrace(int unit, int val); -int isic_gettrace(int unit); - static char *ISACversion[] = { "2085 Version A1/A2 or 2086/2186 Version 1.1", "2085 Version B1", @@ -82,6 +82,15 @@ static char *HSCXversion[] = { "Unknown Version" }; +/* jump table for multiplex routines */ +struct i4b_l1mux_func isic_l1mux_func = { + isic_ret_linktab, + isic_set_linktab, + isic_mph_command_req, + isic_ph_data_req, + isic_ph_activate_req, +}; + /*---------------------------------------------------------------------------* * isic - device driver interrupt routine *---------------------------------------------------------------------------*/ @@ -208,26 +217,6 @@ isicintr(struct l1_softc *sc) } /*---------------------------------------------------------------------------* - * isic_settrace - *---------------------------------------------------------------------------*/ -void -isic_settrace(int unit, int val) -{ - struct l1_softc *sc = &l1_sc[unit]; - sc->sc_trace = val; -} - -/*---------------------------------------------------------------------------* - * isic_gettrace - *---------------------------------------------------------------------------*/ -int -isic_gettrace(int unit) -{ - struct l1_softc *sc = &l1_sc[unit]; - return(sc->sc_trace); -} - -/*---------------------------------------------------------------------------* * isic_recover - try to recover from irq lockup *---------------------------------------------------------------------------*/ void @@ -239,38 +228,38 @@ isic_recover(struct l1_softc *sc) byte = HSCX_READ(HSCX_CH_B, H_ISTA); - DBGL1(L1_ERROR, "isic_recover", ("HSCX B: ISTA = 0x%x\n", byte)); + NDBGL1(L1_ERROR, "HSCX B: ISTA = 0x%x", byte); if(byte & HSCX_ISTA_ICA) - DBGL1(L1_ERROR, "isic_recover", ("HSCX A: ISTA = 0x%x\n", (u_char)HSCX_READ(HSCX_CH_A, H_ISTA))); + NDBGL1(L1_ERROR, "HSCX A: ISTA = 0x%x", (u_char)HSCX_READ(HSCX_CH_A, H_ISTA)); if(byte & HSCX_ISTA_EXB) - DBGL1(L1_ERROR, "isic_recover", ("HSCX B: EXIR = 0x%x\n", (u_char)HSCX_READ(HSCX_CH_B, H_EXIR))); + NDBGL1(L1_ERROR, "HSCX B: EXIR = 0x%x", (u_char)HSCX_READ(HSCX_CH_B, H_EXIR)); if(byte & HSCX_ISTA_EXA) - DBGL1(L1_ERROR, "isic_recover", ("HSCX A: EXIR = 0x%x\n", (u_char)HSCX_READ(HSCX_CH_A, H_EXIR))); + NDBGL1(L1_ERROR, "HSCX A: EXIR = 0x%x", (u_char)HSCX_READ(HSCX_CH_A, H_EXIR)); /* get isac irq status */ byte = ISAC_READ(I_ISTA); - DBGL1(L1_ERROR, "isic_recover", (" ISAC: ISTA = 0x%x\n", byte)); + NDBGL1(L1_ERROR, " ISAC: ISTA = 0x%x", byte); if(byte & ISAC_ISTA_EXI) - DBGL1(L1_ERROR, "isic_recover", (" ISAC: EXIR = 0x%x\n", (u_char)ISAC_READ(I_EXIR))); + NDBGL1(L1_ERROR, " ISAC: EXIR = 0x%x", (u_char)ISAC_READ(I_EXIR)); if(byte & ISAC_ISTA_CISQ) { byte = ISAC_READ(I_CIRR); - DBGL1(L1_ERROR, "isic_recover", (" ISAC: CISQ = 0x%x\n", byte)); + NDBGL1(L1_ERROR, " ISAC: CISQ = 0x%x", byte); if(byte & ISAC_CIRR_SQC) - DBGL1(L1_ERROR, "isic_recover", (" ISAC: SQRR = 0x%x\n", (u_char)ISAC_READ(I_SQRR))); + NDBGL1(L1_ERROR, " ISAC: SQRR = 0x%x", (u_char)ISAC_READ(I_SQRR)); } - DBGL1(L1_ERROR, "isic_recover", ("HSCX B: IMASK = 0x%x\n", HSCX_B_IMASK)); - DBGL1(L1_ERROR, "isic_recover", ("HSCX A: IMASK = 0x%x\n", HSCX_A_IMASK)); + NDBGL1(L1_ERROR, "HSCX B: IMASK = 0x%x", HSCX_B_IMASK); + NDBGL1(L1_ERROR, "HSCX A: IMASK = 0x%x", HSCX_A_IMASK); HSCX_WRITE(0, H_MASK, 0xff); HSCX_WRITE(1, H_MASK, 0xff); @@ -279,7 +268,7 @@ isic_recover(struct l1_softc *sc) HSCX_WRITE(1, H_MASK, HSCX_B_IMASK); DELAY(100); - DBGL1(L1_ERROR, "isic_recover", (" ISAC: IMASK = 0x%x\n", ISAC_IMASK)); + NDBGL1(L1_ERROR, " ISAC: IMASK = 0x%x", ISAC_IMASK); ISAC_WRITE(I_MASK, 0xff); DELAY(100); @@ -292,7 +281,6 @@ isic_recover(struct l1_softc *sc) int isic_attach_common(device_t dev) { - int ret; char *drvid = NULL; int unit = device_get_unit(dev); struct l1_softc *sc = &l1_sc[unit]; @@ -304,19 +292,19 @@ isic_attach_common(device_t dev) if(sc->sc_ipac) { - ret = IPAC_READ(IPAC_ID); - - switch(ret) - { - case 0x01: - break; - - default: - printf("isic%d: Error, IPAC version %d unknown!\n", - unit, ret); - return ENXIO; - break; - + sc->sc_ipac_version = IPAC_READ(IPAC_ID); + + switch(sc->sc_ipac_version) + { + case IPAC_V11: + case IPAC_V12: + break; + + default: + printf("isic%d: Error, IPAC version %d unknown!\n", + unit, sc->sc_ipac_version); + return(0); + break; } } else @@ -389,8 +377,8 @@ isic_attach_common(device_t dev) /* init higher protocol layers */ - MPH_Status_Ind(sc->sc_unit, STI_ATTACH, sc->sc_cardtyp); - + i4b_l1_mph_status_ind(L0ISICUNIT(sc->sc_unit), STI_ATTACH, sc->sc_cardtyp, &isic_l1mux_func); + /* announce manufacturer and card type for ISA cards */ switch(sc->sc_flags) @@ -441,7 +429,10 @@ isic_attach_common(device_t dev) if(sc->sc_ipac) { - printf("isic%d: IPAC PSB2115 Version 1.1\n", unit); + if(sc->sc_ipac_version == IPAC_V11) + printf("isic%d: IPAC PSB2115 Version 1.1\n", unit); + else + printf("isic%d: IPAC PSB2115 Version 1.2\n", unit); } else { diff --git a/sys/i4b/layer1/i4b_l1.h b/sys/i4b/layer1/isic/i4b_isic.h index 8ee9868..2cee7aa 100644 --- a/sys/i4b/layer1/i4b_l1.h +++ b/sys/i4b/layer1/isic/i4b_isic.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved. + * Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,16 +27,16 @@ * i4b_l1.h - isdn4bsd layer 1 header file * --------------------------------------- * - * $Id: i4b_l1.h,v 1.3 1999/12/13 21:25:26 hm Exp $ + * $Id: i4b_isic.h,v 1.4 2000/09/04 09:17:26 hm Exp $ * * $FreeBSD$ * - * last edit-date: [Mon Dec 13 22:02:07 1999] + * last edit-date: [Mon Sep 4 09:34:38 2000] * *---------------------------------------------------------------------------*/ -#ifndef I4B_L1_H_ -#define I4B_L1_H_ +#ifndef _I4B_ISIC_H_ +#define _I4B_ISIC_H_ #include <sys/resource.h> #include <sys/bus.h> @@ -46,6 +46,16 @@ #include <i4b/include/i4b_l3l4.h> +#include <i4b/layer1/isic/i4b_isic_ext.h> + +/*--------------------------------------------------------------------------- + * isic driver: max no of units + * Teles/Creatix/Neuhaus cards have a hardware limitation + * as one is able to set 3 (sometimes 4) different configurations by + * jumpers so a maximum of 3 (4) cards per ISA bus is possible. + *---------------------------------------------------------------------------*/ + #define ISIC_MAXUNIT 3 /* max no of supported units 0..3 */ + /*--------------------------------------------------------------------------- * kernel config file flags definition *---------------------------------------------------------------------------*/ @@ -127,8 +137,8 @@ typedef struct /* link between b channel and driver */ - isdn_link_t isdn_linktab; /* b channel addresses */ - drvr_link_t *drvr_linktab; /* ptr to driver linktab*/ + isdn_link_t isic_isdn_linktab; /* b channel addresses */ + drvr_link_t *isic_drvr_linktab; /* ptr to driver linktab*/ /* statistics */ @@ -204,7 +214,8 @@ struct l1_softc int sc_isac_version; /* version number of ISAC */ int sc_hscx_version; /* version number of HSCX */ - + int sc_ipac_version; /* version number of IPAC */ + int sc_I430state; /* I.430 state F3 .... F8 */ int sc_I430T3; /* I.430 Timer T3 running */ @@ -297,7 +308,6 @@ enum I430commands { #define N_COMMANDS CMD_ILL - extern struct l1_softc l1_sc[]; extern void isicintr(struct l1_softc *sc); @@ -336,12 +346,18 @@ extern int isic_attach_s0163 (device_t dev); extern int isic_probe_avma1 (device_t dev); extern int isic_attach_avma1 (device_t dev); +extern int isic_probe_usrtai (device_t dev); +extern int isic_attach_usrtai (device_t dev); + +extern int isic_probe_itkix1 (device_t dev); +extern int isic_attach_itkix1 (device_t dev); + extern int isic_attach_drnngo (device_t dev); extern int isic_attach_Cs0P (device_t dev); extern int isic_attach_Eqs1pi(device_t dev); extern int isic_attach_sws(device_t dev); extern int isic_attach_siemens_isurf(device_t dev); extern int isic_attach_asi(device_t dev); +extern int isic_attach_Dyn(device_t dev); - -#endif /* I4B_L1_H_ */ +#endif /* _I4B_ISIC_H_ */ diff --git a/sys/i4b/layer1/isic/i4b_isic_ext.h b/sys/i4b/layer1/isic/i4b_isic_ext.h new file mode 100644 index 0000000..1e40058 --- /dev/null +++ b/sys/i4b/layer1/isic/i4b_isic_ext.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 1997, 2000 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_l1.h - isdn4bsd layer 1 header file + * --------------------------------------- + * + * $Id: i4b_isic_ext.h,v 1.3 2000/06/02 16:14:36 hm Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Fri Jun 2 14:43:57 2000] + * + *---------------------------------------------------------------------------*/ + +#ifndef _I4B_ISIC_EXT_H_ +#define _I4B_ISIC_EXT_H_ + +#include <i4b/include/i4b_l3l4.h> + +int isic_ph_data_req(int unit, struct mbuf *m, int freeflag); +int isic_ph_activate_req(int unit); +int isic_mph_command_req(int unit, int command, void *parm); + +void isic_set_linktab(int unit, int channel, drvr_link_t *dlt); +isdn_link_t *isic_ret_linktab(int unit, int channel); + +#endif /* _I4B_ISIC_H_ */ diff --git a/sys/i4b/layer1/i4b_isic_isa.c b/sys/i4b/layer1/isic/i4b_isic_isa.c index 6228fa1..40b05bd 100644 --- a/sys/i4b/layer1/i4b_isic_isa.c +++ b/sys/i4b/layer1/isic/i4b_isic_isa.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved. + * Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,11 +27,11 @@ * i4b_isic_isa.c - ISA bus interface * ================================== * - * $Id: i4b_isic_isa.c,v 1.4 1999/12/13 21:25:26 hm Exp $ + * $Id: i4b_isic_isa.c,v 1.3 2000/05/29 15:41:41 hm Exp $ * * $FreeBSD$ * - * last edit-date: [Mon Dec 13 22:01:39 1999] + * last edit-date: [Mon May 29 16:45:34 2000] * *---------------------------------------------------------------------------*/ @@ -53,12 +53,12 @@ #include <machine/i4b_ioctl.h> #include <machine/i4b_trace.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> +#include <i4b/layer1/isic/i4b_isic.h> +#include <i4b/layer1/isic/i4b_ipac.h> +#include <i4b/layer1/isic/i4b_isac.h> +#include <i4b/layer1/isic/i4b_hscx.h> -#include <i4b/include/i4b_l1l2.h> +/* #include <i4b/include/i4b_l1l2.h> */ #include <i4b/include/i4b_mbuf.h> #include <i4b/include/i4b_global.h> diff --git a/sys/i4b/layer1/i4b_isic_pnp.c b/sys/i4b/layer1/isic/i4b_isic_pnp.c index 70d0812..3fe6595 100644 --- a/sys/i4b/layer1/i4b_isic_pnp.c +++ b/sys/i4b/layer1/isic/i4b_isic_pnp.c @@ -3,7 +3,7 @@ * * Copyright (c) 1998, 1999 German Tischler. All rights reserved. * - * Copyright (c) 1998, 1999 Hellmuth Michaelis. All rights reserved. + * Copyright (c) 1998, 2000 Hellmuth Michaelis. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -37,11 +37,11 @@ * i4b_isic_pnp.c - i4b pnp support * -------------------------------- * - * $Id: i4b_isic_pnp.c,v 1.5 1999/12/13 21:25:26 hm Exp $ + * $Id: i4b_isic_pnp.c,v 1.2 2000/03/09 16:12:51 hm Exp $ * * $FreeBSD$ * - * last edit-date: [Mon Dec 13 22:01:48 1999] + * last edit-date: [Thu Mar 9 16:04:10 2000] * *---------------------------------------------------------------------------*/ @@ -60,7 +60,7 @@ #include <i4b/include/i4b_global.h> #include <machine/i4b_ioctl.h> -#include <i4b/layer1/i4b_l1.h> +#include <i4b/layer1/isic/i4b_isic.h> #include <isa/isavar.h> diff --git a/sys/i4b/layer1/i4b_itk_ix1.c b/sys/i4b/layer1/isic/i4b_itk_ix1.c index 9ec4cf3..9bf94c5 100644 --- a/sys/i4b/layer1/i4b_itk_ix1.c +++ b/sys/i4b/layer1/isic/i4b_itk_ix1.c @@ -26,13 +26,11 @@ * i4b_itk_ix1.c - ITK ix1 micro passive card driver for isdn4bsd * -------------------------------------------------------------- * - * $FreeBSD$ + * $Id: i4b_itk_ix1.c,v 1.1 2000/08/24 14:08:41 hm Exp $ * - * last edit-date: [Sun Feb 14 10:28:00 1999] + * last edit-date: [Thu Aug 24 15:44:33 2000] * - * mh - created - * mh - fixed FreeBSD problems reported by Kevin Sheehan - * mh - added probe routine + * $FreeBSD$ * *--------------------------------------------------------------------------- * @@ -64,48 +62,30 @@ * *---------------------------------------------------------------------------*/ -#if defined(__FreeBSD__) #include "isic.h" #include "opt_i4b.h" -#else -#define NISIC 1 -#endif + #if NISIC > 0 && defined(ITKIX1) #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 <sys/socket.h> -#ifdef __FreeBSD__ #include <machine/clock.h> -#include <i386/isa/isa_device.h> -#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 <i4b/i4b_debug.h> -#include <i4b/i4b_ioctl.h> -#endif -#include <i4b/layer1/i4b_l1.h> -#include <i4b/layer1/i4b_isac.h> -#include <i4b/layer1/i4b_hscx.h> +#include <i4b/layer1/isic/i4b_isic.h> +#include <i4b/layer1/isic/i4b_isac.h> +#include <i4b/layer1/isic/i4b_hscx.h> #include <i4b/include/i4b_global.h> +#include <i4b/include/i4b_mbuf.h> /* Register offsets */ #define ITK_ISAC_DATA 0 @@ -120,72 +100,208 @@ #define HSCXA 0 #define HSCXB 0x40 -/* - * Local function prototypes - */ -#ifdef __FreeBSD__ -/* FreeBSD version */ -static void itkix1_read_fifo(void *buf, const void *base, size_t len); -static void itkix1_write_fifo(void *base, const void *buf, size_t len); -static void itkix1_write_reg(u_char *base, u_int offset, u_int v); -static u_char itkix1_read_reg(u_char *base, u_int offset); -#else -/* NetBSD/OpenBSD version */ -static void itkix1_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size); -static void itkix1_write_fifo(struct isic_softc *sc, int what, const void *buf, size_t size); -static void itkix1_write_reg(struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data); -static u_int8_t itkix1_read_reg(struct isic_softc *sc, int what, bus_size_t offs); -#endif +static void +itkix1_read_fifo(struct l1_softc *sc, int what, void *buf, size_t size) +{ + bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[0]); + bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]); + switch (what) + { + case ISIC_WHAT_ISAC: + bus_space_write_1(t, h, ITK_ALE, 0); + bus_space_read_multi_1(t, h, ITK_ISAC_DATA, buf, size); + break; + case ISIC_WHAT_HSCXA: + bus_space_write_1(t, h, ITK_ALE, HSCXA); + bus_space_read_multi_1(t, h, ITK_HSCX_DATA, buf, size); + break; + case ISIC_WHAT_HSCXB: + bus_space_write_1(t, h, ITK_ALE, HSCXB); + bus_space_read_multi_1(t, h, ITK_HSCX_DATA, buf, size); + break; + } +} + +static void +itkix1_write_fifo(struct l1_softc *sc, int what, void *buf, size_t size) +{ + bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[0]); + bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]); + switch (what) + { + case ISIC_WHAT_ISAC: + bus_space_write_1(t, h, ITK_ALE, 0); + bus_space_write_multi_1(t, h, ITK_ISAC_DATA, (u_int8_t*)buf, size); + break; + case ISIC_WHAT_HSCXA: + bus_space_write_1(t, h, ITK_ALE, HSCXA); + bus_space_write_multi_1(t, h, ITK_HSCX_DATA, (u_int8_t*)buf, size); + break; + case ISIC_WHAT_HSCXB: + bus_space_write_1(t, h, ITK_ALE, HSCXB); + bus_space_write_multi_1(t, h, ITK_HSCX_DATA, (u_int8_t*)buf, size); + break; + } +} + +static void +itkix1_write_reg(struct l1_softc *sc, int what, bus_size_t offs, u_int8_t data) +{ + bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[0]); + bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]); + switch (what) + { + case ISIC_WHAT_ISAC: + bus_space_write_1(t, h, ITK_ALE, offs); + bus_space_write_1(t, h, ITK_ISAC_DATA, data); + break; + case ISIC_WHAT_HSCXA: + bus_space_write_1(t, h, ITK_ALE, HSCXA+offs); + bus_space_write_1(t, h, ITK_HSCX_DATA, data); + break; + case ISIC_WHAT_HSCXB: + bus_space_write_1(t, h, ITK_ALE, HSCXB+offs); + bus_space_write_1(t, h, ITK_HSCX_DATA, data); + break; + } +} + +static u_int8_t +itkix1_read_reg(struct l1_softc *sc, int what, bus_size_t offs) +{ + bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[0]); + bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]); + switch (what) + { + case ISIC_WHAT_ISAC: + bus_space_write_1(t, h, ITK_ALE, offs); + return bus_space_read_1(t, h, ITK_ISAC_DATA); + case ISIC_WHAT_HSCXA: + bus_space_write_1(t, h, ITK_ALE, HSCXA+offs); + return bus_space_read_1(t, h, ITK_HSCX_DATA); + case ISIC_WHAT_HSCXB: + bus_space_write_1(t, h, ITK_ALE, HSCXB+offs); + return bus_space_read_1(t, h, ITK_HSCX_DATA); + } + return 0; +} /* * Probe for card */ -#ifdef __FreeBSD__ int -isic_probe_itkix1(struct isa_device *dev) -{ +isic_probe_itkix1(device_t dev) +{ + size_t unit = device_get_unit(dev); /* get unit */ + struct l1_softc *sc = 0; /* softc */ + void *ih = 0; /* dummy */ + bus_space_tag_t t; /* bus things */ + bus_space_handle_t h; u_int8_t hd, hv1, hv2, saveale; int ret; - /* save old value of this port, we're stomping over it */ - saveale = inb(dev->id_iobase + ITK_ALE); + #if defined(ITK_PROBE_DEBUG) + printf("Checking unit %u\n", unit); + #endif - /* select invalid register */ - outb(dev->id_iobase + ITK_ALE, 0xff); - /* get HSCX data for this non existent register */ - hd = inb(dev->id_iobase + ITK_HSCX_DATA); - /* get HSCX version info */ - outb(dev->id_iobase + ITK_ALE, HSCXA + H_VSTR); - hv1 = inb(dev->id_iobase + ITK_HSCX_DATA); - outb(dev->id_iobase + ITK_ALE, HSCXB + H_VSTR); - hv2 = inb(dev->id_iobase + ITK_HSCX_DATA); + /* check max unit range */ + if(unit >= ISIC_MAXUNIT) + { + printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for ITK IX1!\n", + unit, unit); + return ENXIO; + } - /* succeed if version bits are OK and we got a zero from the - * non existent register */ - ret = (hd == 0) && ((hv1 & 0x0f) == 0x05) && ((hv2 & 0x0f) == 0x05); + sc = &l1_sc[unit]; /* get pointer to softc */ + sc->sc_unit = unit; /* set unit */ + sc->sc_flags = FLAG_ITK_IX1; /* set flags */ + + #if defined(ITK_PROBE_DEBUG) + printf("Allocating io base..."); + #endif + + if(!(sc->sc_resources.io_base[0] = + bus_alloc_resource(dev, SYS_RES_IOPORT, + &sc->sc_resources.io_rid[0], + 0ul, ~0ul, 1, RF_ACTIVE))) + { + printf("isic%d: Could not allocate i/o port for ITK IX1.\n", unit); + return ENXIO; + } - /* retstore save value if we fail (if we succeed the old value - * has no meaning) */ - if (!ret) - outb(dev->id_iobase + ITK_ALE, saveale); + #if defined(ITK_PROBE_DEBUG) + printf("done.\n"); + #endif -#ifdef ITK_PROBE_DEBUG - printf("\nITK ix1 micro probe: hscx = 0x%02x, v1 = 0x%02x, v2 = 0x%02x, would have %s\n", - hd, hv1, hv2, ret ? "succeeded" : "failed"); - return 1; -#else - return ret; -#endif -} -#else -int -isic_probe_itkix1(struct isic_attach_args *ia) -{ - bus_space_tag_t t = ia->ia_maps[0].t; - bus_space_handle_t h = ia->ia_maps[0].h; - u_int8_t hd, hv1, hv2, saveale; - int ret; + sc->sc_port = rman_get_start(sc->sc_resources.io_base[0]); + t = rman_get_bustag(sc->sc_resources.io_base[0]); + h = rman_get_bushandle(sc->sc_resources.io_base[0]); + + #if defined(ITK_PROBE_DEBUG) + printf("Allocating irq..."); + #endif + + /* get our irq */ + if(!(sc->sc_resources.irq = + bus_alloc_resource(dev, SYS_RES_IRQ, + &sc->sc_resources.irq_rid, + 0ul, ~0ul, 1, RF_ACTIVE))) + { + printf("isic%d: Could not allocate irq for ITK IX1.\n", unit); + bus_release_resource(dev,SYS_RES_IOPORT, + sc->sc_resources.io_rid[0], + sc->sc_resources.io_base[0]); + return ENXIO; + } + + #if defined(ITK_PROBE_DEBUG) + printf("done.\n"); + #endif + + /* get the irq number */ + sc->sc_irq = rman_get_start(sc->sc_resources.irq); + + #if defined(ITK_PROBE_DEBUG) + printf("Setting up access routines..."); + #endif + + /* setup access routines */ + sc->clearirq = NULL; + sc->readreg = itkix1_read_reg; + sc->writereg = itkix1_write_reg; + sc->readfifo = itkix1_read_fifo; + sc->writefifo = itkix1_write_fifo; + + /* setup card type */ + sc->sc_cardtyp = CARD_TYPEP_ITKIX1; + + /* setup IOM bus type */ + sc->sc_bustyp = BUS_TYPE_IOM2; + + sc->sc_ipac = 0; + sc->sc_bfifolen = HSCX_FIFO_LEN; + + #if defined(ITK_PROBE_DEBUG) + printf("done.\n"); + #endif + + /* register interupt routine */ + + #if defined(ITK_PROBE_DEBUG) + printf("Setting up access interupt..."); + #endif + + bus_setup_intr(dev, sc->sc_resources.irq, + INTR_TYPE_NET, + (void(*)(void *))(isicintr), + sc, &ih); + #if defined(ITK_PROBE_DEBUG) + printf("done.\n"); + + printf("Doing probe stuff..."); + #endif + /* save old value of this port, we're stomping over it */ saveale = bus_space_read_1(t, h, ITK_ALE); @@ -199,40 +315,72 @@ isic_probe_itkix1(struct isic_attach_args *ia) bus_space_write_1(t, h, ITK_ALE, HSCXB + H_VSTR); hv2 = bus_space_read_1(t, h, ITK_HSCX_DATA); - /* succeed if version bits are OK and we got a zero from the - * non existent register */ ret = (hd == 0) && ((hv1 & 0x0f) == 0x05) && ((hv2 & 0x0f) == 0x05); + /* succeed if version bits are OK and we got a zero from the + * non existent register. we found verison 0x05 and 0x04 + * out there... */ + ret = (hd == 0) + && (((hv1 & 0x0f) == 0x05) || ((hv1 & 0x0f) == 0x04)) + && (((hv2 & 0x0f) == 0x05) || ((hv2 & 0x0f) == 0x04)); /* retstore save value if we fail (if we succeed the old value * has no meaning) */ if (!ret) bus_space_write_1(t, h, ITK_ALE, saveale); -#ifdef ITK_PROBE_DEBUG + #if defined(ITK_PROBE_DEBUG) + printf("done.\n"); + + printf("Doing second probe stuff..."); + #endif + + hv1 = HSCX_READ(0, H_VSTR) & 0xf; + hv2 = HSCX_READ(1, H_VSTR) & 0xf; + /* Read HSCX A/B VSTR. Expected value is 0x05 (V2.1) or 0x04 (V2.0). */ + if((hv1 != 0x05 && hv1 != 0x04) || (hv2 != 0x05 && hv2 != 0x04)) + { + printf("isic%d: HSCX VSTR test failed for ITK ix1 micro\n", + unit); + printf("isic%d: HSC0: VSTR: %#x\n", + unit, HSCX_READ(0, H_VSTR)); + printf("isic%d: HSC1: VSTR: %#x\n", + unit, HSCX_READ(1, H_VSTR)); + isic_detach_common(dev); + return ENXIO; + } + + #if defined(ITK_PROBE_DEBUG) + printf("done.\n"); + #endif + +#if defined(ITK_PROBE_DEBUG) printf("\nITK ix1 micro probe: hscx = 0x%02x, v1 = 0x%02x, v2 = 0x%02x, would have %s\n", hd, hv1, hv2, ret ? "succeeded" : "failed"); - return 1; + isic_detach_common(dev); + return ENXIO; #else - return ret; + if ( ret ) + { + return 0; + } + else + { + isic_detach_common(dev); + return ENXIO; + } #endif } -#endif /* * Attach card */ -#ifdef __FreeBSD__ int -isic_attach_itkix1(struct isa_device *dev) +isic_attach_itkix1(device_t dev) { - struct isic_softc *sc = &isic_sc[dev->id_unit]; - - sc->sc_irq = dev->id_irq; - - dev->id_msize = 0; - - /* check if we got an iobase */ - sc->sc_port = dev->id_iobase; + size_t unit = device_get_unit(dev); /* get unit */ + struct l1_softc *sc = &l1_sc[unit]; + bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[0]); + bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]); /* setup access routines */ sc->clearirq = NULL; @@ -250,233 +398,12 @@ isic_attach_itkix1(struct isa_device *dev) 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 + 2; - - /* 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 ITK ix1 micro\n", - dev->id_unit); - printf("isic%d: HSC0: VSTR: %#x\n", - dev->id_unit, HSCX_READ(0, H_VSTR)); - printf("isic%d: HSC1: VSTR: %#x\n", - dev->id_unit, HSCX_READ(1, H_VSTR)); - return (0); - } - - outb((dev->id_iobase)+ITK_CONFIG, 1); + bus_space_write_1(t, h, ITK_CONFIG, 1); DELAY(SEC_DELAY / 10); - outb((dev->id_iobase)+ITK_CONFIG, 0); + bus_space_write_1(t, h, ITK_CONFIG, 0); DELAY(SEC_DELAY / 10); - return(1); -} - -#else - -int isic_attach_itkix1(struct isic_softc *sc) -{ - /* setup access routines */ - sc->clearirq = NULL; - sc->readreg = itkix1_read_reg; - sc->writereg = itkix1_write_reg; - sc->readfifo = itkix1_read_fifo; - sc->writefifo = itkix1_write_fifo; - - /* setup card type */ - sc->sc_cardtyp = CARD_TYPEP_ITKIX1; - - /* setup IOM bus type */ - sc->sc_bustyp = BUS_TYPE_IOM2; - - sc->sc_ipac = 0; - sc->sc_bfifolen = HSCX_FIFO_LEN; - - /* 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("%s: HSCX VSTR test failed for ITK ix1 micro\n", - sc->sc_dev.dv_xname); - printf("%s: HSC0: VSTR: %#x\n", - sc->sc_dev.dv_xname, HSCX_READ(0, H_VSTR)); - printf("%s: HSC1: VSTR: %#x\n", - sc->sc_dev.dv_xname, HSCX_READ(1, H_VSTR)); - return 0; - } - - bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, ITK_CONFIG, 1); - DELAY(SEC_DELAY / 10); - bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, ITK_CONFIG, 0); - DELAY(SEC_DELAY / 10); - return 1; -} - -#endif - -#ifdef __FreeBSD__ -static void -itkix1_read_fifo(void *buf, const void *base, size_t len) -{ - u_int port = (u_int)base & ~0x0003; - switch ((u_int)base & 3) { - case 0: /* ISAC */ - outb(port+ITK_ALE, 0); - insb(port+ITK_ISAC_DATA, (u_char *)buf, (u_int)len); - break; - case 1: /* HSCXA */ - outb(port+ITK_ALE, HSCXA); - insb(port+ITK_HSCX_DATA, (u_char *)buf, (u_int)len); - break; - case 2: /* HSCXB */ - outb(port+ITK_ALE, HSCXB); - insb(port+ITK_HSCX_DATA, (u_char *)buf, (u_int)len); - break; - } -} -#else -static void -itkix1_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size) -{ - bus_space_tag_t t = sc->sc_maps[0].t; - bus_space_handle_t h = sc->sc_maps[0].h; - switch (what) { - case ISIC_WHAT_ISAC: - bus_space_write_1(t, h, ITK_ALE, 0); - bus_space_read_multi_1(t, h, ITK_ISAC_DATA, buf, size); - break; - case ISIC_WHAT_HSCXA: - bus_space_write_1(t, h, ITK_ALE, HSCXA); - bus_space_read_multi_1(t, h, ITK_HSCX_DATA, buf, size); - break; - case ISIC_WHAT_HSCXB: - bus_space_write_1(t, h, ITK_ALE, HSCXB); - bus_space_read_multi_1(t, h, ITK_HSCX_DATA, buf, size); - break; - } -} -#endif -#ifdef __FreeBSD__ -static void -itkix1_write_fifo(void *base, const void *buf, size_t len) -{ - u_int port = (u_int)base & ~0x0003; - switch ((u_int)base & 3) { - case 0: /* ISAC */ - outb(port+ITK_ALE, 0); - outsb(port+ITK_ISAC_DATA, (u_char *)buf, (u_int)len); - break; - case 1: /* HSCXA */ - outb(port+ITK_ALE, HSCXA); - outsb(port+ITK_HSCX_DATA, (u_char *)buf, (u_int)len); - break; - case 2: /* HSCXB */ - outb(port+ITK_ALE, HSCXB); - outsb(port+ITK_HSCX_DATA, (u_char *)buf, (u_int)len); - break; - } -} -#else -static void itkix1_write_fifo(struct isic_softc *sc, int what, const void *buf, size_t size) -{ - bus_space_tag_t t = sc->sc_maps[0].t; - bus_space_handle_t h = sc->sc_maps[0].h; - switch (what) { - case ISIC_WHAT_ISAC: - bus_space_write_1(t, h, ITK_ALE, 0); - bus_space_write_multi_1(t, h, ITK_ISAC_DATA, (u_int8_t*)buf, size); - break; - case ISIC_WHAT_HSCXA: - bus_space_write_1(t, h, ITK_ALE, HSCXA); - bus_space_write_multi_1(t, h, ITK_HSCX_DATA, (u_int8_t*)buf, size); - break; - case ISIC_WHAT_HSCXB: - bus_space_write_1(t, h, ITK_ALE, HSCXB); - bus_space_write_multi_1(t, h, ITK_HSCX_DATA, (u_int8_t*)buf, size); - break; - } -} -#endif - -#ifdef __FreeBSD__ -static void -itkix1_write_reg(u_char *base, u_int offset, u_int v) -{ - u_int port = (u_int)base & ~0x0003; - switch ((u_int)base & 3) { - case 0: /* ISAC */ - outb(port+ITK_ALE, offset); - outb(port+ITK_ISAC_DATA, (u_char)v); - break; - case 1: /* HSCXA */ - outb(port+ITK_ALE, HSCXA+offset); - outb(port+ITK_HSCX_DATA, (u_char)v); - break; - case 2: /* HSCXB */ - outb(port+ITK_ALE, HSCXB+offset); - outb(port+ITK_HSCX_DATA, (u_char)v); - break; - } -} -#else -static void itkix1_write_reg(struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data) -{ - bus_space_tag_t t = sc->sc_maps[0].t; - bus_space_handle_t h = sc->sc_maps[0].h; - switch (what) { - case ISIC_WHAT_ISAC: - bus_space_write_1(t, h, ITK_ALE, offs); - bus_space_write_1(t, h, ITK_ISAC_DATA, data); - break; - case ISIC_WHAT_HSCXA: - bus_space_write_1(t, h, ITK_ALE, HSCXA+offs); - bus_space_write_1(t, h, ITK_HSCX_DATA, data); - break; - case ISIC_WHAT_HSCXB: - bus_space_write_1(t, h, ITK_ALE, HSCXB+offs); - bus_space_write_1(t, h, ITK_HSCX_DATA, data); - break; - } -} -#endif - -#ifdef __FreeBSD__ -static u_char -itkix1_read_reg(u_char *base, u_int offset) -{ - u_int port = (u_int)base & ~0x0003; - switch ((u_int)base & 3) { - case 0: /* ISAC */ - outb(port+ITK_ALE, offset); - return (inb(port+ITK_ISAC_DATA)); - case 1: /* HSCXA */ - outb(port+ITK_ALE, HSCXA+offset); - return (inb(port+ITK_HSCX_DATA)); - case 2: /* HSCXB */ - outb(port+ITK_ALE, HSCXB+offset); - return (inb(port+ITK_HSCX_DATA)); - } -} -#else -static u_int8_t itkix1_read_reg(struct isic_softc *sc, int what, bus_size_t offs) -{ - bus_space_tag_t t = sc->sc_maps[0].t; - bus_space_handle_t h = sc->sc_maps[0].h; - switch (what) { - case ISIC_WHAT_ISAC: - bus_space_write_1(t, h, ITK_ALE, offs); - return bus_space_read_1(t, h, ITK_ISAC_DATA); - case ISIC_WHAT_HSCXA: - bus_space_write_1(t, h, ITK_ALE, HSCXA+offs); - return bus_space_read_1(t, h, ITK_HSCX_DATA); - case ISIC_WHAT_HSCXB: - bus_space_write_1(t, h, ITK_ALE, HSCXB+offs); - return bus_space_read_1(t, h, ITK_HSCX_DATA); - } return 0; } -#endif #endif /* ITKIX1 */ diff --git a/sys/i4b/layer1/i4b_l1.c b/sys/i4b/layer1/isic/i4b_l1.c index 617f58c..f19eda8 100644 --- a/sys/i4b/layer1/i4b_l1.c +++ b/sys/i4b/layer1/isic/i4b_l1.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved. + * Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,11 +27,11 @@ * i4b_l1.c - isdn4bsd layer 1 handler * ----------------------------------- * - * $Id: i4b_l1.c,v 1.2 1999/12/13 21:25:26 hm Exp $ + * $Id: i4b_l1.c,v 1.7 2000/06/02 16:14:36 hm Exp $ * * $FreeBSD$ * - * last edit-date: [Mon Dec 13 22:01:55 1999] + * last edit-date: [Fri Jun 2 18:09:53 2000] * *---------------------------------------------------------------------------*/ @@ -40,6 +40,7 @@ #if NISIC > 0 #include <sys/param.h> +#include <sys/kernel.h> #include <sys/systm.h> #include <sys/mbuf.h> #include <sys/socket.h> @@ -53,56 +54,15 @@ #include <machine/i4b_ioctl.h> #include <machine/i4b_trace.h> +#include <i4b/layer1/isic/i4b_isic.h> +#include <i4b/layer1/isic/i4b_isac.h> +#include <i4b/layer1/isic/i4b_hscx.h> + #include <i4b/layer1/i4b_l1.h> -#include <i4b/layer1/i4b_isac.h> -#include <i4b/layer1/i4b_hscx.h> -#include <i4b/include/i4b_l1l2.h> #include <i4b/include/i4b_mbuf.h> #include <i4b/include/i4b_global.h> -unsigned int i4b_l1_debug = L1_DEBUG_DEFAULT; - -static int ph_data_req(int, struct mbuf *, int); -static int ph_activate_req(int); - -/* from i4btrc driver i4b_trace.c */ -extern int get_trace_data_from_l1(int unit, int what, int len, char *buf); - -/* from layer 2 */ -extern int i4b_ph_data_ind(int unit, struct mbuf *m); -extern int i4b_ph_activate_ind(int unit); -extern int i4b_ph_deactivate_ind(int unit); -extern int i4b_mph_attach_ind(int unit); -extern int i4b_mph_status_ind(int, int, int); - -/* layer 1 lme */ -static int i4b_mph_command_req(int, int, int); - -/* jump table */ -struct i4b_l1l2_func i4b_l1l2_func = { - - /* Layer 1 --> Layer 2 */ - - (int (*)(int, struct mbuf *)) i4b_ph_data_ind, - (int (*)(int)) i4b_ph_activate_ind, - (int (*)(int)) i4b_ph_deactivate_ind, - - /* Layer 2 --> Layer 1 */ - - (int (*)(int, struct mbuf *, int)) ph_data_req, - (int (*)(int)) ph_activate_req, - - /* Layer 1 --> upstream, ISDN trace data */ - - (int (*)(i4b_trace_hdr_t *, int, u_char *)) get_trace_data_from_l1, - - /* Driver control and status information */ - - (int (*)(int, int, int)) i4b_mph_status_ind, - (int (*)(int, int, int)) i4b_mph_command_req, -}; - /*---------------------------------------------------------------------------* * * L2 -> L1: PH-DATA-REQUEST @@ -119,15 +79,15 @@ struct i4b_l1l2_func i4b_l1l2_func = { * !=0 ok, frame sent out * *---------------------------------------------------------------------------*/ -static int -ph_data_req(int unit, struct mbuf *m, int freeflag) +int +isic_ph_data_req(int unit, struct mbuf *m, int freeflag) { u_char cmd; int s; struct l1_softc *sc = &l1_sc[unit]; #ifdef NOTDEF - DBGL1(L1_PRIM, "PH-DATA-REQ", ("unit %d, freeflag=%d\n", unit, freeflag)); + NDBGL1(L1_PRIM, "unit %d, freeflag=%d", unit, freeflag); #endif if(m == NULL) /* failsafe */ @@ -137,8 +97,8 @@ ph_data_req(int unit, struct mbuf *m, int freeflag) if(sc->sc_I430state == ST_F3) /* layer 1 not running ? */ { - DBGL1(L1_I_ERR, "ph_data_req", ("still in state F3!\n")); - ph_activate_req(unit); + NDBGL1(L1_I_ERR, "still in state F3!"); + isic_ph_activate_req(unit); } if(sc->sc_state & ISAC_TX_ACTIVE) @@ -152,23 +112,23 @@ ph_data_req(int unit, struct mbuf *m, int freeflag) else sc->sc_freeflag2 = 0; /* IRQ must not mfree */ - DBGL1(L1_I_MSG, "ph_data_req", ("using 2nd ISAC TX buffer, state = %s\n", isic_printstate(sc))); + NDBGL1(L1_I_MSG, "using 2nd ISAC TX buffer, state = %s", isic_printstate(sc)); if(sc->sc_trace & TRACE_D_TX) { i4b_trace_hdr_t hdr; - hdr.unit = unit; + hdr.unit = L0ISICUNIT(unit); hdr.type = TRC_CH_D; hdr.dir = FROM_TE; hdr.count = ++sc->sc_trace_dcount; MICROTIME(hdr.time); - MPH_Trace_Ind(&hdr, m->m_len, m->m_data); + i4b_l1_trace_ind(&hdr, m->m_len, m->m_data); } splx(s); return(1); } - DBGL1(L1_I_ERR, "ph_data_req", ("No Space in TX FIFO, state = %s\n", isic_printstate(sc))); + NDBGL1(L1_I_ERR, "No Space in TX FIFO, state = %s", isic_printstate(sc)); if(freeflag == MBUF_FREE) i4b_Dfreembuf(m); @@ -180,17 +140,17 @@ ph_data_req(int unit, struct mbuf *m, int freeflag) if(sc->sc_trace & TRACE_D_TX) { i4b_trace_hdr_t hdr; - hdr.unit = unit; + hdr.unit = L0ISICUNIT(unit); hdr.type = TRC_CH_D; hdr.dir = FROM_TE; hdr.count = ++sc->sc_trace_dcount; MICROTIME(hdr.time); - MPH_Trace_Ind(&hdr, m->m_len, m->m_data); + i4b_l1_trace_ind(&hdr, m->m_len, m->m_data); } sc->sc_state |= ISAC_TX_ACTIVE; /* set transmitter busy flag */ - DBGL1(L1_I_MSG, "ph_data_req", ("ISAC_TX_ACTIVE set\n")); + NDBGL1(L1_I_MSG, "ISAC_TX_ACTIVE set"); sc->sc_freeflag = 0; /* IRQ must NOT mfree */ @@ -240,11 +200,11 @@ ph_data_req(int unit, struct mbuf *m, int freeflag) * !=0 * *---------------------------------------------------------------------------*/ -static int -ph_activate_req(int unit) +int +isic_ph_activate_req(int unit) { struct l1_softc *sc = &l1_sc[unit]; - DBGL1(L1_PRIM, "PH-ACTIVATE-REQ", ("unit %d\n", unit)); + NDBGL1(L1_PRIM, "unit %d", unit); isic_next_state(sc, EV_PHAR); return(0); } @@ -252,25 +212,46 @@ ph_activate_req(int unit) /*---------------------------------------------------------------------------* * command from the upper layers *---------------------------------------------------------------------------*/ -static int -i4b_mph_command_req(int unit, int command, int parm) +int +isic_mph_command_req(int unit, int command, void *parm) { struct l1_softc *sc = &l1_sc[unit]; switch(command) { case CMR_DOPEN: /* daemon running */ - DBGL1(L1_PRIM, "MPH-COMMAND-REQ", ("unit %d, command = CMR_DOPEN\n", unit)); + NDBGL1(L1_PRIM, "unit %d, command = CMR_DOPEN", unit); sc->sc_enabled = 1; break; case CMR_DCLOSE: /* daemon not running */ - DBGL1(L1_PRIM, "MPH-COMMAND-REQ", ("unit %d, command = CMR_DCLOSE\n", unit)); + NDBGL1(L1_PRIM, "unit %d, command = CMR_DCLOSE", unit); sc->sc_enabled = 0; break; + case CMR_SETTRACE: + NDBGL1(L1_PRIM, "unit %d, command = CMR_SETTRACE, parm = %d", unit, (unsigned int)parm); + sc->sc_trace = (unsigned int)parm; + break; + + case CMR_GCST: + { + struct chipstat *cst; + NDBGL1(L1_PRIM, "unit %d, command = CMR_GCST, parm = %d", unit, (unsigned int)parm); + cst = (struct chipstat *)parm; + cst->driver_type = L1DRVR_ISIC; + cst->stats.hscxstat.unit = sc->sc_unit; + cst->stats.hscxstat.chan = cst->driver_bchannel; + cst->stats.hscxstat.vfr = sc->sc_chan[cst->driver_bchannel].stat_VFR; + cst->stats.hscxstat.rdo = sc->sc_chan[cst->driver_bchannel].stat_RDO; + cst->stats.hscxstat.crc = sc->sc_chan[cst->driver_bchannel].stat_CRC; + cst->stats.hscxstat.rab = sc->sc_chan[cst->driver_bchannel].stat_RAB; + cst->stats.hscxstat.xdu = sc->sc_chan[cst->driver_bchannel].stat_XDU; + cst->stats.hscxstat.rfo = sc->sc_chan[cst->driver_bchannel].stat_RFO; + break; + } default: - DBGL1(L1_ERROR, "i4b_mph_command_req", ("ERROR, unknown command = %d, unit = %d, parm = %d\n", command, unit, parm)); + NDBGL1(L1_ERROR, "ERROR, unknown command = %d, unit = %d, parm = %d", command, unit, (unsigned int)parm); break; } diff --git a/sys/i4b/layer1/i4b_l1fsm.c b/sys/i4b/layer1/isic/i4b_l1fsm.c index 2370ad4..d3ce147 100644 --- a/sys/i4b/layer1/i4b_l1fsm.c +++ b/sys/i4b/layer1/isic/i4b_l1fsm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved. + * Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,11 +27,11 @@ * i4b_l1fsm.c - isdn4bsd layer 1 I.430 state machine * -------------------------------------------------- * - * $Id: i4b_l1fsm.c,v 1.2 1999/12/13 21:25:26 hm Exp $ + * $Id: i4b_l1fsm.c,v 1.8 2000/05/29 15:41:41 hm Exp $ * * $FreeBSD$ * - * last edit-date: [Mon Dec 13 22:02:16 1999] + * last edit-date: [Mon May 29 16:46:03 2000] * *---------------------------------------------------------------------------*/ @@ -52,16 +52,19 @@ #include <machine/i4b_debug.h> #include <machine/i4b_ioctl.h> +#include <machine/i4b_trace.h> + +#include <i4b/layer1/isic/i4b_isic.h> +#include <i4b/layer1/isic/i4b_isac.h> +#include <i4b/layer1/isic/i4b_hscx.h> #include <i4b/layer1/i4b_l1.h> -#include <i4b/layer1/i4b_isac.h> -#include <i4b/layer1/i4b_hscx.h> #include <i4b/include/i4b_global.h> -#include <i4b/include/i4b_l1l2.h> -#include <i4b/include/i4b_mbuf.h> +#include <i4b/include/i4b_mbuf.h> +#if DO_I4B_DEBUG static char *state_text[N_STATES] = { "F3 Deactivated", "F4 Awaiting Signal", @@ -86,6 +89,7 @@ static char *event_text[N_EVENTS] = { "EV_EI Error Ind", "Illegal Event" }; +#endif /* Function prototypes */ @@ -113,7 +117,7 @@ timer3_expired(struct l1_softc *sc) { if(sc->sc_I430T3) { - DBGL1(L1_T_ERR, "timer3_expired", ("state = %s\n", isic_printstate(sc))); + NDBGL1(L1_T_ERR, "state = %s", isic_printstate(sc)); sc->sc_I430T3 = 0; /* XXX try some recovery here XXX */ @@ -144,14 +148,14 @@ timer3_expired(struct l1_softc *sc) splx(s); - MPH_Status_Ind(sc->sc_unit, STI_NOL1ACC, 0); + i4b_l1_mph_status_ind(L0ISICUNIT(sc->sc_unit), STI_NOL1ACC, 0, NULL); } isic_next_state(sc, EV_T3); } else { - DBGL1(L1_T_ERR, "timer3_expired", ("expired without starting it ....\n")); + NDBGL1(L1_T_ERR, "expired without starting it ...."); } } @@ -161,7 +165,7 @@ timer3_expired(struct l1_softc *sc) static void T3_start(struct l1_softc *sc) { - DBGL1(L1_T_MSG, "T3_start", ("state = %s\n", isic_printstate(sc))); + NDBGL1(L1_T_MSG, "state = %s", isic_printstate(sc)); sc->sc_I430T3 = 1; sc->sc_T3_callout = timeout((TIMEOUT_FUNC_T)timer3_expired,(struct l1_softc *)sc, 2*hz); } @@ -172,7 +176,7 @@ T3_start(struct l1_softc *sc) static void T3_stop(struct l1_softc *sc) { - DBGL1(L1_T_MSG, "T3_stop", ("state = %s\n", isic_printstate(sc))); + NDBGL1(L1_T_MSG, "state = %s", isic_printstate(sc)); sc->sc_init_tries = 0; /* init connect retry count */ @@ -189,9 +193,9 @@ T3_stop(struct l1_softc *sc) static void F_T3ex(struct l1_softc *sc) { - DBGL1(L1_F_MSG, "F_T3ex", ("FSM function F_T3ex executing\n")); + NDBGL1(L1_F_MSG, "FSM function F_T3ex executing"); if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S) - PH_Deact_Ind(sc->sc_unit); + i4b_l1_ph_deactivate_ind(L0ISICUNIT(sc->sc_unit)); } /*---------------------------------------------------------------------------* @@ -202,13 +206,13 @@ timer4_expired(struct l1_softc *sc) { if(sc->sc_I430T4) { - DBGL1(L1_T_MSG, "timer4_expired", ("state = %s\n", isic_printstate(sc))); + NDBGL1(L1_T_MSG, "state = %s", isic_printstate(sc)); sc->sc_I430T4 = 0; - MPH_Status_Ind(sc->sc_unit, STI_PDEACT, 0); + i4b_l1_mph_status_ind(L0ISICUNIT(sc->sc_unit), STI_PDEACT, 0, NULL); } else { - DBGL1(L1_T_ERR, "timer4_expired", ("expired without starting it ....\n")); + NDBGL1(L1_T_ERR, "expired without starting it ...."); } } @@ -218,7 +222,7 @@ timer4_expired(struct l1_softc *sc) static void T4_start(struct l1_softc *sc) { - DBGL1(L1_T_MSG, "T4_start", ("state = %s\n", isic_printstate(sc))); + NDBGL1(L1_T_MSG, "state = %s", isic_printstate(sc)); sc->sc_I430T4 = 1; sc->sc_T4_callout = timeout((TIMEOUT_FUNC_T)timer4_expired,(struct l1_softc *)sc, hz); } @@ -229,7 +233,7 @@ T4_start(struct l1_softc *sc) static void T4_stop(struct l1_softc *sc) { - DBGL1(L1_T_MSG, "T4_stop", ("state = %s\n", isic_printstate(sc))); + NDBGL1(L1_T_MSG, "state = %s", isic_printstate(sc)); if(sc->sc_I430T4) { @@ -246,10 +250,10 @@ F_AI8(struct l1_softc *sc) { T4_stop(sc); - DBGL1(L1_F_MSG, "F_AI8", ("FSM function F_AI8 executing\n")); + NDBGL1(L1_F_MSG, "FSM function F_AI8 executing"); if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S) - PH_Act_Ind(sc->sc_unit); + i4b_l1_ph_activate_ind(L0ISICUNIT(sc->sc_unit)); T3_stop(sc); @@ -258,12 +262,12 @@ F_AI8(struct l1_softc *sc) i4b_trace_hdr_t hdr; char info = INFO4_8; - hdr.unit = sc->sc_unit; + hdr.unit = L0ISICUNIT(sc->sc_unit); hdr.type = TRC_CH_I; hdr.dir = FROM_NT; hdr.count = 0; MICROTIME(hdr.time); - MPH_Trace_Ind(&hdr, 1, &info); + i4b_l1_trace_ind(&hdr, 1, &info); } } @@ -275,10 +279,10 @@ F_AI10(struct l1_softc *sc) { T4_stop(sc); - DBGL1(L1_F_MSG, "F_AI10", ("FSM function F_AI10 executing\n")); + NDBGL1(L1_F_MSG, "FSM function F_AI10 executing"); if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S) - PH_Act_Ind(sc->sc_unit); + i4b_l1_ph_activate_ind(L0ISICUNIT(sc->sc_unit)); T3_stop(sc); @@ -287,12 +291,12 @@ F_AI10(struct l1_softc *sc) i4b_trace_hdr_t hdr; char info = INFO4_10; - hdr.unit = sc->sc_unit; + hdr.unit = L0ISICUNIT(sc->sc_unit); hdr.type = TRC_CH_I; hdr.dir = FROM_NT; hdr.count = 0; MICROTIME(hdr.time); - MPH_Trace_Ind(&hdr, 1, &info); + i4b_l1_trace_ind(&hdr, 1, &info); } } @@ -302,19 +306,19 @@ F_AI10(struct l1_softc *sc) static void F_I01(struct l1_softc *sc) { - DBGL1(L1_F_MSG, "F_I01", ("FSM function F_I01 executing\n")); + NDBGL1(L1_F_MSG, "FSM function F_I01 executing"); if(sc->sc_trace & TRACE_I) { i4b_trace_hdr_t hdr; char info = INFO0; - hdr.unit = sc->sc_unit; + hdr.unit = L0ISICUNIT(sc->sc_unit); hdr.type = TRC_CH_I; hdr.dir = FROM_NT; hdr.count = 0; MICROTIME(hdr.time); - MPH_Trace_Ind(&hdr, 1, &info); + i4b_l1_trace_ind(&hdr, 1, &info); } } @@ -324,22 +328,22 @@ F_I01(struct l1_softc *sc) static void F_I02(struct l1_softc *sc) { - DBGL1(L1_F_MSG, "F_I02", ("FSM function F_I02 executing\n")); + NDBGL1(L1_F_MSG, "FSM function F_I02 executing"); if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S) - PH_Deact_Ind(sc->sc_unit); + i4b_l1_ph_deactivate_ind(L0ISICUNIT(sc->sc_unit)); if(sc->sc_trace & TRACE_I) { i4b_trace_hdr_t hdr; char info = INFO0; - hdr.unit = sc->sc_unit; + hdr.unit = L0ISICUNIT(sc->sc_unit); hdr.type = TRC_CH_I; hdr.dir = FROM_NT; hdr.count = 0; MICROTIME(hdr.time); - MPH_Trace_Ind(&hdr, 1, &info); + i4b_l1_trace_ind(&hdr, 1, &info); } } @@ -349,10 +353,10 @@ F_I02(struct l1_softc *sc) static void F_I03(struct l1_softc *sc) { - DBGL1(L1_F_MSG, "F_I03", ("FSM function F_I03 executing\n")); + NDBGL1(L1_F_MSG, "FSM function F_I03 executing"); if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S) - PH_Deact_Ind(sc->sc_unit); + i4b_l1_ph_deactivate_ind(L0ISICUNIT(sc->sc_unit)); T4_start(sc); @@ -361,12 +365,12 @@ F_I03(struct l1_softc *sc) i4b_trace_hdr_t hdr; char info = INFO0; - hdr.unit = sc->sc_unit; + hdr.unit = L0ISICUNIT(sc->sc_unit); hdr.type = TRC_CH_I; hdr.dir = FROM_NT; hdr.count = 0; MICROTIME(hdr.time); - MPH_Trace_Ind(&hdr, 1, &info); + i4b_l1_trace_ind(&hdr, 1, &info); } } @@ -376,19 +380,19 @@ F_I03(struct l1_softc *sc) static void F_AR(struct l1_softc *sc) { - DBGL1(L1_F_MSG, "F_AR", ("FSM function F_AR executing\n")); + NDBGL1(L1_F_MSG, "FSM function F_AR executing"); if(sc->sc_trace & TRACE_I) { i4b_trace_hdr_t hdr; char info = INFO1_8; - hdr.unit = sc->sc_unit; + hdr.unit = L0ISICUNIT(sc->sc_unit); hdr.type = TRC_CH_I; hdr.dir = FROM_TE; hdr.count = 0; MICROTIME(hdr.time); - MPH_Trace_Ind(&hdr, 1, &info); + i4b_l1_trace_ind(&hdr, 1, &info); } isic_isac_l1_cmd(sc, CMD_AR8); @@ -402,19 +406,19 @@ F_AR(struct l1_softc *sc) static void F_I2(struct l1_softc *sc) { - DBGL1(L1_F_MSG, "F_I2", ("FSM function F_I2 executing\n")); + NDBGL1(L1_F_MSG, "FSM function F_I2 executing"); if(sc->sc_trace & TRACE_I) { i4b_trace_hdr_t hdr; char info = INFO2; - hdr.unit = sc->sc_unit; + hdr.unit = L0ISICUNIT(sc->sc_unit); hdr.type = TRC_CH_I; hdr.dir = FROM_NT; hdr.count = 0; MICROTIME(hdr.time); - MPH_Trace_Ind(&hdr, 1, &info); + i4b_l1_trace_ind(&hdr, 1, &info); } } @@ -425,7 +429,7 @@ F_I2(struct l1_softc *sc) static void F_ill(struct l1_softc *sc) { - DBGL1(L1_F_ERR, "F_ill", ("FSM function F_ill executing\n")); + NDBGL1(L1_F_ERR, "FSM function F_ill executing"); } /*---------------------------------------------------------------------------* @@ -434,7 +438,7 @@ F_ill(struct l1_softc *sc) static void F_NULL(struct l1_softc *sc) { - DBGL1(L1_F_MSG, "F_NULL", ("FSM function F_NULL executing\n")); + NDBGL1(L1_F_MSG, "FSM function F_NULL executing"); } @@ -483,24 +487,25 @@ isic_next_state(struct l1_softc *sc, int event) if(newstate >= N_STATES) panic("i4b_l1fsm.c: newstate >= N_STATES\n"); - DBGL1(L1_F_MSG, "isic_next_state", ("FSM event [%s]: [%s => %s]\n", event_text[event], + NDBGL1(L1_F_MSG, "FSM event [%s]: [%s => %s]", event_text[event], state_text[currstate], - state_text[newstate])); + state_text[newstate]); (*isic_state_tab[event][currstate].func)(sc); if(newstate == ST_ILL) { newstate = ST_F3; - DBGL1(L1_F_ERR, "isic_next_state", ("FSM Illegal State ERROR, oldstate = %s, newstate = %s, event = %s!\n", + NDBGL1(L1_F_ERR, "FSM Illegal State ERROR, oldstate = %s, newstate = %s, event = %s!", state_text[currstate], state_text[newstate], - event_text[event])); + event_text[event]); } sc->sc_I430state = newstate; } +#if DO_I4B_DEBUG /*---------------------------------------------------------------------------* * return pointer to current state description *---------------------------------------------------------------------------*/ @@ -509,6 +514,7 @@ isic_printstate(struct l1_softc *sc) { return((char *) state_text[sc->sc_I430state]); } +#endif #endif /* NISIC > 0 */ diff --git a/sys/i4b/layer1/i4b_siemens_isurf.c b/sys/i4b/layer1/isic/i4b_siemens_isurf.c index 384e118..52a70ec 100644 --- a/sys/i4b/layer1/i4b_siemens_isurf.c +++ b/sys/i4b/layer1/isic/i4b_siemens_isurf.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Udo Schweigert. All rights reserved. + * Copyright (c) 1999, 2000 Udo Schweigert. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -37,11 +37,11 @@ * Siemens I-Surf 2.0 PnP specific routines for isic driver * -------------------------------------------------------- * - * $Id: i4b_siemens_isurf.c,v 1.2 1999/12/13 21:25:26 hm Exp $ + * $Id: i4b_siemens_isurf.c,v 1.3 2000/05/29 15:41:41 hm Exp $ * * $FreeBSD$ * - * last edit-date: [Mon Dec 13 22:02:28 1999] + * last edit-date: [Mon May 29 16:46:31 2000] * *---------------------------------------------------------------------------*/ @@ -51,6 +51,7 @@ #if NISIC > 0 && defined(SIEMENS_ISURF2) #include <sys/param.h> +#include <sys/kernel.h> #include <sys/systm.h> #include <sys/mbuf.h> #include <sys/socket.h> @@ -63,13 +64,13 @@ #include <machine/i4b_ioctl.h> #include <i4b/include/i4b_global.h> -#include <i4b/include/i4b_l1l2.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> +#include <i4b/layer1/isic/i4b_isic.h> +#include <i4b/layer1/isic/i4b_ipac.h> +#include <i4b/layer1/isic/i4b_isac.h> +#include <i4b/layer1/isic/i4b_hscx.h> /* masks for register encoded in base addr */ diff --git a/sys/i4b/layer1/i4b_sws.c b/sys/i4b/layer1/isic/i4b_sws.c index 9bc2015..4815001 100644 --- a/sys/i4b/layer1/i4b_sws.c +++ b/sys/i4b/layer1/isic/i4b_sws.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998 German Tischler. All rights reserved. + * Copyright (c) 1998, 2000 German Tischler. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -44,11 +44,11 @@ * isic - I4B Siemens ISDN Chipset Driver for SWS cards * ==================================================== * - * $Id: i4b_sws.c,v 1.2 1999/12/13 21:25:26 hm Exp $ + * $Id: i4b_sws.c,v 1.3 2000/05/29 15:41:41 hm Exp $ * * $FreeBSD$ * - * last edit-date: [Mon Dec 13 22:02:39 1999] + * last edit-date: [Mon May 29 16:46:49 2000] * *---------------------------------------------------------------------------*/ @@ -68,6 +68,7 @@ #define SWS_REGS 8 /* we use an area of 8 bytes for io */ #include <sys/param.h> +#include <sys/kernel.h> #include <sys/systm.h> #include <sys/mbuf.h> #include <sys/socket.h> @@ -79,12 +80,12 @@ #include <machine/i4b_debug.h> #include <machine/i4b_ioctl.h> -#include <i4b/layer1/i4b_l1.h> -#include <i4b/layer1/i4b_isac.h> -#include <i4b/layer1/i4b_hscx.h> +#include <i4b/layer1/isic/i4b_isic.h> +#include <i4b/layer1/isic/i4b_isac.h> +#include <i4b/layer1/isic/i4b_hscx.h> #include <i4b/include/i4b_global.h> -#include <i4b/include/i4b_l1l2.h> +/* #include <i4b/include/i4b_l1l2.h> */ #include <i4b/include/i4b_mbuf.h> /*---------------------------------------------------------------------------* diff --git a/sys/i4b/layer1/i4b_tel_s016.c b/sys/i4b/layer1/isic/i4b_tel_s016.c index 87f4dbb..8f4cebb 100644 --- a/sys/i4b/layer1/i4b_tel_s016.c +++ b/sys/i4b/layer1/isic/i4b_tel_s016.c @@ -3,7 +3,7 @@ * * Copyright (c) 1996 Gary Jennejohn. All rights reserved. * - * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved. + * Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -37,11 +37,11 @@ * isic - I4B Siemens ISDN Chipset Driver for Teles S0/16 and clones * ================================================================= * - * $Id: i4b_tel_s016.c,v 1.3 1999/12/13 21:25:26 hm Exp $ + * $Id: i4b_tel_s016.c,v 1.3 2000/05/29 15:41:41 hm Exp $ * * $FreeBSD$ * - * last edit-date: [Mon Dec 13 22:02:47 1999] + * last edit-date: [Mon May 29 16:46:56 2000] * *---------------------------------------------------------------------------*/ @@ -51,6 +51,7 @@ #if NISIC > 0 && defined(TEL_S0_16) #include <sys/param.h> +#include <sys/kernel.h> #include <sys/systm.h> #include <sys/mbuf.h> #include <sys/socket.h> @@ -63,12 +64,12 @@ #include <machine/i4b_debug.h> #include <machine/i4b_ioctl.h> -#include <i4b/layer1/i4b_l1.h> -#include <i4b/layer1/i4b_isac.h> -#include <i4b/layer1/i4b_hscx.h> +#include <i4b/layer1/isic/i4b_isic.h> +#include <i4b/layer1/isic/i4b_isac.h> +#include <i4b/layer1/isic/i4b_hscx.h> #include <i4b/include/i4b_global.h> -#include <i4b/include/i4b_l1l2.h> +/* #include <i4b/include/i4b_l1l2.h> */ #include <i4b/include/i4b_mbuf.h> #define TELES_S016_MEMSIZE 0x1000 diff --git a/sys/i4b/layer1/i4b_tel_s0163.c b/sys/i4b/layer1/isic/i4b_tel_s0163.c index fa0c6a6..fa31cd9 100644 --- a/sys/i4b/layer1/i4b_tel_s0163.c +++ b/sys/i4b/layer1/isic/i4b_tel_s0163.c @@ -3,7 +3,7 @@ * * Copyright (c) 1996 Gary Jennejohn. All rights reserved. * - * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved. + * Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -37,11 +37,11 @@ * isic - I4B Siemens ISDN Chipset Driver for Teles S0/16.3 * ======================================================== * - * $Id: i4b_tel_s0163.c,v 1.2 1999/12/13 21:25:27 hm Exp $ + * $Id: i4b_tel_s0163.c,v 1.4 2000/05/29 15:41:41 hm Exp $ * * $FreeBSD$ * - * last edit-date: [Mon Dec 13 22:02:55 1999] + * last edit-date: [Mon May 29 16:47:08 2000] * *---------------------------------------------------------------------------*/ @@ -51,6 +51,7 @@ #if NISIC > 0 && defined(TEL_S0_16_3) #include <sys/param.h> +#include <sys/kernel.h> #include <sys/systm.h> #include <sys/mbuf.h> #include <sys/socket.h> @@ -62,12 +63,12 @@ #include <machine/i4b_debug.h> #include <machine/i4b_ioctl.h> -#include <i4b/layer1/i4b_l1.h> -#include <i4b/layer1/i4b_isac.h> -#include <i4b/layer1/i4b_hscx.h> +#include <i4b/layer1/isic/i4b_isic.h> +#include <i4b/layer1/isic/i4b_isac.h> +#include <i4b/layer1/isic/i4b_hscx.h> #include <i4b/include/i4b_global.h> -#include <i4b/include/i4b_l1l2.h> +/* #include <i4b/include/i4b_l1l2.h> */ #include <i4b/include/i4b_mbuf.h> static u_char intr_no[] = { 1, 1, 0, 2, 4, 6, 1, 1, 1, 0, 8, 10, 12, 1, 1, 14 }; @@ -291,8 +292,8 @@ isic_probe_s0163(device_t dev) isic_detach_common(dev); return ENXIO; } - if ( b2 != 0x1c ) { - printf("isic%d: Error, signature 3 0x%x != 0x1c for Teles S0/16.3!\n", + if (( b2 != 0x1c ) && ( b2 != 0x1f )) { + printf("isic%d: Error, signature 3 0x%x != (0x1c || 0x1f) for Teles S0/16.3!\n", unit, b2); isic_detach_common(dev); return ENXIO; diff --git a/sys/i4b/layer1/i4b_tel_s08.c b/sys/i4b/layer1/isic/i4b_tel_s08.c index d97652e..c6578b1 100644 --- a/sys/i4b/layer1/i4b_tel_s08.c +++ b/sys/i4b/layer1/isic/i4b_tel_s08.c @@ -3,7 +3,7 @@ * * Copyright (c) 1996 Gary Jennejohn. All rights reserved. * - * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved. + * Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -37,11 +37,11 @@ * isic - I4B Siemens ISDN Chipset Driver for Teles S0/8 and clones * ================================================================ * - * $Id: i4b_tel_s08.c,v 1.2 1999/12/13 21:25:27 hm Exp $ + * $Id: i4b_tel_s08.c,v 1.3 2000/05/29 15:41:41 hm Exp $ * * $FreeBSD$ * - * last edit-date: [Mon Dec 13 22:03:06 1999] + * last edit-date: [Mon May 29 16:47:20 2000] * *---------------------------------------------------------------------------*/ @@ -51,6 +51,7 @@ #if NISIC > 0 && defined(TEL_S0_8) #include <sys/param.h> +#include <sys/kernel.h> #include <sys/systm.h> #include <sys/mbuf.h> #include <sys/socket.h> @@ -63,12 +64,12 @@ #include <machine/i4b_debug.h> #include <machine/i4b_ioctl.h> -#include <i4b/layer1/i4b_l1.h> -#include <i4b/layer1/i4b_isac.h> -#include <i4b/layer1/i4b_hscx.h> +#include <i4b/layer1/isic/i4b_isic.h> +#include <i4b/layer1/isic/i4b_isac.h> +#include <i4b/layer1/isic/i4b_hscx.h> #include <i4b/include/i4b_global.h> -#include <i4b/include/i4b_l1l2.h> +/* #include <i4b/include/i4b_l1l2.h> */ #include <i4b/include/i4b_mbuf.h> #define TELES_S08_MEMSIZE 0x1000 diff --git a/sys/i4b/layer1/i4b_usr_sti.c b/sys/i4b/layer1/isic/i4b_usr_sti.c index 2540ae4..0bf8430 100644 --- a/sys/i4b/layer1/i4b_usr_sti.c +++ b/sys/i4b/layer1/isic/i4b_usr_sti.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved. + * Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,9 +27,11 @@ * i4b_usr_sti.c - USRobotics Sportster ISDN TA intern (Tina-pp) * ------------------------------------------------------------- * - * $FreeBSD$ + * $Id: i4b_usr_sti.c,v 1.3 2000/05/29 15:41:42 hm Exp $ * - * last edit-date: [Sun Feb 14 10:29:05 1999] + * $FreeBSD$ + * + * last edit-date: [Mon May 29 16:47:26 2000] * *---------------------------------------------------------------------------*/ @@ -37,16 +39,12 @@ #include "isic.h" #include "opt_i4b.h" #else -#define NISIC 1 +#define NISIC 1 #endif -#if NISIC > 0 && defined(USR_STI) + +#if (NISIC > 0) && defined(USR_STI) #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> @@ -74,9 +72,9 @@ #include <i4b/i4b_ioctl.h> #endif -#include <i4b/layer1/i4b_l1.h> -#include <i4b/layer1/i4b_isac.h> -#include <i4b/layer1/i4b_hscx.h> +#include <i4b/layer1/isic/i4b_isic.h> +#include <i4b/layer1/isic/i4b_isac.h> +#include <i4b/layer1/isic/i4b_hscx.h> #include <i4b/include/i4b_global.h> @@ -96,10 +94,6 @@ static u_char intr_no[] = { 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 3, 4, 5, 0, 6, 7 }; #ifdef __FreeBSD__ -/* prototypes */ -int isic_probe_usrtai __P((device_t)); -int isic_attach_usrtai __P((device_t)); - #define ADDR(reg) \ (((reg/4) * 1024) + ((reg%4) * 2)) diff --git a/sys/i4b/layer1/isic_supio.c b/sys/i4b/layer1/isic_supio.c deleted file mode 100644 index 709dbce..0000000 --- a/sys/i4b/layer1/isic_supio.c +++ /dev/null @@ -1,386 +0,0 @@ -/* - * Copyright (c) 1998 Ignatios Souvatzis. 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. - * - *--------------------------------------------------------------------------- - * - * 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" or "isicII". - * ----------------------------------------------------------- - * - * $FreeBSD$ - * - * last edit-date: [Mon Mar 22 22:49:20 MET 1999] - * - * -is ISDN Master II support added. - * -is original implementation [Sun Feb 14 10:29:19 1999] - * - *---------------------------------------------------------------------------*/ - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/errno.h> -#include <sys/syslog.h> -#include <sys/device.h> -#include <sys/socket.h> -#include <net/if.h> -#include <sys/systm.h> -#include <sys/malloc.h> - -#include <machine/cpu.h> -#include <machine/intr.h> -#include <machine/bus.h> - -#include <amiga/dev/supio.h> - -#include <i4b/i4b_ioctl.h> -#include <i4b/i4b_trace.h> -#include <i4b/include/i4b_global.h> -#include <i4b/include/i4b_l1l2.h> -#include <i4b/layer1/i4b_l1.h> -#include <i4b/layer1/i4b_hscx.h> -#include <i4b/layer1/i4b_isac.h> - -/*static*/ int isic_supio_match __P((struct device *, struct cfdata *, void *)); -/*static*/ void isic_supio_attach __P((struct device *, struct device *, void *)); - -/*static*/ u_int8_t aster_read_reg __P((struct isic_softc *sc, int what, - bus_size_t offs)); -/*static*/ void aster_write_reg __P((struct isic_softc *sc, int what, - bus_size_t offs, u_int8_t data)); -/*static*/ void aster_read_fifo __P((struct isic_softc *sc, int what, - void *buf, size_t size)); -/*static*/ void aster_write_fifo __P((struct isic_softc *sc, int what, - const void *data, size_t size)); - -static int supio_isicattach __P((struct isic_softc *sc)); - -struct isic_supio_softc { - struct isic_softc sc_isic; - struct isr sc_isr; - struct bus_space_tag sc_bst; -}; - -struct cfattach isic_supio_ca = { - sizeof(struct isic_supio_softc), isic_supio_match, isic_supio_attach -}; - -/* - * Probe card - */ -/*static*/ int -isic_supio_match(parent, cf, aux) - struct device *parent; - struct cfdata *cf; - void *aux; -{ - struct supio_attach_args *sap = aux; - - /* ARGSUSED */ - return (!strcmp("isic", sap->supio_name) || - !strcmp("isicII", sap->supio_name)); -} - -int isic_supio_ipl = 2; -/* - * Attach the card - */ -/*static*/ void -isic_supio_attach(parent, self, aux) - struct device *parent, *self; - void *aux; -{ - struct isic_supio_softc *ssc = (void *)self; - struct isic_softc *sc = &ssc->sc_isic; - struct supio_attach_args *sap = 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; - sc->sc_unit = sc->sc_dev.dv_unit; /* XXX ??? */ - - /* 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 = 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 = 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 = (o2 + 0x80)/2; - sc->sc_maps[2].size = 0; /* foreign mapping, leave it alone */ - - sc->clearirq = NULL; - sc->readreg = aster_read_reg; - sc->writereg = aster_write_reg; - sc->readfifo = aster_read_fifo; - sc->writefifo = aster_write_fifo; - - /* setup card type */ - sc->sc_cardtyp = CARD_TYPEP_BLMASTER; - sc->sc_bustyp = BUS_TYPE_IOM2; - - sc->sc_ipac = 0; - sc->sc_bfifolen = HSCX_FIFO_LEN; - - /* enable RTS on HSCX A */ - aster_write_reg(sc, ISIC_WHAT_HSCXA, H_MODE, HSCX_MODE_RTS); - - /* MI initialization of card */ - - printf("\n"); - supio_isicattach(sc); - - ssc->sc_isr.isr_intr = isicintr; - ssc->sc_isr.isr_arg = sc; - ssc->sc_isr.isr_ipl = isic_supio_ipl; /* XXX */ - add_isr(&ssc->sc_isr); -} - -#if 0 -int -isic_supiointr(p) - void *p; -{ - /* XXX should test whether it is our interupt at all */ - add_sicallback((sifunc_t)isicintr, p, NULL); - return 1; -} -#endif - -/*static*/ void -aster_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size) -{ - bus_space_tag_t t = sc->sc_maps[what].t; - bus_space_handle_t h = sc->sc_maps[what].h; - bus_size_t o = sc->sc_maps[what].offset; - - bus_space_read_multi_1(t, h, o, buf, size); -} - -/*static*/ void -aster_write_fifo(struct isic_softc *sc, int what, const void *buf, size_t size) -{ - bus_space_tag_t t = sc->sc_maps[what].t; - bus_space_handle_t h = sc->sc_maps[what].h; - bus_size_t o = sc->sc_maps[what].offset; - - bus_space_write_multi_1(t, h, o, (u_int8_t*)buf, size); -} - -/*static*/ u_int8_t -aster_read_reg(struct isic_softc *sc, int what, bus_size_t offs) -{ - bus_space_tag_t t = sc->sc_maps[what].t; - bus_space_handle_t h = sc->sc_maps[what].h; - bus_size_t o = sc->sc_maps[what].offset; - - return bus_space_read_1(t, h, o + offs); -} - -/*static*/ void -aster_write_reg(struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data) -{ - bus_space_tag_t t = sc->sc_maps[what].t; - bus_space_handle_t h = sc->sc_maps[what].h; - bus_size_t o = sc->sc_maps[what].offset; - - bus_space_write_1(t, h, o + offs, data); -} - -/*---------------------------------------------------------------------------* - * card independend attach for pcmcia^Wsupio cards - * XXX this should be centralized! - *---------------------------------------------------------------------------*/ - -/* - * parameter and format for message producing e.g. "isic0: " - * there is no FreeBSD/Amiga, so just: - */ - -#define ISIC_FMT "%s: " -#define ISIC_PARM sc->sc_dev.dv_xname -#define TERMFMT "\n" - -int -supio_isicattach(struct isic_softc *sc) -{ - static char *ISACversion[] = { - "2085 Version A1/A2 or 2086/2186 Version 1.1", - "2085 Version B1", - "2085 Version B2", - "2085 Version V2.3 (B3)", - "Unknown Version" - }; - - static char *HSCXversion[] = { - "82525 Version A1", - "Unknown (0x01)", - "82525 Version A2", - "Unknown (0x03)", - "82525 Version A3", - "82525 or 21525 Version 2.1", - "Unknown Version" - }; - - isic_sc[sc->sc_unit] = sc; - sc->sc_isac_version = 0; - 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 */ - - isic_isac_init(sc); - - /* HSCX setup */ - - isic_bchannel_setup(sc->sc_unit, HSCX_CH_A, BPROT_NONE, 0); - - isic_bchannel_setup(sc->sc_unit, HSCX_CH_B, BPROT_NONE, 0); - - /* setup linktab */ - - isic_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); - - /* announce chip versions */ - - 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'); - } - - 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]); - } - - return(1); -} - diff --git a/sys/i4b/layer1/iwic/i4b_iwic.h b/sys/i4b/layer1/iwic/i4b_iwic.h new file mode 100644 index 0000000..1da90d7 --- /dev/null +++ b/sys/i4b/layer1/iwic/i4b_iwic.h @@ -0,0 +1,224 @@ +/* + * Copyright (c) 1999, 2000 Dave Boyce. 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_iwic - isdn4bsd Winbond W6692 driver + * ---------------------------------------- + * + * $Id: i4b_iwic.h,v 1.5 2000/03/13 15:23:43 hm Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Mon Mar 13 16:23:15 2000] + * + *---------------------------------------------------------------------------*/ + +#ifndef _I4B_IWIC_H_ +#define _I4B_IWIC_H_ + +#include <i4b/layer1/iwic/i4b_iwic_ext.h> + +/*---------------------------------------------------------------------------* + * PCI resources used + *---------------------------------------------------------------------------*/ + +#define INFO_IO_BASES 2 + +struct i4b_info { + struct resource * io_base[INFO_IO_BASES]; + int io_rid [INFO_IO_BASES]; + struct resource * irq; + int irq_rid; + struct resource * mem; + int mem_rid; +}; + +/*---------------------------------------------------------------------------* + * state of a B channel + *---------------------------------------------------------------------------*/ +struct iwic_bchan +{ + int unit; /* unit number */ + int channel; /* channel number */ + int offset; /* offset from iobase */ + int bprot; /* b channel protocol used */ + int state; /* transceiver state: */ +#define ST_IDLE 0x00 /* channel idle */ +#define ST_TX_ACTIVE 0x01 /* tx running */ + + int sc_trace_bcount; + + /* receive data from ISDN */ + + struct ifqueue rx_queue; /* receiver queue */ + int rxcount; /* rx statistics counter*/ + struct mbuf *in_mbuf; /* rx input buffer */ + u_char *in_cbptr; /* curr buffer pointer */ + int in_len; /* rx input buffer len */ + + /* transmit data to ISDN */ + + struct ifqueue tx_queue; /* transmitter queue */ + int txcount; /* tx statistics counter */ + struct mbuf *out_mbuf_head; /* first mbuf in possible chain */ + struct mbuf *out_mbuf_cur; /* current mbuf in possbl chain */ + unsigned char *out_mbuf_cur_ptr; /* data pointer into mbuf */ + int out_mbuf_cur_len; /* remaining bytes in mbuf */ + + /* linktab */ + + isdn_link_t iwic_isdn_linktab; + drvr_link_t *iwic_drvr_linktab; +}; + +/*---------------------------------------------------------------------------* + * state of a D channel + *---------------------------------------------------------------------------*/ +struct iwic_dchan +{ + int enabled; + int trace_count; + struct mbuf *ibuf; + u_char *ibuf_ptr; /* Input buffer pointer */ + int ibuf_len; /* Current length of input buffer */ + int ibuf_max_len; /* Max length in input buffer */ + int rx_count; + + int tx_ready; /* Can send next 64 bytes of data. */ + int tx_count; + + struct mbuf *obuf; + int free_obuf; + u_char *obuf_ptr; + int obuf_len; + + struct mbuf *obuf2; + int free_obuf2; +}; + +/*---------------------------------------------------------------------------* + * state of one iwic unit + *---------------------------------------------------------------------------*/ +struct iwic_softc +{ + int sc_unit; + u_int32_t sc_iobase; + int sc_trace; + int sc_cardtyp; + + int sc_I430state; + int sc_I430T3; + + int enabled; + + struct iwic_dchan sc_dchan; + struct iwic_bchan sc_bchan[2]; + + struct i4b_info sc_resources; +}; + +/*---------------------------------------------------------------------------* + * rd/wr register/fifo macros + *---------------------------------------------------------------------------*/ +#define IWIC_READ(sc,reg) (inb ((sc)->sc_iobase + (u_int32_t)(reg))) +#define IWIC_WRITE(sc,reg,val) (outb ((sc)->sc_iobase + (u_int32_t)(reg), (val))) +#define IWIC_WRDFIFO(sc,p,l) (outsb ((sc)->sc_iobase + D_XFIFO, (p), (l))) +#define IWIC_RDDFIFO(sc,p,l) (insb ((sc)->sc_iobase + D_RFIFO, (p), (l))) +#define IWIC_WRBFIFO(sc,b,p,l) (outsb (((sc)->sc_iobase + (b)->offset + B_XFIFO), (p), (l))) +#define IWIC_RDBFIFO(sc,b,p,l) (insb (((sc)->sc_iobase + (b)->offset + B_RFIFO), (p), (l))) + +/*---------------------------------------------------------------------------* + * possible I.430 states + *---------------------------------------------------------------------------*/ +enum I430states +{ + ST_F3N, /* F3 Deactivated, no clock */ + ST_F3, /* F3 Deactivated */ + ST_F4, /* F4 Awaiting Signal */ + ST_F5, /* F5 Identifying Input */ + ST_F6, /* F6 Synchronized */ + ST_F7, /* F7 Activated */ + ST_F8, /* F8 Lost Framing */ + ST_ILL, /* Illegal State */ + N_STATES +}; + +/*---------------------------------------------------------------------------* + * possible I.430 events + *---------------------------------------------------------------------------*/ +enum I430events +{ + EV_PHAR, /* PH ACTIVATE REQUEST */ + EV_CE, /* Clock enabled */ + EV_T3, /* Timer 3 expired */ + EV_INFO0, /* receiving INFO0 */ + EV_RSY, /* receiving any signal */ + EV_INFO2, /* receiving INFO2 */ + EV_INFO48, /* receiving INFO4 pri 8/9 */ + EV_INFO410, /* receiving INFO4 pri 10/11 */ + EV_DR, /* Deactivate Request */ + EV_PU, /* Power UP */ + EV_DIS, /* Disconnected (only 2085) */ + EV_EI, /* Error Indication */ + EV_ILL, /* Illegal Event */ + N_EVENTS +}; + +/*---------------------------------------------------------------------------* + * available commands + *---------------------------------------------------------------------------*/ +enum I430commands +{ + CMD_ECK, /* Enable clock */ + CMD_TIM, /* Timing */ + CMD_RT, /* Reset */ + CMD_AR8, /* Activation request pri 8 */ + CMD_AR10, /* Activation request pri 10 */ + CMD_DIU, /* Deactivate Indication Upstream */ + CMD_ILL /* Illegal command */ +}; + + +extern struct iwic_softc iwic_sc[]; + +#define iwic_find_sc(unit) (&iwic_sc[(unit)]) + +extern void iwic_init(struct iwic_softc *); +extern void iwic_next_state(struct iwic_softc *, int); + +extern void iwic_dchan_init(struct iwic_softc *); +extern void iwic_dchan_xirq(struct iwic_softc *); +extern void iwic_dchan_xfer_irq(struct iwic_softc *, int); +extern void iwic_dchan_disable(struct iwic_softc *sc); +extern int iwic_dchan_data_req(struct iwic_softc *sc, struct mbuf *m, int freeflag); +extern void iwic_dchan_transmit(struct iwic_softc *sc); + +char *iwic_printstate(struct iwic_softc *sc); + +void iwic_init_linktab(struct iwic_softc *sc); +void iwic_bchan_xirq(struct iwic_softc *, int); +void iwic_bchannel_setup(int unit, int h_chan, int bprot, int activate); + +#endif /* _I4B_IWIC_H_ */ diff --git a/sys/i4b/layer1/iwic/i4b_iwic_bchan.c b/sys/i4b/layer1/iwic/i4b_iwic_bchan.c new file mode 100644 index 0000000..e6bbaca --- /dev/null +++ b/sys/i4b/layer1/iwic/i4b_iwic_bchan.c @@ -0,0 +1,749 @@ +/* + * Copyright (c) 1999, 2000 Dave Boyce. All rights reserved. + * + * Copyright (c) 2000 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_iwic - isdn4bsd Winbond W6692 driver + * ---------------------------------------- + * + * $Id: i4b_iwic_bchan.c,v 1.8 2000/05/29 15:41:42 hm Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Mon May 29 16:48:56 2000] + * + *---------------------------------------------------------------------------*/ + +#include "iwic.h" +#include "opt_i4b.h" +#include "pci.h" + +#if (NIWIC > 0) && (NPCI > 0) + +#include <sys/param.h> +#include <sys/kernel.h> +#include <sys/systm.h> +#include <sys/mbuf.h> +#include <sys/socket.h> + +#include <net/if.h> + +#include <machine/clock.h> + +#include <machine/i4b_debug.h> +#include <machine/i4b_ioctl.h> +#include <machine/i4b_trace.h> + +#include <i4b/layer1/i4b_l1.h> + +#include <i4b/layer1/iwic/i4b_iwic.h> +#include <i4b/layer1/iwic/i4b_w6692.h> + +#include <i4b/include/i4b_global.h> +#include <i4b/include/i4b_mbuf.h> + +static void iwic_bchan_init(struct iwic_softc *sc, int chan_no, int activate); + +/*---------------------------------------------------------------------------* + * B-channel interrupt handler + *---------------------------------------------------------------------------*/ +void +iwic_bchan_xirq(struct iwic_softc *sc, int chan_no) +{ + int irq_stat; + struct iwic_bchan *chan; + int cmd = 0; + int activity = 0; + + chan = &sc->sc_bchan[chan_no]; + + irq_stat = IWIC_READ(sc, chan->offset + B_EXIR); + + NDBGL1(L1_H_IRQ, "irq_stat = 0x%x", irq_stat); + + if((irq_stat & (B_EXIR_RMR | B_EXIR_RME | B_EXIR_RDOV | B_EXIR_XFR | B_EXIR_XDUN)) == 0) + { + NDBGL1(L1_H_XFRERR, "spurious IRQ!"); + return; + } + + if (irq_stat & B_EXIR_RDOV) + { + NDBGL1(L1_H_XFRERR, "RDOV"); + } + + if (irq_stat & B_EXIR_XDUN) + { + NDBGL1(L1_H_XFRERR, "XDUN"); + } + +/* RX message end interrupt */ + + if(irq_stat & B_EXIR_RME) + { +/* XXXX */ int error = 0; + register int fifo_data_len; + + NDBGL1(L1_H_IRQ, "B_EXIR_RME"); + + fifo_data_len = ((IWIC_READ(sc,chan->offset+B_RBCL)) & + ((IWIC_BCHAN_FIFO_LEN)-1)); + + if(fifo_data_len == 0) + fifo_data_len = IWIC_BCHAN_FIFO_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 iwic_bchan_irq: 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) + { + /* read data from fifo */ + + NDBGL1(L1_H_IRQ, "B_EXIR_RME, rd fifo, len = %d", fifo_data_len); + + IWIC_RDBFIFO(sc, chan, chan->in_cbptr, fifo_data_len); + + cmd |= (B_CMDR_RACK | B_CMDR_RACT); + IWIC_WRITE(sc, chan->offset + B_CMDR, cmd); + cmd = 0; + + chan->in_len += fifo_data_len; + chan->rxcount += 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 = L0IWICUNIT(sc->sc_unit); + hdr.type = (chan_no == IWIC_BCH_A ? TRC_CH_B1 : TRC_CH_B2); + hdr.dir = FROM_NT; + hdr.count = ++sc->sc_bchan[chan_no].sc_trace_bcount; + MICROTIME(hdr.time); + i4b_l1_trace_ind(&hdr, chan->in_mbuf->m_len, chan->in_mbuf->m_data); + } + + (*chan->iwic_drvr_linktab->bch_rx_data_ready)(chan->iwic_drvr_linktab->unit); + + activity = ACT_RX; + + /* mark buffer ptr as unused */ + + chan->in_mbuf = NULL; + chan->in_cbptr = NULL; + chan->in_len = 0; + } + else + { + NDBGL1(L1_H_XFRERR, "RAWHDLC rx buffer overflow in RME, in_len=%d, fifolen=%d", chan->in_len, fifo_data_len); + chan->in_cbptr = chan->in_mbuf->m_data; + chan->in_len = 0; + cmd |= (B_CMDR_RRST | B_CMDR_RACK); + } + } + else + { + if (chan->in_mbuf != NULL) + { + i4b_Bfreembuf(chan->in_mbuf); + chan->in_mbuf = NULL; + chan->in_cbptr = NULL; + chan->in_len = 0; + } + cmd |= (B_CMDR_RRST | B_CMDR_RACK); + } + } + +/* RX fifo full interrupt */ + + if(irq_stat & B_EXIR_RMR) + { + NDBGL1(L1_H_IRQ, "B_EXIR_RMR"); + + if(chan->in_mbuf == NULL) + { + if((chan->in_mbuf = i4b_Bgetmbuf(BCH_MAX_DATALEN)) == NULL) + panic("L1 iwic_bchan_irq: RMR, cannot allocate mbuf!\n"); + chan->in_cbptr = chan->in_mbuf->m_data; + chan->in_len = 0; + } + + chan->rxcount += IWIC_BCHAN_FIFO_LEN; + + if((chan->in_len + IWIC_BCHAN_FIFO_LEN) <= BCH_MAX_DATALEN) + { + /* read data from fifo */ + + NDBGL1(L1_H_IRQ, "B_EXIR_RMR, rd fifo, len = max (64)"); + + IWIC_RDBFIFO(sc, chan, chan->in_cbptr, IWIC_BCHAN_FIFO_LEN); + + chan->in_cbptr += IWIC_BCHAN_FIFO_LEN; + chan->in_len += IWIC_BCHAN_FIFO_LEN; + } + 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 = L0IWICUNIT(sc->sc_unit); + hdr.type = (chan_no == IWIC_BCH_A ? TRC_CH_B1 : TRC_CH_B2); + hdr.dir = FROM_NT; + hdr.count = ++sc->sc_bchan[chan_no].sc_trace_bcount; + MICROTIME(hdr.time); + i4b_l1_trace_ind(&hdr, chan->in_mbuf->m_len, chan->in_mbuf->m_data); + } + + /* silence detection */ + + if(!(i4b_l1_bchan_tel_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->iwic_drvr_linktab->bch_rx_data_ready)(chan->iwic_drvr_linktab->unit); + + /* alloc new buffer */ + + if((chan->in_mbuf = i4b_Bgetmbuf(BCH_MAX_DATALEN)) == NULL) + panic("L1 iwic_bchan_irq: RMR, cannot allocate new mbuf!\n"); + + /* setup new data ptr */ + + chan->in_cbptr = chan->in_mbuf->m_data; + + /* read data from fifo */ + + NDBGL1(L1_H_IRQ, "B_EXIR_RMR, rd fifo1, len = max (64)"); + + IWIC_RDBFIFO(sc, chan, chan->in_cbptr, IWIC_BCHAN_FIFO_LEN); + + chan->in_cbptr += IWIC_BCHAN_FIFO_LEN; + chan->in_len = IWIC_BCHAN_FIFO_LEN; + + chan->rxcount += IWIC_BCHAN_FIFO_LEN; + } + else + { + NDBGL1(L1_H_XFRERR, "RAWHDLC rx buffer overflow in RPF, in_len=%d", chan->in_len); + chan->in_cbptr = chan->in_mbuf->m_data; + chan->in_len = 0; + cmd |= (B_CMDR_RRST | B_CMDR_RACK); + } + } + + /* command to release fifo space */ + + cmd |= B_CMDR_RACK; + } + +/* TX interrupt */ + + if (irq_stat & B_EXIR_XFR) + { + /* transmit fifo empty, new data can be written to fifo */ + + int activity = -1; + int len; + int nextlen; + + NDBGL1(L1_H_IRQ, "B_EXIR_XFR"); + + if(chan->out_mbuf_cur == NULL) /* last frame is transmitted */ + { + IF_DEQUEUE(&chan->tx_queue, chan->out_mbuf_head); + + if(chan->out_mbuf_head == NULL) + { + chan->state &= ~ST_TX_ACTIVE; + (*chan->iwic_drvr_linktab->bch_tx_queue_empty)(chan->iwic_drvr_linktab->unit); + } + else + { + chan->state |= ST_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 = L0IWICUNIT(sc->sc_unit); + hdr.type = (chan_no == IWIC_BCH_A ? TRC_CH_B1 : TRC_CH_B2); + hdr.dir = FROM_TE; + hdr.count = ++sc->sc_bchan[chan_no].sc_trace_bcount; + MICROTIME(hdr.time); + i4b_l1_trace_ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data); + } + + if(chan->bprot == BPROT_NONE) + { + if(!(i4b_l1_bchan_tel_silence(chan->out_mbuf_cur->m_data, chan->out_mbuf_cur->m_len))) + activity = ACT_TX; + } + else + { + activity = ACT_TX; + } + } + } + + len = 0; + + while(chan->out_mbuf_cur && len != IWIC_BCHAN_FIFO_LEN) + { + nextlen = min(chan->out_mbuf_cur_len, IWIC_BCHAN_FIFO_LEN - len); + + NDBGL1(L1_H_IRQ, "B_EXIR_XFR, wr fifo, len = %d", nextlen); + + IWIC_WRBFIFO(sc, chan, chan->out_mbuf_cur_ptr, nextlen); + + cmd |= B_CMDR_XMS; + + 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 = L0IWICUNIT(sc->sc_unit); + hdr.type = (chan_no == IWIC_BCH_A ? TRC_CH_B1 : TRC_CH_B2); + hdr.dir = FROM_TE; + hdr.count = ++sc->sc_bchan[chan_no].sc_trace_bcount; + MICROTIME(hdr.time); + i4b_l1_trace_ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data); + } + } + else + { + if (chan->bprot != BPROT_NONE) + cmd |= B_CMDR_XME; + i4b_Bfreembuf(chan->out_mbuf_head); + chan->out_mbuf_head = NULL; + } + } + } + } + if(cmd) + { + cmd |= B_CMDR_RACT; + IWIC_WRITE(sc, chan->offset + B_CMDR, cmd); + } +} + +/*---------------------------------------------------------------------------* + * initialize one B channels rx/tx data structures + *---------------------------------------------------------------------------*/ +void +iwic_bchannel_setup(int unit, int chan_no, int bprot, int activate) +{ + struct iwic_softc *sc = &iwic_sc[unit]; + struct iwic_bchan *chan = &sc->sc_bchan[chan_no]; + + int s = SPLI4B(); + + NDBGL1(L1_BCHAN, "unit %d, chan %d, bprot %d, activate %d", unit, chan_no, bprot, activate); + + /* general part */ + + chan->bprot = bprot; /* B channel protocol */ + chan->state = ST_IDLE; /* B channel state */ + + if(activate == 0) + { + /* deactivation */ + iwic_bchan_init(sc, chan_no, activate); + } + + /* 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 */ + iwic_bchan_init(sc, chan_no, activate); + } + + splx(s); +} + +/*---------------------------------------------------------------------------* + * initalize / deinitialize B-channel hardware + *---------------------------------------------------------------------------*/ +static void +iwic_bchan_init(struct iwic_softc *sc, int chan_no, int activate) +{ + struct iwic_bchan *bchan = &sc->sc_bchan[chan_no]; + + NDBGL1(L1_BCHAN, "chan %d, activate %d", chan_no, activate); + + if(activate) + { + if(bchan->bprot == BPROT_NONE) + { + /* Extended transparent mode */ + IWIC_WRITE(sc, bchan->offset + B_MODE, B_MODE_MMS); + } + else + { + /* Transparent mode */ + IWIC_WRITE(sc, bchan->offset + B_MODE, 0); + /* disable address comparation */ + IWIC_WRITE (sc, bchan->offset+B_ADM1, 0xff); + IWIC_WRITE (sc, bchan->offset+B_ADM2, 0xff); + } + + /* reset & start receiver */ + IWIC_WRITE(sc, bchan->offset + B_CMDR, B_CMDR_RRST|B_CMDR_RACT); + + /* clear irq mask */ + IWIC_WRITE(sc, bchan->offset + B_EXIM, 0); + } + else + { + /* mask all irqs */ + IWIC_WRITE(sc, bchan->offset + B_EXIM, 0xff); + + /* reset mode */ + IWIC_WRITE(sc, bchan->offset + B_MODE, 0); + + /* Bring interface down */ + IWIC_WRITE(sc, bchan->offset + B_CMDR, B_CMDR_RRST | B_CMDR_XRST); + + /* Flush pending interrupts */ + IWIC_READ(sc, bchan->offset + B_EXIR); + } +} + +/*---------------------------------------------------------------------------* + * start transmission on a b channel + *---------------------------------------------------------------------------*/ +static void +iwic_bchannel_start(int unit, int chan_no) +{ + struct iwic_softc *sc = &iwic_sc[unit]; + register struct iwic_bchan *chan = &sc->sc_bchan[chan_no]; + register int next_len; + register int len; + + int s; + int activity = -1; + int cmd = 0; + + s = SPLI4B(); /* enter critical section */ + + NDBGL1(L1_BCHAN, "unit %d, channel %d", unit, chan_no); + + if(chan->state & ST_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(!(i4b_l1_bchan_tel_silence(chan->out_mbuf_cur->m_data, chan->out_mbuf_cur->m_len))) + activity = ACT_TX; + } + else + { + activity = ACT_TX; + } + + chan->state |= ST_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 = L0IWICUNIT(unit); + hdr.type = (chan_no == IWIC_BCH_A ? TRC_CH_B1 : TRC_CH_B2); + hdr.dir = FROM_TE; + hdr.count = ++sc->sc_bchan[chan_no].sc_trace_bcount; + MICROTIME(hdr.time); + i4b_l1_trace_ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data); + } + + len = 0; /* # of chars put into tx fifo this time */ + + /* + * fill the tx fifo with data from the current mbuf. if + * current mbuf holds less data than 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 chip that it has to send + * CRC and closing flag + */ + + while((len < IWIC_BCHAN_FIFO_LEN) && chan->out_mbuf_cur) + { + /* + * put as much data into the fifo as is + * available from the current mbuf + */ + + if((len + chan->out_mbuf_cur_len) >= IWIC_BCHAN_FIFO_LEN) + next_len = IWIC_BCHAN_FIFO_LEN - len; + else + next_len = chan->out_mbuf_cur_len; + + /* write what we have from current mbuf to fifo */ + + IWIC_WRBFIFO(sc, chan, chan->out_mbuf_cur_ptr, next_len); + + len += next_len; /* update # of bytes written */ + chan->txcount += next_len; /* statistics */ + chan->out_mbuf_cur_ptr += next_len; /* data ptr */ + chan->out_mbuf_cur_len -= next_len; /* data len */ + + /* + * in case the current mbuf (of a possible chain) data + * has been put into the fifo, check if there is a next + * mbuf in the chain. If there is one, get ptr to it + * and update the data ptr and the length + */ + + if((chan->out_mbuf_cur_len <= 0) && + ((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 = L0IWICUNIT(unit); + hdr.type = (chan_no == IWIC_BCH_A ? TRC_CH_B1 : TRC_CH_B2); + hdr.dir = FROM_TE; + hdr.count = ++sc->sc_bchan[chan_no].sc_trace_bcount; + MICROTIME(hdr.time); + i4b_l1_trace_ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data); + } + } + } + + /* + * if there is either still data in the current mbuf and/or + * there is a successor on the chain available issue just + * a XTF (transmit) command to teh chip. if ther is no more + * data available from the current mbuf (-chain), issue + * an XTF and an XME (message end) command which will then + * send the CRC and the closing HDLC flag sequence + */ + + if(chan->out_mbuf_cur && (chan->out_mbuf_cur_len > 0)) + { + /* + * more data available, send current fifo out. + * next xfer to tx fifo is done in the + * interrupt routine. + */ + + cmd |= B_CMDR_XMS; + } + else + { + /* end of mbuf chain */ + + if(chan->bprot == BPROT_NONE) + cmd |= B_CMDR_XMS; + else + cmd |= (B_CMDR_XMS | B_CMDR_XME); + + i4b_Bfreembuf(chan->out_mbuf_head); /* free mbuf chain */ + + chan->out_mbuf_head = NULL; + chan->out_mbuf_cur = NULL; + chan->out_mbuf_cur_ptr = NULL; + chan->out_mbuf_cur_len = 0; + } + + /* call timeout handling routine */ + + if(activity == ACT_RX || activity == ACT_TX) + (*chan->iwic_drvr_linktab->bch_activity)(chan->iwic_drvr_linktab->unit, activity); + + if(cmd) + { + cmd |= B_CMDR_RACT; + IWIC_WRITE(sc, chan->offset + B_CMDR, cmd); + } + + splx(s); +} + +/*---------------------------------------------------------------------------* + * + *---------------------------------------------------------------------------*/ +static void +iwic_bchannel_stat(int unit, int chan_no, bchan_statistics_t *bsp) +{ + struct iwic_softc *sc = iwic_find_sc(unit); + struct iwic_bchan *bchan = &sc->sc_bchan[chan_no]; + + int s = SPLI4B(); + + bsp->outbytes = bchan->txcount; + bsp->inbytes = bchan->rxcount; + + bchan->txcount = 0; + bchan->rxcount = 0; + + splx(s); +} + +/*---------------------------------------------------------------------------* + * initialize our local linktab + *---------------------------------------------------------------------------*/ +void +iwic_init_linktab(struct iwic_softc *sc) +{ + struct iwic_bchan *chan; + isdn_link_t *lt; + + /* make sure the hardware driver is known to layer 4 */ + ctrl_types[CTRL_PASSIVE].set_linktab = i4b_l1_set_linktab; + ctrl_types[CTRL_PASSIVE].get_linktab = i4b_l1_ret_linktab; + + /* channel A */ + + chan = &sc->sc_bchan[IWIC_BCH_A]; + lt = &chan->iwic_isdn_linktab; + + lt->unit = sc->sc_unit; + lt->channel = IWIC_BCH_A; + lt->bch_config = iwic_bchannel_setup; + lt->bch_tx_start = iwic_bchannel_start; + lt->bch_stat = iwic_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; + + /* channel B */ + + chan = &sc->sc_bchan[IWIC_BCH_B]; + lt = &chan->iwic_isdn_linktab; + + lt->unit = sc->sc_unit; + lt->channel = IWIC_BCH_B; + lt->bch_config = iwic_bchannel_setup; + lt->bch_tx_start = iwic_bchannel_start; + lt->bch_stat = iwic_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; +} + +#endif /* NIWIC > 0 */ diff --git a/sys/i4b/layer1/iwic/i4b_iwic_dchan.c b/sys/i4b/layer1/iwic/i4b_iwic_dchan.c new file mode 100644 index 0000000..b088505 --- /dev/null +++ b/sys/i4b/layer1/iwic/i4b_iwic_dchan.c @@ -0,0 +1,494 @@ +/* + * Copyright (c) 1999, 2000 Dave Boyce. 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_iwic - isdn4bsd Winbond W6692 driver + * ---------------------------------------- + * + * $Id: i4b_iwic_dchan.c,v 1.5 2000/05/29 15:41:42 hm Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Wed Mar 8 16:17:16 2000] + * + *---------------------------------------------------------------------------*/ + +#include "iwic.h" +#include "opt_i4b.h" +#include "pci.h" + +#if (NIWIC > 0) && (NPCI > 0) + +#include <sys/param.h> +#include <sys/kernel.h> +#include <sys/systm.h> +#include <sys/mbuf.h> +#include <sys/socket.h> + +#include <net/if.h> + +#include <machine/clock.h> + +#include <machine/i4b_debug.h> +#include <machine/i4b_ioctl.h> +#include <machine/i4b_trace.h> + +#include <i4b/layer1/i4b_l1.h> + +#include <i4b/include/i4b_global.h> +#include <i4b/include/i4b_l3l4.h> +#include <i4b/include/i4b_mbuf.h> + +#include <i4b/layer1/iwic/i4b_iwic.h> +#include <i4b/layer1/iwic/i4b_w6692.h> + +#define MAX_DFRAME_LEN 264 + +static void dchan_receive(struct iwic_softc *sc, int ista); + +#ifdef NOTDEF +static void output_bytes(char *prefix, u_char * ptr, int len); +#endif + +/*---------------------------------------------------------------------------* + * + *---------------------------------------------------------------------------*/ +void +iwic_dchan_init(struct iwic_softc *sc) +{ + sc->sc_dchan.ibuf = NULL; + sc->sc_dchan.rx_count = 0; + + sc->sc_dchan.obuf = NULL; + sc->sc_dchan.obuf2 = NULL; + sc->sc_dchan.tx_count = 0; + sc->sc_dchan.tx_ready = 0; + + IWIC_WRITE(sc, D_CTL, D_CTL_SRST); + + DELAY(5000); + + IWIC_WRITE(sc, D_CTL, 0); + + IWIC_WRITE(sc, SQX, SQX_SCIE); + + IWIC_WRITE(sc, PCTL, 0x00); + IWIC_WRITE(sc, MOCR, 0x00); + IWIC_WRITE(sc, GCR, 0x00); + + IWIC_WRITE(sc, D_CMDR, D_CMDR_RRST | D_CMDR_XRST); + IWIC_WRITE(sc, D_MODE, D_MODE_RACT); + + IWIC_WRITE(sc, D_SAM, 0xff); + IWIC_WRITE(sc, D_TAM, 0xff); + + IWIC_WRITE(sc, D_EXIM, 0x00); +} + +/*---------------------------------------------------------------------------* + * + *---------------------------------------------------------------------------*/ +void +iwic_dchan_xirq(struct iwic_softc *sc) +{ + int irq_stat; + int stat; + + irq_stat = IWIC_READ(sc, D_EXIR); + + if (irq_stat & D_EXIR_RDOV) + { + NDBGL1(L1_I_ERR, "RDOV in state %s", iwic_printstate(sc)); + } + if (irq_stat & D_EXIR_XDUN) + { + NDBGL1(L1_I_ERR, "XDUN in state %s", iwic_printstate(sc)); + sc->sc_dchan.tx_ready = 0; + } + if (irq_stat & D_EXIR_XCOL) + { + NDBGL1(L1_I_ERR, "XCOL in state %s", iwic_printstate(sc)); + sc->sc_dchan.tx_ready = 0; + } + if (irq_stat & D_EXIR_TIN2) + { + NDBGL1(L1_I_ERR, "TIN2 in state %s", iwic_printstate(sc)); + } + if (irq_stat & D_EXIR_MOC) + { + stat = IWIC_READ(sc, MOR); + NDBGL1(L1_I_ERR, "MOC in state %s, byte = 0x%x", iwic_printstate(sc), stat); + } + + if (irq_stat & D_EXIR_ISC) + { + stat = (IWIC_READ(sc, CIR)) & 0x0f; + + switch (stat) + { + case CIR_CE: + NDBGL1(L1_I_CICO, "rx CE in state %s", iwic_printstate(sc)); + iwic_next_state(sc, EV_CE); + break; + case CIR_DRD: + NDBGL1(L1_I_CICO, "rx DRD in state %s", iwic_printstate(sc)); + iwic_next_state(sc, EV_INFO0); + i4b_l1_mph_status_ind(L0IWICUNIT(sc->sc_unit), STI_L1STAT, LAYER_IDLE, NULL); + break; + case CIR_LD: + NDBGL1(L1_I_CICO, "rx LD in state %s", iwic_printstate(sc)); + iwic_next_state(sc, EV_RSY); + break; + case CIR_ARD: + NDBGL1(L1_I_CICO, "rx ARD in state %s", iwic_printstate(sc)); + iwic_next_state(sc, EV_INFO2); + break; + case CIR_TI: + NDBGL1(L1_I_CICO, "rx TI in state %s", iwic_printstate(sc)); + iwic_next_state(sc, EV_INFO0); + break; + case CIR_ATI: + NDBGL1(L1_I_CICO, "rx ATI in state %s", iwic_printstate(sc)); + iwic_next_state(sc, EV_INFO0); + break; + case CIR_AI8: + NDBGL1(L1_I_CICO, "rx AI8 in state %s", iwic_printstate(sc)); + i4b_l1_mph_status_ind(L0IWICUNIT(sc->sc_unit), STI_L1STAT, LAYER_ACTIVE, NULL); + iwic_next_state(sc, EV_INFO48); + break; + case CIR_AI10: + NDBGL1(L1_I_CICO, "rx AI10 in state %s", iwic_printstate(sc)); + i4b_l1_mph_status_ind(L0IWICUNIT(sc->sc_unit), STI_L1STAT, LAYER_ACTIVE, NULL); + iwic_next_state(sc, EV_INFO410); + break; + case CIR_CD: + NDBGL1(L1_I_CICO, "rx DIS in state %s", iwic_printstate(sc)); + iwic_next_state(sc, EV_DIS); + break; + default: + NDBGL1(L1_I_ERR, "ERROR, unknown indication 0x%x in state %s", stat, iwic_printstate(sc)); + iwic_next_state(sc, EV_INFO0); + break; + } + } + + if (irq_stat & D_EXIR_TEXP) + { + NDBGL1(L1_I_ERR, "TEXP in state %s", iwic_printstate(sc)); + } + + if (irq_stat & D_EXIR_WEXP) + { + NDBGL1(L1_I_ERR, "WEXP in state %s", iwic_printstate(sc)); + } +} + +/*---------------------------------------------------------------------------* + * All receiving and transmitting takes place here. + *---------------------------------------------------------------------------*/ +void +iwic_dchan_xfer_irq(struct iwic_softc *sc, int ista) +{ + NDBGL1(L1_I_MSG, "ISTA = 0x%x", ista); + + if (ista & (ISTA_D_RMR | ISTA_D_RME)) + { + /* Receive message ready */ + dchan_receive(sc, ista); + } + if (ista & ISTA_D_XFR) + { + /* Transmitter ready */ + sc->sc_dchan.tx_ready = 1; + + iwic_dchan_transmit(sc); + } +} + +/*---------------------------------------------------------------------------* + * + *---------------------------------------------------------------------------*/ +void +iwic_dchan_disable(struct iwic_softc *sc) +{ + int s; + + s = SPLI4B(); + + if (sc->sc_dchan.obuf) + { + if (sc->sc_dchan.free_obuf) + i4b_Dfreembuf(sc->sc_dchan.obuf); + sc->sc_dchan.obuf = NULL; + } + + if (sc->sc_dchan.obuf2) + { + if (sc->sc_dchan.free_obuf2) + i4b_Dfreembuf(sc->sc_dchan.obuf2); + sc->sc_dchan.obuf2 = NULL; + } + + splx(s); + + IWIC_WRITE(sc, CIX, CIX_DRC); +} + +/*---------------------------------------------------------------------------* + * + *---------------------------------------------------------------------------*/ +int +iwic_dchan_data_req(struct iwic_softc *sc, struct mbuf *m, int freeflag) +{ + int s; + + if (!m) + return 0; + + s = SPLI4B(); + + /* Queue message */ + + if (sc->sc_dchan.obuf) + { + if (sc->sc_dchan.obuf2) + { + NDBGL1(L1_I_ERR, "no buffer space!"); + } + else + { + sc->sc_dchan.obuf2 = m; + sc->sc_dchan.free_obuf2 = freeflag; + } + } + else + { + sc->sc_dchan.obuf = m; + sc->sc_dchan.obuf_ptr = m->m_data; + sc->sc_dchan.obuf_len = m->m_len; + sc->sc_dchan.free_obuf = freeflag; + } + + iwic_dchan_transmit(sc); + + splx(s); + + return (0); +} + +/*---------------------------------------------------------------------------* + * + *---------------------------------------------------------------------------*/ +static void +dchan_get_mbuf(struct iwic_softc *sc, int len) +{ + sc->sc_dchan.ibuf = i4b_Dgetmbuf(len); + + if (!sc->sc_dchan.ibuf) + panic("dchan_get_mbuf: unable to allocate %d bytes for mbuf!\n", len); + + sc->sc_dchan.ibuf_ptr = sc->sc_dchan.ibuf->m_data; + sc->sc_dchan.ibuf_max_len = sc->sc_dchan.ibuf->m_len; + sc->sc_dchan.ibuf_len = 0; +} + +/*---------------------------------------------------------------------------* + * + *---------------------------------------------------------------------------*/ +static void +dchan_receive(struct iwic_softc *sc, int ista) +{ + if (ista & ISTA_D_RMR) + { + /* Got 64 bytes in FIFO */ + + if (!sc->sc_dchan.ibuf) + { + dchan_get_mbuf(sc, MAX_DFRAME_LEN); + + } + else if ((sc->sc_dchan.ibuf_len + MAX_DFRAME_LEN) > + sc->sc_dchan.ibuf_max_len) + { +/*XXX*/ panic("dchan_receive: not enough space in buffer!\n"); + } + + IWIC_RDDFIFO(sc, sc->sc_dchan.ibuf_ptr, 64); + + sc->sc_dchan.ibuf_ptr += 64; + sc->sc_dchan.ibuf_len += 64; + sc->sc_dchan.rx_count += 64; + } + if (ista & ISTA_D_RME) + { + /* Got end of frame */ + int hi, lo; + int total_frame_len; + int status; + + lo = IWIC_READ(sc, D_RBCL); + hi = IWIC_READ(sc, D_RBCH); + total_frame_len = D_RBC(hi, lo); + lo = lo & 0x3f; + + if (lo == 0) + lo = IWIC_DCHAN_FIFO_LEN; + + if (!sc->sc_dchan.ibuf) + { + dchan_get_mbuf(sc, lo); + } + else if ((sc->sc_dchan.ibuf_len + lo) > + sc->sc_dchan.ibuf_max_len) + { + panic("dchan_receive: buffer not long enough"); + } + + IWIC_RDDFIFO(sc, sc->sc_dchan.ibuf_ptr, lo); + sc->sc_dchan.ibuf_len += lo; + sc->sc_dchan.rx_count += lo; + + status = IWIC_READ(sc, D_RSTA); + + if (status & (D_RSTA_RDOV | D_RSTA_CRCE | D_RSTA_RMB)) + { + NDBGL1(L1_I_ERR, "bad read status 0x%x", status); + } + + sc->sc_dchan.ibuf->m_len = sc->sc_dchan.ibuf_len; + + if(sc->sc_trace & TRACE_D_RX) + { + i4b_trace_hdr_t hdr; + hdr.unit = L0IWICUNIT(sc->sc_unit); + hdr.type = TRC_CH_D; + hdr.dir = FROM_NT; + hdr.count = ++sc->sc_dchan.trace_count; + MICROTIME(hdr.time); + i4b_l1_trace_ind(&hdr, sc->sc_dchan.ibuf->m_len, sc->sc_dchan.ibuf->m_data); + } + + i4b_l1_ph_data_ind(L0IWICUNIT(sc->sc_unit), sc->sc_dchan.ibuf); + + sc->sc_dchan.ibuf = NULL; + } + IWIC_WRITE(sc, D_CMDR, D_CMDR_RACK); +} + +/*---------------------------------------------------------------------------* + * + *---------------------------------------------------------------------------*/ +void +iwic_dchan_transmit(struct iwic_softc *sc) +{ + int cmd; + u_char *ptr; + int len; + + if (!sc->sc_dchan.tx_ready) + return; + + if (!sc->sc_dchan.obuf) + return; + + if (sc->sc_I430state != ST_F7) + return; + + ptr = sc->sc_dchan.obuf_ptr; + len = min(sc->sc_dchan.obuf_len, IWIC_DCHAN_FIFO_LEN); + + if(sc->sc_trace & TRACE_D_TX) + { + i4b_trace_hdr_t hdr; + hdr.unit = L0IWICUNIT(sc->sc_unit); + hdr.type = TRC_CH_D; + hdr.dir = FROM_TE; + hdr.count = ++sc->sc_dchan.trace_count; + MICROTIME(hdr.time); + i4b_l1_trace_ind(&hdr, len, ptr); + } + + IWIC_WRDFIFO(sc, ptr, len); + + sc->sc_dchan.tx_count += len; + + if (len < sc->sc_dchan.obuf_len) + { + sc->sc_dchan.obuf_ptr += len; + sc->sc_dchan.obuf_len -= len; + + cmd = D_CMDR_XMS; + + } + else + { + if (sc->sc_dchan.free_obuf) + i4b_Dfreembuf(sc->sc_dchan.obuf); + + sc->sc_dchan.obuf = NULL; + sc->sc_dchan.obuf_ptr = NULL; + sc->sc_dchan.obuf_len = 0; + + if (sc->sc_dchan.obuf2) + { + sc->sc_dchan.obuf = sc->sc_dchan.obuf2; + sc->sc_dchan.obuf_ptr = sc->sc_dchan.obuf->m_data; + sc->sc_dchan.obuf_len = sc->sc_dchan.obuf->m_len; + sc->sc_dchan.free_obuf = sc->sc_dchan.free_obuf2; + + sc->sc_dchan.obuf2 = NULL; + } + cmd = D_CMDR_XMS | D_CMDR_XME; + } + sc->sc_dchan.tx_ready = 0; + IWIC_WRITE(sc, D_CMDR, cmd); +} + +#ifdef NOTDEF +/*---------------------------------------------------------------------------* + * + *---------------------------------------------------------------------------*/ +static void +output_bytes(char *prefix, u_char * ptr, int len) +{ + char buf[400]; + char tmp[10]; + int i; + + sprintf(buf, "%s bytes ", prefix); + for (i = 0; i < len; i++) + { + if (i != (len - 1)) + sprintf(tmp, "0x%x, ", ptr[i] & 0xff); + else + sprintf(tmp, "0x%x", ptr[i] & 0xff); + strcat(buf, tmp); + } + strcat(buf, "\n"; + printf(buf); +} +#endif + +#endif diff --git a/sys/i4b/layer1/iwic/i4b_iwic_ext.h b/sys/i4b/layer1/iwic/i4b_iwic_ext.h new file mode 100644 index 0000000..7f75797 --- /dev/null +++ b/sys/i4b/layer1/iwic/i4b_iwic_ext.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2000 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_iwic - isdn4bsd Winbond W6692 driver + * ---------------------------------------- + * + * $Id: i4b_iwic_ext.h,v 1.4 2000/06/02 16:14:36 hm Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Fri Jun 2 14:52:10 2000] + * + *---------------------------------------------------------------------------*/ + +#ifndef _I4B_IWIC_EXT_H_ +#define _I4B_IWIC_EXT_H_ + +#include <i4b/include/i4b_l3l4.h> + +void iwic_set_linktab(int unit, int channel, drvr_link_t * dlt); +isdn_link_t *iwic_ret_linktab(int unit, int channel); + +int iwic_ph_data_req(int unit, struct mbuf *m, int freeflag); +int iwic_ph_activate_req(int unit); +int iwic_mph_command_req(int unit, int command, void *parm); + +#endif /* _I4B_IWIC_EXT_H_ */ diff --git a/sys/i4b/layer1/iwic/i4b_iwic_fsm.c b/sys/i4b/layer1/iwic/i4b_iwic_fsm.c new file mode 100644 index 0000000..2737fc6 --- /dev/null +++ b/sys/i4b/layer1/iwic/i4b_iwic_fsm.c @@ -0,0 +1,235 @@ +/* + * Copyright (c) 1999, 2000 Dave Boyce. 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_iwic - isdn4bsd Winbond W6692 driver + * ---------------------------------------- + * + * $Id: i4b_iwic_fsm.c,v 1.4 2000/05/29 15:41:42 hm Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Thu Apr 27 14:56:54 2000] + * + *---------------------------------------------------------------------------*/ + +#include "iwic.h" +#include "opt_i4b.h" +#include "pci.h" + +#if (NIWIC > 0) && (NPCI > 0) + +#include <sys/param.h> +#include <sys/kernel.h> +#include <sys/systm.h> +#include <sys/mbuf.h> +#include <sys/socket.h> +#include <net/if.h> + +#include <machine/clock.h> + +#include <machine/i4b_debug.h> +#include <machine/i4b_ioctl.h> +#include <machine/i4b_trace.h> + +#include <i4b/layer1/i4b_l1.h> + +#include <i4b/include/i4b_global.h> +#include <i4b/include/i4b_l3l4.h> +#include <i4b/include/i4b_mbuf.h> + +#include <i4b/layer1/iwic/i4b_iwic.h> +#include <i4b/layer1/iwic/i4b_w6692.h> + +#if DO_I4B_DEBUG +static char *state_names[] = { + "F3N", + "F3", + "F4", + "F5", + "F6", + "F7", + "F8", + "ILLEGAL", +}; + +static char *event_names[] = { + "PHAR", + "CE", + "T3", + "INFO0", + "RSY", + "INFO2", + "INFO48", + "INFO410", + "DR", + "PU", + "DIS", + "EI", + "ILLEGAL" +}; +#endif + +/*---------------------------------------------------------------------------* + * + *---------------------------------------------------------------------------*/ +static void +F_NULL(struct iwic_softc *sc) +{ + NDBGL1(L1_F_MSG, "FSM function F_NULL executing"); +} + +/*---------------------------------------------------------------------------* + * + *---------------------------------------------------------------------------*/ +static void +F_AR(struct iwic_softc *sc) +{ + NDBGL1(L1_F_MSG, "FSM function F_AR executing"); + IWIC_WRITE(sc, CIX, CIX_ECK); +} + +/*---------------------------------------------------------------------------* + * + *---------------------------------------------------------------------------*/ +static void +F_AR3(struct iwic_softc *sc) +{ + NDBGL1(L1_F_MSG, "FSM function F_AR3 executing"); + IWIC_WRITE(sc, CIX, CIX_AR8); +} + +/*---------------------------------------------------------------------------* + * + *---------------------------------------------------------------------------*/ +static void +F_I0I(struct iwic_softc *sc) +{ + NDBGL1(L1_F_MSG, "FSM function F_IOI executing"); +} + +/*---------------------------------------------------------------------------* + * + *---------------------------------------------------------------------------*/ +static void +F_I0A(struct iwic_softc *sc) +{ + NDBGL1(L1_F_MSG, "FSM function F_IOA executing"); + iwic_dchan_disable(sc); + i4b_l1_ph_deactivate_ind(L0IWICUNIT(sc->sc_unit)); +} + +/*---------------------------------------------------------------------------* + * + *---------------------------------------------------------------------------*/ +static void +F_AI8(struct iwic_softc *sc) +{ + NDBGL1(L1_F_MSG, "FSM function F_AI8 executing"); + iwic_dchan_transmit(sc); + i4b_l1_ph_activate_ind(L0IWICUNIT(sc->sc_unit)); +} + +/*---------------------------------------------------------------------------* + * + *---------------------------------------------------------------------------*/ +static void +F_AI10(struct iwic_softc *sc) +{ + NDBGL1(L1_F_MSG, "FSM function F_AI10 executing"); + iwic_dchan_transmit(sc); + i4b_l1_ph_activate_ind(L0IWICUNIT(sc->sc_unit)); +} + +/*---------------------------------------------------------------------------* + * + *---------------------------------------------------------------------------*/ +struct iwic_state_tab { + void (*func) (struct iwic_softc *sc); /* function to execute */ + int newstate; /* next state */ +} iwic_state_tab[N_EVENTS][N_STATES] = { + +/* STATE: F3N F3 F4 F5 F6 F7 F8 ILLEGAL STATE */ +/* ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ */ +/* EV_PHAR */ {{F_AR, ST_F3 }, {F_AR3, ST_F4 }, {F_NULL, ST_F4 }, {F_NULL, ST_F5 }, {F_NULL, ST_F6 }, {F_NULL, ST_F7 }, {F_NULL, ST_F8 }, {F_NULL, ST_ILL }}, +/* EV_CE */ {{F_NULL, ST_F3 }, {F_AR3, ST_F4 }, {F_NULL, ST_F4 }, {F_NULL, ST_F4 }, {F_NULL, ST_F4 }, {F_NULL, ST_F4 }, {F_NULL, ST_F4 }, {F_NULL, ST_ILL }}, +/* EV_T3 */ {{F_NULL, ST_F3N }, {F_NULL, ST_F3 }, {F_NULL, ST_F3 }, {F_NULL, ST_F3 }, {F_NULL, ST_F3 }, {F_NULL, ST_F7 }, {F_NULL, ST_F8 }, {F_NULL, ST_ILL }}, +/* EV_INFO0 */ {{F_I0I, ST_F3 }, {F_I0I, ST_F3 }, {F_I0I, ST_F3 }, {F_I0I, ST_F3 }, {F_I0A, ST_F3 }, {F_I0A, ST_F3 }, {F_I0A, ST_F3 }, {F_NULL, ST_ILL }}, +/* EV_RSY */ {{F_NULL, ST_F3 }, {F_NULL, ST_F5 }, {F_NULL, ST_F5 }, {F_NULL, ST_F5 }, {F_NULL, ST_F8 }, {F_NULL, ST_F8 }, {F_NULL, ST_F8 }, {F_NULL, ST_ILL }}, +/* EV_INFO2 */ {{F_NULL, ST_F6 }, {F_NULL, ST_F6 }, {F_NULL, ST_F6 }, {F_NULL, ST_F6 }, {F_NULL, ST_F6 }, {F_NULL, ST_F6 }, {F_NULL, ST_F6 }, {F_NULL, ST_ILL }}, +/* EV_INFO48 */ {{F_AI8 , ST_F7 }, {F_AI8, ST_F7 }, {F_AI8, ST_F7 }, {F_AI8, ST_F7 }, {F_AI8, ST_F7 }, {F_AI8, ST_F7 }, {F_AI8, ST_F7 }, {F_NULL, ST_ILL }}, +/* EV_INFO410*/ {{F_AI10, ST_F7 }, {F_AI10, ST_F7 }, {F_AI10, ST_F7 }, {F_AI10, ST_F7 }, {F_AI10, ST_F7 }, {F_AI10, ST_F7 }, {F_AI10, ST_F7 }, {F_NULL, ST_ILL }}, +/* EV_DR */ {{F_NULL, ST_F3 }, {F_NULL, ST_F3 }, {F_NULL, ST_F4 }, {F_NULL, ST_F5 }, {F_NULL, ST_F6 }, {F_NULL, ST_F7 }, {F_NULL, ST_F8 }, {F_NULL, ST_ILL }}, +/* EV_PU */ {{F_NULL, ST_F3 }, {F_NULL, ST_F3 }, {F_NULL, ST_F4 }, {F_NULL, ST_F5 }, {F_NULL, ST_F6 }, {F_NULL, ST_F7 }, {F_NULL, ST_F8 }, {F_NULL, ST_ILL }}, +/* EV_DIS */ {{F_NULL, ST_F3N }, {F_NULL, ST_F3N }, {F_NULL, ST_F3N }, {F_NULL, ST_F3N }, {F_NULL, ST_F3N }, {F_I0A, ST_F3N }, {F_I0A, ST_F3N }, {F_NULL, ST_ILL }}, +/* EV_EI */ {{F_NULL, ST_F3 }, {F_NULL, ST_F3 }, {F_NULL, ST_F3 }, {F_NULL, ST_F3 }, {F_NULL, ST_F3 }, {F_NULL, ST_F3 }, {F_NULL, ST_F3 }, {F_NULL, ST_ILL }}, +/* EV_ILL */ {{F_NULL, ST_ILL }, {F_NULL, ST_ILL }, {F_NULL, ST_ILL }, {F_NULL, ST_ILL }, {F_NULL, ST_ILL }, {F_NULL, ST_ILL }, {F_NULL, ST_ILL }, {F_NULL, ST_ILL }}, +}; + +/*---------------------------------------------------------------------------* + * + *---------------------------------------------------------------------------*/ +void +iwic_next_state(struct iwic_softc *sc, int event) +{ + int currstate, newstate; + + NDBGL1(L1_F_MSG, "event %s", event_names[event]); + + if (event >= N_EVENTS) + { + printf("iwic_next_state: event >= N_EVENTS\n"); + return; + } + + currstate = sc->sc_I430state; + + newstate = iwic_state_tab[event][currstate].newstate; + if (newstate >= N_STATES) + { + printf("iwic_next_state: newstate >= N_STATES\n"); + return; + } + + NDBGL1(L1_F_MSG, "state %s -> %s", + state_names[currstate], state_names[newstate]); + + sc->sc_I430state = newstate; + + (*iwic_state_tab[event][currstate].func) (sc); +} + +#if DO_I4B_DEBUG +/*---------------------------------------------------------------------------* + * return pointer to current state description + *---------------------------------------------------------------------------*/ +char * +iwic_printstate(struct iwic_softc *sc) +{ + return((char *)state_names[sc->sc_I430state]); +} +#endif + +#endif diff --git a/sys/i4b/layer1/iwic/i4b_iwic_l1if.c b/sys/i4b/layer1/iwic/i4b_iwic_l1if.c new file mode 100644 index 0000000..e0208cc --- /dev/null +++ b/sys/i4b/layer1/iwic/i4b_iwic_l1if.c @@ -0,0 +1,166 @@ +/* + * Copyright (c) 1999, 2000 Dave Boyce. 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_iwic - isdn4bsd Winbond W6692 driver + * ---------------------------------------- + * + * $Id: i4b_iwic_l1if.c,v 1.3 2000/06/02 16:14:36 hm Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Fri Jun 2 14:52:39 2000] + * + *---------------------------------------------------------------------------*/ + +#include "iwic.h" +#include "opt_i4b.h" +#include "pci.h" + +#if (NIWIC > 0) && (NPCI > 0) + +#include <sys/param.h> +#include <sys/kernel.h> +#include <sys/systm.h> +#include <sys/mbuf.h> +#include <sys/socket.h> +#include <net/if.h> + +#include <machine/clock.h> + +#include <machine/bus.h> +#include <machine/resource.h> +#include <sys/bus.h> +#include <sys/rman.h> + +#include <pci/pcireg.h> +#include <pci/pcivar.h> + +#include <machine/i4b_debug.h> +#include <machine/i4b_ioctl.h> +#include <machine/i4b_trace.h> + +#include <i4b/include/i4b_global.h> +#include <i4b/include/i4b_l3l4.h> +#include <i4b/include/i4b_mbuf.h> + +#include <i4b/layer1/i4b_l1.h> + +#include <i4b/layer1/iwic/i4b_iwic.h> +#include <i4b/layer1/iwic/i4b_iwic_ext.h> +#include <i4b/layer1/iwic/i4b_w6692.h> + +/* jump table for multiplex routines */ + +struct i4b_l1mux_func iwic_l1mux_func = { + iwic_ret_linktab, + iwic_set_linktab, + iwic_mph_command_req, + iwic_ph_data_req, + iwic_ph_activate_req, +}; + +/*---------------------------------------------------------------------------* + * + *---------------------------------------------------------------------------*/ +int +iwic_ph_data_req(int unit, struct mbuf *m, int freeflag) +{ + struct iwic_softc *sc = iwic_find_sc(unit); + + return iwic_dchan_data_req(sc, m, freeflag); +} + +/*---------------------------------------------------------------------------* + * + *---------------------------------------------------------------------------*/ +int +iwic_ph_activate_req(int unit) +{ + struct iwic_softc *sc = iwic_find_sc(unit); + + iwic_next_state(sc, EV_PHAR); + + return 0; +} + +/*---------------------------------------------------------------------------* + * + *---------------------------------------------------------------------------*/ +int +iwic_mph_command_req(int unit, int command, void *parm) +{ + struct iwic_softc *sc = iwic_find_sc(unit); + + switch (command) + { + case CMR_DOPEN: /* Daemon running */ + NDBGL1(L1_PRIM, "CMR_DOPEN"); + sc->enabled = TRUE; + break; + + case CMR_DCLOSE: /* Daemon not running */ + NDBGL1(L1_PRIM, "CMR_DCLOSE"); + sc->enabled = FALSE; + break; + + case CMR_SETTRACE: + NDBGL1(L1_PRIM, "CMR_SETTRACE, parm = %d", (unsigned int)parm); + sc->sc_trace = (unsigned int)parm; + break; + + default: + NDBGL1(L1_PRIM, "unknown command = %d", command); + break; + } + + return 0; +} + +/*---------------------------------------------------------------------------* + * + *---------------------------------------------------------------------------*/ +isdn_link_t * +iwic_ret_linktab(int unit, int channel) +{ + struct iwic_softc *sc = iwic_find_sc(unit); + struct iwic_bchan *bchan = &sc->sc_bchan[channel]; + + return &bchan->iwic_isdn_linktab; +} + +/*---------------------------------------------------------------------------* + * + *---------------------------------------------------------------------------*/ +void +iwic_set_linktab (int unit, int channel, drvr_link_t *dlt) +{ + struct iwic_softc *sc = iwic_find_sc(unit); + struct iwic_bchan *bchan = &sc->sc_bchan[channel]; + + bchan->iwic_drvr_linktab = dlt; +} + +#endif diff --git a/sys/i4b/layer1/iwic/i4b_iwic_pci.c b/sys/i4b/layer1/iwic/i4b_iwic_pci.c new file mode 100644 index 0000000..e503b2f --- /dev/null +++ b/sys/i4b/layer1/iwic/i4b_iwic_pci.c @@ -0,0 +1,317 @@ +/* + * Copyright (c) 1999, 2000 Dave Boyce. 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_iwic - isdn4bsd Winbond W6692 driver + * ---------------------------------------- + * + * $Id: i4b_iwic_pci.c,v 1.14 2000/09/04 09:08:45 hm Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Mon Sep 4 09:49:03 2000] + * + *---------------------------------------------------------------------------*/ + +#include "iwic.h" +#include "opt_i4b.h" +#include "pci.h" + +#if (NIWIC > 0) && (NPCI > 0) + +#include <sys/param.h> +#include <sys/kernel.h> +#include <sys/systm.h> +#include <sys/mbuf.h> +#include <sys/socket.h> +#include <net/if.h> + +#include <machine/clock.h> + +#include <machine/bus.h> +#include <machine/resource.h> +#include <sys/bus.h> +#include <sys/rman.h> + +#include <pci/pcireg.h> +#include <pci/pcivar.h> + +#include <machine/i4b_debug.h> +#include <machine/i4b_ioctl.h> +#include <machine/i4b_trace.h> + +#include <i4b/include/i4b_global.h> +#include <i4b/include/i4b_l3l4.h> +#include <i4b/include/i4b_mbuf.h> + +#include <i4b/layer1/i4b_l1.h> + +#include <i4b/layer1/iwic/i4b_iwic.h> +#include <i4b/layer1/iwic/i4b_iwic_ext.h> +#include <i4b/layer1/iwic/i4b_w6692.h> + +extern struct i4b_l1mux_func iwic_l1mux_func; + +/* Winbond PCI Configuration Space */ + +#define BASEREG0_MAPOFF 0x00 +#define BASEREG1_MAPOFF 0x04 + +#define BADDR0 (PCIR_MAPS + BASEREG0_MAPOFF) +#define BADDR1 (PCIR_MAPS + BASEREG1_MAPOFF) + + +static void iwic_pci_intr(struct iwic_softc *sc); +static int iwic_pci_probe(device_t dev); +static int iwic_pci_attach(device_t dev); + +static device_method_t iwic_pci_methods[] = +{ + DEVMETHOD(device_probe, iwic_pci_probe), + DEVMETHOD(device_attach, iwic_pci_attach), + { 0, 0 } +}; + +static driver_t iwic_pci_driver = +{ + "iwic", + iwic_pci_methods, + 0 +}; + +static devclass_t iwic_pci_devclass; + +DRIVER_MODULE(iwic, pci, iwic_pci_driver, iwic_pci_devclass, 0, 0); + +#define IWIC_MAXUNIT 4 + +struct iwic_softc iwic_sc[IWIC_MAXUNIT]; + +/*---------------------------------------------------------------------------* + * PCI ID list for ASUSCOM card got from Asuscom in March 2000: + * + * Vendor ID: 0675 Device ID: 1702 + * Vendor ID: 0675 Device ID: 1703 + * Vendor ID: 0675 Device ID: 1707 + * Vendor ID: 10CF Device ID: 105E + * Vendor ID: 1043 Device ID: 0675 SubVendor: 144F SubDevice ID: 2000 + * Vendor ID: 1043 Device ID: 0675 SubVendor: 144F SubDevice ID: 1702 + * Vendor ID: 1043 Device ID: 0675 SubVendor: 144F SubDevice ID: 1707 + * Vendor ID: 1043 Device ID: 0675 SubVendor: 1043 SubDevice ID: 1702 + * Vendor ID: 1043 Device ID: 0675 SubVendor: 1043 SubDevice ID: 1707 + * Vendor ID: 1050 Device ID: 6692 SubVendor: 0675 SubDevice ID: 1702 + *---------------------------------------------------------------------------*/ + +static struct winids { + u_int32_t type; + int sv; + int sd; + const char *desc; +} win_ids[] = { + { 0x66921050, -1, -1, "Generic Winbond W6692 ISDN PCI (0x66921050)" }, + { 0x17020675, -1, -1, "ASUSCOM P-IN100-ST-D (Winbond W6692, 0x17020675)" }, + { 0x17030675, -1, -1, "ASUSCOM P-IN100-ST-D (Winbond W6692, 0x17030675)" }, + { 0x17070675, -1, -1, "ASUSCOM P-IN100-ST-D (Winbond W6692, 0x17070675)" }, + { 0x105e10cf, -1, -1, "ASUSCOM P-IN100-ST-D (Winbond W6692, 0x105e10cf)" }, + { 0x06751043, 0x144F, 0x2000, "ASUSCOM P-IN100-ST-D (Winbond W6692, 0x06751043)" }, + { 0x06751043, 0x144F, 0x1702, "ASUSCOM P-IN100-ST-D (Winbond W6692, 0x06751043)" }, + { 0x06751043, 0x144F, 0x1707, "ASUSCOM P-IN100-ST-D (Winbond W6692, 0x06751043)" }, + { 0x06751043, 0x1443, 0x1702, "ASUSCOM P-IN100-ST-D (Winbond W6692, 0x06751043)" }, + { 0x06751043, 0x1443, 0x1707, "ASUSCOM P-IN100-ST-D (Winbond W6692, 0x06751043)" }, + { 0x06751043, 0x144F, 0x2000, "ASUSCOM P-IN100-ST-D (Winbond W6692, 0x06751043)" }, + { 0x06751043, 0x144F, 0x2000, "ASUSCOM P-IN100-ST-D (Winbond W6692, 0x06751043)" }, + { 0x06751043, 0x144F, 0x2000, "ASUSCOM P-IN100-ST-D (Winbond W6692, 0x06751043)" }, + { 0x00000000, 0, 0, NULL } +}; + +/*---------------------------------------------------------------------------* + * iwic PCI probe + *---------------------------------------------------------------------------*/ +static int +iwic_pci_probe(device_t dev) +{ + u_int32_t type = pci_get_devid(dev); + u_int32_t sv = pci_get_subvendor(dev); + u_int32_t sd = pci_get_subdevice(dev); + + struct winids *wip = win_ids; + + while(wip->type) + { + if(wip->type == type) + { + if(((wip->sv == -1) && (wip->sd == -1)) || + ((wip->sv == sv) && (wip->sd == sd))) + break; + } + ++wip; + } + + if(wip->desc) + { + if(bootverbose) + { + printf("iwic_pci_probe: vendor = 0x%x, device = 0x%x\n", pci_get_vendor(dev), pci_get_device(dev)); + printf("iwic_pci_probe: subvendor = 0x%x, subdevice = 0x%x\n", sv, sd); + } + device_set_desc(dev, wip->desc); + return(0); + } + else + { + return(ENXIO); + } +} + +/*---------------------------------------------------------------------------* + * PCI attach + *---------------------------------------------------------------------------*/ +static int +iwic_pci_attach(device_t dev) +{ + unsigned short iobase; + struct iwic_softc *sc; + void *ih = 0; + int unit = device_get_unit(dev); + struct iwic_bchan *bchan; + + /* check max unit range */ + + if(unit >= IWIC_MAXUNIT) + { + printf("iwic%d: Error, unit %d >= IWIC_MAXUNIT!\n", unit, unit); + return(ENXIO); + } + + sc = iwic_find_sc(unit); /* get softc */ + + sc->sc_unit = unit; + + /* use the i/o mapped base address */ + + sc->sc_resources.io_rid[0] = BADDR1; + + if(!(sc->sc_resources.io_base[0] = + bus_alloc_resource(dev, SYS_RES_IOPORT, + &sc->sc_resources.io_rid[0], + 0UL, ~0UL, 1, RF_ACTIVE))) + { + printf("iwic%d: Couldn't alloc io port!\n", unit); + return(ENXIO); + } + + iobase = rman_get_start(sc->sc_resources.io_base[0]); + + if(!(sc->sc_resources.irq = + bus_alloc_resource(dev, SYS_RES_IRQ, + &sc->sc_resources.irq_rid, + 0UL, ~0UL, 1, RF_SHAREABLE|RF_ACTIVE))) + { + printf("iwic%d: Couldn't alloc irq!\n",unit); + return(ENXIO); + } + + /* setup card type */ + + sc->sc_cardtyp = CARD_TYPEP_WINB6692; + sc->sc_iobase = (u_int32_t) iobase; + sc->sc_trace = TRACE_OFF; + sc->sc_I430state = ST_F3N; /* Deactivated */ + sc->enabled = FALSE; + + if(bus_setup_intr(dev, sc->sc_resources.irq, INTR_TYPE_NET, + (void(*)(void*))iwic_pci_intr, + sc, &ih)) + { + printf("iwic%d: Couldn't set up irq!\n", unit); + return(ENXIO); + } + + /* disable interrupts */ + IWIC_WRITE(sc, IMASK, 0xff); + + iwic_dchan_init(sc); + + bchan = &sc->sc_bchan[IWIC_BCH_A]; + bchan->unit = unit; + bchan->offset = B1_CHAN_OFFSET; + bchan->channel = IWIC_BCH_A; + bchan->state = ST_IDLE; + + iwic_bchannel_setup(unit, IWIC_BCH_A, BPROT_NONE, 0); + + bchan = &sc->sc_bchan[IWIC_BCH_B]; + bchan->unit = unit; + bchan->offset = B2_CHAN_OFFSET; + bchan->channel = IWIC_BCH_B; + bchan->state = ST_IDLE; + + iwic_bchannel_setup(unit, IWIC_BCH_B, BPROT_NONE, 0); + + iwic_init_linktab(sc); + + i4b_l1_mph_status_ind(L0IWICUNIT(sc->sc_unit), STI_ATTACH, sc->sc_cardtyp, &iwic_l1mux_func); + + IWIC_READ(sc, ISTA); + + /* Enable interrupts */ + IWIC_WRITE(sc, IMASK, IMASK_XINT0 | IMASK_XINT1); + + return(0); +} + +/*---------------------------------------------------------------------------* + * IRQ handler + *---------------------------------------------------------------------------*/ +static void +iwic_pci_intr(struct iwic_softc *sc) +{ + while (1) + { + int irq_stat = IWIC_READ(sc, ISTA); + + if (irq_stat == 0) + break; + + if (irq_stat & (ISTA_D_RME | ISTA_D_RMR | ISTA_D_XFR)) + { + iwic_dchan_xfer_irq(sc, irq_stat); + } + if (irq_stat & ISTA_D_EXI) + { + iwic_dchan_xirq(sc); + } + if (irq_stat & ISTA_B1_EXI) + { + iwic_bchan_xirq(sc, 0); + } + if (irq_stat & ISTA_B2_EXI) + { + iwic_bchan_xirq(sc, 1); + } + } +} + +#endif diff --git a/sys/i4b/layer1/iwic/i4b_w6692.h b/sys/i4b/layer1/iwic/i4b_w6692.h new file mode 100644 index 0000000..3fb1d15 --- /dev/null +++ b/sys/i4b/layer1/iwic/i4b_w6692.h @@ -0,0 +1,264 @@ +/* + * Copyright (c) 1999, 2000 Dave Boyce. 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_iwic - isdn4bsd Winbond W6692 driver + * ---------------------------------------- + * + * $Id: i4b_w6692.h,v 1.1 2000/03/07 14:12:26 hm Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Mon Mar 6 12:19:55 2000] + * + *---------------------------------------------------------------------------*/ + +#ifndef _I4B_W6692_H_ +#define _I4B_W6692_H_ + +#define IWIC_BCH_A 0 /* channel A */ +#define IWIC_BCH_B 1 /* channel B */ + +/*---------------------------------------------------------------------------* + * FIFO depths + *---------------------------------------------------------------------------*/ +#define IWIC_DCHAN_FIFO_LEN 64 +#define IWIC_BCHAN_FIFO_LEN 64 + +/*---------------------------------------------------------------------------* + * D-Channel register offsets + *---------------------------------------------------------------------------*/ +#define D_RFIFO 0x00 /* D channel receive FIFO */ +#define D_XFIFO 0x04 /* D channel transmit FIFO */ +#define D_CMDR 0x08 /* D channel command register */ +#define D_MODE 0x0c /* D channel mode control */ +#define D_TIMR 0x10 /* D channel timer control */ +#define D_EXIR 0x1c /* D channel extended interrupt */ +#define D_EXIM 0x20 /* D channel extended interrupt mask */ +#define D_STAR 0x24 /* D channel status register */ +#define D_RSTA 0x28 /* D channel receive status */ +#define D_SAM 0x2c /* D channel address mask 1 */ +#define D_SAP1 0x30 /* D channel individual SAPI 1 */ +#define D_SAP2 0x34 /* D channel individual SAPI 2 */ +#define D_TAM 0x38 /* D channel address mask 2 */ +#define D_TEI1 0x3c /* D channel individual TEI 1 */ +#define D_TEI2 0x40 /* D channel individual TEI 2 */ +#define D_RBCH 0x44 /* D channel receive frame byte count high */ +#define D_RBCL 0x48 /* D channel receive frame byte count low */ +#define D_CTL 0x54 /* D channel control register */ + +/*---------------------------------------------------------------------------* + * B-channel base offsets + *---------------------------------------------------------------------------*/ +#define B1_CHAN_OFFSET 0x80 /* B1 channel offset */ +#define B2_CHAN_OFFSET 0xc0 /* B2 channel offset */ + +/*---------------------------------------------------------------------------* + * B-channel register offsets, from base + *---------------------------------------------------------------------------*/ +#define B_RFIFO 0x00 /* B channel receive FIFO */ +#define B_XFIFO 0x04 /* B channel transmit FIFO */ +#define B_CMDR 0x08 /* B channel command register */ +#define B_MODE 0x0c /* B channel mode control */ +#define B_EXIR 0x10 /* B channel extended interrupt */ +#define B_EXIM 0x14 /* B channel extended interrupt mask */ +#define B_STAR 0x18 /* B channel status register */ +#define B_ADM1 0x1c /* B channel address mask 1 */ +#define B_ADM2 0x20 /* B channel address mask 2 */ +#define B_ADR1 0x24 /* B channel address 1 */ +#define B_ADR2 0x28 /* B channel address 2 */ +#define B_RBCL 0x2c /* B channel receive frame byte count high */ +#define B_RBCH 0x30 /* B channel receive frame byte count low */ + +/*---------------------------------------------------------------------------* + * Remaining control register offsets. + *---------------------------------------------------------------------------*/ +#define ISTA 0x14 /* Interrupt status register */ +#define IMASK 0x18 /* Interrupt mask register */ +#define TIMR2 0x4c /* Timer 2 */ +#define L1_RC 0x50 /* GCI layer 1 ready code */ +#define CIR 0x58 /* Command/Indication receive */ +#define CIX 0x5c /* Command/Indication transmit */ +#define SQR 0x60 /* S/Q channel receive register */ +#define SQX 0x64 /* S/Q channel transmit register */ +#define PCTL 0x68 /* Peripheral control register */ +#define MOR 0x6c /* Monitor receive channel */ +#define MOX 0x70 /* Monitor transmit channel */ +#define MOSR 0x74 /* Monitor channel status register */ +#define MOCR 0x78 /* Monitor channel control register */ +#define GCR 0x7c /* GCI mode control register */ +#define XADDR 0xf4 /* Peripheral address register */ +#define XDATA 0xf8 /* Peripheral data register */ +#define EPCTL 0xfc /* Serial EEPROM control */ + +/*---------------------------------------------------------------------------* + * register bits + *---------------------------------------------------------------------------*/ +#define D_CMDR_RACK 0x80 +#define D_CMDR_RRST 0x40 +#define D_CMDR_STT 0x10 +#define D_CMDR_XMS 0x08 +#define D_CMDR_XME 0x02 +#define D_CMDR_XRST 0x01 + +#define D_MODE_MMS 0x80 +#define D_MODE_RACT 0x40 +#define D_MODE_TMS 0x10 +#define D_MODE_TEE 0x08 +#define D_MODE_MFD 0x04 +#define D_MODE_DLP 0x02 +#define D_MODE_RLP 0x01 + +#define D_TIMR_CNT(i) (((i) >> 5) & 0x07) +#define D_TIMR_VAL(i) ((i) & 0x1f) + +#define ISTA_D_RMR 0x80 +#define ISTA_D_RME 0x40 +#define ISTA_D_XFR 0x20 +#define ISTA_XINT1 0x10 +#define ISTA_XINT0 0x08 +#define ISTA_D_EXI 0x04 +#define ISTA_B1_EXI 0x02 +#define ISTA_B2_EXI 0x01 + +#define IMASK_D_RMR 0x80 +#define IMASK_D_RME 0x40 +#define IMASK_D_XFR 0x20 +#define IMASK_XINT1 0x10 +#define IMASK_XINT0 0x08 +#define IMASK_D_EXI 0x04 +#define IMASK_B1_EXI 0x02 +#define IMASK_B2_EXI 0x01 + +#define D_EXIR_RDOV 0x80 +#define D_EXIR_XDUN 0x40 +#define D_EXIR_XCOL 0x20 +#define D_EXIR_TIN2 0x10 +#define D_EXIR_MOC 0x08 +#define D_EXIR_ISC 0x04 +#define D_EXIR_TEXP 0x02 +#define D_EXIR_WEXP 0x01 + +#define D_EXIM_RDOV 0x80 +#define D_EXIM_XDUN 0x40 +#define D_EXIM_XCOL 0x20 +#define D_EXIM_TIM2 0x10 +#define D_EXIM_MOC 0x08 +#define D_EXIM_ISC 0x04 +#define D_EXIM_TEXP 0x02 +#define D_EXIM_WEXP 0x01 + +#define D_STAR_XDOW 0x80 +#define D_STAR_XBZ 0x20 +#define D_STAR_DRDY 0x10 + +#define D_RSTA_RDOV 0x40 +#define D_RSTA_CRCE 0x20 +#define D_RSTA_RMB 0x10 + +#define D_RBCH_VN(i) (((i) >> 6) & 0x03) +#define D_RBCH_LOV 0x20 +#define D_RBC(h,l) (((((h) & 0x1f)) << 8) + (l)) + +#define D_TIMR2_TMD 0x80 +#define D_TIMR2_TBCN(i) ((i) & 0x3f) + +#define L1_RC_RC(i) ((i) & 0x0f) + +#define D_CTL_WTT(i) (((i) > 6) & 0x03) +#define D_CTL_SRST 0x20 +#define D_CTL_TPS 0x04 +#define D_CTL_OPS(i) ((i) & 0x03) + +#define CIR_SCC 0x80 +#define CIR_ICC 0x40 +#define CIR_CODR(i) ((i) & 0x0f) + +#define CIX_ECK 0x00 +#define CIX_RST 0x01 +#define CIX_SCP 0x04 +#define CIX_SSP 0x02 +#define CIX_AR8 0x08 +#define CIX_AR10 0x09 +#define CIX_EAL 0x0a +#define CIX_DRC 0x0f + +#define CIR_CE 0x07 +#define CIR_DRD 0x00 +#define CIR_LD 0x04 +#define CIR_ARD 0x08 +#define CIR_TI 0x0a +#define CIR_ATI 0x0b +#define CIR_AI8 0x0c +#define CIR_AI10 0x0d +#define CIR_CD 0x0f + +#define SQR_XIND1 0x80 +#define SQR_XIND0 0x40 +#define SQR_MSYN 0x20 +#define SQR_SCIE 0x10 +#define SQR_S(i) ((i) & 0x0f) + +#define SQX_SCIE 0x10 +#define SQX_Q(i) ((i) & 0x0f) + + +#define B_CMDR_RACK 0x80 +#define B_CMDR_RRST 0x40 +#define B_CMDR_RACT 0x20 +#define B_CMDR_XMS 0x04 +#define B_CMDR_XME 0x02 +#define B_CMDR_XRST 0x01 + +#define B_MODE_MMS 0x80 +#define B_MODE_ITF 0x40 +#define B_MODE_EPCM 0x20 +#define B_MODE_BSW1 0x10 +#define B_MODE_BSW0 0x08 +#define B_MODE_SW56 0x04 +#define B_MODE_FTS1 0x02 +#define B_MODE_FTS0 0x01 + +#define B_EXIR_RMR 0x40 +#define B_EXIR_RME 0x20 +#define B_EXIR_RDOV 0x10 +#define B_EXIR_XFR 0x02 +#define B_EXIR_XDUN 0x01 + +#define B_EXIM_RMR 0x40 +#define B_EXIM_RME 0x20 +#define B_EXIM_RDOV 0x10 +#define B_EXIM_XFR 0x02 +#define B_EXIM_XDUN 0x01 + +#define B_STAR_RDOV 0x40 +#define B_STAR_CRCE 0x20 +#define B_STAR_RMB 0x10 +#define B_STAR_XDOW 0x04 +#define B_STAR_XBZ 0x01 + +#define B_RBC(h,l) (((((h) & 0x1f)) << 8) + (l)) + +#endif /* _I4B_W6692_H_ */ diff --git a/sys/i4b/layer1/pci_isic.c b/sys/i4b/layer1/pci_isic.c deleted file mode 100644 index a339c2a..0000000 --- a/sys/i4b/layer1/pci_isic.c +++ /dev/null @@ -1,339 +0,0 @@ -/* - * 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 - * 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.c - pcmcia bus frontend for i4b_isic driver - * ------------------------------------------------------- - * - * $FreeBSD$ - * - * last edit-date: [Wed Mar 10 07:22:08 1999] - * - * -mh original implementation - * -mh added support for Fritz! PCI card - * - *---------------------------------------------------------------------------*/ - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/errno.h> -#include <sys/syslog.h> -#include <sys/device.h> -#include <sys/socket.h> -#include <net/if.h> -#include <sys/systm.h> -#include <sys/malloc.h> - -#include <machine/cpu.h> -#include <machine/intr.h> -#include <machine/bus.h> - - -#include <machine/bus.h> -#include <machine/intr.h> -#include <dev/pci/pcireg.h> -#include <dev/pci/pcivar.h> -#include <dev/pci/pcidevs.h> - -#ifdef __FreeBSD__ -#include <machine/i4b_ioctl.h> -#else -#include <i4b/i4b_ioctl.h> -#endif - -#include <i4b/layer1/i4b_l1.h> -#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> - -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)); - -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 -}; - - -static const struct isic_pci_product { - pci_vendor_id_t npp_vendor; - pci_product_id_t npp_product; - int cardtype; - const char * name; - 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[] = { - -#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, /* card specific initialization */ - isic_pciattach /* generic setup for ISAC/HSCX or IPAC boards */ - }, -#endif - -#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) - struct pci_attach_args *pa; -{ - const struct isic_pci_product * pp = NULL; - - for (pp = isic_pci_products; pp->npp_vendor; pp++) - if (PCI_VENDOR(pa->pa_id) == pp->npp_vendor && - PCI_PRODUCT(pa->pa_id) == pp->npp_product) - return pp; - - return NULL; -} - -/* - * Match card - */ -static int -pci_isic_match(parent, match, aux) - struct device *parent; - struct cfdata *match; - void *aux; -{ - struct pci_attach_args *pa = aux; - - if (!find_matching_card(pa)) - return 0; - - return 1; -} - -/* - * Attach the card - */ -static void -pci_isic_attach(parent, self, aux) - struct device *parent, *self; - void *aux; -{ - struct pci_isic_softc *psc = (void*) self; - struct isic_softc *sc = &psc->sc_isic; - struct pci_attach_args *pa = aux; - const struct isic_pci_product * prod; - - /* Redo probe */ - prod = find_matching_card(pa); - if (prod == NULL) return; /* oops - not found?!? */ - - sc->sc_unit = sc->sc_dev.dv_unit; - printf(": %s\n", prod->name); - - /* card initilization and sc setup */ - prod->attach(psc, pa); - - /* generic setup, if needed for this card */ - if (prod->pciattach) prod->pciattach(psc, pa); -} - -/*---------------------------------------------------------------------------* - * isic - pci device driver attach routine - *---------------------------------------------------------------------------*/ -static void -isic_pciattach(psc, pa) - 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; - - static char *ISACversion[] = { - "2085 Version A1/A2 or 2086/2186 Version 1.1", - "2085 Version B1", - "2085 Version B2", - "2085 Version V2.3 (B3)", - "Unknown Version" - }; - - static char *HSCXversion[] = { - "82525 Version A1", - "Unknown (0x01)", - "82525 Version A2", - "Unknown (0x03)", - "82525 Version A3", - "82525 or 21525 Version 2.1", - "Unknown Version" - }; - - isic_sc[sc->sc_unit] = sc; /* XXX - hack! */ - - sc->sc_isac_version = 0; - sc->sc_hscx_version = 0; - - if(sc->sc_ipac) - { - u_int ret = IPAC_READ(IPAC_ID); - - switch(ret) - { - case 0x01: - printf("%s: IPAC PSB2115 Version 1.1\n", sc->sc_dev.dv_xname); - break; - - default: - printf("%s: Error, IPAC version %d unknown!\n", - sc->sc_dev.dv_xname, ret); - return; - } - } - else - { - 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: - printf("%s: ISAC %s (IOM-%c)\n", - sc->sc_dev.dv_xname, - ISACversion[sc->sc_isac_version], - sc->sc_bustyp == BUS_TYPE_IOM1 ? '1' : '2'); - break; - - default: - printf("%s: Error, ISAC version %d unknown!\n", - sc->sc_dev.dv_xname, sc->sc_isac_version); - return; - } - - 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: - printf("%s: HSCX %s\n", - sc->sc_dev.dv_xname, - HSCXversion[sc->sc_hscx_version]); - break; - - default: - printf("%s: Error, HSCX version %d unknown!\n", - sc->sc_dev.dv_xname, sc->sc_hscx_version); - return; - } - } - - /* ISAC setup */ - - isic_isac_init(sc); - - /* HSCX setup */ - - isic_bchannel_setup(sc->sc_unit, HSCX_CH_A, BPROT_NONE, 0); - - isic_bchannel_setup(sc->sc_unit, HSCX_CH_B, BPROT_NONE, 0); - - /* setup linktab */ - - isic_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); - - - /* 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 deleted file mode 100644 index a19025c..0000000 --- a/sys/i4b/layer1/pci_isic.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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 - * ------------------------------------------------- - * - * $FreeBSD$ - * - * 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 deleted file mode 100644 index d4e0f8e..0000000 --- a/sys/i4b/layer1/pcmcia_isic.c +++ /dev/null @@ -1,358 +0,0 @@ -/* - * Copyright (c) 1998 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. - * - *--------------------------------------------------------------------------- - * - * pcmcia_isic.c - pcmcia bus frontend for i4b_isic driver - * ------------------------------------------------------- - * - * $FreeBSD$ - * - * last edit-date: [Tue Apr 20 14:09:16 1999] - * - * -mh original implementation - * - *---------------------------------------------------------------------------*/ - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/errno.h> -#include <sys/syslog.h> -#include <sys/device.h> -#include <sys/socket.h> -#include <net/if.h> -#include <sys/systm.h> -#include <sys/malloc.h> - -#include <machine/cpu.h> -#include <machine/intr.h> -#include <machine/bus.h> - -#include <dev/pcmcia/pcmciareg.h> -#include <dev/pcmcia/pcmciavar.h> -#include <dev/pcmcia/pcmciadevs.h> - -#ifdef __FreeBSD__ -#include <machine/i4b_ioctl.h> -#include <machine/i4b_trace.h> -#else -#include <i4b/i4b_ioctl.h> -#include <i4b/i4b_trace.h> -#endif - -#include <i4b/layer1/i4b_l1.h> -#include <i4b/layer1/i4b_ipac.h> -#include <i4b/layer1/i4b_isac.h> -#include <i4b/layer1/i4b_hscx.h> - -#include <i4b/include/i4b_l1l2.h> -#include <i4b/include/i4b_global.h> - -#include <i4b/layer1/pcmcia_isic.h> - -static int pcmcia_isic_match __P((struct device *, struct cfdata *, void *)); -static void pcmcia_isic_attach __P((struct device *, struct device *, void *)); -static const struct isic_pcmcia_card_entry * find_matching_card __P((struct pcmcia_attach_args *pa)); -static int pcmcia_isicattach __P((struct isic_softc *sc)); - -struct cfattach pcmcia_isic_ca = { - sizeof(struct pcmcia_isic_softc), pcmcia_isic_match, pcmcia_isic_attach -}; - -struct isic_pcmcia_card_entry { - int32_t vendor; /* vendor ID */ - int32_t product; /* product ID */ - char *cis1_info[4]; /* CIS info to match */ - char *name; /* name of controller */ - int function; /* expected PCMCIA function type */ - int card_type; /* card type found */ - isic_pcmcia_attach_func attach; /* card initialization */ -}; - -static const struct isic_pcmcia_card_entry card_list[] = { - -#ifdef AVM_A1_PCMCIA - { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID, - { "AVM", "ISDN A", NULL, NULL }, - "AVM Fritz!Card", PCMCIA_FUNCTION_NETWORK, - CARD_TYPEP_PCFRITZ, isic_attach_fritzpcmcia }, -#endif - -#ifdef ELSA_ISDNMC - { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID, - { "ELSA GmbH, Aachen", "MicroLink ISDN/MC ", NULL, NULL }, - "ELSA MicroLink ISDN/MC", PCMCIA_FUNCTION_NETWORK, - CARD_TYPEP_ELSAMLIMC, isic_attach_elsaisdnmc }, - { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID, - { "ELSA AG, Aachen", "MicroLink ISDN/MC ", NULL, NULL }, - "ELSA MicroLink ISDN/MC", PCMCIA_FUNCTION_NETWORK, - CARD_TYPEP_ELSAMLIMC, isic_attach_elsaisdnmc }, -#endif - -#ifdef ELSA_MCALL - { 0x105, 0x410a, - { "ELSA", "MicroLink MC all", NULL, NULL }, - "ELSA MicroLink MCall", PCMCIA_FUNCTION_NETWORK, - CARD_TYPEP_ELSAMLMCALL, isic_attach_elsamcall }, -#endif - -}; -#define NUM_MATCH_ENTRIES (sizeof(card_list)/sizeof(card_list[0])) - -static const struct isic_pcmcia_card_entry * -find_matching_card(pa) - struct pcmcia_attach_args *pa; -{ - int i, j; - - for (i = 0; i < NUM_MATCH_ENTRIES; i++) { - if (card_list[i].vendor != PCMCIA_VENDOR_INVALID && pa->card->manufacturer != card_list[i].vendor) - continue; - if (card_list[i].product != PCMCIA_PRODUCT_INVALID && pa->card->product != card_list[i].product) - continue; - if (pa->pf->function != card_list[i].function) - continue; - for (j = 0; j < 4; j++) { - if (card_list[i].cis1_info[j] == NULL) - continue; /* wildcard */ - if (pa->card->cis1_info[j] == NULL) - break; /* not available */ - if (strcmp(pa->card->cis1_info[j], card_list[i].cis1_info[j]) != 0) - break; /* mismatch */ - } - if (j >= 4) - break; - } - if (i >= NUM_MATCH_ENTRIES) - return NULL; - - return &card_list[i]; -} - -/* - * Match card - */ -static int -pcmcia_isic_match(parent, match, aux) - struct device *parent; - struct cfdata *match; - void *aux; -{ - struct pcmcia_attach_args *pa = aux; - - if (!find_matching_card(pa)) - return 0; - - return 1; -} - -/* - * Attach the card - */ -static void -pcmcia_isic_attach(parent, self, aux) - struct device *parent, *self; - void *aux; -{ - struct pcmcia_isic_softc *psc = (void*) self; - struct isic_softc *sc = &psc->sc_isic; - struct pcmcia_attach_args *pa = aux; - struct pcmcia_config_entry *cfe; - const struct isic_pcmcia_card_entry * cde; - - /* Which card is it? */ - cde = find_matching_card(pa); - if (cde == NULL) return; /* oops - not found?!? */ - - psc->sc_pf = pa->pf; - cfe = pa->pf->cfe_head.sqh_first; - - /* Enable the card */ - pcmcia_function_init(pa->pf, cfe); - pcmcia_function_enable(pa->pf); - - if (!cde->attach(psc, cfe, pa)) - return; /* Ooops ? */ - - sc->sc_unit = sc->sc_dev.dv_unit; - - /* Announce card name */ - printf(": %s\n", cde->name); - - /* MI initilization */ - pcmcia_isicattach(sc); - - /* setup interrupt */ - psc->sc_ih = pcmcia_intr_establish(pa->pf, IPL_NET, isicintr, sc); -} - -/*---------------------------------------------------------------------------* - * card independend attach for pcmicia cards - *---------------------------------------------------------------------------*/ - -/* parameter and format for message producing e.g. "isic0: " */ - -#ifdef __FreeBSD__ -#define ISIC_FMT "isic%d: " -#define ISIC_PARM dev->id_unit -#define TERMFMT " " -#else -#define ISIC_FMT "%s: " -#define ISIC_PARM sc->sc_dev.dv_xname -#define TERMFMT "\n" -#endif - -int -pcmcia_isicattach(struct isic_softc *sc) -{ - static char *ISACversion[] = { - "2085 Version A1/A2 or 2086/2186 Version 1.1", - "2085 Version B1", - "2085 Version B2", - "2085 Version V2.3 (B3)", - "Unknown Version" - }; - - static char *HSCXversion[] = { - "82525 Version A1", - "Unknown (0x01)", - "82525 Version A2", - "Unknown (0x03)", - "82525 Version A3", - "82525 or 21525 Version 2.1", - "Unknown Version" - }; - - isic_sc[sc->sc_unit] = sc; - sc->sc_isac_version = 0; - 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 */ - - isic_isac_init(sc); - - /* HSCX setup */ - - isic_bchannel_setup(sc->sc_unit, HSCX_CH_A, BPROT_NONE, 0); - - isic_bchannel_setup(sc->sc_unit, HSCX_CH_B, BPROT_NONE, 0); - - /* setup linktab */ - - isic_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); - - /* announce chip versions */ - - 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'); - } - - 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]); - } - - return(1); -} - diff --git a/sys/i4b/layer1/pcmcia_isic.h b/sys/i4b/layer1/pcmcia_isic.h deleted file mode 100644 index c5426bd..0000000 --- a/sys/i4b/layer1/pcmcia_isic.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 1998 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. - * - *--------------------------------------------------------------------------- - * - * pcmcia_isic.h - common definitions for pcmcia isic cards - * -------------------------------------------------------- - * - * $FreeBSD$ - * - * last edit-date: [Sun Feb 14 10:29:33 1999] - * - * -mh original implementation - * - *---------------------------------------------------------------------------*/ - -struct pcmcia_isic_softc { - struct isic_softc sc_isic; /* parent class */ - - /* PCMCIA-specific goo */ - struct pcmcia_io_handle sc_pcioh; /* PCMCIA i/o space info */ - int sc_io_window; /* our i/o window */ - struct pcmcia_function *sc_pf; /* our PCMCIA function */ - void *sc_ih; /* interrupt handler */ -}; - -typedef int (*isic_pcmcia_attach_func)(struct pcmcia_isic_softc *sc, struct pcmcia_config_entry *cfe, struct pcmcia_attach_args *pa); - -extern int isic_attach_fritzpcmcia(struct pcmcia_isic_softc *sc, struct pcmcia_config_entry *cfe, struct pcmcia_attach_args *pa); -extern int isic_attach_elsaisdnmc(struct pcmcia_isic_softc *sc, struct pcmcia_config_entry *cfe, struct pcmcia_attach_args *pa); -extern int isic_attach_elsamcall(struct pcmcia_isic_softc *sc, struct pcmcia_config_entry *cfe, struct pcmcia_attach_args *pa); - - |