From 6a1e8c89a39e745792906a17cdf08fc5bdd384f4 Mon Sep 17 00:00:00 2001 From: hm Date: Mon, 9 Oct 2000 13:29:00 +0000 Subject: update to i4b version 0.95.04 --- sys/i4b/layer1/i4b_asuscom_ipac.c | 248 ----- sys/i4b/layer1/i4b_avm_a1.c | 419 -------- sys/i4b/layer1/i4b_avm_fritz_pci.c | 1418 ------------------------- sys/i4b/layer1/i4b_avm_fritz_pcmcia.c | 501 --------- sys/i4b/layer1/i4b_avm_fritz_pnp.c | 1271 ---------------------- sys/i4b/layer1/i4b_bchan.c | 437 -------- sys/i4b/layer1/i4b_ctx_s0P.c | 256 ----- sys/i4b/layer1/i4b_drn_ngo.c | 270 ----- sys/i4b/layer1/i4b_dynalink.c | 578 ---------- sys/i4b/layer1/i4b_elsa_isdnmc.c | 325 ------ sys/i4b/layer1/i4b_elsa_mcall.c | 251 ----- sys/i4b/layer1/i4b_elsa_pcc16.c | 390 ------- sys/i4b/layer1/i4b_elsa_qs1i.c | 248 ----- sys/i4b/layer1/i4b_elsa_qs1p.c | 365 ------- sys/i4b/layer1/i4b_hdlc.h | 387 +++++++ sys/i4b/layer1/i4b_hscx.c | 662 ------------ sys/i4b/layer1/i4b_hscx.h | 299 ------ sys/i4b/layer1/i4b_ipac.h | 205 ---- sys/i4b/layer1/i4b_isac.c | 664 ------------ sys/i4b/layer1/i4b_isac.h | 390 ------- sys/i4b/layer1/i4b_isic.c | 515 --------- sys/i4b/layer1/i4b_isic_isa.c | 224 ---- sys/i4b/layer1/i4b_isic_pcmcia.c | 183 ---- sys/i4b/layer1/i4b_isic_pnp.c | 317 ------ sys/i4b/layer1/i4b_itk_ix1.c | 482 --------- sys/i4b/layer1/i4b_l1.c | 280 ----- sys/i4b/layer1/i4b_l1.h | 347 ------ sys/i4b/layer1/i4b_l1dmux.c | 447 ++++++++ sys/i4b/layer1/i4b_l1fsm.c | 514 --------- sys/i4b/layer1/i4b_l1lib.c | 81 ++ sys/i4b/layer1/i4b_siemens_isurf.c | 243 ----- sys/i4b/layer1/i4b_sws.c | 223 ---- sys/i4b/layer1/i4b_tel_s016.c | 383 ------- sys/i4b/layer1/i4b_tel_s0163.c | 386 ------- sys/i4b/layer1/i4b_tel_s08.c | 316 ------ sys/i4b/layer1/i4b_usr_sti.c | 684 ------------ sys/i4b/layer1/ifpi/i4b_ifpi_ext.h | 61 ++ sys/i4b/layer1/ifpi/i4b_ifpi_isac.c | 669 ++++++++++++ sys/i4b/layer1/ifpi/i4b_ifpi_l1.c | 248 +++++ sys/i4b/layer1/ifpi/i4b_ifpi_l1fsm.c | 522 +++++++++ sys/i4b/layer1/ifpi/i4b_ifpi_pci.c | 1487 ++++++++++++++++++++++++++ sys/i4b/layer1/ifpnp/i4b_ifpnp_avm.c | 1390 ++++++++++++++++++++++++ sys/i4b/layer1/ifpnp/i4b_ifpnp_ext.h | 62 ++ sys/i4b/layer1/ifpnp/i4b_ifpnp_isac.c | 669 ++++++++++++ sys/i4b/layer1/ifpnp/i4b_ifpnp_l1.c | 248 +++++ sys/i4b/layer1/ifpnp/i4b_ifpnp_l1fsm.c | 522 +++++++++ sys/i4b/layer1/ihfc/i4b_ihfc.h | 337 ++++++ sys/i4b/layer1/ihfc/i4b_ihfc_drv.c | 1743 +++++++++++++++++++++++++++++++ sys/i4b/layer1/ihfc/i4b_ihfc_drv.h | 230 ++++ sys/i4b/layer1/ihfc/i4b_ihfc_ext.h | 62 ++ sys/i4b/layer1/ihfc/i4b_ihfc_l1if.c | 517 +++++++++ sys/i4b/layer1/ihfc/i4b_ihfc_pnp.c | 421 ++++++++ sys/i4b/layer1/isa_isic.c | 836 --------------- sys/i4b/layer1/isapnp_isic.c | 394 ------- sys/i4b/layer1/isic/i4b_asuscom_ipac.c | 248 +++++ sys/i4b/layer1/isic/i4b_avm_a1.c | 420 ++++++++ sys/i4b/layer1/isic/i4b_bchan.c | 405 +++++++ sys/i4b/layer1/isic/i4b_ctx_s0P.c | 261 +++++ sys/i4b/layer1/isic/i4b_drn_ngo.c | 271 +++++ sys/i4b/layer1/isic/i4b_dynalink.c | 239 +++++ sys/i4b/layer1/isic/i4b_elsa_pcc16.c | 408 ++++++++ sys/i4b/layer1/isic/i4b_elsa_qs1i.c | 249 +++++ sys/i4b/layer1/isic/i4b_elsa_qs1p.c | 365 +++++++ sys/i4b/layer1/isic/i4b_hscx.c | 667 ++++++++++++ sys/i4b/layer1/isic/i4b_hscx.h | 299 ++++++ sys/i4b/layer1/isic/i4b_ipac.h | 206 ++++ sys/i4b/layer1/isic/i4b_isac.c | 666 ++++++++++++ sys/i4b/layer1/isic/i4b_isac.h | 390 +++++++ sys/i4b/layer1/isic/i4b_isic.c | 506 +++++++++ sys/i4b/layer1/isic/i4b_isic.h | 363 +++++++ sys/i4b/layer1/isic/i4b_isic_ext.h | 50 + sys/i4b/layer1/isic/i4b_isic_isa.c | 224 ++++ sys/i4b/layer1/isic/i4b_isic_pnp.c | 317 ++++++ sys/i4b/layer1/isic/i4b_itk_ix1.c | 409 ++++++++ sys/i4b/layer1/isic/i4b_l1.c | 261 +++++ sys/i4b/layer1/isic/i4b_l1fsm.c | 520 +++++++++ sys/i4b/layer1/isic/i4b_siemens_isurf.c | 244 +++++ sys/i4b/layer1/isic/i4b_sws.c | 224 ++++ sys/i4b/layer1/isic/i4b_tel_s016.c | 384 +++++++ sys/i4b/layer1/isic/i4b_tel_s0163.c | 387 +++++++ sys/i4b/layer1/isic/i4b_tel_s08.c | 317 ++++++ sys/i4b/layer1/isic/i4b_usr_sti.c | 678 ++++++++++++ sys/i4b/layer1/isic_supio.c | 386 ------- sys/i4b/layer1/iwic/i4b_iwic.h | 224 ++++ sys/i4b/layer1/iwic/i4b_iwic_bchan.c | 749 +++++++++++++ sys/i4b/layer1/iwic/i4b_iwic_dchan.c | 494 +++++++++ sys/i4b/layer1/iwic/i4b_iwic_ext.h | 50 + sys/i4b/layer1/iwic/i4b_iwic_fsm.c | 235 +++++ sys/i4b/layer1/iwic/i4b_iwic_l1if.c | 166 +++ sys/i4b/layer1/iwic/i4b_iwic_pci.c | 317 ++++++ sys/i4b/layer1/iwic/i4b_w6692.h | 264 +++++ sys/i4b/layer1/pci_isic.c | 339 ------ sys/i4b/layer1/pci_isic.h | 53 - sys/i4b/layer1/pcmcia_isic.c | 358 ------- sys/i4b/layer1/pcmcia_isic.h | 60 -- 95 files changed, 22580 insertions(+), 16720 deletions(-) delete mode 100644 sys/i4b/layer1/i4b_asuscom_ipac.c delete mode 100644 sys/i4b/layer1/i4b_avm_a1.c delete mode 100644 sys/i4b/layer1/i4b_avm_fritz_pci.c delete mode 100644 sys/i4b/layer1/i4b_avm_fritz_pcmcia.c delete mode 100644 sys/i4b/layer1/i4b_avm_fritz_pnp.c delete mode 100644 sys/i4b/layer1/i4b_bchan.c delete mode 100644 sys/i4b/layer1/i4b_ctx_s0P.c delete mode 100644 sys/i4b/layer1/i4b_drn_ngo.c delete mode 100644 sys/i4b/layer1/i4b_dynalink.c delete mode 100644 sys/i4b/layer1/i4b_elsa_isdnmc.c delete mode 100644 sys/i4b/layer1/i4b_elsa_mcall.c delete mode 100644 sys/i4b/layer1/i4b_elsa_pcc16.c delete mode 100644 sys/i4b/layer1/i4b_elsa_qs1i.c delete mode 100644 sys/i4b/layer1/i4b_elsa_qs1p.c create mode 100644 sys/i4b/layer1/i4b_hdlc.h delete mode 100644 sys/i4b/layer1/i4b_hscx.c delete mode 100644 sys/i4b/layer1/i4b_hscx.h delete mode 100644 sys/i4b/layer1/i4b_ipac.h delete mode 100644 sys/i4b/layer1/i4b_isac.c delete mode 100644 sys/i4b/layer1/i4b_isac.h delete mode 100644 sys/i4b/layer1/i4b_isic.c delete mode 100644 sys/i4b/layer1/i4b_isic_isa.c delete mode 100644 sys/i4b/layer1/i4b_isic_pcmcia.c delete mode 100644 sys/i4b/layer1/i4b_isic_pnp.c delete mode 100644 sys/i4b/layer1/i4b_itk_ix1.c delete mode 100644 sys/i4b/layer1/i4b_l1.c delete mode 100644 sys/i4b/layer1/i4b_l1.h create mode 100644 sys/i4b/layer1/i4b_l1dmux.c delete mode 100644 sys/i4b/layer1/i4b_l1fsm.c create mode 100644 sys/i4b/layer1/i4b_l1lib.c delete mode 100644 sys/i4b/layer1/i4b_siemens_isurf.c delete mode 100644 sys/i4b/layer1/i4b_sws.c delete mode 100644 sys/i4b/layer1/i4b_tel_s016.c delete mode 100644 sys/i4b/layer1/i4b_tel_s0163.c delete mode 100644 sys/i4b/layer1/i4b_tel_s08.c delete mode 100644 sys/i4b/layer1/i4b_usr_sti.c create mode 100644 sys/i4b/layer1/ifpi/i4b_ifpi_ext.h create mode 100644 sys/i4b/layer1/ifpi/i4b_ifpi_isac.c create mode 100644 sys/i4b/layer1/ifpi/i4b_ifpi_l1.c create mode 100644 sys/i4b/layer1/ifpi/i4b_ifpi_l1fsm.c create mode 100644 sys/i4b/layer1/ifpi/i4b_ifpi_pci.c create mode 100644 sys/i4b/layer1/ifpnp/i4b_ifpnp_avm.c create mode 100644 sys/i4b/layer1/ifpnp/i4b_ifpnp_ext.h create mode 100644 sys/i4b/layer1/ifpnp/i4b_ifpnp_isac.c create mode 100644 sys/i4b/layer1/ifpnp/i4b_ifpnp_l1.c create mode 100644 sys/i4b/layer1/ifpnp/i4b_ifpnp_l1fsm.c create mode 100644 sys/i4b/layer1/ihfc/i4b_ihfc.h create mode 100644 sys/i4b/layer1/ihfc/i4b_ihfc_drv.c create mode 100644 sys/i4b/layer1/ihfc/i4b_ihfc_drv.h create mode 100644 sys/i4b/layer1/ihfc/i4b_ihfc_ext.h create mode 100644 sys/i4b/layer1/ihfc/i4b_ihfc_l1if.c create mode 100644 sys/i4b/layer1/ihfc/i4b_ihfc_pnp.c delete mode 100644 sys/i4b/layer1/isa_isic.c delete mode 100644 sys/i4b/layer1/isapnp_isic.c create mode 100644 sys/i4b/layer1/isic/i4b_asuscom_ipac.c create mode 100644 sys/i4b/layer1/isic/i4b_avm_a1.c create mode 100644 sys/i4b/layer1/isic/i4b_bchan.c create mode 100644 sys/i4b/layer1/isic/i4b_ctx_s0P.c create mode 100644 sys/i4b/layer1/isic/i4b_drn_ngo.c create mode 100644 sys/i4b/layer1/isic/i4b_dynalink.c create mode 100644 sys/i4b/layer1/isic/i4b_elsa_pcc16.c create mode 100644 sys/i4b/layer1/isic/i4b_elsa_qs1i.c create mode 100644 sys/i4b/layer1/isic/i4b_elsa_qs1p.c create mode 100644 sys/i4b/layer1/isic/i4b_hscx.c create mode 100644 sys/i4b/layer1/isic/i4b_hscx.h create mode 100644 sys/i4b/layer1/isic/i4b_ipac.h create mode 100644 sys/i4b/layer1/isic/i4b_isac.c create mode 100644 sys/i4b/layer1/isic/i4b_isac.h create mode 100644 sys/i4b/layer1/isic/i4b_isic.c create mode 100644 sys/i4b/layer1/isic/i4b_isic.h create mode 100644 sys/i4b/layer1/isic/i4b_isic_ext.h create mode 100644 sys/i4b/layer1/isic/i4b_isic_isa.c create mode 100644 sys/i4b/layer1/isic/i4b_isic_pnp.c create mode 100644 sys/i4b/layer1/isic/i4b_itk_ix1.c create mode 100644 sys/i4b/layer1/isic/i4b_l1.c create mode 100644 sys/i4b/layer1/isic/i4b_l1fsm.c create mode 100644 sys/i4b/layer1/isic/i4b_siemens_isurf.c create mode 100644 sys/i4b/layer1/isic/i4b_sws.c create mode 100644 sys/i4b/layer1/isic/i4b_tel_s016.c create mode 100644 sys/i4b/layer1/isic/i4b_tel_s0163.c create mode 100644 sys/i4b/layer1/isic/i4b_tel_s08.c create mode 100644 sys/i4b/layer1/isic/i4b_usr_sti.c delete mode 100644 sys/i4b/layer1/isic_supio.c create mode 100644 sys/i4b/layer1/iwic/i4b_iwic.h create mode 100644 sys/i4b/layer1/iwic/i4b_iwic_bchan.c create mode 100644 sys/i4b/layer1/iwic/i4b_iwic_dchan.c create mode 100644 sys/i4b/layer1/iwic/i4b_iwic_ext.h create mode 100644 sys/i4b/layer1/iwic/i4b_iwic_fsm.c create mode 100644 sys/i4b/layer1/iwic/i4b_iwic_l1if.c create mode 100644 sys/i4b/layer1/iwic/i4b_iwic_pci.c create mode 100644 sys/i4b/layer1/iwic/i4b_w6692.h delete mode 100644 sys/i4b/layer1/pci_isic.c delete mode 100644 sys/i4b/layer1/pci_isic.h delete mode 100644 sys/i4b/layer1/pcmcia_isic.c delete mode 100644 sys/i4b/layer1/pcmcia_isic.h (limited to 'sys/i4b/layer1') diff --git a/sys/i4b/layer1/i4b_asuscom_ipac.c b/sys/i4b/layer1/i4b_asuscom_ipac.c deleted file mode 100644 index 73639b5..0000000 --- a/sys/i4b/layer1/i4b_asuscom_ipac.c +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright (c) 1999 Ari Suutari. All rights reserved. - * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - *--------------------------------------------------------------------------- - * - * isic - I4B Siemens ISDN Chipset Driver for Asuscom ISDNlink 128K PnP - * ===================================================================== - * - * This driver works with Asuscom ISDNlink 128K PnP ISA adapter, - * which is based on Siemens IPAC chip (my card probes as ASU1690). - * Older Asuscom ISA cards are based on different chipset - * (containing two chips) - for those cards, one might want - * to try the Dynalink driver. - * - * This driver is heavily based on ELSA Quickstep 1000pro PCI - * driver written by Hellmuth Michaelis. Card initialization - * code is modeled after Linux i4l driver written by Karsten - * Keil. - * - * $Id: i4b_asuscom_ipac.c,v 1.4 1999/12/13 21:25:26 hm Exp $ - * - * $FreeBSD$ - * - * last edit-date: [Mon Dec 13 21:58:27 1999] - * - *---------------------------------------------------------------------------*/ - -#include "isic.h" -#include "opt_i4b.h" - -#if (NISIC > 0) && defined (ASUSCOM_IPAC) - -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -/* masks for register encoded in base addr */ - -#define ASI_BASE_MASK 0x0ffff -#define ASI_OFF_MASK 0xf0000 - -/* register id's to be encoded in base addr */ - -#define ASI_IDISAC 0x00000 -#define ASI_IDHSCXA 0x10000 -#define ASI_IDHSCXB 0x20000 -#define ASI_IDIPAC 0x40000 - -/* offsets from base address */ - -#define ASI_OFF_ALE 0x00 -#define ASI_OFF_RW 0x01 - -/*---------------------------------------------------------------------------* - * Asuscom ISDNlink 128K ISAC get fifo routine - *---------------------------------------------------------------------------*/ -static void -asi_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,ASI_OFF_ALE,IPAC_ISAC_OFF); - bus_space_read_multi_1(t,h,ASI_OFF_RW,buf,size); - break; - case ISIC_WHAT_HSCXA: - bus_space_write_1(t,h,ASI_OFF_ALE,IPAC_HSCXA_OFF); - bus_space_read_multi_1(t,h,ASI_OFF_RW,buf,size); - break; - case ISIC_WHAT_HSCXB: - bus_space_write_1(t,h,ASI_OFF_ALE,IPAC_HSCXB_OFF); - bus_space_read_multi_1(t,h,ASI_OFF_RW,buf,size); - break; - } -} - -/*---------------------------------------------------------------------------* - * Asuscom ISDNlink 128K ISAC put fifo routine - *---------------------------------------------------------------------------*/ -static void -asi_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,ASI_OFF_ALE,IPAC_ISAC_OFF); - bus_space_write_multi_1(t,h,ASI_OFF_RW,buf,size); - break; - case ISIC_WHAT_HSCXA: - bus_space_write_1(t,h,ASI_OFF_ALE,IPAC_HSCXA_OFF); - bus_space_write_multi_1(t,h,ASI_OFF_RW,buf,size); - break; - case ISIC_WHAT_HSCXB: - bus_space_write_1(t,h,ASI_OFF_ALE,IPAC_HSCXB_OFF); - bus_space_write_multi_1(t,h,ASI_OFF_RW,buf,size); - break; - } -} - -/*---------------------------------------------------------------------------* - * Asuscom ISDNlink 128K ISAC put register routine - *---------------------------------------------------------------------------*/ -static void -asi_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,ASI_OFF_ALE,reg+IPAC_ISAC_OFF); - bus_space_write_1(t,h,ASI_OFF_RW,data); - break; - case ISIC_WHAT_HSCXA: - bus_space_write_1(t,h,ASI_OFF_ALE,reg+IPAC_HSCXA_OFF); - bus_space_write_1(t,h,ASI_OFF_RW,data); - break; - case ISIC_WHAT_HSCXB: - bus_space_write_1(t,h,ASI_OFF_ALE,reg+IPAC_HSCXB_OFF); - bus_space_write_1(t,h,ASI_OFF_RW,data); - break; - case ISIC_WHAT_IPAC: - bus_space_write_1(t,h,ASI_OFF_ALE,reg+IPAC_IPAC_OFF); - bus_space_write_1(t,h,ASI_OFF_RW,data); - break; - } -} - -/*---------------------------------------------------------------------------* - * Asuscom ISDNlink 128K ISAC get register routine - *---------------------------------------------------------------------------*/ -static u_int8_t -asi_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,ASI_OFF_ALE,reg+IPAC_ISAC_OFF); - return bus_space_read_1(t,h,ASI_OFF_RW); - case ISIC_WHAT_HSCXA: - bus_space_write_1(t,h,ASI_OFF_ALE,reg+IPAC_HSCXA_OFF); - return bus_space_read_1(t,h,ASI_OFF_RW); - case ISIC_WHAT_HSCXB: - bus_space_write_1(t,h,ASI_OFF_ALE,reg+IPAC_HSCXB_OFF); - return bus_space_read_1(t,h,ASI_OFF_RW); - case ISIC_WHAT_IPAC: - bus_space_write_1(t,h,ASI_OFF_ALE,reg+IPAC_IPAC_OFF); - return bus_space_read_1(t,h,ASI_OFF_RW); - default: - return 0; - } -} - -/*---------------------------------------------------------------------------* - * isic_attach_siemens_isurf - attach for Asuscom ISDNlink 128K - *---------------------------------------------------------------------------*/ -int -isic_attach_asi(device_t dev) -{ - int unit = device_get_unit(dev); - struct l1_softc *sc = &l1_sc[unit]; - - /* setup access routines */ - - sc->clearirq = NULL; - sc->readreg = asi_read_reg; - sc->writereg = asi_write_reg; - - sc->readfifo = asi_read_fifo; - sc->writefifo = asi_write_fifo; - - /* setup card type */ - - sc->sc_cardtyp = CARD_TYPEP_ASUSCOMIPAC; - - /* setup IOM bus type */ - - sc->sc_bustyp = BUS_TYPE_IOM2; - - /* setup chip type = IPAC ! */ - - sc->sc_ipac = 1; - sc->sc_bfifolen = IPAC_BFIFO_LEN; - - /* enable hscx/isac irq's */ -/* - * This has been taken from Linux driver. - * (Removed initialization that was not applicaple to - * this board or was already register default setting.) - */ - IPAC_WRITE (IPAC_ACFG, 0xff); /* Setup AUX pin modes */ - IPAC_WRITE (IPAC_AOE, 0x0); /* Setup AUX pin modes */ - IPAC_WRITE (IPAC_MASK, (IPAC_MASK_INT1 | IPAC_MASK_INT0)); - - return(0); -} -#endif /* (NISIC > 0) && defined (ASUSCOM_IPAC) */ diff --git a/sys/i4b/layer1/i4b_avm_a1.c b/sys/i4b/layer1/i4b_avm_a1.c deleted file mode 100644 index 5553907..0000000 --- a/sys/i4b/layer1/i4b_avm_a1.c +++ /dev/null @@ -1,419 +0,0 @@ -/* - * Copyright (c) 1996 Andrew Gordon. All rights reserved. - * - * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 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_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 $ - * - * $FreeBSD$ - * - * last edit-date: [Mon Dec 13 21:58:36 1999] - * - *---------------------------------------------------------------------------*/ - -#include "isic.h" -#include "opt_i4b.h" - -#if NISIC > 0 && defined(AVM_A1) - -#include -#include -#include -#include - -#include - -#include - -#include -#include - -#include - -#include -#include -#include - -/*---------------------------------------------------------------------------* - * AVM A1 and AVM Fritz! Card special registers - *---------------------------------------------------------------------------*/ - -#define AVM_CONF_REG 0x1800 /* base offset for config register */ -#define AVM_CONF_IRQ 0x1801 /* base offset for IRQ register */ - /* config register write */ -#define AVM_CONF_WR_RESET 0x01 /* 1 = RESET ISAC and HSCX */ -#define AVM_CONF_WR_CCL 0x02 /* 1 = clear counter low nibble */ -#define AVM_CONF_WR_CCH 0x04 /* 1 = clear counter high nibble */ -#define AVM_CONF_WR_IRQEN 0x08 /* 1 = enable IRQ */ -#define AVM_CONF_WR_TEST 0x10 /* test bit */ - /* config register read */ -#define AVM_CONF_RD_IIRQ 0x01 /* 0 = ISAC IRQ active */ -#define AVM_CONF_RD_HIRQ 0x02 /* 0 = HSCX IRQ active */ -#define AVM_CONF_RD_CIRQ 0x04 /* 0 = counter IRQ active */ -#define AVM_CONF_RD_ZER1 0x08 /* unused, always read 0 */ -#define AVM_CONF_RD_TEST 0x10 /* test bit read back */ -#define AVM_CONF_RD_ZER2 0x20 /* unused, always read 0 */ - -#define AVM_ISAC_R_OFFS (0x1400-0x20) -#define AVM_HSCXA_R_OFFS (0x400-0x20) -#define AVM_HSCXB_R_OFFS (0xc00-0x20) -#define AVM_ISAC_F_OFFS (0x1400-0x20-0x3e0) -#define AVM_HSCXA_F_OFFS (0x400-0x20-0x3e0) -#define AVM_HSCXB_F_OFFS (0xc00-0x20-0x3e0) - -/*---------------------------------------------------------------------------* - * AVM read fifo routine - *---------------------------------------------------------------------------*/ -static void -avma1_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[what+4]); - bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[what+4]); - bus_space_read_multi_1(t, h, 0, buf, size); -} - -/*---------------------------------------------------------------------------* - * AVM write fifo routine - *---------------------------------------------------------------------------*/ -static void -avma1_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[what+4]); - bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[what+4]); - bus_space_write_multi_1(t, h, 0, (u_int8_t*)buf, size); -} - -/*---------------------------------------------------------------------------* - * AVM write register routine - *---------------------------------------------------------------------------*/ -static void -avma1_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[what+1]); - bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[what+1]); - bus_space_write_1(t, h, offs, data); -} - -/*---------------------------------------------------------------------------* - * AVM read register routine - *---------------------------------------------------------------------------*/ -static u_int8_t -avma1_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[what+1]); - bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[what+1]); - return bus_space_read_1(t, h, offs); -} - -/*---------------------------------------------------------------------------* - * allocate an io port - *---------------------------------------------------------------------------*/ -static int -isic_alloc_port(device_t dev, int rid, u_int base, u_int len) -{ - size_t unit = device_get_unit(dev); - struct l1_softc *sc = &l1_sc[unit]; - - sc->sc_resources.io_rid[rid] = rid; - - bus_set_resource(dev, SYS_RES_IOPORT, rid, base, len); - - if(!(sc->sc_resources.io_base[rid] = - bus_alloc_resource(dev, SYS_RES_IOPORT, - &sc->sc_resources.io_rid[rid], - 0ul, ~0ul, 1, RF_ACTIVE))) - { - printf("isic%d: Error, failed to reserve io #%d!\n", unit, rid); - isic_detach_common(dev); - return(ENXIO); - } - return(0); -} - -/*---------------------------------------------------------------------------* - * isic_probe_avma1 - probe for AVM A1 and compatibles - *---------------------------------------------------------------------------*/ -int -isic_probe_avma1(device_t dev) -{ - size_t unit = device_get_unit(dev); /* get unit */ - struct l1_softc *sc = 0; /* pointer to softc */ - void *ih = 0; /* dummy */ - bus_space_tag_t t; /* bus things */ - bus_space_handle_t h; - u_char savebyte; - u_char byte; - - /* check max unit range */ - - if(unit >= ISIC_MAXUNIT) - { - printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for AVM A1/Fritz!\n", - unit, unit); - return(ENXIO); - } - - sc = &l1_sc[unit]; /* get pointer to softc */ - sc->sc_unit = unit; /* set unit */ - sc->sc_flags = FLAG_AVM_A1; /* set flags */ - - /* see if an io base was supplied */ - - 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 get iobase for AVM A1/Fritz!\n", - unit); - return(ENXIO); - } - - /* set io base */ - - sc->sc_port = rman_get_start(sc->sc_resources.io_base[0]); - - /* release io base */ - - bus_release_resource(dev, SYS_RES_IOPORT, sc->sc_resources.io_rid[0], - sc->sc_resources.io_base[0]); - - switch(sc->sc_port) - { - case 0x200: - case 0x240: - case 0x300: - case 0x340: - break; - - default: - printf("isic%d: Error, invalid iobase 0x%x specified for AVM A1/Fritz!\n", - unit, sc->sc_port); - return(ENXIO); - break; - } - - if(isic_alloc_port(dev, 0, sc->sc_port+AVM_CONF_REG, 0x20)) - return(ENXIO); - - if(isic_alloc_port(dev, 1, sc->sc_port+AVM_ISAC_R_OFFS, 0x20)) - return(ENXIO); - - if(isic_alloc_port(dev, 2, sc->sc_port+AVM_HSCXA_R_OFFS, 0x20)) - return(ENXIO); - - if(isic_alloc_port(dev, 3, sc->sc_port+AVM_HSCXB_R_OFFS, 0x20)) - return(ENXIO); - - if(isic_alloc_port(dev, 4, sc->sc_port+AVM_ISAC_F_OFFS, 0x20)) - return(ENXIO); - - if(isic_alloc_port(dev, 5, sc->sc_port+AVM_HSCXA_F_OFFS, 0x20)) - return(ENXIO); - - if(isic_alloc_port(dev, 6, sc->sc_port+AVM_HSCXB_F_OFFS, 0x20)) - return(ENXIO); - - /* 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 get an irq for AVM A1/Fritz!\n",unit); - isic_detach_common(dev); - return ENXIO; - } - - /* get the irq number */ - sc->sc_irq = rman_get_start(sc->sc_resources.irq); - - /* register interupt routine */ - bus_setup_intr(dev, sc->sc_resources.irq, INTR_TYPE_NET, - (void(*)(void *))(isicintr), - sc, &ih); - - /* check IRQ validity */ - - switch(sc->sc_irq) - { - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - break; - - default: - printf("isic%d: Error, invalid IRQ [%d] specified for AVM A1/Fritz!\n", - unit, sc->sc_irq); - isic_detach_common(dev); - return(ENXIO); - break; - } - - sc->clearirq = NULL; - sc->readreg = avma1_read_reg; - sc->writereg = avma1_write_reg; - - sc->readfifo = avma1_read_fifo; - sc->writefifo = avma1_write_fifo; - - /* setup card type */ - - sc->sc_cardtyp = CARD_TYPEP_AVMA1; - - /* 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 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 A1/Fritz\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)); - return(ENXIO); - } - - /* AVM A1 or Fritz! control register bits: */ - /* read write */ - /* 0x01 hscx irq* RESET */ - /* 0x02 isac irq* clear counter1 */ - /* 0x04 counter irq* clear counter2 */ - /* 0x08 always 0 irq enable */ - /* 0x10 read test bit set test bit */ - /* 0x20 always 0 unused */ - - /* - * XXX the following test may be destructive, to prevent the - * worst case, we save the byte first, and in case the test - * fails, we write back the saved byte ..... - */ - - t = rman_get_bustag(sc->sc_resources.io_base[0]); - h = rman_get_bushandle(sc->sc_resources.io_base[0]); - - savebyte = bus_space_read_1(t, h, 0); - - /* write low to test bit */ - - bus_space_write_1(t, h, 0, 0x00); - - /* test bit and next higher and lower bit must be 0 */ - - if((byte = bus_space_read_1(t, h, 0) & 0x38) != 0x00) - { - printf("isic%d: Error, probe-1 failed, 0x%02x should be 0x00 for AVM A1/Fritz!\n", - unit, byte); - bus_space_write_1(t, h, 0, savebyte); - return(ENXIO); - } - - /* write high to test bit */ - - bus_space_write_1(t, h, 0, 0x10); - - /* test bit must be high, next higher and lower bit must be 0 */ - - if((byte = bus_space_read_1(t, h, 0) & 0x38) != 0x10) - { - printf("isic%d: Error, probe-2 failed, 0x%02x should be 0x10 for AVM A1/Fritz!\n", - unit, byte); - bus_space_write_1(t, h, 0, savebyte); - return(ENXIO); - } - return(0); -} - -/*---------------------------------------------------------------------------* - * isic_attach_avma1 - attach AVM A1 and compatibles - *---------------------------------------------------------------------------*/ -int -isic_attach_avma1(device_t dev) -{ - size_t unit = device_get_unit(dev); - 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]); - - /* reset ISAC/HSCX */ - - bus_space_write_1(t, h, 0, 0x00); - DELAY(SEC_DELAY / 10); - - bus_space_write_1(t, h, 0, AVM_CONF_WR_RESET); - DELAY(SEC_DELAY / 10); - - bus_space_write_1(t, h, 0, 0x00); - DELAY(SEC_DELAY / 10); - - /* setup IRQ */ - - bus_space_write_1(t, h, 1, sc->sc_irq); - DELAY(SEC_DELAY / 10); - - /* enable IRQ, disable counter IRQ */ - - bus_space_write_1(t, h, 0, AVM_CONF_WR_IRQEN | - AVM_CONF_WR_CCH | AVM_CONF_WR_CCL); - DELAY(SEC_DELAY / 10); - - return(0); -} - -#endif /* NISIC > 0 && defined(AVM_A1) */ diff --git a/sys/i4b/layer1/i4b_avm_fritz_pci.c b/sys/i4b/layer1/i4b_avm_fritz_pci.c deleted file mode 100644 index dc86c92..0000000 --- a/sys/i4b/layer1/i4b_avm_fritz_pci.c +++ /dev/null @@ -1,1418 +0,0 @@ -/* - * Copyright (c) 1999 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. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * 4. Altered versions must be plainly marked as such, and must not be - * misrepresented as being the original software and/or documentation. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - *--------------------------------------------------------------------------- - * a lot of code was borrowed from i4b_bchan.c and i4b_hscx.c - *--------------------------------------------------------------------------- - * - * Fritz!Card PCI specific routines for isic driver - * ------------------------------------------------ - * - * New-bus'ified by Gary Jennejohn - 15 Nov 99. - * - * $Id: i4b_avm_fritz_pci.c,v 1.3 1999/12/13 21:25:26 hm Exp $ - * - * $FreeBSD$ - * - * last edit-date: [Mon Dec 13 21:59:04 1999] - * - *---------------------------------------------------------------------------*/ - -#include "isic.h" -#include "opt_i4b.h" - -#if NISIC > 0 && defined(AVM_A1_PCI) - -#include -#include -#include -#include - -#include /* for DELAY */ -#include /* this device uses port accesses only */ -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include -#include - -#include -#include -#include - -#include -#include -#include - -#define PCI_AVMA1_VID 0x1244 -#define PCI_AVMA1_DID 0x0a00 - -/* prototypes */ -static void avma1pp_disable(device_t); - -static void avma1pp_intr(void *); -static void hscx_write_reg(int, u_int, u_int, struct l1_softc *); -static u_char hscx_read_reg(int, u_int, struct l1_softc *); -static u_int hscx_read_reg_int(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 avma1pp_hscx_int_handler(struct l1_softc *); -static void avma1pp_hscx_intr(int, u_int, struct l1_softc *); -static void avma1pp_init_linktab(struct l1_softc *); -static void avma1pp_bchannel_setup(int, int, int, int); -static void avma1pp_bchannel_start(int, int); -static void avma1pp_hscx_init(struct l1_softc *, int, int); -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 device_method_t avma1pp_pci_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, avma1pp_pci_probe), - DEVMETHOD(device_attach, isic_attach_avma1pp), - DEVMETHOD(device_shutdown, avma1pp_disable), - - /* bus interface */ - DEVMETHOD(bus_print_child, bus_generic_print_child), - DEVMETHOD(bus_driver_added, bus_generic_driver_added), - - { 0, 0 } -}; - -/* a minimal softc for the Fritz!Card PCI */ -struct avma1pp_softc -{ - bus_space_handle_t avma1pp_bhandle; - bus_space_tag_t avma1pp_btag; - void *avma1pp_intrhand; - struct resource *avma1pp_irq; - struct resource *avma1pp_res; - u_int8_t avma1pp_unit; /* interface number */ - /* pointer to l1_sc */ - struct l1_softc *avma1pp_isc; -}; - -static driver_t avma1pp_pci_driver = { - "isic", - avma1pp_pci_methods, - sizeof(struct avma1pp_softc) -}; - -static devclass_t avma1pp_pci_devclass; - -DRIVER_MODULE(avma1pp, pci, avma1pp_pci_driver, avma1pp_pci_devclass, 0, 0); - -/*---------------------------------------------------------------------------* - * AVM PCI Fritz!Card special registers - *---------------------------------------------------------------------------*/ - -/* - * register offsets from i/o base - */ -#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 -#define ISAC_HI_REG_OFFSET 0x06 - -/* offset higher than this goes to the HI register set */ -#define MAX_LO_REG_OFFSET 0x2f - -/* mask for the offset */ -#define ISAC_REGSET_MASK 0x0f - -/* the offset from the base to the ISAC registers */ -#define ISAC_REG_OFFSET 0x10 - -/* the offset from the base to the ISAC FIFO */ -#define ISAC_FIFO 0x02 - -/* not really the HSCX, but sort of */ -#define HSCX_FIFO 0x00 -#define HSCX_STAT 0x04 - -/* - * AVM PCI Status Latch 0 read only bits - */ -#define ASL_IRQ_ISAC 0x01 /* ISAC interrupt, active low */ -#define ASL_IRQ_HSCX 0x02 /* HSX interrupt, active low */ -#define ASL_IRQ_TIMER 0x04 /* Timer interrupt, active low */ -#define ASL_IRQ_BCHAN ASL_IRQ_HSCX -/* actually active LOW */ -#define ASL_IRQ_Pending (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 */ -#define ASL_TESTBIT 0x10 /* active high */ - -/* - * AVM Status Latch 1 write only bits - */ -#define ASL1_INTSEL 0x0f /* active high */ -#define ASL1_ENABLE_IOM 0x80 /* active high */ - -/* - * "HSCX" mode bits - */ -#define HSCX_MODE_ITF_FLG 0x01 -#define HSCX_MODE_TRANS 0x02 -#define HSCX_MODE_CCR_7 0x04 -#define HSCX_MODE_CCR_16 0x08 -#define HSCX_MODE_TESTLOOP 0x80 - -/* - * "HSCX" status bits - */ -#define HSCX_STAT_RME 0x01 -#define HSCX_STAT_RDO 0x10 -#define HSCX_STAT_CRCVFRRAB 0x0E -#define HSCX_STAT_CRCVFR 0x06 -#define HSCX_STAT_RML_MASK 0x3f00 - -/* - * "HSCX" interrupt bits - */ -#define HSCX_INT_XPR 0x80 -#define HSCX_INT_XDU 0x40 -#define HSCX_INT_RPR 0x20 -#define HSCX_INT_MASK 0xE0 - -/* - * "HSCX" command bits - */ -#define HSCX_CMD_XRS 0x80 -#define HSCX_CMD_XME 0x01 -#define HSCX_CMD_RRS 0x20 -#define HSCX_CMD_XML_MASK 0x3f00 - -/* - * Commands and parameters are sent to the "HSCX" as a long, but the - * fields are handled as bytes. - * - * The long contains: - * (prot << 16)|(txl << 8)|cmd - * - * where: - * prot = protocol to use - * txl = transmit length - * cmd = the command to be executed - * - * The fields are defined as u_char in struct l1_softc. - * - * Macro to coalesce the byte fields into a u_int - */ -#define AVMA1PPSETCMDLONG(f) (f) = ((sc->avma1pp_cmd) | (sc->avma1pp_txl << 8) \ - | (sc->avma1pp_prot << 16)) - -/* - * 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 avma1pp_bchannel_setup upon active and cleared upon deactivation. - * It is set high to allow room for new flags. - */ -#define HSCX_AVMA1PP_ACTIVE 0x1000 - -/*---------------------------------------------------------------------------* - * AVM read fifo routines - *---------------------------------------------------------------------------*/ - -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; - - 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); - break; - case ISIC_WHAT_HSCXA: - hscx_read_fifo(0, buf, size, sc); - break; - case ISIC_WHAT_HSCXB: - hscx_read_fifo(1, buf, size, sc); - break; - } -} - -static void -hscx_read_fifo(int chan, void *buf, size_t len, struct l1_softc *sc) -{ - u_int32_t *ip; - size_t cnt; - struct avma1pp_softc *asc = (struct avma1pp_softc *)sc->sc_ipacbase; - - - bus_space_write_4(asc->avma1pp_btag, asc->avma1pp_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); - cnt += 4; - } -} - -/*---------------------------------------------------------------------------* - * AVM write fifo routines - *---------------------------------------------------------------------------*/ -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; - - 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); - break; - case ISIC_WHAT_HSCXA: - hscx_write_fifo(0, buf, size, sc); - break; - case ISIC_WHAT_HSCXB: - hscx_write_fifo(1, buf, size, sc); - break; - } -} - -static void -hscx_write_fifo(int chan, 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; - - - sc->avma1pp_cmd &= ~HSCX_CMD_XME; - sc->avma1pp_txl = 0; - 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; - - cnt = 0; /* borrow cnt */ - AVMA1PPSETCMDLONG(cnt); - hscx_write_reg(chan, HSCX_STAT, cnt, sc); - - ip = (u_int32_t *)buf; - cnt = 0; - while (cnt < len) - { - bus_space_write_4(asc->avma1pp_btag, asc->avma1pp_bhandle, ISAC_REG_OFFSET, *ip); - ip++; - cnt += 4; - } -} - -/*---------------------------------------------------------------------------* - * AVM write register routines - *---------------------------------------------------------------------------*/ - -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; - - switch (what) { - case ISIC_WHAT_ISAC: - reg_bank = (offs > MAX_LO_REG_OFFSET) ? ISAC_HI_REG_OFFSET:ISAC_LO_REG_OFFSET; -#ifdef AVMA1PCI_DEBUG - printf("write_reg bank %d off %ld.. ", (int)reg_bank, (long)offs); -#endif - /* set the register bank */ - bus_space_write_1(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); - break; - case ISIC_WHAT_HSCXA: - hscx_write_reg(0, offs, data, sc); - break; - case ISIC_WHAT_HSCXB: - hscx_write_reg(1, offs, data, sc); - break; - } -} - -static void -hscx_write_reg(int chan, u_int off, u_int val, struct l1_softc *sc) -{ - struct avma1pp_softc *asc = (struct avma1pp_softc *)sc->sc_ipacbase; - - /* 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); -} - -/*---------------------------------------------------------------------------* - * AVM read register routines - *---------------------------------------------------------------------------*/ -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; - - switch (what) { - case ISIC_WHAT_ISAC: - reg_bank = (offs > MAX_LO_REG_OFFSET) ? ISAC_HI_REG_OFFSET:ISAC_LO_REG_OFFSET; -#ifdef AVMA1PCI_DEBUG - printf("read_reg bank %d off %ld.. ", (int)reg_bank, (long)offs); -#endif - /* set the register bank */ - bus_space_write_1(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 + - (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 l1_softc *sc) -{ - return(hscx_read_reg_int(chan, off, sc) & 0xff); -} - -/* - * need to be able to return an int because the RBCH is in the 2nd - * byte. - */ -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; - - /* 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)); -} - -/*---------------------------------------------------------------------------* - * avma1pp_probe - probe for a card - *---------------------------------------------------------------------------*/ -static int -avma1pp_pci_probe(dev) - device_t dev; -{ - u_int16_t did, vid; - - vid = pci_get_vendor(dev); - did = pci_get_device(dev); - - if ((vid == PCI_AVMA1_VID) && (did == PCI_AVMA1_DID)) { - device_set_desc(dev, "AVM Fritz!Card PCI"); - return(0); - } - - return(ENXIO); -} - -/*---------------------------------------------------------------------------* - * isic_attach_avma1pp - attach Fritz!Card PCI - *---------------------------------------------------------------------------*/ -int -isic_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 s; - u_int16_t did, vid; - - s = splimp(); - - vid = pci_get_vendor(dev); - did = pci_get_device(dev); - asc = device_get_softc(dev); - unit = device_get_unit(dev); - bzero(asc, sizeof(struct avma1pp_softc)); - - if(unit > ISIC_MAXUNIT) { - printf("avma1pp%d: Error, unit > ISIC_MAXUNIT!\n", unit); - splx(s); - return(ENXIO); - } - - if ((vid != PCI_AVMA1_VID) && (did != PCI_AVMA1_DID)) { - printf("avma1pp%d: unknown device!?\n", unit); - goto fail; - } - - asc->avma1pp_unit = unit; - - rid = PCIR_MAPS+4; - asc->avma1pp_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, - 0, ~0, 1, RF_ACTIVE); - - if (asc->avma1pp_res == 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); - - /* Allocate interrupt */ - rid = 0; - asc->avma1pp_irq = bus_alloc_resource(dev, SYS_RES_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); - 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); - - 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); - 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; - - /* setup access routines */ - - sc->clearirq = NULL; - sc->readreg = avma1pp_read_reg; - sc->writereg = avma1pp_write_reg; - - sc->readfifo = avma1pp_read_fifo; - sc->writefifo = avma1pp_write_fifo; - - /* setup card type */ - - sc->sc_cardtyp = CARD_TYPEP_AVMA1PCI; - - /* setup IOM bus type */ - - sc->sc_bustyp = BUS_TYPE_IOM2; - - /* set up some other miscellaneous things */ - sc->sc_ipac = 0; - 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); -#ifdef AVMA1PCI_DEBUG - printf("avma1pp_attach: I_STAR %x...", v); -#endif - v = ISAC_READ(I_MODE); -#ifdef AVMA1PCI_DEBUG - printf("avma1pp_attach: I_MODE %x...", v); -#endif - v = ISAC_READ(I_ADF2); -#ifdef AVMA1PCI_DEBUG - printf("avma1pp_attach: I_ADF2 %x...", v); -#endif - v = ISAC_READ(I_ISTA); -#ifdef AVMA1PCI_DEBUG - printf("avma1pp_attach: I_ISTA %x...", v); -#endif - if (v & ISAC_ISTA_EXI) - { - v = ISAC_READ(I_EXIR); -#ifdef AVMA1PCI_DEBUG - printf("avma1pp_attach: I_EXIR %x...", v); -#endif - } - v = ISAC_READ(I_CIRR); -#ifdef AVMA1PCI_DEBUG - printf("avma1pp_attach: I_CIRR %x...", v); -#endif - ISAC_WRITE(I_MASK, 0xff); - /* the Linux driver does this to clear any pending HSCX interrupts */ - v = hscx_read_reg_int(0, HSCX_STAT, sc); -#ifdef AVMA1PCI_DEBUG - printf("avma1pp_attach: 0 HSCX_STAT %x...", v); -#endif - v = hscx_read_reg_int(1, HSCX_STAT, sc); -#ifdef AVMA1PCI_DEBUG - printf("avma1pp_attach: 1 HSCX_STAT %x\n", v); -#endif - - bus_space_write_1(asc->avma1pp_btag, asc->avma1pp_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); - 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); - DELAY(SEC_DELAY/100); /* 10 ms */ - v = bus_space_read_1(asc->avma1pp_btag, asc->avma1pp_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); -#endif - - /* from here to the end would normally be done in isic_pciattach */ - - printf("isic%d: ISAC %s (IOM-%c)\n", unit, - "2085 Version A1/A2 or 2086/2186 Version 1.1", - sc->sc_bustyp == BUS_TYPE_IOM1 ? '1' : '2'); - - /* init the ISAC */ - isic_isac_init(sc); - - /* init the "HSCX" */ - avma1pp_bchannel_setup(sc->sc_unit, HSCX_CH_A, BPROT_NONE, 0); - - avma1pp_bchannel_setup(sc->sc_unit, HSCX_CH_B, BPROT_NONE, 0); - - /* can't use the normal B-Channel stuff */ - avma1pp_init_linktab(sc); - - /* set trace level */ - - sc->sc_trace = TRACE_OFF; - - sc->sc_state = ISAC_IDLE; - - sc->sc_ibuf = NULL; - sc->sc_ib = NULL; - sc->sc_ilen = 0; - - sc->sc_obuf = NULL; - sc->sc_op = NULL; - sc->sc_ol = 0; - sc->sc_freeflag = 0; - - sc->sc_obuf2 = NULL; - sc->sc_freeflag2 = 0; - -#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); -#endif - - /* init higher protocol layers */ - - MPH_Status_Ind(sc->sc_unit, STI_ATTACH, sc->sc_cardtyp); - - fail: - splx(s); - return(error); -} - -/* - * this is the real interrupt routine - */ -static void -avma1pp_hscx_intr(int h_chan, u_int stat, struct l1_softc *sc) -{ - register l1_bchan_state_t *chan = &sc->sc_chan[h_chan]; - int activity = -1; - u_int param = 0; - - DBGL1(L1_H_IRQ, "avma1pp_hscx_intr", ("%#x\n", 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")); - /* abort the transmission */ - sc->avma1pp_txl = 0; - sc->avma1pp_cmd |= HSCX_CMD_XRS; - AVMA1PPSETCMDLONG(param); - hscx_write_reg(h_chan, HSCX_STAT, param, sc); - sc->avma1pp_cmd &= ~HSCX_CMD_XRS; - AVMA1PPSETCMDLONG(param); - hscx_write_reg(h_chan, HSCX_STAT, param, sc); - - if (chan->out_mbuf_head != NULL) /* don't continue to transmit this buffer */ - { - i4b_Bfreembuf(chan->out_mbuf_head); - chan->out_mbuf_cur = chan->out_mbuf_head = NULL; - } - } - - /* - * The following is based on examination of the Linux driver. - * - * The logic here is different than with a "real" HSCX; all kinds - * of information (interrupt/status bits) are in stat. - * HSCX_INT_RPR indicates a receive interrupt - * HSCX_STAT_RDO indicates an overrun condition, abort - - * otherwise read the bytes ((stat & HSCX_STZT_RML_MASK) >> 8) - * HSCX_STAT_RME indicates end-of-frame and apparently any - * CRC/framing errors are only reported in this state. - * if ((stat & HSCX_STAT_CRCVFRRAB) != HSCX_STAT_CRCVFR) - * CRC/framing error - */ - - if(stat & HSCX_INT_RPR) - { - register int fifo_data_len; - int error = 0; - /* always have to read the FIFO, so use a scratch buffer */ - u_char scrbuf[HSCX_FIFO_LEN]; - - if(stat & HSCX_STAT_RDO) - { - chan->stat_RDO++; - DBGL1(L1_H_XFRERR, "avma1pp_hscx_intr", ("receive data overflow\n")); - 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) - { - DBGL1(L1_H_XFRERR, "avma1pp_hscx_intr", ("toss data from %d\n", h_chan)); - error++; - } - - fifo_data_len = ((stat & HSCX_STAT_RML_MASK) >> 8); - - if(fifo_data_len == 0) - fifo_data_len = sc->sc_bfifolen; - - /* ALWAYS read data from HSCX fifo */ - - HSCX_RDFIFO(h_chan, scrbuf, fifo_data_len); - chan->rxcount += fifo_data_len; - - /* all error conditions checked, now decide and take action */ - - if(error == 0) - { - if(chan->in_mbuf == NULL) - { - if((chan->in_mbuf = i4b_Bgetmbuf(BCH_MAX_DATALEN)) == NULL) - panic("L1 avma1pp_hscx_intr: RME, cannot allocate mbuf!\n"); - chan->in_cbptr = chan->in_mbuf->m_data; - chan->in_len = 0; - } - - if((chan->in_len + fifo_data_len) <= BCH_MAX_DATALEN) - { - /* OK to copy the data */ - bcopy(scrbuf, chan->in_cbptr, fifo_data_len); - chan->in_cbptr += fifo_data_len; - chan->in_len += fifo_data_len; - - /* setup mbuf data length */ - - chan->in_mbuf->m_len = chan->in_len; - chan->in_mbuf->m_pkthdr.len = chan->in_len; - - if(sc->sc_trace & TRACE_B_RX) - { - i4b_trace_hdr_t hdr; - hdr.unit = sc->sc_unit; - hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2); - hdr.dir = FROM_NT; - hdr.count = ++sc->sc_trace_bcount; - MICROTIME(hdr.time); - MPH_Trace_Ind(&hdr, chan->in_mbuf->m_len, chan->in_mbuf->m_data); - } - - if (stat & HSCX_STAT_RME) - { - if((stat & HSCX_STAT_CRCVFRRAB) == HSCX_STAT_CRCVFR) - { - (*chan->drvr_linktab->bch_rx_data_ready)(chan->drvr_linktab->unit); - activity = ACT_RX; - - /* mark buffer ptr as unused */ - - chan->in_mbuf = NULL; - chan->in_cbptr = NULL; - chan->in_len = 0; - } - else - { - chan->stat_CRC++; - DBGL1(L1_H_XFRERR, "avma1pp_hscx_intr", ("CRC/RAB\n")); - if (chan->in_mbuf != NULL) - { - i4b_Bfreembuf(chan->in_mbuf); - chan->in_mbuf = NULL; - chan->in_cbptr = NULL; - chan->in_len = 0; - } - } - } - } /* END enough space in mbuf */ - else - { - if(chan->bprot == BPROT_NONE) - { - /* setup mbuf data length */ - - chan->in_mbuf->m_len = chan->in_len; - chan->in_mbuf->m_pkthdr.len = chan->in_len; - - if(sc->sc_trace & TRACE_B_RX) - { - i4b_trace_hdr_t hdr; - hdr.unit = sc->sc_unit; - hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2); - hdr.dir = FROM_NT; - hdr.count = ++sc->sc_trace_bcount; - MICROTIME(hdr.time); - MPH_Trace_Ind(&hdr, chan->in_mbuf->m_len, chan->in_mbuf->m_data); - } - - if(!(isic_hscx_silence(chan->in_mbuf->m_data, chan->in_mbuf->m_len))) - activity = ACT_RX; - - /* move rx'd data to rx queue */ - - 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->drvr_linktab->bch_rx_data_ready)(chan->drvr_linktab->unit); - - /* alloc new buffer */ - - if((chan->in_mbuf = i4b_Bgetmbuf(BCH_MAX_DATALEN)) == NULL) - panic("L1 avma1pp_hscx_intr: RPF, cannot allocate new mbuf!\n"); - - /* setup new data ptr */ - - chan->in_cbptr = chan->in_mbuf->m_data; - - /* OK to copy the data */ - bcopy(scrbuf, chan->in_cbptr, fifo_data_len); - - chan->in_cbptr += fifo_data_len; - chan->in_len = fifo_data_len; - - chan->rxcount += fifo_data_len; - } - else - { - DBGL1(L1_H_XFRERR, "avma1pp_hscx_intr", ("RAWHDLC rx buffer overflow in RPF, in_len=%d\n", chan->in_len)); - chan->in_cbptr = chan->in_mbuf->m_data; - chan->in_len = 0; - } - } - } /* if(error == 0) */ - else - { - /* land here for RDO */ - if (chan->in_mbuf != NULL) - { - i4b_Bfreembuf(chan->in_mbuf); - chan->in_mbuf = NULL; - chan->in_cbptr = NULL; - chan->in_len = 0; - } - sc->avma1pp_txl = 0; - sc->avma1pp_cmd |= HSCX_CMD_RRS; - AVMA1PPSETCMDLONG(param); - hscx_write_reg(h_chan, HSCX_STAT, param, sc); - sc->avma1pp_cmd &= ~HSCX_CMD_RRS; - AVMA1PPSETCMDLONG(param); - hscx_write_reg(h_chan, HSCX_STAT, param, sc); - } - } - - - /* transmit fifo empty, new data can be written to fifo */ - - if(stat & HSCX_INT_XPR) - { - /* - * for a description what is going on here, please have - * a look at isic_bchannel_start() in i4b_bchan.c ! - */ - - DBGL1(L1_H_IRQ, "avma1pp_hscx_intr", ("unit %d, chan %d - XPR, Tx Fifo Empty!\n", sc->sc_unit, h_chan)); - - 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); - } - else - { - chan->state |= HSCX_TX_ACTIVE; - chan->out_mbuf_cur = chan->out_mbuf_head; - chan->out_mbuf_cur_ptr = chan->out_mbuf_cur->m_data; - chan->out_mbuf_cur_len = chan->out_mbuf_cur->m_len; - - if(sc->sc_trace & TRACE_B_TX) - { - i4b_trace_hdr_t hdr; - hdr.unit = sc->sc_unit; - hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2); - hdr.dir = FROM_TE; - hdr.count = ++sc->sc_trace_bcount; - MICROTIME(hdr.time); - MPH_Trace_Ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data); - } - - if(chan->bprot == BPROT_NONE) - { - if(!(isic_hscx_silence(chan->out_mbuf_cur->m_data, chan->out_mbuf_cur->m_len))) - activity = ACT_TX; - } - else - { - activity = ACT_TX; - } - } - } - - isic_hscx_fifo(chan, sc); - } - - /* call timeout handling routine */ - - if(activity == ACT_RX || activity == ACT_TX) - (*chan->drvr_linktab->bch_activity)(chan->drvr_linktab->unit, activity); -} - -/* - * this is the main routine which checks each channel and then calls - * the real interrupt routine as appropriate - */ -static void -avma1pp_hscx_int_handler(struct l1_softc *sc) -{ - u_int stat; - - /* has to be a u_int because the byte count is in the 2nd byte */ - stat = hscx_read_reg_int(0, HSCX_STAT, sc); - if (stat & HSCX_INT_MASK) - avma1pp_hscx_intr(0, stat, sc); - stat = hscx_read_reg_int(1, HSCX_STAT, sc); - if (stat & HSCX_INT_MASK) - avma1pp_hscx_intr(1, stat, sc); -} - -static void -avma1pp_disable(device_t dev) -{ - struct avma1pp_softc *asc = device_get_softc(dev); - - bus_space_write_1(asc->avma1pp_btag, asc->avma1pp_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; - - asc = xsc; - sc = asc->avma1pp_isc; - - stat = bus_space_read_1(asc->avma1pp_btag, asc->avma1pp_bhandle, STAT0_OFFSET); - DBGL1(L1_H_IRQ, "avma1pp_intr", ("stat %x\n", stat)); - /* was there an interrupt from this card ? */ - if ((stat & ASL_IRQ_Pending) == ASL_IRQ_Pending) - return; /* no */ - /* interrupts are low active */ - if (!(stat & ASL_IRQ_TIMER)) - DBGL1(L1_H_IRQ, "avma1pp_intr", ("timer interrupt ???\n")); - if (!(stat & ASL_IRQ_HSCX)) - { - DBGL1(L1_H_IRQ, "avma1pp_intr", ("HSCX\n")); - avma1pp_hscx_int_handler(sc); - } - if (!(stat & ASL_IRQ_ISAC)) - { - DBGL1(L1_H_IRQ, "avma1pp_intr", ("ISAC\n")); - ISICINTR(sc); - } -} - -static void -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")); - - if (activate == 0) - { - /* only deactivate if both channels are idle */ - if (sc->sc_chan[HSCX_CH_A].state != HSCX_IDLE || - sc->sc_chan[HSCX_CH_B].state != HSCX_IDLE) - { - return; - } - sc->avma1pp_cmd = HSCX_CMD_XRS|HSCX_CMD_RRS; - sc->avma1pp_prot = HSCX_MODE_TRANS; - AVMA1PPSETCMDLONG(param); - hscx_write_reg(h_chan, HSCX_STAT, param, sc); - return; - } - if(chan->bprot == BPROT_RHDLC) - { - DBGL1(L1_BCHAN, "avma1pp_hscx_init", ("BPROT_RHDLC\n")); - - /* HDLC Frames, transparent mode 0 */ - sc->avma1pp_cmd = HSCX_CMD_XRS|HSCX_CMD_RRS; - sc->avma1pp_prot = HSCX_MODE_ITF_FLG; - AVMA1PPSETCMDLONG(param); - hscx_write_reg(h_chan, HSCX_STAT, param, sc); - sc->avma1pp_cmd = HSCX_CMD_XRS; - AVMA1PPSETCMDLONG(param); - hscx_write_reg(h_chan, HSCX_STAT, param, sc); - sc->avma1pp_cmd = 0; - } - else - { - DBGL1(L1_BCHAN, "avma1pp_hscx_init", ("BPROT_NONE??\n")); - - /* Raw Telephony, extended transparent mode 1 */ - sc->avma1pp_cmd = HSCX_CMD_XRS|HSCX_CMD_RRS; - sc->avma1pp_prot = HSCX_MODE_TRANS; - AVMA1PPSETCMDLONG(param); - hscx_write_reg(h_chan, HSCX_STAT, param, sc); - sc->avma1pp_cmd = HSCX_CMD_XRS; - AVMA1PPSETCMDLONG(param); - hscx_write_reg(h_chan, HSCX_STAT, param, sc); - sc->avma1pp_cmd = 0; - } -} - -static void -avma1pp_bchannel_setup(int unit, int h_chan, int bprot, int activate) -{ -#ifdef __FreeBSD__ - struct l1_softc *sc = &l1_sc[unit]; -#else - struct l1_softc *sc = isic_find_sc(unit); -#endif - l1_bchan_state_t *chan = &sc->sc_chan[h_chan]; - - int s = SPLI4B(); - - if(activate == 0) - { - /* deactivation */ - chan->state = HSCX_IDLE; - 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")); - - /* general part */ - - chan->unit = sc->sc_unit; /* unit number */ - chan->channel = h_chan; /* B channel */ - chan->bprot = bprot; /* B channel protocol */ - chan->state = HSCX_IDLE; /* B channel state */ - - /* receiver part */ - - i4b_Bcleanifq(&chan->rx_queue); /* clean rx queue */ - - chan->rx_queue.ifq_maxlen = IFQ_MAXLEN; - - chan->rxcount = 0; /* reset rx counter */ - - i4b_Bfreembuf(chan->in_mbuf); /* clean rx mbuf */ - - chan->in_mbuf = NULL; /* reset mbuf ptr */ - chan->in_cbptr = NULL; /* reset mbuf curr ptr */ - chan->in_len = 0; /* reset mbuf data len */ - - /* transmitter part */ - - i4b_Bcleanifq(&chan->tx_queue); /* clean tx queue */ - - chan->tx_queue.ifq_maxlen = IFQ_MAXLEN; - - chan->txcount = 0; /* reset tx counter */ - - i4b_Bfreembuf(chan->out_mbuf_head); /* clean tx mbuf */ - - chan->out_mbuf_head = NULL; /* reset head mbuf ptr */ - chan->out_mbuf_cur = NULL; /* reset current mbuf ptr */ - chan->out_mbuf_cur_ptr = NULL; /* reset current mbuf data ptr */ - chan->out_mbuf_cur_len = 0; /* reset current mbuf data cnt */ - - if(activate != 0) - { - /* activation */ - avma1pp_hscx_init(sc, h_chan, activate); - chan->state |= HSCX_AVMA1PP_ACTIVE; - } - - splx(s); -} - -static void -avma1pp_bchannel_start(int unit, int h_chan) -{ -#ifdef __FreeBSD__ - struct l1_softc *sc = &l1_sc[unit]; -#else - struct l1_softc *sc = isic_find_sc(unit); -#endif - register l1_bchan_state_t *chan = &sc->sc_chan[h_chan]; - int s; - int activity = -1; - - s = SPLI4B(); /* enter critical section */ - if(chan->state & HSCX_TX_ACTIVE) /* already running ? */ - { - splx(s); - return; /* yes, leave */ - } - - /* get next mbuf from queue */ - - IF_DEQUEUE(&chan->tx_queue, chan->out_mbuf_head); - - if(chan->out_mbuf_head == NULL) /* queue empty ? */ - { - splx(s); /* leave critical section */ - return; /* yes, exit */ - } - - /* init current mbuf values */ - - chan->out_mbuf_cur = chan->out_mbuf_head; - chan->out_mbuf_cur_len = chan->out_mbuf_cur->m_len; - chan->out_mbuf_cur_ptr = chan->out_mbuf_cur->m_data; - - /* activity indicator for timeout handling */ - - if(chan->bprot == BPROT_NONE) - { - if(!(isic_hscx_silence(chan->out_mbuf_cur->m_data, chan->out_mbuf_cur->m_len))) - activity = ACT_TX; - } - else - { - activity = ACT_TX; - } - - chan->state |= HSCX_TX_ACTIVE; /* we start transmitting */ - - if(sc->sc_trace & TRACE_B_TX) /* if trace, send mbuf to trace dev */ - { - i4b_trace_hdr_t hdr; - hdr.unit = unit; - hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2); - hdr.dir = FROM_TE; - hdr.count = ++sc->sc_trace_bcount; - MICROTIME(hdr.time); - MPH_Trace_Ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data); - } - - isic_hscx_fifo(chan, sc); - - /* call timeout handling routine */ - - if(activity == ACT_RX || activity == ACT_TX) - (*chan->drvr_linktab->bch_activity)(chan->drvr_linktab->unit, activity); - - splx(s); -} - -/*---------------------------------------------------------------------------* - * return the address of isic drivers linktab - *---------------------------------------------------------------------------*/ -static isdn_link_t * -avma1pp_ret_linktab(int unit, int channel) -{ -#ifdef __FreeBSD__ - struct l1_softc *sc = &l1_sc[unit]; -#else - struct l1_softc *sc = isic_find_sc(unit); -#endif - l1_bchan_state_t *chan = &sc->sc_chan[channel]; - - return(&chan->isdn_linktab); -} - -/*---------------------------------------------------------------------------* - * set the driver linktab in the b channel softc - *---------------------------------------------------------------------------*/ -static void -avma1pp_set_linktab(int unit, int channel, drvr_link_t *dlt) -{ -#ifdef __FreeBSD__ - struct l1_softc *sc = &l1_sc[unit]; -#else - struct l1_softc *sc = isic_find_sc(unit); -#endif - l1_bchan_state_t *chan = &sc->sc_chan[channel]; - - chan->drvr_linktab = dlt; -} - - -/*---------------------------------------------------------------------------* - * initialize our local linktab - *---------------------------------------------------------------------------*/ -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; - - /* make sure the hardware driver is known to layer 4 */ - /* avoid overwriting if already set */ - if (ctrl_types[CTRL_PASSIVE].set_linktab == NULL) - { - ctrl_types[CTRL_PASSIVE].set_linktab = avma1pp_set_linktab; - ctrl_types[CTRL_PASSIVE].get_linktab = avma1pp_ret_linktab; - } - - /* local setup */ - lt->unit = sc->sc_unit; - lt->channel = HSCX_CH_A; - lt->bch_config = avma1pp_bchannel_setup; - lt->bch_tx_start = avma1pp_bchannel_start; - lt->bch_stat = avma1pp_bchannel_stat; - lt->tx_queue = &chan->tx_queue; - - /* used by non-HDLC data transfers, i.e. telephony drivers */ - lt->rx_queue = &chan->rx_queue; - - /* used by HDLC data transfers, i.e. ipr and isp drivers */ - lt->rx_mbuf = &chan->in_mbuf; - - chan = &sc->sc_chan[HSCX_CH_B]; - lt = &chan->isdn_linktab; - - lt->unit = sc->sc_unit; - lt->channel = HSCX_CH_B; - lt->bch_config = avma1pp_bchannel_setup; - lt->bch_tx_start = avma1pp_bchannel_start; - lt->bch_stat = avma1pp_bchannel_stat; - lt->tx_queue = &chan->tx_queue; - - /* used by non-HDLC data transfers, i.e. telephony drivers */ - lt->rx_queue = &chan->rx_queue; - - /* used by HDLC data transfers, i.e. ipr and isp drivers */ - lt->rx_mbuf = &chan->in_mbuf; -} - -/* - * use this instead of isic_bchannel_stat in i4b_bchan.c because it's static - */ -static void -avma1pp_bchannel_stat(int unit, int h_chan, bchan_statistics_t *bsp) -{ -#ifdef __FreeBSD__ - struct l1_softc *sc = &l1_sc[unit]; -#else - struct l1_softc *sc = isic_find_sc(unit); -#endif - l1_bchan_state_t *chan = &sc->sc_chan[h_chan]; - int s; - - s = SPLI4B(); - - bsp->outbytes = chan->txcount; - bsp->inbytes = chan->rxcount; - - chan->txcount = 0; - chan->rxcount = 0; - - splx(s); -} - -/*---------------------------------------------------------------------------* - * fill HSCX fifo with data from the current mbuf - * Put this here until it can go into i4b_hscx.c - *---------------------------------------------------------------------------*/ -int -isic_hscx_fifo(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]; - - len = 0; - - /* - * fill the HSCX tx fifo with data from the current mbuf. if - * current mbuf holds less data than HSCX fifo length, try to - * get the next mbuf from (a possible) mbuf chain. if there is - * not enough data in a single mbuf or in a chain, then this - * is the last mbuf and we tell the HSCX that it has to send - * CRC and closing flag - */ - - while(chan->out_mbuf_cur && len != sc->sc_bfifolen) - { - nextlen = min(chan->out_mbuf_cur_len, sc->sc_bfifolen - len); - -#ifdef NOTDEF - printf("i:mh=%p, mc=%p, mcp=%p, mcl=%d l=%d nl=%d # ", - chan->out_mbuf_head, - chan->out_mbuf_cur, - chan->out_mbuf_cur_ptr, - chan->out_mbuf_cur_len, - len, - nextlen); -#endif - - 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]; - - len += nextlen; - chan->txcount += nextlen; - - chan->out_mbuf_cur_ptr += nextlen; - chan->out_mbuf_cur_len -= nextlen; - - if(chan->out_mbuf_cur_len == 0) - { - if((chan->out_mbuf_cur = chan->out_mbuf_cur->m_next) != NULL) - { - chan->out_mbuf_cur_ptr = chan->out_mbuf_cur->m_data; - chan->out_mbuf_cur_len = chan->out_mbuf_cur->m_len; - - if(sc->sc_trace & TRACE_B_TX) - { - i4b_trace_hdr_t hdr; - hdr.unit = sc->sc_unit; - hdr.type = (chan->channel == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2); - hdr.dir = FROM_TE; - hdr.count = ++sc->sc_trace_bcount; - MICROTIME(hdr.time); - MPH_Trace_Ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data); - } - } - else - { - if (chan->bprot != BPROT_NONE) - cmd |= HSCX_CMDR_XME; - i4b_Bfreembuf(chan->out_mbuf_head); - chan->out_mbuf_head = NULL; - } - } - } - /* write what we have from the scratch buf to the HSCX fifo */ - if (len != 0) - HSCX_WRFIFO(chan->channel, scrbuf, len); - return(cmd); -} - -#endif /* NISIC > 0 && defined(AVM_A1_PCI) */ diff --git a/sys/i4b/layer1/i4b_avm_fritz_pcmcia.c b/sys/i4b/layer1/i4b_avm_fritz_pcmcia.c 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 -#if defined(__FreeBSD__) && __FreeBSD__ >= 3 -#include -#else -#include -#endif -#include -#include -#include - -#ifdef __FreeBSD__ -#include -#include -#else -#include -#include -#endif - -#include -#include - -#ifdef __FreeBSD__ -#include -#include -#else -#include -#include -#include -#include -#endif - -#include -#include -#include - -#ifndef __FreeBSD__ -#include - -/* 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_avm_fritz_pnp.c b/sys/i4b/layer1/i4b_avm_fritz_pnp.c deleted file mode 100644 index 54db491..0000000 --- a/sys/i4b/layer1/i4b_avm_fritz_pnp.c +++ /dev/null @@ -1,1271 +0,0 @@ -/* - * Copyright (c) 1999 Udo Schweigert. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * 4. Altered versions must be plainly marked as such, and must not be - * misrepresented as being the original software and/or documentation. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - *--------------------------------------------------------------------------- - * A lot of code was borrowed from i4b_bchan.c and i4b_hscx.c - * Based on AVM Fritz!PCI driver by Gary Jennejohn - *--------------------------------------------------------------------------- - * In case of trouble please contact Udo Schweigert - *--------------------------------------------------------------------------- - * - * Fritz!Card PnP specific routines for isic driver - * ------------------------------------------------ - * - * $FreeBSD$ - * - * last edit-date: [Thu 10 Jun 08:50:28 CEST 1999] - * - *---------------------------------------------------------------------------*/ - -#if defined(__FreeBSD__) -#include "isic.h" -#include "opt_i4b.h" - -#if NISIC > 0 && defined(AVM_PNP) - -#include -#if defined(__FreeBSD__) && __FreeBSD__ >= 3 -#include -#if __FreeBSD__ >= 5 -#include -#endif -#else -#include -#endif -#include -#include -#include - -#include -#include - -#include -#include - -#include -#include - -#include -#include -#include - -#include -#include -#include - -static void hscx_write_reg(int, u_int, struct isic_softc *, int); -static void hscx_write_reg_val(int, u_int, u_char, struct isic_softc *); -static u_char hscx_read_reg(int, u_int, struct isic_softc *); -static void hscx_read_fifo(int, void *, size_t, struct isic_softc *); -static void hscx_write_fifo(int, const void *, size_t, struct isic_softc *); -static void avm_pnp_hscx_int_handler(struct isic_softc *); -static void avm_pnp_hscx_intr(int, int, int, struct isic_softc *); -static void avm_pnp_init_linktab(struct isic_softc *); -static void avm_pnp_bchannel_setup(int, int, int, int); -static void avm_pnp_bchannel_start(int, int); -static void avm_pnp_hscx_init(struct isic_softc *, int, int); -static void avm_pnp_bchannel_stat(int, int, bchan_statistics_t *); -static void avm_pnp_set_linktab(int, int, drvr_link_t *); -static void avm_pnp_intr(int); -static isdn_link_t * avm_pnp_ret_linktab(int, int); -extern void isicintr_sc(struct isic_softc *); - -/*---------------------------------------------------------------------------* - * AVM PnP Fritz!Card special registers - *---------------------------------------------------------------------------*/ - -/* - * register offsets from i/o base - */ -#define STAT0_OFFSET 0x02 -#define STAT1_OFFSET 0x03 -#define ADDR_REG_OFFSET 0x04 - -/* these 2 are used to select an ISAC register set */ -#define ISAC_LO_REG_OFFSET 0x04 -#define ISAC_HI_REG_OFFSET 0x06 - -/* offset higher than this goes to the HI register set */ -#define MAX_LO_REG_OFFSET 0x2f - -/* mask for the offset */ -#define ISAC_REGSET_MASK 0x0f - -/* the offset from the base to the ISAC registers */ -#define ISAC_REG_OFFSET 0x10 - -/* the offset from the base to the ISAC FIFO */ -#define ISAC_FIFO 0x02 - -/* not really the HSCX, but sort of */ -#define HSCX_FIFO 0x00 -#define HSCX_STAT 0x04 - -/* - * AVM PnP Status Latch 0 read only bits - */ -#define ASL_IRQ_ISAC 0x01 /* ISAC interrupt, active low */ -#define ASL_IRQ_HSCX 0x02 /* HSX interrupt, active low */ -#define ASL_IRQ_TIMER 0x04 /* Timer interrupt, active low */ -#define ASL_IRQ_BCHAN ASL_IRQ_HSCX -/* actually active LOW */ -#define ASL_IRQ_Pending 0x07 - -/* - * AVM Status Latch 0 write only bits - */ -#define ASL_RESET_ALL 0x01 /* reset siemens IC's, active 1 */ -#define ASL_TIMERDISABLE 0x02 /* active high */ -#define ASL_TIMERRESET 0x04 /* active high */ -#define ASL_ENABLE_INT 0x08 /* active high */ -#define ASL_TESTBIT 0x10 /* active high */ - -/* - * AVM Status Latch 1 write only bits - */ -#define ASL1_INTSEL 0x0f /* active high */ -#define ASL1_ENABLE_IOM 0x80 /* active high */ - -/* - * "HSCX" mode bits - */ -#define HSCX_MODE_ITF_FLG 0x01 -#define HSCX_MODE_TRANS 0x02 -#define HSCX_MODE_CCR_7 0x04 -#define HSCX_MODE_CCR_16 0x08 -#define HSCX_MODE_TESTLOOP 0x80 - -/* - * "HSCX" status bits - */ -#define HSCX_STAT_RME 0x01 -#define HSCX_STAT_RDO 0x10 -#define HSCX_STAT_CRCVFRRAB 0x0E -#define HSCX_STAT_CRCVFR 0x06 -#define HSCX_STAT_RML_MASK 0x3f00 - -/* - * "HSCX" interrupt bits - */ -#define HSCX_INT_XPR 0x80 -#define HSCX_INT_XDU 0x40 -#define HSCX_INT_RPR 0x20 -#define HSCX_INT_MASK 0xE0 - -/* - * "HSCX" command bits - */ -#define HSCX_CMD_XRS 0x80 -#define HSCX_CMD_XME 0x01 -#define HSCX_CMD_RRS 0x20 -#define HSCX_CMD_XML_MASK 0x3f00 - -/* "fake" addresses for the non-existent HSCX */ -/* note: the unit number is in the lower byte for both the ISAC and "HSCX" */ -#define HSCX0FAKE 0xfa000 /* read: fake0 */ -#define HSCX1FAKE 0xfa100 /* read: fake1 */ -#define IS_HSCX_MASK 0xfff00 - -/* - * to prevent deactivating the "HSCX" when both channels are active we - * define an HSCX_ACTIVE flag which is or'd into the channel's state - * flag in avm_pnp_bchannel_setup upon active and cleared upon deactivation. - * It is set high to allow room for new flags. - */ -#define HSCX_AVMPNP_ACTIVE 0x1000 - -/*---------------------------------------------------------------------------* - * AVM read fifo routines - *---------------------------------------------------------------------------*/ - -static void -avm_pnp_read_fifo(void *buf, const void *base, size_t len) -{ - int unit; - struct isic_softc *sc; - - unit = (int)base & 0xff; - sc = &isic_sc[unit]; - - /* check whether the target is an HSCX */ - if (((int)base & IS_HSCX_MASK) == HSCX0FAKE) - { - hscx_read_fifo(0, buf, len, sc); - return; - } - if (((int)base & IS_HSCX_MASK) == HSCX1FAKE) - { - hscx_read_fifo(1, buf, len, sc); - return; - } - /* tell the board to access the ISAC fifo */ - outb(sc->sc_port + ADDR_REG_OFFSET, ISAC_FIFO); - insb(sc->sc_port + ISAC_REG_OFFSET, (u_char *)buf, len); -} - -static void -hscx_read_fifo(int chan, void *buf, size_t len, struct isic_softc *sc) -{ - u_char *ip; - size_t cnt; - - outb(sc->sc_port + ADDR_REG_OFFSET, chan); - ip = (u_char *)buf; - cnt = 0; - - while (cnt < len) - { - *ip++ = inb(sc->sc_port + ISAC_REG_OFFSET); - cnt++; - } -} - -/*---------------------------------------------------------------------------* - * AVM write fifo routines - *---------------------------------------------------------------------------*/ -static void -avm_pnp_write_fifo(void *base, const void *buf, size_t len) -{ - int unit; - struct isic_softc *sc; - - unit = (int)base & 0xff; - sc = &isic_sc[unit]; - - /* check whether the target is an HSCX */ - if (((int)base & IS_HSCX_MASK) == HSCX0FAKE) - { - hscx_write_fifo(0, buf, len, sc); - return; - } - if (((int)base & IS_HSCX_MASK) == HSCX1FAKE) - { - hscx_write_fifo(1, buf, len, sc); - return; - } - /* tell the board to use the ISAC fifo */ - outb(sc->sc_port + ADDR_REG_OFFSET, ISAC_FIFO); - outsb(sc->sc_port + ISAC_REG_OFFSET, (const u_char *)buf, len); -} - -static void -hscx_write_fifo(int chan, const void *buf, size_t len, struct isic_softc *sc) -{ - register const u_char *ip; - register size_t cnt; - isic_Bchan_t *Bchan = &sc->sc_chan[chan]; - - sc->avma1pp_cmd &= ~HSCX_CMD_XME; - sc->avma1pp_txl = 0; - - if (Bchan->out_mbuf_cur == NULL && Bchan->bprot != BPROT_NONE) - sc->avma1pp_cmd |= HSCX_CMD_XME; - - if (len != sc->sc_bfifolen) - sc->avma1pp_txl = len; - - hscx_write_reg(chan, HSCX_STAT, sc, 3); - - ip = (const u_char *)buf; - cnt = 0; - while (cnt < len) - { - outb(sc->sc_port + ISAC_REG_OFFSET, *ip++); - cnt++; - } -} - -/*---------------------------------------------------------------------------* - * AVM write register routines - *---------------------------------------------------------------------------*/ -static void -avm_pnp_write_reg(u_char *base, u_int offset, u_int v) -{ - int unit; - struct isic_softc *sc; - u_char reg_bank; - - unit = (int)base & 0xff; - sc = &isic_sc[unit]; - - /* check whether the target is an HSCX */ - if (((int)base & IS_HSCX_MASK) == HSCX0FAKE) - { - hscx_write_reg_val(0, offset, v, sc); - return; - } - if (((int)base & IS_HSCX_MASK) == HSCX1FAKE) - { - hscx_write_reg_val(1, offset, v, sc); - return; - } - /* must be the ISAC */ - reg_bank = (offset > MAX_LO_REG_OFFSET) ? ISAC_HI_REG_OFFSET:ISAC_LO_REG_OFFSET; - /* set the register bank */ - outb(sc->sc_port + ADDR_REG_OFFSET, reg_bank); - outb(sc->sc_port + ISAC_REG_OFFSET + (offset & ISAC_REGSET_MASK), v); -} - -static void -hscx_write_reg(int chan, u_int off, struct isic_softc *sc, int which) -{ - /* HACK */ - if (off == H_MASK) - return; - /* point at the correct channel */ - outb(sc->sc_port + ADDR_REG_OFFSET, chan); - if (which & 4) - outb(sc->sc_port + ISAC_REG_OFFSET + off + 2, sc->avma1pp_prot); - if (which & 2) - outb(sc->sc_port + ISAC_REG_OFFSET + off + 1, sc->avma1pp_txl); - if (which & 1) - outb(sc->sc_port + ISAC_REG_OFFSET + off, sc->avma1pp_cmd); -} - -static void -hscx_write_reg_val(int chan, u_int off, u_char val, struct isic_softc *sc) -{ - /* HACK */ - if (off == H_MASK) - return; - /* point at the correct channel */ - outb(sc->sc_port + ADDR_REG_OFFSET, chan); - outb(sc->sc_port + ISAC_REG_OFFSET + off, val); -} - -/*---------------------------------------------------------------------------* - * AVM read register routines - *---------------------------------------------------------------------------*/ - -static u_char -avm_pnp_read_reg(u_char *base, u_int offset) -{ - int unit; - struct isic_softc *sc; - u_char reg_bank; - - unit = (int)base & 0xff; - sc = &isic_sc[unit]; - - /* check whether the target is an HSCX */ - if (((int)base & IS_HSCX_MASK) == HSCX0FAKE) - return(hscx_read_reg(0, offset, sc)); - if (((int)base & IS_HSCX_MASK) == HSCX1FAKE) - return(hscx_read_reg(1, offset, sc)); - /* must be the ISAC */ - reg_bank = (offset > MAX_LO_REG_OFFSET) ? ISAC_HI_REG_OFFSET:ISAC_LO_REG_OFFSET; - /* set the register bank */ - outb(sc->sc_port + ADDR_REG_OFFSET, reg_bank); - return(inb(sc->sc_port + ISAC_REG_OFFSET + - (offset & ISAC_REGSET_MASK))); -} - -static u_char -hscx_read_reg(int chan, u_int off, struct isic_softc *sc) -{ - /* HACK */ - if (off == H_ISTA) - return(0); - /* point at the correct channel */ - outb(sc->sc_port + ADDR_REG_OFFSET, chan); - return(inb(sc->sc_port + ISAC_REG_OFFSET + off)); -} - -/*---------------------------------------------------------------------------* - * isic_probe_avm_pnp - probe Fritz!Card PnP - *---------------------------------------------------------------------------*/ - -int -isic_probe_avm_pnp(struct isa_device *dev, unsigned int iobase2) -{ - struct isic_softc *sc = &isic_sc[dev->id_unit]; - - /* check max unit range */ - - if(dev->id_unit >= ISIC_MAXUNIT) - { - printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for AVM Fritz! PnP\n", - dev->id_unit, dev->id_unit); - return(0); - } - sc->sc_unit = dev->id_unit; - - /* check IRQ validity */ - - switch(ffs(dev->id_irq) - 1) - { - case 3: - case 4: - case 5: - case 7: - case 10: - case 11: - case 12: - case 15: - break; - - default: - printf("isic%d: Error, invalid IRQ [%d] specified for AVM Fritz! PnP!\n", - dev->id_unit, ffs(dev->id_irq)-1); - return(0); - break; - } - sc->sc_irq = dev->id_irq; - - dev->id_intr = (driver_intr_t *) avm_pnp_intr; - - /* check if memory addr specified */ - - if(dev->id_maddr) - { - printf("isic%d: Error, mem addr 0x%lx specified for AVM Fritz! PnP!\n", - dev->id_unit, (u_long)dev->id_maddr); - return(0); - } - dev->id_msize = 0; - - /* check if we got an iobase */ - - if(!((dev->id_iobase >= 0x160) && (dev->id_iobase <= 0x360))) - { - printf("isic%d: Error, invalid iobase 0x%x specified for AVM Fritz! PnP!\n", - dev->id_unit, dev->id_iobase); - return(0); - } - sc->sc_port = dev->id_iobase; - - - /* setup access routines */ - - sc->clearirq = NULL; - sc->readreg = avm_pnp_read_reg; - sc->writereg = avm_pnp_write_reg; - - sc->readfifo = avm_pnp_read_fifo; - sc->writefifo = avm_pnp_write_fifo; - - /* setup card type */ - - sc->sc_cardtyp = CARD_TYPEP_AVM_PNP; - - /* setup IOM bus type */ - - sc->sc_bustyp = BUS_TYPE_IOM2; - - sc->sc_ipac = 0; - sc->sc_bfifolen = HSCX_FIFO_LEN; - - /* the ISAC lives at offset 0x10, but we can't use that. */ - /* instead, put the unit number into the lower byte - HACK */ - ISAC_BASE = (caddr_t)((int)(dev->id_iobase & ~0xff) + dev->id_unit); - - outb(sc->sc_port + STAT0_OFFSET, ASL_RESET_ALL|ASL_TIMERDISABLE); - ISAC_WRITE(I_MASK, 0x0); - outb(sc->sc_port + STAT0_OFFSET, ASL_TIMERRESET|ASL_ENABLE_INT|ASL_TIMERDISABLE); - ISAC_WRITE(I_MASK, 0x41); - return (1); -} - -/*---------------------------------------------------------------------------* - * isic_attach_avm_pnp - attach Fritz!Card PnP - *---------------------------------------------------------------------------*/ -int -isic_attach_avm_pnp(struct isa_device *dev, unsigned int iobase2) -{ - struct isic_softc *sc; - u_int v; - int unit; - - unit = dev->id_unit; - sc = &isic_sc[unit]; - - /* this thing doesn't have an HSCX, so fake the base addresses */ - /* put the unit number into the lower byte - HACK */ - HSCX_A_BASE = (caddr_t)(HSCX0FAKE + unit); - HSCX_B_BASE = (caddr_t)(HSCX1FAKE + unit); - - - /* reset the card */ - - /* the Linux driver does this to clear any pending ISAC interrupts */ - v = 0; - v = ISAC_READ(I_STAR); - v = ISAC_READ(I_MODE); - v = ISAC_READ(I_ADF2); - v = ISAC_READ(I_ISTA); - if (v & ISAC_ISTA_EXI) - { - v = ISAC_READ(I_EXIR); - } - v = ISAC_READ(I_CIRR); - ISAC_WRITE(I_MASK, 0xff); - - /* the Linux driver does this to clear any pending HSCX interrupts */ - v = hscx_read_reg(0, HSCX_STAT, sc); - v = hscx_read_reg(0, HSCX_STAT+1, sc); - v = hscx_read_reg(0, HSCX_STAT+2, sc); - v = hscx_read_reg(0, HSCX_STAT+3, sc); - v = hscx_read_reg(1, HSCX_STAT, sc); - v = hscx_read_reg(1, HSCX_STAT+1, sc); - v = hscx_read_reg(1, HSCX_STAT+2, sc); - v = hscx_read_reg(1, HSCX_STAT+3, sc); - - outb(sc->sc_port + STAT0_OFFSET, ASL_RESET_ALL|ASL_TIMERDISABLE); - DELAY(SEC_DELAY/100); /* 10 ms */ - outb(sc->sc_port + STAT0_OFFSET, ASL_TIMERRESET|ASL_ENABLE_INT|ASL_TIMERDISABLE); - DELAY(SEC_DELAY/100); /* 10 ms */ - outb(sc->sc_port + STAT1_OFFSET, ASL1_ENABLE_IOM+(ffs(sc->sc_irq)-1)); - DELAY(SEC_DELAY/100); /* 10 ms */ - - printf("isic%d: ISAC %s (IOM-%c)\n", unit, - "2085 Version A1/A2 or 2086/2186 Version 1.1", - sc->sc_bustyp == BUS_TYPE_IOM1 ? '1' : '2'); - - /* init the ISAC */ - isic_isac_init(sc); - - /* init the "HSCX" */ - avm_pnp_bchannel_setup(sc->sc_unit, HSCX_CH_A, BPROT_NONE, 0); - - avm_pnp_bchannel_setup(sc->sc_unit, HSCX_CH_B, BPROT_NONE, 0); - - /* can't use the normal B-Channel stuff */ - avm_pnp_init_linktab(sc); - - /* set trace level */ - - sc->sc_trace = TRACE_OFF; - - sc->sc_state = ISAC_IDLE; - - sc->sc_ibuf = NULL; - sc->sc_ib = NULL; - sc->sc_ilen = 0; - - sc->sc_obuf = NULL; - sc->sc_op = NULL; - sc->sc_ol = 0; - sc->sc_freeflag = 0; - - sc->sc_obuf2 = NULL; - sc->sc_freeflag2 = 0; - -#if defined(__FreeBSD__) && __FreeBSD__ >=3 - callout_handle_init(&sc->sc_T3_callout); - callout_handle_init(&sc->sc_T4_callout); -#endif - - /* init higher protocol layers */ - - MPH_Status_Ind(sc->sc_unit, STI_ATTACH, sc->sc_cardtyp); - - return(0); -} - -/* - * this is the real interrupt routine - */ -static void -avm_pnp_hscx_intr(int h_chan, int stat, int cnt, struct isic_softc *sc) -{ - register isic_Bchan_t *chan = &sc->sc_chan[h_chan]; - int activity = -1; - - DBGL1(L1_H_IRQ, "avm_pnp_hscx_intr", ("%#x\n", stat)); - - if((stat & HSCX_INT_XDU) && (chan->bprot != BPROT_NONE))/* xmit data underrun */ - { - chan->stat_XDU++; - DBGL1(L1_H_XFRERR, "avm_pnp_hscx_intr", ("xmit data underrun\n")); - /* abort the transmission */ - sc->avma1pp_txl = 0; - sc->avma1pp_cmd |= HSCX_CMD_XRS; - hscx_write_reg(h_chan, HSCX_STAT, sc, 1); - sc->avma1pp_cmd &= ~HSCX_CMD_XRS; - hscx_write_reg(h_chan, HSCX_STAT, sc, 1); - - if (chan->out_mbuf_head != NULL) /* don't continue to transmit this buffer */ - { - i4b_Bfreembuf(chan->out_mbuf_head); - chan->out_mbuf_cur = chan->out_mbuf_head = NULL; - } - } - - /* - * The following is based on examination of the Linux driver. - * - * The logic here is different than with a "real" HSCX; all kinds - * of information (interrupt/status bits) are in stat. - * HSCX_INT_RPR indicates a receive interrupt - * HSCX_STAT_RDO indicates an overrun condition, abort - - * otherwise read the bytes ((stat & HSCX_STZT_RML_MASK) >> 8) - * HSCX_STAT_RME indicates end-of-frame and apparently any - * CRC/framing errors are only reported in this state. - * if ((stat & HSCX_STAT_CRCVFRRAB) != HSCX_STAT_CRCVFR) - * CRC/framing error - */ - - if(stat & HSCX_INT_RPR) - { - register int fifo_data_len; - int error = 0; - /* always have to read the FIFO, so use a scratch buffer */ - u_char scrbuf[HSCX_FIFO_LEN]; - - if(stat & HSCX_STAT_RDO) - { - chan->stat_RDO++; - DBGL1(L1_H_XFRERR, "avm_pnp_hscx_intr", ("receive data overflow\n")); - error++; - } - - fifo_data_len = cnt; - - if(fifo_data_len == 0) - fifo_data_len = sc->sc_bfifolen; - - /* ALWAYS read data from HSCX fifo */ - - HSCX_RDFIFO(h_chan, scrbuf, fifo_data_len); - chan->rxcount += fifo_data_len; - - /* all error conditions checked, now decide and take action */ - - if(error == 0) - { - if(chan->in_mbuf == NULL) - { - if((chan->in_mbuf = i4b_Bgetmbuf(BCH_MAX_DATALEN)) == NULL) - panic("L1 avm_pnp_hscx_intr: RME, cannot allocate mbuf!\n"); - chan->in_cbptr = chan->in_mbuf->m_data; - chan->in_len = 0; - } - - if((chan->in_len + fifo_data_len) <= BCH_MAX_DATALEN) - { - /* OK to copy the data */ - bcopy(scrbuf, chan->in_cbptr, fifo_data_len); - chan->in_cbptr += fifo_data_len; - chan->in_len += fifo_data_len; - - /* setup mbuf data length */ - - chan->in_mbuf->m_len = chan->in_len; - chan->in_mbuf->m_pkthdr.len = chan->in_len; - - - if(sc->sc_trace & TRACE_B_RX) - { - i4b_trace_hdr_t hdr; - hdr.unit = sc->sc_unit; - hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2); - hdr.dir = FROM_NT; - hdr.count = ++sc->sc_trace_bcount; - MICROTIME(hdr.time); - MPH_Trace_Ind(&hdr, chan->in_mbuf->m_len, chan->in_mbuf->m_data); - } - - if (stat & HSCX_STAT_RME) - { - if((stat & HSCX_STAT_CRCVFRRAB) == HSCX_STAT_CRCVFR) - { - (*chan->drvr_linktab->bch_rx_data_ready)(chan->drvr_linktab->unit); - activity = ACT_RX; - - /* mark buffer ptr as unused */ - - chan->in_mbuf = NULL; - chan->in_cbptr = NULL; - chan->in_len = 0; - } - else - { - chan->stat_CRC++; - DBGL1(L1_H_XFRERR, "avm_pnp_hscx_intr", ("CRC/RAB\n")); - if (chan->in_mbuf != NULL) - { - i4b_Bfreembuf(chan->in_mbuf); - chan->in_mbuf = NULL; - chan->in_cbptr = NULL; - chan->in_len = 0; - } - } - } - } /* END enough space in mbuf */ - else - { - if(chan->bprot == BPROT_NONE) - { - /* setup mbuf data length */ - - chan->in_mbuf->m_len = chan->in_len; - chan->in_mbuf->m_pkthdr.len = chan->in_len; - - if(sc->sc_trace & TRACE_B_RX) - { - i4b_trace_hdr_t hdr; - hdr.unit = sc->sc_unit; - hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2); - hdr.dir = FROM_NT; - hdr.count = ++sc->sc_trace_bcount; - MICROTIME(hdr.time); - MPH_Trace_Ind(&hdr, chan->in_mbuf->m_len, chan->in_mbuf->m_data); - } - - /* move rx'd data to rx queue */ - - IF_ENQUEUE(&chan->rx_queue, chan->in_mbuf); - - (*chan->drvr_linktab->bch_rx_data_ready)(chan->drvr_linktab->unit); - - if(!(isic_hscx_silence(chan->in_mbuf->m_data, chan->in_mbuf->m_len))) - activity = ACT_RX; - - /* alloc new buffer */ - - if((chan->in_mbuf = i4b_Bgetmbuf(BCH_MAX_DATALEN)) == NULL) - panic("L1 avm_pnp_hscx_intr: RPF, cannot allocate new mbuf!\n"); - - /* setup new data ptr */ - - chan->in_cbptr = chan->in_mbuf->m_data; - - /* OK to copy the data */ - bcopy(scrbuf, chan->in_cbptr, fifo_data_len); - - chan->in_cbptr += fifo_data_len; - chan->in_len = fifo_data_len; - - chan->rxcount += fifo_data_len; - } - else - { - DBGL1(L1_H_XFRERR, "avm_pnp_hscx_intr", ("RAWHDLC rx buffer overflow in RPF, in_len=%d\n", chan->in_len)); - chan->in_cbptr = chan->in_mbuf->m_data; - chan->in_len = 0; - } - } - } /* if(error == 0) */ - else - { - /* land here for RDO */ - if (chan->in_mbuf != NULL) - { - i4b_Bfreembuf(chan->in_mbuf); - chan->in_mbuf = NULL; - chan->in_cbptr = NULL; - chan->in_len = 0; - } - sc->avma1pp_txl = 0; - sc->avma1pp_cmd |= HSCX_CMD_RRS; - hscx_write_reg(h_chan, HSCX_STAT, sc, 1); - sc->avma1pp_cmd &= ~HSCX_CMD_RRS; - hscx_write_reg(h_chan, HSCX_STAT, sc, 1); - } - } - - - /* transmit fifo empty, new data can be written to fifo */ - - if(stat & HSCX_INT_XPR) - { - /* - * for a description what is going on here, please have - * a look at isic_bchannel_start() in i4b_bchan.c ! - */ - - DBGL1(L1_H_IRQ, "avm_pnp_hscx_intr", ("unit %d, chan %d - XPR, Tx Fifo Empty!\n", sc->sc_unit, h_chan)); - - if(chan->out_mbuf_cur == NULL || chan->out_mbuf_head == NULL) /* last frame is transmitted */ - { - IF_DEQUEUE(&chan->tx_queue, chan->out_mbuf_head); - - if(chan->out_mbuf_head == NULL) - { - chan->state &= ~HSCX_TX_ACTIVE; - (*chan->drvr_linktab->bch_tx_queue_empty)(chan->drvr_linktab->unit); - } - else - { - chan->state |= HSCX_TX_ACTIVE; - chan->out_mbuf_cur = chan->out_mbuf_head; - chan->out_mbuf_cur_ptr = chan->out_mbuf_cur->m_data; - chan->out_mbuf_cur_len = chan->out_mbuf_cur->m_len; - - if(sc->sc_trace & TRACE_B_TX) - { - i4b_trace_hdr_t hdr; - hdr.unit = sc->sc_unit; - hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2); - hdr.dir = FROM_TE; - hdr.count = ++sc->sc_trace_bcount; - MICROTIME(hdr.time); - MPH_Trace_Ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data); - } - if(chan->bprot == BPROT_NONE) - { - if(!(isic_hscx_silence(chan->out_mbuf_cur->m_data, chan->out_mbuf_cur->m_len))) - activity = ACT_TX; - } - else - { - activity = ACT_TX; - } - } - } - - isic_hscx_fifo(chan, sc); - } - - /* call timeout handling routine */ - - if(activity == ACT_RX || activity == ACT_TX) - (*chan->drvr_linktab->bch_activity)(chan->drvr_linktab->unit, activity); -} - -/* - * this is the main routine which checks each channel and then calls - * the real interrupt routine as appropriate - */ -static void -avm_pnp_hscx_int_handler(struct isic_softc *sc) -{ - u_char stat = 0; - u_char cnt = 0; - - stat = hscx_read_reg(0, HSCX_STAT, sc); - if (stat & HSCX_INT_RPR) - cnt = hscx_read_reg(0, HSCX_STAT+1, sc); - if (stat & HSCX_INT_MASK) - avm_pnp_hscx_intr(0, stat, cnt, sc); - - cnt = 0; - stat = hscx_read_reg(1, HSCX_STAT, sc); - if (stat & HSCX_INT_RPR) - cnt = hscx_read_reg(1, HSCX_STAT+1, sc); - if (stat & HSCX_INT_MASK) - avm_pnp_hscx_intr(1, stat, cnt, sc); -} - -static void -avm_pnp_hscx_init(struct isic_softc *sc, int h_chan, int activate) -{ - isic_Bchan_t *chan = &sc->sc_chan[h_chan]; - - DBGL1(L1_BCHAN, "avm_pnp_hscx_init", ("unit=%d, channel=%d, %s\n", - sc->sc_unit, h_chan, activate ? "activate" : "deactivate")); - - if (activate == 0) - { - /* only deactivate if both channels are idle */ - if (sc->sc_chan[HSCX_CH_A].state != HSCX_IDLE || - sc->sc_chan[HSCX_CH_B].state != HSCX_IDLE) - { - return; - } - sc->avma1pp_cmd = HSCX_CMD_XRS|HSCX_CMD_RRS; - sc->avma1pp_prot = HSCX_MODE_TRANS; - hscx_write_reg(h_chan, HSCX_STAT, sc, 5); - return; - } - if(chan->bprot == BPROT_RHDLC) - { - DBGL1(L1_BCHAN, "avm_pnp_hscx_init", ("BPROT_RHDLC\n")); - - /* HDLC Frames, transparent mode 0 */ - sc->avma1pp_cmd = HSCX_CMD_XRS|HSCX_CMD_RRS; - sc->avma1pp_prot = HSCX_MODE_ITF_FLG; - hscx_write_reg(h_chan, HSCX_STAT, sc, 5); - sc->avma1pp_cmd = HSCX_CMD_XRS; - hscx_write_reg(h_chan, HSCX_STAT, sc, 1); - sc->avma1pp_cmd = 0; - } - else - { - DBGL1(L1_BCHAN, "avm_pnp_hscx_init", ("BPROT_NONE??\n")); - - /* Raw Telephony, extended transparent mode 1 */ - sc->avma1pp_cmd = HSCX_CMD_XRS|HSCX_CMD_RRS; - sc->avma1pp_prot = HSCX_MODE_TRANS; - hscx_write_reg(h_chan, HSCX_STAT, sc, 5); - sc->avma1pp_cmd = HSCX_CMD_XRS; - hscx_write_reg(h_chan, HSCX_STAT, sc, 1); - sc->avma1pp_cmd = 0; - } -} - -static void -avm_pnp_bchannel_setup(int unit, int h_chan, int bprot, int activate) -{ - struct isic_softc *sc = &isic_sc[unit]; - isic_Bchan_t *chan = &sc->sc_chan[h_chan]; - - int s = SPLI4B(); - - if(activate == 0) - { - /* deactivation */ - chan->state &= ~HSCX_AVMPNP_ACTIVE; - avm_pnp_hscx_init(sc, h_chan, activate); - } - - DBGL1(L1_BCHAN, "avm_pnp_bchannel_setup", ("unit=%d, channel=%d, %s\n", - sc->sc_unit, h_chan, activate ? "activate" : "deactivate")); - - /* general part */ - - chan->unit = sc->sc_unit; /* unit number */ - chan->channel = h_chan; /* B channel */ - chan->bprot = bprot; /* B channel protocol */ - chan->state = HSCX_IDLE; /* B channel state */ - - /* receiver part */ - - i4b_Bcleanifq(&chan->rx_queue); /* clean rx queue */ - - chan->rx_queue.ifq_maxlen = IFQ_MAXLEN; - - chan->rxcount = 0; /* reset rx counter */ - - i4b_Bfreembuf(chan->in_mbuf); /* clean rx mbuf */ - - chan->in_mbuf = NULL; /* reset mbuf ptr */ - chan->in_cbptr = NULL; /* reset mbuf curr ptr */ - chan->in_len = 0; /* reset mbuf data len */ - - /* transmitter part */ - - i4b_Bcleanifq(&chan->tx_queue); /* clean tx queue */ - - chan->tx_queue.ifq_maxlen = IFQ_MAXLEN; - - chan->txcount = 0; /* reset tx counter */ - - i4b_Bfreembuf(chan->out_mbuf_head); /* clean tx mbuf */ - - chan->out_mbuf_head = NULL; /* reset head mbuf ptr */ - chan->out_mbuf_cur = NULL; /* reset current mbuf ptr */ - chan->out_mbuf_cur_ptr = NULL; /* reset current mbuf data ptr */ - chan->out_mbuf_cur_len = 0; /* reset current mbuf data cnt */ - - if(activate != 0) - { - /* activation */ - avm_pnp_hscx_init(sc, h_chan, activate); - chan->state |= HSCX_AVMPNP_ACTIVE; - } - - splx(s); -} - -static void -avm_pnp_bchannel_start(int unit, int h_chan) -{ - struct isic_softc *sc = &isic_sc[unit]; - register isic_Bchan_t *chan = &sc->sc_chan[h_chan]; - int s; - int activity = -1; - - s = SPLI4B(); /* enter critical section */ - if(chan->state & HSCX_TX_ACTIVE) /* already running ? */ - { - splx(s); - return; /* yes, leave */ - } - - /* get next mbuf from queue */ - - IF_DEQUEUE(&chan->tx_queue, chan->out_mbuf_head); - - if(chan->out_mbuf_head == NULL) /* queue empty ? */ - { - splx(s); /* leave critical section */ - return; /* yes, exit */ - } - - /* init current mbuf values */ - - chan->out_mbuf_cur = chan->out_mbuf_head; - chan->out_mbuf_cur_len = chan->out_mbuf_cur->m_len; - chan->out_mbuf_cur_ptr = chan->out_mbuf_cur->m_data; - - /* activity indicator for timeout handling */ - - if(chan->bprot == BPROT_NONE) - { - if(!(isic_hscx_silence(chan->out_mbuf_cur->m_data, chan->out_mbuf_cur->m_len))) - activity = ACT_TX; - } - else - { - activity = ACT_TX; - } - - chan->state |= HSCX_TX_ACTIVE; /* we start transmitting */ - - if(sc->sc_trace & TRACE_B_TX) /* if trace, send mbuf to trace dev */ - { - i4b_trace_hdr_t hdr; - hdr.unit = unit; - hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2); - hdr.dir = FROM_TE; - hdr.count = ++sc->sc_trace_bcount; - MICROTIME(hdr.time); - MPH_Trace_Ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data); - } - - isic_hscx_fifo(chan, sc); - - /* call timeout handling routine */ - - if(activity == ACT_RX || activity == ACT_TX) - (*chan->drvr_linktab->bch_activity)(chan->drvr_linktab->unit, activity); - - splx(s); -} - -/*---------------------------------------------------------------------------* - * return the address of isic drivers linktab - *---------------------------------------------------------------------------*/ -static isdn_link_t * -avm_pnp_ret_linktab(int unit, int channel) -{ - struct isic_softc *sc = &isic_sc[unit]; - isic_Bchan_t *chan = &sc->sc_chan[channel]; - - return(&chan->isdn_linktab); -} - -/*---------------------------------------------------------------------------* - * set the driver linktab in the b channel softc - *---------------------------------------------------------------------------*/ -static void -avm_pnp_set_linktab(int unit, int channel, drvr_link_t *dlt) -{ - struct isic_softc *sc = &isic_sc[unit]; - isic_Bchan_t *chan = &sc->sc_chan[channel]; - - chan->drvr_linktab = dlt; -} - - -/*---------------------------------------------------------------------------* - * initialize our local linktab - *---------------------------------------------------------------------------*/ -static void -avm_pnp_init_linktab(struct isic_softc *sc) -{ - isic_Bchan_t *chan = &sc->sc_chan[HSCX_CH_A]; - isdn_link_t *lt = &chan->isdn_linktab; - - /* make sure the hardware driver is known to layer 4 */ - /* avoid overwriting if already set */ - if (ctrl_types[CTRL_PASSIVE].set_linktab == NULL) - { - ctrl_types[CTRL_PASSIVE].set_linktab = avm_pnp_set_linktab; - ctrl_types[CTRL_PASSIVE].get_linktab = avm_pnp_ret_linktab; - } - - /* local setup */ - lt->unit = sc->sc_unit; - lt->channel = HSCX_CH_A; - lt->bch_config = avm_pnp_bchannel_setup; - lt->bch_tx_start = avm_pnp_bchannel_start; - lt->bch_stat = avm_pnp_bchannel_stat; - lt->tx_queue = &chan->tx_queue; - - /* used by non-HDLC data transfers, i.e. telephony drivers */ - lt->rx_queue = &chan->rx_queue; - - /* used by HDLC data transfers, i.e. ipr and isp drivers */ - lt->rx_mbuf = &chan->in_mbuf; - - chan = &sc->sc_chan[HSCX_CH_B]; - lt = &chan->isdn_linktab; - - lt->unit = sc->sc_unit; - lt->channel = HSCX_CH_B; - lt->bch_config = avm_pnp_bchannel_setup; - lt->bch_tx_start = avm_pnp_bchannel_start; - lt->bch_stat = avm_pnp_bchannel_stat; - lt->tx_queue = &chan->tx_queue; - - /* used by non-HDLC data transfers, i.e. telephony drivers */ - lt->rx_queue = &chan->rx_queue; - - /* used by HDLC data transfers, i.e. ipr and isp drivers */ - lt->rx_mbuf = &chan->in_mbuf; -} - -/* - * use this instead of isic_bchannel_stat in i4b_bchan.c because it's static - */ -static void -avm_pnp_bchannel_stat(int unit, int h_chan, bchan_statistics_t *bsp) -{ - struct isic_softc *sc = &isic_sc[unit]; - isic_Bchan_t *chan = &sc->sc_chan[h_chan]; - int s; - - s = SPLI4B(); - - bsp->outbytes = chan->txcount; - bsp->inbytes = chan->rxcount; - - chan->txcount = 0; - chan->rxcount = 0; - - splx(s); -} - -/*---------------------------------------------------------------------------* - * fill HSCX fifo with data from the current mbuf - * Put this here until it can go into i4b_hscx.c - *---------------------------------------------------------------------------*/ -static int -isic_hscx_fifo(isic_Bchan_t *chan, struct isic_softc *sc) -{ - int len; - int nextlen; - int i; - /* using a scratch buffer simplifies writing to the FIFO */ - u_char scrbuf[HSCX_FIFO_LEN]; - - len = 0; - - /* - * fill the HSCX tx fifo with data from the current mbuf. if - * current mbuf holds less data than HSCX fifo length, try to - * get the next mbuf from (a possible) mbuf chain. if there is - * not enough data in a single mbuf or in a chain, then this - * is the last mbuf and we tell the HSCX that it has to send - * CRC and closing flag - */ - - while(chan->out_mbuf_cur && len != sc->sc_bfifolen) - { - nextlen = min(chan->out_mbuf_cur_len, sc->sc_bfifolen - len); - -#ifdef NOTDEF - printf("i:mh=%p, mc=%p, mcp=%p, mcl=%d l=%d nl=%d # ", - chan->out_mbuf_head, - chan->out_mbuf_cur, - chan->out_mbuf_cur_ptr, - chan->out_mbuf_cur_len, - len, - nextlen); -#endif - - /* collect the data in the scratch buffer */ - for (i = 0; i < nextlen; i++) - scrbuf[i + len] = chan->out_mbuf_cur_ptr[i]; - - len += nextlen; - chan->txcount += nextlen; - - chan->out_mbuf_cur_ptr += nextlen; - chan->out_mbuf_cur_len -= nextlen; - - if(chan->out_mbuf_cur_len == 0) - { - if((chan->out_mbuf_cur = chan->out_mbuf_cur->m_next) != NULL) - { - chan->out_mbuf_cur_ptr = chan->out_mbuf_cur->m_data; - chan->out_mbuf_cur_len = chan->out_mbuf_cur->m_len; - - if(sc->sc_trace & TRACE_B_TX) - { - i4b_trace_hdr_t hdr; - hdr.unit = sc->sc_unit; - hdr.type = (chan->channel == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2); - hdr.dir = FROM_TE; - hdr.count = ++sc->sc_trace_bcount; - MICROTIME(hdr.time); - MPH_Trace_Ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data); - } - } - else - { - i4b_Bfreembuf(chan->out_mbuf_head); - chan->out_mbuf_head = NULL; - } - } - } - /* write what we have from the scratch buf to the HSCX fifo */ - if (len != 0) - HSCX_WRFIFO(chan->channel, scrbuf, len); - - return(0); -} - -void -avm_pnp_intr(int unit) -{ - struct isic_softc *sc; - u_char stat; - register u_char isac_irq_stat; - int was_isac = 0; - - sc = &isic_sc[unit]; - - for(;;) { - stat = inb(sc->sc_port + STAT0_OFFSET); - - DBGL1(L1_H_IRQ, "avm_pnp_intr", ("stat %x\n", stat)); - - /* was there an interrupt from this card ? */ - if ((stat & ASL_IRQ_Pending) == ASL_IRQ_Pending) - break; /* no */ - - /* interrupts are low active */ - if (!(stat & ASL_IRQ_TIMER)) - DBGL1(L1_H_IRQ, "avm_pnp_intr", ("timer interrupt ???\n")); - - if (!(stat & ASL_IRQ_ISAC)) - { - DBGL1(L1_H_IRQ, "avm_pnp_intr", ("ISAC\n")); - isac_irq_stat = ISAC_READ(I_ISTA); - isic_isac_irq(sc, isac_irq_stat); - was_isac = 1; - } - - if (!(stat & ASL_IRQ_HSCX)) - { - DBGL1(L1_H_IRQ, "avm_pnp_intr", ("HSCX\n")); - avm_pnp_hscx_int_handler(sc); - } - } - if (was_isac) { - ISAC_WRITE(0x20, 0xFF); - ISAC_WRITE(0x20, 0x0); - } -} -#endif /* NISIC > 0 && defined(AVM_PNP) */ -#endif /* FreeBSD */ diff --git a/sys/i4b/layer1/i4b_bchan.c b/sys/i4b/layer1/i4b_bchan.c deleted file mode 100644 index d2a1a7c..0000000 --- a/sys/i4b/layer1/i4b_bchan.c +++ /dev/null @@ -1,437 +0,0 @@ -/* - * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - *--------------------------------------------------------------------------- - * - * i4b_bchan.c - B channel handling L1 procedures - * ---------------------------------------------- - * - * $Id: i4b_bchan.c,v 1.2 1999/12/13 21:25:26 hm Exp $ - * - * $FreeBSD$ - * - * last edit-date: [Mon Dec 13 21:59:11 1999] - * - *---------------------------------------------------------------------------*/ - -#include "isic.h" - -#if NISIC > 0 - -#include -#include -#include -#include - -#include - -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -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 - *---------------------------------------------------------------------------*/ -void -isic_bchannel_setup(int unit, int h_chan, int bprot, int activate) -{ - struct l1_softc *sc = &l1_sc[unit]; - l1_bchan_state_t *chan = &sc->sc_chan[h_chan]; - - int s = SPLI4B(); - - if(activate == 0) - { - /* deactivation */ - 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")); - - /* general part */ - - chan->unit = sc->sc_unit; /* unit number */ - chan->channel = h_chan; /* B channel */ - chan->bprot = bprot; /* B channel protocol */ - chan->state = HSCX_IDLE; /* B channel state */ - - /* receiver part */ - - i4b_Bcleanifq(&chan->rx_queue); /* clean rx queue */ - - chan->rx_queue.ifq_maxlen = IFQ_MAXLEN; - - chan->rxcount = 0; /* reset rx counter */ - - i4b_Bfreembuf(chan->in_mbuf); /* clean rx mbuf */ - - chan->in_mbuf = NULL; /* reset mbuf ptr */ - chan->in_cbptr = NULL; /* reset mbuf curr ptr */ - chan->in_len = 0; /* reset mbuf data len */ - - /* transmitter part */ - - i4b_Bcleanifq(&chan->tx_queue); /* clean tx queue */ - - chan->tx_queue.ifq_maxlen = IFQ_MAXLEN; - - chan->txcount = 0; /* reset tx counter */ - - i4b_Bfreembuf(chan->out_mbuf_head); /* clean tx mbuf */ - - chan->out_mbuf_head = NULL; /* reset head mbuf ptr */ - chan->out_mbuf_cur = NULL; /* reset current mbuf ptr */ - chan->out_mbuf_cur_ptr = NULL; /* reset current mbuf data ptr */ - chan->out_mbuf_cur_len = 0; /* reset current mbuf data cnt */ - - if(activate != 0) - { - /* activation */ - isic_hscx_init(sc, h_chan, activate); - } - - splx(s); -} - -/*---------------------------------------------------------------------------* - * start transmission on a b channel - *---------------------------------------------------------------------------*/ -static void -isic_bchannel_start(int unit, int h_chan) -{ - struct l1_softc *sc = &l1_sc[unit]; - register l1_bchan_state_t *chan = &sc->sc_chan[h_chan]; - register int next_len; - register int len; - - int s; - int activity = -1; - int cmd = 0; - - s = SPLI4B(); /* enter critical section */ - if(chan->state & HSCX_TX_ACTIVE) /* already running ? */ - { - splx(s); - return; /* yes, leave */ - } - - /* get next mbuf from queue */ - - IF_DEQUEUE(&chan->tx_queue, chan->out_mbuf_head); - - if(chan->out_mbuf_head == NULL) /* queue empty ? */ - { - splx(s); /* leave critical section */ - return; /* yes, exit */ - } - - /* init current mbuf values */ - - chan->out_mbuf_cur = chan->out_mbuf_head; - chan->out_mbuf_cur_len = chan->out_mbuf_cur->m_len; - chan->out_mbuf_cur_ptr = chan->out_mbuf_cur->m_data; - - /* activity indicator for timeout handling */ - - if(chan->bprot == BPROT_NONE) - { - if(!(isic_hscx_silence(chan->out_mbuf_cur->m_data, chan->out_mbuf_cur->m_len))) - activity = ACT_TX; - } - else - { - activity = ACT_TX; - } - - chan->state |= HSCX_TX_ACTIVE; /* we start transmitting */ - - if(sc->sc_trace & TRACE_B_TX) /* if trace, send mbuf to trace dev */ - { - i4b_trace_hdr_t hdr; - hdr.unit = unit; - hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2); - hdr.dir = FROM_TE; - hdr.count = ++sc->sc_trace_bcount; - MICROTIME(hdr.time); - MPH_Trace_Ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data); - } - - len = 0; /* # of chars put into HSCX tx fifo this time */ - - /* - * fill the HSCX tx fifo with data from the current mbuf. if - * current mbuf holds less data than HSCX fifo length, try to - * get the next mbuf from (a possible) mbuf chain. if there is - * not enough data in a single mbuf or in a chain, then this - * is the last mbuf and we tell the HSCX that it has to send - * CRC and closing flag - */ - - while((len < sc->sc_bfifolen) && chan->out_mbuf_cur) - { - /* - * put as much data into the HSCX fifo as is - * available from the current mbuf - */ - - if((len + chan->out_mbuf_cur_len) >= sc->sc_bfifolen) - next_len = sc->sc_bfifolen - len; - else - next_len = chan->out_mbuf_cur_len; - -#ifdef NOTDEF - printf("b:mh=%x, mc=%x, mcp=%x, mcl=%d l=%d nl=%d # ", - chan->out_mbuf_head, - chan->out_mbuf_cur, - chan->out_mbuf_cur_ptr, - chan->out_mbuf_cur_len, - len, - next_len); -#endif - - /* wait for tx fifo write enabled */ - - isic_hscx_waitxfw(sc, h_chan); - - /* write what we have from current mbuf to HSCX fifo */ - - HSCX_WRFIFO(h_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 = unit; - hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2); - hdr.dir = FROM_TE; - hdr.count = ++sc->sc_trace_bcount; - MICROTIME(hdr.time); - MPH_Trace_Ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data); - } - } - } - - /* - * if 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 HSCX. 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 HSCX tx fifo is done in the - * HSCX interrupt routine. - */ - - cmd |= HSCX_CMDR_XTF; - } - else - { - /* end of mbuf chain */ - - if(chan->bprot == BPROT_NONE) - cmd |= HSCX_CMDR_XTF; - else - cmd |= HSCX_CMDR_XTF | HSCX_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->drvr_linktab->bch_activity)(chan->drvr_linktab->unit, activity); - - if(cmd) - isic_hscx_cmd(sc, h_chan, cmd); - - splx(s); -} - -/*---------------------------------------------------------------------------* - * fill statistics struct - *---------------------------------------------------------------------------*/ -static void -isic_bchannel_stat(int unit, int h_chan, bchan_statistics_t *bsp) -{ - struct l1_softc *sc = &l1_sc[unit]; - l1_bchan_state_t *chan = &sc->sc_chan[h_chan]; - int s; - - s = SPLI4B(); - - bsp->outbytes = chan->txcount; - bsp->inbytes = chan->rxcount; - - chan->txcount = 0; - chan->rxcount = 0; - - splx(s); -} - -/*---------------------------------------------------------------------------* - * return the address of isic drivers linktab - *---------------------------------------------------------------------------*/ -static 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); -} - -/*---------------------------------------------------------------------------* - * set the driver linktab in the b channel softc - *---------------------------------------------------------------------------*/ -static 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; -} - -/*---------------------------------------------------------------------------* - * initialize our local linktab - *---------------------------------------------------------------------------*/ -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; - - /* 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; - - /* local setup */ - lt->unit = sc->sc_unit; - lt->channel = HSCX_CH_A; - lt->bch_config = isic_bchannel_setup; - lt->bch_tx_start = isic_bchannel_start; - lt->bch_stat = isic_bchannel_stat; - lt->tx_queue = &chan->tx_queue; - - /* used by non-HDLC data transfers, i.e. telephony drivers */ - lt->rx_queue = &chan->rx_queue; - - /* used by HDLC data transfers, i.e. ipr and isp drivers */ - lt->rx_mbuf = &chan->in_mbuf; - - chan = &sc->sc_chan[HSCX_CH_B]; - lt = &chan->isdn_linktab; - - lt->unit = sc->sc_unit; - lt->channel = HSCX_CH_B; - lt->bch_config = isic_bchannel_setup; - lt->bch_tx_start = isic_bchannel_start; - lt->bch_stat = isic_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; -} - -/*---------------------------------------------------------------------------* - * 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/i4b_ctx_s0P.c deleted file mode 100644 index 9597780..0000000 --- a/sys/i4b/layer1/i4b_ctx_s0P.c +++ /dev/null @@ -1,256 +0,0 @@ -/* - * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - *--------------------------------------------------------------------------- - * - * isic - I4B Siemens ISDN Chipset Driver for Creatix/Teles PnP - * ============================================================ - * - * $Id: i4b_ctx_s0P.c,v 1.4 1999/12/13 21:25:26 hm Exp $ - * - * $FreeBSD$ - * - * last edit-date: [Mon Dec 13 21:59:23 1999] - * - * 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 - * the same hardware and don't share the same PnP config - * information, once the base addresses are set, the - * offsets are same and therefore they can use the same - * driver. - * - *---------------------------------------------------------------------------*/ - -#include "isic.h" -#include "opt_i4b.h" - -#if (NISIC > 0) && (defined(CRTX_S0_P) || defined(TEL_S0_16_3_P)) - -#include -#include -#include -#include - -#include - -#include - -#include -#include - -#include - -#include -#include -#include - -#include -#include - -/*---------------------------------------------------------------------------* - * Creatix / Teles PnP ISAC get fifo routine - *---------------------------------------------------------------------------*/ -static void -ctxs0P_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[what+2]); - bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[what+2]); - bus_space_read_multi_1(t,h,0x3e,buf,size); -} - -/*---------------------------------------------------------------------------* - * Creatix / Teles PnP ISAC put fifo routine - *---------------------------------------------------------------------------*/ -static void -ctxs0P_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[what+2]); - bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[what+2]); - bus_space_write_multi_1(t,h,0x3e,buf,size); -} - -/*---------------------------------------------------------------------------* - * Creatix / Teles PnP ISAC put register routine - *---------------------------------------------------------------------------*/ -static void -ctxs0P_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[what+2]); - bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[what+2]); - bus_space_write_1(t,h,offs,data); -} - -/*---------------------------------------------------------------------------* - * Creatix / Teles PnP ISAC get register routine - *---------------------------------------------------------------------------*/ -static u_int8_t -ctxs0P_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[what+2]); - bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[what+2]); - return bus_space_read_1(t,h,offs); -} - -/*---------------------------------------------------------------------------* - * isic_attach_Cs0P - attach Creatix / Teles PnP - *---------------------------------------------------------------------------*/ -int -isic_attach_Cs0P(device_t dev) -{ - u_int32_t iobase1; - u_int32_t iobase2; - int unit = device_get_unit(dev); - struct l1_softc *sc = &l1_sc[unit]; - bus_space_tag_t t; - bus_space_handle_t h; - - /* - * this card needs a second io_base, - * free resources if we don't get it - */ - - sc->sc_resources.io_rid[1] = 1; - - if(!(sc->sc_resources.io_base[1] = - bus_alloc_resource(dev, SYS_RES_IOPORT, - &sc->sc_resources.io_rid[1], - 0UL, ~0UL, 1, RF_ACTIVE))) - { - printf("isic%d: Could not get io area 1 for Creatix / Teles PnP!\n", unit); - isic_detach_common(dev); - return ENXIO; - } - - /* remember the io base addresses */ - - iobase1 = rman_get_start(sc->sc_resources.io_base[0]); - iobase2 = rman_get_start(sc->sc_resources.io_base[1]); - - /* - * because overlapping resources are invalid, - * release the first io port resource - */ - - bus_release_resource(dev, SYS_RES_IOPORT, sc->sc_resources.io_rid[0], - sc->sc_resources.io_base[0]); - - /* set and allocate a base io address for the ISAC chip */ - - sc->sc_resources.io_rid[2] = 2; - - bus_set_resource(dev, SYS_RES_IOPORT, 2, iobase1-0x20, 0x40); - - if(!(sc->sc_resources.io_base[2] = - bus_alloc_resource(dev, SYS_RES_IOPORT, - &sc->sc_resources.io_rid[2], - 0ul, ~0ul, 1, RF_ACTIVE))) - { - printf("isic%d: Could not get io area 2 for Creatix / Teles PnP!\n", unit); - isic_detach_common(dev); - return ENXIO; - } - - /* - * because overlapping resources are invalid, - * release the second io port resource - */ - - bus_release_resource(dev, SYS_RES_IOPORT, sc->sc_resources.io_rid[1], - sc->sc_resources.io_base[1]); - - /* set and allocate a resource for the HSCX channel A */ - - sc->sc_resources.io_rid[3] = 3; - -/*XXX*/ /* FIXME !!!! - * the width of the resource is too small, there are accesses - * to it with an offset of 0x3e into the next resource. anyway, - * it seems to work and i have no idea how to do 2 resources - * overlapping each other. - */ - - bus_set_resource(dev, SYS_RES_IOPORT, 3, iobase2-0x20, 0x20); - - if(!(sc->sc_resources.io_base[3] = - bus_alloc_resource(dev,SYS_RES_IOPORT, - &sc->sc_resources.io_rid[3], - 0ul,~0ul, 1, RF_ACTIVE))) - { - printf("isic%d: Could not get io area 3 for Creatix / Teles PnP!\n", unit); - isic_detach_common(dev); - return ENXIO; - } - - /* set and allocate a resources for the HSCX channel B */ - - sc->sc_resources.io_rid[4] = 4; - - bus_set_resource(dev, SYS_RES_IOPORT, 4, iobase2, 0x40); - - if(!(sc->sc_resources.io_base[4] = - bus_alloc_resource(dev,SYS_RES_IOPORT, - &sc->sc_resources.io_rid[4], - 0ul, ~0ul, 1, RF_ACTIVE))) - { - printf("isic%d: Could not get io area 4 for Creatix / Teles PnP!\n", unit); - isic_detach_common(dev); - return ENXIO; - } - - /* setup access routines */ - - sc->clearirq = NULL; - sc->readreg = ctxs0P_read_reg; - sc->writereg = ctxs0P_write_reg; - - sc->readfifo = ctxs0P_read_fifo; - sc->writefifo = ctxs0P_write_fifo; - - /* setup card type */ - - sc->sc_cardtyp = CARD_TYPEP_CS0P; - - /* setup IOM bus type */ - - sc->sc_bustyp = BUS_TYPE_IOM2; - - sc->sc_ipac = 0; - sc->sc_bfifolen = HSCX_FIFO_LEN; - - /* enable the card */ - - t = rman_get_bustag(sc->sc_resources.io_base[2]); - h = rman_get_bushandle(sc->sc_resources.io_base[2]); - - bus_space_write_1(t, h, 0x3c, 0); - DELAY(SEC_DELAY / 10); - - bus_space_write_1(t, h, 0x3c, 1); - DELAY(SEC_DELAY / 10); - - return 0; -} - -#endif /* (NISIC > 0) && (defined(CRTX_S0_P) || defined(TEL_S0_16_3_P)) */ - diff --git a/sys/i4b/layer1/i4b_drn_ngo.c b/sys/i4b/layer1/i4b_drn_ngo.c deleted file mode 100644 index 99592ec..0000000 --- a/sys/i4b/layer1/i4b_drn_ngo.c +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - *--------------------------------------------------------------------------- - * - * 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 $ - * - * $FreeBSD$ - * - * last edit-date: [Mon Dec 13 21:59:30 1999] - * - *---------------------------------------------------------------------------*/ - -#include "isic.h" -#include "opt_i4b.h" - -#if (NISIC > 0) && defined(DRN_NGO) - -#include -#include -#include -#include - -#include - -#include - -#include -#include - -#include - -#include -#include -#include - -/*---------------------------------------------------------------------------* - * Niccy GO@ definitions - * - * the card uses 2 i/o addressranges each using 2 bytes - * - * addressrange 0: - * offset 0 - ISAC dataregister - * offset 1 - HSCX dataregister - * addressrange 1: - * offset 0 - ISAC addressregister - * offset 1 - HSCX addressregister - * - * to access an ISAC/HSCX register, you have to write the register - * number into the ISAC or HSCX addressregister and then read/write - * data for the ISAC/HSCX register into/from the corresponding - * dataregister. - * - * Thanks to Klaus Muehle of Dr. Neuhaus Telekommunikation for giving - * out this information! - * - *---------------------------------------------------------------------------*/ -#define NICCY_PORT_MIN 0x200 -#define NICCY_PORT_MAX 0x3e0 - -#define HSCX_ABIT 0x1000 /* flag, HSCX A is meant */ -#define HSCX_BBIT 0x2000 /* flag, HSCX B is meant */ - -#define HSCX_BOFF 0x40 - -#define ADDR_OFF 2 /* address register range offset */ - -#define ISAC_DATA 0 -#define HSCX_DATA 1 - -#define ISAC_ADDR 0 -#define HSCX_ADDR 1 - -/*---------------------------------------------------------------------------* - * Dr. Neuhaus Niccy GO@ read fifo routine - *---------------------------------------------------------------------------*/ -static void -drnngo_read_fifo(struct l1_softc *sc, int what, void *buf, size_t size) -{ - bus_space_tag_t tdata, tadr; - bus_space_handle_t hdata, hadr; - - tdata = rman_get_bustag(sc->sc_resources.io_base[0]); - hdata = rman_get_bushandle(sc->sc_resources.io_base[0]); - tadr = rman_get_bustag(sc->sc_resources.io_base[1]); - hadr = rman_get_bushandle(sc->sc_resources.io_base[1]); - - switch(what) - { - case ISIC_WHAT_ISAC: - bus_space_write_1 (tadr ,hadr, ISAC_ADDR,0x0); - bus_space_read_multi_1(tdata,hdata,ISAC_DATA,buf,size); - break; - case ISIC_WHAT_HSCXA: - bus_space_write_1 (tadr ,hadr ,HSCX_ADDR,0x0); - bus_space_read_multi_1(tdata,hdata,HSCX_DATA,buf,size); - break; - case ISIC_WHAT_HSCXB: - bus_space_write_1 (tadr ,hadr ,HSCX_ADDR,HSCX_BOFF); - bus_space_read_multi_1(tdata,hdata,HSCX_DATA,buf,size); - break; - } -} - -/*---------------------------------------------------------------------------* - * Dr. Neuhaus Niccy GO@ write fifo routine - *---------------------------------------------------------------------------*/ -static void -drnngo_write_fifo(struct l1_softc *sc, int what, void *buf, size_t size) -{ - bus_space_tag_t tdata, tadr; - bus_space_handle_t hdata, hadr; - - tdata = rman_get_bustag(sc->sc_resources.io_base[0]); - hdata = rman_get_bushandle(sc->sc_resources.io_base[0]); - tadr = rman_get_bustag(sc->sc_resources.io_base[1]); - hadr = rman_get_bushandle(sc->sc_resources.io_base[1]); - - switch(what) - { - case ISIC_WHAT_ISAC: - bus_space_write_1 (tadr ,hadr, ISAC_ADDR,0x0); - bus_space_write_multi_1(tdata,hdata,ISAC_DATA,buf,size); - break; - case ISIC_WHAT_HSCXA: - bus_space_write_1 (tadr ,hadr ,HSCX_ADDR,0x0); - bus_space_write_multi_1(tdata,hdata,HSCX_DATA,buf,size); - break; - case ISIC_WHAT_HSCXB: - bus_space_write_1 (tadr ,hadr ,HSCX_ADDR,HSCX_BOFF); - bus_space_write_multi_1(tdata,hdata,HSCX_DATA,buf,size); - break; - } -} - -/*---------------------------------------------------------------------------* - * Dr. Neuhaus Niccy GO@ write register routine - *---------------------------------------------------------------------------*/ -static void -drnngo_write_reg(struct l1_softc *sc, int what, bus_size_t reg, u_int8_t data) -{ - bus_space_tag_t tdata, tadr; - bus_space_handle_t hdata, hadr; - - tdata = rman_get_bustag(sc->sc_resources.io_base[0]); - hdata = rman_get_bushandle(sc->sc_resources.io_base[0]); - tadr = rman_get_bustag(sc->sc_resources.io_base[1]); - hadr = rman_get_bushandle(sc->sc_resources.io_base[1]); - - switch(what) - { - case ISIC_WHAT_ISAC: - bus_space_write_1(tadr ,hadr, ISAC_ADDR,reg); - bus_space_write_1(tdata,hdata,ISAC_DATA,data); - break; - case ISIC_WHAT_HSCXA: - bus_space_write_1(tadr ,hadr ,HSCX_ADDR,reg); - bus_space_write_1(tdata,hdata,HSCX_DATA,data); - break; - case ISIC_WHAT_HSCXB: - bus_space_write_1(tadr ,hadr ,HSCX_ADDR,reg+HSCX_BOFF); - bus_space_write_1(tdata,hdata,HSCX_DATA,data); - break; - } -} - -/*---------------------------------------------------------------------------* - * Dr. Neuhaus Niccy GO@ read register routine - *---------------------------------------------------------------------------*/ -static u_int8_t -drnngo_read_reg(struct l1_softc *sc, int what, bus_size_t reg) -{ - bus_space_tag_t tdata, tadr; - bus_space_handle_t hdata, hadr; - - tdata = rman_get_bustag(sc->sc_resources.io_base[0]); - hdata = rman_get_bushandle(sc->sc_resources.io_base[0]); - tadr = rman_get_bustag(sc->sc_resources.io_base[1]); - hadr = rman_get_bushandle(sc->sc_resources.io_base[1]); - - switch(what) - { - case ISIC_WHAT_ISAC: - bus_space_write_1(tadr ,hadr, ISAC_ADDR,reg); - return bus_space_read_1(tdata,hdata,ISAC_DATA); - case ISIC_WHAT_HSCXA: - bus_space_write_1(tadr ,hadr ,HSCX_ADDR,reg); - return bus_space_read_1(tdata,hdata,HSCX_DATA); - case ISIC_WHAT_HSCXB: - bus_space_write_1(tadr ,hadr ,HSCX_ADDR,reg+HSCX_BOFF); - return bus_space_read_1(tdata,hdata,HSCX_DATA); - default: - return 0; - } -} - -/*---------------------------------------------------------------------------* - * probe for ISA PnP cards - *---------------------------------------------------------------------------*/ -int -isic_attach_drnngo(device_t dev) -{ - int unit = device_get_unit(dev); - struct l1_softc *sc = &l1_sc[unit]; - - sc->sc_resources.io_rid[1] = 1; - - /* - * this card needs a second io_base, - * free resources if we don't get it - */ - - if(!(sc->sc_resources.io_base[1] = - bus_alloc_resource(dev, SYS_RES_IOPORT, - &sc->sc_resources.io_rid[1], - 0UL, ~0UL, 1, RF_ACTIVE))) - { - printf("isic%d: Failed to get second io base.\n", unit); - isic_detach_common(dev); - return ENXIO; - } - - /* setup ISAC access routines */ - - sc->clearirq = NULL; - sc->readreg = drnngo_read_reg; - sc->writereg = drnngo_write_reg; - - sc->readfifo = drnngo_read_fifo; - sc->writefifo = drnngo_write_fifo; - - /* setup card type */ - - sc->sc_cardtyp = CARD_TYPEP_DRNNGO; - - /* setup IOM bus type */ - - sc->sc_bustyp = BUS_TYPE_IOM2; - - sc->sc_ipac = 0; - sc->sc_bfifolen = HSCX_FIFO_LEN; - - return (0); -} - -#endif /* (NISIC > 0) && defined(DRN_NGO) */ 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 - * - * -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 -#include -#include -#include -#include -#include - -#ifdef __FreeBSD__ -#if __FreeBSD__ >= 3 -#include -#else -#include -#endif -#include -#include -/* #include */ -#elif defined(__bsdi__) -#include -#else -#include -#include -#endif - -#ifdef __FreeBSD__ -#include -#include -#else -#include -#include -#endif - -#include -#include -#include - -#include -#include -#include - -#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 -#if defined(__FreeBSD__) && __FreeBSD__ >= 3 -#include -#else -#include -#endif -#include -#include -#include - -#ifdef __FreeBSD__ -#include -#include -#else -#include -#include -#endif - -#include -#include - -#ifdef __FreeBSD__ -#include -#include -#else -#include -#include - -#include -#include -#endif - -#include -#include -#include - -#include - -#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 -#if defined(__FreeBSD__) && __FreeBSD__ >= 3 -#include -#else -#include -#endif -#include -#include -#include - -#ifdef __FreeBSD__ -#include -#include -#else -#include -#include -#endif - -#include -#include - -#ifdef __FreeBSD__ -#include -#include -#else -#include -#include - -#include -#include -#endif - -#include -#include -#include -#include - -#include - -#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_elsa_pcc16.c b/sys/i4b/layer1/i4b_elsa_pcc16.c deleted file mode 100644 index 5f1df77..0000000 --- a/sys/i4b/layer1/i4b_elsa_pcc16.c +++ /dev/null @@ -1,390 +0,0 @@ -/* - * Copyright (c) 1999 Hellmuth Michaelis. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - *--------------------------------------------------------------------------- - * - * isic - I4B Siemens ISDN Chipset Driver for ELSA MicroLink ISDN/PCC-16 - * ===================================================================== - * - * $Id: i4b_elsa_pcc16.c,v 1.2 1999/12/13 21:25:26 hm Exp $ - * - * $FreeBSD$ - * - * last edit-date: [Mon Dec 13 21:59:36 1999] - * - *---------------------------------------------------------------------------*/ - -#include "isic.h" -#include "opt_i4b.h" - -#if (NISIC > 0) && defined(ELSA_PCC16) - -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include -#include -#include - -#include -#include -#include - -static void i4b_epcc16_clrirq(struct l1_softc *sc); - -/* masks for register encoded in base addr */ - -#define ELSA_BASE_MASK 0x0ffff -#define ELSA_OFF_MASK 0xf0000 - -/* register id's to be encoded in base addr */ - -#define ELSA_IDISAC 0x00000 -#define ELSA_IDHSCXA 0x10000 -#define ELSA_IDHSCXB 0x20000 - -/* offsets from base address */ - -#define ELSA_OFF_ISAC 0x00 -#define ELSA_OFF_HSCX 0x02 -#define ELSA_OFF_OFF 0x03 -#define ELSA_OFF_CTRL 0x04 -#define ELSA_OFF_CFG 0x05 -#define ELSA_OFF_TIMR 0x06 -#define ELSA_OFF_IRQ 0x07 - -/* control register (write access) */ - -#define ELSA_CTRL_LED_YELLOW 0x02 -#define ELSA_CTRL_LED_GREEN 0x08 -#define ELSA_CTRL_RESET 0x20 -#define ELSA_CTRL_TIMEREN 0x80 -#define ELSA_CTRL_SECRET 0x50 - -/*---------------------------------------------------------------------------* - * ELSA MicroLink ISDN/PCC-16 clear IRQ routine - *---------------------------------------------------------------------------*/ -static void -i4b_epcc16_clrirq(struct l1_softc *sc) -{ - 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]); - bus_space_write_1(t, h, ELSA_OFF_IRQ, 0); -} - -/*---------------------------------------------------------------------------* - * ELSA MicroLink ISDN/PCC-16 ISAC get fifo routine - *---------------------------------------------------------------------------*/ -static void -epcc16_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, ELSA_OFF_OFF, 0); - bus_space_read_multi_1(t, h, ELSA_OFF_ISAC, buf, size); - break; - case ISIC_WHAT_HSCXA: - bus_space_write_1(t, h, ELSA_OFF_OFF, 0); - bus_space_read_multi_1(t, h, ELSA_OFF_HSCX, buf, size); - break; - case ISIC_WHAT_HSCXB: - bus_space_write_1(t, h, ELSA_OFF_OFF, 0x40); - bus_space_read_multi_1(t, h, ELSA_OFF_HSCX, buf, size); - break; - } -} - -/*---------------------------------------------------------------------------* - * ELSA MicroLink ISDN/PCC-16 ISAC put fifo routine - *---------------------------------------------------------------------------*/ -static void -epcc16_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, ELSA_OFF_OFF, 0); - bus_space_write_multi_1(t, h, ELSA_OFF_ISAC, buf, size); - break; - case ISIC_WHAT_HSCXA: - bus_space_write_1(t, h, ELSA_OFF_OFF, 0); - bus_space_write_multi_1(t, h, ELSA_OFF_HSCX, buf, size); - break; - case ISIC_WHAT_HSCXB: - bus_space_write_1(t, h, ELSA_OFF_OFF, 0x40); - bus_space_write_multi_1(t, h, ELSA_OFF_HSCX, buf, size); - break; - } -} - -/*---------------------------------------------------------------------------* - * ELSA MicroLink ISDN/PCC-16 ISAC put register routine - *---------------------------------------------------------------------------*/ -static void -epcc16_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, ELSA_OFF_OFF, offs); - bus_space_write_1(t, h, ELSA_OFF_ISAC, data); - break; - case ISIC_WHAT_HSCXA: - bus_space_write_1(t, h, ELSA_OFF_OFF, offs); - bus_space_write_1(t, h, ELSA_OFF_HSCX, data); - break; - case ISIC_WHAT_HSCXB: - bus_space_write_1(t, h, ELSA_OFF_OFF, 0x40+offs); - bus_space_write_1(t, h, ELSA_OFF_HSCX, data); - break; - } -} - -/*---------------------------------------------------------------------------* - * ELSA MicroLink ISDN/PCC-16 ISAC get register routine - *---------------------------------------------------------------------------*/ -static u_int8_t -epcc16_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, ELSA_OFF_OFF, offs); - return bus_space_read_1(t, h, ELSA_OFF_ISAC); - case ISIC_WHAT_HSCXA: - bus_space_write_1(t, h, ELSA_OFF_OFF, offs); - return bus_space_read_1(t, h, ELSA_OFF_HSCX); - case ISIC_WHAT_HSCXB: - bus_space_write_1(t, h, ELSA_OFF_OFF, 0x40+offs); - return bus_space_read_1(t, h, ELSA_OFF_HSCX); - } - return 0; -} - -/*---------------------------------------------------------------------------* - * isic_detach_Epcc16 - detach for ELSA MicroLink ISDN/PCC-16 - *---------------------------------------------------------------------------*/ -static void -isic_detach_Epcc16(device_t dev) -{ - struct l1_softc *sc = &l1_sc[device_get_unit(dev)]; - - if ( sc->sc_resources.irq ) - { - bus_teardown_intr(dev,sc->sc_resources.irq, - (void(*)(void *))isicintr); - bus_release_resource(dev,SYS_RES_IRQ, - sc->sc_resources.irq_rid, - sc->sc_resources.irq); - sc->sc_resources.irq = 0; - } - - if ( sc->sc_resources.io_base[0] ) { - bus_release_resource(dev,SYS_RES_IOPORT, - sc->sc_resources.io_rid[0], - sc->sc_resources.io_base[0]); - sc->sc_resources.io_base[0] = 0; - } -} - -/*---------------------------------------------------------------------------* - * isic_probe_Epcc16 - probe for ELSA MicroLink ISDN/PCC-16 - *---------------------------------------------------------------------------*/ -int -isic_probe_Epcc16(device_t dev) -{ - size_t unit = device_get_unit(dev); /* get unit */ - struct l1_softc *sc = 0; /* pointer to softc */ - void *ih = 0; /* dummy */ - - /* check max unit range */ - if(unit >= ISIC_MAXUNIT) - { - printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for ELSA PCC-16!\n", - unit, unit); - return(ENXIO); - } - - sc = &l1_sc[unit]; /* get pointer to softc */ - - sc->sc_unit = unit; /* set unit */ - - sc->sc_flags = FLAG_ELSA_PCC16; /* set flags */ - - /* see if an io base was supplied */ - - 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 get iobase for ELSA PCC-16.\n", - unit); - return(ENXIO); - } - - /* check if we got an iobase */ - - sc->sc_port = rman_get_start(sc->sc_resources.io_base[0]); - - switch(sc->sc_port) - { - case 0x160: - case 0x170: - case 0x260: - case 0x360: - break; - default: - printf("isic%d: Error, invalid iobase 0x%x specified for ELSA MicroLink ISDN/PCC-16!\n", - unit, sc->sc_port); - isic_detach_Epcc16(dev); - return(ENXIO); - break; - } - - /* setup access routines */ - - sc->clearirq = i4b_epcc16_clrirq; - sc->readreg = epcc16_read_reg; - sc->writereg = epcc16_write_reg; - - sc->readfifo = epcc16_read_fifo; - sc->writefifo = epcc16_write_fifo; - - /* setup card type */ - - sc->sc_cardtyp = CARD_TYPEP_ELSAQS1ISA; - - /* 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 for the ELSA PCC-16 - * is 0x05 ( = version 2.1 ) in the least significant bits. - */ - - 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); - } - - /* 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 get an irq.\n",unit); - isic_detach_Epcc16(dev); - return ENXIO; - } - - /* get the irq number */ - sc->sc_irq = rman_get_start(sc->sc_resources.irq); - - /* check IRQ validity */ - switch(sc->sc_irq) - { - case 2: - case 9: - case 3: - case 5: - case 10: - case 11: - case 15: - break; - - default: - printf("isic%d: Error, invalid IRQ [%d] specified for ELSA MicroLink ISDN/PCC-16!\n", - unit, sc->sc_irq); - isic_detach_Epcc16(dev); - return(ENXIO); - break; - } - - /* register interupt routine */ - bus_setup_intr(dev,sc->sc_resources.irq,INTR_TYPE_NET, - (void(*)(void *))(isicintr), - sc,&ih); - - - return (0); -} - -/*---------------------------------------------------------------------------* - * isic_attach_Epcc16 - attach for ELSA MicroLink ISDN/PCC-16 - *---------------------------------------------------------------------------*/ -int -isic_attach_Epcc16(device_t dev) -{ - int unit = device_get_unit(dev); - 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]); - - u_char byte = ELSA_CTRL_SECRET; - - byte &= ~ELSA_CTRL_RESET; - bus_space_write_1(t, h, ELSA_OFF_CTRL, byte); - DELAY(20); - byte |= ELSA_CTRL_RESET; - bus_space_write_1(t, h, ELSA_OFF_CTRL, byte); - - DELAY(20); - bus_space_write_1(t, h, ELSA_OFF_IRQ, 0xff); - - return 0; -} - -#endif /* (NISIC > 0) && defined(ELSA_PCC16) */ diff --git a/sys/i4b/layer1/i4b_elsa_qs1i.c b/sys/i4b/layer1/i4b_elsa_qs1i.c deleted file mode 100644 index 8a767d6..0000000 --- a/sys/i4b/layer1/i4b_elsa_qs1i.c +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - *--------------------------------------------------------------------------- - * - * isic - I4B Siemens ISDN Chipset Driver for ELSA Quickstep 1000pro ISA - * ===================================================================== - * - * $Id: i4b_elsa_qs1i.c,v 1.3 1999/12/13 21:25:26 hm Exp $ - * - * $FreeBSD$ - * - * last edit-date: [Mon Dec 13 21:59:44 1999] - * - *---------------------------------------------------------------------------*/ - -#include "isic.h" -#include "opt_i4b.h" - -#if (NISIC > 0) && defined(ELSA_QS1ISA) - -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include -#include -#include - -#include -#include -#include - -static void i4b_eq1i_clrirq(struct l1_softc *sc); - -/* masks for register encoded in base addr */ - -#define ELSA_BASE_MASK 0x0ffff -#define ELSA_OFF_MASK 0xf0000 - -/* register id's to be encoded in base addr */ - -#define ELSA_IDISAC 0x00000 -#define ELSA_IDHSCXA 0x10000 -#define ELSA_IDHSCXB 0x20000 - -/* offsets from base address */ - -#define ELSA_OFF_ISAC 0x00 -#define ELSA_OFF_HSCX 0x02 -#define ELSA_OFF_OFF 0x03 -#define ELSA_OFF_CTRL 0x04 -#define ELSA_OFF_CFG 0x05 -#define ELSA_OFF_TIMR 0x06 -#define ELSA_OFF_IRQ 0x07 - -/* control register (write access) */ - -#define ELSA_CTRL_LED_YELLOW 0x02 -#define ELSA_CTRL_LED_GREEN 0x08 -#define ELSA_CTRL_RESET 0x20 -#define ELSA_CTRL_TIMEREN 0x80 -#define ELSA_CTRL_SECRET 0x50 - -/*---------------------------------------------------------------------------* - * ELSA QuickStep 1000pro/ISA clear IRQ routine - *---------------------------------------------------------------------------*/ -static void -i4b_eq1i_clrirq(struct l1_softc *sc) -{ - 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]); - bus_space_write_1(t, h, ELSA_OFF_IRQ, 0); -} - -/*---------------------------------------------------------------------------* - * ELSA QuickStep 1000pro/ISA ISAC get fifo routine - *---------------------------------------------------------------------------*/ -static void -eqs1pi_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, ELSA_OFF_OFF, 0); - bus_space_read_multi_1(t, h, ELSA_OFF_ISAC, buf, size); - break; - case ISIC_WHAT_HSCXA: - bus_space_write_1(t, h, ELSA_OFF_OFF, 0); - bus_space_read_multi_1(t, h, ELSA_OFF_HSCX, buf, size); - break; - case ISIC_WHAT_HSCXB: - bus_space_write_1(t, h, ELSA_OFF_OFF, 0x40); - bus_space_read_multi_1(t, h, ELSA_OFF_HSCX, buf, size); - break; - } -} - -/*---------------------------------------------------------------------------* - * ELSA QuickStep 1000pro/ISA ISAC put fifo routine - *---------------------------------------------------------------------------*/ -static void -eqs1pi_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, ELSA_OFF_OFF, 0); - bus_space_write_multi_1(t, h, ELSA_OFF_ISAC, buf, size); - break; - case ISIC_WHAT_HSCXA: - bus_space_write_1(t, h, ELSA_OFF_OFF, 0); - bus_space_write_multi_1(t, h, ELSA_OFF_HSCX, buf, size); - break; - case ISIC_WHAT_HSCXB: - bus_space_write_1(t, h, ELSA_OFF_OFF, 0x40); - bus_space_write_multi_1(t, h, ELSA_OFF_HSCX, buf, size); - break; - } -} - -/*---------------------------------------------------------------------------* - * ELSA QuickStep 1000pro/ISA ISAC put register routine - *---------------------------------------------------------------------------*/ -static void -eqs1pi_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, ELSA_OFF_OFF, offs); - bus_space_write_1(t, h, ELSA_OFF_ISAC, data); - break; - case ISIC_WHAT_HSCXA: - bus_space_write_1(t, h, ELSA_OFF_OFF, offs); - bus_space_write_1(t, h, ELSA_OFF_HSCX, data); - break; - case ISIC_WHAT_HSCXB: - bus_space_write_1(t, h, ELSA_OFF_OFF, 0x40+offs); - bus_space_write_1(t, h, ELSA_OFF_HSCX, data); - break; - } -} - -/*---------------------------------------------------------------------------* - * ELSA QuickStep 1000pro/ISA ISAC get register routine - *---------------------------------------------------------------------------*/ -static u_int8_t -eqs1pi_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, ELSA_OFF_OFF, offs); - return bus_space_read_1(t, h, ELSA_OFF_ISAC); - case ISIC_WHAT_HSCXA: - bus_space_write_1(t, h, ELSA_OFF_OFF, offs); - return bus_space_read_1(t, h, ELSA_OFF_HSCX); - case ISIC_WHAT_HSCXB: - bus_space_write_1(t, h, ELSA_OFF_OFF, 0x40+offs); - return bus_space_read_1(t, h, ELSA_OFF_HSCX); - } - return 0; -} - -/*---------------------------------------------------------------------------* - * isic_attach_Eqs1pi - attach for ELSA QuickStep 1000pro/ISA - *---------------------------------------------------------------------------*/ -int -isic_attach_Eqs1pi(device_t dev) -{ - int unit = device_get_unit(dev); - 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]); - - u_char byte = ELSA_CTRL_SECRET; - - /* setup access routines */ - - sc->clearirq = i4b_eq1i_clrirq; - sc->readreg = eqs1pi_read_reg; - sc->writereg = eqs1pi_write_reg; - - sc->readfifo = eqs1pi_read_fifo; - sc->writefifo = eqs1pi_write_fifo; - - /* setup card type */ - - sc->sc_cardtyp = CARD_TYPEP_ELSAQS1ISA; - - /* setup IOM bus type */ - - sc->sc_bustyp = BUS_TYPE_IOM2; - - sc->sc_ipac = 0; - sc->sc_bfifolen = HSCX_FIFO_LEN; - - /* enable the card */ - - byte &= ~ELSA_CTRL_RESET; - bus_space_write_1(t, h, ELSA_OFF_CTRL, byte); - DELAY(20); - byte |= ELSA_CTRL_RESET; - bus_space_write_1(t, h, ELSA_OFF_CTRL, byte); - - DELAY(20); - bus_space_write_1(t, h, ELSA_OFF_IRQ, 0xff); - - return 0; -} -#endif /* (NISIC > 0) && defined(ELSA_QS1ISA) */ diff --git a/sys/i4b/layer1/i4b_elsa_qs1p.c b/sys/i4b/layer1/i4b_elsa_qs1p.c deleted file mode 100644 index aac277c..0000000 --- a/sys/i4b/layer1/i4b_elsa_qs1p.c +++ /dev/null @@ -1,365 +0,0 @@ -/* - * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - *--------------------------------------------------------------------------- - * - * isic - I4B Siemens ISDN Chipset Driver for ELSA MicroLink ISDN/PCI - * ================================================================== - * - * $Id: i4b_elsa_qs1p.c,v 1.2 1999/12/13 21:25:26 hm Exp $ - * - * $FreeBSD$ - * - * last edit-date: [Mon Dec 13 21:59:51 1999] - * - * Note: ELSA Quickstep 1000pro PCI = ELSA MicroLink ISDN/PCI - * - *---------------------------------------------------------------------------*/ - -#include "isic.h" -#include "opt_i4b.h" -#include "pci.h" - -#if (NISIC > 0) && (NPCI > 0) && defined(ELSA_QS1PCI) - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -#define MEM0_MAPOFF 0 -#define PORT0_MAPOFF 4 -#define PORT1_MAPOFF 12 - -#define ELSA_PORT0_MAPOFF (PCIR_MAPS+PORT0_MAPOFF) -#define ELSA_PORT1_MAPOFF (PCIR_MAPS+PORT1_MAPOFF) - -#define PCI_QS1000_DID 0x1000 -#define PCI_QS1000_VID 0x1048 - -/* masks for register encoded in base addr */ - -#define ELSA_BASE_MASK 0x0ffff -#define ELSA_OFF_MASK 0xf0000 - -/* register id's to be encoded in base addr */ - -#define ELSA_IDISAC 0x00000 -#define ELSA_IDHSCXA 0x10000 -#define ELSA_IDHSCXB 0x20000 -#define ELSA_IDIPAC 0x40000 - -/* offsets from base address */ - -#define ELSA_OFF_ALE 0x00 -#define ELSA_OFF_RW 0x01 - - -static int eqs1p_pci_probe(device_t dev); -static int eqs1p_pci_attach(device_t dev); - -static device_method_t eqs1p_pci_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, eqs1p_pci_probe), - DEVMETHOD(device_attach, eqs1p_pci_attach), - { 0, 0 } -}; - -static driver_t eqs1p_pci_driver = { - "isic", - eqs1p_pci_methods, - 0 -}; - -static devclass_t eqs1p_pci_devclass; - -DRIVER_MODULE(eqs1p, pci, eqs1p_pci_driver, eqs1p_pci_devclass, 0, 0); - -/*---------------------------------------------------------------------------* - * ELSA MicroLink ISDN/PCI fifo read routine - *---------------------------------------------------------------------------*/ -static void -eqs1pp_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[1]); - bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[1]); - - switch(what) - { - case ISIC_WHAT_ISAC: - bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_ISAC_OFF); - bus_space_read_multi_1(t, h, ELSA_OFF_RW, buf, size); - break; - case ISIC_WHAT_HSCXA: - bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXA_OFF); - bus_space_read_multi_1(t, h, ELSA_OFF_RW, buf, size); - break; - case ISIC_WHAT_HSCXB: - bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXB_OFF); - bus_space_read_multi_1(t, h, ELSA_OFF_RW, buf, size); - break; - } -} - -/*---------------------------------------------------------------------------* - * ELSA MicroLink ISDN/PCI fifo write routine - *---------------------------------------------------------------------------*/ -static void -eqs1pp_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[1]); - bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[1]); - - switch(what) - { - case ISIC_WHAT_ISAC: - bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_ISAC_OFF); - bus_space_write_multi_1(t, h, ELSA_OFF_RW, (u_int8_t*)buf, size); - break; - case ISIC_WHAT_HSCXA: - bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXA_OFF); - bus_space_write_multi_1(t, h, ELSA_OFF_RW, (u_int8_t*)buf, size); - break; - case ISIC_WHAT_HSCXB: - bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXB_OFF); - bus_space_write_multi_1(t, h, ELSA_OFF_RW, (u_int8_t*)buf, size); - break; - } -} - -/*---------------------------------------------------------------------------* - * ELSA MicroLink ISDN/PCI register write routine - *---------------------------------------------------------------------------*/ -static void -eqs1pp_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[1]); - bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[1]); - - switch(what) - { - case ISIC_WHAT_ISAC: - bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_ISAC_OFF+offs); - bus_space_write_1(t, h, ELSA_OFF_RW, data); - break; - case ISIC_WHAT_HSCXA: - bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXA_OFF+offs); - bus_space_write_1(t, h, ELSA_OFF_RW, data); - break; - case ISIC_WHAT_HSCXB: - bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXB_OFF+offs); - bus_space_write_1(t, h, ELSA_OFF_RW, data); - break; - case ISIC_WHAT_IPAC: - bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_IPAC_OFF+offs); - bus_space_write_1(t, h, ELSA_OFF_RW, data); - break; - } -} - -/*---------------------------------------------------------------------------* - * ELSA MicroLink ISDN/PCI register read routine - *---------------------------------------------------------------------------*/ -static u_int8_t -eqs1pp_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[1]); - bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[1]); - - switch(what) - { - case ISIC_WHAT_ISAC: - bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_ISAC_OFF+offs); - return bus_space_read_1(t, h, ELSA_OFF_RW); - case ISIC_WHAT_HSCXA: - bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXA_OFF+offs); - return bus_space_read_1(t, h, ELSA_OFF_RW); - case ISIC_WHAT_HSCXB: - bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXB_OFF+offs); - return bus_space_read_1(t, h, ELSA_OFF_RW); - case ISIC_WHAT_IPAC: - bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_IPAC_OFF+offs); - return bus_space_read_1(t, h, ELSA_OFF_RW); - } - return 0; -} - -/*---------------------------------------------------------------------------* - * avma1pp_probe - probe for a card - *---------------------------------------------------------------------------*/ -static int -eqs1p_pci_probe(device_t dev) -{ - if((pci_get_vendor(dev) == PCI_QS1000_VID) && - (pci_get_device(dev) == PCI_QS1000_DID)) - { - device_set_desc(dev, "ELSA MicroLink ISDN/PCI"); - return(0); - } - return(ENXIO); -} - -/*---------------------------------------------------------------------------* - * isic_attach_Eqs1pp - attach for ELSA MicroLink ISDN/PCI - *---------------------------------------------------------------------------*/ -static int -eqs1p_pci_attach(device_t dev) -{ - bus_space_tag_t t; - bus_space_handle_t h; - struct l1_softc *sc; - void *ih = 0; - int unit = device_get_unit(dev); - - /* check max unit range */ - - if(unit >= ISIC_MAXUNIT) - { - printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for ELSA MicroLink ISDN/PCI!\n", - unit, unit); - return(ENXIO); - } - - sc = &l1_sc[unit]; /* get softc */ - - sc->sc_unit = unit; - - /* get io_base */ - - sc->sc_resources.io_rid[0] = ELSA_PORT0_MAPOFF; - - 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: Couldn't get first iobase for ELSA MicroLink ISDN/PCI!\n", unit); - return(ENXIO); - } - - sc->sc_resources.io_rid[1] = ELSA_PORT1_MAPOFF; - - if(!(sc->sc_resources.io_base[1] = - bus_alloc_resource(dev, SYS_RES_IOPORT, - &sc->sc_resources.io_rid[1], - 0UL, ~0UL, 1, RF_ACTIVE))) - { - printf("isic%d: Couldn't get second iobase for ELSA MicroLink ISDN/PCI!\n", unit); - isic_detach_common(dev); - return(ENXIO); - } - - sc->sc_port = rman_get_start(sc->sc_resources.io_base[1]); - - 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 get irq for ELSA MicroLink ISDN/PCI!\n",unit); - isic_detach_common(dev); - return(ENXIO); - } - - sc->sc_irq = rman_get_start(sc->sc_resources.irq); - - /* setup access routines */ - - sc->clearirq = NULL; - sc->readreg = eqs1pp_read_reg; - sc->writereg = eqs1pp_write_reg; - - sc->readfifo = eqs1pp_read_fifo; - sc->writefifo = eqs1pp_write_fifo; - - /* setup card type */ - - sc->sc_cardtyp = CARD_TYPEP_ELSAQS1PCI; - - /* setup IOM bus type */ - - sc->sc_bustyp = BUS_TYPE_IOM2; - - /* setup chip type = IPAC ! */ - - sc->sc_ipac = 1; - sc->sc_bfifolen = IPAC_BFIFO_LEN; - - if(isic_attach_common(dev)) - { - isic_detach_common(dev); - return(ENXIO); - } - - if(bus_setup_intr(dev, sc->sc_resources.irq, INTR_TYPE_NET, - (void(*)(void*))isicintr, - sc, &ih)) - { - printf("isic%d: Couldn't set up irq for ELSA MicroLink ISDN/PCI!\n", unit); - isic_detach_common(dev); - return(ENXIO); - } - - /* enable hscx/isac irq's */ - - IPAC_WRITE(IPAC_MASK, (IPAC_MASK_INT1 | IPAC_MASK_INT0)); - - IPAC_WRITE(IPAC_ACFG, 0); /* outputs are open drain */ - IPAC_WRITE(IPAC_AOE, /* aux 5..2 are inputs, 7, 6 outputs */ - (IPAC_AOE_OE5 | IPAC_AOE_OE4 | IPAC_AOE_OE3 | IPAC_AOE_OE2)); - IPAC_WRITE(IPAC_ATX, 0xff); /* set all output lines high */ - - t = rman_get_bustag(sc->sc_resources.io_base[0]); - h = rman_get_bushandle(sc->sc_resources.io_base[0]); - - bus_space_write_1(t, h, 0x4c, 0x41); /* enable card interrupt */ - - return(0); -} - -#endif /* (NISIC > 0) && (NPCI > 0) && defined(ELSA_QS1PCI) */ 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_hscx.c b/sys/i4b/layer1/i4b_hscx.c deleted file mode 100644 index 825316f..0000000 --- a/sys/i4b/layer1/i4b_hscx.c +++ /dev/null @@ -1,662 +0,0 @@ -/* - * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - *--------------------------------------------------------------------------- - * - * i4b - Siemens HSCX chip (B-channel) handling - * -------------------------------------------- - * - * $Id: i4b_hscx.c,v 1.2 1999/12/13 21:25:26 hm Exp $ - * - * $FreeBSD$ - * - * last edit-date: [Mon Dec 13 21:59:58 1999] - * - *---------------------------------------------------------------------------*/ - -#include "isic.h" - -#if NISIC > 0 - -#include -#include -#include -#include - -#include -#include - -#include - -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -/*---------------------------------------------------------------------------* - * HSCX IRQ Handler - *---------------------------------------------------------------------------*/ -void -isic_hscx_irq(register struct l1_softc *sc, u_char ista, int h_chan, u_char ex_irq) -{ - register l1_bchan_state_t *chan = &sc->sc_chan[h_chan]; - u_char exir = 0; - int activity = -1; - u_char cmd = 0; - - DBGL1(L1_H_IRQ, "isic_hscx_irq", ("%#x\n", ista)); - - if(ex_irq) - { - /* get channel extended irq reg */ - - exir = HSCX_READ(h_chan, H_EXIR); - - if(exir & HSCX_EXIR_RFO) - { - chan->stat_RFO++; - DBGL1(L1_H_XFRERR, "isic_hscx_irq", ("ex_irq: receive data overflow\n")); - } - - 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")); - isic_hscx_cmd(sc, h_chan, HSCX_CMDR_XRES); - - if (chan->out_mbuf_head != NULL) /* don't continue to transmit this buffer */ - { - i4b_Bfreembuf(chan->out_mbuf_head); - chan->out_mbuf_cur = chan->out_mbuf_head = NULL; - } - } - - } - - /* rx message end, end of frame */ - - if(ista & HSCX_ISTA_RME) - { - register int fifo_data_len; - u_char rsta; - int error = 0; - - rsta = HSCX_READ(h_chan, H_RSTA); - - if((rsta & 0xf0) != 0xa0) - { - if((rsta & HSCX_RSTA_VFR) == 0) - { - chan->stat_VFR++; - cmd |= (HSCX_CMDR_RHR); - DBGL1(L1_H_XFRERR, "isic_hscx_irq", ("received invalid Frame\n")); - error++; - } - - if(rsta & HSCX_RSTA_RDO) - { - chan->stat_RDO++; - DBGL1(L1_H_XFRERR, "isic_hscx_irq", ("receive data overflow\n")); - error++; - } - - if((rsta & HSCX_RSTA_CRC) == 0) - { - chan->stat_CRC++; - cmd |= (HSCX_CMDR_RHR); - DBGL1(L1_H_XFRERR, "isic_hscx_irq", ("CRC check failed\n")); - error++; - } - - if(rsta & HSCX_RSTA_RAB) - { - chan->stat_RAB++; - DBGL1(L1_H_XFRERR, "isic_hscx_irq", ("Receive message aborted\n")); - error++; - } - } - - fifo_data_len = ((HSCX_READ(h_chan, H_RBCL)) & - ((sc->sc_bfifolen)-1)); - - if(fifo_data_len == 0) - fifo_data_len = sc->sc_bfifolen; - - /* 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 isic_hscx_irq: RME, cannot allocate mbuf!\n"); - chan->in_cbptr = chan->in_mbuf->m_data; - chan->in_len = 0; - } - - fifo_data_len -= 1; /* last byte in fifo is RSTA ! */ - - if((chan->in_len + fifo_data_len) <= BCH_MAX_DATALEN) - { - /* read data from HSCX fifo */ - - HSCX_RDFIFO(h_chan, chan->in_cbptr, fifo_data_len); - - cmd |= (HSCX_CMDR_RMC); - isic_hscx_cmd(sc, h_chan, 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 = 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); - } - - (*chan->drvr_linktab->bch_rx_data_ready)(chan->drvr_linktab->unit); - - activity = ACT_RX; - - /* mark buffer ptr as unused */ - - chan->in_mbuf = NULL; - chan->in_cbptr = NULL; - chan->in_len = 0; - } - else - { - 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)); - chan->in_cbptr = chan->in_mbuf->m_data; - chan->in_len = 0; - cmd |= (HSCX_CMDR_RHR | HSCX_CMDR_RMC); - } - } - else - { - if (chan->in_mbuf != NULL) - { - i4b_Bfreembuf(chan->in_mbuf); - chan->in_mbuf = NULL; - chan->in_cbptr = NULL; - chan->in_len = 0; - } - cmd |= (HSCX_CMDR_RMC); - } - } - - /* rx fifo full */ - - if(ista & HSCX_ISTA_RPF) - { - if(chan->in_mbuf == NULL) - { - if((chan->in_mbuf = i4b_Bgetmbuf(BCH_MAX_DATALEN)) == NULL) - panic("L1 isic_hscx_irq: RPF, cannot allocate mbuf!\n"); - chan->in_cbptr = chan->in_mbuf->m_data; - chan->in_len = 0; - } - - chan->rxcount += sc->sc_bfifolen; - - if((chan->in_len + sc->sc_bfifolen) <= BCH_MAX_DATALEN) - { - /* read data from HSCX fifo */ - - HSCX_RDFIFO(h_chan, chan->in_cbptr, sc->sc_bfifolen); - - chan->in_cbptr += sc->sc_bfifolen; - chan->in_len += sc->sc_bfifolen; - } - else - { - if(chan->bprot == BPROT_NONE) - { - /* setup mbuf data length */ - - chan->in_mbuf->m_len = chan->in_len; - chan->in_mbuf->m_pkthdr.len = chan->in_len; - - if(sc->sc_trace & TRACE_B_RX) - { - i4b_trace_hdr_t hdr; - hdr.unit = sc->sc_unit; - hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2); - hdr.dir = FROM_NT; - hdr.count = ++sc->sc_trace_bcount; - MICROTIME(hdr.time); - MPH_Trace_Ind(&hdr, chan->in_mbuf->m_len, chan->in_mbuf->m_data); - } - - /* silence detection */ - - if(!(isic_hscx_silence(chan->in_mbuf->m_data, chan->in_mbuf->m_len))) - activity = ACT_RX; - - if(!(IF_QFULL(&chan->rx_queue))) - { - IF_ENQUEUE(&chan->rx_queue, chan->in_mbuf); - } - else - { - i4b_Bfreembuf(chan->in_mbuf); - } - - /* signal upper driver that data is available */ - - (*chan->drvr_linktab->bch_rx_data_ready)(chan->drvr_linktab->unit); - - /* alloc new buffer */ - - if((chan->in_mbuf = i4b_Bgetmbuf(BCH_MAX_DATALEN)) == NULL) - panic("L1 isic_hscx_irq: RPF, cannot allocate new mbuf!\n"); - - /* setup new data ptr */ - - chan->in_cbptr = chan->in_mbuf->m_data; - - /* read data from HSCX fifo */ - - HSCX_RDFIFO(h_chan, chan->in_cbptr, sc->sc_bfifolen); - - chan->in_cbptr += sc->sc_bfifolen; - chan->in_len = sc->sc_bfifolen; - - chan->rxcount += sc->sc_bfifolen; - } - else - { - DBGL1(L1_H_XFRERR, "isic_hscx_irq", ("RAWHDLC rx buffer overflow in RPF, in_len=%d\n", chan->in_len)); - chan->in_cbptr = chan->in_mbuf->m_data; - chan->in_len = 0; - cmd |= (HSCX_CMDR_RHR); - } - } - - /* command to release fifo space */ - - cmd |= HSCX_CMDR_RMC; - } - - /* transmit fifo empty, new data can be written to fifo */ - - if(ista & HSCX_ISTA_XPR) - { - /* - * for a description what is going on here, please have - * a look at isic_bchannel_start() in i4b_bchan.c ! - */ - - int activity = -1; - 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)); - - 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); - } - else - { - chan->state |= HSCX_TX_ACTIVE; - chan->out_mbuf_cur = chan->out_mbuf_head; - chan->out_mbuf_cur_ptr = chan->out_mbuf_cur->m_data; - chan->out_mbuf_cur_len = chan->out_mbuf_cur->m_len; - - if(sc->sc_trace & TRACE_B_TX) - { - i4b_trace_hdr_t hdr; - hdr.unit = sc->sc_unit; - hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2); - hdr.dir = FROM_TE; - hdr.count = ++sc->sc_trace_bcount; - MICROTIME(hdr.time); - MPH_Trace_Ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data); - } - - if(chan->bprot == BPROT_NONE) - { - if(!(isic_hscx_silence(chan->out_mbuf_cur->m_data, chan->out_mbuf_cur->m_len))) - activity = ACT_TX; - } - else - { - activity = ACT_TX; - } - } - } - - len = 0; - - while(chan->out_mbuf_cur && len != sc->sc_bfifolen) - { - nextlen = min(chan->out_mbuf_cur_len, sc->sc_bfifolen - len); - -#ifdef NOTDEF - printf("i:mh=%x, mc=%x, mcp=%x, mcl=%d l=%d nl=%d # ", - chan->out_mbuf_head, - chan->out_mbuf_cur, - chan->out_mbuf_cur_ptr, - chan->out_mbuf_cur_len, - len, - next_len); -#endif - - isic_hscx_waitxfw(sc, h_chan); /* necessary !!! */ - - HSCX_WRFIFO(h_chan, chan->out_mbuf_cur_ptr, nextlen); - cmd |= HSCX_CMDR_XTF; - - len += nextlen; - chan->txcount += nextlen; - - chan->out_mbuf_cur_ptr += nextlen; - chan->out_mbuf_cur_len -= nextlen; - - if(chan->out_mbuf_cur_len == 0) - { - if((chan->out_mbuf_cur = chan->out_mbuf_cur->m_next) != NULL) - { - chan->out_mbuf_cur_ptr = chan->out_mbuf_cur->m_data; - chan->out_mbuf_cur_len = chan->out_mbuf_cur->m_len; - - if(sc->sc_trace & TRACE_B_TX) - { - i4b_trace_hdr_t hdr; - hdr.unit = sc->sc_unit; - hdr.type = (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); - } - } - else - { - if (chan->bprot != BPROT_NONE) - cmd |= HSCX_CMDR_XME; - i4b_Bfreembuf(chan->out_mbuf_head); - chan->out_mbuf_head = NULL; - } - - } - } - } - - if(cmd) /* is there a command for the HSCX ? */ - { - isic_hscx_cmd(sc, h_chan, cmd); /* yes, to HSCX */ - } - - /* call timeout handling routine */ - - if(activity == ACT_RX || activity == ACT_TX) - (*chan->drvr_linktab->bch_activity)(chan->drvr_linktab->unit, activity); -} - -/*---------------------------------------------------------------------------* - * HSCX initialization - * - * for telephony: extended transparent mode 1 - * for raw hdlc: transparent mode 0 - *---------------------------------------------------------------------------*/ -void -isic_hscx_init(struct l1_softc *sc, int h_chan, int activate) -{ - l1_bchan_state_t *chan = &sc->sc_chan[h_chan]; - - HSCX_WRITE(h_chan, H_MASK, 0xff); /* mask irq's */ - - if(sc->sc_ipac) - { - /* CCR1: Power Up, Clock Mode 5 */ - HSCX_WRITE(h_chan, H_CCR1, HSCX_CCR1_PU | /* power up */ - HSCX_CCR1_CM1); /* IPAC clock mode 5 */ - } - else - { - /* CCR1: Power Up, Clock Mode 5 */ - HSCX_WRITE(h_chan, H_CCR1, HSCX_CCR1_PU | /* power up */ - HSCX_CCR1_CM2 | /* HSCX clock mode 5 */ - HSCX_CCR1_CM0); - } - - /* XAD1: Transmit Address Byte 1 */ - HSCX_WRITE(h_chan, H_XAD1, 0xff); - - /* XAD2: Transmit Address Byte 2 */ - HSCX_WRITE(h_chan, H_XAD2, 0xff); - - /* RAH2: Receive Address Byte High Reg. 2 */ - HSCX_WRITE(h_chan, H_RAH2, 0xff); - - /* XBCH: reset Transmit Byte Count High */ - HSCX_WRITE(h_chan, H_XBCH, 0x00); - - /* RLCR: reset Receive Length Check Register */ - HSCX_WRITE(h_chan, H_RLCR, 0x00); - - /* CCR2: set tx/rx clock shift bit 0 */ - /* disable CTS irq, disable RIE irq*/ - HSCX_WRITE(h_chan, H_CCR2, HSCX_CCR2_XCS0|HSCX_CCR2_RCS0); - - /* XCCR: tx bit count per time slot */ - HSCX_WRITE(h_chan, H_XCCR, 0x07); - - /* RCCR: rx bit count per time slot */ - HSCX_WRITE(h_chan, H_RCCR, 0x07); - - if(sc->sc_bustyp == BUS_TYPE_IOM2) - { - switch(h_chan) - { - case HSCX_CH_A: /* Prepare HSCX channel A */ - /* TSAX: tx clock shift bits 1 & 2 */ - /* tx time slot number */ - HSCX_WRITE(h_chan, H_TSAX, 0x2f); - - /* TSAR: rx clock shift bits 1 & 2 */ - /* rx time slot number */ - HSCX_WRITE(h_chan, H_TSAR, 0x2f); - break; - - case HSCX_CH_B: /* Prepare HSCX channel B */ - /* TSAX: tx clock shift bits 1 & 2 */ - /* tx time slot number */ - HSCX_WRITE(h_chan, H_TSAX, 0x03); - - /* TSAR: rx clock shift bits 1 & 2 */ - /* rx time slot number */ - HSCX_WRITE(h_chan, H_TSAR, 0x03); - break; - } - } - else /* IOM 1 setup */ - { - /* TSAX: tx clock shift bits 1 & 2 */ - /* tx time slot number */ - HSCX_WRITE(h_chan, H_TSAX, 0x07); - - /* TSAR: rx clock shift bits 1 & 2 */ - /* rx time slot number */ - HSCX_WRITE(h_chan, H_TSAR, 0x07); - } - - if(activate) - { - if(chan->bprot == BPROT_RHDLC) - { - /* HDLC Frames, transparent mode 0 */ - HSCX_WRITE(h_chan, H_MODE, - HSCX_MODE_MDS1|HSCX_MODE_RAC|HSCX_MODE_RTS); - } - else - { - /* Raw Telephony, extended transparent mode 1 */ - HSCX_WRITE(h_chan, H_MODE, - HSCX_MODE_MDS1|HSCX_MODE_MDS0|HSCX_MODE_ADM|HSCX_MODE_RTS); - } - - isic_hscx_cmd(sc, h_chan, HSCX_CMDR_RHR|HSCX_CMDR_XRES); - } - else - { - /* TSAX: tx time slot */ - HSCX_WRITE(h_chan, H_TSAX, 0xff); - - /* TSAR: rx time slot */ - HSCX_WRITE(h_chan, H_TSAR, 0xff); - - /* Raw Telephony, extended transparent mode 1 */ - HSCX_WRITE(h_chan, H_MODE, - HSCX_MODE_MDS1|HSCX_MODE_MDS0|HSCX_MODE_ADM|HSCX_MODE_RTS); - } - - /* don't touch ICA, EXA and EXB bits, this could be HSCX_CH_B */ - /* always disable RSC and TIN */ - - chan->hscx_mask |= HSCX_MASK_RSC | HSCX_MASK_TIN; - - if(activate) - { - /* enable */ - chan->hscx_mask &= ~(HSCX_MASK_RME | HSCX_MASK_RPF | HSCX_MASK_XPR); - } - else - { - /* disable */ - chan->hscx_mask |= HSCX_MASK_RME | HSCX_MASK_RPF | HSCX_MASK_XPR; - } - - /* handle ICA, EXA, and EXB via interrupt mask of channel b */ - - if (h_chan == HSCX_CH_A) - { - if (activate) - HSCX_B_IMASK &= ~(HSCX_MASK_EXA | HSCX_MASK_ICA); - else - HSCX_B_IMASK |= HSCX_MASK_EXA | HSCX_MASK_ICA; - HSCX_WRITE(HSCX_CH_A, H_MASK, HSCX_A_IMASK); - HSCX_WRITE(HSCX_CH_B, H_MASK, HSCX_B_IMASK); - } - else - { - if (activate) - HSCX_B_IMASK &= ~HSCX_MASK_EXB; - else - HSCX_B_IMASK |= HSCX_MASK_EXB; - HSCX_WRITE(HSCX_CH_B, H_MASK, HSCX_B_IMASK); - } - - /* clear spurious interrupts left over */ - - if(h_chan == HSCX_CH_A) - { - HSCX_READ(h_chan, H_EXIR); - HSCX_READ(h_chan, H_ISTA); - } - else /* mask ICA, because it must not be cleared by reading ISTA */ - { - HSCX_WRITE(HSCX_CH_B, H_MASK, HSCX_B_IMASK | HSCX_MASK_ICA); - HSCX_READ(h_chan, H_EXIR); - HSCX_READ(h_chan, H_ISTA); - HSCX_WRITE(HSCX_CH_B, H_MASK, HSCX_B_IMASK); - } -} - -/*---------------------------------------------------------------------------* - * write command to HSCX command register - *---------------------------------------------------------------------------*/ -void -isic_hscx_cmd(struct l1_softc *sc, int h_chan, unsigned char cmd) -{ - int timeout = 20; - - while(((HSCX_READ(h_chan, H_STAR)) & HSCX_STAR_CEC) && timeout) - { - DELAY(10); - timeout--; - } - - if(timeout == 0) - { - DBGL1(L1_H_ERR, "isic_hscx_cmd", ("HSCX wait for CEC timeout!\n")); - } - - HSCX_WRITE(h_chan, H_CMDR, cmd); -} - -/*---------------------------------------------------------------------------* - * wait for HSCX transmit FIFO write enable - *---------------------------------------------------------------------------*/ -void -isic_hscx_waitxfw(struct l1_softc *sc, int h_chan) -{ -#define WAITVAL 50 -#define WAITTO 200 - - int timeout = WAITTO; - - while((!(((HSCX_READ(h_chan, H_STAR)) & - (HSCX_STAR_CEC | HSCX_STAR_XFW)) == HSCX_STAR_XFW)) && timeout) - { - DELAY(WAITVAL); - timeout--; - } - - if(timeout == 0) - { - DBGL1(L1_H_ERR, "isic_hscx_waitxfw", ("HSCX wait for XFW timeout!\n")); - } - else if (timeout != WAITTO) - { - DBGL1(L1_H_XFRERR, "isic_hscx_waitxfw", ("HSCX wait for XFW time: %d uS\n", (WAITTO-timeout)*50)); - } -} - -#endif /* NISIC > 0 */ diff --git a/sys/i4b/layer1/i4b_hscx.h b/sys/i4b/layer1/i4b_hscx.h deleted file mode 100644 index e642698..0000000 --- a/sys/i4b/layer1/i4b_hscx.h +++ /dev/null @@ -1,299 +0,0 @@ -/* - * Copyright (c) 1996, 1998 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. - * 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. - * - *--------------------------------------------------------------------------- - * - * $Id: i4b_hscx.h,v 1.2 1999/12/13 21:25:26 hm Exp $ - * - * $FreeBSD$ - * - * last edit-date: [Mon Dec 13 22:00:49 1999] - * - *---------------------------------------------------------------------------*/ - -#ifndef I4B_HSCX_H_ -#define I4B_HSCX_H_ - -enum HSCX_VERSIONS { - HSCX_VA1, /* 82525 A1 */ - HSCX_UNKN1, /* unknown 1 */ - HSCX_VA2, /* 82525 A2 */ - HSCX_UNKN3, /* unknown 3 */ - HSCX_VA3, /* 82525 A3 */ - HSCX_V21, /* 82525 2.1 */ - HSCX_UNKN /* unknown version */ -}; - -#define HSCX_CH_A 0 /* channel A */ -#define HSCX_CH_B 1 /* channel B */ - -#define HSCX_FIFO_LEN 32 /* 32 bytes FIFO on chip */ - -/* - * definitions of registers and bits for the HSCX ISDN chip. - */ - -typedef struct hscx_reg { - - /* 32 byte deep FIFO always first */ - - unsigned char hscx_fifo [HSCX_FIFO_LEN]; - - /* most registers can be read/written, but have different names */ - /* so define a union with read/write names to make that clear */ - - union { - struct { - unsigned char hscx_ista; - unsigned char hscx_star; - unsigned char hscx_mode; - unsigned char hscx_timr; - unsigned char hscx_exir; - unsigned char hscx_rbcl; - unsigned char dummy_26; - unsigned char hscx_rsta; - unsigned char hscx_ral1; - unsigned char hscx_rhcr; - unsigned char dummy_2a; - unsigned char dummy_2b; - unsigned char hscx_ccr2; - unsigned char hscx_rbch; - unsigned char hscx_vstr; - unsigned char hscx_ccr; - unsigned char dummy_30; - unsigned char dummy_31; - unsigned char dummy_32; - unsigned char dummy_33; - } hscx_r; - struct { - unsigned char hscx_mask; - unsigned char hscx_cmdr; - unsigned char hscx_mode; - unsigned char hscx_timr; - unsigned char hscx_xad1; - unsigned char hscx_xad2; - unsigned char hscx_rah1; - unsigned char hscx_rah2; - unsigned char hscx_ral1; - unsigned char hscx_ral2; - unsigned char hscx_xbcl; - unsigned char hscx_bgr; - unsigned char hscx_ccr2; - unsigned char hscx_xbch; - unsigned char hscx_rlcr; - unsigned char hscx_ccr1; - unsigned char hscx_tsax; - unsigned char hscx_tsar; - unsigned char hscx_xccr; - unsigned char hscx_rccr; - } hscx_w; - } hscx_rw; -} hscx_reg_t; - -#define REG_OFFSET(type, field) (int)(&(((type *)0)->field)) - -/* HSCX read registers */ - -#define h_ista hscx_rw.hscx_r.hscx_ista -#define H_ISTA REG_OFFSET(hscx_reg_t, hscx_rw.hscx_r.hscx_ista) -#define h_star hscx_rw.hscx_r.hscx_star -#define H_STAR REG_OFFSET(hscx_reg_t, hscx_rw.hscx_r.hscx_star) -#define h_mode hscx_rw.hscx_r.hscx_mode -#define H_MODE REG_OFFSET(hscx_reg_t, hscx_rw.hscx_r.hscx_mode) -#define h_timr hscx_rw.hscx_r.hscx_timr -#define H_TIMR REG_OFFSET(hscx_reg_t, hscx_rw.hscx_r.hscx_timr) -#define h_exir hscx_rw.hscx_r.hscx_exir -#define H_EXIR REG_OFFSET(hscx_reg_t, hscx_rw.hscx_r.hscx_exir) -#define h_rbcl hscx_rw.hscx_r.hscx_rbcl -#define H_RBCL REG_OFFSET(hscx_reg_t, hscx_rw.hscx_r.hscx_rbcl) -#define h_rsta hscx_rw.hscx_r.hscx_rsta -#define H_RSTA REG_OFFSET(hscx_reg_t, hscx_rw.hscx_r.hscx_rsta) -#define h_ral1 hscx_rw.hscx_r.hscx_ral1 -#define H_RAL1 REG_OFFSET(hscx_reg_t, hscx_rw.hscx_r.hscx_ral1) -#define h_rhcr hscx_rw.hscx_r.hscx_rhcr -#define H_RHCR REG_OFFSET(hscx_reg_t, hscx_rw.hscx_r.hscx_rhcr) -#define h_ccr2 hscx_rw.hscx_r.hscx_ccr2 -#define H_CCR2 REG_OFFSET(hscx_reg_t, hscx_rw.hscx_r.hscx_ccr2) -#define h_rbch hscx_rw.hscx_r.hscx_rbch -#define H_RBCH REG_OFFSET(hscx_reg_t, hscx_rw.hscx_r.hscx_rbch) -#define h_vstr hscx_rw.hscx_r.hscx_vstr -#define H_VSTR REG_OFFSET(hscx_reg_t, hscx_rw.hscx_r.hscx_vstr) -#define h_ccr hscx_rw.hscx_r.hscx_ccr -#define H_CCR REG_OFFSET(hscx_reg_t, hscx_rw.hscx_r.hscx_ccr) - -/* HSCX write registers - for hscx_mode, hscx_timr, hscx_ral1, hscx_ccr2 */ -/* see read registers */ - -#define h_mask hscx_rw.hscx_w.hscx_mask -#define H_MASK REG_OFFSET(hscx_reg_t, hscx_rw.hscx_w.hscx_mask) -#define h_cmdr hscx_rw.hscx_w.hscx_cmdr -#define H_CMDR REG_OFFSET(hscx_reg_t, hscx_rw.hscx_w.hscx_cmdr) -#define h_xad1 hscx_rw.hscx_w.hscx_xad1 -#define H_XAD1 REG_OFFSET(hscx_reg_t, hscx_rw.hscx_w.hscx_xad1) -#define h_xad2 hscx_rw.hscx_w.hscx_xad2 -#define H_XAD2 REG_OFFSET(hscx_reg_t, hscx_rw.hscx_w.hscx_xad2) -#define h_rah1 hscx_rw.hscx_w.hscx_rah1 -#define H_RAH1 REG_OFFSET(hscx_reg_t, hscx_rw.hscx_w.hscx_rah1) -#define h_rah2 hscx_rw.hscx_w.hscx_rah2 -#define H_RAH2 REG_OFFSET(hscx_reg_t, hscx_rw.hscx_w.hscx_rah2) -#define h_ral2 hscx_rw.hscx_w.hscx_ral2 -#define H_RAL2 REG_OFFSET(hscx_reg_t, hscx_rw.hscx_w.hscx_ral2) -#define h_xbcl hscx_rw.hscx_w.hscx_xbcl -#define H_XBCL REG_OFFSET(hscx_reg_t, hscx_rw.hscx_w.hscx_xbcl) -#define h_bgr hscx_rw.hscx_w.hscx_bgr -#define H_BGR REG_OFFSET(hscx_reg_t, hscx_rw.hscx_w.hscx_bgr) -#define h_xbch hscx_rw.hscx_w.hscx_xbch -#define H_XBCH REG_OFFSET(hscx_reg_t, hscx_rw.hscx_w.hscx_xbch) -#define h_rlcr hscx_rw.hscx_w.hscx_rlcr -#define H_RLCR REG_OFFSET(hscx_reg_t, hscx_rw.hscx_w.hscx_rlcr) -#define h_ccr1 hscx_rw.hscx_w.hscx_ccr1 -#define H_CCR1 REG_OFFSET(hscx_reg_t, hscx_rw.hscx_w.hscx_ccr1) -#define h_tsax hscx_rw.hscx_w.hscx_tsax -#define H_TSAX REG_OFFSET(hscx_reg_t, hscx_rw.hscx_w.hscx_tsax) -#define h_tsar hscx_rw.hscx_w.hscx_tsar -#define H_TSAR REG_OFFSET(hscx_reg_t, hscx_rw.hscx_w.hscx_tsar) -#define h_xccr hscx_rw.hscx_w.hscx_xccr -#define H_XCCR REG_OFFSET(hscx_reg_t, hscx_rw.hscx_w.hscx_xccr) -#define h_rccr hscx_rw.hscx_w.hscx_rccr -#define H_RCCR REG_OFFSET(hscx_reg_t, hscx_rw.hscx_w.hscx_rccr) - -#define HSCX_ISTA_RME 0x80 -#define HSCX_ISTA_RPF 0x40 -#define HSCX_ISTA_RSC 0x20 -#define HSCX_ISTA_XPR 0x10 -#define HSCX_ISTA_TIN 0x08 -#define HSCX_ISTA_ICA 0x04 -#define HSCX_ISTA_EXA 0x02 -#define HSCX_ISTA_EXB 0x01 - -#define HSCX_MASK_RME 0x80 -#define HSCX_MASK_RPF 0x40 -#define HSCX_MASK_RSC 0x20 -#define HSCX_MASK_XPR 0x10 -#define HSCX_MASK_TIN 0x08 -#define HSCX_MASK_ICA 0x04 -#define HSCX_MASK_EXA 0x02 -#define HSCX_MASK_EXB 0x01 - -#define HSCX_EXIR_XMR 0x80 -#define HSCX_EXIR_XDU 0x40 -#define HSCX_EXIR_PCE 0x20 -#define HSCX_EXIR_RFO 0x10 -#define HSCX_EXIR_CSC 0x08 -#define HSCX_EXIR_RFS 0x04 - -/* the other bits are always 0 */ - -#define HSCX_STAR_XDOV 0x80 -#define HSCX_STAR_XFW 0x40 -#define HSCX_STAR_XRNR 0x20 -#define HSCX_STAR_RRNR 0x10 -#define HSCX_STAR_RLI 0x08 -#define HSCX_STAR_CEC 0x04 -#define HSCX_STAR_CTS 0x02 -#define HSCX_STAR_WFA 0x01 - -#define HSCX_CMDR_RMC 0x80 -#define HSCX_CMDR_RHR 0x40 -/* also known as XREP in transparent mode */ -#define HSCX_CMDR_RNR 0x20 -#define HSCX_CMDR_STI 0x10 -#define HSCX_CMDR_XTF 0x08 -#define HSCX_CMDR_XIF 0x04 -#define HSCX_CMDR_XME 0x02 -#define HSCX_CMDR_XRES 0x01 - -#define HSCX_MODE_MDS1 0x80 -#define HSCX_MODE_MDS0 0x40 -#define HSCX_MODE_ADM 0x20 -#define HSCX_MODE_TMD 0x10 -#define HSCX_MODE_RAC 0x08 -#define HSCX_MODE_RTS 0x04 -#define HSCX_MODE_TRS 0x02 -#define HSCX_MODE_TLP 0x01 - -#define HSCX_RSTA_VFR 0x80 -#define HSCX_RSTA_RDO 0x40 -#define HSCX_RSTA_CRC 0x20 -#define HSCX_RSTA_RAB 0x10 -#define HSCX_RSTA_HA1 0x08 -#define HSCX_RSTA_HA0 0x04 -#define HSCX_RSTA_CR 0x02 -#define HSCX_RSTA_LA 0x01 - -#define HSCX_RSTA_MASK 0xf0 /* the interesting ones */ - -/* only used in DMA mode */ -#define HSCX_XBCH_DMA 0x80 -#define HSCX_XBCH_NRM 0x40 -#define HSCX_XBCH_CAS 0x20 -#define HSCX_XBCH_XC 0x10 -/* the rest are bits 11 thru 8 of the byte count */ - -#define HSCX_RBCH_DMA 0x80 -#define HSCX_RBCH_NRM 0x40 -#define HSCX_RBCH_CAS 0x20 -#define HSCX_RBCH_OV 0x10 -/* the rest are bits 11 thru 8 of the byte count */ - -#define HSCX_VSTR_CD 0x80 -/* bits 6 thru 4 are 0 */ -/* bits 3 thru 0 are the version number */ - -#define HSCX_RLCR_RC 0x80 -/* the rest of the bits are used to set the received length */ - -#define HSCX_CCR1_PU 0x80 -/* bits 6 and 5 are SC1 SC0 */ -#define HSCX_CCR1_ODS 0x10 -#define HSCX_CCR1_ITF 0x08 -#define HSCX_CCR1_CM2 0x04 -#define HSCX_CCR1_CM1 0x02 -#define HSCX_CCR1_CM0 0x01 - -/* for clock mode 5 */ -#define HSCX_CCR2_SOC2 0x80 -#define HSCX_CCR2_SOC1 0x40 -#define HSCX_CCR2_XCS0 0x20 -#define HSCX_CCR2_RCS0 0x10 -#define HSCX_CCR2_TIO 0x08 -#define HSCX_CCR2_CIE 0x04 -#define HSCX_CCR2_RIE 0x02 -#define HSCX_CCR2_DIV 0x01 - -/* bits 7 thru 2 are TSNX */ -#define HSCX_TSAX_XCS2 0x02 -#define HSCX_TSAX_XCS1 0x01 - -/* bits 7 thru 2 are TSNR */ -#define HSCX_TSAR_RCS2 0x02 -#define HSCX_TSAR_RCS1 0x01 - -#endif /* I4B_HSCX_H_ */ diff --git a/sys/i4b/layer1/i4b_ipac.h b/sys/i4b/layer1/i4b_ipac.h deleted file mode 100644 index 73683d3..0000000 --- a/sys/i4b/layer1/i4b_ipac.h +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - *--------------------------------------------------------------------------- - * - * 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 $ - * - * $FreeBSD$ - * - * last edit-date: [Mon Dec 13 22:00:58 1999] - * - *--------------------------------------------------------------------------- - */ - -#ifndef _I4B_IPAC_H_ -#define _I4B_IPAC_H_ - -#define IPAC_BFIFO_LEN 64 /* 64 bytes B-channel FIFO on chip */ - -#define IPAC_HSCXA_OFF 0x00 -#define IPAC_HSCXB_OFF 0x40 -#define IPAC_ISAC_OFF 0x80 -#define IPAC_IPAC_OFF 0xc0 - -/* chip version */ - -#define IPAC_V11 0x01 /* IPAC Version 1.1 */ - -/* - * definitions of registers and bits for the IPAC ISDN chip. - */ - -typedef struct ipac_reg { - - /* most registers can be read/written, but have different names */ - /* so define a union with read/write names to make that clear */ - - union { - struct { - unsigned char ipac_conf; - unsigned char ipac_ista; - unsigned char ipac_id; - unsigned char ipac_acfg; - unsigned char ipac_aoe; - unsigned char ipac_arx; - unsigned char ipac_pita1; - unsigned char ipac_pita2; - unsigned char ipac_pota1; - unsigned char ipac_pota2; - unsigned char ipac_pcfg; - unsigned char ipac_scfg; - unsigned char ipac_timr2; - } ipac_r; - struct { - unsigned char ipac_conf; - unsigned char ipac_mask; - unsigned char ipac_dummy; - unsigned char ipac_acfg; - unsigned char ipac_aoe; - unsigned char ipac_atx; - unsigned char ipac_pita1; - unsigned char ipac_pita2; - unsigned char ipac_pota1; - unsigned char ipac_pota2; - unsigned char ipac_pcfg; - unsigned char ipac_scfg; - unsigned char ipac_timr2; - } ipac_w; - } ipac_rw; -} ipac_reg_t; - -#define REG_OFFSET(type, field) (int)(&(((type *)0)->field)) - -/* IPAC read registers */ - -#define IPAC_CONF REG_OFFSET(ipac_reg_t, ipac_rw.ipac_r.ipac_conf) -#define IPAC_ISTA REG_OFFSET(ipac_reg_t, ipac_rw.ipac_r.ipac_ista) -#define IPAC_ID REG_OFFSET(ipac_reg_t, ipac_rw.ipac_r.ipac_id) -#define IPAC_ACFG REG_OFFSET(ipac_reg_t, ipac_rw.ipac_r.ipac_acfg) -#define IPAC_AOE REG_OFFSET(ipac_reg_t, ipac_rw.ipac_r.ipac_aoe) -#define IPAC_ARX REG_OFFSET(ipac_reg_t, ipac_rw.ipac_r.ipac_arx) -#define IPAC_PITA1 REG_OFFSET(ipac_reg_t, ipac_rw.ipac_r.ipac_pita1) -#define IPAC_PITA2 REG_OFFSET(ipac_reg_t, ipac_rw.ipac_r.ipac_pita2) -#define IPAC_POTA1 REG_OFFSET(ipac_reg_t, ipac_rw.ipac_r.ipac_pota1) -#define IPAC_POTA2 REG_OFFSET(ipac_reg_t, ipac_rw.ipac_r.ipac_pota2) -#define IPAC_PCFG REG_OFFSET(ipac_reg_t, ipac_rw.ipac_r.ipac_pcfg) -#define IPAC_SCFG REG_OFFSET(ipac_reg_t, ipac_rw.ipac_r.ipac_scfg) -#define IPAC_TIMR2 REG_OFFSET(ipac_reg_t, ipac_rw.ipac_r.ipac_timr2) - -/* IPAC write registers */ - -#define IPAC_MASK REG_OFFSET(ipac_reg_t, ipac_rw.ipac_w.ipac_mask) -#define IPAC_ATX REG_OFFSET(ipac_reg_t, ipac_rw.ipac_w.ipac_atx) - -/* register bits */ - -#define IPAC_CONF_AMP 0x80 -#define IPAC_CONF_CFS 0x40 -#define IPAC_CONF_TEM 0x20 -#define IPAC_CONF_PDS 0x10 -#define IPAC_CONF_IDH 0x08 -#define IPAC_CONF_SGO 0x04 -#define IPAC_CONF_ODS 0x02 -#define IPAC_CONF_IOF 0x01 - -#define IPAC_ISTA_INT1 0x80 -#define IPAC_ISTA_INT0 0x40 -#define IPAC_ISTA_ICD 0x20 -#define IPAC_ISTA_EXD 0x10 -#define IPAC_ISTA_ICA 0x08 -#define IPAC_ISTA_EXA 0x04 -#define IPAC_ISTA_ICB 0x02 -#define IPAC_ISTA_EXB 0x01 - -#define IPAC_MASK_INT1 0x80 -#define IPAC_MASK_INT0 0x40 -#define IPAC_MASK_ICD 0x20 -#define IPAC_MASK_EXD 0x10 -#define IPAC_MASK_ICA 0x08 -#define IPAC_MASK_EXA 0x04 -#define IPAC_MASK_ICB 0x02 -#define IPAC_MASK_EXB 0x01 - -#define IPAC_ACFG_OD7 0x80 -#define IPAC_ACFG_OD6 0x40 -#define IPAC_ACFG_OD5 0x20 -#define IPAC_ACFG_OD4 0x10 -#define IPAC_ACFG_OD3 0x08 -#define IPAC_ACFG_OD2 0x04 -#define IPAC_ACFG_EL1 0x02 -#define IPAC_ACFG_EL2 0x01 - -#define IPAC_AOE_OE7 0x80 -#define IPAC_AOE_OE6 0x40 -#define IPAC_AOE_OE5 0x20 -#define IPAC_AOE_OE4 0x10 -#define IPAC_AOE_OE3 0x08 -#define IPAC_AOE_OE2 0x04 - -#define IPAC_ARX_AR7 0x80 -#define IPAC_ARX_AR6 0x40 -#define IPAC_ARX_AR5 0x20 -#define IPAC_ARX_AR4 0x10 -#define IPAC_ARX_AR3 0x08 -#define IPAC_ARX_AR2 0x04 - -#define IPAC_ATX_AT7 0x80 -#define IPAC_ATX_AT6 0x40 -#define IPAC_ATX_AT5 0x20 -#define IPAC_ATX_AT4 0x10 -#define IPAC_ATX_AT3 0x08 -#define IPAC_ATX_AT2 0x04 - -#define IPAC_PITA1_ENA 0x80 -#define IPAC_PITA1_DUDD 0x40 - -#define IPAC_PITA2_ENA 0x80 -#define IPAC_PITA2_DUDD 0x40 - -#define IPAC_POTA1_ENA 0x80 -#define IPAC_POTA1_DUDD 0x40 - -#define IPAC_POTA2_ENA 0x80 -#define IPAC_POTA2_DUDD 0x40 - -#define IPAC_PCFG_DPS 0x80 -#define IPAC_PCFG_ACL 0x40 -#define IPAC_PCFG_LED 0x20 -#define IPAC_PCFG_PLD 0x10 -#define IPAC_PCFG_FBS 0x08 -#define IPAC_PCFG_CSL2 0x04 -#define IPAC_PCFG_CSL1 0x02 -#define IPAC_PCFG_CSL0 0x01 - -#define IPAC_SCFG_PRI 0x80 -#define IPAC_SCFG_TXD 0x40 -#define IPAC_SCFG_TLEN 0x20 - -#define IPAC_TIMR2_TMD 0x80 - -#endif /* _I4B_IPAC_H_ */ diff --git a/sys/i4b/layer1/i4b_isac.c b/sys/i4b/layer1/i4b_isac.c deleted file mode 100644 index 8c5cb15..0000000 --- a/sys/i4b/layer1/i4b_isac.c +++ /dev/null @@ -1,664 +0,0 @@ -/* - * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - *--------------------------------------------------------------------------- - * - * 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 $ - * - * $FreeBSD$ - * - * last edit-date: [Mon Dec 13 22:01:05 1999] - * - *---------------------------------------------------------------------------*/ - -#include "isic.h" - -#if NISIC > 0 - -#include "opt_i4b.h" - -#include -#include -#include -#include - -#include -#include - -#include - -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -static u_char isic_isac_exir_hdlr(register struct l1_softc *sc, u_char exir); -static void isic_isac_ind_hdlr(register struct l1_softc *sc, int ind); - -/*---------------------------------------------------------------------------* - * ISAC interrupt service routine - *---------------------------------------------------------------------------*/ -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)); - - if(ista & ISAC_ISTA_EXI) /* extended interrupt */ - { - c |= isic_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++; - DBGL1(L1_I_ERR, "isic_isac_irq", ("unit %d: CRC error\n", 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)); - } - - if(rsta & ISAC_RSTA_RAB) /* ReceiveABorted */ - { - error++; - DBGL1(L1_I_ERR, "isic_isac_irq", ("unit %d: Receive Aborted error\n", 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)); - - 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("isic_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 = 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); - } - - c |= ISAC_CMDR_RMC; - - if(sc->sc_enabled && - (ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S)) - { - PH_Data_Ind(sc->sc_unit, sc->sc_ibuf); - } - else - { - i4b_Dfreembuf(sc->sc_ibuf); - } - } - else - { - DBGL1(L1_I_ERR, "isic_isac_irq", ("RME, input buffer overflow!\n")); - 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("isic_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 - { - DBGL1(L1_I_ERR, "isic_isac_irq", ("RPF, input buffer overflow!\n")); - 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) - isic_isac_ind_hdlr(sc, (ci >> 2) & 0xf); - } - - if(c) - { - ISAC_WRITE(I_CMDR, c); - ISACCMDRWRDELAY(); - } -} - -/*---------------------------------------------------------------------------* - * ISAC L1 Extended IRQ handler - *---------------------------------------------------------------------------*/ -static u_char -isic_isac_exir_hdlr(register struct l1_softc *sc, u_char exir) -{ - u_char c = 0; - - if(exir & ISAC_EXIR_XMR) - { - DBGL1(L1_I_ERR, "isic_isac_exir_hdlr", ("EXIRQ Tx Message Repeat\n")); - - c |= ISAC_CMDR_XRES; - } - - if(exir & ISAC_EXIR_XDU) - { - DBGL1(L1_I_ERR, "isic_isac_exir_hdlr", ("EXIRQ Tx Data Underrun\n")); - - c |= ISAC_CMDR_XRES; - } - - if(exir & ISAC_EXIR_PCE) - { - DBGL1(L1_I_ERR, "isic_isac_exir_hdlr", ("EXIRQ Protocol Error\n")); - } - - if(exir & ISAC_EXIR_RFO) - { - DBGL1(L1_I_ERR, "isic_isac_exir_hdlr", ("EXIRQ Rx Frame Overflow\n")); - - 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")); - } - - if(exir & ISAC_EXIR_MOS) - { - DBGL1(L1_I_ERR, "L1 isic_isac_exir_hdlr", ("EXIRQ Monitor Status\n")); - } - - 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")); - } - - 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")); - } - - return(c); -} - -/*---------------------------------------------------------------------------* - * ISAC L1 Indication handler - *---------------------------------------------------------------------------*/ -static void -isic_isac_ind_hdlr(register struct l1_softc *sc, int ind) -{ - register int event; - - switch(ind) - { - case ISAC_CIRR_IAI8: - DBGL1(L1_I_CICO, "isic_isac_ind_hdlr", ("rx AI8 in state %s\n", 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); - break; - - case ISAC_CIRR_IAI10: - DBGL1(L1_I_CICO, "isic_isac_ind_hdlr", ("rx AI10 in state %s\n", 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); - break; - - case ISAC_CIRR_IRSY: - DBGL1(L1_I_CICO, "isic_isac_ind_hdlr", ("rx RSY in state %s\n", 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))); - 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))); - 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))); - event = EV_INFO0; - MPH_Status_Ind(sc->sc_unit, STI_L1STAT, LAYER_IDLE); - break; - - case ISAC_CIRR_IDIS: - DBGL1(L1_I_CICO, "isic_isac_ind_hdlr", ("rx DIS in state %s\n", 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))); - 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))); - 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))); - 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))); - 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))); - 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))); - event = EV_INFO0; - break; - } - isic_next_state(sc, event); -} - -/*---------------------------------------------------------------------------* - * execute a layer 1 command - *---------------------------------------------------------------------------*/ -void -isic_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) - { - DBGL1(L1_I_ERR, "isic_isac_l1_cmd", ("illegal cmd 0x%x in state %s\n", command, isic_printstate(sc))); - return; - } - - if(sc->sc_bustyp == BUS_TYPE_IOM2) - cmd = ISAC_CIX0_LOW; - else - cmd = 0; - - switch(command) - { - case CMD_TIM: - DBGL1(L1_I_CICO, "isic_isac_l1_cmd", ("tx TIM in state %s\n", 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))); - 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))); - 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))); - 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))); - cmd |= (ISAC_CIXR_CDIU << 2); - break; - } - ISAC_WRITE(I_CIXR, cmd); -} - -/*---------------------------------------------------------------------------* - * L1 ISAC initialization - *---------------------------------------------------------------------------*/ -int -isic_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) - { - DBGL1(L1_I_SETUP, "isic_isac_setup", ("configuring for IOM-1 mode\n")); - - /* 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 - { - DBGL1(L1_I_SETUP, "isic_isac_setup", ("configuring for IOM-2 mode\n")); - - /* 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 /* NISIC > 0 */ diff --git a/sys/i4b/layer1/i4b_isac.h b/sys/i4b/layer1/i4b_isac.h deleted file mode 100644 index 83fa1db..0000000 --- a/sys/i4b/layer1/i4b_isac.h +++ /dev/null @@ -1,390 +0,0 @@ -/* - * Copyright (c) 1996, 1998 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. - * 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. - * - *--------------------------------------------------------------------------- - * - * $Id: i4b_isac.h,v 1.2 1999/12/13 21:25:26 hm Exp $ - * - * $FreeBSD$ - * - * last edit-date: [Mon Dec 13 22:01:25 1999] - * - *---------------------------------------------------------------------------*/ - -#ifndef I4B_ISAC_H_ -#define I4B_ISAC_H_ - -/* - * The ISAC databook specifies a delay of 2.5 DCL clock cycles between - * writes to the ISAC command register CMDR. This is the delay used to - * satisfy this requirement. - */ - -#define I4B_ISAC_CMDRWRDELAY 30 - -#if (I4B_ISAC_CMDRWRDELAY > 0) -#define ISACCMDRWRDELAY() DELAY(I4B_ISAC_CMDRWRDELAY) -#else -#warning "I4B_ISAC_CMDRWRDELAY set to 0!" -#define ISACCMDRWRDELAY() -#endif - -enum ISAC_VERSIONS { - ISAC_VA, /* 2085 A1 or A2, 2086/2186 V1.1 */ - ISAC_VB1, /* 2085 B1 */ - ISAC_VB2, /* 2085 B2 */ - ISAC_VB3, /* 2085 B3/V2.3 */ - ISAC_UNKN /* unknown version */ -}; - -#define ISAC_FIFO_LEN 32 /* 32 bytes FIFO on chip */ - -/* - * definitions of registers and bits for the ISAC ISDN chip. - */ - -typedef struct isac_reg { - - /* 32 byte deep FIFO always first */ - - unsigned char isac_fifo [ISAC_FIFO_LEN]; - - /* most registers can be read/written, but have different names */ - /* so define a union with read/write names to make that clear */ - - union { - struct { - unsigned char isac_ista; - unsigned char isac_star; - unsigned char isac_mode; - unsigned char isac_timr; - unsigned char isac_exir; - unsigned char isac_rbcl; - unsigned char isac_sapr; - unsigned char isac_rsta; - unsigned char dummy_28; - unsigned char isac_rhcr; - unsigned char isac_rbch; - unsigned char isac_star2; - unsigned char dummy_2c; - unsigned char dummy_2d; - unsigned char dummy_2e; - unsigned char dummt_2f; - unsigned char isac_spcr; - unsigned char isac_cirr; - unsigned char isac_mor; - unsigned char isac_sscr; - unsigned char isac_sfcr; - unsigned char isac_c1r; - unsigned char isac_c2r; - unsigned char isac_b1cr; - unsigned char isac_b2cr; - unsigned char isac_adf2; - unsigned char isac_mosr; - unsigned char isac_sqrr; - } isac_r; - struct { - unsigned char isac_mask; - unsigned char isac_cmdr; - unsigned char isac_mode; - unsigned char isac_timr; - unsigned char isac_xad1; - unsigned char isac_xad2; - unsigned char isac_sap1; - unsigned char isac_sap2; - unsigned char isac_tei1; - unsigned char isac_tei2; - unsigned char dummy_2a; - unsigned char isac_star2; - unsigned char dummy_2c; - unsigned char dummy_2d; - unsigned char dummy_2e; - unsigned char dummt_2f; - unsigned char isac_spcr; - unsigned char isac_cixr; - unsigned char isac_mox; - unsigned char isac_sscx; - unsigned char isac_sfcw; - unsigned char isac_c1r; - unsigned char isac_c2r; - unsigned char isac_stcr; - unsigned char isac_adf1; - unsigned char isac_adf2; - unsigned char isac_mocr; - unsigned char isac_sqxr; - } isac_w; - } isac_rw; -} isac_reg_t; - -#define REG_OFFSET(type, field) (int)(&(((type *)0)->field)) - -/* ISAC read registers */ - -#define i_ista isac_rw.isac_r.isac_ista -#define I_ISTA REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_ista) -#define i_star isac_rw.isac_r.isac_star -#define I_STAR REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_star) -#define i_mode isac_rw.isac_r.isac_mode -#define I_MODE REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_mode) -#define i_timr isac_rw.isac_r.isac_timr -#define I_TIMR REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_timr) -#define i_exir isac_rw.isac_r.isac_exir -#define I_EXIR REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_exir) -#define i_rbcl isac_rw.isac_r.isac_rbcl -#define I_RBCL REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_rbcl) -#define i_sapr isac_rw.isac_r.isac_sapr -#define I_SAPR REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_sapr) -#define i_rsta isac_rw.isac_r.isac_rsta -#define I_RSTA REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_rsta) -#define i_rhcr isac_rw.isac_r.isac_rhcr -#define I_RHCR REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_rhcr) -#define i_rbch isac_rw.isac_r.isac_rbch -#define I_RBCH REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_rbch) -#define i_star2 isac_rw.isac_r.isac_star2 -#define I_STAR2 REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_star2) -#define i_spcr isac_rw.isac_r.isac_spcr -#define I_SPCR REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_spcr) -#define i_cirr isac_rw.isac_r.isac_cirr -#define I_CIRR REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_cirr) -#define i_mor isac_rw.isac_r.isac_mor -#define I_MOR REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_mor) -#define i_sscr isac_rw.isac_r.isac_sscr -#define I_SSCR REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_sscr) -#define i_sfcr isac_rw.isac_r.isac_sfcr -#define I_SFCR REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_sfcr) -#define i_c1r isac_rw.isac_r.isac_c1r -#define I_C1R REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_c1r) -#define i_c2r isac_rw.isac_r.isac_c2r -#define I_C2R REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_c2r) -#define i_b1cr isac_rw.isac_r.isac_b1cr -#define I_B1CR REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_b1cr) -#define i_b2cr isac_rw.isac_r.isac_b2cr -#define I_B2CR REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_b2cr) -#define i_adf2 isac_rw.isac_r.isac_adf2 -#define I_ADF2 REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_adf2) -#define i_mosr isac_rw.isac_r.isac_mosr -#define I_MOSR REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_mosr) -#define i_sqrr isac_rw.isac_r.isac_sqrr -#define I_SQRR REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_sqrr) - -/* ISAC write registers - isac_mode, isac_timr, isac_star2, isac_spcr, */ -/* isac_c1r, isac_c2r, isac_adf2 see read registers */ - -#define i_mask isac_rw.isac_w.isac_mask -#define I_MASK REG_OFFSET(isac_reg_t, isac_rw.isac_w.isac_mask) -#define i_cmdr isac_rw.isac_w.isac_cmdr -#define I_CMDR REG_OFFSET(isac_reg_t, isac_rw.isac_w.isac_cmdr) -#define i_xad1 isac_rw.isac_w.isac_xad1 -#define I_XAD1 REG_OFFSET(isac_reg_t, isac_rw.isac_w.isac_xad1) -#define i_xad2 isac_rw.isac_w.isac_xad2 -#define I_XAD2 REG_OFFSET(isac_reg_t, isac_rw.isac_w.isac_xad2) -#define i_sap1 isac_rw.isac_w.isac_sap1 -#define I_SAP1 REG_OFFSET(isac_reg_t, isac_rw.isac_w.isac_sap1) -#define i_sap2 isac_rw.isac_w.isac_sap2 -#define I_SAP2 REG_OFFSET(isac_reg_t, isac_rw.isac_w.isac_sap2) -#define i_tei1 isac_rw.isac_w.isac_tei1 -#define i_tei2 isac_rw.isac_w.isac_tei2 -#define i_cixr isac_rw.isac_w.isac_cixr -#define I_CIXR REG_OFFSET(isac_reg_t, isac_rw.isac_w.isac_cixr) -#define I_CIX0 I_CIXR -#define i_mox isac_rw.isac_w.isac_mox -#define I_MOX REG_OFFSET(isac_reg_t, isac_rw.isac_w.isac_mox) -#define i_sscx isac_rw.isac_w.isac_sscx -#define I_SSCX REG_OFFSET(isac_reg_t, isac_rw.isac_w.isac_sscx) -#define i_sfcw isac_rw.isac_w.isac_sfcw -#define I_SFCW REG_OFFSET(isac_reg_t, isac_rw.isac_w.isac_sfcw) -#define i_stcr isac_rw.isac_w.isac_stcr -#define I_STCR REG_OFFSET(isac_reg_t, isac_rw.isac_w.isac_stcr) -#define i_adf1 isac_rw.isac_w.isac_adf1 -#define I_ADF1 REG_OFFSET(isac_reg_t, isac_rw.isac_w.isac_adf1) -#define i_mocr isac_rw.isac_w.isac_mocr -#define I_MOCR REG_OFFSET(isac_reg_t, isac_rw.isac_w.isac_mocr) -#define i_sqxr isac_rw.isac_w.isac_sqxr -#define I_SQXR REG_OFFSET(isac_reg_t, isac_rw.isac_w.isac_sqxr) - -#define ISAC_ISTA_RME 0x80 -#define ISAC_ISTA_RPF 0x40 -#define ISAC_ISTA_RSC 0x20 -#define ISAC_ISTA_XPR 0x10 -#define ISAC_ISTA_TIN 0x08 -#define ISAC_ISTA_CISQ 0x04 -#define ISAC_ISTA_SIN 0x02 -#define ISAC_ISTA_EXI 0x01 - -#define ISAC_MASK_RME 0x80 -#define ISAC_MASL_RPF 0x40 -#define ISAC_MASK_RSC 0x20 -#define ISAC_MASK_XPR 0x10 -#define ISAC_MASK_TIN 0x08 -#define ISAC_MASK_CISQ 0x04 -#define ISAC_MASK_SIN 0x02 -#define ISAC_MASK_EXI 0x01 -#define ISAC_MASK_ALL 0xff - -#define ISAC_STAR_XDOV 0x80 -#define ISAC_STAR_XFW 0x40 -#define ISAC_STAR_XRNR 0x20 -#define ISAC_STAR_RRNR 0x10 -#define ISAC_STAR_MBR 0x08 -#define ISAC_STAR_MAC1 0x04 -#define ISAC_STAR_BVS 0x02 -#define ISAC_STAR_MAC0 0x01 - -#define ISAC_CMDR_RMC 0x80 -#define ISAC_CMDR_RRES 0x40 -#define ISAC_CMDR_RNR 0x20 -#define ISAC_CMDR_STI 0x10 -#define ISAC_CMDR_XTF 0x08 -#define ISAC_CMDR_XIF 0x04 -#define ISAC_CMDR_XME 0x02 -#define ISAC_CMDR_XRES 0x01 - -#define ISAC_MODE_MDS2 0x80 -#define ISAC_MODE_MDS1 0x40 -#define ISAC_MODE_MDS0 0x20 -#define ISAC_MODE_TMD 0x10 -#define ISAC_MODE_RAC 0x08 -#define ISAC_MODE_DIM2 0x04 -#define ISAC_MODE_DIM1 0x02 -#define ISAC_MODE_DIM0 0x01 - -#define ISAC_EXIR_XMR 0x80 -#define ISAC_EXIR_XDU 0x40 -#define ISAC_EXIR_PCE 0x20 -#define ISAC_EXIR_RFO 0x10 -#define ISAC_EXIR_SOV 0x08 -#define ISAC_EXIR_MOS 0x04 -#define ISAC_EXIR_SAW 0x02 -#define ISAC_EXIR_WOV 0x01 - -#define ISAC_RSTA_RDA 0x80 -#define ISAC_RSTA_RDO 0x40 -#define ISAC_RSTA_CRC 0x20 -#define ISAC_RSTA_RAB 0x10 -#define ISAC_RSTA_SA1 0x08 -#define ISAC_RSTA_SA0 0x04 -#define ISAC_RSTA_CR 0x02 -#define ISAC_RSTA_TA 0x01 - -#define ISAC_RSTA_MASK 0x70 /* the interesting bits */ - -#define ISAC_RBCH_XAC 0x80 -#define ISAC_RBCH_VN1 0x40 -#define ISAC_RBCH_VN0 0x20 -#define ISAC_RBCH_OV 0x10 -/* the other 4 bits are the high bits of the receive byte count */ - -#define ISAC_SPCR_SPU 0x80 -#define ISAC_SPCR_SAC 0x40 -#define ISAC_SPCR_SPM 0x20 -#define ISAC_SPCR_TLP 0x10 -#define ISAC_SPCR_C1C1 0x08 -#define ISAC_SPCR_C1C0 0x04 -#define ISAC_SPCR_C2C1 0x02 -#define ISAC_SPCR_C2C0 0x01 - -#define ISAC_CIRR_SQC 0x80 -#define ISAC_CIRR_BAS 0x40 -/* bits 5-2 CODR */ -#define ISAC_CIRR_CIC0 0x02 -/* bit 0 is always 0 */ -/* C/I codes from bits 5-2 (>> 2 & 0xf) */ -/* the indications */ -#define ISAC_CIRR_IPU 0x07 -#define ISAC_CIRR_IDR 0x00 -#define ISAC_CIRR_ISD 0x02 -#define ISAC_CIRR_IDIS 0x03 -#define ISAC_CIRR_IEI 0x06 -#define ISAC_CIRR_IRSY 0x04 -#define ISAC_CIRR_IARD 0x08 -#define ISAC_CIRR_ITI 0x0a -#define ISAC_CIRR_IATI 0x0b -#define ISAC_CIRR_IAI8 0x0c -#define ISAC_CIRR_IAI10 0x0d -#define ISAC_CIRR_IDID 0x0f - -#define ISAC_CI_MASK 0x0f - -#define ISAC_CIXR_RSS 0x80 -#define ISAC_CIXR_BAC 0x40 -/* bits 5-2 CODX */ -#define ISAC_CIXR_TCX 0x02 -#define ISAC_CIXR_ECX 0x01 -/* in IOM-2 mode the low bits are always 1 */ -#define ISAC_CIX0_LOW 0x03 -/* C/I codes from bits 5-2 (>> 2 & 0xf) */ -/* the commands */ -#define ISAC_CIXR_CTIM 0 -#define ISAC_CIXR_CRS 0x01 -#define ISAC_CIXR_CSCZ 0x04 -#define ISAC_CIXR_CSSZ 0x02 -#define ISAC_CIXR_CAR8 0x08 -#define ISAC_CIXR_CAR10 0x09 -#define ISAC_CIXR_CARL 0x0a -#define ISAC_CIXR_CDIU 0x0f - -#define ISAC_STCR_TSF 0x80 -#define ISAC_STCR_TBA2 0x40 -#define ISAC_STCR_TBA1 0x20 -#define ISAC_STCR_TBA0 0x10 -#define ISAC_STCR_ST1 0x08 -#define ISAC_STCR_ST0 0x04 -#define ISAC_STCR_SC1 0x02 -#define ISAC_STCR_SC0 0x01 - -#define ISAC_ADF1_WTC1 0x80 -#define ISAC_ADF1_WTC2 0x40 -#define ISAC_ADF1_TEM 0x20 -#define ISAC_ADF1_PFS 0x10 -#define ISAC_ADF1_CFS 0x08 -#define ISAC_ADF1_FC2 0x04 -#define ISAC_ADF1_FC1 0x02 -#define ISAC_ADF1_ITF 0x01 - -#define ISAC_ADF2_IMS 0x80 -/* all other bits are 0 */ - -/* bits 7-5 are always 0 */ -#define ISAC_SQRR_SYN 0x10 -#define ISAC_SQRR_SQR1 0x08 -#define ISAC_SQRR_SQR2 0x04 -#define ISAC_SQRR_SQR3 0x02 -#define ISAC_SQRR_SQR4 0x01 - -#define ISAC_SQXR_IDC 0x80 -#define ISAC_SQXR_CFS 0x40 -#define ISAC_SQXR_CI1E 0x20 -#define ISAC_SQXR_SQIE 0x10 -#define ISAC_SQXR_SQX1 0x08 -#define ISAC_SQXR_SQX2 0x04 -#define ISAC_SQXR_SQX3 0x02 -#define ISAC_SQXR_SQX4 0x01 - -#endif /* I4B_ISAC_H_ */ diff --git a/sys/i4b/layer1/i4b_isic.c b/sys/i4b/layer1/i4b_isic.c deleted file mode 100644 index d3d5ca8..0000000 --- a/sys/i4b/layer1/i4b_isic.c +++ /dev/null @@ -1,515 +0,0 @@ -/* - * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - *--------------------------------------------------------------------------- - * - * i4b_isic.c - global isic stuff - * ============================== - * - * $Id: i4b_isic.c,v 1.3 1999/12/13 21:25:26 hm Exp $ - * - * $FreeBSD$ - * - * last edit-date: [Mon Dec 13 22:01:33 1999] - * - *---------------------------------------------------------------------------*/ - -#include "isic.h" -#include "opt_i4b.h" - -#if NISIC > 0 - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -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", - "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 - device driver interrupt routine - *---------------------------------------------------------------------------*/ -void -isicintr(struct l1_softc *sc) -{ - if(sc->sc_ipac == 0) /* HSCX/ISAC interupt routine */ - { - u_char was_hscx_irq = 0; - u_char was_isac_irq = 0; - - register u_char hscx_irq_stat; - register u_char isac_irq_stat; - - for(;;) - { - /* get hscx irq status from hscx b ista */ - hscx_irq_stat = - HSCX_READ(HSCX_CH_B, H_ISTA) & ~HSCX_B_IMASK; - - /* get isac irq status */ - isac_irq_stat = ISAC_READ(I_ISTA); - - /* do as long as there are pending irqs in the chips */ - if(!hscx_irq_stat && !isac_irq_stat) - break; - - if(hscx_irq_stat & (HSCX_ISTA_RME | HSCX_ISTA_RPF | - HSCX_ISTA_RSC | HSCX_ISTA_XPR | - HSCX_ISTA_TIN | HSCX_ISTA_EXB)) - { - isic_hscx_irq(sc, hscx_irq_stat, - HSCX_CH_B, - hscx_irq_stat & HSCX_ISTA_EXB); - was_hscx_irq = 1; - } - - if(hscx_irq_stat & (HSCX_ISTA_ICA | HSCX_ISTA_EXA)) - { - isic_hscx_irq(sc, - HSCX_READ(HSCX_CH_A, H_ISTA) & ~HSCX_A_IMASK, - HSCX_CH_A, - hscx_irq_stat & HSCX_ISTA_EXA); - was_hscx_irq = 1; - } - - if(isac_irq_stat) - { - isic_isac_irq(sc, isac_irq_stat); /* isac handler */ - was_isac_irq = 1; - } - } - - HSCX_WRITE(0, H_MASK, 0xff); - ISAC_WRITE(I_MASK, 0xff); - HSCX_WRITE(1, H_MASK, 0xff); - -#ifdef ELSA_QS1ISA - DELAY(80); - - if((sc->sc_cardtyp == CARD_TYPEP_ELSAQS1ISA) && (sc->clearirq)) - { - sc->clearirq(sc); - } -#else - DELAY(100); -#endif - - HSCX_WRITE(0, H_MASK, HSCX_A_IMASK); - ISAC_WRITE(I_MASK, ISAC_IMASK); - HSCX_WRITE(1, H_MASK, HSCX_B_IMASK); - } - else /* IPAC interrupt routine */ - { - register u_char ipac_irq_stat; - register u_char was_ipac_irq = 0; - - for(;;) - { - /* get global irq status */ - - ipac_irq_stat = (IPAC_READ(IPAC_ISTA)) & 0x3f; - - /* check hscx a */ - - if(ipac_irq_stat & (IPAC_ISTA_ICA | IPAC_ISTA_EXA)) - { - /* HSCX A interrupt */ - isic_hscx_irq(sc, HSCX_READ(HSCX_CH_A, H_ISTA), - HSCX_CH_A, - ipac_irq_stat & IPAC_ISTA_EXA); - was_ipac_irq = 1; - } - if(ipac_irq_stat & (IPAC_ISTA_ICB | IPAC_ISTA_EXB)) - { - /* HSCX B interrupt */ - isic_hscx_irq(sc, HSCX_READ(HSCX_CH_B, H_ISTA), - HSCX_CH_B, - ipac_irq_stat & IPAC_ISTA_EXB); - was_ipac_irq = 1; - } - if(ipac_irq_stat & IPAC_ISTA_ICD) - { - /* ISAC interrupt */ - isic_isac_irq(sc, ISAC_READ(I_ISTA)); - was_ipac_irq = 1; - } - if(ipac_irq_stat & IPAC_ISTA_EXD) - { - /* force ISAC interrupt handling */ - isic_isac_irq(sc, ISAC_ISTA_EXI); - was_ipac_irq = 1; - } - - /* do as long as there are pending irqs in the chip */ - if(!ipac_irq_stat) - break; - } - - IPAC_WRITE(IPAC_MASK, 0xff); - DELAY(50); - IPAC_WRITE(IPAC_MASK, 0xc0); - } -} - -/*---------------------------------------------------------------------------* - * 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 -isic_recover(struct l1_softc *sc) -{ - u_char byte; - - /* get hscx irq status from hscx b ista */ - - byte = HSCX_READ(HSCX_CH_B, H_ISTA); - - DBGL1(L1_ERROR, "isic_recover", ("HSCX B: ISTA = 0x%x\n", 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))); - - 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))); - - 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))); - - /* get isac irq status */ - - byte = ISAC_READ(I_ISTA); - - DBGL1(L1_ERROR, "isic_recover", (" ISAC: ISTA = 0x%x\n", byte)); - - if(byte & ISAC_ISTA_EXI) - DBGL1(L1_ERROR, "isic_recover", (" ISAC: EXIR = 0x%x\n", (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)); - - if(byte & ISAC_CIRR_SQC) - DBGL1(L1_ERROR, "isic_recover", (" ISAC: SQRR = 0x%x\n", (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)); - - HSCX_WRITE(0, H_MASK, 0xff); - HSCX_WRITE(1, H_MASK, 0xff); - DELAY(100); - HSCX_WRITE(0, H_MASK, HSCX_A_IMASK); - HSCX_WRITE(1, H_MASK, HSCX_B_IMASK); - DELAY(100); - - DBGL1(L1_ERROR, "isic_recover", (" ISAC: IMASK = 0x%x\n", ISAC_IMASK)); - - ISAC_WRITE(I_MASK, 0xff); - DELAY(100); - ISAC_WRITE(I_MASK, ISAC_IMASK); -} - -/*---------------------------------------------------------------------------* - * isic_attach_common - common attach routine for all busses - *---------------------------------------------------------------------------*/ -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]; - - sc->sc_unit = unit; - - sc->sc_isac_version = 0; - sc->sc_hscx_version = 0; - - 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; - - } - } - 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: - break; - - default: - printf("isic%d: Error, ISAC version %d unknown!\n", - unit, sc->sc_isac_version); - return ENXIO; - 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%d: Error, HSCX version %d unknown!\n", - unit, sc->sc_hscx_version); - return ENXIO; - break; - } - } - - isic_isac_init(sc); /* ISAC setup */ - - /* 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); - - isic_init_linktab(sc); /* setup linktab */ - - sc->sc_trace = TRACE_OFF; /* set trace level */ - - sc->sc_state = ISAC_IDLE; /* set state */ - - sc->sc_ibuf = NULL; /* input buffering */ - sc->sc_ib = NULL; - sc->sc_ilen = 0; - - sc->sc_obuf = NULL; /* output buffering */ - sc->sc_op = NULL; - sc->sc_ol = 0; - sc->sc_freeflag = 0; - - sc->sc_obuf2 = NULL; /* second output buffer */ - sc->sc_freeflag2 = 0; - - /* timer setup */ - - callout_handle_init(&sc->sc_T3_callout); - callout_handle_init(&sc->sc_T4_callout); - - /* init higher protocol layers */ - - MPH_Status_Ind(sc->sc_unit, STI_ATTACH, sc->sc_cardtyp); - - /* announce manufacturer and card type for ISA cards */ - - switch(sc->sc_flags) - { - case FLAG_TELES_S0_8: - drvid = "Teles S0/8 (or compatible)"; - break; - - case FLAG_TELES_S0_16: - drvid = "Teles S0/16 (or compatible)"; - break; - - case FLAG_TELES_S0_163: - drvid = "Teles S0/16.3"; - break; - - case FLAG_AVM_A1: - drvid = "AVM A1 or Fritz!Card Classic"; - break; - - case FLAG_AVM_A1_PCMCIA: - drvid = "AVM Fritz!Card PCMCIA"; - break; - - case FLAG_USR_ISDN_TA_INT: - drvid = "USRobotics Sportster ISDN TA intern"; - break; - - case FLAG_ITK_IX1: - drvid = "ITK ix1 micro"; - break; - - case FLAG_ELSA_PCC16: - drvid = "ELSA MicroLink ISDN/PCC-16"; - break; - - default: - drvid = NULL; /* pnp/pci cards announce themselves */ - break; - } - - if(drvid) - printf("isic%d: %s\n", unit, drvid); - - if(bootverbose) - { - /* announce chip versions */ - - if(sc->sc_ipac) - { - printf("isic%d: IPAC PSB2115 Version 1.1\n", unit); - } - else - { - printf("isic%d: ISAC %s (IOM-%c)\n", - unit, - ISACversion[sc->sc_isac_version], - sc->sc_bustyp == BUS_TYPE_IOM1 ? '1' : '2'); - - printf("isic%d: HSCX %s\n", - unit, - HSCXversion[sc->sc_hscx_version]); - } - } - return 0; -} - -/*---------------------------------------------------------------------------* - * isic_detach_common - common detach routine for all busses - *---------------------------------------------------------------------------*/ -void -isic_detach_common(device_t dev) -{ - struct l1_softc *sc = &l1_sc[device_get_unit(dev)]; - int i; - - sc->sc_flags = 0; - - /* free interrupt resources */ - - if(sc->sc_resources.irq) - { - /* tear down interupt handler */ - bus_teardown_intr(dev, sc->sc_resources.irq, - (void(*)(void *))isicintr); - - /* free irq */ - bus_release_resource(dev, SYS_RES_IRQ, - sc->sc_resources.irq_rid, - sc->sc_resources.irq); - sc->sc_resources.irq_rid = 0; - sc->sc_resources.irq = 0; - } - - /* free memory resource */ - - if(sc->sc_resources.mem) - { - bus_release_resource(dev,SYS_RES_MEMORY, - sc->sc_resources.mem_rid, - sc->sc_resources.mem); - sc->sc_resources.mem_rid = 0; - sc->sc_resources.mem = 0; - } - - /* free iobases */ - - for(i=0; i < INFO_IO_BASES ; i++) - { - if(sc->sc_resources.io_base[i]) - { - bus_release_resource(dev, SYS_RES_IOPORT, - sc->sc_resources.io_rid[i], - sc->sc_resources.io_base[i]); - sc->sc_resources.io_rid[i] = 0; - sc->sc_resources.io_base[i] = 0; - } - } -} - -#endif /* NISIC > 0 */ - diff --git a/sys/i4b/layer1/i4b_isic_isa.c b/sys/i4b/layer1/i4b_isic_isa.c deleted file mode 100644 index 6228fa1..0000000 --- a/sys/i4b/layer1/i4b_isic_isa.c +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - *--------------------------------------------------------------------------- - * - * i4b_isic_isa.c - ISA bus interface - * ================================== - * - * $Id: i4b_isic_isa.c,v 1.4 1999/12/13 21:25:26 hm Exp $ - * - * $FreeBSD$ - * - * last edit-date: [Mon Dec 13 22:01:39 1999] - * - *---------------------------------------------------------------------------*/ - -#include "isic.h" -#include "opt_i4b.h" - -#if NISIC > 0 - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -struct l1_softc l1_sc[ISIC_MAXUNIT]; - -static int isic_isa_probe(device_t dev); -static int isic_isa_attach(device_t dev); - -static device_method_t isic_methods[] = { - DEVMETHOD(device_probe, isic_isa_probe), - DEVMETHOD(device_attach, isic_isa_attach), - { 0, 0 } -}; - -static driver_t isic_driver = { - "isic", - isic_methods, - 0 -}; - -static devclass_t isic_devclass; - -DRIVER_MODULE(isic, isa, isic_driver, isic_devclass, 0, 0); - -/*---------------------------------------------------------------------------* - * probe for ISA non-PnP cards - *---------------------------------------------------------------------------*/ -static int -isic_isa_probe(device_t dev) -{ - int ret = ENXIO; - - if(isa_get_vendorid(dev)) /* no PnP probes here */ - return ENXIO; - - switch(device_get_flags(dev)) - { -#ifdef TEL_S0_16 - case FLAG_TELES_S0_16: - ret = isic_probe_s016(dev); - break; -#endif - -#ifdef TEL_S0_8 - case FLAG_TELES_S0_8: - ret = isic_probe_s08(dev); - break; -#endif - -#ifdef ELSA_PCC16 - case FLAG_ELSA_PCC16: - ret = isic_probe_Epcc16(dev); - break; -#endif - -#ifdef TEL_S0_16_3 - case FLAG_TELES_S0_163: - ret = isic_probe_s0163(dev); - break; -#endif - -#ifdef AVM_A1 - case FLAG_AVM_A1: - ret = isic_probe_avma1(dev); - break; -#endif - -#ifdef USR_STI - case FLAG_USR_ISDN_TA_INT: - ret = isic_probe_usrtai(dev); - break; -#endif - -#ifdef ITKIX1 - case FLAG_ITK_IX1: - ret = isic_probe_itkix1(dev); - break; -#endif - - default: - printf("isic%d: probe, unknown flag: %d\n", - device_get_unit(dev), device_get_flags(dev)); - break; - } - return(ret); -} - -/*---------------------------------------------------------------------------* - * attach for ISA non-PnP cards - *---------------------------------------------------------------------------*/ -static int -isic_isa_attach(device_t dev) -{ - int ret = ENXIO; - - struct l1_softc *sc = &l1_sc[device_get_unit(dev)]; - - sc->sc_unit = device_get_unit(dev); - - /* card dependent setup */ - - switch(sc->sc_flags) - { -#ifdef TEL_S0_16 - case FLAG_TELES_S0_16: - ret = isic_attach_s016(dev); - break; -#endif - -#ifdef TEL_S0_8 - case FLAG_TELES_S0_8: - ret = isic_attach_s08(dev); - break; -#endif - -#ifdef ELSA_PCC16 - case FLAG_ELSA_PCC16: - ret = isic_attach_Epcc16(dev); - break; -#endif - -#ifdef TEL_S0_16_3 - case FLAG_TELES_S0_163: - ret = isic_attach_s0163(dev); - break; -#endif - -#ifdef AVM_A1 - case FLAG_AVM_A1: - ret = isic_attach_avma1(dev); - break; -#endif - -#ifdef USR_STI - case FLAG_USR_ISDN_TA_INT: - ret = isic_attach_usrtai(dev); - break; -#endif - -#ifdef ITKIX1 - case FLAG_ITK_IX1: - ret = isic_attach_itkix1(dev); - break; -#endif - - default: - printf("isic%d: attach, unknown flag: %d\n", - device_get_unit(dev), device_get_flags(dev)); - break; - } - - if(ret) - return(ret); - - ret = isic_attach_common(dev); - - return(ret); -} -#endif /* NISIC > 0 */ 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 -#include -#include -#include - -#if defined(__FreeBSD__) && __FreeBSD__ >= 3 -#include -#else -#include -#endif - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -#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_isic_pnp.c b/sys/i4b/layer1/i4b_isic_pnp.c deleted file mode 100644 index 70d0812..0000000 --- a/sys/i4b/layer1/i4b_isic_pnp.c +++ /dev/null @@ -1,317 +0,0 @@ -/* - * Copyright (c) 1998 Eivind Eklund. All rights reserved. - * - * Copyright (c) 1998, 1999 German Tischler. 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_pnp.c - i4b pnp support - * -------------------------------- - * - * $Id: i4b_isic_pnp.c,v 1.5 1999/12/13 21:25:26 hm Exp $ - * - * $FreeBSD$ - * - * last edit-date: [Mon Dec 13 22:01:48 1999] - * - *---------------------------------------------------------------------------*/ - -#include "isic.h" -#include "opt_i4b.h" - -#if (NISIC > 0) - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include - -#define VID_TEL163PNP 0x10212750 /* Teles 16.3 PnP */ -#define VID_CREATIXPP 0x0000980e /* Creatix S0/16 P+P */ -#define VID_DYNALINK 0x88167506 /* Dynalink */ -#define VID_SEDLBAUER 0x0100274c /* Sedlbauer WinSpeed */ -#define VID_NICCYGO 0x5001814c /* Neuhaus Niccy GO@ */ -#define VID_ELSAQS1P 0x33019315 /* ELSA Quickstep1000pro*/ -#define VID_ITK0025 0x25008b26 /* ITK Ix1 Micro V3 */ -#define VID_AVMPNP 0x0009cd06 /* AVM Fritz! PnP */ -#define VID_SIESURF2 0x2000254d /* Siemens I-Surf 2.0 PnP*/ -#define VID_ASUSCOM_IPAC 0x90167506 /* Asuscom (with IPAC) */ - -static struct isic_pnp_ids { - u_long vend_id; - char *id_str; -} isic_pnp_ids[] = { -#if defined(TEL_S0_16_3_P) || defined(CRTX_S0_P) - { VID_TEL163PNP, "Teles S0/16.3 PnP" }, - { VID_CREATIXPP, "Creatix S0/16 PnP" }, -#endif -#ifdef DYNALINK - { VID_DYNALINK, "Dynalink IS64PH" }, -#endif -#ifdef SEDLBAUER - { VID_SEDLBAUER, "Sedlbauer WinSpeed" }, -#endif -#ifdef DRN_NGO - { VID_NICCYGO, "Dr.Neuhaus Niccy Go@" }, -#endif -#ifdef ELSA_QS1ISA - { VID_ELSAQS1P, "ELSA QuickStep 1000pro" }, -#endif -#ifdef ITKIX1 - { VID_ITK0025, "ITK ix1 Micro V3.0" }, -#endif -#ifdef AVM_PNP - { VID_AVMPNP, "AVM Fritz!Card PnP" }, -#endif -#ifdef SIEMENS_ISURF2 - { VID_SIESURF2, "Siemens I-Surf 2.0 PnP" }, -#endif -#ifdef ASUSCOM_IPAC - { VID_ASUSCOM_IPAC, "Asuscom ISDNLink 128 PnP" }, -#endif - { 0, 0 } -}; - -static int isic_pnp_probe(device_t dev); -static int isic_pnp_attach(device_t dev); - -static device_method_t isic_pnp_methods[] = { - DEVMETHOD(device_probe, isic_pnp_probe), - DEVMETHOD(device_attach, isic_pnp_attach), - { 0, 0 } -}; - -static driver_t isic_pnp_driver = { - "isic", - isic_pnp_methods, - 0, -}; - -static devclass_t isic_devclass; - -DRIVER_MODULE(isicpnp, isa, isic_pnp_driver, isic_devclass, 0, 0); - -/*---------------------------------------------------------------------------* - * probe for ISA PnP cards - *---------------------------------------------------------------------------*/ -int -isic_pnp_probe(device_t dev) -{ - struct isic_pnp_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 */ - - for(ids = isic_pnp_ids; ids->vend_id != 0; ids++) - { - if(vend_id == ids->vend_id) - { - string = ids->id_str; - break; - } - } - - if(string) /* set name if we have one */ - { - device_set_desc(dev, string); /* set description */ - return 0; - } - else - { - return ENXIO; - } -} - -/*---------------------------------------------------------------------------* - * attach for ISA PnP cards - *---------------------------------------------------------------------------*/ -int -isic_pnp_attach(device_t dev) -{ - u_int32_t vend_id = isa_get_vendorid(dev); /* vendor id */ - unsigned int unit = device_get_unit(dev); /* get unit */ - const char *name = device_get_desc(dev); /* get description */ - struct l1_softc *sc = 0; /* softc */ - void *ih = 0; /* a dummy */ - int ret; - - /* see if we are out of bounds */ - - if(unit >= ISIC_MAXUNIT) - { - printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for %s\n", unit, unit, name); - return ENXIO; - } - - /* get information structure for this unit */ - - sc = &l1_sc[unit]; - - /* 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_pnp_attach: Couldn't get my io_base.\n"); - return ENXIO; - } - - /* will not be used for pnp devices */ - - sc->sc_port = rman_get_start(sc->sc_resources.io_base[0]); - - /* 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: Could not get irq.\n",unit); - isic_detach_common(dev); - return ENXIO; - } - - /* not needed */ - sc->sc_irq = rman_get_start(sc->sc_resources.irq); - - - /* set flag so we know what this card is */ - - ret = ENXIO; - - switch(vend_id) - { -#if defined(TEL_S0_16_3_P) || defined(CRTX_S0_P) - case VID_TEL163PNP: - sc->sc_flags = FLAG_TELES_S0_163_PnP; - ret = isic_attach_Cs0P(dev); - break; - - case VID_CREATIXPP: - sc->sc_flags = FLAG_CREATIX_S0_PnP; - ret = isic_attach_Cs0P(dev); - break; -#endif -#ifdef DYNALINK - case VID_DYNALINK: - sc->sc_flags = FLAG_DYNALINK; - ret = isic_attach_Dyn(dev); - break; -#endif -#ifdef SEDLBAUER - case VID_SEDLBAUER: - sc->sc_flags = FLAG_SWS; - ret = isic_attach_sws(dev); - break; -#endif -#ifdef DRN_NGO - case VID_NICCYGO: - sc->sc_flags = FLAG_DRN_NGO; - ret = isic_attach_drnngo(dev); - break; -#endif -#ifdef ELSA_QS1ISA - case VID_ELSAQS1P: - sc->sc_flags = FLAG_ELSA_QS1P_ISA; - ret = isic_attach_Eqs1pi(dev); - break; -#endif -#ifdef ITKIX1 - case VID_ITK0025: - sc->sc_flags = FLAG_ITK_IX1; - ret = isic_attach_itkix1(dev); - break; -#endif -#ifdef AVM_PNP - case VID_AVMPNP: - sc->sc_flags = FLAG_AVM_PNP; - ret = isic_attach_avm_pnp(dev); - break; -#endif -#ifdef SIEMENS_ISURF2 - case VID_SIESURF2: - sc->sc_flags = FLAG_SIEMENS_ISURF2; - ret = isic_attach_siemens_isurf(dev); - break; -#endif -#ifdef ASUSCOM_IPAC - case VID_ASUSCOM_IPAC: - sc->sc_flags = FLAG_ASUSCOM_IPAC; - ret = isic_attach_asi(dev); - break; -#endif - default: - printf("isic%d: Error, no driver for %s\n", unit, name); - ret = ENXIO; - break; - } - - if(ret) - { - isic_detach_common(dev); - return ENXIO; - } - - if(isic_attach_common(dev)) - { - /* unset flag */ - sc->sc_flags = 0; - - /* free irq here, it hasn't been attached yet */ - bus_release_resource(dev,SYS_RES_IRQ,sc->sc_resources.irq_rid, - sc->sc_resources.irq); - sc->sc_resources.irq = 0; - isic_detach_common(dev); - return ENXIO; - } - else - { - /* setup intr routine */ - bus_setup_intr(dev,sc->sc_resources.irq,INTR_TYPE_NET, - (void(*)(void*))isicintr, - sc,&ih); - return 0; - } -} -#endif /* (NISIC > 0) */ diff --git a/sys/i4b/layer1/i4b_itk_ix1.c b/sys/i4b/layer1/i4b_itk_ix1.c deleted file mode 100644 index 9ec4cf3..0000000 --- a/sys/i4b/layer1/i4b_itk_ix1.c +++ /dev/null @@ -1,482 +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. The name of the author may not be used to endorse or promote products - * derived from this software withough specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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_itk_ix1.c - ITK ix1 micro passive card driver for isdn4bsd - * -------------------------------------------------------------- - * - * $FreeBSD$ - * - * last edit-date: [Sun Feb 14 10:28:00 1999] - * - * mh - created - * mh - fixed FreeBSD problems reported by Kevin Sheehan - * mh - added probe routine - * - *--------------------------------------------------------------------------- - * - * The ITK ix1 micro ISDN card is an ISA card with one region - * of four io ports mapped and a fixed irq all jumpered on the card. - * Access to the board is straight forward and simmilar to - * the ELSA and DYNALINK cards. If a PCI version of this card - * exists all we need is probably a pci-bus attachment, all - * this low level routines should work imediately. - * - * To reset the card: - * - write 0x01 to ITK_CONFIG - * - wait >= 10 ms - * - write 0x00 to ITK_CONFIG - * - * To read or write data: - * - write address to ITK_ALE port - * - read data from or write data to ITK_ISAC_DATA port or ITK_HSCX_DATA port - * The two HSCX channel registers are offset by HSCXA (0x00) and HSCXB (0x40). - * - * The probe routine was derived by trial and error from a representative - * sample of two cards ;-) The standard way (checking HSCX versions) - * was extended by reading a zero from a non existant HSCX register (register - * 0xff). Reading the config register gives varying results, so this doesn't - * seem to be used as an id register (like the Teles S0/16.3). - * - * If the probe fails for your card use "options ITK_PROBE_DEBUG" to get - * additional debug output. - * - *---------------------------------------------------------------------------*/ - -#if defined(__FreeBSD__) -#include "isic.h" -#include "opt_i4b.h" -#else -#define NISIC 1 -#endif -#if NISIC > 0 && defined(ITKIX1) - -#include -#if defined(__FreeBSD__) && __FreeBSD__ >= 3 -#include -#else -#include -#endif -#include -#include -#include - -#ifdef __FreeBSD__ -#include -#include -#else -#include -#include -#endif - -#include -#include - -#ifdef __FreeBSD__ -#include -#include -#else -#include -#include -#endif - -#include -#include -#include - -#include - -/* Register offsets */ -#define ITK_ISAC_DATA 0 -#define ITK_HSCX_DATA 1 -#define ITK_ALE 2 -#define ITK_CONFIG 3 - -/* Size of IO range to allocate for this card */ -#define ITK_IO_SIZE 4 - -/* Register offsets for the two HSCX channels */ -#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 - -/* - * Probe for card - */ -#ifdef __FreeBSD__ -int -isic_probe_itkix1(struct isa_device *dev) -{ - 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); - - /* 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); - - /* 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); - - /* retstore save value if we fail (if we succeed the old value - * has no meaning) */ - if (!ret) - outb(dev->id_iobase + ITK_ALE, saveale); - -#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; - - /* save old value of this port, we're stomping over it */ - saveale = bus_space_read_1(t, h, ITK_ALE); - - /* select invalid register */ - bus_space_write_1(t, h, ITK_ALE, 0xff); - /* get HSCX data for this non existent register */ - hd = bus_space_read_1(t, h, ITK_HSCX_DATA); - /* get HSCX version info */ - bus_space_write_1(t, h, ITK_ALE, HSCXA + H_VSTR); - hv1 = bus_space_read_1(t, h, ITK_HSCX_DATA); - 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); - - /* 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 - 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 -} -#endif - -/* - * Attach card - */ -#ifdef __FreeBSD__ -int -isic_attach_itkix1(struct isa_device *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; - - /* 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; - - /* 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); - DELAY(SEC_DELAY / 10); - outb((dev->id_iobase)+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/i4b_l1.c deleted file mode 100644 index 617f58c..0000000 --- a/sys/i4b/layer1/i4b_l1.c +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - *--------------------------------------------------------------------------- - * - * i4b_l1.c - isdn4bsd layer 1 handler - * ----------------------------------- - * - * $Id: i4b_l1.c,v 1.2 1999/12/13 21:25:26 hm Exp $ - * - * $FreeBSD$ - * - * last edit-date: [Mon Dec 13 22:01:55 1999] - * - *---------------------------------------------------------------------------*/ - -#include "isic.h" - -#if NISIC > 0 - -#include -#include -#include -#include - -#include -#include - -#include - -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -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 - * ========================= - * - * 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 - * - *---------------------------------------------------------------------------*/ -static int -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)); -#endif - - if(m == NULL) /* failsafe */ - return (0); - - s = SPLI4B(); - - 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); - } - - 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 */ - - DBGL1(L1_I_MSG, "ph_data_req", ("using 2nd ISAC TX buffer, state = %s\n", isic_printstate(sc))); - - if(sc->sc_trace & TRACE_D_TX) - { - i4b_trace_hdr_t hdr; - hdr.unit = 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); - } - splx(s); - return(1); - } - - DBGL1(L1_I_ERR, "ph_data_req", ("No Space in TX FIFO, state = %s\n", isic_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 = 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); - } - - sc->sc_state |= ISAC_TX_ACTIVE; /* set transmitter busy flag */ - - DBGL1(L1_I_MSG, "ph_data_req", ("ISAC_TX_ACTIVE set\n")); - - 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 - * - *---------------------------------------------------------------------------*/ -static int -ph_activate_req(int unit) -{ - struct l1_softc *sc = &l1_sc[unit]; - DBGL1(L1_PRIM, "PH-ACTIVATE-REQ", ("unit %d\n", unit)); - isic_next_state(sc, EV_PHAR); - return(0); -} - -/*---------------------------------------------------------------------------* - * command from the upper layers - *---------------------------------------------------------------------------*/ -static int -i4b_mph_command_req(int unit, int command, int 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)); - sc->sc_enabled = 1; - break; - - case CMR_DCLOSE: /* daemon not running */ - DBGL1(L1_PRIM, "MPH-COMMAND-REQ", ("unit %d, command = CMR_DCLOSE\n", unit)); - sc->sc_enabled = 0; - break; - - default: - DBGL1(L1_ERROR, "i4b_mph_command_req", ("ERROR, unknown command = %d, unit = %d, parm = %d\n", command, unit, parm)); - break; - } - - return(0); -} - -#endif /* NISIC > 0 */ diff --git a/sys/i4b/layer1/i4b_l1.h b/sys/i4b/layer1/i4b_l1.h deleted file mode 100644 index 8ee9868..0000000 --- a/sys/i4b/layer1/i4b_l1.h +++ /dev/null @@ -1,347 +0,0 @@ -/* - * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - *---------------------------------------------------------------------------* - * - * i4b_l1.h - isdn4bsd layer 1 header file - * --------------------------------------- - * - * $Id: i4b_l1.h,v 1.3 1999/12/13 21:25:26 hm Exp $ - * - * $FreeBSD$ - * - * last edit-date: [Mon Dec 13 22:02:07 1999] - * - *---------------------------------------------------------------------------*/ - -#ifndef I4B_L1_H_ -#define I4B_L1_H_ - -#include -#include -#include -#include -#include - -#include - -/*--------------------------------------------------------------------------- - * kernel config file flags definition - *---------------------------------------------------------------------------*/ -#define FLAG_TELES_S0_8 1 -#define FLAG_TELES_S0_16 2 -#define FLAG_TELES_S0_163 3 -#define FLAG_AVM_A1 4 -#define FLAG_TELES_S0_163_PnP 5 -#define FLAG_CREATIX_S0_PnP 6 -#define FLAG_USR_ISDN_TA_INT 7 -#define FLAG_DRN_NGO 8 -#define FLAG_SWS 9 -#define FLAG_AVM_A1_PCMCIA 10 -#define FLAG_DYNALINK 11 -#define FLAG_BLMASTER 12 -#define FLAG_ELSA_QS1P_ISA 13 -#define FLAG_ELSA_QS1P_PCI 14 -#define FLAG_SIEMENS_ITALK 15 -#define FLAG_ELSA_MLIMC 16 -#define FLAG_ELSA_MLMCALL 17 -#define FLAG_ITK_IX1 18 -#define FLAG_AVMA1PCI 19 -#define FLAG_ELSA_PCC16 20 -#define FLAG_AVM_PNP 21 -#define FLAG_SIEMENS_ISURF2 22 -#define FLAG_ASUSCOM_IPAC 23 - -#define SEC_DELAY 1000000 /* one second DELAY for DELAY*/ - -#define MAX_DFRAME_LEN 264 /* max length of a D frame */ - -#define min(a,b) ((a)<(b)?(a):(b)) - -#define INFO_IO_BASES 50 /* 49 needed for USR */ - -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; -}; - -/*---------------------------------------------------------------------------* - * l1_bchan_state: the state of one B channel - *---------------------------------------------------------------------------*/ -typedef struct -{ - int unit; /* cards unit number */ - int channel; /* which channel is this*/ - caddr_t hscx; /* HSCX address */ - u_char hscx_mask; /* HSCX interrupt mask */ - int bprot; /* B channel protocol */ - int state; /* this channels state */ -#define HSCX_IDLE 0x00 /* channel idle */ -#define HSCX_TX_ACTIVE 0x01 /* tx running */ - - /* 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 */ - - /* link between b channel and driver */ - - isdn_link_t isdn_linktab; /* b channel addresses */ - drvr_link_t *drvr_linktab; /* ptr to driver linktab*/ - - /* statistics */ - - /* RSTA */ - - int stat_VFR; /* HSCX RSTA Valid FRame */ - int stat_RDO; /* HSCX RSTA Rx Data Overflow */ - int stat_CRC; /* HSCX RSTA CRC */ - int stat_RAB; /* HSCX RSTA Rx message ABorted */ - - /* EXIR */ - - int stat_XDU; /* HSCX EXIR tx data underrun */ - int stat_RFO; /* HSCX EXIR rx frame overflow */ - -} l1_bchan_state_t; - -/*---------------------------------------------------------------------------* - * l1_softc: the state of the layer 1 of the D channel - *---------------------------------------------------------------------------*/ -struct l1_softc -{ - int sc_unit; /* unit number */ - int sc_irq; /* interrupt vector */ - struct i4b_info sc_resources; - int sc_flags; - - int sc_port; /* port base address */ - - int sc_cardtyp; /* CARD_TYPEP_xxxx */ - - int sc_bustyp; /* IOM1 or IOM2 */ -#define BUS_TYPE_IOM1 0x01 -#define BUS_TYPE_IOM2 0x02 - - int sc_trace; /* output protocol data for tracing */ - unsigned int sc_trace_dcount;/* d channel trace frame counter */ - unsigned int sc_trace_bcount;/* b channel trace frame counter */ - - int sc_state; /* ISAC state flag */ -#define ISAC_IDLE 0x00 /* state = idle */ -#define ISAC_TX_ACTIVE 0x01 /* state = transmitter active */ - - int sc_init_tries; /* no of out tries to access S0 */ - - caddr_t sc_vmem_addr; /* card RAM virtual memory base */ - caddr_t sc_isac; /* ISAC port base addr */ -#define ISAC_BASE (sc->sc_isac) - - caddr_t sc_ipacbase; /* IPAC port base addr */ -#define IPAC_BASE (sc->sc_ipacbase) - - u_char sc_isac_mask; /* ISAC IRQ mask */ -#define ISAC_IMASK (sc->sc_isac_mask) - - l1_bchan_state_t sc_chan[2]; /* B-channel state */ -#define HSCX_A_BASE (sc->sc_chan[0].hscx) -#define HSCX_A_IMASK (sc->sc_chan[0].hscx_mask) -#define HSCX_B_BASE (sc->sc_chan[1].hscx) -#define HSCX_B_IMASK (sc->sc_chan[1].hscx_mask) - - struct mbuf *sc_ibuf; /* input buffer mgmt */ - u_short sc_ilen; - u_char *sc_ib; - /* this is for the irq TX routine */ - struct mbuf *sc_obuf; /* pointer to an mbuf with TX frame */ - u_char *sc_op; /* ptr to next chunk of frame to tx */ - int sc_ol; /* length of remaining frame to tx */ - int sc_freeflag; /* m_freem mbuf if set */ - - struct mbuf *sc_obuf2; /* pointer to an mbuf with TX frame */ - int sc_freeflag2; /* m_freem mbuf if set */ - - int sc_isac_version; /* version number of ISAC */ - int sc_hscx_version; /* version number of HSCX */ - - int sc_I430state; /* I.430 state F3 .... F8 */ - - int sc_I430T3; /* I.430 Timer T3 running */ - - struct callout_handle sc_T3_callout; - - int sc_I430T4; /* Timer T4 running */ - - struct callout_handle sc_T4_callout; - - /* - * byte fields for the AVM Fritz!Card PCI. These are packed into - * a u_int in the driver. - */ - u_char avma1pp_cmd; - u_char avma1pp_txl; - u_char avma1pp_prot; - - int sc_enabled; /* daemon is running */ - - int sc_ipac; /* flag, running on ipac */ - int sc_bfifolen; /* length of b channel fifos */ - -#define ISIC_WHAT_ISAC 0 -#define ISIC_WHAT_HSCXA 1 -#define ISIC_WHAT_HSCXB 2 -#define ISIC_WHAT_IPAC 3 - - u_int8_t (*readreg) (struct l1_softc *sc, int what, bus_size_t offs); - void (*writereg) (struct l1_softc *sc, int what, bus_size_t offs, u_int8_t data); - void (*readfifo) (struct l1_softc *sc, int what, void *buf, size_t size); - void (*writefifo) (struct l1_softc *sc, int what, void *data, size_t size); - void (*clearirq) (struct l1_softc *sc); - -#define ISAC_READ(r) (*sc->readreg)(sc, ISIC_WHAT_ISAC, (r)) -#define ISAC_WRITE(r,v) (*sc->writereg)(sc, ISIC_WHAT_ISAC, (r), (v)) -#define ISAC_RDFIFO(b,s) (*sc->readfifo)(sc, ISIC_WHAT_ISAC, (b), (s)) -#define ISAC_WRFIFO(b,s) (*sc->writefifo)(sc, ISIC_WHAT_ISAC, (b), (s)) - -#define HSCX_READ(n,r) (*sc->readreg)(sc, ISIC_WHAT_HSCXA+(n), (r)) -#define HSCX_WRITE(n,r,v) (*sc->writereg)(sc, ISIC_WHAT_HSCXA+(n), (r), (v)) -#define HSCX_RDFIFO(n,b,s) (*sc->readfifo)(sc, ISIC_WHAT_HSCXA+(n), (b), (s)) -#define HSCX_WRFIFO(n,b,s) (*sc->writefifo)(sc, ISIC_WHAT_HSCXA+(n), (b), (s)) - -#define IPAC_READ(r) (*sc->readreg)(sc, ISIC_WHAT_IPAC, (r)) -#define IPAC_WRITE(r, v) (*sc->writereg)(sc, ISIC_WHAT_IPAC, (r), (v)) -}; - -/*---------------------------------------------------------------------------* - * possible I.430/ISAC states - *---------------------------------------------------------------------------*/ -enum I430states { - 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/ISAC events - *---------------------------------------------------------------------------*/ -enum I430events { - EV_PHAR, /* PH ACTIVATE REQUEST */ - 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 -}; - -enum I430commands { - CMD_TIM, /* Timing */ - CMD_RS, /* Reset */ - CMD_AR8, /* Activation request pri 8 */ - CMD_AR10, /* Activation request pri 10 */ - CMD_DIU, /* Deactivate Indication Upstream */ - CMD_ILL /* Illegal command */ -}; - -#define N_COMMANDS CMD_ILL - - -extern struct l1_softc l1_sc[]; - -extern void isicintr(struct l1_softc *sc); -extern int isic_attach_common(device_t dev); -extern void isic_detach_common(device_t dev); -extern void isic_recover(struct l1_softc *sc); - -extern void isic_bchannel_setup (int unit, int hscx_channel, int bprot, int activate ); - -extern void isic_init_linktab ( struct l1_softc *sc ); -extern int isic_isac_init ( struct l1_softc *sc ); -extern void isic_isac_irq ( struct l1_softc *sc, int r ); -extern void isic_isac_l1_cmd ( struct l1_softc *sc, int command ); -extern void isic_next_state ( struct l1_softc *sc, int event ); -extern char *isic_printstate ( struct l1_softc *sc ); - -extern int isic_hscx_fifo(l1_bchan_state_t *, struct l1_softc *); -extern void isic_hscx_init ( struct l1_softc *sc, int hscx_channel, int activate ); -extern void isic_hscx_irq ( struct l1_softc *sc, u_char ista, int hscx_channel, u_char ex_irq ); -extern int isic_hscx_silence ( unsigned char *data, int len ); -extern void isic_hscx_cmd( struct l1_softc *sc, int h_chan, unsigned char cmd ); -extern void isic_hscx_waitxfw( struct l1_softc *sc, int h_chan ); - -extern int isic_probe_s016 (device_t dev); -extern int isic_attach_s016 (device_t dev); - -extern int isic_probe_s08 (device_t dev); -extern int isic_attach_s08 (device_t dev); - -extern int isic_probe_Epcc16 (device_t dev); -extern int isic_attach_Epcc16 (device_t dev); - -extern int isic_probe_s0163 (device_t dev); -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_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); - - -#endif /* I4B_L1_H_ */ 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 +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include + +#include +#include +#include + +/* + * 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_l1fsm.c b/sys/i4b/layer1/i4b_l1fsm.c deleted file mode 100644 index 2370ad4..0000000 --- a/sys/i4b/layer1/i4b_l1fsm.c +++ /dev/null @@ -1,514 +0,0 @@ -/* - * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - *--------------------------------------------------------------------------- - * - * 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 $ - * - * $FreeBSD$ - * - * last edit-date: [Mon Dec 13 22:02:16 1999] - * - *---------------------------------------------------------------------------*/ - -#include "isic.h" - -#if NISIC > 0 - -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include -#include - -#include -#include -#include - -#include -#include -#include - - -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" -}; - -/* 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) - { - DBGL1(L1_T_ERR, "timer3_expired", ("state = %s\n", isic_printstate(sc))); - sc->sc_I430T3 = 0; - - /* XXX try some recovery here XXX */ - - isic_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); - - MPH_Status_Ind(sc->sc_unit, STI_NOL1ACC, 0); - } - - isic_next_state(sc, EV_T3); - } - else - { - DBGL1(L1_T_ERR, "timer3_expired", ("expired without starting it ....\n")); - } -} - -/*---------------------------------------------------------------------------* - * I.430 Timer T3 start - *---------------------------------------------------------------------------*/ -static void -T3_start(struct l1_softc *sc) -{ - DBGL1(L1_T_MSG, "T3_start", ("state = %s\n", isic_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) -{ - DBGL1(L1_T_MSG, "T3_stop", ("state = %s\n", isic_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) -{ - DBGL1(L1_F_MSG, "F_T3ex", ("FSM function F_T3ex executing\n")); - if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S) - PH_Deact_Ind(sc->sc_unit); -} - -/*---------------------------------------------------------------------------* - * Timer T4 expire function - *---------------------------------------------------------------------------*/ -static void -timer4_expired(struct l1_softc *sc) -{ - if(sc->sc_I430T4) - { - DBGL1(L1_T_MSG, "timer4_expired", ("state = %s\n", isic_printstate(sc))); - sc->sc_I430T4 = 0; - MPH_Status_Ind(sc->sc_unit, STI_PDEACT, 0); - } - else - { - DBGL1(L1_T_ERR, "timer4_expired", ("expired without starting it ....\n")); - } -} - -/*---------------------------------------------------------------------------* - * Timer T4 start - *---------------------------------------------------------------------------*/ -static void -T4_start(struct l1_softc *sc) -{ - DBGL1(L1_T_MSG, "T4_start", ("state = %s\n", isic_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) -{ - DBGL1(L1_T_MSG, "T4_stop", ("state = %s\n", isic_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); - - DBGL1(L1_F_MSG, "F_AI8", ("FSM function F_AI8 executing\n")); - - if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S) - PH_Act_Ind(sc->sc_unit); - - T3_stop(sc); - - if(sc->sc_trace & TRACE_I) - { - i4b_trace_hdr_t hdr; - char info = INFO4_8; - - hdr.unit = sc->sc_unit; - hdr.type = TRC_CH_I; - hdr.dir = FROM_NT; - hdr.count = 0; - MICROTIME(hdr.time); - MPH_Trace_Ind(&hdr, 1, &info); - } -} - -/*---------------------------------------------------------------------------* - * FSM function: received AI10 - *---------------------------------------------------------------------------*/ -static void -F_AI10(struct l1_softc *sc) -{ - T4_stop(sc); - - DBGL1(L1_F_MSG, "F_AI10", ("FSM function F_AI10 executing\n")); - - if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S) - PH_Act_Ind(sc->sc_unit); - - T3_stop(sc); - - if(sc->sc_trace & TRACE_I) - { - i4b_trace_hdr_t hdr; - char info = INFO4_10; - - hdr.unit = sc->sc_unit; - hdr.type = TRC_CH_I; - hdr.dir = FROM_NT; - hdr.count = 0; - MICROTIME(hdr.time); - MPH_Trace_Ind(&hdr, 1, &info); - } -} - -/*---------------------------------------------------------------------------* - * FSM function: received INFO 0 in states F3 .. F5 - *---------------------------------------------------------------------------*/ -static void -F_I01(struct l1_softc *sc) -{ - DBGL1(L1_F_MSG, "F_I01", ("FSM function F_I01 executing\n")); - - if(sc->sc_trace & TRACE_I) - { - i4b_trace_hdr_t hdr; - char info = INFO0; - - hdr.unit = sc->sc_unit; - hdr.type = TRC_CH_I; - hdr.dir = FROM_NT; - hdr.count = 0; - MICROTIME(hdr.time); - MPH_Trace_Ind(&hdr, 1, &info); - } -} - -/*---------------------------------------------------------------------------* - * FSM function: received INFO 0 in state F6 - *---------------------------------------------------------------------------*/ -static void -F_I02(struct l1_softc *sc) -{ - DBGL1(L1_F_MSG, "F_I02", ("FSM function F_I02 executing\n")); - - if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S) - PH_Deact_Ind(sc->sc_unit); - - if(sc->sc_trace & TRACE_I) - { - i4b_trace_hdr_t hdr; - char info = INFO0; - - hdr.unit = sc->sc_unit; - hdr.type = TRC_CH_I; - hdr.dir = FROM_NT; - hdr.count = 0; - MICROTIME(hdr.time); - MPH_Trace_Ind(&hdr, 1, &info); - } -} - -/*---------------------------------------------------------------------------* - * FSM function: received INFO 0 in state F7 or F8 - *---------------------------------------------------------------------------*/ -static void -F_I03(struct l1_softc *sc) -{ - DBGL1(L1_F_MSG, "F_I03", ("FSM function F_I03 executing\n")); - - if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S) - PH_Deact_Ind(sc->sc_unit); - - T4_start(sc); - - if(sc->sc_trace & TRACE_I) - { - i4b_trace_hdr_t hdr; - char info = INFO0; - - hdr.unit = sc->sc_unit; - hdr.type = TRC_CH_I; - hdr.dir = FROM_NT; - hdr.count = 0; - MICROTIME(hdr.time); - MPH_Trace_Ind(&hdr, 1, &info); - } -} - -/*---------------------------------------------------------------------------* - * FSM function: activate request - *---------------------------------------------------------------------------*/ -static void -F_AR(struct l1_softc *sc) -{ - DBGL1(L1_F_MSG, "F_AR", ("FSM function F_AR executing\n")); - - if(sc->sc_trace & TRACE_I) - { - i4b_trace_hdr_t hdr; - char info = INFO1_8; - - hdr.unit = sc->sc_unit; - hdr.type = TRC_CH_I; - hdr.dir = FROM_TE; - hdr.count = 0; - MICROTIME(hdr.time); - MPH_Trace_Ind(&hdr, 1, &info); - } - - isic_isac_l1_cmd(sc, CMD_AR8); - - T3_start(sc); -} - -/*---------------------------------------------------------------------------* - * FSM function: received INFO2 - *---------------------------------------------------------------------------*/ -static void -F_I2(struct l1_softc *sc) -{ - DBGL1(L1_F_MSG, "F_I2", ("FSM function F_I2 executing\n")); - - if(sc->sc_trace & TRACE_I) - { - i4b_trace_hdr_t hdr; - char info = INFO2; - - hdr.unit = sc->sc_unit; - hdr.type = TRC_CH_I; - hdr.dir = FROM_NT; - hdr.count = 0; - MICROTIME(hdr.time); - MPH_Trace_Ind(&hdr, 1, &info); - } - -} - -/*---------------------------------------------------------------------------* - * illegal state default action - *---------------------------------------------------------------------------*/ -static void -F_ill(struct l1_softc *sc) -{ - DBGL1(L1_F_ERR, "F_ill", ("FSM function F_ill executing\n")); -} - -/*---------------------------------------------------------------------------* - * No action - *---------------------------------------------------------------------------*/ -static void -F_NULL(struct l1_softc *sc) -{ - DBGL1(L1_F_MSG, "F_NULL", ("FSM function F_NULL executing\n")); -} - - -/*---------------------------------------------------------------------------* - * layer 1 state transition table - *---------------------------------------------------------------------------*/ -struct isic_state_tab { - void (*func) (struct l1_softc *sc); /* function to execute */ - int newstate; /* next state */ -} isic_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 -isic_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 = isic_state_tab[event][currstate].newstate; - - 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], - state_text[currstate], - 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", - state_text[currstate], - state_text[newstate], - event_text[event])); - } - - sc->sc_I430state = newstate; -} - -/*---------------------------------------------------------------------------* - * return pointer to current state description - *---------------------------------------------------------------------------*/ -char * -isic_printstate(struct l1_softc *sc) -{ - return((char *) state_text[sc->sc_I430state]); -} - -#endif /* NISIC > 0 */ - 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 +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include + +#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/i4b_siemens_isurf.c b/sys/i4b/layer1/i4b_siemens_isurf.c deleted file mode 100644 index 384e118..0000000 --- a/sys/i4b/layer1/i4b_siemens_isurf.c +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Copyright (c) 1999 Udo Schweigert. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * 4. Altered versions must be plainly marked as such, and must not be - * misrepresented as being the original software and/or documentation. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - *--------------------------------------------------------------------------- - * Based on ELSA Quickstep 1000pro PCI driver (i4b_elsa_qs1p.c) - *--------------------------------------------------------------------------- - * In case of trouble please contact Udo Schweigert - *--------------------------------------------------------------------------- - * - * 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 $ - * - * $FreeBSD$ - * - * last edit-date: [Mon Dec 13 22:02:28 1999] - * - *---------------------------------------------------------------------------*/ - -#include "isic.h" -#include "opt_i4b.h" - -#if NISIC > 0 && defined(SIEMENS_ISURF2) - -#include -#include -#include -#include - -#include - -#include - -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -/* masks for register encoded in base addr */ - -#define SIE_ISURF_BASE_MASK 0x0ffff -#define SIE_ISURF_OFF_MASK 0xf0000 - -/* register id's to be encoded in base addr */ - -#define SIE_ISURF_IDISAC 0x00000 -#define SIE_ISURF_IDHSCXA 0x10000 -#define SIE_ISURF_IDHSCXB 0x20000 -#define SIE_ISURF_IDIPAC 0x40000 - -/* offsets from base address */ - -#define SIE_ISURF_OFF_ALE 0x00 -#define SIE_ISURF_OFF_RW 0x01 - -/*---------------------------------------------------------------------------* - * Siemens I-Surf 2.0 PnP ISAC get fifo routine - *---------------------------------------------------------------------------*/ -static void -siemens_isurf_read_fifo(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,SIE_ISURF_OFF_ALE,IPAC_ISAC_OFF); - bus_space_read_multi_1(t,h,SIE_ISURF_OFF_RW,buf,size); - break; - case ISIC_WHAT_HSCXA: - bus_space_write_1(t,h,SIE_ISURF_OFF_ALE,IPAC_HSCXA_OFF); - bus_space_read_multi_1(t,h,SIE_ISURF_OFF_RW,buf,size); - break; - case ISIC_WHAT_HSCXB: - bus_space_write_1(t,h,SIE_ISURF_OFF_ALE,IPAC_HSCXB_OFF); - bus_space_read_multi_1(t,h,SIE_ISURF_OFF_RW,buf,size); - break; - } -} - -/*---------------------------------------------------------------------------* - * Siemens I-Surf 2.0 PnP ISAC put fifo routine - *---------------------------------------------------------------------------*/ -static void -siemens_isurf_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,SIE_ISURF_OFF_ALE,IPAC_ISAC_OFF); - bus_space_write_multi_1(t,h,SIE_ISURF_OFF_RW,buf,size); - break; - case ISIC_WHAT_HSCXA: - bus_space_write_1(t,h,SIE_ISURF_OFF_ALE,IPAC_HSCXA_OFF); - bus_space_write_multi_1(t,h,SIE_ISURF_OFF_RW,buf,size); - break; - case ISIC_WHAT_HSCXB: - bus_space_write_1(t,h,SIE_ISURF_OFF_ALE,IPAC_HSCXB_OFF); - bus_space_write_multi_1(t,h,SIE_ISURF_OFF_RW,buf,size); - break; - } -} - -/*---------------------------------------------------------------------------* - * Siemens I-Surf 2.0 PnP ISAC put register routine - *---------------------------------------------------------------------------*/ -static void -siemens_isurf_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,SIE_ISURF_OFF_ALE,reg+IPAC_ISAC_OFF); - bus_space_write_1(t,h,SIE_ISURF_OFF_RW,data); - break; - case ISIC_WHAT_HSCXA: - bus_space_write_1(t,h,SIE_ISURF_OFF_ALE,reg+IPAC_HSCXA_OFF); - bus_space_write_1(t,h,SIE_ISURF_OFF_RW,data); - break; - case ISIC_WHAT_HSCXB: - bus_space_write_1(t,h,SIE_ISURF_OFF_ALE,reg+IPAC_HSCXB_OFF); - bus_space_write_1(t,h,SIE_ISURF_OFF_RW,data); - break; - case ISIC_WHAT_IPAC: - bus_space_write_1(t,h,SIE_ISURF_OFF_ALE,reg+IPAC_IPAC_OFF); - bus_space_write_1(t,h,SIE_ISURF_OFF_RW,data); - break; - } -} - -/*---------------------------------------------------------------------------* - * Siemens I-Surf 2.0 PnP ISAC get register routine - *---------------------------------------------------------------------------*/ -static u_int8_t -siemens_isurf_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,SIE_ISURF_OFF_ALE,reg+IPAC_ISAC_OFF); - return bus_space_read_1(t,h,SIE_ISURF_OFF_RW); - case ISIC_WHAT_HSCXA: - bus_space_write_1(t,h,SIE_ISURF_OFF_ALE,reg+IPAC_HSCXA_OFF); - return bus_space_read_1(t,h,SIE_ISURF_OFF_RW); - case ISIC_WHAT_HSCXB: - bus_space_write_1(t,h,SIE_ISURF_OFF_ALE,reg+IPAC_HSCXB_OFF); - return bus_space_read_1(t,h,SIE_ISURF_OFF_RW); - case ISIC_WHAT_IPAC: - bus_space_write_1(t,h,SIE_ISURF_OFF_ALE,reg+IPAC_IPAC_OFF); - return bus_space_read_1(t,h,SIE_ISURF_OFF_RW); - default: - return 0; - } -} - -/*---------------------------------------------------------------------------* - * isic_attach_siemens_isurf - attach for Siemens I-Surf 2.0 PnP - *---------------------------------------------------------------------------*/ -int -isic_attach_siemens_isurf(device_t dev) -{ - int unit = device_get_unit(dev); - struct l1_softc *sc = &l1_sc[unit]; - - /* setup access routines */ - - sc->clearirq = NULL; - sc->readreg = siemens_isurf_read_reg; - sc->writereg = siemens_isurf_write_reg; - - sc->readfifo = siemens_isurf_read_fifo; - sc->writefifo = siemens_isurf_write_fifo; - - /* setup card type */ - - sc->sc_cardtyp = CARD_TYPEP_SIE_ISURF2; - - /* setup IOM bus type */ - - sc->sc_bustyp = BUS_TYPE_IOM2; - - /* setup chip type = IPAC ! */ - - sc->sc_ipac = 1; - sc->sc_bfifolen = IPAC_BFIFO_LEN; - - /* enable hscx/isac irq's */ - - IPAC_WRITE(IPAC_MASK, (IPAC_MASK_INT1 | IPAC_MASK_INT0)); - - IPAC_WRITE(IPAC_ACFG, 0); /* outputs are open drain */ - IPAC_WRITE(IPAC_AOE, /* aux 5..2 are inputs, 7, 6 outputs */ - (IPAC_AOE_OE5 | IPAC_AOE_OE4 | IPAC_AOE_OE3 | IPAC_AOE_OE2)); - IPAC_WRITE(IPAC_ATX, 0xff); /* set all output lines high */ - - return(0); -} -#endif /* NISIC > 0 && defined(SIEMENS_ISURF2) */ diff --git a/sys/i4b/layer1/i4b_sws.c b/sys/i4b/layer1/i4b_sws.c deleted file mode 100644 index 9bc2015..0000000 --- a/sys/i4b/layer1/i4b_sws.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright (c) 1998 German Tischler. 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. - * - *--------------------------------------------------------------------------- - * - * Card format: - * - * iobase + 0 : reset on (0x03) - * iobase + 1 : reset off (0x0) - * iobase + 2 : isac read/write - * iobase + 3 : hscx read/write ( offset 0-0x3f hscx0 , - * offset 0x40-0x7f hscx1 ) - * iobase + 4 : offset for indirect adressing - * - *--------------------------------------------------------------------------- - * - * isic - I4B Siemens ISDN Chipset Driver for SWS cards - * ==================================================== - * - * $Id: i4b_sws.c,v 1.2 1999/12/13 21:25:26 hm Exp $ - * - * $FreeBSD$ - * - * last edit-date: [Mon Dec 13 22:02:39 1999] - * - *---------------------------------------------------------------------------*/ - -#include "isic.h" -#include "opt_i4b.h" - -#if defined (SEDLBAUER) && NISIC > 0 - -#define SWS_RESON 0 /* reset on */ -#define SWS_RESOFF 1 /* reset off */ -#define SWS_ISAC 2 /* ISAC */ -#define SWS_HSCX0 3 /* HSCX0 */ -#define SWS_RW 4 /* indirect access register */ -#define SWS_HSCX1 5 /* this is for fakeing that we mean hscx1, though */ - /* access is done through hscx0 */ - -#define SWS_REGS 8 /* we use an area of 8 bytes for io */ - -#include -#include -#include -#include - -#include - -#include - -#include -#include - -#include -#include -#include - -#include -#include -#include - -/*---------------------------------------------------------------------------* - * SWS P&P ISAC get fifo routine - *---------------------------------------------------------------------------*/ -static void -sws_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,SWS_RW,0x0); - bus_space_read_multi_1(t,h,SWS_ISAC,buf,size); - break; - case ISIC_WHAT_HSCXA: - bus_space_write_1(t,h,SWS_RW,0x0); - bus_space_read_multi_1(t,h,SWS_HSCX0,buf,size); - break; - case ISIC_WHAT_HSCXB: - bus_space_write_1(t,h,SWS_RW,0x0+0x40); - bus_space_read_multi_1(t,h,SWS_HSCX0,buf,size); - break; - } -} - -static void -sws_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,SWS_RW,0x0); - bus_space_write_multi_1(t,h,SWS_ISAC,buf,size); - break; - case ISIC_WHAT_HSCXA: - bus_space_write_1(t,h,SWS_RW,0x0); - bus_space_write_multi_1(t,h,SWS_HSCX0,buf,size); - break; - case ISIC_WHAT_HSCXB: - bus_space_write_1(t,h,SWS_RW,0x0+0x40); - bus_space_write_multi_1(t,h,SWS_HSCX0,buf,size); - break; - } -} - -static void -sws_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,SWS_RW,reg); - bus_space_write_1(t,h,SWS_ISAC,data); - break; - case ISIC_WHAT_HSCXA: - bus_space_write_1(t,h,SWS_RW,reg); - bus_space_write_1(t,h,SWS_HSCX0,data); - break; - case ISIC_WHAT_HSCXB: - bus_space_write_1(t,h,SWS_RW,reg+0x40); - bus_space_write_1(t,h,SWS_HSCX0,data); - break; - } -} - -static u_char -sws_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,SWS_RW,reg); - return bus_space_read_1(t,h,SWS_ISAC); - case ISIC_WHAT_HSCXA: - bus_space_write_1(t,h,SWS_RW,reg); - return bus_space_read_1(t,h,SWS_HSCX0); - case ISIC_WHAT_HSCXB: - bus_space_write_1(t,h,SWS_RW,reg+0x40); - return bus_space_read_1(t,h,SWS_HSCX0); - default: - return 0; - } -} - -/* attach callback routine */ -int -isic_attach_sws(device_t dev) -{ - int unit = device_get_unit(dev); - struct l1_softc *sc = &l1_sc[unit]; - - 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 = sws_read_reg; - sc->writereg = sws_write_reg; - sc->readfifo = sws_read_fifo; - sc->writefifo = sws_write_fifo; - sc->clearirq = NULL; - sc->sc_cardtyp = CARD_TYPEP_SWS; - sc->sc_bustyp = BUS_TYPE_IOM2; - sc->sc_ipac = 0; - sc->sc_bfifolen = HSCX_FIFO_LEN; - - /* - * Read HSCX A/B VSTR. Expected value for the SWS PnP card is - * 0x05 ( = version 2.1 ) in the least significant bits. - */ - - if( ((HSCX_READ(0, H_VSTR) & 0xf) != 0x5) || - ((HSCX_READ(1, H_VSTR) & 0xf) != 0x5) ) - { - printf("isic%d: HSCX VSTR test failed for SWS PnP\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,SWS_RESON,0x3); - DELAY(SEC_DELAY / 5); - bus_space_write_1(t,h,SWS_RESOFF,0x0); - DELAY(SEC_DELAY / 5); - - return(0); -} -#endif /* defined(SEDLBAUER) && NISIC > 0 */ diff --git a/sys/i4b/layer1/i4b_tel_s016.c b/sys/i4b/layer1/i4b_tel_s016.c deleted file mode 100644 index 87f4dbb..0000000 --- a/sys/i4b/layer1/i4b_tel_s016.c +++ /dev/null @@ -1,383 +0,0 @@ -/* - * Copyright (c) 1996 Arne Helme. All rights reserved. - * - * Copyright (c) 1996 Gary Jennejohn. All rights reserved. - * - * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 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 - 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 $ - * - * $FreeBSD$ - * - * last edit-date: [Mon Dec 13 22:02:47 1999] - * - *---------------------------------------------------------------------------*/ - -#include "isic.h" -#include "opt_i4b.h" - -#if NISIC > 0 && defined(TEL_S0_16) - -#include -#include -#include -#include - -#include -#include - -#include - -#include -#include - -#include -#include -#include - -#include -#include -#include - -#define TELES_S016_MEMSIZE 0x1000 - -static u_char intr_no[] = { 1, 1, 0, 2, 4, 6, 1, 1, 1, 0, 8, 10, 12, 1, 1, 14 }; -static const bus_size_t offset[] = { 0x100, 0x180, 0x1c0 }; - -/*---------------------------------------------------------------------------* - * Teles S0/16 write register routine - *---------------------------------------------------------------------------*/ -static void -tels016_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.mem); - bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.mem); - - offs += offset[what]; - - if (offs & 0x01) - offs |= 0x200; - - bus_space_write_1(t, h, offs, data); -} - -/*---------------------------------------------------------------------------* - * Teles S0/16 read register routine - *---------------------------------------------------------------------------*/ -static u_int8_t -tels016_read_reg(struct l1_softc *sc, int what, bus_size_t offs) -{ - bus_space_tag_t t = rman_get_bustag(sc->sc_resources.mem); - bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.mem); - - offs += offset[what]; - - if(offs & 0x01) - offs |= 0x200; - - return bus_space_read_1(t, h, offs); -} - -/*---------------------------------------------------------------------------* - * Teles S0/16 fifo write routine - *---------------------------------------------------------------------------*/ -static void -tels016_write_fifo(struct l1_softc *sc, int what, void *data, size_t size) -{ - bus_space_tag_t t = rman_get_bustag(sc->sc_resources.mem); - bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.mem); - bus_space_write_region_1(t, h, offset[what], data, size); -} - -/*---------------------------------------------------------------------------* - * Teles S0/16 fifo read routine - *---------------------------------------------------------------------------*/ -static void -tels016_read_fifo(struct l1_softc *sc, int what, void *buf, size_t size) -{ - bus_space_tag_t t = rman_get_bustag(sc->sc_resources.mem); - bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.mem); - bus_space_read_region_1(t, h, offset[what], buf, size); -} - -/*---------------------------------------------------------------------------* - * isic_probe_s016 - probe for Teles S0/16 and compatibles - *---------------------------------------------------------------------------*/ -int -isic_probe_s016(device_t dev) -{ - size_t unit = device_get_unit(dev); /* get unit */ - struct l1_softc *sc = 0; /* softc */ - void *ih = 0; /* dummy */ - u_int8_t b0,b1,b2; /* for signature */ - bus_space_tag_t t; /* bus things */ - bus_space_handle_t h; - - /* check max unit range */ - - if(unit >= ISIC_MAXUNIT) - { - printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for Teles S0/16!\n", - unit, unit); - return(ENXIO); - } - - sc = &l1_sc[unit]; /* get pointer to softc */ - - sc->sc_unit = unit; /* set unit */ - - sc->sc_flags = FLAG_TELES_S0_16; /* set flags */ - - /* see if an io base was supplied */ - - 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 Teles S0/16.\n", unit); - return(ENXIO); - } - - sc->sc_port = rman_get_start(sc->sc_resources.io_base[0]); - - /* - * check if the provided io port is valid - */ - - switch(sc->sc_port) - { - case 0xd80: - case 0xe80: - case 0xf80: - break; - - default: - printf("isic%d: Error, invalid iobase 0x%x specified for Teles S0/16!\n", - unit, sc->sc_port); - isic_detach_common(dev); - return(ENXIO); - break; - } - - /* allocate memory resource */ - - if(!(sc->sc_resources.mem = - bus_alloc_resource(dev, SYS_RES_MEMORY, - &sc->sc_resources.mem_rid, - 0ul, ~0ul, TELES_S016_MEMSIZE, - RF_ACTIVE))) - { - printf("isic%d: Could not allocate memory for Teles S0/16.\n", unit); - isic_detach_common(dev); - return(ENXIO); - } - - /* - * get virtual addr. - */ - sc->sc_vmem_addr = rman_get_virtual(sc->sc_resources.mem); - - /* - * check for valid adresses - */ - switch(kvtop(sc->sc_vmem_addr)) - { - case 0xc0000: - case 0xc2000: - case 0xc4000: - case 0xc6000: - case 0xc8000: - case 0xca000: - case 0xcc000: - case 0xce000: - case 0xd0000: - case 0xd2000: - case 0xd4000: - case 0xd6000: - case 0xd8000: - case 0xda000: - case 0xdc000: - case 0xde000: - break; - - default: - printf("isic%d: Error, invalid memory address 0x%lx for Teles S0/16!\n", - unit, kvtop(sc->sc_vmem_addr)); - isic_detach_common(dev); - return(ENXIO); - break; - } - - /* setup ISAC access routines */ - - sc->clearirq = NULL; - - sc->readreg = tels016_read_reg; - sc->writereg = tels016_write_reg; - - sc->readfifo = tels016_read_fifo; - sc->writefifo = tels016_write_fifo; - - /* setup card type */ - sc->sc_cardtyp = CARD_TYPEP_16; - - /* setup IOM bus type */ - - sc->sc_bustyp = BUS_TYPE_IOM1; - - sc->sc_ipac = 0; - sc->sc_bfifolen = HSCX_FIFO_LEN; - - /* setup ISAC base addr, though we don't really need it */ - - ISAC_BASE = (caddr_t)((sc->sc_vmem_addr) + 0x100); - - /* setup HSCX base addr */ - - HSCX_A_BASE = (caddr_t)((sc->sc_vmem_addr) + 0x180); - HSCX_B_BASE = (caddr_t)((sc->sc_vmem_addr) + 0x1c0); - - t = rman_get_bustag(sc->sc_resources.io_base[0]); - h = rman_get_bushandle(sc->sc_resources.io_base[0]); - - /* get signature bytes */ - b0 = bus_space_read_1(t, h, 0); - b1 = bus_space_read_1(t, h, 1); - b2 = bus_space_read_1(t, h, 2); - - /* check signature bytes */ - if(b0 != 0x51) - { - printf("isic%d: Error, signature 1 0x%x != 0x51 for Teles S0/16!\n", - unit, b0); - isic_detach_common(dev); - return(ENXIO); - } - - if(b1 != 0x93) - { - printf("isic%d: Error, signature 2 0x%x != 0x93 for Teles S0/16!\n", - unit, b1); - isic_detach_common(dev); - return(ENXIO); - } - - if((b2 != 0x1e) && (b2 != 0x1f)) - { - printf("isic%d: Error, signature 3 0x%x != 0x1e or 0x1f for Teles S0/16!\n", - unit, b2); - isic_detach_common(dev); - return(ENXIO); - } - - /* 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 Teles S0/16.\n", unit); - isic_detach_common(dev); - return ENXIO; - } - - /* register interupt routine */ - - bus_setup_intr(dev, sc->sc_resources.irq, - INTR_TYPE_NET, - (void(*)(void *))(isicintr), - sc, &ih); - - /* get the irq number */ - - sc->sc_irq = rman_get_start(sc->sc_resources.irq); - - /* check IRQ validity */ - - if((intr_no[sc->sc_irq]) == 1) - { - printf("isic%d: Error, invalid IRQ [%d] specified for Teles S0/16!\n", - unit, sc->sc_irq); - isic_detach_common(dev); - return(ENXIO); - } - - return (0); -} - -/*---------------------------------------------------------------------------* - * isic_attach_s016 - attach Teles S0/16 and compatibles - *---------------------------------------------------------------------------*/ -int -isic_attach_s016(device_t dev) -{ - struct l1_softc *sc = &l1_sc[device_get_unit(dev)]; - u_long irq; - - bus_space_tag_t ta = rman_get_bustag(sc->sc_resources.mem); - bus_space_handle_t ha = rman_get_bushandle(sc->sc_resources.mem); - bus_space_tag_t tb = rman_get_bustag(sc->sc_resources.io_base[0]); - bus_space_handle_t hb = rman_get_bushandle(sc->sc_resources.io_base[0]); - - /* is this right for FreeBSD or off by one ? */ - irq = intr_no[sc->sc_irq]; - - /* configure IRQ */ - - irq |= ((u_long) sc->sc_vmem_addr) >> 9; - - DELAY(SEC_DELAY / 10); - bus_space_write_1(tb, hb, 4, irq); - - DELAY(SEC_DELAY / 10); - bus_space_write_1(tb, hb, 4, irq | 0x01); - - DELAY(SEC_DELAY / 5); - - /* set card bit off */ - - bus_space_write_1(ta, ha, 0x80, 0); - DELAY(SEC_DELAY / 5); - - /* set card bit on */ - - bus_space_write_1(ta, ha, 0x80, 1); - DELAY(SEC_DELAY / 5); - - return 0; -} -#endif /* ISIC > 0 */ diff --git a/sys/i4b/layer1/i4b_tel_s0163.c b/sys/i4b/layer1/i4b_tel_s0163.c deleted file mode 100644 index fa0c6a6..0000000 --- a/sys/i4b/layer1/i4b_tel_s0163.c +++ /dev/null @@ -1,386 +0,0 @@ -/* - * Copyright (c) 1996 Arne Helme. All rights reserved. - * - * Copyright (c) 1996 Gary Jennejohn. All rights reserved. - * - * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 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 - 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 $ - * - * $FreeBSD$ - * - * last edit-date: [Mon Dec 13 22:02:55 1999] - * - *---------------------------------------------------------------------------*/ - -#include "isic.h" -#include "opt_i4b.h" - -#if NISIC > 0 && defined(TEL_S0_16_3) - -#include -#include -#include -#include - -#include - -#include - -#include -#include - -#include -#include -#include - -#include -#include -#include - -static u_char intr_no[] = { 1, 1, 0, 2, 4, 6, 1, 1, 1, 0, 8, 10, 12, 1, 1, 14 }; - -#define ISAC_OFFS 0x400 -#define HSCXA_OFFS 0xc00 -#define HSCXB_OFFS 0x800 - -/*---------------------------------------------------------------------------* - * Teles S0/16.3 read fifo routine - *---------------------------------------------------------------------------*/ -static void -tels0163_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[what+1]); - bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[what+1]); - bus_space_read_multi_1(t,h,0x1e,buf,size); -} - -/*---------------------------------------------------------------------------* - * Teles S0/16.3 write fifo routine - *---------------------------------------------------------------------------*/ -static void -tels0163_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[what+1]); - bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[what+1]); - bus_space_write_multi_1(t,h,0x1e,buf,size); -} - -/*---------------------------------------------------------------------------* - * Teles S0/16.3 ISAC put register routine - *---------------------------------------------------------------------------*/ -static void -tels0163_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[what+1]); - bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[what+1]); - bus_space_write_1(t,h,offs - 0x20,data); -} - -/*---------------------------------------------------------------------------* - * Teles S0/16.3 ISAC get register routine - *---------------------------------------------------------------------------*/ -static u_int8_t -tels0163_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[what+1]); - bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[what+1]); - return bus_space_read_1(t,h,offs - 0x20); -} - -/*---------------------------------------------------------------------------* - * isic_probe_s0163 - probe routine for Teles S0/16.3 - *---------------------------------------------------------------------------*/ -int -isic_probe_s0163(device_t dev) -{ - size_t unit = device_get_unit(dev); /* get unit */ - struct l1_softc *sc = 0; /* pointer to softc */ - void *ih = 0; /* dummy */ - bus_space_tag_t t; /* bus things */ - bus_space_handle_t h; - u_int8_t b0,b1,b2; /* signature */ - - /* check max unit range */ - - if(unit >= ISIC_MAXUNIT) - { - printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for Teles 16.3!\n", - unit, unit); - return(ENXIO); - } - - sc = &l1_sc[unit]; /* get pointer to softc */ - sc->sc_unit = unit; /* set unit */ - sc->sc_flags = FLAG_TELES_S0_163; /* set flags */ - - /* see if an io base was supplied */ - - 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 get iobase for Teles S0/16.3.\n", - unit); - return(ENXIO); - } - - /* set io base */ - - sc->sc_port = rman_get_start(sc->sc_resources.io_base[0]); - /* Release the resource - re-allocate later with correct size */ - bus_release_resource(dev, SYS_RES_IOPORT, sc->sc_resources.io_rid[0], - sc->sc_resources.io_base[0]); - - switch(sc->sc_port) - { - case 0xd80: - case 0xe80: - case 0xf80: - break; - - case 0x180: - case 0x280: - case 0x380: - printf("isic%d: Error, instead of using iobase 0x%x for your Teles S0/16.3,\n", - unit, sc->sc_port); - printf("isic%d: please use 0x%x in the kernel configuration file!\n", - unit, sc->sc_port+0xc00); - isic_detach_common(dev); - return(ENXIO); - break; - - default: - printf("isic%d: Error, invalid iobase 0x%x specified for Teles S0/16.3!\n", - unit, sc->sc_port); - isic_detach_common(dev); - return(ENXIO); - break; - } - - /* set io port resources */ - - sc->sc_resources.io_rid[0] = 0; - bus_set_resource(dev, SYS_RES_IOPORT, 0, sc->sc_port, 0x20); - sc->sc_resources.io_base[0] = - bus_alloc_resource(dev, SYS_RES_IOPORT, - &sc->sc_resources.io_rid[0], - 0ul, ~0ul, 1, RF_ACTIVE); - if(!sc->sc_resources.io_base[0]) - { - printf("isic%d: Error allocating io at 0x%x for Teles S0/16.3!\n", - unit, sc->sc_port); - isic_detach_common(dev); - return ENXIO; - } - sc->sc_resources.io_rid[1] = 1; - bus_set_resource(dev, SYS_RES_IOPORT, 1, - sc->sc_port-ISAC_OFFS, 0x20); - sc->sc_resources.io_base[1] = - bus_alloc_resource(dev, SYS_RES_IOPORT, - &sc->sc_resources.io_rid[1], - 0ul, ~0ul, 1, RF_ACTIVE); - if(!sc->sc_resources.io_base[1]) - { - printf("isic%d: Error allocating io at 0x%x for Teles S0/16.3!\n", - unit, sc->sc_port-ISAC_OFFS); - isic_detach_common(dev); - return ENXIO; - } - - sc->sc_resources.io_rid[2] = 2; - bus_set_resource(dev, SYS_RES_IOPORT, 2, - sc->sc_port-HSCXA_OFFS, 0x20); - sc->sc_resources.io_base[2] = - bus_alloc_resource(dev, SYS_RES_IOPORT, - &sc->sc_resources.io_rid[2], - 0ul, ~0ul, 1, RF_ACTIVE); - if(!sc->sc_resources.io_base[2]) - { - printf("isic%d: Error allocating io at 0x%x for Teles S0/16.3!\n", - unit, sc->sc_port-HSCXA_OFFS); - isic_detach_common(dev); - return ENXIO; - } - - sc->sc_resources.io_rid[3] = 3; - bus_set_resource(dev, SYS_RES_IOPORT, 3, - sc->sc_port-HSCXB_OFFS, 0x20); - sc->sc_resources.io_base[3] = - bus_alloc_resource(dev, SYS_RES_IOPORT, - &sc->sc_resources.io_rid[3], - 0ul, ~0ul, 1, RF_ACTIVE); - if(!sc->sc_resources.io_base[3]) - { - printf("isic%d: Error allocating io at 0x%x for Teles S0/16.3!\n", - unit, sc->sc_port-HSCXB_OFFS); - isic_detach_common(dev); - return ENXIO; - } - - /* setup access routines */ - - sc->clearirq = NULL; - sc->readreg = tels0163_read_reg; - sc->writereg = tels0163_write_reg; - - sc->readfifo = tels0163_read_fifo; - sc->writefifo = tels0163_write_fifo; - - /* setup card type */ - - sc->sc_cardtyp= CARD_TYPEP_16_3; - - /* setup IOM bus type */ - - sc->sc_bustyp = BUS_TYPE_IOM2; - - sc->sc_ipac = 0; - sc->sc_bfifolen = HSCX_FIFO_LEN; - - t = rman_get_bustag(sc->sc_resources.io_base[0]); - h = rman_get_bushandle(sc->sc_resources.io_base[0]); - - b0 = bus_space_read_1(t, h, 0); - b1 = bus_space_read_1(t, h, 1); - b2 = bus_space_read_1(t, h, 2); - - if ( b0 != 0x51 && b0 != 0x10 ) { - printf("isic%d: Error, signature 1 0x%x != 0x51 or 0x10 for Teles S0/16.3!\n", - unit, b0); - isic_detach_common(dev); - return ENXIO; - } - - if ( b1 != 0x93 ) { - printf("isic%d: Error, signature 2 0x%x != 0x93 for Teles S0/16.3!\n", - unit, b1); - isic_detach_common(dev); - return ENXIO; - } - if ( b2 != 0x1c ) { - printf("isic%d: Error, signature 3 0x%x != 0x1c for Teles S0/16.3!\n", - unit, b2); - isic_detach_common(dev); - return ENXIO; - } - - /* - * Read HSCX A/B VSTR. Expected value for the S0/16.3 card is - * 0x05 or 0x04 (for older 16.3's) 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 Teles S0/16.3\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); - } - - /* 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 get IRQ for Teles S0/16.3.\n",unit); - isic_detach_common(dev); - return ENXIO; - } - - /* get the irq number */ - sc->sc_irq = rman_get_start(sc->sc_resources.irq); - - switch(sc->sc_irq) - { - case 2: - case 9: - case 5: - case 10: - case 12: - case 15: - break; - - default: - printf("isic%d: Error, invalid IRQ [%d] specified for Teles S0/16.3!\n", - unit, sc->sc_irq); - isic_detach_common(dev); - return(ENXIO); - break; - } - - /* register interupt routine */ - bus_setup_intr(dev, sc->sc_resources.irq, - INTR_TYPE_NET, - (void(*)(void *))(isicintr), - sc, &ih); - - return (0); -} - -/*---------------------------------------------------------------------------* - * isic_attach_s0163 - attach Teles S0/16.3 and compatibles - *---------------------------------------------------------------------------*/ -int -isic_attach_s0163(device_t dev) -{ - unsigned int 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]); - - /* configure IRQ */ - - DELAY(SEC_DELAY / 10); - bus_space_write_1(t, h, 4, intr_no[sc->sc_irq]); - - DELAY(SEC_DELAY / 10); - bus_space_write_1(t, h, 4, intr_no[sc->sc_irq] | 0x01); - - return (0); -} - -#endif /* ISIC > 0 */ - diff --git a/sys/i4b/layer1/i4b_tel_s08.c b/sys/i4b/layer1/i4b_tel_s08.c deleted file mode 100644 index d97652e..0000000 --- a/sys/i4b/layer1/i4b_tel_s08.c +++ /dev/null @@ -1,316 +0,0 @@ -/* - * Copyright (c) 1996 Arne Helme. All rights reserved. - * - * Copyright (c) 1996 Gary Jennejohn. All rights reserved. - * - * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 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 - 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 $ - * - * $FreeBSD$ - * - * last edit-date: [Mon Dec 13 22:03:06 1999] - * - *---------------------------------------------------------------------------*/ - -#include "isic.h" -#include "opt_i4b.h" - -#if NISIC > 0 && defined(TEL_S0_8) - -#include -#include -#include -#include - -#include -#include - -#include - -#include -#include - -#include -#include -#include - -#include -#include -#include - -#define TELES_S08_MEMSIZE 0x1000 - -static const bus_size_t offset[] = { 0x100, 0x180, 0x1c0 }; - -/*---------------------------------------------------------------------------* - * Teles S0/8 write register routine - *---------------------------------------------------------------------------*/ -static void -tels08_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.mem); - bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.mem); - - offs += offset[what]; - - if (offs & 0x01) - offs |= 0x200; - - bus_space_write_1(t, h, offs, data); -} - -/*---------------------------------------------------------------------------* - * Teles S0/8 read register routine - *---------------------------------------------------------------------------*/ -static u_int8_t -tels08_read_reg(struct l1_softc *sc, int what, bus_size_t offs) -{ - bus_space_tag_t t = rman_get_bustag(sc->sc_resources.mem); - bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.mem); - - offs += offset[what]; - - if (offs & 0x01) - offs |= 0x200; - - return bus_space_read_1(t, h, offs); -} - -/*---------------------------------------------------------------------------* - * Teles S0/8 fifo write access - *---------------------------------------------------------------------------*/ -static void -tels08_write_fifo(struct l1_softc *sc, int what, void *data, size_t size) -{ - bus_space_tag_t t = rman_get_bustag(sc->sc_resources.mem); - bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.mem); - bus_space_write_region_1(t, h, offset[what], data, size); -} - -/*---------------------------------------------------------------------------* - * Teles S0/8 fifo read access - *---------------------------------------------------------------------------*/ -static void -tels08_read_fifo(struct l1_softc *sc, int what, void *buf, size_t size) -{ - bus_space_tag_t t = rman_get_bustag(sc->sc_resources.mem); - bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.mem); - bus_space_read_region_1(t, h, offset[what], buf, size); -} - -/*---------------------------------------------------------------------------* - * isic_probe_s08 - probe for Teles S0/8 and compatibles - *---------------------------------------------------------------------------*/ -int -isic_probe_s08(device_t dev) -{ - size_t unit = device_get_unit(dev); /* get unit */ - struct l1_softc *sc = 0; /* pointer to softc */ - void *ih = 0; /* dummy */ - - /* check max unit range */ - - if(unit >= ISIC_MAXUNIT) - { - printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for Teles S0/8!\n", - unit, unit); - return(ENXIO); - } - - sc = &l1_sc[unit]; /* get pointer to softc */ - - sc->sc_unit = unit; /* set unit */ - - sc->sc_flags = FLAG_TELES_S0_8; /* set flags */ - - /* see if an io base was supplied */ - - 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))) - { - /* the S0/8 is completely memory mapped ! */ - - bus_release_resource(dev,SYS_RES_IOPORT, - sc->sc_resources.io_rid[0], - sc->sc_resources.io_base[0]); - printf("isic%d: Error, iobase specified for Teles S0/8!\n", unit); - return(ENXIO); - } - - /* allocate memory */ - - if(!(sc->sc_resources.mem = - bus_alloc_resource(dev, SYS_RES_MEMORY, - &sc->sc_resources.mem_rid, - 0ul, ~0ul, TELES_S08_MEMSIZE, RF_ACTIVE))) - { - printf("isic%d: Could not allocate memory for Teles S0/8!\n", unit); - return(ENXIO); - } - - /* - * get virtual addr. it's just needed to see if it is in - * the valid range - */ - - sc->sc_vmem_addr = rman_get_virtual(sc->sc_resources.mem); - - /* check if inside memory range of 0xA0000 .. 0xDF000 */ - - if((kvtop(sc->sc_vmem_addr) < 0xa0000) || - (kvtop(sc->sc_vmem_addr) > 0xdf000)) - { - printf("isic%d: Error, mem addr 0x%lx outside 0xA0000-0xDF000 for Teles S0/8!\n", - unit, kvtop(sc->sc_vmem_addr)); - bus_release_resource(dev,SYS_RES_MEMORY, - sc->sc_resources.mem_rid, - sc->sc_resources.mem); - sc->sc_resources.mem = 0; - return(ENXIO); - } - - /* setup ISAC access routines */ - - sc->clearirq = NULL; - - sc->readreg = tels08_read_reg; - sc->writereg = tels08_write_reg; - - sc->readfifo = tels08_read_fifo; - sc->writefifo = tels08_write_fifo; - - sc->sc_cardtyp = CARD_TYPEP_8; /* setup card type */ - - sc->sc_bustyp = BUS_TYPE_IOM1; /* setup IOM bus type */ - - sc->sc_ipac = 0; - sc->sc_bfifolen = HSCX_FIFO_LEN; - - /* setup ISAC base addr, though we don't really need it */ - - ISAC_BASE = (caddr_t)((sc->sc_vmem_addr) + 0x100); - - /* setup HSCX base addr */ - - HSCX_A_BASE = (caddr_t)((sc->sc_vmem_addr) + 0x180); - HSCX_B_BASE = (caddr_t)((sc->sc_vmem_addr) + 0x1c0); - - /* allocate 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 Teles S0/8!\n",unit); - - bus_release_resource(dev,SYS_RES_MEMORY, - sc->sc_resources.mem_rid, - sc->sc_resources.mem); - - sc->sc_resources.mem = 0; - return ENXIO; - } - - /* get the irq number */ - - sc->sc_irq = rman_get_start(sc->sc_resources.irq); - - /* check IRQ validity */ - - switch(sc->sc_irq) - { - case 2: - case 9: /* XXX */ - case 3: - case 4: - case 5: - case 6: - case 7: - break; - - default: - printf("isic%d: Error, invalid IRQ [%d] specified for Teles S0/8!\n", - unit, sc->sc_irq); - bus_release_resource(dev,SYS_RES_IRQ, - sc->sc_resources.irq_rid, - sc->sc_resources.irq); - sc->sc_resources.irq = 0; - bus_release_resource(dev,SYS_RES_MEMORY, - sc->sc_resources.mem_rid, - sc->sc_resources.mem); - sc->sc_resources.mem = 0; - return(ENXIO); - break; - } - - /* register interupt routine */ - - bus_setup_intr(dev, sc->sc_resources.irq, - INTR_TYPE_NET, - (void(*)(void *))(isicintr), - sc, &ih); - - return (0); -} - -/*---------------------------------------------------------------------------* - * isic_attach_s08 - attach Teles S0/8 and compatibles - *---------------------------------------------------------------------------*/ -int -isic_attach_s08(device_t dev) -{ - struct l1_softc *sc = &l1_sc[device_get_unit(dev)]; - bus_space_tag_t t = rman_get_bustag(sc->sc_resources.mem); - bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.mem); - - /* set card off */ - - bus_space_write_1(t, h, 0x80, 0); - - DELAY(SEC_DELAY / 5); - - /* set card on */ - - bus_space_write_1(t, h, 0x80, 1); - - DELAY(SEC_DELAY / 5); - - return 0; -} -#endif /* ISIC > 0 */ diff --git a/sys/i4b/layer1/i4b_usr_sti.c b/sys/i4b/layer1/i4b_usr_sti.c deleted file mode 100644 index 2540ae4..0000000 --- a/sys/i4b/layer1/i4b_usr_sti.c +++ /dev/null @@ -1,684 +0,0 @@ -/* - * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - *--------------------------------------------------------------------------- - * - * i4b_usr_sti.c - USRobotics Sportster ISDN TA intern (Tina-pp) - * ------------------------------------------------------------- - * - * $FreeBSD$ - * - * last edit-date: [Sun Feb 14 10:29:05 1999] - * - *---------------------------------------------------------------------------*/ - -#if defined(__FreeBSD__) -#include "isic.h" -#include "opt_i4b.h" -#else -#define NISIC 1 -#endif -#if NISIC > 0 && defined(USR_STI) - -#include -#if defined(__FreeBSD__) && __FreeBSD__ >= 3 -#include -#else -#include -#endif -#include -#include -#include - -#ifdef __FreeBSD__ -#include -#include -#include -#include -#include -#include -#else -#include -#include -#endif - -#include -#include - -#ifdef __FreeBSD__ -#include -#include -#else -#include -#include -#endif - -#include -#include -#include - -#include - -/*---------------------------------------------------------------------------* - * USR Sportster TA intern special registers - *---------------------------------------------------------------------------*/ -#define USR_HSCXA_OFF 0x0000 -#define USR_HSCXB_OFF 0x4000 -#define USR_INTL_OFF 0x8000 -#define USR_ISAC_OFF 0xc000 - -#define USR_RES_BIT 0x80 /* 0 = normal, 1 = reset ISAC/HSCX */ -#define USR_INTE_BIT 0x40 /* 0 = IRQ disabled, 1 = IRQ's enabled */ -#define USR_IL_MASK 0x07 /* IRQ level config */ - -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)) - -#ifdef USRTA_DEBUG_PORTACCESS -int debugcntr; -#define USRTA_DEBUG(fmt) \ - if (++debugcntr < 1000) printf fmt; -#else -#define USRTA_DEBUG(fmt) -#endif - -/*---------------------------------------------------------------------------* - * USRobotics read fifo routine - *---------------------------------------------------------------------------*/ -static void -usrtai_read_fifo(struct l1_softc *sc, int what, void *buf, size_t size) -{ - register int offset = 0; - register unsigned int base = 0; - -USRTA_DEBUG(("usrtai_read_fifo: what %d size %d\n", what, size)) - switch (what) - { - case ISIC_WHAT_ISAC: - base = (unsigned int)ISAC_BASE; - break; - case ISIC_WHAT_HSCXA: - base = (unsigned int)HSCX_A_BASE; - break; - case ISIC_WHAT_HSCXB: - base = (unsigned int)HSCX_B_BASE; - break; - default: - printf("usrtai_read_fifo: invalid what %d\n", what); - return; - } - - for(;size > 0; size--, offset++) - { - *((u_char *)buf + offset) = inb(base + ADDR(offset)); - } -} - -/*---------------------------------------------------------------------------* - * USRobotics write fifo routine - *---------------------------------------------------------------------------*/ -static void -usrtai_write_fifo(struct l1_softc *sc, int what, void *data, size_t size) -{ - register int offset = 0; - register unsigned int base = 0; - -USRTA_DEBUG(("usrtai_write_fifo: what %d size %d\n", what, size)) - switch (what) - { - case ISIC_WHAT_ISAC: - base = (unsigned int)ISAC_BASE; - break; - case ISIC_WHAT_HSCXA: - base = (unsigned int)HSCX_A_BASE; - break; - case ISIC_WHAT_HSCXB: - base = (unsigned int)HSCX_B_BASE; - break; - default: - printf("usrtai_write_fifo: invalid what %d\n", what); - return; - } - - - for(;size > 0; size--, offset++) - { - outb(base + ADDR(offset), *((u_char *)data + offset)); - } -} - -/*---------------------------------------------------------------------------* - * USRobotics write register routine - *---------------------------------------------------------------------------*/ -static void -usrtai_write_reg(struct l1_softc *sc, int what, bus_size_t offs, u_int8_t data) -{ - register unsigned int base = 0; - -USRTA_DEBUG(("usrtai_write_reg: what %d ADDR(%d) %d data %#x\n", what, offs, ADDR(offs), data)) - switch (what) - { - case ISIC_WHAT_ISAC: - base = (unsigned int)ISAC_BASE; - break; - case ISIC_WHAT_HSCXA: - base = (unsigned int)HSCX_A_BASE; - break; - case ISIC_WHAT_HSCXB: - base = (unsigned int)HSCX_B_BASE; - break; - default: - printf("usrtai_write_reg invalid what %d\n", what); - return; - } - - outb(base + ADDR(offs), (u_char)data); -} - -/*---------------------------------------------------------------------------* - * USRobotics read register routine - *---------------------------------------------------------------------------*/ -static u_int8_t -usrtai_read_reg(struct l1_softc *sc, int what, bus_size_t offs) -{ - register unsigned int base = 0; - u_int8_t byte; - -USRTA_DEBUG(("usrtai_read_reg: what %d ADDR(%d) %d..", what, offs, ADDR(offs))) - switch (what) - { - case ISIC_WHAT_ISAC: - base = (unsigned int)ISAC_BASE; - break; - case ISIC_WHAT_HSCXA: - base = (unsigned int)HSCX_A_BASE; - break; - case ISIC_WHAT_HSCXB: - base = (unsigned int)HSCX_B_BASE; - break; - default: - printf("usrtai_read_reg: invalid what %d\n", what); - return(0); - } - - byte = inb(base + ADDR(offs)); -USRTA_DEBUG(("usrtai_read_reg: got %#x\n", byte)) - return(byte); -} - -/*---------------------------------------------------------------------------* - * allocate an io port - based on code in isa_isic.c - *---------------------------------------------------------------------------*/ -static int -usrtai_alloc_port(device_t dev) -{ - size_t unit = device_get_unit(dev); - struct l1_softc *sc = &l1_sc[unit]; - int i, num = 0; - bus_size_t base; - - /* 49 io mappings: 1 config and 48x8 registers */ - - /* config at offset 0x8000 */ - base = sc->sc_port + 0x8000; - if (base < 0 || base > 0x0ffff) - return 1; - sc->sc_resources.io_rid[num] = num; - - bus_set_resource(dev, SYS_RES_IOPORT, num, base, 1); - - if(!(sc->sc_resources.io_base[num] = - bus_alloc_resource(dev, SYS_RES_IOPORT, - &sc->sc_resources.io_rid[num], - 0ul, ~0ul, 1, RF_ACTIVE))) - { - printf("isic%d: Error, failed to reserve io #%dport %#x!\n", unit, num, base); - isic_detach_common(dev); - return(ENXIO); - } - num++; - - /* HSCX A at offset 0 */ - base = sc->sc_port; - for (i = 0; i < 16; i++) { - if (base+i*1024 < 0 || base+i*1024+8 > 0x0ffff) - return 1; - sc->sc_resources.io_rid[num] = num; - - bus_set_resource(dev, SYS_RES_IOPORT, num, base+i*1024, 8); - - if(!(sc->sc_resources.io_base[num] = - bus_alloc_resource(dev, SYS_RES_IOPORT, - &sc->sc_resources.io_rid[num], - 0ul, ~0ul, 1, RF_ACTIVE))) - { - printf("isic%d: Error, failed to reserve io #%d port %#x!\n", unit, num, base+i*1024); - isic_detach_common(dev); - return(ENXIO); - } - ++num; - } - - /* HSCX B at offset 0x4000 */ - base = sc->sc_port + 0x4000; - for (i = 0; i < 16; i++) { - if (base+i*1024 < 0 || base+i*1024+8 > 0x0ffff) - return 1; - sc->sc_resources.io_rid[num] = num; - - bus_set_resource(dev, SYS_RES_IOPORT, num, base+i*1024, 8); - - if(!(sc->sc_resources.io_base[num] = - bus_alloc_resource(dev, SYS_RES_IOPORT, - &sc->sc_resources.io_rid[num], - 0ul, ~0ul, 1, RF_ACTIVE))) - { - printf("isic%d: Error, failed to reserve io #%d port %#x!\n", unit, num, base+i*1024); - isic_detach_common(dev); - return(ENXIO); - } - ++num; - } - - /* ISAC at offset 0xc000 */ - base = sc->sc_port + 0xc000; - for (i = 0; i < 16; i++) { - if (base+i*1024 < 0 || base+i*1024+8 > 0x0ffff) - return 1; - sc->sc_resources.io_rid[num] = num; - - bus_set_resource(dev, SYS_RES_IOPORT, num, base+i*1024, 8); - - if(!(sc->sc_resources.io_base[num] = - bus_alloc_resource(dev, SYS_RES_IOPORT, - &sc->sc_resources.io_rid[num], - 0ul, ~0ul, 1, RF_ACTIVE))) - { - printf("isic%d: Error, failed to reserve io #%d port %#x!\n", unit, num, base+i*1024); - isic_detach_common(dev); - return(ENXIO); - } - ++num; - } - - return(0); -} - -/*---------------------------------------------------------------------------* - * isic_probe_usrtai - probe for USR - *---------------------------------------------------------------------------*/ -int -isic_probe_usrtai(device_t dev) -{ - size_t unit = device_get_unit(dev); /* get unit */ - struct l1_softc *sc = 0; /* pointer to softc */ - void *ih = 0; /* dummy */ - - /* check max unit range */ - - if(unit >= ISIC_MAXUNIT) - { - printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for USR Sportster TA!\n", - unit, unit); - return(ENXIO); - } - - sc = &l1_sc[unit]; /* get pointer to softc */ - sc->sc_unit = unit; /* set unit */ - sc->sc_flags = FLAG_USR_ISDN_TA_INT; /* set flags */ - - /* see if an io base was supplied */ - - 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 get iobase for USR Sportster TA!\n", - unit); - return(ENXIO); - } - - /* set io base */ - - sc->sc_port = rman_get_start(sc->sc_resources.io_base[0]); - - /* release io base */ - - bus_release_resource(dev, SYS_RES_IOPORT, sc->sc_resources.io_rid[0], - sc->sc_resources.io_base[0]); - - - /* check if we got an iobase */ - - switch(sc->sc_port) - { - case 0x200: - case 0x208: - case 0x210: - case 0x218: - case 0x220: - case 0x228: - case 0x230: - case 0x238: - case 0x240: - case 0x248: - case 0x250: - case 0x258: - case 0x260: - case 0x268: - case 0x270: - case 0x278: - break; - - default: - printf("isic%d: Error, invalid iobase 0x%x specified for USR Sportster TA!\n", - unit, sc->sc_port); - return(0); - break; - } - - /* allocate all the ports needed */ - - if(usrtai_alloc_port(dev)) - { - printf("isic%d: Could not get the ports for USR Sportster TA!\n", unit); - isic_detach_common(dev); - return(ENXIO); - } - - /* 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 get an irq for USR Sportster TA!\n",unit); - isic_detach_common(dev); - return ENXIO; - } - - /* get the irq number */ - sc->sc_irq = rman_get_start(sc->sc_resources.irq); - - /* register interrupt routine */ - bus_setup_intr(dev, sc->sc_resources.irq, INTR_TYPE_NET, - (void(*)(void *))(isicintr), - sc, &ih); - - /* check IRQ validity */ - - if(intr_no[sc->sc_irq] == 0) - { - printf("isic%d: Error, invalid IRQ [%d] specified for USR Sportster TA!\n", - unit, sc->sc_irq); - return(1); - } - - /* setup ISAC access routines */ - - sc->clearirq = NULL; - sc->readreg = usrtai_read_reg; - sc->writereg = usrtai_write_reg; - - sc->readfifo = usrtai_read_fifo; - sc->writefifo = usrtai_write_fifo; - - /* setup card type */ - - sc->sc_cardtyp = CARD_TYPEP_USRTA; - - /* 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 + USR_ISAC_OFF; - HSCX_A_BASE = (caddr_t)sc->sc_port + USR_HSCXA_OFF; - HSCX_B_BASE = (caddr_t)sc->sc_port + USR_HSCXB_OFF; - - /* - * Read HSCX A/B VSTR. Expected value for USR Sportster TA based - * boards is 0x05 in the least significant bits. - */ - - if( ((HSCX_READ(0, H_VSTR) & 0xf) != 0x5) || - ((HSCX_READ(1, H_VSTR) & 0xf) != 0x5) ) - { - printf("isic%d: HSCX VSTR test failed for USR Sportster TA\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)); - return (1); - } - - return (0); -} - -/*---------------------------------------------------------------------------* - * isic_attach_usrtai - attach USR - *---------------------------------------------------------------------------*/ -int -isic_attach_usrtai(device_t dev) -{ - u_char irq = 0; - size_t unit = device_get_unit(dev); /* get unit */ - struct l1_softc *sc = 0; /* pointer to softc */ - - sc = &l1_sc[unit]; /* get pointer to softc */ - - /* reset the HSCX and ISAC chips */ - - outb(sc->sc_port + USR_INTL_OFF, USR_RES_BIT); - DELAY(SEC_DELAY / 10); - - outb(sc->sc_port + USR_INTL_OFF, 0x00); - DELAY(SEC_DELAY / 10); - - /* setup IRQ */ - - if((irq = intr_no[sc->sc_irq]) == 0) - { - printf("isic%d: Attach error, invalid IRQ [%d] specified for USR Sportster TA!\n", - unit, sc->sc_irq); - return(1); - } - - /* configure and enable irq */ - - outb(sc->sc_port + USR_INTL_OFF, irq | USR_INTE_BIT); - DELAY(SEC_DELAY / 10); - - return (0); -} - -#else /* end of FreeBSD, start NetBSD */ - -/* - * Use of sc->sc_maps: - * 0 : config register - * 1 - 16 : HSCX A registers - * 17 - 32 : HSCX B registers - * 33 - 48 : ISAC registers - */ - -#define USR_REG_OFFS(reg) ((reg % 4) * 2) -#define USR_HSCXA_MAP(reg) ((reg / 4) + 1) -#define USR_HSCXB_MAP(reg) ((reg / 4) + 17) -#define USR_ISAC_MAP(reg) ((reg / 4) + 33) - -static int map_base[] = { 33, 1, 17, 0 }; /* ISAC, HSCX A, HSCX B */ - -/*---------------------------------------------------------------------------* - * USRobotics read fifo routine - *---------------------------------------------------------------------------*/ -static void -usrtai_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size) -{ - int map, off, offset; - u_char * p = buf; - bus_space_tag_t t; - bus_space_handle_t h; - - for (offset = 0; size > 0; size--, offset++) { - map = map_base[what] + (offset / 4); - t = sc->sc_maps[map].t; - h = sc->sc_maps[map].h; - off = USR_REG_OFFS(offset); - - *p++ = bus_space_read_1(t, h, off); - } -} - -/*---------------------------------------------------------------------------* - * USRobotics write fifo routine - *---------------------------------------------------------------------------*/ -static void -usrtai_write_fifo(struct isic_softc *sc, int what, const void *buf, size_t size) -{ - int map, off, offset; - const u_char * p = buf; - bus_space_tag_t t; - bus_space_handle_t h; - u_char v; - - for (offset = 0; size > 0; size--, offset++) { - map = map_base[what] + (offset / 4); - t = sc->sc_maps[map].t; - h = sc->sc_maps[map].h; - off = USR_REG_OFFS(offset); - - v = *p++; - bus_space_write_1(t, h, off, v); - } -} - -/*---------------------------------------------------------------------------* - * USRobotics write register routine - *---------------------------------------------------------------------------*/ -static void -usrtai_write_reg(struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data) -{ - int map = map_base[what] + (offs / 4), - off = USR_REG_OFFS(offs); - bus_space_tag_t t = sc->sc_maps[map].t; - bus_space_handle_t h = sc->sc_maps[map].h; - - bus_space_write_1(t, h, off, data); -} - -/*---------------------------------------------------------------------------* - * USRobotics read register routine - *---------------------------------------------------------------------------*/ -static u_char -usrtai_read_reg(struct isic_softc *sc, int what, bus_size_t offs) -{ - int map = map_base[what] + (offs / 4), - off = USR_REG_OFFS(offs); - bus_space_tag_t t = sc->sc_maps[map].t; - bus_space_handle_t h = sc->sc_maps[map].h; - - return bus_space_read_1(t, h, off); -} - -/*---------------------------------------------------------------------------* - * isic_probe_usrtai - probe for USR - *---------------------------------------------------------------------------*/ -int -isic_probe_usrtai(struct isic_attach_args *ia) -{ - /* - * Read HSCX A/B VSTR. Expected value for IOM2 based - * boards is 0x05 in the least significant bits. - */ - - if(((bus_space_read_1(ia->ia_maps[USR_HSCXA_MAP(H_VSTR)].t, ia->ia_maps[USR_HSCXA_MAP(H_VSTR)].h, USR_REG_OFFS(H_VSTR)) & 0x0f) != 0x05) || - ((bus_space_read_1(ia->ia_maps[USR_HSCXB_MAP(H_VSTR)].t, ia->ia_maps[USR_HSCXB_MAP(H_VSTR)].h, USR_REG_OFFS(H_VSTR)) & 0x0f) != 0x05)) - return 0; - - return (1); -} - -/*---------------------------------------------------------------------------* - * isic_attach_usrtai - attach USR - *---------------------------------------------------------------------------*/ -int -isic_attach_usrtai(struct isic_softc *sc) -{ - bus_space_tag_t t = sc->sc_maps[0].t; - bus_space_handle_t h = sc->sc_maps[0].h; - u_char irq = intr_no[sc->sc_irq]; - - sc->clearirq = NULL; - sc->readreg = usrtai_read_reg; - sc->writereg = usrtai_write_reg; - - sc->readfifo = usrtai_read_fifo; - sc->writefifo = usrtai_write_fifo; - - /* setup card type */ - - sc->sc_cardtyp = CARD_TYPEP_USRTA; - - /* setup IOM bus type */ - - sc->sc_bustyp = BUS_TYPE_IOM2; - - sc->sc_ipac = 0; - sc->sc_bfifolen = HSCX_FIFO_LEN; - - /* reset the HSCX and ISAC chips */ - - bus_space_write_1(t, h, 0, USR_RES_BIT); - DELAY(SEC_DELAY / 10); - - bus_space_write_1(t, h, 0, 0x00); - DELAY(SEC_DELAY / 10); - - /* setup IRQ */ - - bus_space_write_1(t, h, 0, irq | USR_INTE_BIT); - DELAY(SEC_DELAY / 10); - - return (1); -} - -#endif /* __FreeBSD__ */ - -#endif /* ISIC > 0 */ 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 + +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 +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include + +#include + +#include +#include +#include + +#include + +#include +#include + +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 +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include + +#include + +#include + +#include +#include + +/*---------------------------------------------------------------------------* + * + * 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 +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include + +#include + +#include + +#include + +#include + +#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/ifpi/i4b_ifpi_pci.c b/sys/i4b/layer1/ifpi/i4b_ifpi_pci.c new file mode 100644 index 0000000..b1502c7 --- /dev/null +++ b/sys/i4b/layer1/ifpi/i4b_ifpi_pci.c @@ -0,0 +1,1487 @@ +/* + * 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 + * 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_ifpi_pci.c: AVM Fritz!Card PCI hardware driver + * -------------------------------------------------- + * + * $Id: i4b_ifpi_pci.c,v 1.4 2000/06/02 11:58:56 hm Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Fri Jun 2 13:58:02 2000] + * + *---------------------------------------------------------------------------*/ + +#include "ifpi.h" +#include "opt_i4b.h" +#include "pci.h" + +#if (NIFPI > 0) && (NPCI > 0) + +#include +#include +#include +#include + +#include /* for DELAY */ +#include /* this device uses port accesses only */ +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include + +#define PCI_AVMA1_VID 0x1244 +#define PCI_AVMA1_DID 0x0a00 + +/* prototypes */ +static void avma1pp_disable(device_t); + +static void avma1pp_intr(void *); +static void hscx_write_reg(int, u_int, u_int, struct l1_softc *); +static u_char hscx_read_reg(int, u_int, struct l1_softc *); +static u_int hscx_read_reg_int(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 avma1pp_hscx_int_handler(struct l1_softc *); +static void avma1pp_hscx_intr(int, u_int, struct l1_softc *); +static void avma1pp_init_linktab(struct l1_softc *); +static void avma1pp_bchannel_setup(int, int, int, int); +static void avma1pp_bchannel_start(int, int); +static void avma1pp_hscx_init(struct l1_softc *, int, int); +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); +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, avma1pp_attach_avma1pp), + DEVMETHOD(device_shutdown, avma1pp_disable), + + /* bus interface */ + DEVMETHOD(bus_print_child, bus_generic_print_child), + DEVMETHOD(bus_driver_added, bus_generic_driver_added), + + { 0, 0 } +}; + +#if 0 /* use what's in l1_softc */ +/* a minimal softc for the Fritz!Card PCI */ +struct avma1pp_softc +{ + bus_space_handle_t avma1pp_bhandle; + bus_space_tag_t avma1pp_btag; + void *avma1pp_intrhand; + struct resource *avma1pp_irq; + struct resource *avma1pp_res; + /* pointer to ifpi_sc */ + struct l1_softc *avma1pp_isc; +}; +#endif + +static driver_t avma1pp_pci_driver = { + "ifpi", + avma1pp_pci_methods, + 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 + *---------------------------------------------------------------------------*/ + +/* + * register offsets from i/o base + */ +#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 +#define ISAC_HI_REG_OFFSET 0x06 + +/* offset higher than this goes to the HI register set */ +#define MAX_LO_REG_OFFSET 0x2f + +/* mask for the offset */ +#define ISAC_REGSET_MASK 0x0f + +/* the offset from the base to the ISAC registers */ +#define ISAC_REG_OFFSET 0x10 + +/* the offset from the base to the ISAC FIFO */ +#define ISAC_FIFO 0x02 + +/* not really the HSCX, but sort of */ +#define HSCX_FIFO 0x00 +#define HSCX_STAT 0x04 + +/* + * AVM PCI Status Latch 0 read only bits + */ +#define ASL_IRQ_ISAC 0x01 /* ISAC interrupt, active low */ +#define ASL_IRQ_HSCX 0x02 /* HSX interrupt, active low */ +#define ASL_IRQ_TIMER 0x04 /* Timer interrupt, active low */ +#define ASL_IRQ_BCHAN ASL_IRQ_HSCX +/* actually active LOW */ +#define ASL_IRQ_Pending (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 */ +#define ASL_TESTBIT 0x10 /* active high */ + +/* + * AVM Status Latch 1 write only bits + */ +#define ASL1_INTSEL 0x0f /* active high */ +#define ASL1_ENABLE_IOM 0x80 /* active high */ + +/* + * "HSCX" mode bits + */ +#define HSCX_MODE_ITF_FLG 0x01 +#define HSCX_MODE_TRANS 0x02 +#define HSCX_MODE_CCR_7 0x04 +#define HSCX_MODE_CCR_16 0x08 +#define HSCX_MODE_TESTLOOP 0x80 + +/* + * "HSCX" status bits + */ +#define HSCX_STAT_RME 0x01 +#define HSCX_STAT_RDO 0x10 +#define HSCX_STAT_CRCVFRRAB 0x0E +#define HSCX_STAT_CRCVFR 0x06 +#define HSCX_STAT_RML_MASK 0x3f00 + +/* + * "HSCX" interrupt bits + */ +#define HSCX_INT_XPR 0x80 +#define HSCX_INT_XDU 0x40 +#define HSCX_INT_RPR 0x20 +#define HSCX_INT_MASK 0xE0 + +/* + * "HSCX" command bits + */ +#define HSCX_CMD_XRS 0x80 +#define HSCX_CMD_XME 0x01 +#define HSCX_CMD_RRS 0x20 +#define HSCX_CMD_XML_MASK 0x3f00 + +/* + * Commands and parameters are sent to the "HSCX" as a long, but the + * fields are handled as bytes. + * + * The long contains: + * (prot << 16)|(txl << 8)|cmd + * + * where: + * prot = protocol to use + * txl = transmit length + * cmd = the command to be executed + * + * The fields are defined as u_char in struct l1_softc. + * + * Macro to coalesce the byte fields into a u_int + */ +#define AVMA1PPSETCMDLONG(f) (f) = ((sc->avma1pp_cmd) | (sc->avma1pp_txl << 8) \ + | (sc->avma1pp_prot << 16)) + +/* + * 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 avma1pp_bchannel_setup upon active and cleared upon deactivation. + * It is set high to allow room for new flags. + */ +#define HSCX_AVMA1PP_ACTIVE 0x1000 + +/*---------------------------------------------------------------------------* + * AVM read fifo routines + *---------------------------------------------------------------------------*/ + +static void +avma1pp_read_fifo(struct l1_softc *sc, int what, void *buf, size_t size) +{ + 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(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; + } +} + +static void +hscx_read_fifo(int chan, void *buf, size_t len, struct l1_softc *sc) +{ + u_int32_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]); + + 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(btag, bhandle, ISAC_REG_OFFSET); + cnt += 4; + } +} + +/*---------------------------------------------------------------------------* + * AVM write fifo routines + *---------------------------------------------------------------------------*/ +static void +avma1pp_write_fifo(struct l1_softc *sc, int what, void *buf, size_t size) +{ + 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(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; + } +} + +static void +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]; + 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) + { + if (Bchan->bprot != BPROT_NONE) + sc->avma1pp_cmd |= HSCX_CMD_XME; + } + if (len != sc->sc_bfifolen) + sc->avma1pp_txl = len; + + cnt = 0; /* borrow cnt */ + AVMA1PPSETCMDLONG(cnt); + hscx_write_reg(chan, HSCX_STAT, cnt, sc); + + ip = (u_int32_t *)buf; + cnt = 0; + while (cnt < len) + { + bus_space_write_4(btag, bhandle, ISAC_REG_OFFSET, *ip); + ip++; + cnt += 4; + } +} + +/*---------------------------------------------------------------------------* + * AVM write register routines + *---------------------------------------------------------------------------*/ + +static void +avma1pp_write_reg(struct l1_softc *sc, int what, bus_size_t offs, u_int8_t data) +{ + u_char reg_bank; + 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; +#ifdef AVMA1PCI_DEBUG + printf("write_reg bank %d off %ld.. ", (int)reg_bank, (long)offs); +#endif + /* 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(0, offs, data, sc); + break; + case ISIC_WHAT_HSCXB: + hscx_write_reg(1, offs, data, sc); + break; + } +} + +static void +hscx_write_reg(int chan, u_int off, u_int val, struct l1_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]); + + /* point at the correct channel */ + bus_space_write_4(btag, bhandle, ADDR_REG_OFFSET, chan); + bus_space_write_4(btag, bhandle, ISAC_REG_OFFSET + off, val); +} + +/*---------------------------------------------------------------------------* + * AVM read register routines + *---------------------------------------------------------------------------*/ +static u_int8_t +avma1pp_read_reg(struct l1_softc *sc, int what, bus_size_t offs) +{ + u_char reg_bank; + 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; +#ifdef AVMA1PCI_DEBUG + printf("read_reg bank %d off %ld.. ", (int)reg_bank, (long)offs); +#endif + /* 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 l1_softc *sc) +{ + return(hscx_read_reg_int(chan, off, sc) & 0xff); +} + +/* + * need to be able to return an int because the RBCH is in the 2nd + * byte. + */ +static u_int +hscx_read_reg_int(int chan, u_int off, struct l1_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]); + + /* point at the correct channel */ + bus_space_write_4(btag, bhandle, ADDR_REG_OFFSET, chan); + return(bus_space_read_4(btag, bhandle, ISAC_REG_OFFSET + off)); +} + +/*---------------------------------------------------------------------------* + * avma1pp_probe - probe for a card + *---------------------------------------------------------------------------*/ +static int +avma1pp_pci_probe(dev) + device_t dev; +{ + u_int16_t did, vid; + + vid = pci_get_vendor(dev); + did = pci_get_device(dev); + + if ((vid == PCI_AVMA1_VID) && (did == PCI_AVMA1_DID)) { + device_set_desc(dev, "AVM Fritz!Card PCI"); + return(0); + } + + return(ENXIO); +} + +/*---------------------------------------------------------------------------* + * avma1pp_attach_avma1pp - attach Fritz!Card PCI + *---------------------------------------------------------------------------*/ +int +avma1pp_attach_avma1pp(device_t dev) +{ + struct l1_softc *sc; + u_int v; + 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); + sc = device_get_softc(dev); + unit = device_get_unit(dev); + bzero(sc, sizeof(struct l1_softc)); + + /* probably not really required */ + if(unit > IFPI_MAXUNIT) { + printf("avma1pp%d: Error, unit > IFPI_MAXUNIT!\n", unit); + splx(s); + return(ENXIO); + } + + if ((vid != PCI_AVMA1_VID) && (did != PCI_AVMA1_DID)) { + printf("avma1pp%d: unknown device!?\n", unit); + goto fail; + } + + ifpi_scp[unit] = sc; + + 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 (sc->sc_resources.io_base[0] == NULL) { + printf("avma1pp%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]); + + /* Allocate interrupt */ + 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 (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, sc->sc_resources.irq, INTR_TYPE_NET, avma1pp_intr, sc, &ih); + + if (error) { + 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->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 */ + + sc->clearirq = NULL; + sc->readreg = avma1pp_read_reg; + sc->writereg = avma1pp_write_reg; + + sc->readfifo = avma1pp_read_fifo; + sc->writefifo = avma1pp_write_fifo; + + /* setup card type */ + + sc->sc_cardtyp = CARD_TYPEP_AVMA1PCI; + + /* setup IOM bus type */ + + sc->sc_bustyp = BUS_TYPE_IOM2; + + /* set up some other miscellaneous things */ + sc->sc_ipac = 0; + 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); +#ifdef AVMA1PCI_DEBUG + printf("avma1pp_attach: I_STAR %x...", v); +#endif + v = ISAC_READ(I_MODE); +#ifdef AVMA1PCI_DEBUG + printf("avma1pp_attach: I_MODE %x...", v); +#endif + v = ISAC_READ(I_ADF2); +#ifdef AVMA1PCI_DEBUG + printf("avma1pp_attach: I_ADF2 %x...", v); +#endif + v = ISAC_READ(I_ISTA); +#ifdef AVMA1PCI_DEBUG + printf("avma1pp_attach: I_ISTA %x...", v); +#endif + if (v & ISAC_ISTA_EXI) + { + v = ISAC_READ(I_EXIR); +#ifdef AVMA1PCI_DEBUG + printf("avma1pp_attach: I_EXIR %x...", v); +#endif + } + v = ISAC_READ(I_CIRR); +#ifdef AVMA1PCI_DEBUG + printf("avma1pp_attach: I_CIRR %x...", v); +#endif + ISAC_WRITE(I_MASK, 0xff); + /* the Linux driver does this to clear any pending HSCX interrupts */ + v = hscx_read_reg_int(0, HSCX_STAT, sc); +#ifdef AVMA1PCI_DEBUG + printf("avma1pp_attach: 0 HSCX_STAT %x...", v); +#endif + v = hscx_read_reg_int(1, HSCX_STAT, sc); +#ifdef AVMA1PCI_DEBUG + printf("avma1pp_attach: 1 HSCX_STAT %x\n", v); +#endif + + bus_space_write_1(btag, bhandle, STAT0_OFFSET, ASL_RESET_ALL|ASL_TIMERDISABLE); + DELAY(SEC_DELAY/100); /* 10 ms */ + 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(btag, bhandle, STAT1_OFFSET, ASL1_ENABLE_IOM|sc->sc_irq); + DELAY(SEC_DELAY/100); /* 10 ms */ + v = bus_space_read_1(btag, bhandle, STAT1_OFFSET); + printf("after reset: S1 %#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("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 */ + ifpi_isac_init(sc); + + /* init the "HSCX" */ + avma1pp_bchannel_setup(sc->sc_unit, HSCX_CH_A, BPROT_NONE, 0); + + avma1pp_bchannel_setup(sc->sc_unit, HSCX_CH_B, BPROT_NONE, 0); + + /* can't use the normal B-Channel stuff */ + avma1pp_init_linktab(sc); + + /* set trace level */ + + sc->sc_trace = TRACE_OFF; + + sc->sc_state = ISAC_IDLE; + + sc->sc_ibuf = NULL; + sc->sc_ib = NULL; + sc->sc_ilen = 0; + + sc->sc_obuf = NULL; + sc->sc_op = NULL; + sc->sc_ol = 0; + sc->sc_freeflag = 0; + + sc->sc_obuf2 = NULL; + sc->sc_freeflag2 = 0; + +#if defined(__FreeBSD__) && __FreeBSD__ >=3 + callout_handle_init(&sc->sc_T3_callout); + callout_handle_init(&sc->sc_T4_callout); +#endif + + /* init higher protocol layers */ + + i4b_l1_mph_status_ind(L0IFPIUNIT(sc->sc_unit), STI_ATTACH, sc->sc_cardtyp, &avma1pp_l1mux_func); + + fail: + splx(s); + return(error); +} + +/* + * this is the real interrupt routine + */ +static void +avma1pp_hscx_intr(int h_chan, u_int stat, struct l1_softc *sc) +{ + register l1_bchan_state_t *chan = &sc->sc_chan[h_chan]; + int activity = -1; + u_int param = 0; + + NDBGL1(L1_H_IRQ, "%#x", stat); + + if((stat & HSCX_INT_XDU) && (chan->bprot != BPROT_NONE))/* xmit data underrun */ + { + chan->stat_XDU++; + NDBGL1(L1_H_XFRERR, "xmit data underrun"); + /* abort the transmission */ + sc->avma1pp_txl = 0; + sc->avma1pp_cmd |= HSCX_CMD_XRS; + AVMA1PPSETCMDLONG(param); + hscx_write_reg(h_chan, HSCX_STAT, param, sc); + sc->avma1pp_cmd &= ~HSCX_CMD_XRS; + AVMA1PPSETCMDLONG(param); + hscx_write_reg(h_chan, HSCX_STAT, param, sc); + + if (chan->out_mbuf_head != NULL) /* don't continue to transmit this buffer */ + { + i4b_Bfreembuf(chan->out_mbuf_head); + chan->out_mbuf_cur = chan->out_mbuf_head = NULL; + } + } + + /* + * The following is based on examination of the Linux driver. + * + * The logic here is different than with a "real" HSCX; all kinds + * of information (interrupt/status bits) are in stat. + * HSCX_INT_RPR indicates a receive interrupt + * HSCX_STAT_RDO indicates an overrun condition, abort - + * otherwise read the bytes ((stat & HSCX_STZT_RML_MASK) >> 8) + * HSCX_STAT_RME indicates end-of-frame and apparently any + * CRC/framing errors are only reported in this state. + * if ((stat & HSCX_STAT_CRCVFRRAB) != HSCX_STAT_CRCVFR) + * CRC/framing error + */ + + if(stat & HSCX_INT_RPR) + { + register int fifo_data_len; + int error = 0; + /* always have to read the FIFO, so use a scratch buffer */ + u_char scrbuf[HSCX_FIFO_LEN]; + + if(stat & HSCX_STAT_RDO) + { + chan->stat_RDO++; + 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 = ((stat & HSCX_STAT_RML_MASK) >> 8); + + if(fifo_data_len == 0) + fifo_data_len = sc->sc_bfifolen; + + /* ALWAYS read data from HSCX fifo */ + + HSCX_RDFIFO(h_chan, scrbuf, fifo_data_len); + chan->rxcount += fifo_data_len; + + /* all error conditions checked, now decide and take action */ + + if(error == 0) + { + if(chan->in_mbuf == NULL) + { + if((chan->in_mbuf = i4b_Bgetmbuf(BCH_MAX_DATALEN)) == NULL) + panic("L1 avma1pp_hscx_intr: RME, cannot allocate mbuf!\n"); + chan->in_cbptr = chan->in_mbuf->m_data; + chan->in_len = 0; + } + + if((chan->in_len + fifo_data_len) <= BCH_MAX_DATALEN) + { + /* OK to copy the data */ + bcopy(scrbuf, chan->in_cbptr, fifo_data_len); + chan->in_cbptr += fifo_data_len; + chan->in_len += fifo_data_len; + + /* setup mbuf data length */ + + chan->in_mbuf->m_len = chan->in_len; + chan->in_mbuf->m_pkthdr.len = chan->in_len; + + if(sc->sc_trace & TRACE_B_RX) + { + i4b_trace_hdr_t hdr; + hdr.unit = 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); + 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->isic_drvr_linktab->bch_rx_data_ready)(chan->isic_drvr_linktab->unit); + activity = ACT_RX; + + /* mark buffer ptr as unused */ + + chan->in_mbuf = NULL; + chan->in_cbptr = NULL; + chan->in_len = 0; + } + else + { + chan->stat_CRC++; + NDBGL1(L1_H_XFRERR, "CRC/RAB"); + if (chan->in_mbuf != NULL) + { + i4b_Bfreembuf(chan->in_mbuf); + chan->in_mbuf = NULL; + chan->in_cbptr = NULL; + chan->in_len = 0; + } + } + } + } /* END enough space in mbuf */ + else + { + if(chan->bprot == BPROT_NONE) + { + /* setup mbuf data length */ + + chan->in_mbuf->m_len = chan->in_len; + chan->in_mbuf->m_pkthdr.len = chan->in_len; + + if(sc->sc_trace & TRACE_B_RX) + { + i4b_trace_hdr_t hdr; + hdr.unit = 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); + 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 (!(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); + + /* alloc new buffer */ + + if((chan->in_mbuf = i4b_Bgetmbuf(BCH_MAX_DATALEN)) == NULL) + panic("L1 avma1pp_hscx_intr: RPF, cannot allocate new mbuf!\n"); + + /* setup new data ptr */ + + chan->in_cbptr = chan->in_mbuf->m_data; + + /* OK to copy the data */ + bcopy(scrbuf, chan->in_cbptr, fifo_data_len); + + chan->in_cbptr += fifo_data_len; + chan->in_len = fifo_data_len; + + chan->rxcount += fifo_data_len; + } + else + { + 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; + } + } + } /* if(error == 0) */ + else + { + /* land here for RDO */ + if (chan->in_mbuf != NULL) + { + i4b_Bfreembuf(chan->in_mbuf); + chan->in_mbuf = NULL; + chan->in_cbptr = NULL; + chan->in_len = 0; + } + sc->avma1pp_txl = 0; + sc->avma1pp_cmd |= HSCX_CMD_RRS; + AVMA1PPSETCMDLONG(param); + hscx_write_reg(h_chan, HSCX_STAT, param, sc); + sc->avma1pp_cmd &= ~HSCX_CMD_RRS; + AVMA1PPSETCMDLONG(param); + hscx_write_reg(h_chan, HSCX_STAT, param, sc); + } + } + + + /* transmit fifo empty, new data can be written to fifo */ + + if(stat & HSCX_INT_XPR) + { + /* + * for a description what is going on here, please have + * a look at isic_bchannel_start() in i4b_bchan.c ! + */ + + 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 */ + { + IF_DEQUEUE(&chan->tx_queue, chan->out_mbuf_head); + + if(chan->out_mbuf_head == NULL) + { + chan->state &= ~HSCX_TX_ACTIVE; + (*chan->isic_drvr_linktab->bch_tx_queue_empty)(chan->isic_drvr_linktab->unit); + } + else + { + chan->state |= HSCX_TX_ACTIVE; + chan->out_mbuf_cur = chan->out_mbuf_head; + chan->out_mbuf_cur_ptr = chan->out_mbuf_cur->m_data; + chan->out_mbuf_cur_len = chan->out_mbuf_cur->m_len; + + if(sc->sc_trace & TRACE_B_TX) + { + i4b_trace_hdr_t hdr; + hdr.unit = 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); + 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; + } + } + } + + avma1pp_hscx_fifo(chan, sc); + } + + /* call timeout handling routine */ + + if(activity == ACT_RX || activity == ACT_TX) + (*chan->isic_drvr_linktab->bch_activity)(chan->isic_drvr_linktab->unit, activity); +} + +/* + * this is the main routine which checks each channel and then calls + * the real interrupt routine as appropriate + */ +static void +avma1pp_hscx_int_handler(struct l1_softc *sc) +{ + u_int stat; + + /* has to be a u_int because the byte count is in the 2nd byte */ + stat = hscx_read_reg_int(0, HSCX_STAT, sc); + if (stat & HSCX_INT_MASK) + avma1pp_hscx_intr(0, stat, sc); + stat = hscx_read_reg_int(1, HSCX_STAT, sc); + if (stat & HSCX_INT_MASK) + avma1pp_hscx_intr(1, stat, sc); +} + +static void +avma1pp_disable(device_t 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(btag, bhandle, STAT0_OFFSET, ASL_RESET_ALL|ASL_TIMERDISABLE); +} + +static void +avma1pp_intr(void *xsc) +{ + 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"); + avma1pp_hscx_int_handler(sc); + } + if (!(stat & ASL_IRQ_ISAC)) + { + NDBGL1(L1_H_IRQ, "ISAC"); + ifpi_isac_intr(sc); + } +} + +static void +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; + + NDBGL1(L1_BCHAN, "unit=%d, channel=%d, %s", + sc->sc_unit, h_chan, activate ? "activate" : "deactivate"); + + if (activate == 0) + { + /* only deactivate if both channels are idle */ + if (sc->sc_chan[HSCX_CH_A].state != HSCX_IDLE || + sc->sc_chan[HSCX_CH_B].state != HSCX_IDLE) + { + return; + } + sc->avma1pp_cmd = HSCX_CMD_XRS|HSCX_CMD_RRS; + sc->avma1pp_prot = HSCX_MODE_TRANS; + AVMA1PPSETCMDLONG(param); + hscx_write_reg(h_chan, HSCX_STAT, param, sc); + return; + } + if(chan->bprot == BPROT_RHDLC) + { + NDBGL1(L1_BCHAN, "BPROT_RHDLC"); + + /* HDLC Frames, transparent mode 0 */ + sc->avma1pp_cmd = HSCX_CMD_XRS|HSCX_CMD_RRS; + sc->avma1pp_prot = HSCX_MODE_ITF_FLG; + AVMA1PPSETCMDLONG(param); + hscx_write_reg(h_chan, HSCX_STAT, param, sc); + sc->avma1pp_cmd = HSCX_CMD_XRS; + AVMA1PPSETCMDLONG(param); + hscx_write_reg(h_chan, HSCX_STAT, param, sc); + sc->avma1pp_cmd = 0; + } + else + { + NDBGL1(L1_BCHAN, "BPROT_NONE??"); + + /* Raw Telephony, extended transparent mode 1 */ + sc->avma1pp_cmd = HSCX_CMD_XRS|HSCX_CMD_RRS; + sc->avma1pp_prot = HSCX_MODE_TRANS; + AVMA1PPSETCMDLONG(param); + hscx_write_reg(h_chan, HSCX_STAT, param, sc); + sc->avma1pp_cmd = HSCX_CMD_XRS; + AVMA1PPSETCMDLONG(param); + hscx_write_reg(h_chan, HSCX_STAT, param, sc); + sc->avma1pp_cmd = 0; + } +} + +static void +avma1pp_bchannel_setup(int unit, int h_chan, int bprot, int activate) +{ +#ifdef __FreeBSD__ + 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[h_chan]; + + int s = SPLI4B(); + + if(activate == 0) + { + /* deactivation */ + chan->state = HSCX_IDLE; + avma1pp_hscx_init(sc, h_chan, activate); + } + + NDBGL1(L1_BCHAN, "unit=%d, channel=%d, %s", + sc->sc_unit, h_chan, activate ? "activate" : "deactivate"); + + /* general part */ + + chan->unit = sc->sc_unit; /* unit number */ + chan->channel = h_chan; /* B channel */ + chan->bprot = bprot; /* B channel protocol */ + chan->state = HSCX_IDLE; /* B channel state */ + + /* receiver part */ + + i4b_Bcleanifq(&chan->rx_queue); /* clean rx queue */ + + chan->rx_queue.ifq_maxlen = IFQ_MAXLEN; + + chan->rxcount = 0; /* reset rx counter */ + + i4b_Bfreembuf(chan->in_mbuf); /* clean rx mbuf */ + + chan->in_mbuf = NULL; /* reset mbuf ptr */ + chan->in_cbptr = NULL; /* reset mbuf curr ptr */ + chan->in_len = 0; /* reset mbuf data len */ + + /* transmitter part */ + + i4b_Bcleanifq(&chan->tx_queue); /* clean tx queue */ + + chan->tx_queue.ifq_maxlen = IFQ_MAXLEN; + + chan->txcount = 0; /* reset tx counter */ + + i4b_Bfreembuf(chan->out_mbuf_head); /* clean tx mbuf */ + + chan->out_mbuf_head = NULL; /* reset head mbuf ptr */ + chan->out_mbuf_cur = NULL; /* reset current mbuf ptr */ + chan->out_mbuf_cur_ptr = NULL; /* reset current mbuf data ptr */ + chan->out_mbuf_cur_len = 0; /* reset current mbuf data cnt */ + + if(activate != 0) + { + /* activation */ + avma1pp_hscx_init(sc, h_chan, activate); + chan->state |= HSCX_AVMA1PP_ACTIVE; + } + + splx(s); +} + +static void +avma1pp_bchannel_start(int unit, int h_chan) +{ +#ifdef __FreeBSD__ + struct l1_softc *sc = ifpi_scp[unit]; +#else + struct l1_softc *sc = isic_find_sc(unit); +#endif + register l1_bchan_state_t *chan = &sc->sc_chan[h_chan]; + int s; + int activity = -1; + + s = SPLI4B(); /* enter critical section */ + if(chan->state & HSCX_TX_ACTIVE) /* already running ? */ + { + splx(s); + return; /* yes, leave */ + } + + /* get next mbuf from queue */ + + IF_DEQUEUE(&chan->tx_queue, chan->out_mbuf_head); + + if(chan->out_mbuf_head == NULL) /* queue empty ? */ + { + splx(s); /* leave critical section */ + return; /* yes, exit */ + } + + /* init current mbuf values */ + + chan->out_mbuf_cur = chan->out_mbuf_head; + chan->out_mbuf_cur_len = chan->out_mbuf_cur->m_len; + chan->out_mbuf_cur_ptr = chan->out_mbuf_cur->m_data; + + /* activity indicator for timeout handling */ + + if(chan->bprot == BPROT_NONE) + { + if(!(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 |= HSCX_TX_ACTIVE; /* we start transmitting */ + + if(sc->sc_trace & TRACE_B_TX) /* if trace, send mbuf to trace dev */ + { + i4b_trace_hdr_t hdr; + hdr.unit = 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); + i4b_l1_trace_ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data); + } + + avma1pp_hscx_fifo(chan, sc); + + /* call timeout handling routine */ + + if(activity == ACT_RX || activity == ACT_TX) + (*chan->isic_drvr_linktab->bch_activity)(chan->isic_drvr_linktab->unit, activity); + + splx(s); +} + +/*---------------------------------------------------------------------------* + * return the address of isic drivers linktab + *---------------------------------------------------------------------------*/ +static isdn_link_t * +avma1pp_ret_linktab(int unit, int channel) +{ +#ifdef __FreeBSD__ + 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->isic_isdn_linktab); +} + +/*---------------------------------------------------------------------------* + * set the driver linktab in the b channel softc + *---------------------------------------------------------------------------*/ +static void +avma1pp_set_linktab(int unit, int channel, drvr_link_t *dlt) +{ +#ifdef __FreeBSD__ + 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->isic_drvr_linktab = dlt; +} + + +/*---------------------------------------------------------------------------* + * initialize our local linktab + *---------------------------------------------------------------------------*/ +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->isic_isdn_linktab; + + /* make sure the hardware driver is known to layer 4 */ + /* avoid overwriting if already set */ + if (ctrl_types[CTRL_PASSIVE].set_linktab == NULL) + { + ctrl_types[CTRL_PASSIVE].set_linktab = avma1pp_set_linktab; + ctrl_types[CTRL_PASSIVE].get_linktab = avma1pp_ret_linktab; + } + + /* local setup */ + lt->unit = sc->sc_unit; + lt->channel = HSCX_CH_A; + lt->bch_config = avma1pp_bchannel_setup; + lt->bch_tx_start = avma1pp_bchannel_start; + lt->bch_stat = avma1pp_bchannel_stat; + lt->tx_queue = &chan->tx_queue; + + /* used by non-HDLC data transfers, i.e. telephony drivers */ + lt->rx_queue = &chan->rx_queue; + + /* used by HDLC data transfers, i.e. ipr and isp drivers */ + lt->rx_mbuf = &chan->in_mbuf; + + chan = &sc->sc_chan[HSCX_CH_B]; + lt = &chan->isic_isdn_linktab; + + lt->unit = sc->sc_unit; + lt->channel = HSCX_CH_B; + lt->bch_config = avma1pp_bchannel_setup; + lt->bch_tx_start = avma1pp_bchannel_start; + lt->bch_stat = avma1pp_bchannel_stat; + lt->tx_queue = &chan->tx_queue; + + /* used by non-HDLC data transfers, i.e. telephony drivers */ + lt->rx_queue = &chan->rx_queue; + + /* used by HDLC data transfers, i.e. ipr and isp drivers */ + lt->rx_mbuf = &chan->in_mbuf; +} + +/* + * use this instead of isic_bchannel_stat in i4b_bchan.c because it's static + */ +static void +avma1pp_bchannel_stat(int unit, int h_chan, bchan_statistics_t *bsp) +{ +#ifdef __FreeBSD__ + 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[h_chan]; + int s; + + s = SPLI4B(); + + bsp->outbytes = chan->txcount; + bsp->inbytes = chan->rxcount; + + chan->txcount = 0; + chan->rxcount = 0; + + splx(s); +} + +/*---------------------------------------------------------------------------* + * fill HSCX fifo with data from the current mbuf + * Put this here until it can go into i4b_hscx.c + *---------------------------------------------------------------------------*/ +static int +avma1pp_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]; + + len = 0; + + /* + * fill the HSCX tx fifo with data from the current mbuf. if + * current mbuf holds less data than HSCX fifo length, try to + * get the next mbuf from (a possible) mbuf chain. if there is + * not enough data in a single mbuf or in a chain, then this + * is the last mbuf and we tell the HSCX that it has to send + * CRC and closing flag + */ + + while(chan->out_mbuf_cur && len != sc->sc_bfifolen) + { + nextlen = min(chan->out_mbuf_cur_len, sc->sc_bfifolen - len); + +#ifdef NOTDEF + printf("i:mh=%p, mc=%p, mcp=%p, mcl=%d l=%d nl=%d # ", + chan->out_mbuf_head, + chan->out_mbuf_cur, + chan->out_mbuf_cur_ptr, + chan->out_mbuf_cur_len, + len, + nextlen); +#endif + + 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]; + + 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 = 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); + 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; + } + } + } + /* write what we have from the scratch buf to the HSCX fifo */ + if (len != 0) + HSCX_WRFIFO(chan->channel, scrbuf, len); + return(cmd); +} + +/*---------------------------------------------------------------------------* + * 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/ifpnp/i4b_ifpnp_avm.c b/sys/i4b/layer1/ifpnp/i4b_ifpnp_avm.c new file mode 100644 index 0000000..b1d3c0e --- /dev/null +++ b/sys/i4b/layer1/ifpnp/i4b_ifpnp_avm.c @@ -0,0 +1,1390 @@ +/* + * 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 + * 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_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: [Mon May 29 15:24:43 2000] + * + *---------------------------------------------------------------------------*/ + +#include "ifpnp.h" +#include "opt_i4b.h" + +#if (NIFPNP > 0) + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include + +/* 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 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 isdn_link_t * avm_pnp_ret_linktab(int, int); +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 + *---------------------------------------------------------------------------*/ + +/* + * 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 +#define ISAC_HI_REG_OFFSET 0x06 + +/* offset higher than this goes to the HI register set */ +#define MAX_LO_REG_OFFSET 0x2f + +/* mask for the offset */ +#define ISAC_REGSET_MASK 0x0f + +/* the offset from the base to the ISAC registers */ +#define ISAC_REG_OFFSET 0x10 + +/* the offset from the base to the ISAC FIFO */ +#define ISAC_FIFO 0x02 + +/* not really the HSCX, but sort of */ +#define HSCX_FIFO 0x00 +#define HSCX_STAT 0x04 + +/* + * AVM PnP Status Latch 0 read only bits + */ +#define ASL_IRQ_ISAC 0x01 /* ISAC interrupt, active low */ +#define ASL_IRQ_HSCX 0x02 /* HSX interrupt, active low */ +#define ASL_IRQ_TIMER 0x04 /* Timer interrupt, active low */ +#define ASL_IRQ_BCHAN ASL_IRQ_HSCX +/* actually active LOW */ +#define ASL_IRQ_Pending (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 */ +#define ASL_TESTBIT 0x10 /* active high */ + +/* + * AVM Status Latch 1 write only bits + */ +#define ASL1_INTSEL 0x0f /* active high */ +#define ASL1_ENABLE_IOM 0x80 /* active high */ + +/* + * "HSCX" mode bits + */ +#define HSCX_MODE_ITF_FLG 0x01 +#define HSCX_MODE_TRANS 0x02 +#define HSCX_MODE_CCR_7 0x04 +#define HSCX_MODE_CCR_16 0x08 +#define HSCX_MODE_TESTLOOP 0x80 + +/* + * "HSCX" status bits + */ +#define HSCX_STAT_RME 0x01 +#define HSCX_STAT_RDO 0x10 +#define HSCX_STAT_CRCVFRRAB 0x0E +#define HSCX_STAT_CRCVFR 0x06 +#define HSCX_STAT_RML_MASK 0x3f00 + +/* + * "HSCX" interrupt bits + */ +#define HSCX_INT_XPR 0x80 +#define HSCX_INT_XDU 0x40 +#define HSCX_INT_RPR 0x20 +#define HSCX_INT_MASK 0xE0 + +/* + * "HSCX" command bits + */ +#define HSCX_CMD_XRS 0x80 +#define HSCX_CMD_XME 0x01 +#define HSCX_CMD_RRS 0x20 +#define HSCX_CMD_XML_MASK 0x3f00 + +/* + * 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_AVMA1PP_ACTIVE 0x1000 + +/*---------------------------------------------------------------------------* + * AVM read fifo routines + *---------------------------------------------------------------------------*/ + +static void +avm_pnp_read_fifo(struct l1_softc *sc, int what, void *buf, size_t size) +{ + 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(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; + } +} + +static void +hscx_read_fifo(int chan, void *buf, size_t len, struct l1_softc *sc) +{ + 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]); + + bus_space_write_1(btag, bhandle, ADDR_REG_OFFSET, chan); + ip = (u_int8_t *)buf; + cnt = 0; + while (cnt++ < len) + { + *ip++ = bus_space_read_1(btag, bhandle, ISAC_REG_OFFSET); + } +} + +/*---------------------------------------------------------------------------* + * AVM write fifo routines + *---------------------------------------------------------------------------*/ +static void +avm_pnp_write_fifo(struct l1_softc *sc, int what, void *buf, size_t size) +{ + 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(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; + } +} + +static void +hscx_write_fifo(int chan, void *buf, size_t len, struct l1_softc *sc) +{ + 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) + { + if (Bchan->bprot != BPROT_NONE) + sc->avma1pp_cmd |= HSCX_CMD_XME; + } + if (len != sc->sc_bfifolen) + sc->avma1pp_txl = len; + + hscx_write_reg(chan, HSCX_STAT, sc, 3); + + ip = (u_int8_t *)buf; + cnt = 0; + while (cnt++ < len) + { + bus_space_write_1(btag, bhandle, ISAC_REG_OFFSET, *ip++); + } +} + +/*---------------------------------------------------------------------------* + * AVM write register routines + *---------------------------------------------------------------------------*/ + +static void +avm_pnp_write_reg(struct l1_softc *sc, int what, bus_size_t offs, u_int8_t data) +{ + u_char reg_bank; + 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; + } +} + +static void +hscx_write_reg(int chan, u_int off, struct l1_softc *sc, u_int which) +{ + 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 */ + 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_int8_t val, struct l1_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]); + + /* point at the correct channel */ + 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_int8_t +avm_pnp_read_reg(struct l1_softc *sc, int what, bus_size_t offs) +{ + u_char reg_bank; + 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_int +hscx_read_reg(int chan, u_int off, struct l1_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]); + + /* point at the correct channel */ + 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 } +}; + +/*---------------------------------------------------------------------------* + * avm_pnp_probe - probe for a card + *---------------------------------------------------------------------------*/ +static int +avm_pnp_probe(dev) + device_t dev; +{ + 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 */ + + for(ids = ifpnp_ids; ids->vend_id != 0; ids++) + { + if(vend_id == ids->vend_id) + { + string = ids->id_str; + break; + } + } + + if(string) /* set name if we have one */ + { + device_set_desc(dev, string); /* set description */ + return 0; + } + else + { + return ENXIO; + } +} + +/*---------------------------------------------------------------------------* + * 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; + + 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); + } + + ifpnp_scp[unit] = sc; + + + /* 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("avm_pnp_attach: Couldn't get my io_base.\n"); + return ENXIO; + } + 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]); + + /* 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("avm_pnp%d: Could not get irq.\n",unit); + error = ENXIO; + goto fail; + } + + /* 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 */ + + sc->clearirq = NULL; + sc->readreg = avm_pnp_read_reg; + sc->writereg = avm_pnp_write_reg; + + sc->readfifo = avm_pnp_read_fifo; + sc->writefifo = avm_pnp_write_fifo; + + /* setup card type */ + + sc->sc_cardtyp = CARD_TYPEP_AVM_PNP; + + /* setup IOM bus type */ + + sc->sc_bustyp = BUS_TYPE_IOM2; + + /* set up some other miscellaneous things */ + sc->sc_ipac = 0; + 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); + v = ISAC_READ(I_MODE); + v = ISAC_READ(I_ADF2); + v = ISAC_READ(I_ISTA); + if (v & ISAC_ISTA_EXI) + { + v = ISAC_READ(I_EXIR); + } + v = ISAC_READ(I_CIRR); + ISAC_WRITE(I_MASK, 0xff); + /* the Linux driver does this to clear any pending HSCX interrupts */ + v = hscx_read_reg(0, HSCX_STAT, sc); + v = hscx_read_reg(1, HSCX_STAT, sc); + + bus_space_write_1(btag, bhandle, STAT0_OFFSET, ASL_RESET_ALL|ASL_TIMERDISABLE); + DELAY(SEC_DELAY/100); /* 10 ms */ + bus_space_write_1(btag, bhandle, STAT1_OFFSET, ASL1_ENABLE_IOM|sc->sc_irq); + DELAY(SEC_DELAY/100); /* 10 ms */ + bus_space_write_1(btag, bhandle, STAT0_OFFSET, ASL_TIMERRESET|ASL_ENABLE_INT|ASL_TIMERDISABLE); + DELAY(SEC_DELAY/100); /* 10 ms */ + + 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 */ + ifpnp_isac_init(sc); + + /* init the "HSCX" */ + avm_pnp_bchannel_setup(sc->sc_unit, HSCX_CH_A, BPROT_NONE, 0); + + avm_pnp_bchannel_setup(sc->sc_unit, HSCX_CH_B, BPROT_NONE, 0); + + /* can't use the normal B-Channel stuff */ + avm_pnp_init_linktab(sc); + + /* set trace level */ + + sc->sc_trace = TRACE_OFF; + + sc->sc_state = ISAC_IDLE; + + sc->sc_ibuf = NULL; + sc->sc_ib = NULL; + sc->sc_ilen = 0; + + sc->sc_obuf = NULL; + sc->sc_op = NULL; + sc->sc_ol = 0; + sc->sc_freeflag = 0; + + sc->sc_obuf2 = NULL; + sc->sc_freeflag2 = 0; + + callout_handle_init(&sc->sc_T3_callout); + callout_handle_init(&sc->sc_T4_callout); + + /* init higher protocol layers */ + + i4b_l1_mph_status_ind(L0IFPNPUNIT(sc->sc_unit), STI_ATTACH, sc->sc_cardtyp, &avm_pnp_l1mux_func); + + fail: + splx(s); + return(error); +} + +/* + * this is the real interrupt routine + */ +static void +avm_pnp_hscx_intr(int h_chan, u_int stat, u_int cnt, struct l1_softc *sc) +{ + register l1_bchan_state_t *chan = &sc->sc_chan[h_chan]; + int activity = -1; + + NDBGL1(L1_H_IRQ, "%#x", stat); + + if((stat & HSCX_INT_XDU) && (chan->bprot != BPROT_NONE))/* xmit data underrun */ + { + chan->stat_XDU++; + NDBGL1(L1_H_XFRERR, "xmit data underrun"); + /* abort the transmission */ + sc->avma1pp_txl = 0; + sc->avma1pp_cmd |= HSCX_CMD_XRS; + hscx_write_reg(h_chan, HSCX_STAT, sc, 1); + sc->avma1pp_cmd &= ~HSCX_CMD_XRS; + hscx_write_reg(h_chan, HSCX_STAT, sc, 1); + + if (chan->out_mbuf_head != NULL) /* don't continue to transmit this buffer */ + { + i4b_Bfreembuf(chan->out_mbuf_head); + chan->out_mbuf_cur = chan->out_mbuf_head = NULL; + } + } + + /* + * The following is based on examination of the Linux driver. + * + * The logic here is different than with a "real" HSCX; all kinds + * of information (interrupt/status bits) are in stat. + * HSCX_INT_RPR indicates a receive interrupt + * HSCX_STAT_RDO indicates an overrun condition, abort - + * otherwise read the bytes ((stat & HSCX_STZT_RML_MASK) >> 8) + * HSCX_STAT_RME indicates end-of-frame and apparently any + * CRC/framing errors are only reported in this state. + * if ((stat & HSCX_STAT_CRCVFRRAB) != HSCX_STAT_CRCVFR) + * CRC/framing error + */ + + if(stat & HSCX_INT_RPR) + { + register int fifo_data_len; + int error = 0; + /* always have to read the FIFO, so use a scratch buffer */ + u_char scrbuf[HSCX_FIFO_LEN]; + + if(stat & HSCX_STAT_RDO) + { + chan->stat_RDO++; + 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) + fifo_data_len = sc->sc_bfifolen; + + /* ALWAYS read data from HSCX fifo */ + + HSCX_RDFIFO(h_chan, scrbuf, fifo_data_len); + chan->rxcount += fifo_data_len; + + /* all error conditions checked, now decide and take action */ + + if(error == 0) + { + if(chan->in_mbuf == NULL) + { + if((chan->in_mbuf = i4b_Bgetmbuf(BCH_MAX_DATALEN)) == NULL) + panic("L1 avm_pnp_hscx_intr: RME, cannot allocate mbuf!\n"); + chan->in_cbptr = chan->in_mbuf->m_data; + chan->in_len = 0; + } + + if((chan->in_len + fifo_data_len) <= BCH_MAX_DATALEN) + { + /* OK to copy the data */ + bcopy(scrbuf, chan->in_cbptr, fifo_data_len); + chan->in_cbptr += fifo_data_len; + chan->in_len += fifo_data_len; + + /* setup mbuf data length */ + + chan->in_mbuf->m_len = chan->in_len; + chan->in_mbuf->m_pkthdr.len = chan->in_len; + + if(sc->sc_trace & TRACE_B_RX) + { + i4b_trace_hdr_t hdr; + hdr.unit = 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); + 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->isic_drvr_linktab->bch_rx_data_ready)(chan->isic_drvr_linktab->unit); + activity = ACT_RX; + + /* mark buffer ptr as unused */ + + chan->in_mbuf = NULL; + chan->in_cbptr = NULL; + chan->in_len = 0; + } + else + { + chan->stat_CRC++; + NDBGL1(L1_H_XFRERR, "CRC/RAB"); + if (chan->in_mbuf != NULL) + { + i4b_Bfreembuf(chan->in_mbuf); + chan->in_mbuf = NULL; + chan->in_cbptr = NULL; + chan->in_len = 0; + } + } + } + } /* END enough space in mbuf */ + else + { + if(chan->bprot == BPROT_NONE) + { + /* setup mbuf data length */ + + chan->in_mbuf->m_len = chan->in_len; + chan->in_mbuf->m_pkthdr.len = chan->in_len; + + if(sc->sc_trace & TRACE_B_RX) + { + i4b_trace_hdr_t hdr; + hdr.unit = 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); + 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 (!(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); + + /* alloc new buffer */ + + if((chan->in_mbuf = i4b_Bgetmbuf(BCH_MAX_DATALEN)) == NULL) + panic("L1 avm_pnp_hscx_intr: RPF, cannot allocate new mbuf!\n"); + + /* setup new data ptr */ + + chan->in_cbptr = chan->in_mbuf->m_data; + + /* OK to copy the data */ + bcopy(scrbuf, chan->in_cbptr, fifo_data_len); + + chan->in_cbptr += fifo_data_len; + chan->in_len = fifo_data_len; + + chan->rxcount += fifo_data_len; + } + else + { + 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; + } + } + } /* if(error == 0) */ + else + { + /* land here for RDO */ + if (chan->in_mbuf != NULL) + { + i4b_Bfreembuf(chan->in_mbuf); + chan->in_mbuf = NULL; + chan->in_cbptr = NULL; + chan->in_len = 0; + } + sc->avma1pp_txl = 0; + sc->avma1pp_cmd |= HSCX_CMD_RRS; + hscx_write_reg(h_chan, HSCX_STAT, sc, 1); + sc->avma1pp_cmd &= ~HSCX_CMD_RRS; + hscx_write_reg(h_chan, HSCX_STAT, sc, 1); + } + } + + + /* transmit fifo empty, new data can be written to fifo */ + + if(stat & HSCX_INT_XPR) + { + /* + * for a description what is going on here, please have + * a look at isic_bchannel_start() in i4b_bchan.c ! + */ + + 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 */ + { + IF_DEQUEUE(&chan->tx_queue, chan->out_mbuf_head); + + if(chan->out_mbuf_head == NULL) + { + chan->state &= ~HSCX_TX_ACTIVE; + (*chan->isic_drvr_linktab->bch_tx_queue_empty)(chan->isic_drvr_linktab->unit); + } + else + { + chan->state |= HSCX_TX_ACTIVE; + chan->out_mbuf_cur = chan->out_mbuf_head; + chan->out_mbuf_cur_ptr = chan->out_mbuf_cur->m_data; + chan->out_mbuf_cur_len = chan->out_mbuf_cur->m_len; + + if(sc->sc_trace & TRACE_B_TX) + { + i4b_trace_hdr_t hdr; + hdr.unit = 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); + 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; + } + } + } + + avm_pnp_hscx_fifo(chan, sc); + } + + /* call timeout handling routine */ + + if(activity == ACT_RX || activity == ACT_TX) + (*chan->isic_drvr_linktab->bch_activity)(chan->isic_drvr_linktab->unit, activity); +} + +/* + * this is the main routine which checks each channel and then calls + * the real interrupt routine as appropriate + */ +static void +avm_pnp_hscx_int_handler(struct l1_softc *sc) +{ + u_char stat = 0; + u_char cnt = 0; + + stat = hscx_read_reg(0, HSCX_STAT, sc); + if (stat & HSCX_INT_RPR) + cnt = hscx_read_reg(0, HSCX_STAT+1, sc); + if (stat & HSCX_INT_MASK) + avm_pnp_hscx_intr(0, stat, cnt, sc); + + cnt = 0; + stat = hscx_read_reg(1, HSCX_STAT, sc); + if (stat & HSCX_INT_RPR) + cnt = hscx_read_reg(1, HSCX_STAT+1, sc); + if (stat & HSCX_INT_MASK) + avm_pnp_hscx_intr(1, stat, cnt, sc); +} + +static void +avm_pnp_intr(void *xsc) +{ + 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); + } +} + +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) + { + /* only deactivate if both channels are idle */ + if (sc->sc_chan[HSCX_CH_A].state != HSCX_IDLE || + sc->sc_chan[HSCX_CH_B].state != HSCX_IDLE) + { + return; + } + sc->avma1pp_cmd = HSCX_CMD_XRS|HSCX_CMD_RRS; + sc->avma1pp_prot = HSCX_MODE_TRANS; + hscx_write_reg(h_chan, HSCX_STAT, sc, 5); + return; + } + if(chan->bprot == BPROT_RHDLC) + { + NDBGL1(L1_BCHAN, "BPROT_RHDLC"); + + /* HDLC Frames, transparent mode 0 */ + sc->avma1pp_cmd = HSCX_CMD_XRS|HSCX_CMD_RRS; + sc->avma1pp_prot = HSCX_MODE_ITF_FLG; + hscx_write_reg(h_chan, HSCX_STAT, sc, 5); + sc->avma1pp_cmd = HSCX_CMD_XRS; + hscx_write_reg(h_chan, HSCX_STAT, sc, 1); + sc->avma1pp_cmd = 0; + } + else + { + NDBGL1(L1_BCHAN, "BPROT_NONE??"); + + /* Raw Telephony, extended transparent mode 1 */ + sc->avma1pp_cmd = HSCX_CMD_XRS|HSCX_CMD_RRS; + sc->avma1pp_prot = HSCX_MODE_TRANS; + hscx_write_reg(h_chan, HSCX_STAT, sc, 5); + sc->avma1pp_cmd = HSCX_CMD_XRS; + hscx_write_reg(h_chan, HSCX_STAT, sc, 1); + sc->avma1pp_cmd = 0; + } +} + +static void +avm_pnp_bchannel_setup(int unit, int h_chan, int bprot, int activate) +{ + struct 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_IDLE; + avm_pnp_hscx_init(sc, h_chan, activate); + } + + NDBGL1(L1_BCHAN, "unit=%d, channel=%d, %s", + sc->sc_unit, h_chan, activate ? "activate" : "deactivate"); + + /* general part */ + + chan->unit = sc->sc_unit; /* unit number */ + chan->channel = h_chan; /* B channel */ + chan->bprot = bprot; /* B channel protocol */ + chan->state = HSCX_IDLE; /* B channel state */ + + /* receiver part */ + + i4b_Bcleanifq(&chan->rx_queue); /* clean rx queue */ + + chan->rx_queue.ifq_maxlen = IFQ_MAXLEN; + + chan->rxcount = 0; /* reset rx counter */ + + i4b_Bfreembuf(chan->in_mbuf); /* clean rx mbuf */ + + chan->in_mbuf = NULL; /* reset mbuf ptr */ + chan->in_cbptr = NULL; /* reset mbuf curr ptr */ + chan->in_len = 0; /* reset mbuf data len */ + + /* transmitter part */ + + i4b_Bcleanifq(&chan->tx_queue); /* clean tx queue */ + + chan->tx_queue.ifq_maxlen = IFQ_MAXLEN; + + chan->txcount = 0; /* reset tx counter */ + + i4b_Bfreembuf(chan->out_mbuf_head); /* clean tx mbuf */ + + chan->out_mbuf_head = NULL; /* reset head mbuf ptr */ + chan->out_mbuf_cur = NULL; /* reset current mbuf ptr */ + chan->out_mbuf_cur_ptr = NULL; /* reset current mbuf data ptr */ + chan->out_mbuf_cur_len = 0; /* reset current mbuf data cnt */ + + if(activate != 0) + { + /* activation */ + avm_pnp_hscx_init(sc, h_chan, activate); + chan->state |= HSCX_AVMA1PP_ACTIVE; + } + + splx(s); +} + +static void +avm_pnp_bchannel_start(int unit, int 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; + + s = SPLI4B(); /* enter critical section */ + if(chan->state & HSCX_TX_ACTIVE) /* already running ? */ + { + splx(s); + return; /* yes, leave */ + } + + /* get next mbuf from queue */ + + IF_DEQUEUE(&chan->tx_queue, chan->out_mbuf_head); + + if(chan->out_mbuf_head == NULL) /* queue empty ? */ + { + splx(s); /* leave critical section */ + return; /* yes, exit */ + } + + /* init current mbuf values */ + + chan->out_mbuf_cur = chan->out_mbuf_head; + chan->out_mbuf_cur_len = chan->out_mbuf_cur->m_len; + chan->out_mbuf_cur_ptr = chan->out_mbuf_cur->m_data; + + /* activity indicator for timeout handling */ + + if(chan->bprot == BPROT_NONE) + { + if(!(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 |= HSCX_TX_ACTIVE; /* we start transmitting */ + + if(sc->sc_trace & TRACE_B_TX) /* if trace, send mbuf to trace dev */ + { + i4b_trace_hdr_t hdr; + hdr.unit = 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); + i4b_l1_trace_ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data); + } + + avm_pnp_hscx_fifo(chan, sc); + + /* call timeout handling routine */ + + if(activity == ACT_RX || activity == ACT_TX) + (*chan->isic_drvr_linktab->bch_activity)(chan->isic_drvr_linktab->unit, activity); + + splx(s); +} + +/*---------------------------------------------------------------------------* + * return the address of isic drivers linktab + *---------------------------------------------------------------------------*/ +static isdn_link_t * +avm_pnp_ret_linktab(int unit, int channel) +{ + struct l1_softc *sc = ifpnp_scp[unit]; + l1_bchan_state_t *chan = &sc->sc_chan[channel]; + + return(&chan->isic_isdn_linktab); +} + +/*---------------------------------------------------------------------------* + * set the driver linktab in the b channel softc + *---------------------------------------------------------------------------*/ +static void +avm_pnp_set_linktab(int unit, int channel, drvr_link_t *dlt) +{ + struct l1_softc *sc = ifpnp_scp[unit]; + l1_bchan_state_t *chan = &sc->sc_chan[channel]; + + chan->isic_drvr_linktab = dlt; +} + + +/*---------------------------------------------------------------------------* + * initialize our local linktab + *---------------------------------------------------------------------------*/ +static void +avm_pnp_init_linktab(struct l1_softc *sc) +{ + 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 */ + if (ctrl_types[CTRL_PASSIVE].set_linktab == NULL) + { + ctrl_types[CTRL_PASSIVE].set_linktab = avm_pnp_set_linktab; + ctrl_types[CTRL_PASSIVE].get_linktab = avm_pnp_ret_linktab; + } + + /* local setup */ + lt->unit = sc->sc_unit; + lt->channel = HSCX_CH_A; + lt->bch_config = avm_pnp_bchannel_setup; + lt->bch_tx_start = avm_pnp_bchannel_start; + lt->bch_stat = avm_pnp_bchannel_stat; + lt->tx_queue = &chan->tx_queue; + + /* used by non-HDLC data transfers, i.e. telephony drivers */ + lt->rx_queue = &chan->rx_queue; + + /* used by HDLC data transfers, i.e. ipr and isp drivers */ + lt->rx_mbuf = &chan->in_mbuf; + + chan = &sc->sc_chan[HSCX_CH_B]; + lt = &chan->isic_isdn_linktab; + + lt->unit = sc->sc_unit; + lt->channel = HSCX_CH_B; + lt->bch_config = avm_pnp_bchannel_setup; + lt->bch_tx_start = avm_pnp_bchannel_start; + lt->bch_stat = avm_pnp_bchannel_stat; + lt->tx_queue = &chan->tx_queue; + + /* used by non-HDLC data transfers, i.e. telephony drivers */ + lt->rx_queue = &chan->rx_queue; + + /* used by HDLC data transfers, i.e. ipr and isp drivers */ + lt->rx_mbuf = &chan->in_mbuf; +} + +/* + * use this instead of isic_bchannel_stat in i4b_bchan.c because it's static + */ +static void +avm_pnp_bchannel_stat(int unit, int h_chan, bchan_statistics_t *bsp) +{ + struct l1_softc *sc = ifpnp_scp[unit]; + l1_bchan_state_t *chan = &sc->sc_chan[h_chan]; + int s; + + s = SPLI4B(); + + bsp->outbytes = chan->txcount; + bsp->inbytes = chan->rxcount; + + chan->txcount = 0; + chan->rxcount = 0; + + splx(s); +} + +/*---------------------------------------------------------------------------* + * fill HSCX fifo with data from the current mbuf + * Put this here until it can go into i4b_hscx.c + *---------------------------------------------------------------------------*/ +static int +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]; + + len = 0; + + /* + * fill the HSCX tx fifo with data from the current mbuf. if + * current mbuf holds less data than HSCX fifo length, try to + * get the next mbuf from (a possible) mbuf chain. if there is + * not enough data in a single mbuf or in a chain, then this + * is the last mbuf and we tell the HSCX that it has to send + * CRC and closing flag + */ + + while(chan->out_mbuf_cur && len != sc->sc_bfifolen) + { + nextlen = min(chan->out_mbuf_cur_len, sc->sc_bfifolen - len); + +#ifdef NOTDEF + printf("i:mh=%p, mc=%p, mcp=%p, mcl=%d l=%d nl=%d # ", + chan->out_mbuf_head, + chan->out_mbuf_cur, + chan->out_mbuf_cur_ptr, + chan->out_mbuf_cur_len, + len, + nextlen); +#endif + + 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]; + + 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 = 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); + 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; + } + } + } + /* write what we have from the scratch buf to the HSCX fifo */ + if (len != 0) + HSCX_WRFIFO(chan->channel, scrbuf, len); + return(cmd); +} + +/*---------------------------------------------------------------------------* + * ifpnp - ISAC interrupt routine + *---------------------------------------------------------------------------*/ +static void +ifpnp_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) + ifpnp_isac_irq(sc, isac_irq_stat); /* isac handler */ + else + break; + } + + ISAC_WRITE(I_MASK, 0xff); + + DELAY(100); + + ISAC_WRITE(I_MASK, ISAC_IMASK); +} + +/*---------------------------------------------------------------------------* + * ifpnp_recover - try to recover from irq lockup + *---------------------------------------------------------------------------*/ +void +ifpnp_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 /* 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 + +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 +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include + +#include + +#include +#include +#include + +#include + +#include +#include + +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 +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include + +#include + +#include + +#include +#include + +/*---------------------------------------------------------------------------* + * + * 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 +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include + +#include + +#include + +#include + +#include + +#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 + +/*---------------------------------------------------------------------------* + * 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 +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +/*---------------------------------------------------------------------------* + * 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 + + +/* 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 +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +/*---------------------------------------------------------------------------* + * 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 +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include + +/*---------------------------------------------------------------------------* + * 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 -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#ifdef __FreeBSD__ -#include -#else -#include -#endif - -#include - -#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 -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -#ifdef __FreeBSD__ -#include -#include -#else -#include -#include -#endif - -#include -#include -#include -#include - -#include -#include - -#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/isic/i4b_asuscom_ipac.c b/sys/i4b/layer1/isic/i4b_asuscom_ipac.c new file mode 100644 index 0000000..5d696c1 --- /dev/null +++ b/sys/i4b/layer1/isic/i4b_asuscom_ipac.c @@ -0,0 +1,248 @@ +/* + * Copyright (c) 1999 Ari Suutari. 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 + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + *--------------------------------------------------------------------------- + * + * isic - I4B Siemens ISDN Chipset Driver for Asuscom ISDNlink 128K PnP + * ===================================================================== + * + * This driver works with Asuscom ISDNlink 128K PnP ISA adapter, + * which is based on Siemens IPAC chip (my card probes as ASU1690). + * Older Asuscom ISA cards are based on different chipset + * (containing two chips) - for those cards, one might want + * to try the Dynalink driver. + * + * This driver is heavily based on ELSA Quickstep 1000pro PCI + * driver written by Hellmuth Michaelis. Card initialization + * code is modeled after Linux i4l driver written by Karsten + * Keil. + * + * $Id: i4b_asuscom_ipac.c,v 1.3 2000/05/29 15:41:41 hm Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Mon May 29 16:41:56 2000] + * + *---------------------------------------------------------------------------*/ + +#include "isic.h" +#include "opt_i4b.h" + +#if (NISIC > 0) && defined (ASUSCOM_IPAC) + +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include + +#include +/* #include */ +#include + +#include +#include +#include +#include + +/* masks for register encoded in base addr */ + +#define ASI_BASE_MASK 0x0ffff +#define ASI_OFF_MASK 0xf0000 + +/* register id's to be encoded in base addr */ + +#define ASI_IDISAC 0x00000 +#define ASI_IDHSCXA 0x10000 +#define ASI_IDHSCXB 0x20000 +#define ASI_IDIPAC 0x40000 + +/* offsets from base address */ + +#define ASI_OFF_ALE 0x00 +#define ASI_OFF_RW 0x01 + +/*---------------------------------------------------------------------------* + * Asuscom ISDNlink 128K ISAC get fifo routine + *---------------------------------------------------------------------------*/ +static void +asi_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,ASI_OFF_ALE,IPAC_ISAC_OFF); + bus_space_read_multi_1(t,h,ASI_OFF_RW,buf,size); + break; + case ISIC_WHAT_HSCXA: + bus_space_write_1(t,h,ASI_OFF_ALE,IPAC_HSCXA_OFF); + bus_space_read_multi_1(t,h,ASI_OFF_RW,buf,size); + break; + case ISIC_WHAT_HSCXB: + bus_space_write_1(t,h,ASI_OFF_ALE,IPAC_HSCXB_OFF); + bus_space_read_multi_1(t,h,ASI_OFF_RW,buf,size); + break; + } +} + +/*---------------------------------------------------------------------------* + * Asuscom ISDNlink 128K ISAC put fifo routine + *---------------------------------------------------------------------------*/ +static void +asi_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,ASI_OFF_ALE,IPAC_ISAC_OFF); + bus_space_write_multi_1(t,h,ASI_OFF_RW,buf,size); + break; + case ISIC_WHAT_HSCXA: + bus_space_write_1(t,h,ASI_OFF_ALE,IPAC_HSCXA_OFF); + bus_space_write_multi_1(t,h,ASI_OFF_RW,buf,size); + break; + case ISIC_WHAT_HSCXB: + bus_space_write_1(t,h,ASI_OFF_ALE,IPAC_HSCXB_OFF); + bus_space_write_multi_1(t,h,ASI_OFF_RW,buf,size); + break; + } +} + +/*---------------------------------------------------------------------------* + * Asuscom ISDNlink 128K ISAC put register routine + *---------------------------------------------------------------------------*/ +static void +asi_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,ASI_OFF_ALE,reg+IPAC_ISAC_OFF); + bus_space_write_1(t,h,ASI_OFF_RW,data); + break; + case ISIC_WHAT_HSCXA: + bus_space_write_1(t,h,ASI_OFF_ALE,reg+IPAC_HSCXA_OFF); + bus_space_write_1(t,h,ASI_OFF_RW,data); + break; + case ISIC_WHAT_HSCXB: + bus_space_write_1(t,h,ASI_OFF_ALE,reg+IPAC_HSCXB_OFF); + bus_space_write_1(t,h,ASI_OFF_RW,data); + break; + case ISIC_WHAT_IPAC: + bus_space_write_1(t,h,ASI_OFF_ALE,reg+IPAC_IPAC_OFF); + bus_space_write_1(t,h,ASI_OFF_RW,data); + break; + } +} + +/*---------------------------------------------------------------------------* + * Asuscom ISDNlink 128K ISAC get register routine + *---------------------------------------------------------------------------*/ +static u_int8_t +asi_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,ASI_OFF_ALE,reg+IPAC_ISAC_OFF); + return bus_space_read_1(t,h,ASI_OFF_RW); + case ISIC_WHAT_HSCXA: + bus_space_write_1(t,h,ASI_OFF_ALE,reg+IPAC_HSCXA_OFF); + return bus_space_read_1(t,h,ASI_OFF_RW); + case ISIC_WHAT_HSCXB: + bus_space_write_1(t,h,ASI_OFF_ALE,reg+IPAC_HSCXB_OFF); + return bus_space_read_1(t,h,ASI_OFF_RW); + case ISIC_WHAT_IPAC: + bus_space_write_1(t,h,ASI_OFF_ALE,reg+IPAC_IPAC_OFF); + return bus_space_read_1(t,h,ASI_OFF_RW); + default: + return 0; + } +} + +/*---------------------------------------------------------------------------* + * isic_attach_siemens_isurf - attach for Asuscom ISDNlink 128K + *---------------------------------------------------------------------------*/ +int +isic_attach_asi(device_t dev) +{ + int unit = device_get_unit(dev); + struct l1_softc *sc = &l1_sc[unit]; + + /* setup access routines */ + + sc->clearirq = NULL; + sc->readreg = asi_read_reg; + sc->writereg = asi_write_reg; + + sc->readfifo = asi_read_fifo; + sc->writefifo = asi_write_fifo; + + /* setup card type */ + + sc->sc_cardtyp = CARD_TYPEP_ASUSCOMIPAC; + + /* setup IOM bus type */ + + sc->sc_bustyp = BUS_TYPE_IOM2; + + /* setup chip type = IPAC ! */ + + sc->sc_ipac = 1; + sc->sc_bfifolen = IPAC_BFIFO_LEN; + + /* enable hscx/isac irq's */ +/* + * This has been taken from Linux driver. + * (Removed initialization that was not applicaple to + * this board or was already register default setting.) + */ + IPAC_WRITE (IPAC_ACFG, 0xff); /* Setup AUX pin modes */ + IPAC_WRITE (IPAC_AOE, 0x0); /* Setup AUX pin modes */ + IPAC_WRITE (IPAC_MASK, (IPAC_MASK_INT1 | IPAC_MASK_INT0)); + + return(0); +} +#endif /* (NISIC > 0) && defined (ASUSCOM_IPAC) */ diff --git a/sys/i4b/layer1/isic/i4b_avm_a1.c b/sys/i4b/layer1/isic/i4b_avm_a1.c new file mode 100644 index 0000000..ee076f0 --- /dev/null +++ b/sys/i4b/layer1/isic/i4b_avm_a1.c @@ -0,0 +1,420 @@ +/* + * Copyright (c) 1996 Andrew Gordon. 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 + * 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_avm_a1.c - AVM A1/Fritz passive card driver for isdn4bsd + * ------------------------------------------------------------ + * + * $Id: i4b_avm_a1.c,v 1.3 2000/05/29 15:41:41 hm Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Mon May 29 16:42:06 2000] + * + *---------------------------------------------------------------------------*/ + +#include "isic.h" +#include "opt_i4b.h" + +#if NISIC > 0 && defined(AVM_A1) + +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include + +#include + +#include +#include +#include + +/*---------------------------------------------------------------------------* + * AVM A1 and AVM Fritz! Card special registers + *---------------------------------------------------------------------------*/ + +#define AVM_CONF_REG 0x1800 /* base offset for config register */ +#define AVM_CONF_IRQ 0x1801 /* base offset for IRQ register */ + /* config register write */ +#define AVM_CONF_WR_RESET 0x01 /* 1 = RESET ISAC and HSCX */ +#define AVM_CONF_WR_CCL 0x02 /* 1 = clear counter low nibble */ +#define AVM_CONF_WR_CCH 0x04 /* 1 = clear counter high nibble */ +#define AVM_CONF_WR_IRQEN 0x08 /* 1 = enable IRQ */ +#define AVM_CONF_WR_TEST 0x10 /* test bit */ + /* config register read */ +#define AVM_CONF_RD_IIRQ 0x01 /* 0 = ISAC IRQ active */ +#define AVM_CONF_RD_HIRQ 0x02 /* 0 = HSCX IRQ active */ +#define AVM_CONF_RD_CIRQ 0x04 /* 0 = counter IRQ active */ +#define AVM_CONF_RD_ZER1 0x08 /* unused, always read 0 */ +#define AVM_CONF_RD_TEST 0x10 /* test bit read back */ +#define AVM_CONF_RD_ZER2 0x20 /* unused, always read 0 */ + +#define AVM_ISAC_R_OFFS (0x1400-0x20) +#define AVM_HSCXA_R_OFFS (0x400-0x20) +#define AVM_HSCXB_R_OFFS (0xc00-0x20) +#define AVM_ISAC_F_OFFS (0x1400-0x20-0x3e0) +#define AVM_HSCXA_F_OFFS (0x400-0x20-0x3e0) +#define AVM_HSCXB_F_OFFS (0xc00-0x20-0x3e0) + +/*---------------------------------------------------------------------------* + * AVM read fifo routine + *---------------------------------------------------------------------------*/ +static void +avma1_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[what+4]); + bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[what+4]); + bus_space_read_multi_1(t, h, 0, buf, size); +} + +/*---------------------------------------------------------------------------* + * AVM write fifo routine + *---------------------------------------------------------------------------*/ +static void +avma1_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[what+4]); + bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[what+4]); + bus_space_write_multi_1(t, h, 0, (u_int8_t*)buf, size); +} + +/*---------------------------------------------------------------------------* + * AVM write register routine + *---------------------------------------------------------------------------*/ +static void +avma1_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[what+1]); + bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[what+1]); + bus_space_write_1(t, h, offs, data); +} + +/*---------------------------------------------------------------------------* + * AVM read register routine + *---------------------------------------------------------------------------*/ +static u_int8_t +avma1_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[what+1]); + bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[what+1]); + return bus_space_read_1(t, h, offs); +} + +/*---------------------------------------------------------------------------* + * allocate an io port + *---------------------------------------------------------------------------*/ +static int +isic_alloc_port(device_t dev, int rid, u_int base, u_int len) +{ + size_t unit = device_get_unit(dev); + struct l1_softc *sc = &l1_sc[unit]; + + sc->sc_resources.io_rid[rid] = rid; + + bus_set_resource(dev, SYS_RES_IOPORT, rid, base, len); + + if(!(sc->sc_resources.io_base[rid] = + bus_alloc_resource(dev, SYS_RES_IOPORT, + &sc->sc_resources.io_rid[rid], + 0ul, ~0ul, 1, RF_ACTIVE))) + { + printf("isic%d: Error, failed to reserve io #%d!\n", unit, rid); + isic_detach_common(dev); + return(ENXIO); + } + return(0); +} + +/*---------------------------------------------------------------------------* + * isic_probe_avma1 - probe for AVM A1 and compatibles + *---------------------------------------------------------------------------*/ +int +isic_probe_avma1(device_t dev) +{ + size_t unit = device_get_unit(dev); /* get unit */ + struct l1_softc *sc = 0; /* pointer to softc */ + void *ih = 0; /* dummy */ + bus_space_tag_t t; /* bus things */ + bus_space_handle_t h; + u_char savebyte; + u_char byte; + + /* check max unit range */ + + if(unit >= ISIC_MAXUNIT) + { + printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for AVM A1/Fritz!\n", + unit, unit); + return(ENXIO); + } + + sc = &l1_sc[unit]; /* get pointer to softc */ + sc->sc_unit = unit; /* set unit */ + sc->sc_flags = FLAG_AVM_A1; /* set flags */ + + /* see if an io base was supplied */ + + 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 get iobase for AVM A1/Fritz!\n", + unit); + return(ENXIO); + } + + /* set io base */ + + sc->sc_port = rman_get_start(sc->sc_resources.io_base[0]); + + /* release io base */ + + bus_release_resource(dev, SYS_RES_IOPORT, sc->sc_resources.io_rid[0], + sc->sc_resources.io_base[0]); + + switch(sc->sc_port) + { + case 0x200: + case 0x240: + case 0x300: + case 0x340: + break; + + default: + printf("isic%d: Error, invalid iobase 0x%x specified for AVM A1/Fritz!\n", + unit, sc->sc_port); + return(ENXIO); + break; + } + + if(isic_alloc_port(dev, 0, sc->sc_port+AVM_CONF_REG, 0x20)) + return(ENXIO); + + if(isic_alloc_port(dev, 1, sc->sc_port+AVM_ISAC_R_OFFS, 0x20)) + return(ENXIO); + + if(isic_alloc_port(dev, 2, sc->sc_port+AVM_HSCXA_R_OFFS, 0x20)) + return(ENXIO); + + if(isic_alloc_port(dev, 3, sc->sc_port+AVM_HSCXB_R_OFFS, 0x20)) + return(ENXIO); + + if(isic_alloc_port(dev, 4, sc->sc_port+AVM_ISAC_F_OFFS, 0x20)) + return(ENXIO); + + if(isic_alloc_port(dev, 5, sc->sc_port+AVM_HSCXA_F_OFFS, 0x20)) + return(ENXIO); + + if(isic_alloc_port(dev, 6, sc->sc_port+AVM_HSCXB_F_OFFS, 0x20)) + return(ENXIO); + + /* 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 get an irq for AVM A1/Fritz!\n",unit); + isic_detach_common(dev); + return ENXIO; + } + + /* get the irq number */ + sc->sc_irq = rman_get_start(sc->sc_resources.irq); + + /* register interupt routine */ + bus_setup_intr(dev, sc->sc_resources.irq, INTR_TYPE_NET, + (void(*)(void *))(isicintr), + sc, &ih); + + /* check IRQ validity */ + + switch(sc->sc_irq) + { + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + break; + + default: + printf("isic%d: Error, invalid IRQ [%d] specified for AVM A1/Fritz!\n", + unit, sc->sc_irq); + isic_detach_common(dev); + return(ENXIO); + break; + } + + sc->clearirq = NULL; + sc->readreg = avma1_read_reg; + sc->writereg = avma1_write_reg; + + sc->readfifo = avma1_read_fifo; + sc->writefifo = avma1_write_fifo; + + /* setup card type */ + + sc->sc_cardtyp = CARD_TYPEP_AVMA1; + + /* 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 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 A1/Fritz\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)); + return(ENXIO); + } + + /* AVM A1 or Fritz! control register bits: */ + /* read write */ + /* 0x01 hscx irq* RESET */ + /* 0x02 isac irq* clear counter1 */ + /* 0x04 counter irq* clear counter2 */ + /* 0x08 always 0 irq enable */ + /* 0x10 read test bit set test bit */ + /* 0x20 always 0 unused */ + + /* + * XXX the following test may be destructive, to prevent the + * worst case, we save the byte first, and in case the test + * fails, we write back the saved byte ..... + */ + + t = rman_get_bustag(sc->sc_resources.io_base[0]); + h = rman_get_bushandle(sc->sc_resources.io_base[0]); + + savebyte = bus_space_read_1(t, h, 0); + + /* write low to test bit */ + + bus_space_write_1(t, h, 0, 0x00); + + /* test bit and next higher and lower bit must be 0 */ + + if((byte = bus_space_read_1(t, h, 0) & 0x38) != 0x00) + { + printf("isic%d: Error, probe-1 failed, 0x%02x should be 0x00 for AVM A1/Fritz!\n", + unit, byte); + bus_space_write_1(t, h, 0, savebyte); + return(ENXIO); + } + + /* write high to test bit */ + + bus_space_write_1(t, h, 0, 0x10); + + /* test bit must be high, next higher and lower bit must be 0 */ + + if((byte = bus_space_read_1(t, h, 0) & 0x38) != 0x10) + { + printf("isic%d: Error, probe-2 failed, 0x%02x should be 0x10 for AVM A1/Fritz!\n", + unit, byte); + bus_space_write_1(t, h, 0, savebyte); + return(ENXIO); + } + return(0); +} + +/*---------------------------------------------------------------------------* + * isic_attach_avma1 - attach AVM A1 and compatibles + *---------------------------------------------------------------------------*/ +int +isic_attach_avma1(device_t dev) +{ + size_t unit = device_get_unit(dev); + 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]); + + /* reset ISAC/HSCX */ + + bus_space_write_1(t, h, 0, 0x00); + DELAY(SEC_DELAY / 10); + + bus_space_write_1(t, h, 0, AVM_CONF_WR_RESET); + DELAY(SEC_DELAY / 10); + + bus_space_write_1(t, h, 0, 0x00); + DELAY(SEC_DELAY / 10); + + /* setup IRQ */ + + bus_space_write_1(t, h, 1, sc->sc_irq); + DELAY(SEC_DELAY / 10); + + /* enable IRQ, disable counter IRQ */ + + bus_space_write_1(t, h, 0, AVM_CONF_WR_IRQEN | + AVM_CONF_WR_CCH | AVM_CONF_WR_CCL); + DELAY(SEC_DELAY / 10); + + return(0); +} + +#endif /* NISIC > 0 && defined(AVM_A1) */ diff --git a/sys/i4b/layer1/isic/i4b_bchan.c b/sys/i4b/layer1/isic/i4b_bchan.c new file mode 100644 index 0000000..1fb6cc6 --- /dev/null +++ b/sys/i4b/layer1/isic/i4b_bchan.c @@ -0,0 +1,405 @@ +/* + * 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_bchan.c - B channel handling L1 procedures + * ---------------------------------------------- + * + * $Id: i4b_bchan.c,v 1.6 2000/05/29 15:41:41 hm Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Mon May 29 16:42:26 2000] + * + *---------------------------------------------------------------------------*/ + +#include "isic.h" + +#if NISIC > 0 + +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include + +static void isic_bchannel_start(int unit, int h_chan); +static void isic_bchannel_stat(int unit, int h_chan, bchan_statistics_t *bsp); + +/*---------------------------------------------------------------------------* + * initialize one B channels rx/tx data structures and init/deinit HSCX + *---------------------------------------------------------------------------*/ +void +isic_bchannel_setup(int unit, int h_chan, int bprot, int activate) +{ + struct l1_softc *sc = &l1_sc[unit]; + l1_bchan_state_t *chan = &sc->sc_chan[h_chan]; + + int s = SPLI4B(); + + if(activate == 0) + { + /* deactivation */ + isic_hscx_init(sc, h_chan, activate); + } + + NDBGL1(L1_BCHAN, "unit=%d, channel=%d, %s", + sc->sc_unit, h_chan, activate ? "activate" : "deactivate"); + + /* general part */ + + chan->unit = sc->sc_unit; /* unit number */ + chan->channel = h_chan; /* B channel */ + chan->bprot = bprot; /* B channel protocol */ + chan->state = HSCX_IDLE; /* B channel state */ + + /* receiver part */ + + i4b_Bcleanifq(&chan->rx_queue); /* clean rx queue */ + + chan->rx_queue.ifq_maxlen = IFQ_MAXLEN; + + chan->rxcount = 0; /* reset rx counter */ + + i4b_Bfreembuf(chan->in_mbuf); /* clean rx mbuf */ + + chan->in_mbuf = NULL; /* reset mbuf ptr */ + chan->in_cbptr = NULL; /* reset mbuf curr ptr */ + chan->in_len = 0; /* reset mbuf data len */ + + /* transmitter part */ + + i4b_Bcleanifq(&chan->tx_queue); /* clean tx queue */ + + chan->tx_queue.ifq_maxlen = IFQ_MAXLEN; + + chan->txcount = 0; /* reset tx counter */ + + i4b_Bfreembuf(chan->out_mbuf_head); /* clean tx mbuf */ + + chan->out_mbuf_head = NULL; /* reset head mbuf ptr */ + chan->out_mbuf_cur = NULL; /* reset current mbuf ptr */ + chan->out_mbuf_cur_ptr = NULL; /* reset current mbuf data ptr */ + chan->out_mbuf_cur_len = 0; /* reset current mbuf data cnt */ + + if(activate != 0) + { + /* activation */ + isic_hscx_init(sc, h_chan, activate); + } + + splx(s); +} + +/*---------------------------------------------------------------------------* + * start transmission on a b channel + *---------------------------------------------------------------------------*/ +static void +isic_bchannel_start(int unit, int h_chan) +{ + struct l1_softc *sc = &l1_sc[unit]; + register l1_bchan_state_t *chan = &sc->sc_chan[h_chan]; + register int next_len; + register int len; + + int s; + int activity = -1; + int cmd = 0; + + s = SPLI4B(); /* enter critical section */ + if(chan->state & HSCX_TX_ACTIVE) /* already running ? */ + { + splx(s); + return; /* yes, leave */ + } + + /* get next mbuf from queue */ + + IF_DEQUEUE(&chan->tx_queue, chan->out_mbuf_head); + + if(chan->out_mbuf_head == NULL) /* queue empty ? */ + { + splx(s); /* leave critical section */ + return; /* yes, exit */ + } + + /* init current mbuf values */ + + chan->out_mbuf_cur = chan->out_mbuf_head; + chan->out_mbuf_cur_len = chan->out_mbuf_cur->m_len; + chan->out_mbuf_cur_ptr = chan->out_mbuf_cur->m_data; + + /* activity indicator for timeout handling */ + + if(chan->bprot == BPROT_NONE) + { + if(!(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 |= HSCX_TX_ACTIVE; /* we start transmitting */ + + if(sc->sc_trace & TRACE_B_TX) /* if trace, send mbuf to trace dev */ + { + i4b_trace_hdr_t hdr; + hdr.unit = 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); + 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 */ + + /* + * fill the HSCX tx fifo with data from the current mbuf. if + * current mbuf holds less data than HSCX fifo length, try to + * get the next mbuf from (a possible) mbuf chain. if there is + * not enough data in a single mbuf or in a chain, then this + * is the last mbuf and we tell the HSCX that it has to send + * CRC and closing flag + */ + + while((len < sc->sc_bfifolen) && chan->out_mbuf_cur) + { + /* + * put as much data into the HSCX fifo as is + * available from the current mbuf + */ + + if((len + chan->out_mbuf_cur_len) >= sc->sc_bfifolen) + next_len = sc->sc_bfifolen - len; + else + next_len = chan->out_mbuf_cur_len; + +#ifdef NOTDEF + printf("b:mh=%x, mc=%x, mcp=%x, mcl=%d l=%d nl=%d # ", + chan->out_mbuf_head, + chan->out_mbuf_cur, + chan->out_mbuf_cur_ptr, + chan->out_mbuf_cur_len, + len, + next_len); +#endif + + /* wait for tx fifo write enabled */ + + isic_hscx_waitxfw(sc, h_chan); + + /* write what we have from current mbuf to HSCX fifo */ + + HSCX_WRFIFO(h_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 = 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); + 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 HSCX. 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 HSCX tx fifo is done in the + * HSCX interrupt routine. + */ + + cmd |= HSCX_CMDR_XTF; + } + else + { + /* end of mbuf chain */ + + if(chan->bprot == BPROT_NONE) + cmd |= HSCX_CMDR_XTF; + else + cmd |= HSCX_CMDR_XTF | HSCX_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->isic_drvr_linktab->bch_activity)(chan->isic_drvr_linktab->unit, activity); + + if(cmd) + isic_hscx_cmd(sc, h_chan, cmd); + + splx(s); +} + +/*---------------------------------------------------------------------------* + * fill statistics struct + *---------------------------------------------------------------------------*/ +static void +isic_bchannel_stat(int unit, int h_chan, bchan_statistics_t *bsp) +{ + struct l1_softc *sc = &l1_sc[unit]; + l1_bchan_state_t *chan = &sc->sc_chan[h_chan]; + int s; + + s = SPLI4B(); + + bsp->outbytes = chan->txcount; + bsp->inbytes = chan->rxcount; + + chan->txcount = 0; + chan->rxcount = 0; + + splx(s); +} + +/*---------------------------------------------------------------------------* + * return the address of isic drivers linktab + *---------------------------------------------------------------------------*/ +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->isic_isdn_linktab); +} + +/*---------------------------------------------------------------------------* + * set the driver linktab in the b channel softc + *---------------------------------------------------------------------------*/ +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->isic_drvr_linktab = dlt; +} + +/*---------------------------------------------------------------------------* + * initialize our local linktab + *---------------------------------------------------------------------------*/ +void +isic_init_linktab(struct l1_softc *sc) +{ + 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 */ + 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; + lt->channel = HSCX_CH_A; + lt->bch_config = isic_bchannel_setup; + lt->bch_tx_start = isic_bchannel_start; + lt->bch_stat = isic_bchannel_stat; + lt->tx_queue = &chan->tx_queue; + + /* used by non-HDLC data transfers, i.e. telephony drivers */ + lt->rx_queue = &chan->rx_queue; + + /* used by HDLC data transfers, i.e. ipr and isp drivers */ + lt->rx_mbuf = &chan->in_mbuf; + + chan = &sc->sc_chan[HSCX_CH_B]; + lt = &chan->isic_isdn_linktab; + + lt->unit = sc->sc_unit; + lt->channel = HSCX_CH_B; + lt->bch_config = isic_bchannel_setup; + lt->bch_tx_start = isic_bchannel_start; + lt->bch_stat = isic_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 /* NISIC > 0 */ diff --git a/sys/i4b/layer1/isic/i4b_ctx_s0P.c b/sys/i4b/layer1/isic/i4b_ctx_s0P.c new file mode 100644 index 0000000..c58b691 --- /dev/null +++ b/sys/i4b/layer1/isic/i4b_ctx_s0P.c @@ -0,0 +1,261 @@ +/* + * 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. + * + *--------------------------------------------------------------------------- + * + * isic - I4B Siemens ISDN Chipset Driver for Creatix/Teles PnP + * ============================================================ + * + * $Id: i4b_ctx_s0P.c,v 1.4 2000/08/22 11:30:04 hm Exp $ + * + * $FreeBSD$ + * + * 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 + * the same hardware and don't share the same PnP config + * information, once the base addresses are set, the + * offsets are same and therefore they can use the same + * driver. + * + *---------------------------------------------------------------------------*/ + +#include "isic.h" +#include "opt_i4b.h" + +#if (NISIC > 0) && (defined(CRTX_S0_P) || defined(TEL_S0_16_3_P)) + +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include + +#include + +#include +#include +#include + +/* #include */ +#include + +/*---------------------------------------------------------------------------* + * Creatix / Teles PnP ISAC get fifo routine + *---------------------------------------------------------------------------*/ +static void +ctxs0P_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[what+2]); + bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[what+2]); + bus_space_read_multi_1(t,h,0x3e,buf,size); +} + +/*---------------------------------------------------------------------------* + * Creatix / Teles PnP ISAC put fifo routine + *---------------------------------------------------------------------------*/ +static void +ctxs0P_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[what+2]); + bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[what+2]); + bus_space_write_multi_1(t,h,0x3e,buf,size); +} + +/*---------------------------------------------------------------------------* + * Creatix / Teles PnP ISAC put register routine + *---------------------------------------------------------------------------*/ +static void +ctxs0P_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[what+2]); + bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[what+2]); + bus_space_write_1(t,h,offs,data); +} + +/*---------------------------------------------------------------------------* + * Creatix / Teles PnP ISAC get register routine + *---------------------------------------------------------------------------*/ +static u_int8_t +ctxs0P_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[what+2]); + bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[what+2]); + return bus_space_read_1(t,h,offs); +} + +/*---------------------------------------------------------------------------* + * isic_attach_Cs0P - attach Creatix / Teles PnP + *---------------------------------------------------------------------------*/ +int +isic_attach_Cs0P(device_t dev) +{ + u_int32_t iobase1; + u_int32_t iobase2; + int unit = device_get_unit(dev); + struct l1_softc *sc = &l1_sc[unit]; + bus_space_tag_t t; + bus_space_handle_t h; + + /* + * this card needs a second io_base, + * free resources if we don't get it + */ + + sc->sc_resources.io_rid[1] = 1; + + if(!(sc->sc_resources.io_base[1] = + bus_alloc_resource(dev, SYS_RES_IOPORT, + &sc->sc_resources.io_rid[1], + 0UL, ~0UL, 1, RF_ACTIVE))) + { + printf("isic%d: Could not get io area 1 for Creatix / Teles PnP!\n", unit); + isic_detach_common(dev); + return ENXIO; + } + + /* remember the io base addresses */ + + iobase1 = rman_get_start(sc->sc_resources.io_base[0]); + iobase2 = rman_get_start(sc->sc_resources.io_base[1]); + + /* + * because overlapping resources are invalid, + * release the first io port resource + */ + + bus_release_resource(dev, SYS_RES_IOPORT, sc->sc_resources.io_rid[0], + sc->sc_resources.io_base[0]); + + /* set and allocate a base io address for the ISAC chip */ + + sc->sc_resources.io_rid[2] = 2; + + bus_set_resource(dev, SYS_RES_IOPORT, 2, iobase1-0x20, 0x40); + + if(!(sc->sc_resources.io_base[2] = + bus_alloc_resource(dev, SYS_RES_IOPORT, + &sc->sc_resources.io_rid[2], + 0ul, ~0ul, 1, RF_ACTIVE))) + { + printf("isic%d: Could not get io area 2 for Creatix / Teles PnP!\n", unit); + isic_detach_common(dev); + return ENXIO; + } + + /* + * because overlapping resources are invalid, + * release the second io port resource + */ + + bus_release_resource(dev, SYS_RES_IOPORT, sc->sc_resources.io_rid[1], + sc->sc_resources.io_base[1]); + + /* set and allocate a resource for the HSCX channel A */ + + sc->sc_resources.io_rid[3] = 3; + +/*XXX*/ /* FIXME !!!! + * the width of the resource is too small, there are accesses + * to it with an offset of 0x3e into the next resource. anyway, + * it seems to work and i have no idea how to do 2 resources + * 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, + &sc->sc_resources.io_rid[3], + 0ul,~0ul, 1, RF_ACTIVE))) + { + printf("isic%d: Could not get io area 3 for Creatix / Teles PnP!\n", unit); + isic_detach_common(dev); + return ENXIO; + } + + /* set and allocate a resources for the HSCX channel B */ + + sc->sc_resources.io_rid[4] = 4; + + bus_set_resource(dev, SYS_RES_IOPORT, 4, iobase2, 0x40); + + if(!(sc->sc_resources.io_base[4] = + bus_alloc_resource(dev,SYS_RES_IOPORT, + &sc->sc_resources.io_rid[4], + 0ul, ~0ul, 1, RF_ACTIVE))) + { + printf("isic%d: Could not get io area 4 for Creatix / Teles PnP!\n", unit); + isic_detach_common(dev); + return ENXIO; + } + + /* setup access routines */ + + sc->clearirq = NULL; + sc->readreg = ctxs0P_read_reg; + sc->writereg = ctxs0P_write_reg; + + sc->readfifo = ctxs0P_read_fifo; + sc->writefifo = ctxs0P_write_fifo; + + /* setup card type */ + + sc->sc_cardtyp = CARD_TYPEP_CS0P; + + /* setup IOM bus type */ + + sc->sc_bustyp = BUS_TYPE_IOM2; + + sc->sc_ipac = 0; + sc->sc_bfifolen = HSCX_FIFO_LEN; + + /* enable the card */ + + t = rman_get_bustag(sc->sc_resources.io_base[2]); + h = rman_get_bushandle(sc->sc_resources.io_base[2]); + + bus_space_write_1(t, h, 0x3c, 0); + DELAY(SEC_DELAY / 10); + + bus_space_write_1(t, h, 0x3c, 1); + DELAY(SEC_DELAY / 10); + + return 0; +} + +#endif /* (NISIC > 0) && (defined(CRTX_S0_P) || defined(TEL_S0_16_3_P)) */ + diff --git a/sys/i4b/layer1/isic/i4b_drn_ngo.c b/sys/i4b/layer1/isic/i4b_drn_ngo.c new file mode 100644 index 0000000..042dbb2 --- /dev/null +++ b/sys/i4b/layer1/isic/i4b_drn_ngo.c @@ -0,0 +1,271 @@ +/* + * 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_drn_ngo.c - Dr. Neuhaus Niccy GO@ and SAGEM Cybermod + * -------------------------------------------------------- + * + * $Id: i4b_drn_ngo.c,v 1.3 2000/05/29 15:41:41 hm Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Mon May 29 16:43:21 2000] + * + *---------------------------------------------------------------------------*/ + +#include "isic.h" +#include "opt_i4b.h" + +#if (NISIC > 0) && defined(DRN_NGO) + +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include + +#include + +#include +#include +#include + +/*---------------------------------------------------------------------------* + * Niccy GO@ definitions + * + * the card uses 2 i/o addressranges each using 2 bytes + * + * addressrange 0: + * offset 0 - ISAC dataregister + * offset 1 - HSCX dataregister + * addressrange 1: + * offset 0 - ISAC addressregister + * offset 1 - HSCX addressregister + * + * to access an ISAC/HSCX register, you have to write the register + * number into the ISAC or HSCX addressregister and then read/write + * data for the ISAC/HSCX register into/from the corresponding + * dataregister. + * + * Thanks to Klaus Muehle of Dr. Neuhaus Telekommunikation for giving + * out this information! + * + *---------------------------------------------------------------------------*/ +#define NICCY_PORT_MIN 0x200 +#define NICCY_PORT_MAX 0x3e0 + +#define HSCX_ABIT 0x1000 /* flag, HSCX A is meant */ +#define HSCX_BBIT 0x2000 /* flag, HSCX B is meant */ + +#define HSCX_BOFF 0x40 + +#define ADDR_OFF 2 /* address register range offset */ + +#define ISAC_DATA 0 +#define HSCX_DATA 1 + +#define ISAC_ADDR 0 +#define HSCX_ADDR 1 + +/*---------------------------------------------------------------------------* + * Dr. Neuhaus Niccy GO@ read fifo routine + *---------------------------------------------------------------------------*/ +static void +drnngo_read_fifo(struct l1_softc *sc, int what, void *buf, size_t size) +{ + bus_space_tag_t tdata, tadr; + bus_space_handle_t hdata, hadr; + + tdata = rman_get_bustag(sc->sc_resources.io_base[0]); + hdata = rman_get_bushandle(sc->sc_resources.io_base[0]); + tadr = rman_get_bustag(sc->sc_resources.io_base[1]); + hadr = rman_get_bushandle(sc->sc_resources.io_base[1]); + + switch(what) + { + case ISIC_WHAT_ISAC: + bus_space_write_1 (tadr ,hadr, ISAC_ADDR,0x0); + bus_space_read_multi_1(tdata,hdata,ISAC_DATA,buf,size); + break; + case ISIC_WHAT_HSCXA: + bus_space_write_1 (tadr ,hadr ,HSCX_ADDR,0x0); + bus_space_read_multi_1(tdata,hdata,HSCX_DATA,buf,size); + break; + case ISIC_WHAT_HSCXB: + bus_space_write_1 (tadr ,hadr ,HSCX_ADDR,HSCX_BOFF); + bus_space_read_multi_1(tdata,hdata,HSCX_DATA,buf,size); + break; + } +} + +/*---------------------------------------------------------------------------* + * Dr. Neuhaus Niccy GO@ write fifo routine + *---------------------------------------------------------------------------*/ +static void +drnngo_write_fifo(struct l1_softc *sc, int what, void *buf, size_t size) +{ + bus_space_tag_t tdata, tadr; + bus_space_handle_t hdata, hadr; + + tdata = rman_get_bustag(sc->sc_resources.io_base[0]); + hdata = rman_get_bushandle(sc->sc_resources.io_base[0]); + tadr = rman_get_bustag(sc->sc_resources.io_base[1]); + hadr = rman_get_bushandle(sc->sc_resources.io_base[1]); + + switch(what) + { + case ISIC_WHAT_ISAC: + bus_space_write_1 (tadr ,hadr, ISAC_ADDR,0x0); + bus_space_write_multi_1(tdata,hdata,ISAC_DATA,buf,size); + break; + case ISIC_WHAT_HSCXA: + bus_space_write_1 (tadr ,hadr ,HSCX_ADDR,0x0); + bus_space_write_multi_1(tdata,hdata,HSCX_DATA,buf,size); + break; + case ISIC_WHAT_HSCXB: + bus_space_write_1 (tadr ,hadr ,HSCX_ADDR,HSCX_BOFF); + bus_space_write_multi_1(tdata,hdata,HSCX_DATA,buf,size); + break; + } +} + +/*---------------------------------------------------------------------------* + * Dr. Neuhaus Niccy GO@ write register routine + *---------------------------------------------------------------------------*/ +static void +drnngo_write_reg(struct l1_softc *sc, int what, bus_size_t reg, u_int8_t data) +{ + bus_space_tag_t tdata, tadr; + bus_space_handle_t hdata, hadr; + + tdata = rman_get_bustag(sc->sc_resources.io_base[0]); + hdata = rman_get_bushandle(sc->sc_resources.io_base[0]); + tadr = rman_get_bustag(sc->sc_resources.io_base[1]); + hadr = rman_get_bushandle(sc->sc_resources.io_base[1]); + + switch(what) + { + case ISIC_WHAT_ISAC: + bus_space_write_1(tadr ,hadr, ISAC_ADDR,reg); + bus_space_write_1(tdata,hdata,ISAC_DATA,data); + break; + case ISIC_WHAT_HSCXA: + bus_space_write_1(tadr ,hadr ,HSCX_ADDR,reg); + bus_space_write_1(tdata,hdata,HSCX_DATA,data); + break; + case ISIC_WHAT_HSCXB: + bus_space_write_1(tadr ,hadr ,HSCX_ADDR,reg+HSCX_BOFF); + bus_space_write_1(tdata,hdata,HSCX_DATA,data); + break; + } +} + +/*---------------------------------------------------------------------------* + * Dr. Neuhaus Niccy GO@ read register routine + *---------------------------------------------------------------------------*/ +static u_int8_t +drnngo_read_reg(struct l1_softc *sc, int what, bus_size_t reg) +{ + bus_space_tag_t tdata, tadr; + bus_space_handle_t hdata, hadr; + + tdata = rman_get_bustag(sc->sc_resources.io_base[0]); + hdata = rman_get_bushandle(sc->sc_resources.io_base[0]); + tadr = rman_get_bustag(sc->sc_resources.io_base[1]); + hadr = rman_get_bushandle(sc->sc_resources.io_base[1]); + + switch(what) + { + case ISIC_WHAT_ISAC: + bus_space_write_1(tadr ,hadr, ISAC_ADDR,reg); + return bus_space_read_1(tdata,hdata,ISAC_DATA); + case ISIC_WHAT_HSCXA: + bus_space_write_1(tadr ,hadr ,HSCX_ADDR,reg); + return bus_space_read_1(tdata,hdata,HSCX_DATA); + case ISIC_WHAT_HSCXB: + bus_space_write_1(tadr ,hadr ,HSCX_ADDR,reg+HSCX_BOFF); + return bus_space_read_1(tdata,hdata,HSCX_DATA); + default: + return 0; + } +} + +/*---------------------------------------------------------------------------* + * probe for ISA PnP cards + *---------------------------------------------------------------------------*/ +int +isic_attach_drnngo(device_t dev) +{ + int unit = device_get_unit(dev); + struct l1_softc *sc = &l1_sc[unit]; + + sc->sc_resources.io_rid[1] = 1; + + /* + * this card needs a second io_base, + * free resources if we don't get it + */ + + if(!(sc->sc_resources.io_base[1] = + bus_alloc_resource(dev, SYS_RES_IOPORT, + &sc->sc_resources.io_rid[1], + 0UL, ~0UL, 1, RF_ACTIVE))) + { + printf("isic%d: Failed to get second io base.\n", unit); + isic_detach_common(dev); + return ENXIO; + } + + /* setup ISAC access routines */ + + sc->clearirq = NULL; + sc->readreg = drnngo_read_reg; + sc->writereg = drnngo_write_reg; + + sc->readfifo = drnngo_read_fifo; + sc->writefifo = drnngo_write_fifo; + + /* setup card type */ + + sc->sc_cardtyp = CARD_TYPEP_DRNNGO; + + /* setup IOM bus type */ + + sc->sc_bustyp = BUS_TYPE_IOM2; + + sc->sc_ipac = 0; + sc->sc_bfifolen = HSCX_FIFO_LEN; + + return (0); +} + +#endif /* (NISIC > 0) && defined(DRN_NGO) */ 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 +#include +#include +#include + +#include + +#include + +#include +#include + +#include +#include +#include + +/* 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/isic/i4b_elsa_pcc16.c b/sys/i4b/layer1/isic/i4b_elsa_pcc16.c new file mode 100644 index 0000000..ef8786a --- /dev/null +++ b/sys/i4b/layer1/isic/i4b_elsa_pcc16.c @@ -0,0 +1,408 @@ +/* + * 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 + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + *--------------------------------------------------------------------------- + * + * isic - I4B Siemens ISDN Chipset Driver for ELSA MicroLink ISDN/PCC-16 + * ===================================================================== + * + * 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: [Wed Jul 19 09:53:35 2000] + * + *---------------------------------------------------------------------------*/ + +#include "isic.h" +#include "opt_i4b.h" + +#if (NISIC > 0) && defined(ELSA_PCC16) + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include +/* #include */ +#include + +#include +#include +#include + +static void i4b_epcc16_clrirq(struct l1_softc *sc); + +/* masks for register encoded in base addr */ + +#define ELSA_BASE_MASK 0x0ffff +#define ELSA_OFF_MASK 0xf0000 + +/* register id's to be encoded in base addr */ + +#define ELSA_IDISAC 0x00000 +#define ELSA_IDHSCXA 0x10000 +#define ELSA_IDHSCXB 0x20000 + +/* offsets from base address */ + +#define ELSA_OFF_ISAC 0x00 +#define ELSA_OFF_HSCX 0x02 +#define ELSA_OFF_OFF 0x03 +#define ELSA_OFF_CTRL 0x04 +#define ELSA_OFF_CFG 0x05 +#define ELSA_OFF_TIMR 0x06 +#define ELSA_OFF_IRQ 0x07 + +/* control register (write access) */ + +#define ELSA_CTRL_LED_YELLOW 0x02 +#define ELSA_CTRL_LED_GREEN 0x08 +#define ELSA_CTRL_RESET 0x20 +#define ELSA_CTRL_TIMEREN 0x80 +#define ELSA_CTRL_SECRET 0x50 + +/*---------------------------------------------------------------------------* + * ELSA MicroLink ISDN/PCC-16 clear IRQ routine + *---------------------------------------------------------------------------*/ +static void +i4b_epcc16_clrirq(struct l1_softc *sc) +{ + 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]); + bus_space_write_1(t, h, ELSA_OFF_IRQ, 0); +} + +/*---------------------------------------------------------------------------* + * ELSA MicroLink ISDN/PCC-16 ISAC get fifo routine + *---------------------------------------------------------------------------*/ +static void +epcc16_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, ELSA_OFF_OFF, 0); + bus_space_read_multi_1(t, h, ELSA_OFF_ISAC, buf, size); + break; + case ISIC_WHAT_HSCXA: + bus_space_write_1(t, h, ELSA_OFF_OFF, 0); + bus_space_read_multi_1(t, h, ELSA_OFF_HSCX, buf, size); + break; + case ISIC_WHAT_HSCXB: + bus_space_write_1(t, h, ELSA_OFF_OFF, 0x40); + bus_space_read_multi_1(t, h, ELSA_OFF_HSCX, buf, size); + break; + } +} + +/*---------------------------------------------------------------------------* + * ELSA MicroLink ISDN/PCC-16 ISAC put fifo routine + *---------------------------------------------------------------------------*/ +static void +epcc16_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, ELSA_OFF_OFF, 0); + bus_space_write_multi_1(t, h, ELSA_OFF_ISAC, buf, size); + break; + case ISIC_WHAT_HSCXA: + bus_space_write_1(t, h, ELSA_OFF_OFF, 0); + bus_space_write_multi_1(t, h, ELSA_OFF_HSCX, buf, size); + break; + case ISIC_WHAT_HSCXB: + bus_space_write_1(t, h, ELSA_OFF_OFF, 0x40); + bus_space_write_multi_1(t, h, ELSA_OFF_HSCX, buf, size); + break; + } +} + +/*---------------------------------------------------------------------------* + * ELSA MicroLink ISDN/PCC-16 ISAC put register routine + *---------------------------------------------------------------------------*/ +static void +epcc16_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, ELSA_OFF_OFF, offs); + bus_space_write_1(t, h, ELSA_OFF_ISAC, data); + break; + case ISIC_WHAT_HSCXA: + bus_space_write_1(t, h, ELSA_OFF_OFF, offs); + bus_space_write_1(t, h, ELSA_OFF_HSCX, data); + break; + case ISIC_WHAT_HSCXB: + bus_space_write_1(t, h, ELSA_OFF_OFF, 0x40+offs); + bus_space_write_1(t, h, ELSA_OFF_HSCX, data); + break; + } +} + +/*---------------------------------------------------------------------------* + * ELSA MicroLink ISDN/PCC-16 ISAC get register routine + *---------------------------------------------------------------------------*/ +static u_int8_t +epcc16_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, ELSA_OFF_OFF, offs); + return bus_space_read_1(t, h, ELSA_OFF_ISAC); + case ISIC_WHAT_HSCXA: + bus_space_write_1(t, h, ELSA_OFF_OFF, offs); + return bus_space_read_1(t, h, ELSA_OFF_HSCX); + case ISIC_WHAT_HSCXB: + bus_space_write_1(t, h, ELSA_OFF_OFF, 0x40+offs); + return bus_space_read_1(t, h, ELSA_OFF_HSCX); + } + return 0; +} + +/*---------------------------------------------------------------------------* + * isic_detach_Epcc16 - detach for ELSA MicroLink ISDN/PCC-16 + *---------------------------------------------------------------------------*/ +static void +isic_detach_Epcc16(device_t dev) +{ + struct l1_softc *sc = &l1_sc[device_get_unit(dev)]; + + if ( sc->sc_resources.irq ) + { + bus_teardown_intr(dev,sc->sc_resources.irq, + (void(*)(void *))isicintr); + bus_release_resource(dev,SYS_RES_IRQ, + sc->sc_resources.irq_rid, + sc->sc_resources.irq); + sc->sc_resources.irq = 0; + } + + if ( sc->sc_resources.io_base[0] ) { + bus_release_resource(dev,SYS_RES_IOPORT, + sc->sc_resources.io_rid[0], + sc->sc_resources.io_base[0]); + sc->sc_resources.io_base[0] = 0; + } +} + +/*---------------------------------------------------------------------------* + * isic_probe_Epcc16 - probe for ELSA MicroLink ISDN/PCC-16 + *---------------------------------------------------------------------------*/ +int +isic_probe_Epcc16(device_t dev) +{ + size_t unit = device_get_unit(dev); /* get unit */ + struct l1_softc *sc = 0; /* pointer to softc */ + void *ih = 0; /* dummy */ + + /* check max unit range */ + if(unit >= ISIC_MAXUNIT) + { + printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for ELSA PCC-16!\n", + unit, unit); + return(ENXIO); + } + + sc = &l1_sc[unit]; /* get pointer to softc */ + + sc->sc_unit = unit; /* set unit */ + + sc->sc_flags = FLAG_ELSA_PCC16; /* set flags */ + + /* see if an io base was supplied */ + + 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 get iobase for ELSA PCC-16.\n", + unit); + return(ENXIO); + } + + /* check if we got an iobase */ + + sc->sc_port = rman_get_start(sc->sc_resources.io_base[0]); + + switch(sc->sc_port) + { + case 0x160: + case 0x170: + case 0x260: + case 0x360: + break; + default: + printf("isic%d: Error, invalid iobase 0x%x specified for ELSA MicroLink ISDN/PCC-16!\n", + unit, sc->sc_port); + isic_detach_Epcc16(dev); + return(ENXIO); + break; + } + + /* setup access routines */ + + sc->clearirq = i4b_epcc16_clrirq; + sc->readreg = epcc16_read_reg; + sc->writereg = epcc16_write_reg; + + sc->readfifo = epcc16_read_fifo; + sc->writefifo = epcc16_write_fifo; + + /* setup card type */ + + sc->sc_cardtyp = CARD_TYPEP_ELSAQS1ISA; + + /* 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 for the ELSA PCC-16 + * is 0x05 ( = version 2.1 ) in the least significant bits. + */ + + if( ((HSCX_READ(0, H_VSTR) & 0xf) != 0x5) || + ((HSCX_READ(1, H_VSTR) & 0xf) != 0x5) ) + { + /* patch from "Doobee R . Tzeck" : + * 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 */ + + 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 get an irq.\n",unit); + isic_detach_Epcc16(dev); + return ENXIO; + } + + /* get the irq number */ + sc->sc_irq = rman_get_start(sc->sc_resources.irq); + + /* check IRQ validity */ + switch(sc->sc_irq) + { + case 2: + case 9: + case 3: + case 5: + case 10: + case 11: + case 15: + break; + + default: + printf("isic%d: Error, invalid IRQ [%d] specified for ELSA MicroLink ISDN/PCC-16!\n", + unit, sc->sc_irq); + isic_detach_Epcc16(dev); + return(ENXIO); + break; + } + + /* register interupt routine */ + bus_setup_intr(dev,sc->sc_resources.irq,INTR_TYPE_NET, + (void(*)(void *))(isicintr), + sc,&ih); + + + return (0); +} + +/*---------------------------------------------------------------------------* + * isic_attach_Epcc16 - attach for ELSA MicroLink ISDN/PCC-16 + *---------------------------------------------------------------------------*/ +int +isic_attach_Epcc16(device_t dev) +{ + int unit = device_get_unit(dev); + 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]); + + u_char byte = ELSA_CTRL_SECRET; + + byte &= ~ELSA_CTRL_RESET; + bus_space_write_1(t, h, ELSA_OFF_CTRL, byte); + DELAY(20); + byte |= ELSA_CTRL_RESET; + bus_space_write_1(t, h, ELSA_OFF_CTRL, byte); + + DELAY(20); + bus_space_write_1(t, h, ELSA_OFF_IRQ, 0xff); + + return 0; +} + +#endif /* (NISIC > 0) && defined(ELSA_PCC16) */ diff --git a/sys/i4b/layer1/isic/i4b_elsa_qs1i.c b/sys/i4b/layer1/isic/i4b_elsa_qs1i.c new file mode 100644 index 0000000..40d4705 --- /dev/null +++ b/sys/i4b/layer1/isic/i4b_elsa_qs1i.c @@ -0,0 +1,249 @@ +/* + * 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. + * + *--------------------------------------------------------------------------- + * + * isic - I4B Siemens ISDN Chipset Driver for ELSA Quickstep 1000pro ISA + * ===================================================================== + * + * $Id: i4b_elsa_qs1i.c,v 1.3 2000/05/29 15:41:41 hm Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Mon May 29 16:44:08 2000] + * + *---------------------------------------------------------------------------*/ + +#include "isic.h" +#include "opt_i4b.h" + +#if (NISIC > 0) && defined(ELSA_QS1ISA) + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include +/* #include */ +#include + +#include +#include +#include + +static void i4b_eq1i_clrirq(struct l1_softc *sc); + +/* masks for register encoded in base addr */ + +#define ELSA_BASE_MASK 0x0ffff +#define ELSA_OFF_MASK 0xf0000 + +/* register id's to be encoded in base addr */ + +#define ELSA_IDISAC 0x00000 +#define ELSA_IDHSCXA 0x10000 +#define ELSA_IDHSCXB 0x20000 + +/* offsets from base address */ + +#define ELSA_OFF_ISAC 0x00 +#define ELSA_OFF_HSCX 0x02 +#define ELSA_OFF_OFF 0x03 +#define ELSA_OFF_CTRL 0x04 +#define ELSA_OFF_CFG 0x05 +#define ELSA_OFF_TIMR 0x06 +#define ELSA_OFF_IRQ 0x07 + +/* control register (write access) */ + +#define ELSA_CTRL_LED_YELLOW 0x02 +#define ELSA_CTRL_LED_GREEN 0x08 +#define ELSA_CTRL_RESET 0x20 +#define ELSA_CTRL_TIMEREN 0x80 +#define ELSA_CTRL_SECRET 0x50 + +/*---------------------------------------------------------------------------* + * ELSA QuickStep 1000pro/ISA clear IRQ routine + *---------------------------------------------------------------------------*/ +static void +i4b_eq1i_clrirq(struct l1_softc *sc) +{ + 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]); + bus_space_write_1(t, h, ELSA_OFF_IRQ, 0); +} + +/*---------------------------------------------------------------------------* + * ELSA QuickStep 1000pro/ISA ISAC get fifo routine + *---------------------------------------------------------------------------*/ +static void +eqs1pi_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, ELSA_OFF_OFF, 0); + bus_space_read_multi_1(t, h, ELSA_OFF_ISAC, buf, size); + break; + case ISIC_WHAT_HSCXA: + bus_space_write_1(t, h, ELSA_OFF_OFF, 0); + bus_space_read_multi_1(t, h, ELSA_OFF_HSCX, buf, size); + break; + case ISIC_WHAT_HSCXB: + bus_space_write_1(t, h, ELSA_OFF_OFF, 0x40); + bus_space_read_multi_1(t, h, ELSA_OFF_HSCX, buf, size); + break; + } +} + +/*---------------------------------------------------------------------------* + * ELSA QuickStep 1000pro/ISA ISAC put fifo routine + *---------------------------------------------------------------------------*/ +static void +eqs1pi_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, ELSA_OFF_OFF, 0); + bus_space_write_multi_1(t, h, ELSA_OFF_ISAC, buf, size); + break; + case ISIC_WHAT_HSCXA: + bus_space_write_1(t, h, ELSA_OFF_OFF, 0); + bus_space_write_multi_1(t, h, ELSA_OFF_HSCX, buf, size); + break; + case ISIC_WHAT_HSCXB: + bus_space_write_1(t, h, ELSA_OFF_OFF, 0x40); + bus_space_write_multi_1(t, h, ELSA_OFF_HSCX, buf, size); + break; + } +} + +/*---------------------------------------------------------------------------* + * ELSA QuickStep 1000pro/ISA ISAC put register routine + *---------------------------------------------------------------------------*/ +static void +eqs1pi_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, ELSA_OFF_OFF, offs); + bus_space_write_1(t, h, ELSA_OFF_ISAC, data); + break; + case ISIC_WHAT_HSCXA: + bus_space_write_1(t, h, ELSA_OFF_OFF, offs); + bus_space_write_1(t, h, ELSA_OFF_HSCX, data); + break; + case ISIC_WHAT_HSCXB: + bus_space_write_1(t, h, ELSA_OFF_OFF, 0x40+offs); + bus_space_write_1(t, h, ELSA_OFF_HSCX, data); + break; + } +} + +/*---------------------------------------------------------------------------* + * ELSA QuickStep 1000pro/ISA ISAC get register routine + *---------------------------------------------------------------------------*/ +static u_int8_t +eqs1pi_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, ELSA_OFF_OFF, offs); + return bus_space_read_1(t, h, ELSA_OFF_ISAC); + case ISIC_WHAT_HSCXA: + bus_space_write_1(t, h, ELSA_OFF_OFF, offs); + return bus_space_read_1(t, h, ELSA_OFF_HSCX); + case ISIC_WHAT_HSCXB: + bus_space_write_1(t, h, ELSA_OFF_OFF, 0x40+offs); + return bus_space_read_1(t, h, ELSA_OFF_HSCX); + } + return 0; +} + +/*---------------------------------------------------------------------------* + * isic_attach_Eqs1pi - attach for ELSA QuickStep 1000pro/ISA + *---------------------------------------------------------------------------*/ +int +isic_attach_Eqs1pi(device_t dev) +{ + int unit = device_get_unit(dev); + 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]); + + u_char byte = ELSA_CTRL_SECRET; + + /* setup access routines */ + + sc->clearirq = i4b_eq1i_clrirq; + sc->readreg = eqs1pi_read_reg; + sc->writereg = eqs1pi_write_reg; + + sc->readfifo = eqs1pi_read_fifo; + sc->writefifo = eqs1pi_write_fifo; + + /* setup card type */ + + sc->sc_cardtyp = CARD_TYPEP_ELSAQS1ISA; + + /* setup IOM bus type */ + + sc->sc_bustyp = BUS_TYPE_IOM2; + + sc->sc_ipac = 0; + sc->sc_bfifolen = HSCX_FIFO_LEN; + + /* enable the card */ + + byte &= ~ELSA_CTRL_RESET; + bus_space_write_1(t, h, ELSA_OFF_CTRL, byte); + DELAY(20); + byte |= ELSA_CTRL_RESET; + bus_space_write_1(t, h, ELSA_OFF_CTRL, byte); + + DELAY(20); + bus_space_write_1(t, h, ELSA_OFF_IRQ, 0xff); + + return 0; +} +#endif /* (NISIC > 0) && defined(ELSA_QS1ISA) */ diff --git a/sys/i4b/layer1/isic/i4b_elsa_qs1p.c b/sys/i4b/layer1/isic/i4b_elsa_qs1p.c new file mode 100644 index 0000000..9a94422 --- /dev/null +++ b/sys/i4b/layer1/isic/i4b_elsa_qs1p.c @@ -0,0 +1,365 @@ +/* + * 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. + * + *--------------------------------------------------------------------------- + * + * isic - I4B Siemens ISDN Chipset Driver for ELSA MicroLink ISDN/PCI + * ================================================================== + * + * $Id: i4b_elsa_qs1p.c,v 1.4 2000/06/02 11:58:56 hm Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Fri Jun 2 13:57:26 2000] + * + * Note: ELSA Quickstep 1000pro PCI = ELSA MicroLink ISDN/PCI + * + *---------------------------------------------------------------------------*/ + +#include "isic.h" +#include "opt_i4b.h" +#include "pci.h" + +#if (NISIC > 0) && (NPCI > 0) && defined(ELSA_QS1PCI) + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include +/* #include */ +#include + +#include +#include +#include +#include + +#define MEM0_MAPOFF 0 +#define PORT0_MAPOFF 4 +#define PORT1_MAPOFF 12 + +#define ELSA_PORT0_MAPOFF (PCIR_MAPS+PORT0_MAPOFF) +#define ELSA_PORT1_MAPOFF (PCIR_MAPS+PORT1_MAPOFF) + +#define PCI_QS1000_DID 0x1000 +#define PCI_QS1000_VID 0x1048 + +/* masks for register encoded in base addr */ + +#define ELSA_BASE_MASK 0x0ffff +#define ELSA_OFF_MASK 0xf0000 + +/* register id's to be encoded in base addr */ + +#define ELSA_IDISAC 0x00000 +#define ELSA_IDHSCXA 0x10000 +#define ELSA_IDHSCXB 0x20000 +#define ELSA_IDIPAC 0x40000 + +/* offsets from base address */ + +#define ELSA_OFF_ALE 0x00 +#define ELSA_OFF_RW 0x01 + + +static int eqs1p_pci_probe(device_t dev); +static int eqs1p_pci_attach(device_t dev); + +static device_method_t eqs1p_pci_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, eqs1p_pci_probe), + DEVMETHOD(device_attach, eqs1p_pci_attach), + { 0, 0 } +}; + +static driver_t eqs1p_pci_driver = { + "isic", + eqs1p_pci_methods, + 0 +}; + +static devclass_t eqs1p_pci_devclass; + +DRIVER_MODULE(eqs1p, pci, eqs1p_pci_driver, eqs1p_pci_devclass, 0, 0); + +/*---------------------------------------------------------------------------* + * ELSA MicroLink ISDN/PCI fifo read routine + *---------------------------------------------------------------------------*/ +static void +eqs1pp_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[1]); + bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[1]); + + switch(what) + { + case ISIC_WHAT_ISAC: + bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_ISAC_OFF); + bus_space_read_multi_1(t, h, ELSA_OFF_RW, buf, size); + break; + case ISIC_WHAT_HSCXA: + bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXA_OFF); + bus_space_read_multi_1(t, h, ELSA_OFF_RW, buf, size); + break; + case ISIC_WHAT_HSCXB: + bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXB_OFF); + bus_space_read_multi_1(t, h, ELSA_OFF_RW, buf, size); + break; + } +} + +/*---------------------------------------------------------------------------* + * ELSA MicroLink ISDN/PCI fifo write routine + *---------------------------------------------------------------------------*/ +static void +eqs1pp_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[1]); + bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[1]); + + switch(what) + { + case ISIC_WHAT_ISAC: + bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_ISAC_OFF); + bus_space_write_multi_1(t, h, ELSA_OFF_RW, (u_int8_t*)buf, size); + break; + case ISIC_WHAT_HSCXA: + bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXA_OFF); + bus_space_write_multi_1(t, h, ELSA_OFF_RW, (u_int8_t*)buf, size); + break; + case ISIC_WHAT_HSCXB: + bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXB_OFF); + bus_space_write_multi_1(t, h, ELSA_OFF_RW, (u_int8_t*)buf, size); + break; + } +} + +/*---------------------------------------------------------------------------* + * ELSA MicroLink ISDN/PCI register write routine + *---------------------------------------------------------------------------*/ +static void +eqs1pp_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[1]); + bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[1]); + + switch(what) + { + case ISIC_WHAT_ISAC: + bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_ISAC_OFF+offs); + bus_space_write_1(t, h, ELSA_OFF_RW, data); + break; + case ISIC_WHAT_HSCXA: + bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXA_OFF+offs); + bus_space_write_1(t, h, ELSA_OFF_RW, data); + break; + case ISIC_WHAT_HSCXB: + bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXB_OFF+offs); + bus_space_write_1(t, h, ELSA_OFF_RW, data); + break; + case ISIC_WHAT_IPAC: + bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_IPAC_OFF+offs); + bus_space_write_1(t, h, ELSA_OFF_RW, data); + break; + } +} + +/*---------------------------------------------------------------------------* + * ELSA MicroLink ISDN/PCI register read routine + *---------------------------------------------------------------------------*/ +static u_int8_t +eqs1pp_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[1]); + bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[1]); + + switch(what) + { + case ISIC_WHAT_ISAC: + bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_ISAC_OFF+offs); + return bus_space_read_1(t, h, ELSA_OFF_RW); + case ISIC_WHAT_HSCXA: + bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXA_OFF+offs); + return bus_space_read_1(t, h, ELSA_OFF_RW); + case ISIC_WHAT_HSCXB: + bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXB_OFF+offs); + return bus_space_read_1(t, h, ELSA_OFF_RW); + case ISIC_WHAT_IPAC: + bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_IPAC_OFF+offs); + return bus_space_read_1(t, h, ELSA_OFF_RW); + } + return 0; +} + +/*---------------------------------------------------------------------------* + * avma1pp_probe - probe for a card + *---------------------------------------------------------------------------*/ +static int +eqs1p_pci_probe(device_t dev) +{ + if((pci_get_vendor(dev) == PCI_QS1000_VID) && + (pci_get_device(dev) == PCI_QS1000_DID)) + { + device_set_desc(dev, "ELSA MicroLink ISDN/PCI"); + return(0); + } + return(ENXIO); +} + +/*---------------------------------------------------------------------------* + * isic_attach_Eqs1pp - attach for ELSA MicroLink ISDN/PCI + *---------------------------------------------------------------------------*/ +static int +eqs1p_pci_attach(device_t dev) +{ + bus_space_tag_t t; + bus_space_handle_t h; + struct l1_softc *sc; + void *ih = 0; + int unit = device_get_unit(dev); + + /* check max unit range */ + + if(unit >= ISIC_MAXUNIT) + { + printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for ELSA MicroLink ISDN/PCI!\n", + unit, unit); + return(ENXIO); + } + + sc = &l1_sc[unit]; /* get softc */ + + sc->sc_unit = unit; + + /* get io_base */ + + sc->sc_resources.io_rid[0] = ELSA_PORT0_MAPOFF; + + 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: Couldn't get first iobase for ELSA MicroLink ISDN/PCI!\n", unit); + return(ENXIO); + } + + sc->sc_resources.io_rid[1] = ELSA_PORT1_MAPOFF; + + if(!(sc->sc_resources.io_base[1] = + bus_alloc_resource(dev, SYS_RES_IOPORT, + &sc->sc_resources.io_rid[1], + 0UL, ~0UL, 1, RF_ACTIVE))) + { + printf("isic%d: Couldn't get second iobase for ELSA MicroLink ISDN/PCI!\n", unit); + isic_detach_common(dev); + return(ENXIO); + } + + sc->sc_port = rman_get_start(sc->sc_resources.io_base[1]); + + 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 get irq for ELSA MicroLink ISDN/PCI!\n",unit); + isic_detach_common(dev); + return(ENXIO); + } + + sc->sc_irq = rman_get_start(sc->sc_resources.irq); + + /* setup access routines */ + + sc->clearirq = NULL; + sc->readreg = eqs1pp_read_reg; + sc->writereg = eqs1pp_write_reg; + + sc->readfifo = eqs1pp_read_fifo; + sc->writefifo = eqs1pp_write_fifo; + + /* setup card type */ + + sc->sc_cardtyp = CARD_TYPEP_ELSAQS1PCI; + + /* setup IOM bus type */ + + sc->sc_bustyp = BUS_TYPE_IOM2; + + /* setup chip type = IPAC ! */ + + sc->sc_ipac = 1; + sc->sc_bfifolen = IPAC_BFIFO_LEN; + + if(isic_attach_common(dev)) + { + isic_detach_common(dev); + return(ENXIO); + } + + if(bus_setup_intr(dev, sc->sc_resources.irq, INTR_TYPE_NET, + (void(*)(void*))isicintr, + sc, &ih)) + { + printf("isic%d: Couldn't set up irq for ELSA MicroLink ISDN/PCI!\n", unit); + isic_detach_common(dev); + return(ENXIO); + } + + /* enable hscx/isac irq's */ + + IPAC_WRITE(IPAC_MASK, (IPAC_MASK_INT1 | IPAC_MASK_INT0)); + + IPAC_WRITE(IPAC_ACFG, 0); /* outputs are open drain */ + IPAC_WRITE(IPAC_AOE, /* aux 5..2 are inputs, 7, 6 outputs */ + (IPAC_AOE_OE5 | IPAC_AOE_OE4 | IPAC_AOE_OE3 | IPAC_AOE_OE2)); + IPAC_WRITE(IPAC_ATX, 0xff); /* set all output lines high */ + + t = rman_get_bustag(sc->sc_resources.io_base[0]); + h = rman_get_bushandle(sc->sc_resources.io_base[0]); + + bus_space_write_1(t, h, 0x4c, 0x41); /* enable card interrupt */ + + return(0); +} + +#endif /* (NISIC > 0) && (NPCI > 0) && defined(ELSA_QS1PCI) */ diff --git a/sys/i4b/layer1/isic/i4b_hscx.c b/sys/i4b/layer1/isic/i4b_hscx.c new file mode 100644 index 0000000..7731cb2 --- /dev/null +++ b/sys/i4b/layer1/isic/i4b_hscx.c @@ -0,0 +1,667 @@ +/* + * 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 - Siemens HSCX chip (B-channel) handling + * -------------------------------------------- + * + * $Id: i4b_hscx.c,v 1.7 2000/05/29 15:41:41 hm Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Mon May 29 16:44:50 2000] + * + *---------------------------------------------------------------------------*/ + +#include "isic.h" + +#if NISIC > 0 + +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include + +/*---------------------------------------------------------------------------* + * HSCX IRQ Handler + *---------------------------------------------------------------------------*/ +void +isic_hscx_irq(register struct l1_softc *sc, u_char ista, int h_chan, u_char ex_irq) +{ + register l1_bchan_state_t *chan = &sc->sc_chan[h_chan]; + u_char exir = 0; + int activity = -1; + u_char cmd = 0; + + NDBGL1(L1_H_IRQ, "%#x", ista); + + if(ex_irq) + { + /* get channel extended irq reg */ + + exir = HSCX_READ(h_chan, H_EXIR); + + if(exir & HSCX_EXIR_RFO) + { + chan->stat_RFO++; + NDBGL1(L1_H_XFRERR, "ex_irq: receive data overflow"); + } + + if((exir & HSCX_EXIR_XDU) && (chan->bprot != BPROT_NONE))/* xmit data underrun */ + { + chan->stat_XDU++; + 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 */ + { + i4b_Bfreembuf(chan->out_mbuf_head); + chan->out_mbuf_cur = chan->out_mbuf_head = NULL; + } + } + + } + + /* rx message end, end of frame */ + + if(ista & HSCX_ISTA_RME) + { + register int fifo_data_len; + u_char rsta; + int error = 0; + + rsta = HSCX_READ(h_chan, H_RSTA); + + if((rsta & 0xf0) != 0xa0) + { + if((rsta & HSCX_RSTA_VFR) == 0) + { + chan->stat_VFR++; + cmd |= (HSCX_CMDR_RHR); + NDBGL1(L1_H_XFRERR, "received invalid Frame"); + error++; + } + + if(rsta & HSCX_RSTA_RDO) + { + chan->stat_RDO++; + NDBGL1(L1_H_XFRERR, "receive data overflow"); + error++; + } + + if((rsta & HSCX_RSTA_CRC) == 0) + { + chan->stat_CRC++; + cmd |= (HSCX_CMDR_RHR); + NDBGL1(L1_H_XFRERR, "CRC check failed"); + error++; + } + + if(rsta & HSCX_RSTA_RAB) + { + chan->stat_RAB++; + NDBGL1(L1_H_XFRERR, "Receive message aborted"); + error++; + } + } + + fifo_data_len = ((HSCX_READ(h_chan, H_RBCL)) & + ((sc->sc_bfifolen)-1)); + + if(fifo_data_len == 0) + fifo_data_len = sc->sc_bfifolen; + + /* 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 isic_hscx_irq: RME, cannot allocate mbuf!\n"); + chan->in_cbptr = chan->in_mbuf->m_data; + chan->in_len = 0; + } + + fifo_data_len -= 1; /* last byte in fifo is RSTA ! */ + + if((chan->in_len + fifo_data_len) <= BCH_MAX_DATALEN) + { + /* read data from HSCX fifo */ + + HSCX_RDFIFO(h_chan, chan->in_cbptr, fifo_data_len); + + cmd |= (HSCX_CMDR_RMC); + isic_hscx_cmd(sc, h_chan, 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 = 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); + i4b_l1_trace_ind(&hdr, chan->in_mbuf->m_len, chan->in_mbuf->m_data); + } + + (*chan->isic_drvr_linktab->bch_rx_data_ready)(chan->isic_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 |= (HSCX_CMDR_RHR | HSCX_CMDR_RMC); + } + } + else + { + if (chan->in_mbuf != NULL) + { + i4b_Bfreembuf(chan->in_mbuf); + chan->in_mbuf = NULL; + chan->in_cbptr = NULL; + chan->in_len = 0; + } + cmd |= (HSCX_CMDR_RMC); + } + } + + /* rx fifo full */ + + if(ista & HSCX_ISTA_RPF) + { + if(chan->in_mbuf == NULL) + { + if((chan->in_mbuf = i4b_Bgetmbuf(BCH_MAX_DATALEN)) == NULL) + panic("L1 isic_hscx_irq: RPF, cannot allocate mbuf!\n"); + chan->in_cbptr = chan->in_mbuf->m_data; + chan->in_len = 0; + } + + chan->rxcount += sc->sc_bfifolen; + + if((chan->in_len + sc->sc_bfifolen) <= BCH_MAX_DATALEN) + { + /* read data from HSCX fifo */ + + HSCX_RDFIFO(h_chan, chan->in_cbptr, sc->sc_bfifolen); + + chan->in_cbptr += sc->sc_bfifolen; + chan->in_len += sc->sc_bfifolen; + } + 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 = 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); + 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->isic_drvr_linktab->bch_rx_data_ready)(chan->isic_drvr_linktab->unit); + + /* alloc new buffer */ + + if((chan->in_mbuf = i4b_Bgetmbuf(BCH_MAX_DATALEN)) == NULL) + panic("L1 isic_hscx_irq: RPF, cannot allocate new mbuf!\n"); + + /* setup new data ptr */ + + chan->in_cbptr = chan->in_mbuf->m_data; + + /* read data from HSCX fifo */ + + HSCX_RDFIFO(h_chan, chan->in_cbptr, sc->sc_bfifolen); + + chan->in_cbptr += sc->sc_bfifolen; + chan->in_len = sc->sc_bfifolen; + + chan->rxcount += sc->sc_bfifolen; + } + 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 |= (HSCX_CMDR_RHR); + } + } + + /* command to release fifo space */ + + cmd |= HSCX_CMDR_RMC; + } + + /* transmit fifo empty, new data can be written to fifo */ + + if(ista & HSCX_ISTA_XPR) + { + /* + * for a description what is going on here, please have + * a look at isic_bchannel_start() in i4b_bchan.c ! + */ + + int activity = -1; + int len; + int nextlen; + + 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 */ + { + IF_DEQUEUE(&chan->tx_queue, chan->out_mbuf_head); + + if(chan->out_mbuf_head == NULL) + { + chan->state &= ~HSCX_TX_ACTIVE; + (*chan->isic_drvr_linktab->bch_tx_queue_empty)(chan->isic_drvr_linktab->unit); + } + else + { + chan->state |= HSCX_TX_ACTIVE; + chan->out_mbuf_cur = chan->out_mbuf_head; + chan->out_mbuf_cur_ptr = chan->out_mbuf_cur->m_data; + chan->out_mbuf_cur_len = chan->out_mbuf_cur->m_len; + + if(sc->sc_trace & TRACE_B_TX) + { + i4b_trace_hdr_t hdr; + hdr.unit = 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); + 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 != sc->sc_bfifolen) + { + nextlen = min(chan->out_mbuf_cur_len, sc->sc_bfifolen - len); + +#ifdef NOTDEF + printf("i:mh=%x, mc=%x, mcp=%x, mcl=%d l=%d nl=%d # ", + chan->out_mbuf_head, + chan->out_mbuf_cur, + chan->out_mbuf_cur_ptr, + chan->out_mbuf_cur_len, + len, + next_len); +#endif + + isic_hscx_waitxfw(sc, h_chan); /* necessary !!! */ + + HSCX_WRFIFO(h_chan, chan->out_mbuf_cur_ptr, nextlen); + cmd |= HSCX_CMDR_XTF; + + 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 = 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); + 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; + } + + } + } + } + + if(cmd) /* is there a command for the HSCX ? */ + { + isic_hscx_cmd(sc, h_chan, cmd); /* yes, to HSCX */ + } + + /* call timeout handling routine */ + + if(activity == ACT_RX || activity == ACT_TX) + (*chan->isic_drvr_linktab->bch_activity)(chan->isic_drvr_linktab->unit, activity); +} + +/*---------------------------------------------------------------------------* + * HSCX initialization + * + * for telephony: extended transparent mode 1 + * for raw hdlc: transparent mode 0 + *---------------------------------------------------------------------------*/ +void +isic_hscx_init(struct l1_softc *sc, int h_chan, int activate) +{ + l1_bchan_state_t *chan = &sc->sc_chan[h_chan]; + + HSCX_WRITE(h_chan, H_MASK, 0xff); /* mask irq's */ + + if(sc->sc_ipac) + { + /* CCR1: Power Up, Clock Mode 5 */ + HSCX_WRITE(h_chan, H_CCR1, HSCX_CCR1_PU | /* power up */ + HSCX_CCR1_CM1); /* IPAC clock mode 5 */ + } + else + { + /* CCR1: Power Up, Clock Mode 5 */ + HSCX_WRITE(h_chan, H_CCR1, HSCX_CCR1_PU | /* power up */ + HSCX_CCR1_CM2 | /* HSCX clock mode 5 */ + HSCX_CCR1_CM0); + } + + /* XAD1: Transmit Address Byte 1 */ + HSCX_WRITE(h_chan, H_XAD1, 0xff); + + /* XAD2: Transmit Address Byte 2 */ + HSCX_WRITE(h_chan, H_XAD2, 0xff); + + /* RAH2: Receive Address Byte High Reg. 2 */ + HSCX_WRITE(h_chan, H_RAH2, 0xff); + + /* XBCH: reset Transmit Byte Count High */ + HSCX_WRITE(h_chan, H_XBCH, 0x00); + + /* RLCR: reset Receive Length Check Register */ + HSCX_WRITE(h_chan, H_RLCR, 0x00); + + /* CCR2: set tx/rx clock shift bit 0 */ + /* disable CTS irq, disable RIE irq*/ + HSCX_WRITE(h_chan, H_CCR2, HSCX_CCR2_XCS0|HSCX_CCR2_RCS0); + + /* XCCR: tx bit count per time slot */ + HSCX_WRITE(h_chan, H_XCCR, 0x07); + + /* RCCR: rx bit count per time slot */ + HSCX_WRITE(h_chan, H_RCCR, 0x07); + + if(sc->sc_bustyp == BUS_TYPE_IOM2) + { + switch(h_chan) + { + case HSCX_CH_A: /* Prepare HSCX channel A */ + /* TSAX: tx clock shift bits 1 & 2 */ + /* tx time slot number */ + HSCX_WRITE(h_chan, H_TSAX, 0x2f); + + /* TSAR: rx clock shift bits 1 & 2 */ + /* rx time slot number */ + HSCX_WRITE(h_chan, H_TSAR, 0x2f); + break; + + case HSCX_CH_B: /* Prepare HSCX channel B */ + /* TSAX: tx clock shift bits 1 & 2 */ + /* tx time slot number */ + HSCX_WRITE(h_chan, H_TSAX, 0x03); + + /* TSAR: rx clock shift bits 1 & 2 */ + /* rx time slot number */ + HSCX_WRITE(h_chan, H_TSAR, 0x03); + break; + } + } + else /* IOM 1 setup */ + { + /* TSAX: tx clock shift bits 1 & 2 */ + /* tx time slot number */ + HSCX_WRITE(h_chan, H_TSAX, 0x07); + + /* TSAR: rx clock shift bits 1 & 2 */ + /* rx time slot number */ + HSCX_WRITE(h_chan, H_TSAR, 0x07); + } + + if(activate) + { + if(chan->bprot == BPROT_RHDLC) + { + /* HDLC Frames, transparent mode 0 */ + HSCX_WRITE(h_chan, H_MODE, + HSCX_MODE_MDS1|HSCX_MODE_RAC|HSCX_MODE_RTS); + } + else + { + /* Raw Telephony, extended transparent mode 1 */ + 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 + { + /* TSAX: tx time slot */ + HSCX_WRITE(h_chan, H_TSAX, 0xff); + + /* TSAR: rx time slot */ + HSCX_WRITE(h_chan, H_TSAR, 0xff); + + /* Raw Telephony, extended transparent mode 1 */ + HSCX_WRITE(h_chan, H_MODE, + HSCX_MODE_MDS1|HSCX_MODE_MDS0|HSCX_MODE_ADM|HSCX_MODE_RTS); + } + + /* don't touch ICA, EXA and EXB bits, this could be HSCX_CH_B */ + /* always disable RSC and TIN */ + + chan->hscx_mask |= HSCX_MASK_RSC | HSCX_MASK_TIN; + + if(activate) + { + /* enable */ + chan->hscx_mask &= ~(HSCX_MASK_RME | HSCX_MASK_RPF | HSCX_MASK_XPR); + } + else + { + /* disable */ + chan->hscx_mask |= HSCX_MASK_RME | HSCX_MASK_RPF | HSCX_MASK_XPR; + } + + /* handle ICA, EXA, and EXB via interrupt mask of channel b */ + + if (h_chan == HSCX_CH_A) + { + if (activate) + HSCX_B_IMASK &= ~(HSCX_MASK_EXA | HSCX_MASK_ICA); + else + HSCX_B_IMASK |= HSCX_MASK_EXA | HSCX_MASK_ICA; + HSCX_WRITE(HSCX_CH_A, H_MASK, HSCX_A_IMASK); + HSCX_WRITE(HSCX_CH_B, H_MASK, HSCX_B_IMASK); + } + else + { + if (activate) + HSCX_B_IMASK &= ~HSCX_MASK_EXB; + else + HSCX_B_IMASK |= HSCX_MASK_EXB; + HSCX_WRITE(HSCX_CH_B, H_MASK, HSCX_B_IMASK); + } + + /* clear spurious interrupts left over */ + + if(h_chan == HSCX_CH_A) + { + HSCX_READ(h_chan, H_EXIR); + HSCX_READ(h_chan, H_ISTA); + } + else /* mask ICA, because it must not be cleared by reading ISTA */ + { + HSCX_WRITE(HSCX_CH_B, H_MASK, HSCX_B_IMASK | HSCX_MASK_ICA); + HSCX_READ(h_chan, H_EXIR); + HSCX_READ(h_chan, H_ISTA); + HSCX_WRITE(HSCX_CH_B, H_MASK, HSCX_B_IMASK); + } +} + +/*---------------------------------------------------------------------------* + * write command to HSCX command register + *---------------------------------------------------------------------------*/ +void +isic_hscx_cmd(struct l1_softc *sc, int h_chan, unsigned char cmd) +{ + int timeout = 20; + + while(((HSCX_READ(h_chan, H_STAR)) & HSCX_STAR_CEC) && timeout) + { + DELAY(10); + timeout--; + } + + if(timeout == 0) + { + NDBGL1(L1_H_ERR, "HSCX wait for CEC timeout!"); + } + + HSCX_WRITE(h_chan, H_CMDR, cmd); +} + +/*---------------------------------------------------------------------------* + * wait for HSCX transmit FIFO write enable + *---------------------------------------------------------------------------*/ +void +isic_hscx_waitxfw(struct l1_softc *sc, int h_chan) +{ +#define WAITVAL 50 +#define WAITTO 200 + + int timeout = WAITTO; + + while((!(((HSCX_READ(h_chan, H_STAR)) & + (HSCX_STAR_CEC | HSCX_STAR_XFW)) == HSCX_STAR_XFW)) && timeout) + { + DELAY(WAITVAL); + timeout--; + } + + if(timeout == 0) + { + NDBGL1(L1_H_ERR, "HSCX wait for XFW timeout!"); + } + else if (timeout != WAITTO) + { + NDBGL1(L1_H_XFRERR, "HSCX wait for XFW time: %d uS", (WAITTO-timeout)*50); + } +} + +#endif /* NISIC > 0 */ diff --git a/sys/i4b/layer1/isic/i4b_hscx.h b/sys/i4b/layer1/isic/i4b_hscx.h new file mode 100644 index 0000000..b4a9197 --- /dev/null +++ b/sys/i4b/layer1/isic/i4b_hscx.h @@ -0,0 +1,299 @@ +/* + * 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 + * 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. + * + *--------------------------------------------------------------------------- + * + * $Id: i4b_hscx.h,v 1.2 2000/03/09 16:12:51 hm Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Mon Dec 13 22:00:49 1999] + * + *---------------------------------------------------------------------------*/ + +#ifndef I4B_HSCX_H_ +#define I4B_HSCX_H_ + +enum HSCX_VERSIONS { + HSCX_VA1, /* 82525 A1 */ + HSCX_UNKN1, /* unknown 1 */ + HSCX_VA2, /* 82525 A2 */ + HSCX_UNKN3, /* unknown 3 */ + HSCX_VA3, /* 82525 A3 */ + HSCX_V21, /* 82525 2.1 */ + HSCX_UNKN /* unknown version */ +}; + +#define HSCX_CH_A 0 /* channel A */ +#define HSCX_CH_B 1 /* channel B */ + +#define HSCX_FIFO_LEN 32 /* 32 bytes FIFO on chip */ + +/* + * definitions of registers and bits for the HSCX ISDN chip. + */ + +typedef struct hscx_reg { + + /* 32 byte deep FIFO always first */ + + unsigned char hscx_fifo [HSCX_FIFO_LEN]; + + /* most registers can be read/written, but have different names */ + /* so define a union with read/write names to make that clear */ + + union { + struct { + unsigned char hscx_ista; + unsigned char hscx_star; + unsigned char hscx_mode; + unsigned char hscx_timr; + unsigned char hscx_exir; + unsigned char hscx_rbcl; + unsigned char dummy_26; + unsigned char hscx_rsta; + unsigned char hscx_ral1; + unsigned char hscx_rhcr; + unsigned char dummy_2a; + unsigned char dummy_2b; + unsigned char hscx_ccr2; + unsigned char hscx_rbch; + unsigned char hscx_vstr; + unsigned char hscx_ccr; + unsigned char dummy_30; + unsigned char dummy_31; + unsigned char dummy_32; + unsigned char dummy_33; + } hscx_r; + struct { + unsigned char hscx_mask; + unsigned char hscx_cmdr; + unsigned char hscx_mode; + unsigned char hscx_timr; + unsigned char hscx_xad1; + unsigned char hscx_xad2; + unsigned char hscx_rah1; + unsigned char hscx_rah2; + unsigned char hscx_ral1; + unsigned char hscx_ral2; + unsigned char hscx_xbcl; + unsigned char hscx_bgr; + unsigned char hscx_ccr2; + unsigned char hscx_xbch; + unsigned char hscx_rlcr; + unsigned char hscx_ccr1; + unsigned char hscx_tsax; + unsigned char hscx_tsar; + unsigned char hscx_xccr; + unsigned char hscx_rccr; + } hscx_w; + } hscx_rw; +} hscx_reg_t; + +#define REG_OFFSET(type, field) (int)(&(((type *)0)->field)) + +/* HSCX read registers */ + +#define h_ista hscx_rw.hscx_r.hscx_ista +#define H_ISTA REG_OFFSET(hscx_reg_t, hscx_rw.hscx_r.hscx_ista) +#define h_star hscx_rw.hscx_r.hscx_star +#define H_STAR REG_OFFSET(hscx_reg_t, hscx_rw.hscx_r.hscx_star) +#define h_mode hscx_rw.hscx_r.hscx_mode +#define H_MODE REG_OFFSET(hscx_reg_t, hscx_rw.hscx_r.hscx_mode) +#define h_timr hscx_rw.hscx_r.hscx_timr +#define H_TIMR REG_OFFSET(hscx_reg_t, hscx_rw.hscx_r.hscx_timr) +#define h_exir hscx_rw.hscx_r.hscx_exir +#define H_EXIR REG_OFFSET(hscx_reg_t, hscx_rw.hscx_r.hscx_exir) +#define h_rbcl hscx_rw.hscx_r.hscx_rbcl +#define H_RBCL REG_OFFSET(hscx_reg_t, hscx_rw.hscx_r.hscx_rbcl) +#define h_rsta hscx_rw.hscx_r.hscx_rsta +#define H_RSTA REG_OFFSET(hscx_reg_t, hscx_rw.hscx_r.hscx_rsta) +#define h_ral1 hscx_rw.hscx_r.hscx_ral1 +#define H_RAL1 REG_OFFSET(hscx_reg_t, hscx_rw.hscx_r.hscx_ral1) +#define h_rhcr hscx_rw.hscx_r.hscx_rhcr +#define H_RHCR REG_OFFSET(hscx_reg_t, hscx_rw.hscx_r.hscx_rhcr) +#define h_ccr2 hscx_rw.hscx_r.hscx_ccr2 +#define H_CCR2 REG_OFFSET(hscx_reg_t, hscx_rw.hscx_r.hscx_ccr2) +#define h_rbch hscx_rw.hscx_r.hscx_rbch +#define H_RBCH REG_OFFSET(hscx_reg_t, hscx_rw.hscx_r.hscx_rbch) +#define h_vstr hscx_rw.hscx_r.hscx_vstr +#define H_VSTR REG_OFFSET(hscx_reg_t, hscx_rw.hscx_r.hscx_vstr) +#define h_ccr hscx_rw.hscx_r.hscx_ccr +#define H_CCR REG_OFFSET(hscx_reg_t, hscx_rw.hscx_r.hscx_ccr) + +/* HSCX write registers - for hscx_mode, hscx_timr, hscx_ral1, hscx_ccr2 */ +/* see read registers */ + +#define h_mask hscx_rw.hscx_w.hscx_mask +#define H_MASK REG_OFFSET(hscx_reg_t, hscx_rw.hscx_w.hscx_mask) +#define h_cmdr hscx_rw.hscx_w.hscx_cmdr +#define H_CMDR REG_OFFSET(hscx_reg_t, hscx_rw.hscx_w.hscx_cmdr) +#define h_xad1 hscx_rw.hscx_w.hscx_xad1 +#define H_XAD1 REG_OFFSET(hscx_reg_t, hscx_rw.hscx_w.hscx_xad1) +#define h_xad2 hscx_rw.hscx_w.hscx_xad2 +#define H_XAD2 REG_OFFSET(hscx_reg_t, hscx_rw.hscx_w.hscx_xad2) +#define h_rah1 hscx_rw.hscx_w.hscx_rah1 +#define H_RAH1 REG_OFFSET(hscx_reg_t, hscx_rw.hscx_w.hscx_rah1) +#define h_rah2 hscx_rw.hscx_w.hscx_rah2 +#define H_RAH2 REG_OFFSET(hscx_reg_t, hscx_rw.hscx_w.hscx_rah2) +#define h_ral2 hscx_rw.hscx_w.hscx_ral2 +#define H_RAL2 REG_OFFSET(hscx_reg_t, hscx_rw.hscx_w.hscx_ral2) +#define h_xbcl hscx_rw.hscx_w.hscx_xbcl +#define H_XBCL REG_OFFSET(hscx_reg_t, hscx_rw.hscx_w.hscx_xbcl) +#define h_bgr hscx_rw.hscx_w.hscx_bgr +#define H_BGR REG_OFFSET(hscx_reg_t, hscx_rw.hscx_w.hscx_bgr) +#define h_xbch hscx_rw.hscx_w.hscx_xbch +#define H_XBCH REG_OFFSET(hscx_reg_t, hscx_rw.hscx_w.hscx_xbch) +#define h_rlcr hscx_rw.hscx_w.hscx_rlcr +#define H_RLCR REG_OFFSET(hscx_reg_t, hscx_rw.hscx_w.hscx_rlcr) +#define h_ccr1 hscx_rw.hscx_w.hscx_ccr1 +#define H_CCR1 REG_OFFSET(hscx_reg_t, hscx_rw.hscx_w.hscx_ccr1) +#define h_tsax hscx_rw.hscx_w.hscx_tsax +#define H_TSAX REG_OFFSET(hscx_reg_t, hscx_rw.hscx_w.hscx_tsax) +#define h_tsar hscx_rw.hscx_w.hscx_tsar +#define H_TSAR REG_OFFSET(hscx_reg_t, hscx_rw.hscx_w.hscx_tsar) +#define h_xccr hscx_rw.hscx_w.hscx_xccr +#define H_XCCR REG_OFFSET(hscx_reg_t, hscx_rw.hscx_w.hscx_xccr) +#define h_rccr hscx_rw.hscx_w.hscx_rccr +#define H_RCCR REG_OFFSET(hscx_reg_t, hscx_rw.hscx_w.hscx_rccr) + +#define HSCX_ISTA_RME 0x80 +#define HSCX_ISTA_RPF 0x40 +#define HSCX_ISTA_RSC 0x20 +#define HSCX_ISTA_XPR 0x10 +#define HSCX_ISTA_TIN 0x08 +#define HSCX_ISTA_ICA 0x04 +#define HSCX_ISTA_EXA 0x02 +#define HSCX_ISTA_EXB 0x01 + +#define HSCX_MASK_RME 0x80 +#define HSCX_MASK_RPF 0x40 +#define HSCX_MASK_RSC 0x20 +#define HSCX_MASK_XPR 0x10 +#define HSCX_MASK_TIN 0x08 +#define HSCX_MASK_ICA 0x04 +#define HSCX_MASK_EXA 0x02 +#define HSCX_MASK_EXB 0x01 + +#define HSCX_EXIR_XMR 0x80 +#define HSCX_EXIR_XDU 0x40 +#define HSCX_EXIR_PCE 0x20 +#define HSCX_EXIR_RFO 0x10 +#define HSCX_EXIR_CSC 0x08 +#define HSCX_EXIR_RFS 0x04 + +/* the other bits are always 0 */ + +#define HSCX_STAR_XDOV 0x80 +#define HSCX_STAR_XFW 0x40 +#define HSCX_STAR_XRNR 0x20 +#define HSCX_STAR_RRNR 0x10 +#define HSCX_STAR_RLI 0x08 +#define HSCX_STAR_CEC 0x04 +#define HSCX_STAR_CTS 0x02 +#define HSCX_STAR_WFA 0x01 + +#define HSCX_CMDR_RMC 0x80 +#define HSCX_CMDR_RHR 0x40 +/* also known as XREP in transparent mode */ +#define HSCX_CMDR_RNR 0x20 +#define HSCX_CMDR_STI 0x10 +#define HSCX_CMDR_XTF 0x08 +#define HSCX_CMDR_XIF 0x04 +#define HSCX_CMDR_XME 0x02 +#define HSCX_CMDR_XRES 0x01 + +#define HSCX_MODE_MDS1 0x80 +#define HSCX_MODE_MDS0 0x40 +#define HSCX_MODE_ADM 0x20 +#define HSCX_MODE_TMD 0x10 +#define HSCX_MODE_RAC 0x08 +#define HSCX_MODE_RTS 0x04 +#define HSCX_MODE_TRS 0x02 +#define HSCX_MODE_TLP 0x01 + +#define HSCX_RSTA_VFR 0x80 +#define HSCX_RSTA_RDO 0x40 +#define HSCX_RSTA_CRC 0x20 +#define HSCX_RSTA_RAB 0x10 +#define HSCX_RSTA_HA1 0x08 +#define HSCX_RSTA_HA0 0x04 +#define HSCX_RSTA_CR 0x02 +#define HSCX_RSTA_LA 0x01 + +#define HSCX_RSTA_MASK 0xf0 /* the interesting ones */ + +/* only used in DMA mode */ +#define HSCX_XBCH_DMA 0x80 +#define HSCX_XBCH_NRM 0x40 +#define HSCX_XBCH_CAS 0x20 +#define HSCX_XBCH_XC 0x10 +/* the rest are bits 11 thru 8 of the byte count */ + +#define HSCX_RBCH_DMA 0x80 +#define HSCX_RBCH_NRM 0x40 +#define HSCX_RBCH_CAS 0x20 +#define HSCX_RBCH_OV 0x10 +/* the rest are bits 11 thru 8 of the byte count */ + +#define HSCX_VSTR_CD 0x80 +/* bits 6 thru 4 are 0 */ +/* bits 3 thru 0 are the version number */ + +#define HSCX_RLCR_RC 0x80 +/* the rest of the bits are used to set the received length */ + +#define HSCX_CCR1_PU 0x80 +/* bits 6 and 5 are SC1 SC0 */ +#define HSCX_CCR1_ODS 0x10 +#define HSCX_CCR1_ITF 0x08 +#define HSCX_CCR1_CM2 0x04 +#define HSCX_CCR1_CM1 0x02 +#define HSCX_CCR1_CM0 0x01 + +/* for clock mode 5 */ +#define HSCX_CCR2_SOC2 0x80 +#define HSCX_CCR2_SOC1 0x40 +#define HSCX_CCR2_XCS0 0x20 +#define HSCX_CCR2_RCS0 0x10 +#define HSCX_CCR2_TIO 0x08 +#define HSCX_CCR2_CIE 0x04 +#define HSCX_CCR2_RIE 0x02 +#define HSCX_CCR2_DIV 0x01 + +/* bits 7 thru 2 are TSNX */ +#define HSCX_TSAX_XCS2 0x02 +#define HSCX_TSAX_XCS1 0x01 + +/* bits 7 thru 2 are TSNR */ +#define HSCX_TSAR_RCS2 0x02 +#define HSCX_TSAR_RCS1 0x01 + +#endif /* I4B_HSCX_H_ */ diff --git a/sys/i4b/layer1/isic/i4b_ipac.h b/sys/i4b/layer1/isic/i4b_ipac.h new file mode 100644 index 0000000..623092d --- /dev/null +++ b/sys/i4b/layer1/isic/i4b_ipac.h @@ -0,0 +1,206 @@ +/* + * 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_ipac.h - definitions for the Siemens IPAC PSB2115 chip + * ========================================================== + * + * $Id: i4b_ipac.h,v 1.1 2000/03/07 14:12:26 hm Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Mon Dec 13 22:00:58 1999] + * + *--------------------------------------------------------------------------- + */ + +#ifndef _I4B_IPAC_H_ +#define _I4B_IPAC_H_ + +#define IPAC_BFIFO_LEN 64 /* 64 bytes B-channel FIFO on chip */ + +#define IPAC_HSCXA_OFF 0x00 +#define IPAC_HSCXB_OFF 0x40 +#define IPAC_ISAC_OFF 0x80 +#define IPAC_IPAC_OFF 0xc0 + +/* 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. + */ + +typedef struct ipac_reg { + + /* most registers can be read/written, but have different names */ + /* so define a union with read/write names to make that clear */ + + union { + struct { + unsigned char ipac_conf; + unsigned char ipac_ista; + unsigned char ipac_id; + unsigned char ipac_acfg; + unsigned char ipac_aoe; + unsigned char ipac_arx; + unsigned char ipac_pita1; + unsigned char ipac_pita2; + unsigned char ipac_pota1; + unsigned char ipac_pota2; + unsigned char ipac_pcfg; + unsigned char ipac_scfg; + unsigned char ipac_timr2; + } ipac_r; + struct { + unsigned char ipac_conf; + unsigned char ipac_mask; + unsigned char ipac_dummy; + unsigned char ipac_acfg; + unsigned char ipac_aoe; + unsigned char ipac_atx; + unsigned char ipac_pita1; + unsigned char ipac_pita2; + unsigned char ipac_pota1; + unsigned char ipac_pota2; + unsigned char ipac_pcfg; + unsigned char ipac_scfg; + unsigned char ipac_timr2; + } ipac_w; + } ipac_rw; +} ipac_reg_t; + +#define REG_OFFSET(type, field) (int)(&(((type *)0)->field)) + +/* IPAC read registers */ + +#define IPAC_CONF REG_OFFSET(ipac_reg_t, ipac_rw.ipac_r.ipac_conf) +#define IPAC_ISTA REG_OFFSET(ipac_reg_t, ipac_rw.ipac_r.ipac_ista) +#define IPAC_ID REG_OFFSET(ipac_reg_t, ipac_rw.ipac_r.ipac_id) +#define IPAC_ACFG REG_OFFSET(ipac_reg_t, ipac_rw.ipac_r.ipac_acfg) +#define IPAC_AOE REG_OFFSET(ipac_reg_t, ipac_rw.ipac_r.ipac_aoe) +#define IPAC_ARX REG_OFFSET(ipac_reg_t, ipac_rw.ipac_r.ipac_arx) +#define IPAC_PITA1 REG_OFFSET(ipac_reg_t, ipac_rw.ipac_r.ipac_pita1) +#define IPAC_PITA2 REG_OFFSET(ipac_reg_t, ipac_rw.ipac_r.ipac_pita2) +#define IPAC_POTA1 REG_OFFSET(ipac_reg_t, ipac_rw.ipac_r.ipac_pota1) +#define IPAC_POTA2 REG_OFFSET(ipac_reg_t, ipac_rw.ipac_r.ipac_pota2) +#define IPAC_PCFG REG_OFFSET(ipac_reg_t, ipac_rw.ipac_r.ipac_pcfg) +#define IPAC_SCFG REG_OFFSET(ipac_reg_t, ipac_rw.ipac_r.ipac_scfg) +#define IPAC_TIMR2 REG_OFFSET(ipac_reg_t, ipac_rw.ipac_r.ipac_timr2) + +/* IPAC write registers */ + +#define IPAC_MASK REG_OFFSET(ipac_reg_t, ipac_rw.ipac_w.ipac_mask) +#define IPAC_ATX REG_OFFSET(ipac_reg_t, ipac_rw.ipac_w.ipac_atx) + +/* register bits */ + +#define IPAC_CONF_AMP 0x80 +#define IPAC_CONF_CFS 0x40 +#define IPAC_CONF_TEM 0x20 +#define IPAC_CONF_PDS 0x10 +#define IPAC_CONF_IDH 0x08 +#define IPAC_CONF_SGO 0x04 +#define IPAC_CONF_ODS 0x02 +#define IPAC_CONF_IOF 0x01 + +#define IPAC_ISTA_INT1 0x80 +#define IPAC_ISTA_INT0 0x40 +#define IPAC_ISTA_ICD 0x20 +#define IPAC_ISTA_EXD 0x10 +#define IPAC_ISTA_ICA 0x08 +#define IPAC_ISTA_EXA 0x04 +#define IPAC_ISTA_ICB 0x02 +#define IPAC_ISTA_EXB 0x01 + +#define IPAC_MASK_INT1 0x80 +#define IPAC_MASK_INT0 0x40 +#define IPAC_MASK_ICD 0x20 +#define IPAC_MASK_EXD 0x10 +#define IPAC_MASK_ICA 0x08 +#define IPAC_MASK_EXA 0x04 +#define IPAC_MASK_ICB 0x02 +#define IPAC_MASK_EXB 0x01 + +#define IPAC_ACFG_OD7 0x80 +#define IPAC_ACFG_OD6 0x40 +#define IPAC_ACFG_OD5 0x20 +#define IPAC_ACFG_OD4 0x10 +#define IPAC_ACFG_OD3 0x08 +#define IPAC_ACFG_OD2 0x04 +#define IPAC_ACFG_EL1 0x02 +#define IPAC_ACFG_EL2 0x01 + +#define IPAC_AOE_OE7 0x80 +#define IPAC_AOE_OE6 0x40 +#define IPAC_AOE_OE5 0x20 +#define IPAC_AOE_OE4 0x10 +#define IPAC_AOE_OE3 0x08 +#define IPAC_AOE_OE2 0x04 + +#define IPAC_ARX_AR7 0x80 +#define IPAC_ARX_AR6 0x40 +#define IPAC_ARX_AR5 0x20 +#define IPAC_ARX_AR4 0x10 +#define IPAC_ARX_AR3 0x08 +#define IPAC_ARX_AR2 0x04 + +#define IPAC_ATX_AT7 0x80 +#define IPAC_ATX_AT6 0x40 +#define IPAC_ATX_AT5 0x20 +#define IPAC_ATX_AT4 0x10 +#define IPAC_ATX_AT3 0x08 +#define IPAC_ATX_AT2 0x04 + +#define IPAC_PITA1_ENA 0x80 +#define IPAC_PITA1_DUDD 0x40 + +#define IPAC_PITA2_ENA 0x80 +#define IPAC_PITA2_DUDD 0x40 + +#define IPAC_POTA1_ENA 0x80 +#define IPAC_POTA1_DUDD 0x40 + +#define IPAC_POTA2_ENA 0x80 +#define IPAC_POTA2_DUDD 0x40 + +#define IPAC_PCFG_DPS 0x80 +#define IPAC_PCFG_ACL 0x40 +#define IPAC_PCFG_LED 0x20 +#define IPAC_PCFG_PLD 0x10 +#define IPAC_PCFG_FBS 0x08 +#define IPAC_PCFG_CSL2 0x04 +#define IPAC_PCFG_CSL1 0x02 +#define IPAC_PCFG_CSL0 0x01 + +#define IPAC_SCFG_PRI 0x80 +#define IPAC_SCFG_TXD 0x40 +#define IPAC_SCFG_TLEN 0x20 + +#define IPAC_TIMR2_TMD 0x80 + +#endif /* _I4B_IPAC_H_ */ diff --git a/sys/i4b/layer1/isic/i4b_isac.c b/sys/i4b/layer1/isic/i4b_isac.c new file mode 100644 index 0000000..792d46b --- /dev/null +++ b/sys/i4b/layer1/isic/i4b_isac.c @@ -0,0 +1,666 @@ +/* + * 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_isac.c - i4b siemens isdn chipset driver ISAC handler + * --------------------------------------------------------- + * + * $Id: i4b_isac.c,v 1.7 2000/05/29 15:41:41 hm Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Mon May 29 16:45:08 2000] + * + *---------------------------------------------------------------------------*/ + +#include "isic.h" + +#if NISIC > 0 + +#include "opt_i4b.h" + +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include + +static u_char isic_isac_exir_hdlr(register struct l1_softc *sc, u_char exir); +static void isic_isac_ind_hdlr(register struct l1_softc *sc, int ind); + +/*---------------------------------------------------------------------------* + * ISAC interrupt service routine + *---------------------------------------------------------------------------*/ +void +isic_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 |= isic_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("isic_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 = L0ISICUNIT(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(L0ISICUNIT(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("isic_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) + isic_isac_ind_hdlr(sc, (ci >> 2) & 0xf); + } + + if(c) + { + ISAC_WRITE(I_CMDR, c); + ISACCMDRWRDELAY(); + } +} + +/*---------------------------------------------------------------------------* + * ISAC L1 Extended IRQ handler + *---------------------------------------------------------------------------*/ +static u_char +isic_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 +isic_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", isic_printstate(sc)); + if(sc->sc_bustyp == BUS_TYPE_IOM2) + isic_isac_l1_cmd(sc, CMD_AR8); + event = EV_INFO48; + i4b_l1_mph_status_ind(L0ISICUNIT(sc->sc_unit), STI_L1STAT, LAYER_ACTIVE, NULL); + break; + + case ISAC_CIRR_IAI10: + 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; + i4b_l1_mph_status_ind(L0ISICUNIT(sc->sc_unit), STI_L1STAT, LAYER_ACTIVE, NULL); + break; + + case ISAC_CIRR_IRSY: + NDBGL1(L1_I_CICO, "rx RSY in state %s", isic_printstate(sc)); + event = EV_RSY; + break; + + case ISAC_CIRR_IPU: + NDBGL1(L1_I_CICO, "rx PU in state %s", isic_printstate(sc)); + event = EV_PU; + break; + + case ISAC_CIRR_IDR: + 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: + NDBGL1(L1_I_CICO, "rx DID in state %s", isic_printstate(sc)); + event = EV_INFO0; + i4b_l1_mph_status_ind(L0ISICUNIT(sc->sc_unit), STI_L1STAT, LAYER_IDLE, NULL); + break; + + case ISAC_CIRR_IDIS: + NDBGL1(L1_I_CICO, "rx DIS in state %s", isic_printstate(sc)); + event = EV_DIS; + break; + + case ISAC_CIRR_IEI: + 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: + NDBGL1(L1_I_CICO, "rx ARD in state %s", isic_printstate(sc)); + event = EV_INFO2; + break; + + case ISAC_CIRR_ITI: + NDBGL1(L1_I_CICO, "rx TI in state %s", isic_printstate(sc)); + event = EV_INFO0; + break; + + case ISAC_CIRR_IATI: + NDBGL1(L1_I_CICO, "rx ATI in state %s", isic_printstate(sc)); + event = EV_INFO0; + break; + + case ISAC_CIRR_ISD: + NDBGL1(L1_I_CICO, "rx SD in state %s", isic_printstate(sc)); + event = EV_INFO0; + break; + + default: + NDBGL1(L1_I_ERR, "UNKNOWN Indication 0x%x in state %s", ind, isic_printstate(sc)); + event = EV_INFO0; + break; + } + isic_next_state(sc, event); +} + +/*---------------------------------------------------------------------------* + * execute a layer 1 command + *---------------------------------------------------------------------------*/ +void +isic_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, isic_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", isic_printstate(sc)); + cmd |= (ISAC_CIXR_CTIM << 2); + break; + + case CMD_RS: + NDBGL1(L1_I_CICO, "tx RS in state %s", isic_printstate(sc)); + cmd |= (ISAC_CIXR_CRS << 2); + break; + + case CMD_AR8: + NDBGL1(L1_I_CICO, "tx AR8 in state %s", isic_printstate(sc)); + cmd |= (ISAC_CIXR_CAR8 << 2); + break; + + case CMD_AR10: + NDBGL1(L1_I_CICO, "tx AR10 in state %s", isic_printstate(sc)); + cmd |= (ISAC_CIXR_CAR10 << 2); + break; + + case CMD_DIU: + NDBGL1(L1_I_CICO, "tx DIU in state %s", isic_printstate(sc)); + cmd |= (ISAC_CIXR_CDIU << 2); + break; + } + ISAC_WRITE(I_CIXR, cmd); +} + +/*---------------------------------------------------------------------------* + * L1 ISAC initialization + *---------------------------------------------------------------------------*/ +int +isic_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 /* NISIC > 0 */ diff --git a/sys/i4b/layer1/isic/i4b_isac.h b/sys/i4b/layer1/isic/i4b_isac.h new file mode 100644 index 0000000..2d92d000 --- /dev/null +++ b/sys/i4b/layer1/isic/i4b_isac.h @@ -0,0 +1,390 @@ +/* + * 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 + * 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. + * + *--------------------------------------------------------------------------- + * + * $Id: i4b_isac.h,v 1.2 2000/03/09 16:12:51 hm Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Mon Dec 13 22:01:25 1999] + * + *---------------------------------------------------------------------------*/ + +#ifndef I4B_ISAC_H_ +#define I4B_ISAC_H_ + +/* + * The ISAC databook specifies a delay of 2.5 DCL clock cycles between + * writes to the ISAC command register CMDR. This is the delay used to + * satisfy this requirement. + */ + +#define I4B_ISAC_CMDRWRDELAY 30 + +#if (I4B_ISAC_CMDRWRDELAY > 0) +#define ISACCMDRWRDELAY() DELAY(I4B_ISAC_CMDRWRDELAY) +#else +#warning "I4B_ISAC_CMDRWRDELAY set to 0!" +#define ISACCMDRWRDELAY() +#endif + +enum ISAC_VERSIONS { + ISAC_VA, /* 2085 A1 or A2, 2086/2186 V1.1 */ + ISAC_VB1, /* 2085 B1 */ + ISAC_VB2, /* 2085 B2 */ + ISAC_VB3, /* 2085 B3/V2.3 */ + ISAC_UNKN /* unknown version */ +}; + +#define ISAC_FIFO_LEN 32 /* 32 bytes FIFO on chip */ + +/* + * definitions of registers and bits for the ISAC ISDN chip. + */ + +typedef struct isac_reg { + + /* 32 byte deep FIFO always first */ + + unsigned char isac_fifo [ISAC_FIFO_LEN]; + + /* most registers can be read/written, but have different names */ + /* so define a union with read/write names to make that clear */ + + union { + struct { + unsigned char isac_ista; + unsigned char isac_star; + unsigned char isac_mode; + unsigned char isac_timr; + unsigned char isac_exir; + unsigned char isac_rbcl; + unsigned char isac_sapr; + unsigned char isac_rsta; + unsigned char dummy_28; + unsigned char isac_rhcr; + unsigned char isac_rbch; + unsigned char isac_star2; + unsigned char dummy_2c; + unsigned char dummy_2d; + unsigned char dummy_2e; + unsigned char dummt_2f; + unsigned char isac_spcr; + unsigned char isac_cirr; + unsigned char isac_mor; + unsigned char isac_sscr; + unsigned char isac_sfcr; + unsigned char isac_c1r; + unsigned char isac_c2r; + unsigned char isac_b1cr; + unsigned char isac_b2cr; + unsigned char isac_adf2; + unsigned char isac_mosr; + unsigned char isac_sqrr; + } isac_r; + struct { + unsigned char isac_mask; + unsigned char isac_cmdr; + unsigned char isac_mode; + unsigned char isac_timr; + unsigned char isac_xad1; + unsigned char isac_xad2; + unsigned char isac_sap1; + unsigned char isac_sap2; + unsigned char isac_tei1; + unsigned char isac_tei2; + unsigned char dummy_2a; + unsigned char isac_star2; + unsigned char dummy_2c; + unsigned char dummy_2d; + unsigned char dummy_2e; + unsigned char dummt_2f; + unsigned char isac_spcr; + unsigned char isac_cixr; + unsigned char isac_mox; + unsigned char isac_sscx; + unsigned char isac_sfcw; + unsigned char isac_c1r; + unsigned char isac_c2r; + unsigned char isac_stcr; + unsigned char isac_adf1; + unsigned char isac_adf2; + unsigned char isac_mocr; + unsigned char isac_sqxr; + } isac_w; + } isac_rw; +} isac_reg_t; + +#define REG_OFFSET(type, field) (int)(&(((type *)0)->field)) + +/* ISAC read registers */ + +#define i_ista isac_rw.isac_r.isac_ista +#define I_ISTA REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_ista) +#define i_star isac_rw.isac_r.isac_star +#define I_STAR REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_star) +#define i_mode isac_rw.isac_r.isac_mode +#define I_MODE REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_mode) +#define i_timr isac_rw.isac_r.isac_timr +#define I_TIMR REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_timr) +#define i_exir isac_rw.isac_r.isac_exir +#define I_EXIR REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_exir) +#define i_rbcl isac_rw.isac_r.isac_rbcl +#define I_RBCL REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_rbcl) +#define i_sapr isac_rw.isac_r.isac_sapr +#define I_SAPR REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_sapr) +#define i_rsta isac_rw.isac_r.isac_rsta +#define I_RSTA REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_rsta) +#define i_rhcr isac_rw.isac_r.isac_rhcr +#define I_RHCR REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_rhcr) +#define i_rbch isac_rw.isac_r.isac_rbch +#define I_RBCH REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_rbch) +#define i_star2 isac_rw.isac_r.isac_star2 +#define I_STAR2 REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_star2) +#define i_spcr isac_rw.isac_r.isac_spcr +#define I_SPCR REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_spcr) +#define i_cirr isac_rw.isac_r.isac_cirr +#define I_CIRR REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_cirr) +#define i_mor isac_rw.isac_r.isac_mor +#define I_MOR REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_mor) +#define i_sscr isac_rw.isac_r.isac_sscr +#define I_SSCR REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_sscr) +#define i_sfcr isac_rw.isac_r.isac_sfcr +#define I_SFCR REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_sfcr) +#define i_c1r isac_rw.isac_r.isac_c1r +#define I_C1R REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_c1r) +#define i_c2r isac_rw.isac_r.isac_c2r +#define I_C2R REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_c2r) +#define i_b1cr isac_rw.isac_r.isac_b1cr +#define I_B1CR REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_b1cr) +#define i_b2cr isac_rw.isac_r.isac_b2cr +#define I_B2CR REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_b2cr) +#define i_adf2 isac_rw.isac_r.isac_adf2 +#define I_ADF2 REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_adf2) +#define i_mosr isac_rw.isac_r.isac_mosr +#define I_MOSR REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_mosr) +#define i_sqrr isac_rw.isac_r.isac_sqrr +#define I_SQRR REG_OFFSET(isac_reg_t, isac_rw.isac_r.isac_sqrr) + +/* ISAC write registers - isac_mode, isac_timr, isac_star2, isac_spcr, */ +/* isac_c1r, isac_c2r, isac_adf2 see read registers */ + +#define i_mask isac_rw.isac_w.isac_mask +#define I_MASK REG_OFFSET(isac_reg_t, isac_rw.isac_w.isac_mask) +#define i_cmdr isac_rw.isac_w.isac_cmdr +#define I_CMDR REG_OFFSET(isac_reg_t, isac_rw.isac_w.isac_cmdr) +#define i_xad1 isac_rw.isac_w.isac_xad1 +#define I_XAD1 REG_OFFSET(isac_reg_t, isac_rw.isac_w.isac_xad1) +#define i_xad2 isac_rw.isac_w.isac_xad2 +#define I_XAD2 REG_OFFSET(isac_reg_t, isac_rw.isac_w.isac_xad2) +#define i_sap1 isac_rw.isac_w.isac_sap1 +#define I_SAP1 REG_OFFSET(isac_reg_t, isac_rw.isac_w.isac_sap1) +#define i_sap2 isac_rw.isac_w.isac_sap2 +#define I_SAP2 REG_OFFSET(isac_reg_t, isac_rw.isac_w.isac_sap2) +#define i_tei1 isac_rw.isac_w.isac_tei1 +#define i_tei2 isac_rw.isac_w.isac_tei2 +#define i_cixr isac_rw.isac_w.isac_cixr +#define I_CIXR REG_OFFSET(isac_reg_t, isac_rw.isac_w.isac_cixr) +#define I_CIX0 I_CIXR +#define i_mox isac_rw.isac_w.isac_mox +#define I_MOX REG_OFFSET(isac_reg_t, isac_rw.isac_w.isac_mox) +#define i_sscx isac_rw.isac_w.isac_sscx +#define I_SSCX REG_OFFSET(isac_reg_t, isac_rw.isac_w.isac_sscx) +#define i_sfcw isac_rw.isac_w.isac_sfcw +#define I_SFCW REG_OFFSET(isac_reg_t, isac_rw.isac_w.isac_sfcw) +#define i_stcr isac_rw.isac_w.isac_stcr +#define I_STCR REG_OFFSET(isac_reg_t, isac_rw.isac_w.isac_stcr) +#define i_adf1 isac_rw.isac_w.isac_adf1 +#define I_ADF1 REG_OFFSET(isac_reg_t, isac_rw.isac_w.isac_adf1) +#define i_mocr isac_rw.isac_w.isac_mocr +#define I_MOCR REG_OFFSET(isac_reg_t, isac_rw.isac_w.isac_mocr) +#define i_sqxr isac_rw.isac_w.isac_sqxr +#define I_SQXR REG_OFFSET(isac_reg_t, isac_rw.isac_w.isac_sqxr) + +#define ISAC_ISTA_RME 0x80 +#define ISAC_ISTA_RPF 0x40 +#define ISAC_ISTA_RSC 0x20 +#define ISAC_ISTA_XPR 0x10 +#define ISAC_ISTA_TIN 0x08 +#define ISAC_ISTA_CISQ 0x04 +#define ISAC_ISTA_SIN 0x02 +#define ISAC_ISTA_EXI 0x01 + +#define ISAC_MASK_RME 0x80 +#define ISAC_MASL_RPF 0x40 +#define ISAC_MASK_RSC 0x20 +#define ISAC_MASK_XPR 0x10 +#define ISAC_MASK_TIN 0x08 +#define ISAC_MASK_CISQ 0x04 +#define ISAC_MASK_SIN 0x02 +#define ISAC_MASK_EXI 0x01 +#define ISAC_MASK_ALL 0xff + +#define ISAC_STAR_XDOV 0x80 +#define ISAC_STAR_XFW 0x40 +#define ISAC_STAR_XRNR 0x20 +#define ISAC_STAR_RRNR 0x10 +#define ISAC_STAR_MBR 0x08 +#define ISAC_STAR_MAC1 0x04 +#define ISAC_STAR_BVS 0x02 +#define ISAC_STAR_MAC0 0x01 + +#define ISAC_CMDR_RMC 0x80 +#define ISAC_CMDR_RRES 0x40 +#define ISAC_CMDR_RNR 0x20 +#define ISAC_CMDR_STI 0x10 +#define ISAC_CMDR_XTF 0x08 +#define ISAC_CMDR_XIF 0x04 +#define ISAC_CMDR_XME 0x02 +#define ISAC_CMDR_XRES 0x01 + +#define ISAC_MODE_MDS2 0x80 +#define ISAC_MODE_MDS1 0x40 +#define ISAC_MODE_MDS0 0x20 +#define ISAC_MODE_TMD 0x10 +#define ISAC_MODE_RAC 0x08 +#define ISAC_MODE_DIM2 0x04 +#define ISAC_MODE_DIM1 0x02 +#define ISAC_MODE_DIM0 0x01 + +#define ISAC_EXIR_XMR 0x80 +#define ISAC_EXIR_XDU 0x40 +#define ISAC_EXIR_PCE 0x20 +#define ISAC_EXIR_RFO 0x10 +#define ISAC_EXIR_SOV 0x08 +#define ISAC_EXIR_MOS 0x04 +#define ISAC_EXIR_SAW 0x02 +#define ISAC_EXIR_WOV 0x01 + +#define ISAC_RSTA_RDA 0x80 +#define ISAC_RSTA_RDO 0x40 +#define ISAC_RSTA_CRC 0x20 +#define ISAC_RSTA_RAB 0x10 +#define ISAC_RSTA_SA1 0x08 +#define ISAC_RSTA_SA0 0x04 +#define ISAC_RSTA_CR 0x02 +#define ISAC_RSTA_TA 0x01 + +#define ISAC_RSTA_MASK 0x70 /* the interesting bits */ + +#define ISAC_RBCH_XAC 0x80 +#define ISAC_RBCH_VN1 0x40 +#define ISAC_RBCH_VN0 0x20 +#define ISAC_RBCH_OV 0x10 +/* the other 4 bits are the high bits of the receive byte count */ + +#define ISAC_SPCR_SPU 0x80 +#define ISAC_SPCR_SAC 0x40 +#define ISAC_SPCR_SPM 0x20 +#define ISAC_SPCR_TLP 0x10 +#define ISAC_SPCR_C1C1 0x08 +#define ISAC_SPCR_C1C0 0x04 +#define ISAC_SPCR_C2C1 0x02 +#define ISAC_SPCR_C2C0 0x01 + +#define ISAC_CIRR_SQC 0x80 +#define ISAC_CIRR_BAS 0x40 +/* bits 5-2 CODR */ +#define ISAC_CIRR_CIC0 0x02 +/* bit 0 is always 0 */ +/* C/I codes from bits 5-2 (>> 2 & 0xf) */ +/* the indications */ +#define ISAC_CIRR_IPU 0x07 +#define ISAC_CIRR_IDR 0x00 +#define ISAC_CIRR_ISD 0x02 +#define ISAC_CIRR_IDIS 0x03 +#define ISAC_CIRR_IEI 0x06 +#define ISAC_CIRR_IRSY 0x04 +#define ISAC_CIRR_IARD 0x08 +#define ISAC_CIRR_ITI 0x0a +#define ISAC_CIRR_IATI 0x0b +#define ISAC_CIRR_IAI8 0x0c +#define ISAC_CIRR_IAI10 0x0d +#define ISAC_CIRR_IDID 0x0f + +#define ISAC_CI_MASK 0x0f + +#define ISAC_CIXR_RSS 0x80 +#define ISAC_CIXR_BAC 0x40 +/* bits 5-2 CODX */ +#define ISAC_CIXR_TCX 0x02 +#define ISAC_CIXR_ECX 0x01 +/* in IOM-2 mode the low bits are always 1 */ +#define ISAC_CIX0_LOW 0x03 +/* C/I codes from bits 5-2 (>> 2 & 0xf) */ +/* the commands */ +#define ISAC_CIXR_CTIM 0 +#define ISAC_CIXR_CRS 0x01 +#define ISAC_CIXR_CSCZ 0x04 +#define ISAC_CIXR_CSSZ 0x02 +#define ISAC_CIXR_CAR8 0x08 +#define ISAC_CIXR_CAR10 0x09 +#define ISAC_CIXR_CARL 0x0a +#define ISAC_CIXR_CDIU 0x0f + +#define ISAC_STCR_TSF 0x80 +#define ISAC_STCR_TBA2 0x40 +#define ISAC_STCR_TBA1 0x20 +#define ISAC_STCR_TBA0 0x10 +#define ISAC_STCR_ST1 0x08 +#define ISAC_STCR_ST0 0x04 +#define ISAC_STCR_SC1 0x02 +#define ISAC_STCR_SC0 0x01 + +#define ISAC_ADF1_WTC1 0x80 +#define ISAC_ADF1_WTC2 0x40 +#define ISAC_ADF1_TEM 0x20 +#define ISAC_ADF1_PFS 0x10 +#define ISAC_ADF1_CFS 0x08 +#define ISAC_ADF1_FC2 0x04 +#define ISAC_ADF1_FC1 0x02 +#define ISAC_ADF1_ITF 0x01 + +#define ISAC_ADF2_IMS 0x80 +/* all other bits are 0 */ + +/* bits 7-5 are always 0 */ +#define ISAC_SQRR_SYN 0x10 +#define ISAC_SQRR_SQR1 0x08 +#define ISAC_SQRR_SQR2 0x04 +#define ISAC_SQRR_SQR3 0x02 +#define ISAC_SQRR_SQR4 0x01 + +#define ISAC_SQXR_IDC 0x80 +#define ISAC_SQXR_CFS 0x40 +#define ISAC_SQXR_CI1E 0x20 +#define ISAC_SQXR_SQIE 0x10 +#define ISAC_SQXR_SQX1 0x08 +#define ISAC_SQXR_SQX2 0x04 +#define ISAC_SQXR_SQX3 0x02 +#define ISAC_SQXR_SQX4 0x01 + +#endif /* I4B_ISAC_H_ */ diff --git a/sys/i4b/layer1/isic/i4b_isic.c b/sys/i4b/layer1/isic/i4b_isic.c new file mode 100644 index 0000000..97cbf73 --- /dev/null +++ b/sys/i4b/layer1/isic/i4b_isic.c @@ -0,0 +1,506 @@ +/* + * 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_isic.c - global isic stuff + * ============================== + * + * $Id: i4b_isic.c,v 1.6 2000/05/29 15:41:41 hm Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Mon May 29 16:45:24 2000] + * + *---------------------------------------------------------------------------*/ + +#include "isic.h" +#include "opt_i4b.h" + +#if NISIC > 0 + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include + +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" +}; + +/* 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 + *---------------------------------------------------------------------------*/ +void +isicintr(struct l1_softc *sc) +{ + if(sc->sc_ipac == 0) /* HSCX/ISAC interupt routine */ + { + u_char was_hscx_irq = 0; + u_char was_isac_irq = 0; + + register u_char hscx_irq_stat; + register u_char isac_irq_stat; + + for(;;) + { + /* get hscx irq status from hscx b ista */ + hscx_irq_stat = + HSCX_READ(HSCX_CH_B, H_ISTA) & ~HSCX_B_IMASK; + + /* get isac irq status */ + isac_irq_stat = ISAC_READ(I_ISTA); + + /* do as long as there are pending irqs in the chips */ + if(!hscx_irq_stat && !isac_irq_stat) + break; + + if(hscx_irq_stat & (HSCX_ISTA_RME | HSCX_ISTA_RPF | + HSCX_ISTA_RSC | HSCX_ISTA_XPR | + HSCX_ISTA_TIN | HSCX_ISTA_EXB)) + { + isic_hscx_irq(sc, hscx_irq_stat, + HSCX_CH_B, + hscx_irq_stat & HSCX_ISTA_EXB); + was_hscx_irq = 1; + } + + if(hscx_irq_stat & (HSCX_ISTA_ICA | HSCX_ISTA_EXA)) + { + isic_hscx_irq(sc, + HSCX_READ(HSCX_CH_A, H_ISTA) & ~HSCX_A_IMASK, + HSCX_CH_A, + hscx_irq_stat & HSCX_ISTA_EXA); + was_hscx_irq = 1; + } + + if(isac_irq_stat) + { + isic_isac_irq(sc, isac_irq_stat); /* isac handler */ + was_isac_irq = 1; + } + } + + HSCX_WRITE(0, H_MASK, 0xff); + ISAC_WRITE(I_MASK, 0xff); + HSCX_WRITE(1, H_MASK, 0xff); + +#ifdef ELSA_QS1ISA + DELAY(80); + + if((sc->sc_cardtyp == CARD_TYPEP_ELSAQS1ISA) && (sc->clearirq)) + { + sc->clearirq(sc); + } +#else + DELAY(100); +#endif + + HSCX_WRITE(0, H_MASK, HSCX_A_IMASK); + ISAC_WRITE(I_MASK, ISAC_IMASK); + HSCX_WRITE(1, H_MASK, HSCX_B_IMASK); + } + else /* IPAC interrupt routine */ + { + register u_char ipac_irq_stat; + register u_char was_ipac_irq = 0; + + for(;;) + { + /* get global irq status */ + + ipac_irq_stat = (IPAC_READ(IPAC_ISTA)) & 0x3f; + + /* check hscx a */ + + if(ipac_irq_stat & (IPAC_ISTA_ICA | IPAC_ISTA_EXA)) + { + /* HSCX A interrupt */ + isic_hscx_irq(sc, HSCX_READ(HSCX_CH_A, H_ISTA), + HSCX_CH_A, + ipac_irq_stat & IPAC_ISTA_EXA); + was_ipac_irq = 1; + } + if(ipac_irq_stat & (IPAC_ISTA_ICB | IPAC_ISTA_EXB)) + { + /* HSCX B interrupt */ + isic_hscx_irq(sc, HSCX_READ(HSCX_CH_B, H_ISTA), + HSCX_CH_B, + ipac_irq_stat & IPAC_ISTA_EXB); + was_ipac_irq = 1; + } + if(ipac_irq_stat & IPAC_ISTA_ICD) + { + /* ISAC interrupt */ + isic_isac_irq(sc, ISAC_READ(I_ISTA)); + was_ipac_irq = 1; + } + if(ipac_irq_stat & IPAC_ISTA_EXD) + { + /* force ISAC interrupt handling */ + isic_isac_irq(sc, ISAC_ISTA_EXI); + was_ipac_irq = 1; + } + + /* do as long as there are pending irqs in the chip */ + if(!ipac_irq_stat) + break; + } + + IPAC_WRITE(IPAC_MASK, 0xff); + DELAY(50); + IPAC_WRITE(IPAC_MASK, 0xc0); + } +} + +/*---------------------------------------------------------------------------* + * isic_recover - try to recover from irq lockup + *---------------------------------------------------------------------------*/ +void +isic_recover(struct l1_softc *sc) +{ + u_char byte; + + /* get hscx irq status from hscx b ista */ + + byte = HSCX_READ(HSCX_CH_B, H_ISTA); + + NDBGL1(L1_ERROR, "HSCX B: ISTA = 0x%x", byte); + + if(byte & HSCX_ISTA_ICA) + NDBGL1(L1_ERROR, "HSCX A: ISTA = 0x%x", (u_char)HSCX_READ(HSCX_CH_A, H_ISTA)); + + if(byte & HSCX_ISTA_EXB) + NDBGL1(L1_ERROR, "HSCX B: EXIR = 0x%x", (u_char)HSCX_READ(HSCX_CH_B, H_EXIR)); + + if(byte & HSCX_ISTA_EXA) + 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); + + 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, "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); + DELAY(100); + HSCX_WRITE(0, H_MASK, HSCX_A_IMASK); + HSCX_WRITE(1, H_MASK, HSCX_B_IMASK); + DELAY(100); + + NDBGL1(L1_ERROR, " ISAC: IMASK = 0x%x", ISAC_IMASK); + + ISAC_WRITE(I_MASK, 0xff); + DELAY(100); + ISAC_WRITE(I_MASK, ISAC_IMASK); +} + +/*---------------------------------------------------------------------------* + * isic_attach_common - common attach routine for all busses + *---------------------------------------------------------------------------*/ +int +isic_attach_common(device_t dev) +{ + char *drvid = NULL; + int unit = device_get_unit(dev); + struct l1_softc *sc = &l1_sc[unit]; + + sc->sc_unit = unit; + + sc->sc_isac_version = 0; + sc->sc_hscx_version = 0; + + if(sc->sc_ipac) + { + 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 + { + 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%d: Error, ISAC version %d unknown!\n", + unit, sc->sc_isac_version); + return ENXIO; + 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%d: Error, HSCX version %d unknown!\n", + unit, sc->sc_hscx_version); + return ENXIO; + break; + } + } + + isic_isac_init(sc); /* ISAC setup */ + + /* 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); + + isic_init_linktab(sc); /* setup linktab */ + + sc->sc_trace = TRACE_OFF; /* set trace level */ + + sc->sc_state = ISAC_IDLE; /* set state */ + + sc->sc_ibuf = NULL; /* input buffering */ + sc->sc_ib = NULL; + sc->sc_ilen = 0; + + sc->sc_obuf = NULL; /* output buffering */ + sc->sc_op = NULL; + sc->sc_ol = 0; + sc->sc_freeflag = 0; + + sc->sc_obuf2 = NULL; /* second output buffer */ + sc->sc_freeflag2 = 0; + + /* timer setup */ + + callout_handle_init(&sc->sc_T3_callout); + callout_handle_init(&sc->sc_T4_callout); + + /* init higher protocol layers */ + + 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) + { + case FLAG_TELES_S0_8: + drvid = "Teles S0/8 (or compatible)"; + break; + + case FLAG_TELES_S0_16: + drvid = "Teles S0/16 (or compatible)"; + break; + + case FLAG_TELES_S0_163: + drvid = "Teles S0/16.3"; + break; + + case FLAG_AVM_A1: + drvid = "AVM A1 or Fritz!Card Classic"; + break; + + case FLAG_AVM_A1_PCMCIA: + drvid = "AVM Fritz!Card PCMCIA"; + break; + + case FLAG_USR_ISDN_TA_INT: + drvid = "USRobotics Sportster ISDN TA intern"; + break; + + case FLAG_ITK_IX1: + drvid = "ITK ix1 micro"; + break; + + case FLAG_ELSA_PCC16: + drvid = "ELSA MicroLink ISDN/PCC-16"; + break; + + default: + drvid = NULL; /* pnp/pci cards announce themselves */ + break; + } + + if(drvid) + printf("isic%d: %s\n", unit, drvid); + + if(bootverbose) + { + /* announce chip versions */ + + if(sc->sc_ipac) + { + 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 + { + printf("isic%d: ISAC %s (IOM-%c)\n", + unit, + ISACversion[sc->sc_isac_version], + sc->sc_bustyp == BUS_TYPE_IOM1 ? '1' : '2'); + + printf("isic%d: HSCX %s\n", + unit, + HSCXversion[sc->sc_hscx_version]); + } + } + return 0; +} + +/*---------------------------------------------------------------------------* + * isic_detach_common - common detach routine for all busses + *---------------------------------------------------------------------------*/ +void +isic_detach_common(device_t dev) +{ + struct l1_softc *sc = &l1_sc[device_get_unit(dev)]; + int i; + + sc->sc_flags = 0; + + /* free interrupt resources */ + + if(sc->sc_resources.irq) + { + /* tear down interupt handler */ + bus_teardown_intr(dev, sc->sc_resources.irq, + (void(*)(void *))isicintr); + + /* free irq */ + bus_release_resource(dev, SYS_RES_IRQ, + sc->sc_resources.irq_rid, + sc->sc_resources.irq); + sc->sc_resources.irq_rid = 0; + sc->sc_resources.irq = 0; + } + + /* free memory resource */ + + if(sc->sc_resources.mem) + { + bus_release_resource(dev,SYS_RES_MEMORY, + sc->sc_resources.mem_rid, + sc->sc_resources.mem); + sc->sc_resources.mem_rid = 0; + sc->sc_resources.mem = 0; + } + + /* free iobases */ + + for(i=0; i < INFO_IO_BASES ; i++) + { + if(sc->sc_resources.io_base[i]) + { + bus_release_resource(dev, SYS_RES_IOPORT, + sc->sc_resources.io_rid[i], + sc->sc_resources.io_base[i]); + sc->sc_resources.io_rid[i] = 0; + sc->sc_resources.io_base[i] = 0; + } + } +} + +#endif /* NISIC > 0 */ + diff --git a/sys/i4b/layer1/isic/i4b_isic.h b/sys/i4b/layer1/isic/i4b_isic.h new file mode 100644 index 0000000..2cee7aa --- /dev/null +++ b/sys/i4b/layer1/isic/i4b_isic.h @@ -0,0 +1,363 @@ +/* + * 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.h,v 1.4 2000/09/04 09:17:26 hm Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Mon Sep 4 09:34:38 2000] + * + *---------------------------------------------------------------------------*/ + +#ifndef _I4B_ISIC_H_ +#define _I4B_ISIC_H_ + +#include +#include +#include +#include +#include + +#include + +#include + +/*--------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------*/ +#define FLAG_TELES_S0_8 1 +#define FLAG_TELES_S0_16 2 +#define FLAG_TELES_S0_163 3 +#define FLAG_AVM_A1 4 +#define FLAG_TELES_S0_163_PnP 5 +#define FLAG_CREATIX_S0_PnP 6 +#define FLAG_USR_ISDN_TA_INT 7 +#define FLAG_DRN_NGO 8 +#define FLAG_SWS 9 +#define FLAG_AVM_A1_PCMCIA 10 +#define FLAG_DYNALINK 11 +#define FLAG_BLMASTER 12 +#define FLAG_ELSA_QS1P_ISA 13 +#define FLAG_ELSA_QS1P_PCI 14 +#define FLAG_SIEMENS_ITALK 15 +#define FLAG_ELSA_MLIMC 16 +#define FLAG_ELSA_MLMCALL 17 +#define FLAG_ITK_IX1 18 +#define FLAG_AVMA1PCI 19 +#define FLAG_ELSA_PCC16 20 +#define FLAG_AVM_PNP 21 +#define FLAG_SIEMENS_ISURF2 22 +#define FLAG_ASUSCOM_IPAC 23 + +#define SEC_DELAY 1000000 /* one second DELAY for DELAY*/ + +#define MAX_DFRAME_LEN 264 /* max length of a D frame */ + +#define min(a,b) ((a)<(b)?(a):(b)) + +#define INFO_IO_BASES 50 /* 49 needed for USR */ + +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; +}; + +/*---------------------------------------------------------------------------* + * l1_bchan_state: the state of one B channel + *---------------------------------------------------------------------------*/ +typedef struct +{ + int unit; /* cards unit number */ + int channel; /* which channel is this*/ + caddr_t hscx; /* HSCX address */ + u_char hscx_mask; /* HSCX interrupt mask */ + int bprot; /* B channel protocol */ + int state; /* this channels state */ +#define HSCX_IDLE 0x00 /* channel idle */ +#define HSCX_TX_ACTIVE 0x01 /* tx running */ + + /* 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 */ + + /* link between b channel and driver */ + + isdn_link_t isic_isdn_linktab; /* b channel addresses */ + drvr_link_t *isic_drvr_linktab; /* ptr to driver linktab*/ + + /* statistics */ + + /* RSTA */ + + int stat_VFR; /* HSCX RSTA Valid FRame */ + int stat_RDO; /* HSCX RSTA Rx Data Overflow */ + int stat_CRC; /* HSCX RSTA CRC */ + int stat_RAB; /* HSCX RSTA Rx message ABorted */ + + /* EXIR */ + + int stat_XDU; /* HSCX EXIR tx data underrun */ + int stat_RFO; /* HSCX EXIR rx frame overflow */ + +} l1_bchan_state_t; + +/*---------------------------------------------------------------------------* + * l1_softc: the state of the layer 1 of the D channel + *---------------------------------------------------------------------------*/ +struct l1_softc +{ + int sc_unit; /* unit number */ + int sc_irq; /* interrupt vector */ + struct i4b_info sc_resources; + int sc_flags; + + int sc_port; /* port base address */ + + int sc_cardtyp; /* CARD_TYPEP_xxxx */ + + int sc_bustyp; /* IOM1 or IOM2 */ +#define BUS_TYPE_IOM1 0x01 +#define BUS_TYPE_IOM2 0x02 + + int sc_trace; /* output protocol data for tracing */ + unsigned int sc_trace_dcount;/* d channel trace frame counter */ + unsigned int sc_trace_bcount;/* b channel trace frame counter */ + + int sc_state; /* ISAC state flag */ +#define ISAC_IDLE 0x00 /* state = idle */ +#define ISAC_TX_ACTIVE 0x01 /* state = transmitter active */ + + int sc_init_tries; /* no of out tries to access S0 */ + + caddr_t sc_vmem_addr; /* card RAM virtual memory base */ + caddr_t sc_isac; /* ISAC port base addr */ +#define ISAC_BASE (sc->sc_isac) + + caddr_t sc_ipacbase; /* IPAC port base addr */ +#define IPAC_BASE (sc->sc_ipacbase) + + u_char sc_isac_mask; /* ISAC IRQ mask */ +#define ISAC_IMASK (sc->sc_isac_mask) + + l1_bchan_state_t sc_chan[2]; /* B-channel state */ +#define HSCX_A_BASE (sc->sc_chan[0].hscx) +#define HSCX_A_IMASK (sc->sc_chan[0].hscx_mask) +#define HSCX_B_BASE (sc->sc_chan[1].hscx) +#define HSCX_B_IMASK (sc->sc_chan[1].hscx_mask) + + struct mbuf *sc_ibuf; /* input buffer mgmt */ + u_short sc_ilen; + u_char *sc_ib; + /* this is for the irq TX routine */ + struct mbuf *sc_obuf; /* pointer to an mbuf with TX frame */ + u_char *sc_op; /* ptr to next chunk of frame to tx */ + int sc_ol; /* length of remaining frame to tx */ + int sc_freeflag; /* m_freem mbuf if set */ + + struct mbuf *sc_obuf2; /* pointer to an mbuf with TX frame */ + int sc_freeflag2; /* m_freem mbuf if set */ + + 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 */ + + struct callout_handle sc_T3_callout; + + int sc_I430T4; /* Timer T4 running */ + + struct callout_handle sc_T4_callout; + + /* + * byte fields for the AVM Fritz!Card PCI. These are packed into + * a u_int in the driver. + */ + u_char avma1pp_cmd; + u_char avma1pp_txl; + u_char avma1pp_prot; + + int sc_enabled; /* daemon is running */ + + int sc_ipac; /* flag, running on ipac */ + int sc_bfifolen; /* length of b channel fifos */ + +#define ISIC_WHAT_ISAC 0 +#define ISIC_WHAT_HSCXA 1 +#define ISIC_WHAT_HSCXB 2 +#define ISIC_WHAT_IPAC 3 + + u_int8_t (*readreg) (struct l1_softc *sc, int what, bus_size_t offs); + void (*writereg) (struct l1_softc *sc, int what, bus_size_t offs, u_int8_t data); + void (*readfifo) (struct l1_softc *sc, int what, void *buf, size_t size); + void (*writefifo) (struct l1_softc *sc, int what, void *data, size_t size); + void (*clearirq) (struct l1_softc *sc); + +#define ISAC_READ(r) (*sc->readreg)(sc, ISIC_WHAT_ISAC, (r)) +#define ISAC_WRITE(r,v) (*sc->writereg)(sc, ISIC_WHAT_ISAC, (r), (v)) +#define ISAC_RDFIFO(b,s) (*sc->readfifo)(sc, ISIC_WHAT_ISAC, (b), (s)) +#define ISAC_WRFIFO(b,s) (*sc->writefifo)(sc, ISIC_WHAT_ISAC, (b), (s)) + +#define HSCX_READ(n,r) (*sc->readreg)(sc, ISIC_WHAT_HSCXA+(n), (r)) +#define HSCX_WRITE(n,r,v) (*sc->writereg)(sc, ISIC_WHAT_HSCXA+(n), (r), (v)) +#define HSCX_RDFIFO(n,b,s) (*sc->readfifo)(sc, ISIC_WHAT_HSCXA+(n), (b), (s)) +#define HSCX_WRFIFO(n,b,s) (*sc->writefifo)(sc, ISIC_WHAT_HSCXA+(n), (b), (s)) + +#define IPAC_READ(r) (*sc->readreg)(sc, ISIC_WHAT_IPAC, (r)) +#define IPAC_WRITE(r, v) (*sc->writereg)(sc, ISIC_WHAT_IPAC, (r), (v)) +}; + +/*---------------------------------------------------------------------------* + * possible I.430/ISAC states + *---------------------------------------------------------------------------*/ +enum I430states { + 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/ISAC events + *---------------------------------------------------------------------------*/ +enum I430events { + EV_PHAR, /* PH ACTIVATE REQUEST */ + 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 +}; + +enum I430commands { + CMD_TIM, /* Timing */ + CMD_RS, /* Reset */ + CMD_AR8, /* Activation request pri 8 */ + CMD_AR10, /* Activation request pri 10 */ + CMD_DIU, /* Deactivate Indication Upstream */ + CMD_ILL /* Illegal command */ +}; + +#define N_COMMANDS CMD_ILL + +extern struct l1_softc l1_sc[]; + +extern void isicintr(struct l1_softc *sc); +extern int isic_attach_common(device_t dev); +extern void isic_detach_common(device_t dev); +extern void isic_recover(struct l1_softc *sc); + +extern void isic_bchannel_setup (int unit, int hscx_channel, int bprot, int activate ); + +extern void isic_init_linktab ( struct l1_softc *sc ); +extern int isic_isac_init ( struct l1_softc *sc ); +extern void isic_isac_irq ( struct l1_softc *sc, int r ); +extern void isic_isac_l1_cmd ( struct l1_softc *sc, int command ); +extern void isic_next_state ( struct l1_softc *sc, int event ); +extern char *isic_printstate ( struct l1_softc *sc ); + +extern int isic_hscx_fifo(l1_bchan_state_t *, struct l1_softc *); +extern void isic_hscx_init ( struct l1_softc *sc, int hscx_channel, int activate ); +extern void isic_hscx_irq ( struct l1_softc *sc, u_char ista, int hscx_channel, u_char ex_irq ); +extern int isic_hscx_silence ( unsigned char *data, int len ); +extern void isic_hscx_cmd( struct l1_softc *sc, int h_chan, unsigned char cmd ); +extern void isic_hscx_waitxfw( struct l1_softc *sc, int h_chan ); + +extern int isic_probe_s016 (device_t dev); +extern int isic_attach_s016 (device_t dev); + +extern int isic_probe_s08 (device_t dev); +extern int isic_attach_s08 (device_t dev); + +extern int isic_probe_Epcc16 (device_t dev); +extern int isic_attach_Epcc16 (device_t dev); + +extern int isic_probe_s0163 (device_t dev); +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_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 + +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/isic/i4b_isic_isa.c b/sys/i4b/layer1/isic/i4b_isic_isa.c new file mode 100644 index 0000000..40b05bd --- /dev/null +++ b/sys/i4b/layer1/isic/i4b_isic_isa.c @@ -0,0 +1,224 @@ +/* + * 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_isic_isa.c - ISA bus interface + * ================================== + * + * $Id: i4b_isic_isa.c,v 1.3 2000/05/29 15:41:41 hm Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Mon May 29 16:45:34 2000] + * + *---------------------------------------------------------------------------*/ + +#include "isic.h" +#include "opt_i4b.h" + +#if NISIC > 0 + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include + +/* #include */ +#include +#include + +#include +#include +#include + +struct l1_softc l1_sc[ISIC_MAXUNIT]; + +static int isic_isa_probe(device_t dev); +static int isic_isa_attach(device_t dev); + +static device_method_t isic_methods[] = { + DEVMETHOD(device_probe, isic_isa_probe), + DEVMETHOD(device_attach, isic_isa_attach), + { 0, 0 } +}; + +static driver_t isic_driver = { + "isic", + isic_methods, + 0 +}; + +static devclass_t isic_devclass; + +DRIVER_MODULE(isic, isa, isic_driver, isic_devclass, 0, 0); + +/*---------------------------------------------------------------------------* + * probe for ISA non-PnP cards + *---------------------------------------------------------------------------*/ +static int +isic_isa_probe(device_t dev) +{ + int ret = ENXIO; + + if(isa_get_vendorid(dev)) /* no PnP probes here */ + return ENXIO; + + switch(device_get_flags(dev)) + { +#ifdef TEL_S0_16 + case FLAG_TELES_S0_16: + ret = isic_probe_s016(dev); + break; +#endif + +#ifdef TEL_S0_8 + case FLAG_TELES_S0_8: + ret = isic_probe_s08(dev); + break; +#endif + +#ifdef ELSA_PCC16 + case FLAG_ELSA_PCC16: + ret = isic_probe_Epcc16(dev); + break; +#endif + +#ifdef TEL_S0_16_3 + case FLAG_TELES_S0_163: + ret = isic_probe_s0163(dev); + break; +#endif + +#ifdef AVM_A1 + case FLAG_AVM_A1: + ret = isic_probe_avma1(dev); + break; +#endif + +#ifdef USR_STI + case FLAG_USR_ISDN_TA_INT: + ret = isic_probe_usrtai(dev); + break; +#endif + +#ifdef ITKIX1 + case FLAG_ITK_IX1: + ret = isic_probe_itkix1(dev); + break; +#endif + + default: + printf("isic%d: probe, unknown flag: %d\n", + device_get_unit(dev), device_get_flags(dev)); + break; + } + return(ret); +} + +/*---------------------------------------------------------------------------* + * attach for ISA non-PnP cards + *---------------------------------------------------------------------------*/ +static int +isic_isa_attach(device_t dev) +{ + int ret = ENXIO; + + struct l1_softc *sc = &l1_sc[device_get_unit(dev)]; + + sc->sc_unit = device_get_unit(dev); + + /* card dependent setup */ + + switch(sc->sc_flags) + { +#ifdef TEL_S0_16 + case FLAG_TELES_S0_16: + ret = isic_attach_s016(dev); + break; +#endif + +#ifdef TEL_S0_8 + case FLAG_TELES_S0_8: + ret = isic_attach_s08(dev); + break; +#endif + +#ifdef ELSA_PCC16 + case FLAG_ELSA_PCC16: + ret = isic_attach_Epcc16(dev); + break; +#endif + +#ifdef TEL_S0_16_3 + case FLAG_TELES_S0_163: + ret = isic_attach_s0163(dev); + break; +#endif + +#ifdef AVM_A1 + case FLAG_AVM_A1: + ret = isic_attach_avma1(dev); + break; +#endif + +#ifdef USR_STI + case FLAG_USR_ISDN_TA_INT: + ret = isic_attach_usrtai(dev); + break; +#endif + +#ifdef ITKIX1 + case FLAG_ITK_IX1: + ret = isic_attach_itkix1(dev); + break; +#endif + + default: + printf("isic%d: attach, unknown flag: %d\n", + device_get_unit(dev), device_get_flags(dev)); + break; + } + + if(ret) + return(ret); + + ret = isic_attach_common(dev); + + return(ret); +} +#endif /* NISIC > 0 */ diff --git a/sys/i4b/layer1/isic/i4b_isic_pnp.c b/sys/i4b/layer1/isic/i4b_isic_pnp.c new file mode 100644 index 0000000..3fe6595 --- /dev/null +++ b/sys/i4b/layer1/isic/i4b_isic_pnp.c @@ -0,0 +1,317 @@ +/* + * Copyright (c) 1998 Eivind Eklund. All rights reserved. + * + * Copyright (c) 1998, 1999 German Tischler. 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 + * 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_pnp.c - i4b pnp support + * -------------------------------- + * + * $Id: i4b_isic_pnp.c,v 1.2 2000/03/09 16:12:51 hm Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Thu Mar 9 16:04:10 2000] + * + *---------------------------------------------------------------------------*/ + +#include "isic.h" +#include "opt_i4b.h" + +#if (NISIC > 0) + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include + +#define VID_TEL163PNP 0x10212750 /* Teles 16.3 PnP */ +#define VID_CREATIXPP 0x0000980e /* Creatix S0/16 P+P */ +#define VID_DYNALINK 0x88167506 /* Dynalink */ +#define VID_SEDLBAUER 0x0100274c /* Sedlbauer WinSpeed */ +#define VID_NICCYGO 0x5001814c /* Neuhaus Niccy GO@ */ +#define VID_ELSAQS1P 0x33019315 /* ELSA Quickstep1000pro*/ +#define VID_ITK0025 0x25008b26 /* ITK Ix1 Micro V3 */ +#define VID_AVMPNP 0x0009cd06 /* AVM Fritz! PnP */ +#define VID_SIESURF2 0x2000254d /* Siemens I-Surf 2.0 PnP*/ +#define VID_ASUSCOM_IPAC 0x90167506 /* Asuscom (with IPAC) */ + +static struct isic_pnp_ids { + u_long vend_id; + char *id_str; +} isic_pnp_ids[] = { +#if defined(TEL_S0_16_3_P) || defined(CRTX_S0_P) + { VID_TEL163PNP, "Teles S0/16.3 PnP" }, + { VID_CREATIXPP, "Creatix S0/16 PnP" }, +#endif +#ifdef DYNALINK + { VID_DYNALINK, "Dynalink IS64PH" }, +#endif +#ifdef SEDLBAUER + { VID_SEDLBAUER, "Sedlbauer WinSpeed" }, +#endif +#ifdef DRN_NGO + { VID_NICCYGO, "Dr.Neuhaus Niccy Go@" }, +#endif +#ifdef ELSA_QS1ISA + { VID_ELSAQS1P, "ELSA QuickStep 1000pro" }, +#endif +#ifdef ITKIX1 + { VID_ITK0025, "ITK ix1 Micro V3.0" }, +#endif +#ifdef AVM_PNP + { VID_AVMPNP, "AVM Fritz!Card PnP" }, +#endif +#ifdef SIEMENS_ISURF2 + { VID_SIESURF2, "Siemens I-Surf 2.0 PnP" }, +#endif +#ifdef ASUSCOM_IPAC + { VID_ASUSCOM_IPAC, "Asuscom ISDNLink 128 PnP" }, +#endif + { 0, 0 } +}; + +static int isic_pnp_probe(device_t dev); +static int isic_pnp_attach(device_t dev); + +static device_method_t isic_pnp_methods[] = { + DEVMETHOD(device_probe, isic_pnp_probe), + DEVMETHOD(device_attach, isic_pnp_attach), + { 0, 0 } +}; + +static driver_t isic_pnp_driver = { + "isic", + isic_pnp_methods, + 0, +}; + +static devclass_t isic_devclass; + +DRIVER_MODULE(isicpnp, isa, isic_pnp_driver, isic_devclass, 0, 0); + +/*---------------------------------------------------------------------------* + * probe for ISA PnP cards + *---------------------------------------------------------------------------*/ +int +isic_pnp_probe(device_t dev) +{ + struct isic_pnp_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 */ + + for(ids = isic_pnp_ids; ids->vend_id != 0; ids++) + { + if(vend_id == ids->vend_id) + { + string = ids->id_str; + break; + } + } + + if(string) /* set name if we have one */ + { + device_set_desc(dev, string); /* set description */ + return 0; + } + else + { + return ENXIO; + } +} + +/*---------------------------------------------------------------------------* + * attach for ISA PnP cards + *---------------------------------------------------------------------------*/ +int +isic_pnp_attach(device_t dev) +{ + u_int32_t vend_id = isa_get_vendorid(dev); /* vendor id */ + unsigned int unit = device_get_unit(dev); /* get unit */ + const char *name = device_get_desc(dev); /* get description */ + struct l1_softc *sc = 0; /* softc */ + void *ih = 0; /* a dummy */ + int ret; + + /* see if we are out of bounds */ + + if(unit >= ISIC_MAXUNIT) + { + printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for %s\n", unit, unit, name); + return ENXIO; + } + + /* get information structure for this unit */ + + sc = &l1_sc[unit]; + + /* 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_pnp_attach: Couldn't get my io_base.\n"); + return ENXIO; + } + + /* will not be used for pnp devices */ + + sc->sc_port = rman_get_start(sc->sc_resources.io_base[0]); + + /* 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: Could not get irq.\n",unit); + isic_detach_common(dev); + return ENXIO; + } + + /* not needed */ + sc->sc_irq = rman_get_start(sc->sc_resources.irq); + + + /* set flag so we know what this card is */ + + ret = ENXIO; + + switch(vend_id) + { +#if defined(TEL_S0_16_3_P) || defined(CRTX_S0_P) + case VID_TEL163PNP: + sc->sc_flags = FLAG_TELES_S0_163_PnP; + ret = isic_attach_Cs0P(dev); + break; + + case VID_CREATIXPP: + sc->sc_flags = FLAG_CREATIX_S0_PnP; + ret = isic_attach_Cs0P(dev); + break; +#endif +#ifdef DYNALINK + case VID_DYNALINK: + sc->sc_flags = FLAG_DYNALINK; + ret = isic_attach_Dyn(dev); + break; +#endif +#ifdef SEDLBAUER + case VID_SEDLBAUER: + sc->sc_flags = FLAG_SWS; + ret = isic_attach_sws(dev); + break; +#endif +#ifdef DRN_NGO + case VID_NICCYGO: + sc->sc_flags = FLAG_DRN_NGO; + ret = isic_attach_drnngo(dev); + break; +#endif +#ifdef ELSA_QS1ISA + case VID_ELSAQS1P: + sc->sc_flags = FLAG_ELSA_QS1P_ISA; + ret = isic_attach_Eqs1pi(dev); + break; +#endif +#ifdef ITKIX1 + case VID_ITK0025: + sc->sc_flags = FLAG_ITK_IX1; + ret = isic_attach_itkix1(dev); + break; +#endif +#ifdef AVM_PNP + case VID_AVMPNP: + sc->sc_flags = FLAG_AVM_PNP; + ret = isic_attach_avm_pnp(dev); + break; +#endif +#ifdef SIEMENS_ISURF2 + case VID_SIESURF2: + sc->sc_flags = FLAG_SIEMENS_ISURF2; + ret = isic_attach_siemens_isurf(dev); + break; +#endif +#ifdef ASUSCOM_IPAC + case VID_ASUSCOM_IPAC: + sc->sc_flags = FLAG_ASUSCOM_IPAC; + ret = isic_attach_asi(dev); + break; +#endif + default: + printf("isic%d: Error, no driver for %s\n", unit, name); + ret = ENXIO; + break; + } + + if(ret) + { + isic_detach_common(dev); + return ENXIO; + } + + if(isic_attach_common(dev)) + { + /* unset flag */ + sc->sc_flags = 0; + + /* free irq here, it hasn't been attached yet */ + bus_release_resource(dev,SYS_RES_IRQ,sc->sc_resources.irq_rid, + sc->sc_resources.irq); + sc->sc_resources.irq = 0; + isic_detach_common(dev); + return ENXIO; + } + else + { + /* setup intr routine */ + bus_setup_intr(dev,sc->sc_resources.irq,INTR_TYPE_NET, + (void(*)(void*))isicintr, + sc,&ih); + return 0; + } +} +#endif /* (NISIC > 0) */ diff --git a/sys/i4b/layer1/isic/i4b_itk_ix1.c b/sys/i4b/layer1/isic/i4b_itk_ix1.c new file mode 100644 index 0000000..9bf94c5 --- /dev/null +++ b/sys/i4b/layer1/isic/i4b_itk_ix1.c @@ -0,0 +1,409 @@ +/* + * 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. The name of the author may not be used to endorse or promote products + * derived from this software withough specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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_itk_ix1.c - ITK ix1 micro passive card driver for isdn4bsd + * -------------------------------------------------------------- + * + * $Id: i4b_itk_ix1.c,v 1.1 2000/08/24 14:08:41 hm Exp $ + * + * last edit-date: [Thu Aug 24 15:44:33 2000] + * + * $FreeBSD$ + * + *--------------------------------------------------------------------------- + * + * The ITK ix1 micro ISDN card is an ISA card with one region + * of four io ports mapped and a fixed irq all jumpered on the card. + * Access to the board is straight forward and simmilar to + * the ELSA and DYNALINK cards. If a PCI version of this card + * exists all we need is probably a pci-bus attachment, all + * this low level routines should work imediately. + * + * To reset the card: + * - write 0x01 to ITK_CONFIG + * - wait >= 10 ms + * - write 0x00 to ITK_CONFIG + * + * To read or write data: + * - write address to ITK_ALE port + * - read data from or write data to ITK_ISAC_DATA port or ITK_HSCX_DATA port + * The two HSCX channel registers are offset by HSCXA (0x00) and HSCXB (0x40). + * + * The probe routine was derived by trial and error from a representative + * sample of two cards ;-) The standard way (checking HSCX versions) + * was extended by reading a zero from a non existant HSCX register (register + * 0xff). Reading the config register gives varying results, so this doesn't + * seem to be used as an id register (like the Teles S0/16.3). + * + * If the probe fails for your card use "options ITK_PROBE_DEBUG" to get + * additional debug output. + * + *---------------------------------------------------------------------------*/ + +#include "isic.h" +#include "opt_i4b.h" + +#if NISIC > 0 && defined(ITKIX1) + +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include + +#include +#include +#include + +#include +#include + +/* Register offsets */ +#define ITK_ISAC_DATA 0 +#define ITK_HSCX_DATA 1 +#define ITK_ALE 2 +#define ITK_CONFIG 3 + +/* Size of IO range to allocate for this card */ +#define ITK_IO_SIZE 4 + +/* Register offsets for the two HSCX channels */ +#define HSCXA 0 +#define HSCXB 0x40 + +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 + */ +int +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; + + #if defined(ITK_PROBE_DEBUG) + printf("Checking unit %u\n", unit); + #endif + + /* check max unit range */ + if(unit >= ISIC_MAXUNIT) + { + printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for ITK IX1!\n", + unit, unit); + return ENXIO; + } + + 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; + } + + #if defined(ITK_PROBE_DEBUG) + printf("done.\n"); + #endif + + 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); + + /* select invalid register */ + bus_space_write_1(t, h, ITK_ALE, 0xff); + /* get HSCX data for this non existent register */ + hd = bus_space_read_1(t, h, ITK_HSCX_DATA); + /* get HSCX version info */ + bus_space_write_1(t, h, ITK_ALE, HSCXA + H_VSTR); + hv1 = bus_space_read_1(t, h, ITK_HSCX_DATA); + bus_space_write_1(t, h, ITK_ALE, HSCXB + H_VSTR); + hv2 = bus_space_read_1(t, h, ITK_HSCX_DATA); + + 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); + + #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"); + isic_detach_common(dev); + return ENXIO; +#else + if ( ret ) + { + return 0; + } + else + { + isic_detach_common(dev); + return ENXIO; + } +#endif +} + +/* + * Attach card + */ +int +isic_attach_itkix1(device_t dev) +{ + 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; + 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; + + bus_space_write_1(t, h, ITK_CONFIG, 1); + DELAY(SEC_DELAY / 10); + bus_space_write_1(t, h, ITK_CONFIG, 0); + DELAY(SEC_DELAY / 10); + + return 0; +} + +#endif /* ITKIX1 */ diff --git a/sys/i4b/layer1/isic/i4b_l1.c b/sys/i4b/layer1/isic/i4b_l1.c new file mode 100644 index 0000000..f19eda8 --- /dev/null +++ b/sys/i4b/layer1/isic/i4b_l1.c @@ -0,0 +1,261 @@ +/* + * 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.c - isdn4bsd layer 1 handler + * ----------------------------------- + * + * $Id: i4b_l1.c,v 1.7 2000/06/02 16:14:36 hm Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Fri Jun 2 18:09:53 2000] + * + *---------------------------------------------------------------------------*/ + +#include "isic.h" + +#if NISIC > 0 + +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include + +/*---------------------------------------------------------------------------* + * + * 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 +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 + NDBGL1(L1_PRIM, "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!"); + isic_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", isic_printstate(sc)); + + if(sc->sc_trace & TRACE_D_TX) + { + i4b_trace_hdr_t hdr; + hdr.unit = L0ISICUNIT(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", isic_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 = L0ISICUNIT(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 +isic_ph_activate_req(int unit) +{ + struct l1_softc *sc = &l1_sc[unit]; + NDBGL1(L1_PRIM, "unit %d", unit); + isic_next_state(sc, EV_PHAR); + return(0); +} + +/*---------------------------------------------------------------------------* + * command from the upper layers + *---------------------------------------------------------------------------*/ +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 */ + 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; + + 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: + NDBGL1(L1_ERROR, "ERROR, unknown command = %d, unit = %d, parm = %d", command, unit, (unsigned int)parm); + break; + } + + return(0); +} + +#endif /* NISIC > 0 */ diff --git a/sys/i4b/layer1/isic/i4b_l1fsm.c b/sys/i4b/layer1/isic/i4b_l1fsm.c new file mode 100644 index 0000000..d3ce147 --- /dev/null +++ b/sys/i4b/layer1/isic/i4b_l1fsm.c @@ -0,0 +1,520 @@ +/* + * 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_l1fsm.c - isdn4bsd layer 1 I.430 state machine + * -------------------------------------------------- + * + * $Id: i4b_l1fsm.c,v 1.8 2000/05/29 15:41:41 hm Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Mon May 29 16:46:03 2000] + * + *---------------------------------------------------------------------------*/ + +#include "isic.h" + +#if NISIC > 0 + +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include + +#include + +#include + +#include + +#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", isic_printstate(sc)); + sc->sc_I430T3 = 0; + + /* XXX try some recovery here XXX */ + + isic_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(L0ISICUNIT(sc->sc_unit), STI_NOL1ACC, 0, NULL); + } + + isic_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", isic_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", isic_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(L0ISICUNIT(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", isic_printstate(sc)); + sc->sc_I430T4 = 0; + i4b_l1_mph_status_ind(L0ISICUNIT(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", isic_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", isic_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(L0ISICUNIT(sc->sc_unit)); + + T3_stop(sc); + + if(sc->sc_trace & TRACE_I) + { + i4b_trace_hdr_t hdr; + char info = INFO4_8; + + hdr.unit = L0ISICUNIT(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(L0ISICUNIT(sc->sc_unit)); + + T3_stop(sc); + + if(sc->sc_trace & TRACE_I) + { + i4b_trace_hdr_t hdr; + char info = INFO4_10; + + hdr.unit = L0ISICUNIT(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 = L0ISICUNIT(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(L0ISICUNIT(sc->sc_unit)); + + if(sc->sc_trace & TRACE_I) + { + i4b_trace_hdr_t hdr; + char info = INFO0; + + hdr.unit = L0ISICUNIT(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(L0ISICUNIT(sc->sc_unit)); + + T4_start(sc); + + if(sc->sc_trace & TRACE_I) + { + i4b_trace_hdr_t hdr; + char info = INFO0; + + hdr.unit = L0ISICUNIT(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 = L0ISICUNIT(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); + } + + isic_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 = L0ISICUNIT(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 isic_state_tab { + void (*func) (struct l1_softc *sc); /* function to execute */ + int newstate; /* next state */ +} isic_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 +isic_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 = isic_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]); + + (*isic_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 * +isic_printstate(struct l1_softc *sc) +{ + return((char *) state_text[sc->sc_I430state]); +} +#endif + +#endif /* NISIC > 0 */ + diff --git a/sys/i4b/layer1/isic/i4b_siemens_isurf.c b/sys/i4b/layer1/isic/i4b_siemens_isurf.c new file mode 100644 index 0000000..52a70ec --- /dev/null +++ b/sys/i4b/layer1/isic/i4b_siemens_isurf.c @@ -0,0 +1,244 @@ +/* + * 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 + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * 4. Altered versions must be plainly marked as such, and must not be + * misrepresented as being the original software and/or documentation. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + *--------------------------------------------------------------------------- + * Based on ELSA Quickstep 1000pro PCI driver (i4b_elsa_qs1p.c) + *--------------------------------------------------------------------------- + * In case of trouble please contact Udo Schweigert + *--------------------------------------------------------------------------- + * + * Siemens I-Surf 2.0 PnP specific routines for isic driver + * -------------------------------------------------------- + * + * $Id: i4b_siemens_isurf.c,v 1.3 2000/05/29 15:41:41 hm Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Mon May 29 16:46:31 2000] + * + *---------------------------------------------------------------------------*/ + +#include "isic.h" +#include "opt_i4b.h" + +#if NISIC > 0 && defined(SIEMENS_ISURF2) + +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include + +#include +/* #include */ +#include + +#include +#include +#include +#include + +/* masks for register encoded in base addr */ + +#define SIE_ISURF_BASE_MASK 0x0ffff +#define SIE_ISURF_OFF_MASK 0xf0000 + +/* register id's to be encoded in base addr */ + +#define SIE_ISURF_IDISAC 0x00000 +#define SIE_ISURF_IDHSCXA 0x10000 +#define SIE_ISURF_IDHSCXB 0x20000 +#define SIE_ISURF_IDIPAC 0x40000 + +/* offsets from base address */ + +#define SIE_ISURF_OFF_ALE 0x00 +#define SIE_ISURF_OFF_RW 0x01 + +/*---------------------------------------------------------------------------* + * Siemens I-Surf 2.0 PnP ISAC get fifo routine + *---------------------------------------------------------------------------*/ +static void +siemens_isurf_read_fifo(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,SIE_ISURF_OFF_ALE,IPAC_ISAC_OFF); + bus_space_read_multi_1(t,h,SIE_ISURF_OFF_RW,buf,size); + break; + case ISIC_WHAT_HSCXA: + bus_space_write_1(t,h,SIE_ISURF_OFF_ALE,IPAC_HSCXA_OFF); + bus_space_read_multi_1(t,h,SIE_ISURF_OFF_RW,buf,size); + break; + case ISIC_WHAT_HSCXB: + bus_space_write_1(t,h,SIE_ISURF_OFF_ALE,IPAC_HSCXB_OFF); + bus_space_read_multi_1(t,h,SIE_ISURF_OFF_RW,buf,size); + break; + } +} + +/*---------------------------------------------------------------------------* + * Siemens I-Surf 2.0 PnP ISAC put fifo routine + *---------------------------------------------------------------------------*/ +static void +siemens_isurf_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,SIE_ISURF_OFF_ALE,IPAC_ISAC_OFF); + bus_space_write_multi_1(t,h,SIE_ISURF_OFF_RW,buf,size); + break; + case ISIC_WHAT_HSCXA: + bus_space_write_1(t,h,SIE_ISURF_OFF_ALE,IPAC_HSCXA_OFF); + bus_space_write_multi_1(t,h,SIE_ISURF_OFF_RW,buf,size); + break; + case ISIC_WHAT_HSCXB: + bus_space_write_1(t,h,SIE_ISURF_OFF_ALE,IPAC_HSCXB_OFF); + bus_space_write_multi_1(t,h,SIE_ISURF_OFF_RW,buf,size); + break; + } +} + +/*---------------------------------------------------------------------------* + * Siemens I-Surf 2.0 PnP ISAC put register routine + *---------------------------------------------------------------------------*/ +static void +siemens_isurf_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,SIE_ISURF_OFF_ALE,reg+IPAC_ISAC_OFF); + bus_space_write_1(t,h,SIE_ISURF_OFF_RW,data); + break; + case ISIC_WHAT_HSCXA: + bus_space_write_1(t,h,SIE_ISURF_OFF_ALE,reg+IPAC_HSCXA_OFF); + bus_space_write_1(t,h,SIE_ISURF_OFF_RW,data); + break; + case ISIC_WHAT_HSCXB: + bus_space_write_1(t,h,SIE_ISURF_OFF_ALE,reg+IPAC_HSCXB_OFF); + bus_space_write_1(t,h,SIE_ISURF_OFF_RW,data); + break; + case ISIC_WHAT_IPAC: + bus_space_write_1(t,h,SIE_ISURF_OFF_ALE,reg+IPAC_IPAC_OFF); + bus_space_write_1(t,h,SIE_ISURF_OFF_RW,data); + break; + } +} + +/*---------------------------------------------------------------------------* + * Siemens I-Surf 2.0 PnP ISAC get register routine + *---------------------------------------------------------------------------*/ +static u_int8_t +siemens_isurf_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,SIE_ISURF_OFF_ALE,reg+IPAC_ISAC_OFF); + return bus_space_read_1(t,h,SIE_ISURF_OFF_RW); + case ISIC_WHAT_HSCXA: + bus_space_write_1(t,h,SIE_ISURF_OFF_ALE,reg+IPAC_HSCXA_OFF); + return bus_space_read_1(t,h,SIE_ISURF_OFF_RW); + case ISIC_WHAT_HSCXB: + bus_space_write_1(t,h,SIE_ISURF_OFF_ALE,reg+IPAC_HSCXB_OFF); + return bus_space_read_1(t,h,SIE_ISURF_OFF_RW); + case ISIC_WHAT_IPAC: + bus_space_write_1(t,h,SIE_ISURF_OFF_ALE,reg+IPAC_IPAC_OFF); + return bus_space_read_1(t,h,SIE_ISURF_OFF_RW); + default: + return 0; + } +} + +/*---------------------------------------------------------------------------* + * isic_attach_siemens_isurf - attach for Siemens I-Surf 2.0 PnP + *---------------------------------------------------------------------------*/ +int +isic_attach_siemens_isurf(device_t dev) +{ + int unit = device_get_unit(dev); + struct l1_softc *sc = &l1_sc[unit]; + + /* setup access routines */ + + sc->clearirq = NULL; + sc->readreg = siemens_isurf_read_reg; + sc->writereg = siemens_isurf_write_reg; + + sc->readfifo = siemens_isurf_read_fifo; + sc->writefifo = siemens_isurf_write_fifo; + + /* setup card type */ + + sc->sc_cardtyp = CARD_TYPEP_SIE_ISURF2; + + /* setup IOM bus type */ + + sc->sc_bustyp = BUS_TYPE_IOM2; + + /* setup chip type = IPAC ! */ + + sc->sc_ipac = 1; + sc->sc_bfifolen = IPAC_BFIFO_LEN; + + /* enable hscx/isac irq's */ + + IPAC_WRITE(IPAC_MASK, (IPAC_MASK_INT1 | IPAC_MASK_INT0)); + + IPAC_WRITE(IPAC_ACFG, 0); /* outputs are open drain */ + IPAC_WRITE(IPAC_AOE, /* aux 5..2 are inputs, 7, 6 outputs */ + (IPAC_AOE_OE5 | IPAC_AOE_OE4 | IPAC_AOE_OE3 | IPAC_AOE_OE2)); + IPAC_WRITE(IPAC_ATX, 0xff); /* set all output lines high */ + + return(0); +} +#endif /* NISIC > 0 && defined(SIEMENS_ISURF2) */ diff --git a/sys/i4b/layer1/isic/i4b_sws.c b/sys/i4b/layer1/isic/i4b_sws.c new file mode 100644 index 0000000..4815001 --- /dev/null +++ b/sys/i4b/layer1/isic/i4b_sws.c @@ -0,0 +1,224 @@ +/* + * 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 + * 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. + * + *--------------------------------------------------------------------------- + * + * Card format: + * + * iobase + 0 : reset on (0x03) + * iobase + 1 : reset off (0x0) + * iobase + 2 : isac read/write + * iobase + 3 : hscx read/write ( offset 0-0x3f hscx0 , + * offset 0x40-0x7f hscx1 ) + * iobase + 4 : offset for indirect adressing + * + *--------------------------------------------------------------------------- + * + * isic - I4B Siemens ISDN Chipset Driver for SWS cards + * ==================================================== + * + * $Id: i4b_sws.c,v 1.3 2000/05/29 15:41:41 hm Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Mon May 29 16:46:49 2000] + * + *---------------------------------------------------------------------------*/ + +#include "isic.h" +#include "opt_i4b.h" + +#if defined (SEDLBAUER) && NISIC > 0 + +#define SWS_RESON 0 /* reset on */ +#define SWS_RESOFF 1 /* reset off */ +#define SWS_ISAC 2 /* ISAC */ +#define SWS_HSCX0 3 /* HSCX0 */ +#define SWS_RW 4 /* indirect access register */ +#define SWS_HSCX1 5 /* this is for fakeing that we mean hscx1, though */ + /* access is done through hscx0 */ + +#define SWS_REGS 8 /* we use an area of 8 bytes for io */ + +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include + +#include +#include +#include + +#include +/* #include */ +#include + +/*---------------------------------------------------------------------------* + * SWS P&P ISAC get fifo routine + *---------------------------------------------------------------------------*/ +static void +sws_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,SWS_RW,0x0); + bus_space_read_multi_1(t,h,SWS_ISAC,buf,size); + break; + case ISIC_WHAT_HSCXA: + bus_space_write_1(t,h,SWS_RW,0x0); + bus_space_read_multi_1(t,h,SWS_HSCX0,buf,size); + break; + case ISIC_WHAT_HSCXB: + bus_space_write_1(t,h,SWS_RW,0x0+0x40); + bus_space_read_multi_1(t,h,SWS_HSCX0,buf,size); + break; + } +} + +static void +sws_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,SWS_RW,0x0); + bus_space_write_multi_1(t,h,SWS_ISAC,buf,size); + break; + case ISIC_WHAT_HSCXA: + bus_space_write_1(t,h,SWS_RW,0x0); + bus_space_write_multi_1(t,h,SWS_HSCX0,buf,size); + break; + case ISIC_WHAT_HSCXB: + bus_space_write_1(t,h,SWS_RW,0x0+0x40); + bus_space_write_multi_1(t,h,SWS_HSCX0,buf,size); + break; + } +} + +static void +sws_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,SWS_RW,reg); + bus_space_write_1(t,h,SWS_ISAC,data); + break; + case ISIC_WHAT_HSCXA: + bus_space_write_1(t,h,SWS_RW,reg); + bus_space_write_1(t,h,SWS_HSCX0,data); + break; + case ISIC_WHAT_HSCXB: + bus_space_write_1(t,h,SWS_RW,reg+0x40); + bus_space_write_1(t,h,SWS_HSCX0,data); + break; + } +} + +static u_char +sws_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,SWS_RW,reg); + return bus_space_read_1(t,h,SWS_ISAC); + case ISIC_WHAT_HSCXA: + bus_space_write_1(t,h,SWS_RW,reg); + return bus_space_read_1(t,h,SWS_HSCX0); + case ISIC_WHAT_HSCXB: + bus_space_write_1(t,h,SWS_RW,reg+0x40); + return bus_space_read_1(t,h,SWS_HSCX0); + default: + return 0; + } +} + +/* attach callback routine */ +int +isic_attach_sws(device_t dev) +{ + int unit = device_get_unit(dev); + struct l1_softc *sc = &l1_sc[unit]; + + 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 = sws_read_reg; + sc->writereg = sws_write_reg; + sc->readfifo = sws_read_fifo; + sc->writefifo = sws_write_fifo; + sc->clearirq = NULL; + sc->sc_cardtyp = CARD_TYPEP_SWS; + sc->sc_bustyp = BUS_TYPE_IOM2; + sc->sc_ipac = 0; + sc->sc_bfifolen = HSCX_FIFO_LEN; + + /* + * Read HSCX A/B VSTR. Expected value for the SWS PnP card is + * 0x05 ( = version 2.1 ) in the least significant bits. + */ + + if( ((HSCX_READ(0, H_VSTR) & 0xf) != 0x5) || + ((HSCX_READ(1, H_VSTR) & 0xf) != 0x5) ) + { + printf("isic%d: HSCX VSTR test failed for SWS PnP\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,SWS_RESON,0x3); + DELAY(SEC_DELAY / 5); + bus_space_write_1(t,h,SWS_RESOFF,0x0); + DELAY(SEC_DELAY / 5); + + return(0); +} +#endif /* defined(SEDLBAUER) && NISIC > 0 */ diff --git a/sys/i4b/layer1/isic/i4b_tel_s016.c b/sys/i4b/layer1/isic/i4b_tel_s016.c new file mode 100644 index 0000000..8f4cebb --- /dev/null +++ b/sys/i4b/layer1/isic/i4b_tel_s016.c @@ -0,0 +1,384 @@ +/* + * Copyright (c) 1996 Arne Helme. All rights reserved. + * + * Copyright (c) 1996 Gary Jennejohn. 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 + * 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 - I4B Siemens ISDN Chipset Driver for Teles S0/16 and clones + * ================================================================= + * + * $Id: i4b_tel_s016.c,v 1.3 2000/05/29 15:41:41 hm Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Mon May 29 16:46:56 2000] + * + *---------------------------------------------------------------------------*/ + +#include "isic.h" +#include "opt_i4b.h" + +#if NISIC > 0 && defined(TEL_S0_16) + +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include + +#include +#include +#include + +#include +/* #include */ +#include + +#define TELES_S016_MEMSIZE 0x1000 + +static u_char intr_no[] = { 1, 1, 0, 2, 4, 6, 1, 1, 1, 0, 8, 10, 12, 1, 1, 14 }; +static const bus_size_t offset[] = { 0x100, 0x180, 0x1c0 }; + +/*---------------------------------------------------------------------------* + * Teles S0/16 write register routine + *---------------------------------------------------------------------------*/ +static void +tels016_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.mem); + bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.mem); + + offs += offset[what]; + + if (offs & 0x01) + offs |= 0x200; + + bus_space_write_1(t, h, offs, data); +} + +/*---------------------------------------------------------------------------* + * Teles S0/16 read register routine + *---------------------------------------------------------------------------*/ +static u_int8_t +tels016_read_reg(struct l1_softc *sc, int what, bus_size_t offs) +{ + bus_space_tag_t t = rman_get_bustag(sc->sc_resources.mem); + bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.mem); + + offs += offset[what]; + + if(offs & 0x01) + offs |= 0x200; + + return bus_space_read_1(t, h, offs); +} + +/*---------------------------------------------------------------------------* + * Teles S0/16 fifo write routine + *---------------------------------------------------------------------------*/ +static void +tels016_write_fifo(struct l1_softc *sc, int what, void *data, size_t size) +{ + bus_space_tag_t t = rman_get_bustag(sc->sc_resources.mem); + bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.mem); + bus_space_write_region_1(t, h, offset[what], data, size); +} + +/*---------------------------------------------------------------------------* + * Teles S0/16 fifo read routine + *---------------------------------------------------------------------------*/ +static void +tels016_read_fifo(struct l1_softc *sc, int what, void *buf, size_t size) +{ + bus_space_tag_t t = rman_get_bustag(sc->sc_resources.mem); + bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.mem); + bus_space_read_region_1(t, h, offset[what], buf, size); +} + +/*---------------------------------------------------------------------------* + * isic_probe_s016 - probe for Teles S0/16 and compatibles + *---------------------------------------------------------------------------*/ +int +isic_probe_s016(device_t dev) +{ + size_t unit = device_get_unit(dev); /* get unit */ + struct l1_softc *sc = 0; /* softc */ + void *ih = 0; /* dummy */ + u_int8_t b0,b1,b2; /* for signature */ + bus_space_tag_t t; /* bus things */ + bus_space_handle_t h; + + /* check max unit range */ + + if(unit >= ISIC_MAXUNIT) + { + printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for Teles S0/16!\n", + unit, unit); + return(ENXIO); + } + + sc = &l1_sc[unit]; /* get pointer to softc */ + + sc->sc_unit = unit; /* set unit */ + + sc->sc_flags = FLAG_TELES_S0_16; /* set flags */ + + /* see if an io base was supplied */ + + 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 Teles S0/16.\n", unit); + return(ENXIO); + } + + sc->sc_port = rman_get_start(sc->sc_resources.io_base[0]); + + /* + * check if the provided io port is valid + */ + + switch(sc->sc_port) + { + case 0xd80: + case 0xe80: + case 0xf80: + break; + + default: + printf("isic%d: Error, invalid iobase 0x%x specified for Teles S0/16!\n", + unit, sc->sc_port); + isic_detach_common(dev); + return(ENXIO); + break; + } + + /* allocate memory resource */ + + if(!(sc->sc_resources.mem = + bus_alloc_resource(dev, SYS_RES_MEMORY, + &sc->sc_resources.mem_rid, + 0ul, ~0ul, TELES_S016_MEMSIZE, + RF_ACTIVE))) + { + printf("isic%d: Could not allocate memory for Teles S0/16.\n", unit); + isic_detach_common(dev); + return(ENXIO); + } + + /* + * get virtual addr. + */ + sc->sc_vmem_addr = rman_get_virtual(sc->sc_resources.mem); + + /* + * check for valid adresses + */ + switch(kvtop(sc->sc_vmem_addr)) + { + case 0xc0000: + case 0xc2000: + case 0xc4000: + case 0xc6000: + case 0xc8000: + case 0xca000: + case 0xcc000: + case 0xce000: + case 0xd0000: + case 0xd2000: + case 0xd4000: + case 0xd6000: + case 0xd8000: + case 0xda000: + case 0xdc000: + case 0xde000: + break; + + default: + printf("isic%d: Error, invalid memory address 0x%lx for Teles S0/16!\n", + unit, kvtop(sc->sc_vmem_addr)); + isic_detach_common(dev); + return(ENXIO); + break; + } + + /* setup ISAC access routines */ + + sc->clearirq = NULL; + + sc->readreg = tels016_read_reg; + sc->writereg = tels016_write_reg; + + sc->readfifo = tels016_read_fifo; + sc->writefifo = tels016_write_fifo; + + /* setup card type */ + sc->sc_cardtyp = CARD_TYPEP_16; + + /* setup IOM bus type */ + + sc->sc_bustyp = BUS_TYPE_IOM1; + + sc->sc_ipac = 0; + sc->sc_bfifolen = HSCX_FIFO_LEN; + + /* setup ISAC base addr, though we don't really need it */ + + ISAC_BASE = (caddr_t)((sc->sc_vmem_addr) + 0x100); + + /* setup HSCX base addr */ + + HSCX_A_BASE = (caddr_t)((sc->sc_vmem_addr) + 0x180); + HSCX_B_BASE = (caddr_t)((sc->sc_vmem_addr) + 0x1c0); + + t = rman_get_bustag(sc->sc_resources.io_base[0]); + h = rman_get_bushandle(sc->sc_resources.io_base[0]); + + /* get signature bytes */ + b0 = bus_space_read_1(t, h, 0); + b1 = bus_space_read_1(t, h, 1); + b2 = bus_space_read_1(t, h, 2); + + /* check signature bytes */ + if(b0 != 0x51) + { + printf("isic%d: Error, signature 1 0x%x != 0x51 for Teles S0/16!\n", + unit, b0); + isic_detach_common(dev); + return(ENXIO); + } + + if(b1 != 0x93) + { + printf("isic%d: Error, signature 2 0x%x != 0x93 for Teles S0/16!\n", + unit, b1); + isic_detach_common(dev); + return(ENXIO); + } + + if((b2 != 0x1e) && (b2 != 0x1f)) + { + printf("isic%d: Error, signature 3 0x%x != 0x1e or 0x1f for Teles S0/16!\n", + unit, b2); + isic_detach_common(dev); + return(ENXIO); + } + + /* 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 Teles S0/16.\n", unit); + isic_detach_common(dev); + return ENXIO; + } + + /* register interupt routine */ + + bus_setup_intr(dev, sc->sc_resources.irq, + INTR_TYPE_NET, + (void(*)(void *))(isicintr), + sc, &ih); + + /* get the irq number */ + + sc->sc_irq = rman_get_start(sc->sc_resources.irq); + + /* check IRQ validity */ + + if((intr_no[sc->sc_irq]) == 1) + { + printf("isic%d: Error, invalid IRQ [%d] specified for Teles S0/16!\n", + unit, sc->sc_irq); + isic_detach_common(dev); + return(ENXIO); + } + + return (0); +} + +/*---------------------------------------------------------------------------* + * isic_attach_s016 - attach Teles S0/16 and compatibles + *---------------------------------------------------------------------------*/ +int +isic_attach_s016(device_t dev) +{ + struct l1_softc *sc = &l1_sc[device_get_unit(dev)]; + u_long irq; + + bus_space_tag_t ta = rman_get_bustag(sc->sc_resources.mem); + bus_space_handle_t ha = rman_get_bushandle(sc->sc_resources.mem); + bus_space_tag_t tb = rman_get_bustag(sc->sc_resources.io_base[0]); + bus_space_handle_t hb = rman_get_bushandle(sc->sc_resources.io_base[0]); + + /* is this right for FreeBSD or off by one ? */ + irq = intr_no[sc->sc_irq]; + + /* configure IRQ */ + + irq |= ((u_long) sc->sc_vmem_addr) >> 9; + + DELAY(SEC_DELAY / 10); + bus_space_write_1(tb, hb, 4, irq); + + DELAY(SEC_DELAY / 10); + bus_space_write_1(tb, hb, 4, irq | 0x01); + + DELAY(SEC_DELAY / 5); + + /* set card bit off */ + + bus_space_write_1(ta, ha, 0x80, 0); + DELAY(SEC_DELAY / 5); + + /* set card bit on */ + + bus_space_write_1(ta, ha, 0x80, 1); + DELAY(SEC_DELAY / 5); + + return 0; +} +#endif /* ISIC > 0 */ diff --git a/sys/i4b/layer1/isic/i4b_tel_s0163.c b/sys/i4b/layer1/isic/i4b_tel_s0163.c new file mode 100644 index 0000000..fa31cd9 --- /dev/null +++ b/sys/i4b/layer1/isic/i4b_tel_s0163.c @@ -0,0 +1,387 @@ +/* + * Copyright (c) 1996 Arne Helme. All rights reserved. + * + * Copyright (c) 1996 Gary Jennejohn. 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 + * 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 - I4B Siemens ISDN Chipset Driver for Teles S0/16.3 + * ======================================================== + * + * $Id: i4b_tel_s0163.c,v 1.4 2000/05/29 15:41:41 hm Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Mon May 29 16:47:08 2000] + * + *---------------------------------------------------------------------------*/ + +#include "isic.h" +#include "opt_i4b.h" + +#if NISIC > 0 && defined(TEL_S0_16_3) + +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include + +#include +#include +#include + +#include +/* #include */ +#include + +static u_char intr_no[] = { 1, 1, 0, 2, 4, 6, 1, 1, 1, 0, 8, 10, 12, 1, 1, 14 }; + +#define ISAC_OFFS 0x400 +#define HSCXA_OFFS 0xc00 +#define HSCXB_OFFS 0x800 + +/*---------------------------------------------------------------------------* + * Teles S0/16.3 read fifo routine + *---------------------------------------------------------------------------*/ +static void +tels0163_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[what+1]); + bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[what+1]); + bus_space_read_multi_1(t,h,0x1e,buf,size); +} + +/*---------------------------------------------------------------------------* + * Teles S0/16.3 write fifo routine + *---------------------------------------------------------------------------*/ +static void +tels0163_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[what+1]); + bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[what+1]); + bus_space_write_multi_1(t,h,0x1e,buf,size); +} + +/*---------------------------------------------------------------------------* + * Teles S0/16.3 ISAC put register routine + *---------------------------------------------------------------------------*/ +static void +tels0163_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[what+1]); + bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[what+1]); + bus_space_write_1(t,h,offs - 0x20,data); +} + +/*---------------------------------------------------------------------------* + * Teles S0/16.3 ISAC get register routine + *---------------------------------------------------------------------------*/ +static u_int8_t +tels0163_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[what+1]); + bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[what+1]); + return bus_space_read_1(t,h,offs - 0x20); +} + +/*---------------------------------------------------------------------------* + * isic_probe_s0163 - probe routine for Teles S0/16.3 + *---------------------------------------------------------------------------*/ +int +isic_probe_s0163(device_t dev) +{ + size_t unit = device_get_unit(dev); /* get unit */ + struct l1_softc *sc = 0; /* pointer to softc */ + void *ih = 0; /* dummy */ + bus_space_tag_t t; /* bus things */ + bus_space_handle_t h; + u_int8_t b0,b1,b2; /* signature */ + + /* check max unit range */ + + if(unit >= ISIC_MAXUNIT) + { + printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for Teles 16.3!\n", + unit, unit); + return(ENXIO); + } + + sc = &l1_sc[unit]; /* get pointer to softc */ + sc->sc_unit = unit; /* set unit */ + sc->sc_flags = FLAG_TELES_S0_163; /* set flags */ + + /* see if an io base was supplied */ + + 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 get iobase for Teles S0/16.3.\n", + unit); + return(ENXIO); + } + + /* set io base */ + + sc->sc_port = rman_get_start(sc->sc_resources.io_base[0]); + /* Release the resource - re-allocate later with correct size */ + bus_release_resource(dev, SYS_RES_IOPORT, sc->sc_resources.io_rid[0], + sc->sc_resources.io_base[0]); + + switch(sc->sc_port) + { + case 0xd80: + case 0xe80: + case 0xf80: + break; + + case 0x180: + case 0x280: + case 0x380: + printf("isic%d: Error, instead of using iobase 0x%x for your Teles S0/16.3,\n", + unit, sc->sc_port); + printf("isic%d: please use 0x%x in the kernel configuration file!\n", + unit, sc->sc_port+0xc00); + isic_detach_common(dev); + return(ENXIO); + break; + + default: + printf("isic%d: Error, invalid iobase 0x%x specified for Teles S0/16.3!\n", + unit, sc->sc_port); + isic_detach_common(dev); + return(ENXIO); + break; + } + + /* set io port resources */ + + sc->sc_resources.io_rid[0] = 0; + bus_set_resource(dev, SYS_RES_IOPORT, 0, sc->sc_port, 0x20); + sc->sc_resources.io_base[0] = + bus_alloc_resource(dev, SYS_RES_IOPORT, + &sc->sc_resources.io_rid[0], + 0ul, ~0ul, 1, RF_ACTIVE); + if(!sc->sc_resources.io_base[0]) + { + printf("isic%d: Error allocating io at 0x%x for Teles S0/16.3!\n", + unit, sc->sc_port); + isic_detach_common(dev); + return ENXIO; + } + sc->sc_resources.io_rid[1] = 1; + bus_set_resource(dev, SYS_RES_IOPORT, 1, + sc->sc_port-ISAC_OFFS, 0x20); + sc->sc_resources.io_base[1] = + bus_alloc_resource(dev, SYS_RES_IOPORT, + &sc->sc_resources.io_rid[1], + 0ul, ~0ul, 1, RF_ACTIVE); + if(!sc->sc_resources.io_base[1]) + { + printf("isic%d: Error allocating io at 0x%x for Teles S0/16.3!\n", + unit, sc->sc_port-ISAC_OFFS); + isic_detach_common(dev); + return ENXIO; + } + + sc->sc_resources.io_rid[2] = 2; + bus_set_resource(dev, SYS_RES_IOPORT, 2, + sc->sc_port-HSCXA_OFFS, 0x20); + sc->sc_resources.io_base[2] = + bus_alloc_resource(dev, SYS_RES_IOPORT, + &sc->sc_resources.io_rid[2], + 0ul, ~0ul, 1, RF_ACTIVE); + if(!sc->sc_resources.io_base[2]) + { + printf("isic%d: Error allocating io at 0x%x for Teles S0/16.3!\n", + unit, sc->sc_port-HSCXA_OFFS); + isic_detach_common(dev); + return ENXIO; + } + + sc->sc_resources.io_rid[3] = 3; + bus_set_resource(dev, SYS_RES_IOPORT, 3, + sc->sc_port-HSCXB_OFFS, 0x20); + sc->sc_resources.io_base[3] = + bus_alloc_resource(dev, SYS_RES_IOPORT, + &sc->sc_resources.io_rid[3], + 0ul, ~0ul, 1, RF_ACTIVE); + if(!sc->sc_resources.io_base[3]) + { + printf("isic%d: Error allocating io at 0x%x for Teles S0/16.3!\n", + unit, sc->sc_port-HSCXB_OFFS); + isic_detach_common(dev); + return ENXIO; + } + + /* setup access routines */ + + sc->clearirq = NULL; + sc->readreg = tels0163_read_reg; + sc->writereg = tels0163_write_reg; + + sc->readfifo = tels0163_read_fifo; + sc->writefifo = tels0163_write_fifo; + + /* setup card type */ + + sc->sc_cardtyp= CARD_TYPEP_16_3; + + /* setup IOM bus type */ + + sc->sc_bustyp = BUS_TYPE_IOM2; + + sc->sc_ipac = 0; + sc->sc_bfifolen = HSCX_FIFO_LEN; + + t = rman_get_bustag(sc->sc_resources.io_base[0]); + h = rman_get_bushandle(sc->sc_resources.io_base[0]); + + b0 = bus_space_read_1(t, h, 0); + b1 = bus_space_read_1(t, h, 1); + b2 = bus_space_read_1(t, h, 2); + + if ( b0 != 0x51 && b0 != 0x10 ) { + printf("isic%d: Error, signature 1 0x%x != 0x51 or 0x10 for Teles S0/16.3!\n", + unit, b0); + isic_detach_common(dev); + return ENXIO; + } + + if ( b1 != 0x93 ) { + printf("isic%d: Error, signature 2 0x%x != 0x93 for Teles S0/16.3!\n", + unit, b1); + isic_detach_common(dev); + return ENXIO; + } + 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; + } + + /* + * Read HSCX A/B VSTR. Expected value for the S0/16.3 card is + * 0x05 or 0x04 (for older 16.3's) 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 Teles S0/16.3\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); + } + + /* 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 get IRQ for Teles S0/16.3.\n",unit); + isic_detach_common(dev); + return ENXIO; + } + + /* get the irq number */ + sc->sc_irq = rman_get_start(sc->sc_resources.irq); + + switch(sc->sc_irq) + { + case 2: + case 9: + case 5: + case 10: + case 12: + case 15: + break; + + default: + printf("isic%d: Error, invalid IRQ [%d] specified for Teles S0/16.3!\n", + unit, sc->sc_irq); + isic_detach_common(dev); + return(ENXIO); + break; + } + + /* register interupt routine */ + bus_setup_intr(dev, sc->sc_resources.irq, + INTR_TYPE_NET, + (void(*)(void *))(isicintr), + sc, &ih); + + return (0); +} + +/*---------------------------------------------------------------------------* + * isic_attach_s0163 - attach Teles S0/16.3 and compatibles + *---------------------------------------------------------------------------*/ +int +isic_attach_s0163(device_t dev) +{ + unsigned int 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]); + + /* configure IRQ */ + + DELAY(SEC_DELAY / 10); + bus_space_write_1(t, h, 4, intr_no[sc->sc_irq]); + + DELAY(SEC_DELAY / 10); + bus_space_write_1(t, h, 4, intr_no[sc->sc_irq] | 0x01); + + return (0); +} + +#endif /* ISIC > 0 */ + diff --git a/sys/i4b/layer1/isic/i4b_tel_s08.c b/sys/i4b/layer1/isic/i4b_tel_s08.c new file mode 100644 index 0000000..c6578b1 --- /dev/null +++ b/sys/i4b/layer1/isic/i4b_tel_s08.c @@ -0,0 +1,317 @@ +/* + * Copyright (c) 1996 Arne Helme. All rights reserved. + * + * Copyright (c) 1996 Gary Jennejohn. 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 + * 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 - I4B Siemens ISDN Chipset Driver for Teles S0/8 and clones + * ================================================================ + * + * $Id: i4b_tel_s08.c,v 1.3 2000/05/29 15:41:41 hm Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Mon May 29 16:47:20 2000] + * + *---------------------------------------------------------------------------*/ + +#include "isic.h" +#include "opt_i4b.h" + +#if NISIC > 0 && defined(TEL_S0_8) + +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include + +#include +#include +#include + +#include +/* #include */ +#include + +#define TELES_S08_MEMSIZE 0x1000 + +static const bus_size_t offset[] = { 0x100, 0x180, 0x1c0 }; + +/*---------------------------------------------------------------------------* + * Teles S0/8 write register routine + *---------------------------------------------------------------------------*/ +static void +tels08_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.mem); + bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.mem); + + offs += offset[what]; + + if (offs & 0x01) + offs |= 0x200; + + bus_space_write_1(t, h, offs, data); +} + +/*---------------------------------------------------------------------------* + * Teles S0/8 read register routine + *---------------------------------------------------------------------------*/ +static u_int8_t +tels08_read_reg(struct l1_softc *sc, int what, bus_size_t offs) +{ + bus_space_tag_t t = rman_get_bustag(sc->sc_resources.mem); + bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.mem); + + offs += offset[what]; + + if (offs & 0x01) + offs |= 0x200; + + return bus_space_read_1(t, h, offs); +} + +/*---------------------------------------------------------------------------* + * Teles S0/8 fifo write access + *---------------------------------------------------------------------------*/ +static void +tels08_write_fifo(struct l1_softc *sc, int what, void *data, size_t size) +{ + bus_space_tag_t t = rman_get_bustag(sc->sc_resources.mem); + bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.mem); + bus_space_write_region_1(t, h, offset[what], data, size); +} + +/*---------------------------------------------------------------------------* + * Teles S0/8 fifo read access + *---------------------------------------------------------------------------*/ +static void +tels08_read_fifo(struct l1_softc *sc, int what, void *buf, size_t size) +{ + bus_space_tag_t t = rman_get_bustag(sc->sc_resources.mem); + bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.mem); + bus_space_read_region_1(t, h, offset[what], buf, size); +} + +/*---------------------------------------------------------------------------* + * isic_probe_s08 - probe for Teles S0/8 and compatibles + *---------------------------------------------------------------------------*/ +int +isic_probe_s08(device_t dev) +{ + size_t unit = device_get_unit(dev); /* get unit */ + struct l1_softc *sc = 0; /* pointer to softc */ + void *ih = 0; /* dummy */ + + /* check max unit range */ + + if(unit >= ISIC_MAXUNIT) + { + printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for Teles S0/8!\n", + unit, unit); + return(ENXIO); + } + + sc = &l1_sc[unit]; /* get pointer to softc */ + + sc->sc_unit = unit; /* set unit */ + + sc->sc_flags = FLAG_TELES_S0_8; /* set flags */ + + /* see if an io base was supplied */ + + 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))) + { + /* the S0/8 is completely memory mapped ! */ + + bus_release_resource(dev,SYS_RES_IOPORT, + sc->sc_resources.io_rid[0], + sc->sc_resources.io_base[0]); + printf("isic%d: Error, iobase specified for Teles S0/8!\n", unit); + return(ENXIO); + } + + /* allocate memory */ + + if(!(sc->sc_resources.mem = + bus_alloc_resource(dev, SYS_RES_MEMORY, + &sc->sc_resources.mem_rid, + 0ul, ~0ul, TELES_S08_MEMSIZE, RF_ACTIVE))) + { + printf("isic%d: Could not allocate memory for Teles S0/8!\n", unit); + return(ENXIO); + } + + /* + * get virtual addr. it's just needed to see if it is in + * the valid range + */ + + sc->sc_vmem_addr = rman_get_virtual(sc->sc_resources.mem); + + /* check if inside memory range of 0xA0000 .. 0xDF000 */ + + if((kvtop(sc->sc_vmem_addr) < 0xa0000) || + (kvtop(sc->sc_vmem_addr) > 0xdf000)) + { + printf("isic%d: Error, mem addr 0x%lx outside 0xA0000-0xDF000 for Teles S0/8!\n", + unit, kvtop(sc->sc_vmem_addr)); + bus_release_resource(dev,SYS_RES_MEMORY, + sc->sc_resources.mem_rid, + sc->sc_resources.mem); + sc->sc_resources.mem = 0; + return(ENXIO); + } + + /* setup ISAC access routines */ + + sc->clearirq = NULL; + + sc->readreg = tels08_read_reg; + sc->writereg = tels08_write_reg; + + sc->readfifo = tels08_read_fifo; + sc->writefifo = tels08_write_fifo; + + sc->sc_cardtyp = CARD_TYPEP_8; /* setup card type */ + + sc->sc_bustyp = BUS_TYPE_IOM1; /* setup IOM bus type */ + + sc->sc_ipac = 0; + sc->sc_bfifolen = HSCX_FIFO_LEN; + + /* setup ISAC base addr, though we don't really need it */ + + ISAC_BASE = (caddr_t)((sc->sc_vmem_addr) + 0x100); + + /* setup HSCX base addr */ + + HSCX_A_BASE = (caddr_t)((sc->sc_vmem_addr) + 0x180); + HSCX_B_BASE = (caddr_t)((sc->sc_vmem_addr) + 0x1c0); + + /* allocate 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 Teles S0/8!\n",unit); + + bus_release_resource(dev,SYS_RES_MEMORY, + sc->sc_resources.mem_rid, + sc->sc_resources.mem); + + sc->sc_resources.mem = 0; + return ENXIO; + } + + /* get the irq number */ + + sc->sc_irq = rman_get_start(sc->sc_resources.irq); + + /* check IRQ validity */ + + switch(sc->sc_irq) + { + case 2: + case 9: /* XXX */ + case 3: + case 4: + case 5: + case 6: + case 7: + break; + + default: + printf("isic%d: Error, invalid IRQ [%d] specified for Teles S0/8!\n", + unit, sc->sc_irq); + bus_release_resource(dev,SYS_RES_IRQ, + sc->sc_resources.irq_rid, + sc->sc_resources.irq); + sc->sc_resources.irq = 0; + bus_release_resource(dev,SYS_RES_MEMORY, + sc->sc_resources.mem_rid, + sc->sc_resources.mem); + sc->sc_resources.mem = 0; + return(ENXIO); + break; + } + + /* register interupt routine */ + + bus_setup_intr(dev, sc->sc_resources.irq, + INTR_TYPE_NET, + (void(*)(void *))(isicintr), + sc, &ih); + + return (0); +} + +/*---------------------------------------------------------------------------* + * isic_attach_s08 - attach Teles S0/8 and compatibles + *---------------------------------------------------------------------------*/ +int +isic_attach_s08(device_t dev) +{ + struct l1_softc *sc = &l1_sc[device_get_unit(dev)]; + bus_space_tag_t t = rman_get_bustag(sc->sc_resources.mem); + bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.mem); + + /* set card off */ + + bus_space_write_1(t, h, 0x80, 0); + + DELAY(SEC_DELAY / 5); + + /* set card on */ + + bus_space_write_1(t, h, 0x80, 1); + + DELAY(SEC_DELAY / 5); + + return 0; +} +#endif /* ISIC > 0 */ diff --git a/sys/i4b/layer1/isic/i4b_usr_sti.c b/sys/i4b/layer1/isic/i4b_usr_sti.c new file mode 100644 index 0000000..0bf8430 --- /dev/null +++ b/sys/i4b/layer1/isic/i4b_usr_sti.c @@ -0,0 +1,678 @@ +/* + * 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_usr_sti.c - USRobotics Sportster ISDN TA intern (Tina-pp) + * ------------------------------------------------------------- + * + * $Id: i4b_usr_sti.c,v 1.3 2000/05/29 15:41:42 hm Exp $ + * + * $FreeBSD$ + * + * last edit-date: [Mon May 29 16:47:26 2000] + * + *---------------------------------------------------------------------------*/ + +#if defined(__FreeBSD__) +#include "isic.h" +#include "opt_i4b.h" +#else +#define NISIC 1 +#endif + +#if (NISIC > 0) && defined(USR_STI) + +#include +#include +#include +#include + +#ifdef __FreeBSD__ +#include +#include +#include +#include +#include +#include +#else +#include +#include +#endif + +#include +#include + +#ifdef __FreeBSD__ +#include +#include +#else +#include +#include +#endif + +#include +#include +#include + +#include + +/*---------------------------------------------------------------------------* + * USR Sportster TA intern special registers + *---------------------------------------------------------------------------*/ +#define USR_HSCXA_OFF 0x0000 +#define USR_HSCXB_OFF 0x4000 +#define USR_INTL_OFF 0x8000 +#define USR_ISAC_OFF 0xc000 + +#define USR_RES_BIT 0x80 /* 0 = normal, 1 = reset ISAC/HSCX */ +#define USR_INTE_BIT 0x40 /* 0 = IRQ disabled, 1 = IRQ's enabled */ +#define USR_IL_MASK 0x07 /* IRQ level config */ + +static u_char intr_no[] = { 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 3, 4, 5, 0, 6, 7 }; + +#ifdef __FreeBSD__ + +#define ADDR(reg) \ + (((reg/4) * 1024) + ((reg%4) * 2)) + +#ifdef USRTA_DEBUG_PORTACCESS +int debugcntr; +#define USRTA_DEBUG(fmt) \ + if (++debugcntr < 1000) printf fmt; +#else +#define USRTA_DEBUG(fmt) +#endif + +/*---------------------------------------------------------------------------* + * USRobotics read fifo routine + *---------------------------------------------------------------------------*/ +static void +usrtai_read_fifo(struct l1_softc *sc, int what, void *buf, size_t size) +{ + register int offset = 0; + register unsigned int base = 0; + +USRTA_DEBUG(("usrtai_read_fifo: what %d size %d\n", what, size)) + switch (what) + { + case ISIC_WHAT_ISAC: + base = (unsigned int)ISAC_BASE; + break; + case ISIC_WHAT_HSCXA: + base = (unsigned int)HSCX_A_BASE; + break; + case ISIC_WHAT_HSCXB: + base = (unsigned int)HSCX_B_BASE; + break; + default: + printf("usrtai_read_fifo: invalid what %d\n", what); + return; + } + + for(;size > 0; size--, offset++) + { + *((u_char *)buf + offset) = inb(base + ADDR(offset)); + } +} + +/*---------------------------------------------------------------------------* + * USRobotics write fifo routine + *---------------------------------------------------------------------------*/ +static void +usrtai_write_fifo(struct l1_softc *sc, int what, void *data, size_t size) +{ + register int offset = 0; + register unsigned int base = 0; + +USRTA_DEBUG(("usrtai_write_fifo: what %d size %d\n", what, size)) + switch (what) + { + case ISIC_WHAT_ISAC: + base = (unsigned int)ISAC_BASE; + break; + case ISIC_WHAT_HSCXA: + base = (unsigned int)HSCX_A_BASE; + break; + case ISIC_WHAT_HSCXB: + base = (unsigned int)HSCX_B_BASE; + break; + default: + printf("usrtai_write_fifo: invalid what %d\n", what); + return; + } + + + for(;size > 0; size--, offset++) + { + outb(base + ADDR(offset), *((u_char *)data + offset)); + } +} + +/*---------------------------------------------------------------------------* + * USRobotics write register routine + *---------------------------------------------------------------------------*/ +static void +usrtai_write_reg(struct l1_softc *sc, int what, bus_size_t offs, u_int8_t data) +{ + register unsigned int base = 0; + +USRTA_DEBUG(("usrtai_write_reg: what %d ADDR(%d) %d data %#x\n", what, offs, ADDR(offs), data)) + switch (what) + { + case ISIC_WHAT_ISAC: + base = (unsigned int)ISAC_BASE; + break; + case ISIC_WHAT_HSCXA: + base = (unsigned int)HSCX_A_BASE; + break; + case ISIC_WHAT_HSCXB: + base = (unsigned int)HSCX_B_BASE; + break; + default: + printf("usrtai_write_reg invalid what %d\n", what); + return; + } + + outb(base + ADDR(offs), (u_char)data); +} + +/*---------------------------------------------------------------------------* + * USRobotics read register routine + *---------------------------------------------------------------------------*/ +static u_int8_t +usrtai_read_reg(struct l1_softc *sc, int what, bus_size_t offs) +{ + register unsigned int base = 0; + u_int8_t byte; + +USRTA_DEBUG(("usrtai_read_reg: what %d ADDR(%d) %d..", what, offs, ADDR(offs))) + switch (what) + { + case ISIC_WHAT_ISAC: + base = (unsigned int)ISAC_BASE; + break; + case ISIC_WHAT_HSCXA: + base = (unsigned int)HSCX_A_BASE; + break; + case ISIC_WHAT_HSCXB: + base = (unsigned int)HSCX_B_BASE; + break; + default: + printf("usrtai_read_reg: invalid what %d\n", what); + return(0); + } + + byte = inb(base + ADDR(offs)); +USRTA_DEBUG(("usrtai_read_reg: got %#x\n", byte)) + return(byte); +} + +/*---------------------------------------------------------------------------* + * allocate an io port - based on code in isa_isic.c + *---------------------------------------------------------------------------*/ +static int +usrtai_alloc_port(device_t dev) +{ + size_t unit = device_get_unit(dev); + struct l1_softc *sc = &l1_sc[unit]; + int i, num = 0; + bus_size_t base; + + /* 49 io mappings: 1 config and 48x8 registers */ + + /* config at offset 0x8000 */ + base = sc->sc_port + 0x8000; + if (base < 0 || base > 0x0ffff) + return 1; + sc->sc_resources.io_rid[num] = num; + + bus_set_resource(dev, SYS_RES_IOPORT, num, base, 1); + + if(!(sc->sc_resources.io_base[num] = + bus_alloc_resource(dev, SYS_RES_IOPORT, + &sc->sc_resources.io_rid[num], + 0ul, ~0ul, 1, RF_ACTIVE))) + { + printf("isic%d: Error, failed to reserve io #%dport %#x!\n", unit, num, base); + isic_detach_common(dev); + return(ENXIO); + } + num++; + + /* HSCX A at offset 0 */ + base = sc->sc_port; + for (i = 0; i < 16; i++) { + if (base+i*1024 < 0 || base+i*1024+8 > 0x0ffff) + return 1; + sc->sc_resources.io_rid[num] = num; + + bus_set_resource(dev, SYS_RES_IOPORT, num, base+i*1024, 8); + + if(!(sc->sc_resources.io_base[num] = + bus_alloc_resource(dev, SYS_RES_IOPORT, + &sc->sc_resources.io_rid[num], + 0ul, ~0ul, 1, RF_ACTIVE))) + { + printf("isic%d: Error, failed to reserve io #%d port %#x!\n", unit, num, base+i*1024); + isic_detach_common(dev); + return(ENXIO); + } + ++num; + } + + /* HSCX B at offset 0x4000 */ + base = sc->sc_port + 0x4000; + for (i = 0; i < 16; i++) { + if (base+i*1024 < 0 || base+i*1024+8 > 0x0ffff) + return 1; + sc->sc_resources.io_rid[num] = num; + + bus_set_resource(dev, SYS_RES_IOPORT, num, base+i*1024, 8); + + if(!(sc->sc_resources.io_base[num] = + bus_alloc_resource(dev, SYS_RES_IOPORT, + &sc->sc_resources.io_rid[num], + 0ul, ~0ul, 1, RF_ACTIVE))) + { + printf("isic%d: Error, failed to reserve io #%d port %#x!\n", unit, num, base+i*1024); + isic_detach_common(dev); + return(ENXIO); + } + ++num; + } + + /* ISAC at offset 0xc000 */ + base = sc->sc_port + 0xc000; + for (i = 0; i < 16; i++) { + if (base+i*1024 < 0 || base+i*1024+8 > 0x0ffff) + return 1; + sc->sc_resources.io_rid[num] = num; + + bus_set_resource(dev, SYS_RES_IOPORT, num, base+i*1024, 8); + + if(!(sc->sc_resources.io_base[num] = + bus_alloc_resource(dev, SYS_RES_IOPORT, + &sc->sc_resources.io_rid[num], + 0ul, ~0ul, 1, RF_ACTIVE))) + { + printf("isic%d: Error, failed to reserve io #%d port %#x!\n", unit, num, base+i*1024); + isic_detach_common(dev); + return(ENXIO); + } + ++num; + } + + return(0); +} + +/*---------------------------------------------------------------------------* + * isic_probe_usrtai - probe for USR + *---------------------------------------------------------------------------*/ +int +isic_probe_usrtai(device_t dev) +{ + size_t unit = device_get_unit(dev); /* get unit */ + struct l1_softc *sc = 0; /* pointer to softc */ + void *ih = 0; /* dummy */ + + /* check max unit range */ + + if(unit >= ISIC_MAXUNIT) + { + printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for USR Sportster TA!\n", + unit, unit); + return(ENXIO); + } + + sc = &l1_sc[unit]; /* get pointer to softc */ + sc->sc_unit = unit; /* set unit */ + sc->sc_flags = FLAG_USR_ISDN_TA_INT; /* set flags */ + + /* see if an io base was supplied */ + + 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 get iobase for USR Sportster TA!\n", + unit); + return(ENXIO); + } + + /* set io base */ + + sc->sc_port = rman_get_start(sc->sc_resources.io_base[0]); + + /* release io base */ + + bus_release_resource(dev, SYS_RES_IOPORT, sc->sc_resources.io_rid[0], + sc->sc_resources.io_base[0]); + + + /* check if we got an iobase */ + + switch(sc->sc_port) + { + case 0x200: + case 0x208: + case 0x210: + case 0x218: + case 0x220: + case 0x228: + case 0x230: + case 0x238: + case 0x240: + case 0x248: + case 0x250: + case 0x258: + case 0x260: + case 0x268: + case 0x270: + case 0x278: + break; + + default: + printf("isic%d: Error, invalid iobase 0x%x specified for USR Sportster TA!\n", + unit, sc->sc_port); + return(0); + break; + } + + /* allocate all the ports needed */ + + if(usrtai_alloc_port(dev)) + { + printf("isic%d: Could not get the ports for USR Sportster TA!\n", unit); + isic_detach_common(dev); + return(ENXIO); + } + + /* 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 get an irq for USR Sportster TA!\n",unit); + isic_detach_common(dev); + return ENXIO; + } + + /* get the irq number */ + sc->sc_irq = rman_get_start(sc->sc_resources.irq); + + /* register interrupt routine */ + bus_setup_intr(dev, sc->sc_resources.irq, INTR_TYPE_NET, + (void(*)(void *))(isicintr), + sc, &ih); + + /* check IRQ validity */ + + if(intr_no[sc->sc_irq] == 0) + { + printf("isic%d: Error, invalid IRQ [%d] specified for USR Sportster TA!\n", + unit, sc->sc_irq); + return(1); + } + + /* setup ISAC access routines */ + + sc->clearirq = NULL; + sc->readreg = usrtai_read_reg; + sc->writereg = usrtai_write_reg; + + sc->readfifo = usrtai_read_fifo; + sc->writefifo = usrtai_write_fifo; + + /* setup card type */ + + sc->sc_cardtyp = CARD_TYPEP_USRTA; + + /* 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 + USR_ISAC_OFF; + HSCX_A_BASE = (caddr_t)sc->sc_port + USR_HSCXA_OFF; + HSCX_B_BASE = (caddr_t)sc->sc_port + USR_HSCXB_OFF; + + /* + * Read HSCX A/B VSTR. Expected value for USR Sportster TA based + * boards is 0x05 in the least significant bits. + */ + + if( ((HSCX_READ(0, H_VSTR) & 0xf) != 0x5) || + ((HSCX_READ(1, H_VSTR) & 0xf) != 0x5) ) + { + printf("isic%d: HSCX VSTR test failed for USR Sportster TA\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)); + return (1); + } + + return (0); +} + +/*---------------------------------------------------------------------------* + * isic_attach_usrtai - attach USR + *---------------------------------------------------------------------------*/ +int +isic_attach_usrtai(device_t dev) +{ + u_char irq = 0; + size_t unit = device_get_unit(dev); /* get unit */ + struct l1_softc *sc = 0; /* pointer to softc */ + + sc = &l1_sc[unit]; /* get pointer to softc */ + + /* reset the HSCX and ISAC chips */ + + outb(sc->sc_port + USR_INTL_OFF, USR_RES_BIT); + DELAY(SEC_DELAY / 10); + + outb(sc->sc_port + USR_INTL_OFF, 0x00); + DELAY(SEC_DELAY / 10); + + /* setup IRQ */ + + if((irq = intr_no[sc->sc_irq]) == 0) + { + printf("isic%d: Attach error, invalid IRQ [%d] specified for USR Sportster TA!\n", + unit, sc->sc_irq); + return(1); + } + + /* configure and enable irq */ + + outb(sc->sc_port + USR_INTL_OFF, irq | USR_INTE_BIT); + DELAY(SEC_DELAY / 10); + + return (0); +} + +#else /* end of FreeBSD, start NetBSD */ + +/* + * Use of sc->sc_maps: + * 0 : config register + * 1 - 16 : HSCX A registers + * 17 - 32 : HSCX B registers + * 33 - 48 : ISAC registers + */ + +#define USR_REG_OFFS(reg) ((reg % 4) * 2) +#define USR_HSCXA_MAP(reg) ((reg / 4) + 1) +#define USR_HSCXB_MAP(reg) ((reg / 4) + 17) +#define USR_ISAC_MAP(reg) ((reg / 4) + 33) + +static int map_base[] = { 33, 1, 17, 0 }; /* ISAC, HSCX A, HSCX B */ + +/*---------------------------------------------------------------------------* + * USRobotics read fifo routine + *---------------------------------------------------------------------------*/ +static void +usrtai_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size) +{ + int map, off, offset; + u_char * p = buf; + bus_space_tag_t t; + bus_space_handle_t h; + + for (offset = 0; size > 0; size--, offset++) { + map = map_base[what] + (offset / 4); + t = sc->sc_maps[map].t; + h = sc->sc_maps[map].h; + off = USR_REG_OFFS(offset); + + *p++ = bus_space_read_1(t, h, off); + } +} + +/*---------------------------------------------------------------------------* + * USRobotics write fifo routine + *---------------------------------------------------------------------------*/ +static void +usrtai_write_fifo(struct isic_softc *sc, int what, const void *buf, size_t size) +{ + int map, off, offset; + const u_char * p = buf; + bus_space_tag_t t; + bus_space_handle_t h; + u_char v; + + for (offset = 0; size > 0; size--, offset++) { + map = map_base[what] + (offset / 4); + t = sc->sc_maps[map].t; + h = sc->sc_maps[map].h; + off = USR_REG_OFFS(offset); + + v = *p++; + bus_space_write_1(t, h, off, v); + } +} + +/*---------------------------------------------------------------------------* + * USRobotics write register routine + *---------------------------------------------------------------------------*/ +static void +usrtai_write_reg(struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data) +{ + int map = map_base[what] + (offs / 4), + off = USR_REG_OFFS(offs); + bus_space_tag_t t = sc->sc_maps[map].t; + bus_space_handle_t h = sc->sc_maps[map].h; + + bus_space_write_1(t, h, off, data); +} + +/*---------------------------------------------------------------------------* + * USRobotics read register routine + *---------------------------------------------------------------------------*/ +static u_char +usrtai_read_reg(struct isic_softc *sc, int what, bus_size_t offs) +{ + int map = map_base[what] + (offs / 4), + off = USR_REG_OFFS(offs); + bus_space_tag_t t = sc->sc_maps[map].t; + bus_space_handle_t h = sc->sc_maps[map].h; + + return bus_space_read_1(t, h, off); +} + +/*---------------------------------------------------------------------------* + * isic_probe_usrtai - probe for USR + *---------------------------------------------------------------------------*/ +int +isic_probe_usrtai(struct isic_attach_args *ia) +{ + /* + * Read HSCX A/B VSTR. Expected value for IOM2 based + * boards is 0x05 in the least significant bits. + */ + + if(((bus_space_read_1(ia->ia_maps[USR_HSCXA_MAP(H_VSTR)].t, ia->ia_maps[USR_HSCXA_MAP(H_VSTR)].h, USR_REG_OFFS(H_VSTR)) & 0x0f) != 0x05) || + ((bus_space_read_1(ia->ia_maps[USR_HSCXB_MAP(H_VSTR)].t, ia->ia_maps[USR_HSCXB_MAP(H_VSTR)].h, USR_REG_OFFS(H_VSTR)) & 0x0f) != 0x05)) + return 0; + + return (1); +} + +/*---------------------------------------------------------------------------* + * isic_attach_usrtai - attach USR + *---------------------------------------------------------------------------*/ +int +isic_attach_usrtai(struct isic_softc *sc) +{ + bus_space_tag_t t = sc->sc_maps[0].t; + bus_space_handle_t h = sc->sc_maps[0].h; + u_char irq = intr_no[sc->sc_irq]; + + sc->clearirq = NULL; + sc->readreg = usrtai_read_reg; + sc->writereg = usrtai_write_reg; + + sc->readfifo = usrtai_read_fifo; + sc->writefifo = usrtai_write_fifo; + + /* setup card type */ + + sc->sc_cardtyp = CARD_TYPEP_USRTA; + + /* setup IOM bus type */ + + sc->sc_bustyp = BUS_TYPE_IOM2; + + sc->sc_ipac = 0; + sc->sc_bfifolen = HSCX_FIFO_LEN; + + /* reset the HSCX and ISAC chips */ + + bus_space_write_1(t, h, 0, USR_RES_BIT); + DELAY(SEC_DELAY / 10); + + bus_space_write_1(t, h, 0, 0x00); + DELAY(SEC_DELAY / 10); + + /* setup IRQ */ + + bus_space_write_1(t, h, 0, irq | USR_INTE_BIT); + DELAY(SEC_DELAY / 10); + + return (1); +} + +#endif /* __FreeBSD__ */ + +#endif /* ISIC > 0 */ 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 -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -/*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 + +/*---------------------------------------------------------------------------* + * 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 +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include + +#include + +#include +#include + +#include +#include + +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 +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include + +#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 + +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 +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include + +#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 +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include + +/* 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 +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include + +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 -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - - -#include -#include -#include -#include -#include - -#ifdef __FreeBSD__ -#include -#else -#include -#endif - -#include -#include -#include -#include -#include -#include -#include - -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 -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -#ifdef __FreeBSD__ -#include -#include -#else -#include -#include -#endif - -#include -#include -#include -#include - -#include -#include - -#include - -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); - - -- cgit v1.1