update to i4b version 0.95.04

This commit is contained in:
hm 2000-10-09 13:29:00 +00:00
parent 575265a740
commit 5771a7c42c
67 changed files with 11432 additions and 5572 deletions

View File

@ -1,501 +0,0 @@
/*
* Copyright (c) 1998 Matthias Apitz. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* 4. Altered versions must be plainly marked as such, and must not be
* misrepresented as being the original software and/or documentation.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*---------------------------------------------------------------------------
*
* Fritz!Card pcmcia specific routines for isic driver
* ---------------------------------------------------
*
* $FreeBSD$
*
* last edit-date: [Sun May 2 12:01:16 1999]
*
* -ap added support for AVM PCMCIA Fritz!Card
* -mh split into separate file
*
*---------------------------------------------------------------------------*/
#if defined(__FreeBSD__)
#include "isic.h"
#include "opt_i4b.h"
#else
#define NISIC 1
#endif
#if NISIC > 0 && defined(AVM_A1_PCMCIA)
#include <sys/param.h>
#if defined(__FreeBSD__) && __FreeBSD__ >= 3
#include <sys/ioccom.h>
#else
#include <sys/ioctl.h>
#endif
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#ifdef __FreeBSD__
#include <machine/clock.h>
#include <i386/isa/isa_device.h>
#else
#include <machine/bus.h>
#include <sys/device.h>
#endif
#include <sys/socket.h>
#include <net/if.h>
#ifdef __FreeBSD__
#include <machine/i4b_debug.h>
#include <machine/i4b_ioctl.h>
#else
#include <i4b/i4b_debug.h>
#include <i4b/i4b_ioctl.h>
#include <dev/pcmcia/pcmciareg.h>
#include <dev/pcmcia/pcmciavar.h>
#endif
#include <i4b/layer1/i4b_l1.h>
#include <i4b/layer1/i4b_isac.h>
#include <i4b/layer1/i4b_hscx.h>
#ifndef __FreeBSD__
#include <i4b/layer1/pcmcia_isic.h>
/* PCMCIA support routines */
static u_int8_t avma1_pcmcia_read_reg __P((struct isic_softc *sc, int what, bus_size_t offs));
static void avma1_pcmcia_write_reg __P((struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data));
static void avma1_pcmcia_read_fifo __P((struct isic_softc *sc, int what, void *buf, size_t size));
static void avma1_pcmcia_write_fifo __P((struct isic_softc *sc, int what, const void *data, size_t size));
#endif
/*---------------------------------------------------------------------------*
* AVM PCMCIA Fritz!Card special registers
*---------------------------------------------------------------------------*/
/*
* register offsets from i/o base 0x140 or 0x300
*/
#define ADDR_REG_OFFSET 0x02
#define DATA_REG_OFFSET 0x03
#define STAT0_OFFSET 0x04
#define STAT1_OFFSET 0x05
#define MODREG_OFFSET 0x06
#define VERREG_OFFSET 0x07
/*
* AVM PCMCIA Status Latch 0 read only bits
*/
#define ASL_IRQ_TIMER 0x10 /* Timer interrupt, active low */
#define ASL_IRQ_ISAC 0x20 /* ISAC interrupt, active low */
#define ASL_IRQ_HSCX 0x40 /* HSX interrupt, active low */
#define ASL_IRQ_BCHAN ASL_IRQ_HSCX
#define ASL_IRQ_Pending (ASL_IRQ_ISAC | ASL_IRQ_HSCX | ASL_IRQ_TIMER)
/*
* AVM Status Latch 0 write only bits
*/
#define ASL_RESET_ALL 0x01 /* reset siemens IC's, active 1 */
#define ASL_TIMERDISABLE 0x02 /* active high */
#define ASL_TIMERRESET 0x04 /* active high */
#define ASL_ENABLE_INT 0x08 /* active high */
/*
* AVM Status Latch 1 write only bits
*/
#define ASL1_LED0 0x10 /* active high */
#define ASL1_LED1 0x20 /* active high */
#define ASL1_ENABLE_S0 0xc0 /* enable active S0 I/F */
/*----- EEpromless controller -----*/
/*
* AVM Status Latch read/write bit
*/
#define ASL_TESTBIT 0x80
/*---------------------------------------------------------------------------*
* AVM read fifo routines
*---------------------------------------------------------------------------*/
#ifdef __FreeBSD__
static int PCMCIA_IO_BASE = 0; /* ap: XXX hack */
static void
avma1_pcmcia_read_fifo(void *buf, const void *base, size_t len)
{
outb(PCMCIA_IO_BASE + ADDR_REG_OFFSET, (int)base - 0x20);
insb(PCMCIA_IO_BASE + DATA_REG_OFFSET, (u_char *)buf, (u_int)len);
}
#else
/* offsets of the different 'what' arguments */
static u_int8_t what_map[] = {
0x20-0x20, /* ISIC_WHAT_ISAC */
0xA0-0x20, /* ISIC_WHAT_HSCXA */
0xE0-0x20 /* ISIC_WHAT_HSCXB */
};
static void
avma1_pcmcia_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size)
{
bus_space_tag_t t = sc->sc_maps[0].t;
bus_space_handle_t h = sc->sc_maps[0].h;
bus_space_write_1(t, h, ADDR_REG_OFFSET, what_map[what]);
bus_space_read_multi_1(t, h, DATA_REG_OFFSET, buf, size);
}
#endif
/*---------------------------------------------------------------------------*
* AVM write fifo routines
*---------------------------------------------------------------------------*/
#ifdef __FreeBSD__
static void
avma1_pcmcia_write_fifo(void *base, const void *buf, size_t len)
{
outb(PCMCIA_IO_BASE + ADDR_REG_OFFSET, (int)base - 0x20);
outsb(PCMCIA_IO_BASE + DATA_REG_OFFSET, (u_char *)buf, (u_int)len);
}
#else
static void
avma1_pcmcia_write_fifo(struct isic_softc *sc, int what, const void *buf, size_t size)
{
bus_space_tag_t t = sc->sc_maps[0].t;
bus_space_handle_t h = sc->sc_maps[0].h;
bus_space_write_1(t, h, ADDR_REG_OFFSET, what_map[what]);
bus_space_write_multi_1(t, h, DATA_REG_OFFSET, (u_int8_t*)buf, size);
}
#endif
/*---------------------------------------------------------------------------*
* AVM write register routines
*---------------------------------------------------------------------------*/
#ifdef __FreeBSD__
static void
avma1_pcmcia_write_reg(u_char *base, u_int offset, u_int v)
{
/* offset includes 0x20 FIFO ! */
outb(PCMCIA_IO_BASE + ADDR_REG_OFFSET, (int)base+offset-0x20);
outb(PCMCIA_IO_BASE + DATA_REG_OFFSET, (u_char)v);
}
#else
static void
avma1_pcmcia_write_reg(struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data)
{
bus_space_tag_t t = sc->sc_maps[0].t;
bus_space_handle_t h = sc->sc_maps[0].h;
bus_space_write_1(t, h, ADDR_REG_OFFSET, what_map[what]+offs);
bus_space_write_1(t, h, DATA_REG_OFFSET, data);
}
#endif
/*---------------------------------------------------------------------------*
* AVM read register routines
*---------------------------------------------------------------------------*/
#ifdef __FreeBSD__
static u_char
avma1_pcmcia_read_reg(u_char *base, u_int offset)
{
/* offset includes 0x20 FIFO ! */
outb(PCMCIA_IO_BASE + ADDR_REG_OFFSET, (int)base+offset-0x20);
return (inb(PCMCIA_IO_BASE + DATA_REG_OFFSET));
}
#else
static u_int8_t
avma1_pcmcia_read_reg(struct isic_softc *sc, int what, bus_size_t offs)
{
bus_space_tag_t t = sc->sc_maps[0].t;
bus_space_handle_t h = sc->sc_maps[0].h;
bus_space_write_1(t, h, ADDR_REG_OFFSET, what_map[what]+offs);
return bus_space_read_1(t, h, DATA_REG_OFFSET);
}
#endif
/*---------------------------------------------------------------------------*
* isic_probe_avma1_pcmcia - probe for AVM PCMCIA Fritz!Card
* This is in the bus attachemnt part on NetBSD (pcmcia_isic.c), no
* card specicfic probe is needed on direct config buses like pcmcia.
*---------------------------------------------------------------------------*/
#ifdef __FreeBSD__
int
isic_probe_avma1_pcmcia(struct isa_device *dev)
{
struct isic_softc *sc = &isic_sc[dev->id_unit];
u_char byte;
int i;
u_int cardinfo;
/* check max unit range */
if(dev->id_unit > 1)
{
printf("isic%d: Error, unit %d > MAXUNIT for AVM PCMCIA Fritz!Card\n",
dev->id_unit, dev->id_unit);
return(0);
}
sc->sc_unit = dev->id_unit;
/*
* we trust the IRQ we got from PCCARD service
*/
sc->sc_irq = dev->id_irq;
/* check if we got an iobase */
switch(dev->id_iobase)
{
case 0x140:
case 0x300:
break;
default:
printf("isic%d: Error, invalid iobase 0x%x specified for AVM PCMCIA Fritz!Card.\n",
dev->id_unit, dev->id_iobase);
return(0);
break;
}
sc->sc_port = dev->id_iobase;
/* ResetController */
outb(dev->id_iobase + STAT0_OFFSET, 0x00);
DELAY(SEC_DELAY / 20);
outb(dev->id_iobase + STAT0_OFFSET, 0x01);
DELAY(SEC_DELAY / 20);
outb(dev->id_iobase + STAT0_OFFSET, 0x00);
/*
* CheckController
* The logic to check for the PCMCIA was adapted as
* described by AVM.
*/
outb(dev->id_iobase + ADDR_REG_OFFSET, 0x21); /* ISAC STAR */
if ( (byte=inb(dev->id_iobase + DATA_REG_OFFSET) & 0xfd) != 0x48 )
{
printf("isic%d: Error, ISAC STAR for AVM PCMCIA is 0x%0x (should be 0x48)\n",
dev->id_unit, byte);
return(0);
}
outb(dev->id_iobase + ADDR_REG_OFFSET, 0xa1); /* HSCX STAR */
if ( (byte=inb(dev->id_iobase + DATA_REG_OFFSET) & 0xfd) != 0x48 )
{
printf("isic%d: Error, HSCX STAR for AVM PCMCIA is 0x%0x (should be 0x48)\n",
dev->id_unit, byte);
return(0);
}
byte = ASL_TESTBIT;
for (i=0; i<256; i++) {
byte = byte ? 0 : ASL_TESTBIT;
outb(dev->id_iobase + STAT0_OFFSET, byte);
if ((inb(dev->id_iobase+STAT0_OFFSET)&ASL_TESTBIT)!=byte) {
printf("isic%d: Error during toggle of AVM PCMCIA Status Latch0\n",
dev->id_unit);
return(0);
}
}
sc->clearirq = NULL;
sc->readreg = avma1_pcmcia_read_reg;
sc->writereg = avma1_pcmcia_write_reg;
sc->readfifo = avma1_pcmcia_read_fifo;
sc->writefifo = avma1_pcmcia_write_fifo;
/* setup card type */
sc->sc_cardtyp = CARD_TYPEP_PCFRITZ;
/* setup IOM bus type */
sc->sc_bustyp = BUS_TYPE_IOM2; /* ap: XXX ??? */
sc->sc_ipac = 0;
sc->sc_bfifolen = HSCX_FIFO_LEN;
/* setup ISAC and HSCX base addr */
/*
* NOTE: for PCMCIA these are no real addrs; they are
* offsets to be written into the base+ADDR_REG_OFFSET register
* to pick up the values of the bytes fro base+DATA_REG_OFFSET
*
* see also the logic in the avma1_pcmcia_* routines;
* therefore we also must have the base addr in some static
* space or struct; XXX better solution?
*/
PCMCIA_IO_BASE = dev->id_iobase;
ISAC_BASE = (caddr_t)0x20;
HSCX_A_BASE = (caddr_t)0xA0;
HSCX_B_BASE = (caddr_t)0xE0;
/*
* Read HSCX A/B VSTR.
* Expected value for AVM A1 is 0x04 or 0x05 and for the
* AVM Fritz!Card is 0x05 in the least significant bits.
*/
if( (((HSCX_READ(0, H_VSTR) & 0xf) != 0x5) &&
((HSCX_READ(0, H_VSTR) & 0xf) != 0x4)) ||
(((HSCX_READ(1, H_VSTR) & 0xf) != 0x5) &&
((HSCX_READ(1, H_VSTR) & 0xf) != 0x4)) )
{
printf("isic%d: HSCX VSTR test failed for AVM PCMCIA Fritz!Card\n",
dev->id_unit);
printf("isic%d: HSC0: VSTR: 0x%0x\n",
dev->id_unit, HSCX_READ(0, H_VSTR));
printf("isic%d: HSC1: VSTR: 0x%0x\n",
dev->id_unit, HSCX_READ(1, H_VSTR));
return (0);
}
/*
* seems we really have an AVM PCMCIA Fritz!Card controller
*/
cardinfo = inb(dev->id_iobase + VERREG_OFFSET)<<8 | inb(dev->id_iobase + MODREG_OFFSET);
printf("isic%d: successfully detect AVM PCMCIA cardinfo = 0x%0x\n",
dev->id_unit, cardinfo);
dev->id_flags = FLAG_AVM_A1_PCMCIA;
return (1);
}
#endif /* __FreeBSD__ */
/*---------------------------------------------------------------------------*
* isic_attach_fritzpcmcia - attach Fritz!Card
*---------------------------------------------------------------------------*/
#ifdef __FreeBSD__
int
isic_attach_fritzpcmcia(struct isa_device *dev)
{
/* ResetController again just to make sure... */
outb(dev->id_iobase + STAT0_OFFSET, 0x00);
DELAY(SEC_DELAY / 10);
outb(dev->id_iobase + STAT0_OFFSET, 0x01);
DELAY(SEC_DELAY / 10);
outb(dev->id_iobase + STAT0_OFFSET, 0x00);
DELAY(SEC_DELAY / 10);
/* enable IRQ, disable counter IRQ */
outb(dev->id_iobase + STAT0_OFFSET, ASL_TIMERDISABLE |
ASL_TIMERRESET | ASL_ENABLE_INT);
/* DELAY(SEC_DELAY / 10); */
return(1);
}
#else
/*
* XXX - one time only! Some of this has to go into an enable
* function, with apropriate counterpart in disable, so a card
* could be removed an inserted again. But never mind for now,
* this won't work anyway for several reasons (both in NetBSD
* and in I4B).
*/
int
isic_attach_fritzpcmcia(struct pcmcia_isic_softc *psc, struct pcmcia_config_entry *cfe, struct pcmcia_attach_args *pa)
{
struct isic_softc *sc = &psc->sc_isic;
bus_space_tag_t t;
bus_space_handle_t h;
/* Validate config info */
if (cfe->num_memspace != 0)
printf(": unexpected number of memory spaces %d should be 0\n",
cfe->num_memspace);
if (cfe->num_iospace != 1)
printf(": unexpected number of memory spaces %d should be 1\n",
cfe->num_iospace);
/* Allocate pcmcia space - exactly as dictated by the card */
if (pcmcia_io_alloc(pa->pf, cfe->iospace[0].start, cfe->iospace[0].length,
0, &psc->sc_pcioh))
printf(": can't allocate i/o space\n");
/* map them */
if (pcmcia_io_map(pa->pf, ((cfe->flags & PCMCIA_CFE_IO16) ?
PCMCIA_WIDTH_IO16 : PCMCIA_WIDTH_IO8), 0,
cfe->iospace[0].length, &psc->sc_pcioh, &psc->sc_io_window)) {
printf(": can't map i/o space\n");
return 0;
}
/* Setup bus space maps */
sc->sc_num_mappings = 1;
sc->sc_cardtyp = CARD_TYPEP_PCFRITZ;
MALLOC_MAPS(sc);
/* Copy our handles/tags to the MI maps */
sc->sc_maps[0].t = psc->sc_pcioh.iot;
sc->sc_maps[0].h = psc->sc_pcioh.ioh;
sc->sc_maps[0].offset = 0;
sc->sc_maps[0].size = 0; /* not our mapping */
t = sc->sc_maps[0].t;
h = sc->sc_maps[0].h;
sc->clearirq = NULL;
sc->readreg = avma1_pcmcia_read_reg;
sc->writereg = avma1_pcmcia_write_reg;
sc->readfifo = avma1_pcmcia_read_fifo;
sc->writefifo = avma1_pcmcia_write_fifo;
/* setup card type */
sc->sc_cardtyp = CARD_TYPEP_PCFRITZ;
/* setup IOM bus type */
sc->sc_bustyp = BUS_TYPE_IOM2;
sc->sc_ipac = 0;
sc->sc_bfifolen = HSCX_FIFO_LEN;
/* Reset controller again just to make sure... */
bus_space_write_1(t, h, STAT0_OFFSET, 0x00);
DELAY(SEC_DELAY / 10);
bus_space_write_1(t, h, STAT0_OFFSET, 0x01);
DELAY(SEC_DELAY / 10);
bus_space_write_1(t, h, STAT0_OFFSET, 0x00);
DELAY(SEC_DELAY / 10);
/* enable IRQ, disable counter IRQ */
bus_space_write_1(t, h, STAT0_OFFSET, ASL_TIMERDISABLE |
ASL_TIMERRESET | ASL_ENABLE_INT);
return 1;
}
#endif
#endif /* NISIC > 0 && defined(AVM_A1_PCMCIA) */

View File

@ -1,578 +0,0 @@
/*
* Copyright (c) 1998 Martijn Plak. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* 4. Altered versions must be plainly marked as such, and must not be
* misrepresented as being the original software and/or documentation.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*---------------------------------------------------------------------------
*
* isdn4bsd layer1 driver for Dynalink IS64PH isdn TA
* ==================================================
*
* $FreeBSD$
*
* last edit-date: [Sun Feb 14 10:26:21 1999]
*
* written by Martijn Plak <tigrfhur@xs4all.nl>
*
* -mp 11 jun 1998 first try, code borrowed from Creatix driver
* -mp 18 jun 1998 cleaned up code
* -hm FreeBSD PnP
* -mp 17 dec 1998 made it compile again
*
*---------------------------------------------------------------------------*/
/* NOTES:
This driver was written for the Dynalink IS64PH ISDN TA, based on two
Siemens chips (HSCX 21525 and ISAC 2186). It is sold in the Netherlands.
model numbers found on (my) card:
IS64PH, TAS100H-N, P/N:89590555, TA200S100045521
chips:
Siemens PSB 21525N, HSCX TE V2.1
Siemens PSB 2186N, ISAC-S TE V1.1
95MS14, PNP
plug-and-play info:
device id "ASU1688"
vendor id 0x88167506
serial 0x00000044
i/o port 4 byte alignment, 4 bytes requested,
10 bit i/o decoding, 0x100-0x3f8 (?)
irq 3,4,5,9,10,11,12,15, high true, edge sensitive
At the moment I'm writing this Dynalink is replacing this card with
one based on a single Siemens chip (IPAC). It will apparently be sold
under the same model name.
This driver might also work for Asuscom cards.
*/
#ifdef __FreeBSD__
#include "isic.h"
#include "opt_i4b.h"
#else
#define NISIC 1
#endif
#define NPNP 1
#if (NISIC > 0) && (NPNP > 0) && defined(DYNALINK)
/* HEADERS
*/
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <net/if.h>
#ifdef __FreeBSD__
#if __FreeBSD__ >= 3
#include <sys/ioccom.h>
#else
#include <sys/ioctl.h>
#endif
#include <machine/clock.h>
#include <i386/isa/isa_device.h>
/* #include <i386/isa/pnp.h> */
#elif defined(__bsdi__)
#include <i386/isa/pnp.h>
#else
#include <machine/bus.h>
#include <sys/device.h>
#endif
#ifdef __FreeBSD__
#include <machine/i4b_debug.h>
#include <machine/i4b_ioctl.h>
#else
#include <i4b/i4b_debug.h>
#include <i4b/i4b_ioctl.h>
#endif
#include <i4b/include/i4b_global.h>
#include <i4b/include/i4b_l1l2.h>
#include <i4b/include/i4b_mbuf.h>
#include <i4b/layer1/i4b_l1.h>
#include <i4b/layer1/i4b_isac.h>
#include <i4b/layer1/i4b_hscx.h>
#if defined(__FreeBSD__) || defined(__bsdi__)
static void dynalink_read_fifo(void *buf, const void *base, size_t len);
static void dynalink_write_fifo(void *base, const void *buf, size_t len);
static void dynalink_write_reg(u_char *base, u_int offset, u_int v);
static u_char dynalink_read_reg(u_char *base, u_int offset);
#endif
#ifdef __FreeBSD__
extern struct isa_driver isicdriver;
#endif
#ifdef __bsdi__
extern struct cfdriver isiccd;
#endif
#if !defined(__FreeBSD__) && !defined(__bsdi__)
static void dynalink_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size);
static void dynalink_write_fifo(struct isic_softc *sc, int what, const void *buf, size_t size);
static void dynalink_write_reg(struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data);
static u_int8_t dynalink_read_reg(struct isic_softc *sc, int what, bus_size_t offs);
void isic_attach_Dyn(struct isic_softc *sc);
#endif
/* io address mapping */
#define ISAC 0
#define HSCX 1
#define ADDR 2
/* ADDR bits */
#define ADDRMASK 0x7F
#define RESET 0x80
/* HSCX register offsets */
#define HSCXA 0x00
#define HSCXB 0x40
#if defined(__FreeBSD__) || defined(__bsdi__)
/* base address juggling */
#define HSCXB_HACK 0x400
#define IOBASE(addr) (((int)addr)&0x3FC)
#define IOADDR(addr) (((int)addr)&0x3FF)
#define IS_HSCXB_HACK(addr) ((((int)addr)&HSCXB_HACK)?HSCXB:HSCXA)
#endif
#ifdef __FreeBSD__
/* ISIC probe and attach
*/
int
isic_probe_Dyn(struct isa_device *dev, unsigned int iobase2)
{
struct isic_softc *sc = &isic_sc[dev->id_unit];
if(dev->id_unit >= ISIC_MAXUNIT)
{
printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for Dynalink IS64PH.\n",
dev->id_unit, dev->id_unit);
return(0);
}
sc->sc_unit = dev->id_unit;
/* check IRQ validity */
switch(ffs(dev->id_irq) - 1)
{
case 3:
case 4:
case 5:
case 9:
case 10:
case 11:
case 12:
case 15:
break;
default:
printf("isic%d: Error, invalid IRQ [%d] specified for Dynalink IS64PH.\n",
dev->id_unit, ffs(dev->id_irq)-1);
return(0);
break;
}
sc->sc_irq = dev->id_irq;
/* check if memory addr specified */
if(dev->id_maddr)
{
printf("isic%d: Error, mem addr 0x%lx specified for Dynalink IS64PH.\n",
dev->id_unit, (u_long)dev->id_maddr);
return (0);
}
dev->id_msize = 0;
/* check if we got an iobase */
if ( (dev->id_iobase < 0x100) ||
(dev->id_iobase > 0x3f8) ||
(dev->id_iobase & 3) )
{
printf("isic%d: Error, invalid iobase 0x%x specified for Dynalink!\n", dev->id_unit, dev->id_iobase);
return(0);
}
sc->sc_port = dev->id_iobase;
/* setup access routines */
sc->clearirq = NULL;
sc->readreg = dynalink_read_reg;
sc->writereg = dynalink_write_reg;
sc->readfifo = dynalink_read_fifo;
sc->writefifo = dynalink_write_fifo;
/* setup card type */
sc->sc_cardtyp = CARD_TYPEP_DYNALINK;
/* setup IOM bus type */
sc->sc_bustyp = BUS_TYPE_IOM2;
sc->sc_ipac = 0;
sc->sc_bfifolen = HSCX_FIFO_LEN;
/* setup ISAC and HSCX base addr */
ISAC_BASE = (caddr_t) sc->sc_port;
HSCX_A_BASE = (caddr_t) sc->sc_port + 1;
HSCX_B_BASE = (caddr_t) sc->sc_port + 1 + HSCXB_HACK;
/* Read HSCX A/B VSTR. Expected value is 0x05 (V2.1). */
if( ((HSCX_READ(0, H_VSTR) & 0xf) != 0x5) ||
((HSCX_READ(1, H_VSTR) & 0xf) != 0x5) )
{
printf("isic%d: HSCX VSTR test failed for Dynalink\n",
dev->id_unit);
printf("isic%d: HSC0: VSTR: %#x\n",
dev->id_unit, HSCX_READ(0, H_VSTR));
printf("isic%d: HSC1: VSTR: %#x\n",
dev->id_unit, HSCX_READ(1, H_VSTR));
return (0);
}
return (1);
}
int
isic_attach_Dyn(struct isa_device *dev, unsigned int iobase2)
{
outb((dev->id_iobase)+ADDR, RESET);
DELAY(SEC_DELAY / 10);
outb((dev->id_iobase)+ADDR, 0);
DELAY(SEC_DELAY / 10);
return(1);
}
#elif defined(__bsdi__)
/* ISIC probe and attach
*/
static int
set_softc(struct isic_softc *sc, struct isa_attach_args *ia, int unit)
{
if (unit >= NISIC)
return 0;
sc->sc_unit = unit;
switch(ffs(ia->ia_irq) - 1)
{
case 3:
case 4:
case 5:
case 9:
case 10:
case 11:
case 12:
case 15:
break;
default:
printf("isic%d: Error, invalid IRQ [%d] specified for Dynalink IS64PH.\n",
unit, ffs(ia->ia_irq)-1);
return(0);
break;
}
sc->sc_irq = ia->ia_irq;
/* check if memory addr specified */
if(ia->ia_maddr)
{
printf("isic%d: Error, mem addr 0x%lx specified for Dynalink IS64PH.\n",
unit, (u_long)ia->ia_maddr);
return (0);
}
/* check if we got an iobase */
if ( (ia->ia_iobase < 0x100) ||
(ia->ia_iobase > 0x3f8) ||
(ia->ia_iobase & 3) )
{
printf("isic%d: Error, invalid iobase 0x%x specified for Dynalink!\n", unit, ia->ia_iobase);
return(0);
}
sc->sc_port = ia->ia_iobase;
/* setup access routines */
sc->clearirq = NULL;
sc->readreg = dynalink_read_reg;
sc->writereg = dynalink_write_reg;
sc->readfifo = dynalink_read_fifo;
sc->writefifo = dynalink_write_fifo;
/* setup card type */
sc->sc_cardtyp = CARD_TYPEP_DYNALINK;
/* setup IOM bus type */
sc->sc_bustyp = BUS_TYPE_IOM2;
sc->sc_ipac = 0;
sc->sc_bfifolen = HSCX_FIFO_LEN;
/* setup ISAC and HSCX base addr */
ISAC_BASE = (caddr_t) sc->sc_port;
HSCX_A_BASE = (caddr_t) sc->sc_port + 1;
HSCX_B_BASE = (caddr_t) sc->sc_port + 1 + HSCXB_HACK;
return 1;
}
int
isapnp_match_dynalink(struct device *parent, struct cfdata *cf,
struct isa_attach_args *ia)
{
struct isic_softc dummysc, *sc = &dummysc;
pnp_resource_t res;
char *ids[] = {"ASU1688", NULL};
bzero(&res, sizeof res);
res.res_irq[0].irq_level = ia->ia_irq;
res.res_port[0].prt_base = ia->ia_iobase;
res.res_port[0].prt_length = 4;
if (!pnp_assigndev(ids, isiccd.cd_name, &res))
return (0);
ia->ia_irq = res.res_irq[0].irq_level;
ia->ia_iobase = res.res_port[0].prt_base;
ia->ia_iosize = res.res_port[0].prt_length;
if (set_softc(sc, ia, cf->cf_unit) == 0)
return 0;
/* Read HSCX A/B VSTR. Expected value is 0x05 (V2.1). */
if( ((HSCX_READ(0, H_VSTR) & 0xf) != 0x5) ||
((HSCX_READ(1, H_VSTR) & 0xf) != 0x5) )
{
printf("isic%d: HSCX VSTR test failed for Dynalink\n",
cf->cf_unit);
printf("isic%d: HSC0: VSTR: %#x\n",
cf->cf_unit, HSCX_READ(0, H_VSTR));
printf("isic%d: HSC1: VSTR: %#x\n",
cf->cf_unit, HSCX_READ(1, H_VSTR));
return (0);
}
cf->cf_flags = FLAG_DYNALINK;
return (1);
}
int
isic_attach_Dyn(struct device *parent, struct device *self,
struct isa_attach_args *ia)
{
struct isic_softc *sc = (struct isic_softc *)self;
int unit = sc->sc_dev.dv_unit;
/* Commit the probed attachment values */
if (set_softc(sc, ia, unit) == 0)
panic("isic_attach_Dyn: set_softc");
outb((ia->ia_iobase)+ADDR, RESET);
DELAY(SEC_DELAY / 10);
outb((ia->ia_iobase)+ADDR, 0);
DELAY(SEC_DELAY / 10);
return(1);
}
#else
void isic_attach_Dyn(struct isic_softc *sc)
{
/* setup access routines */
sc->clearirq = NULL;
sc->readreg = dynalink_read_reg;
sc->writereg = dynalink_write_reg;
sc->readfifo = dynalink_read_fifo;
sc->writefifo = dynalink_write_fifo;
/* setup card type */
sc->sc_cardtyp = CARD_TYPEP_DYNALINK;
/* setup IOM bus type */
sc->sc_bustyp = BUS_TYPE_IOM2;
sc->sc_ipac = 0;
sc->sc_bfifolen = HSCX_FIFO_LEN;
/* Read HSCX A/B VSTR. Expected value is 0x05 (V2.1). */
if( ((HSCX_READ(0, H_VSTR) & 0xf) != 0x5) || ((HSCX_READ(1, H_VSTR) & 0xf) != 0x5) )
{
printf("%s: HSCX VSTR test failed for Dynalink PnP\n",
sc->sc_dev.dv_xname);
printf("%s: HSC0: VSTR: %#x\n",
sc->sc_dev.dv_xname, HSCX_READ(0, H_VSTR));
printf("%s: HSC1: VSTR: %#x\n",
sc->sc_dev.dv_xname, HSCX_READ(1, H_VSTR));
return;
}
bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, ADDR, RESET);
DELAY(SEC_DELAY / 10);
bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, ADDR, 0);
DELAY(SEC_DELAY / 10);
}
#endif /* ISIC>0 && NPNP>0 && defined(DYNALINK) */
/* LOW-LEVEL DEVICE ACCESS
NOTE: The isdn4bsd code expects the two HSCX channels at different
base addresses. I'm faking this, and remap them to the same address
in the low-level routines. Search for HSCXB_HACK and IS_HSCXB_HACK.
REM: this is only true for the FreeBSD version of I4B!
*/
#if defined(__FreeBSD__) || defined(__bsdi__)
static void
dynalink_read_fifo(void *buf, const void *base, size_t len)
{
outb(IOBASE(base)+ADDR, 0+IS_HSCXB_HACK(base));
insb(IOADDR(base), (u_char *)buf, (u_int)len);
}
#else
static void
dynalink_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size)
{
bus_space_tag_t t = sc->sc_maps[0].t;
bus_space_handle_t h = sc->sc_maps[0].h;
switch (what) {
case ISIC_WHAT_ISAC:
bus_space_write_1(t, h, ADDR, 0);
bus_space_read_multi_1(t, h, ISAC, buf, size);
break;
case ISIC_WHAT_HSCXA:
bus_space_write_1(t, h, ADDR, HSCXA);
bus_space_read_multi_1(t, h, HSCX, buf, size);
break;
case ISIC_WHAT_HSCXB:
bus_space_write_1(t, h, ADDR, HSCXB);
bus_space_read_multi_1(t, h, HSCX, buf, size);
break;
}
}
#endif
#if defined(__FreeBSD__) || defined(__bsdi__)
static void
dynalink_write_fifo(void *base, const void *buf, size_t len)
{
outb(IOBASE(base)+ADDR, 0+IS_HSCXB_HACK(base));
outsb(IOADDR(base), (u_char *)buf, (u_int)len);
}
#else
static void dynalink_write_fifo(struct isic_softc *sc, int what, const void *buf, size_t size)
{
bus_space_tag_t t = sc->sc_maps[0].t;
bus_space_handle_t h = sc->sc_maps[0].h;
switch (what) {
case ISIC_WHAT_ISAC:
bus_space_write_1(t, h, ADDR, 0);
bus_space_write_multi_1(t, h, ISAC, (u_int8_t*)buf, size);
break;
case ISIC_WHAT_HSCXA:
bus_space_write_1(t, h, ADDR, HSCXA);
bus_space_write_multi_1(t, h, HSCX, (u_int8_t*)buf, size);
break;
case ISIC_WHAT_HSCXB:
bus_space_write_1(t, h, ADDR, HSCXB);
bus_space_write_multi_1(t, h, HSCX, (u_int8_t*)buf, size);
break;
}
}
#endif
#if defined(__FreeBSD__) || defined(__bsdi__)
static void
dynalink_write_reg(u_char *base, u_int offset, u_int v)
{
outb(IOBASE(base)+ADDR, (offset+IS_HSCXB_HACK(base))&ADDRMASK);
outb(IOADDR(base), (u_char)v);
}
#else
static void dynalink_write_reg(struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data)
{
bus_space_tag_t t = sc->sc_maps[0].t;
bus_space_handle_t h = sc->sc_maps[0].h;
switch (what) {
case ISIC_WHAT_ISAC:
bus_space_write_1(t, h, ADDR, offs);
bus_space_write_1(t, h, ISAC, data);
break;
case ISIC_WHAT_HSCXA:
bus_space_write_1(t, h, ADDR, HSCXA+offs);
bus_space_write_1(t, h, HSCX, data);
break;
case ISIC_WHAT_HSCXB:
bus_space_write_1(t, h, ADDR, HSCXB+offs);
bus_space_write_1(t, h, HSCX, data);
break;
}
}
#endif
#if defined(__FreeBSD__) || defined(__bsdi__)
static u_char
dynalink_read_reg(u_char *base, u_int offset)
{
outb(IOBASE(base)+ADDR, (offset+IS_HSCXB_HACK(base))&ADDRMASK);
return (inb(IOADDR(base)));
}
#else
static u_int8_t dynalink_read_reg(struct isic_softc *sc, int what, bus_size_t offs)
{
bus_space_tag_t t = sc->sc_maps[0].t;
bus_space_handle_t h = sc->sc_maps[0].h;
switch (what) {
case ISIC_WHAT_ISAC:
bus_space_write_1(t, h, ADDR, offs);
return bus_space_read_1(t, h, ISAC);
case ISIC_WHAT_HSCXA:
bus_space_write_1(t, h, ADDR, HSCXA+offs);
return bus_space_read_1(t, h, HSCX);
case ISIC_WHAT_HSCXB:
bus_space_write_1(t, h, ADDR, HSCXB+offs);
return bus_space_read_1(t, h, HSCX);
}
return 0;
}
#endif
#endif /* (NISIC > 0) && (NPNP > 0) && defined(DYNALINK) */

View File

@ -1,325 +0,0 @@
/*
* Copyright (c) 1998 Martin Husemann. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* 4. Altered versions must be plainly marked as such, and must not be
* misrepresented as being the original software and/or documentation.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*---------------------------------------------------------------------------
*
* ELSA MicroLink ISDN/MC card specific routines
* ---------------------------------------------
*
* $FreeBSD$
*
* last edit-date: [Sun Feb 14 10:26:25 1999]
*
* -mh added support for elsa ISDN/mc
*
*---------------------------------------------------------------------------*/
#ifdef __FreeBSD__
#include "isic.h"
#include "opt_i4b.h"
#else
#define NISIC 1
#endif
#if NISIC > 0 && defined(ELSA_ISDNMC)
#include <sys/param.h>
#if defined(__FreeBSD__) && __FreeBSD__ >= 3
#include <sys/ioccom.h>
#else
#include <sys/ioctl.h>
#endif
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#ifdef __FreeBSD__
#include <machine/clock.h>
#include <i386/isa/isa_device.h>
#else
#include <machine/bus.h>
#include <sys/device.h>
#endif
#include <sys/socket.h>
#include <net/if.h>
#ifdef __FreeBSD__
#include <machine/i4b_debug.h>
#include <machine/i4b_ioctl.h>
#else
#include <i4b/i4b_debug.h>
#include <i4b/i4b_ioctl.h>
#include <dev/pcmcia/pcmciareg.h>
#include <dev/pcmcia/pcmciavar.h>
#endif
#include <i4b/layer1/i4b_l1.h>
#include <i4b/layer1/i4b_isac.h>
#include <i4b/layer1/i4b_hscx.h>
#include <i4b/layer1/pcmcia_isic.h>
#ifndef __FreeBSD__
/* PCMCIA support routines */
static u_int8_t elsa_isdnmc_read_reg __P((struct isic_softc *sc, int what, bus_size_t offs));
static void elsa_isdnmc_write_reg __P((struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data));
static void elsa_isdnmc_read_fifo __P((struct isic_softc *sc, int what, void *buf, size_t size));
static void elsa_isdnmc_write_fifo __P((struct isic_softc *sc, int what, const void *data, size_t size));
static void elsa_isdnmc_clrirq __P((struct isic_softc *sc));
#endif
/*
* The ELSA MicroLink ISDN/MC uses one contigous IO region,
* mapped by the pcmcia code.
* The chip access is via three ports:
*/
#define ISAC_DATA 1 /* ISAC dataport at offset 1 */
#define HSCX_DATA 2 /* HSCX dataport at offset 2 */
#define ADDR_LATCH 4 /* address latch at offset 4 */
/* This is very similar to the ELSA QuickStep 1000 (ISA) card */
#ifdef __FreeBSD__
static void
elsa_isdnmc_clrirq(void *base)
{
}
#else
static void
elsa_isdnmc_clrirq(struct isic_softc *sc)
{
ISAC_WRITE(I_MASK, 0xff);
HSCX_WRITE(0, H_MASK, 0xff);
HSCX_WRITE(1, H_MASK, 0xff);
ISAC_WRITE(I_MASK, ISAC_IMASK);
HSCX_WRITE(0, H_MASK, HSCX_A_IMASK);
HSCX_WRITE(1, H_MASK, HSCX_B_IMASK);
}
#endif
/*---------------------------------------------------------------------------*
* read fifo routines
*---------------------------------------------------------------------------*/
#ifdef __FreeBSD__
static void
elsa_isdnmc_read_fifo(void *buf, const void *base, size_t len)
{
}
#else
static void
elsa_isdnmc_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size)
{
bus_space_tag_t t = sc->sc_maps[0].t;
bus_space_handle_t h = sc->sc_maps[0].h;
switch (what) {
case ISIC_WHAT_ISAC:
bus_space_write_1(t, h, ADDR_LATCH, 0);
bus_space_read_multi_1(t, h, ISAC_DATA, buf, size);
break;
case ISIC_WHAT_HSCXA:
bus_space_write_1(t, h, ADDR_LATCH, 0);
bus_space_read_multi_1(t, h, HSCX_DATA, buf, size);
break;
case ISIC_WHAT_HSCXB:
bus_space_write_1(t, h, ADDR_LATCH, 0x40);
bus_space_read_multi_1(t, h, HSCX_DATA, buf, size);
break;
}
}
#endif
/*---------------------------------------------------------------------------*
* write fifo routines
*---------------------------------------------------------------------------*/
#ifdef __FreeBSD__
static void
elsa_isdnmc_write_fifo(void *base, const void *buf, size_t len)
{
}
#else
static void
elsa_isdnmc_write_fifo(struct isic_softc *sc, int what, const void *buf, size_t size)
{
bus_space_tag_t t = sc->sc_maps[0].t;
bus_space_handle_t h = sc->sc_maps[0].h;
switch (what) {
case ISIC_WHAT_ISAC:
bus_space_write_1(t, h, ADDR_LATCH, 0);
bus_space_write_multi_1(t, h, ISAC_DATA, (u_int8_t*)buf, size);
break;
case ISIC_WHAT_HSCXA:
bus_space_write_1(t, h, ADDR_LATCH, 0);
bus_space_write_multi_1(t, h, HSCX_DATA, (u_int8_t*)buf, size);
break;
case ISIC_WHAT_HSCXB:
bus_space_write_1(t, h, ADDR_LATCH, 0x40);
bus_space_write_multi_1(t, h, HSCX_DATA, (u_int8_t*)buf, size);
break;
}
}
#endif
/*---------------------------------------------------------------------------*
* write register routines
*---------------------------------------------------------------------------*/
#ifdef __FreeBSD__
static void
elsa_isdnmc_write_reg(u_char *base, u_int offset, u_int v)
{
}
#else
static void
elsa_isdnmc_write_reg(struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data)
{
bus_space_tag_t t = sc->sc_maps[0].t;
bus_space_handle_t h = sc->sc_maps[0].h;
switch (what) {
case ISIC_WHAT_ISAC:
bus_space_write_1(t, h, ADDR_LATCH, offs);
bus_space_write_1(t, h, ISAC_DATA, data);
break;
case ISIC_WHAT_HSCXA:
bus_space_write_1(t, h, ADDR_LATCH, offs);
bus_space_write_1(t, h, HSCX_DATA, data);
break;
case ISIC_WHAT_HSCXB:
bus_space_write_1(t, h, ADDR_LATCH, 0x40+offs);
bus_space_write_1(t, h, HSCX_DATA, data);
break;
}
}
#endif
/*---------------------------------------------------------------------------*
* read register routines
*---------------------------------------------------------------------------*/
#ifdef __FreeBSD__
static u_char
elsa_isdnmc_read_reg(u_char *base, u_int offset)
{
return 0;
}
#else
static u_int8_t
elsa_isdnmc_read_reg(struct isic_softc *sc, int what, bus_size_t offs)
{
bus_space_tag_t t = sc->sc_maps[0].t;
bus_space_handle_t h = sc->sc_maps[0].h;
switch (what) {
case ISIC_WHAT_ISAC:
bus_space_write_1(t, h, ADDR_LATCH, offs);
return bus_space_read_1(t, h, ISAC_DATA);
case ISIC_WHAT_HSCXA:
bus_space_write_1(t, h, ADDR_LATCH, offs);
return bus_space_read_1(t, h, HSCX_DATA);
case ISIC_WHAT_HSCXB:
bus_space_write_1(t, h, ADDR_LATCH, 0x40+offs);
return bus_space_read_1(t, h, HSCX_DATA);
}
return 0;
}
#endif
#ifdef __FreeBSD__
#else
/*
* XXX - one time only! Some of this has to go into an enable
* function, with apropriate counterpart in disable, so a card
* could be removed an inserted again. But never mind for now,
* this won't work anyway for several reasons (both in NetBSD
* and in I4B).
*/
int
isic_attach_elsaisdnmc(struct pcmcia_isic_softc *psc, struct pcmcia_config_entry *cfe, struct pcmcia_attach_args *pa)
{
struct isic_softc *sc = &psc->sc_isic;
bus_space_tag_t t;
bus_space_handle_t h;
/* Validate config info */
if (cfe->num_memspace != 0)
printf(": unexpected number of memory spaces %d should be 0\n",
cfe->num_memspace);
if (cfe->num_iospace != 1)
printf(": unexpected number of memory spaces %d should be 1\n",
cfe->num_iospace);
/* Allocate pcmcia space */
if (pcmcia_io_alloc(pa->pf, 0, cfe->iospace[0].length,
cfe->iospace[0].length, &psc->sc_pcioh))
printf(": can't allocate i/o space\n");
/* map them */
if (pcmcia_io_map(pa->pf, ((cfe->flags & PCMCIA_CFE_IO16) ?
PCMCIA_WIDTH_IO16 : PCMCIA_WIDTH_IO8), 0,
cfe->iospace[0].length, &psc->sc_pcioh, &psc->sc_io_window)) {
printf(": can't map i/o space\n");
return 0;
}
/* OK, this will work! */
sc->sc_cardtyp = CARD_TYPEP_ELSAMLIMC;
/* Setup bus space maps */
sc->sc_num_mappings = 1;
MALLOC_MAPS(sc);
/* Copy our handles/tags to the MI maps */
sc->sc_maps[0].t = psc->sc_pcioh.iot;
sc->sc_maps[0].h = psc->sc_pcioh.ioh;
sc->sc_maps[0].offset = 0;
sc->sc_maps[0].size = 0; /* not our mapping */
t = sc->sc_maps[0].t;
h = sc->sc_maps[0].h;
sc->clearirq = elsa_isdnmc_clrirq;
sc->readreg = elsa_isdnmc_read_reg;
sc->writereg = elsa_isdnmc_write_reg;
sc->readfifo = elsa_isdnmc_read_fifo;
sc->writefifo = elsa_isdnmc_write_fifo;
/* setup IOM bus type */
sc->sc_bustyp = BUS_TYPE_IOM2;
sc->sc_ipac = 0;
sc->sc_bfifolen = HSCX_FIFO_LEN;
return 1;
}
#endif
#endif /* ISIC > 0 */

View File

@ -1,251 +0,0 @@
/*
* Copyright (c) 1998 Martin Husemann. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* 4. Altered versions must be plainly marked as such, and must not be
* misrepresented as being the original software and/or documentation.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*---------------------------------------------------------------------------
*
* ELSA MicroLink MC/all card specific routines
* --------------------------------------------
*
* $FreeBSD$
*
* last edit-date: [Sun Feb 14 10:26:29 1999]
*
* -mh started support for ELSA MC/all
*
*---------------------------------------------------------------------------*/
#ifdef __FreeBSD__
#include "isic.h"
#include "opt_i4b.h"
#else
#define NISIC 1
#endif
#if NISIC > 0 && defined(ELSA_MCALL)
#include <sys/param.h>
#if defined(__FreeBSD__) && __FreeBSD__ >= 3
#include <sys/ioccom.h>
#else
#include <sys/ioctl.h>
#endif
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#ifdef __FreeBSD__
#include <machine/clock.h>
#include <i386/isa/isa_device.h>
#else
#include <machine/bus.h>
#include <sys/device.h>
#endif
#include <sys/socket.h>
#include <net/if.h>
#ifdef __FreeBSD__
#include <machine/i4b_debug.h>
#include <machine/i4b_ioctl.h>
#else
#include <i4b/i4b_debug.h>
#include <i4b/i4b_ioctl.h>
#include <dev/pcmcia/pcmciareg.h>
#include <dev/pcmcia/pcmciavar.h>
#endif
#include <i4b/layer1/i4b_l1.h>
#include <i4b/layer1/i4b_isac.h>
#include <i4b/layer1/i4b_hscx.h>
#include <i4b/layer1/i4b_ipac.h>
#include <i4b/layer1/pcmcia_isic.h>
#ifndef __FreeBSD__
/* PCMCIA support routines */
static u_int8_t elsa_mcall_read_reg __P((struct isic_softc *sc, int what, bus_size_t offs));
static void elsa_mcall_write_reg __P((struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data));
static void elsa_mcall_read_fifo __P((struct isic_softc *sc, int what, void *buf, size_t size));
static void elsa_mcall_write_fifo __P((struct isic_softc *sc, int what, const void *data, size_t size));
#endif
/*---------------------------------------------------------------------------*
* read fifo routines
*---------------------------------------------------------------------------*/
#ifdef __FreeBSD__
static int PCMCIA_IO_BASE = 0; /* ap: XXX hack */
static void
elsa_mcall_read_fifo(void *buf, const void *base, size_t len)
{
}
#else
static void
elsa_mcall_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size)
{
/*
bus_space_tag_t t = sc->sc_maps[0].t;
bus_space_handle_t h = sc->sc_maps[0].h;
*/
}
#endif
/*---------------------------------------------------------------------------*
* write fifo routines
*---------------------------------------------------------------------------*/
#ifdef __FreeBSD__
static void
elsa_mcall_write_fifo(void *base, const void *buf, size_t len)
{
}
#else
static void
elsa_mcall_write_fifo(struct isic_softc *sc, int what, const void *buf, size_t size)
{
/*
bus_space_tag_t t = sc->sc_maps[0].t;
bus_space_handle_t h = sc->sc_maps[0].h;
*/
}
#endif
/*---------------------------------------------------------------------------*
* write register routines
*---------------------------------------------------------------------------*/
#ifdef __FreeBSD__
static void
elsa_mcall_write_reg(u_char *base, u_int offset, u_int v)
{
}
#else
static void
elsa_mcall_write_reg(struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data)
{
/*
bus_space_tag_t t = sc->sc_maps[0].t;
bus_space_handle_t h = sc->sc_maps[0].h;
*/
}
#endif
/*---------------------------------------------------------------------------*
* read register routines
*---------------------------------------------------------------------------*/
#ifdef __FreeBSD__
static u_char
elsa_mcall_read_reg(u_char *base, u_int offset)
{
return 0;
}
#else
static u_int8_t
elsa_mcall_read_reg(struct isic_softc *sc, int what, bus_size_t offs)
{
/*
bus_space_tag_t t = sc->sc_maps[0].t;
bus_space_handle_t h = sc->sc_maps[0].h;
*/
return 0;
}
#endif
#ifdef __FreeBSD__
#else
/*
* XXX - one time only! Some of this has to go into an enable
* function, with apropriate counterpart in disable, so a card
* could be removed an inserted again. But never mind for now,
* this won't work anyway for several reasons (both in NetBSD
* and in I4B).
*/
int
isic_attach_elsamcall(struct pcmcia_isic_softc *psc, struct pcmcia_config_entry *cfe, struct pcmcia_attach_args *pa)
{
struct isic_softc *sc = &psc->sc_isic;
bus_space_tag_t t;
bus_space_handle_t h;
/* Validate config info */
if (cfe->num_memspace != 0)
printf(": unexpected number of memory spaces %d should be 0\n",
cfe->num_memspace);
if (cfe->num_iospace != 1)
printf(": unexpected number of memory spaces %d should be 1\n",
cfe->num_iospace);
/* Allocate pcmcia space */
if (pcmcia_io_alloc(pa->pf, 0, cfe->iospace[0].length,
cfe->iospace[0].length, &psc->sc_pcioh))
printf(": can't allocate i/o space\n");
/* map them */
if (pcmcia_io_map(pa->pf, ((cfe->flags & PCMCIA_CFE_IO16) ?
PCMCIA_WIDTH_IO16 : PCMCIA_WIDTH_IO8), 0,
cfe->iospace[0].length, &psc->sc_pcioh, &psc->sc_io_window)) {
printf(": can't map i/o space\n");
return 0;
}
/* setup card type */
sc->sc_cardtyp = CARD_TYPEP_ELSAMLMCALL;
/* Setup bus space maps */
sc->sc_num_mappings = 1;
MALLOC_MAPS(sc);
/* Copy our handles/tags to the MI maps */
sc->sc_maps[0].t = psc->sc_pcioh.iot;
sc->sc_maps[0].h = psc->sc_pcioh.ioh;
sc->sc_maps[0].offset = 0;
sc->sc_maps[0].size = 0; /* not our mapping */
t = sc->sc_maps[0].t;
h = sc->sc_maps[0].h;
sc->clearirq = NULL;
sc->readreg = elsa_mcall_read_reg;
sc->writereg = elsa_mcall_write_reg;
sc->readfifo = elsa_mcall_read_fifo;
sc->writefifo = elsa_mcall_write_fifo;
/* setup IOM bus type */
sc->sc_bustyp = BUS_TYPE_IOM2;
sc->sc_ipac = 1;
sc->sc_bfifolen = IPAC_BFIFO_LEN;
return 1;
}
#endif
#endif /* NISIC > 0 */

387
sys/i4b/layer1/i4b_hdlc.h Normal file
View File

@ -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_ */

View File

@ -1,183 +0,0 @@
/*
* Copyright (c) 1998 Matthias Apitz. All rights reserved.
*
* Copyright (c) 1998, 1999 Hellmuth Michaelis. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* 4. Altered versions must be plainly marked as such, and must not be
* misrepresented as being the original software and/or documentation.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*---------------------------------------------------------------------------
*
* i4b_isic_pcmcia.c - i4b FreeBSD PCMCIA support
* ----------------------------------------------
*
* $FreeBSD$
*
* last edit-date: [Mon Apr 26 10:52:57 1999]
*
*---------------------------------------------------------------------------*/
#ifdef __FreeBSD__
#include "isic.h"
#include "opt_i4b.h"
#include "card.h"
#undef NCARD
#define NCARD 0
#if (NISIC > 0) && (NCARD > 0)
#include "apm.h"
#include <sys/types.h>
#include <sys/select.h>
#include <sys/param.h>
#include <i386/isa/isa_device.h>
#if defined(__FreeBSD__) && __FreeBSD__ >= 3
#include <sys/ioccom.h>
#else
#include <sys/ioctl.h>
#endif
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <net/if.h>
#include <machine/clock.h>
#include <i386/isa/isa_device.h>
#include <pccard/cardinfo.h>
#include <pccard/driver.h>
#include <pccard/slot.h>
#include <machine/i4b_debug.h>
#include <machine/i4b_ioctl.h>
#include <machine/i4b_trace.h>
#include <i4b/layer1/i4b_l1.h>
#include <i4b/layer1/i4b_isac.h>
#include <i4b/layer1/i4b_hscx.h>
#include <i4b/include/i4b_l1l2.h>
#include <i4b/include/i4b_mbuf.h>
#include <i4b/include/i4b_global.h>
#ifdef __FreeBSD__
#if !(defined(__FreeBSD_version)) || (defined(__FreeBSD_version) && __FreeBSD_version >= 300006)
void isicintr ( int unit );
#else
extern void isicintr(int unit);
#endif
#endif
extern int isicattach(struct isa_device *dev);
/*
* PC-Card (PCMCIA) specific code.
*/
static int isic_pccard_init __P((struct pccard_devinfo *));
static void isic_unload __P((struct pccard_devinfo *));
static int isic_card_intr __P((struct pccard_devinfo *));
#if defined(__FreeBSD__) && __FreeBSD__ < 3
static struct pccard_device isic_info = {
"isic",
isic_pccard_init,
isic_unload,
isic_card_intr,
0, /* Attributes - presently unused */
&net_imask
};
DATA_SET(pccarddrv_set, isic_info);
#else
PCCARD_MODULE(isic, isic_pccard_init, isic_unload, isic_card_intr, 0,net_imask);
#endif
/*
* Initialize the device - called from Slot manager.
*/
static int opened = 0; /* our cards status */
static int isic_pccard_init(devi)
struct pccard_devinfo *devi;
{
#ifdef AVM_A1_PCMCIA
struct isa_device *is = &devi->isahd;
if ((1 << is->id_unit) & opened)
return(EBUSY);
opened |= 1 << is->id_unit;
printf("isic%d: PCMCIA init, irqmask = 0x%x (%d), iobase = 0x%x\n",
is->id_unit, is->id_irq, devi->slt->irq, is->id_iobase);
/*
* look if there is really an AVM PCMCIA Fritz!Card and
* setup the card specific stuff
*/
isic_probe_avma1_pcmcia(is);
/* ap:
* XXX what's to do with the return value?
*/
/*
* try to attach the PCMCIA card as a normal A1 card
*/
isic_realattach(is, 0);
#endif
return(0);
}
static void isic_unload(devi)
struct pccard_devinfo *devi;
{
struct isa_device *is = &devi->isahd;
printf("isic%d: unloaded\n", is->id_unit);
opened &= ~(1 << is->id_unit);
}
/*
* card_intr - Shared interrupt called from
* front end of PC-Card handler.
*/
static int isic_card_intr(devi)
struct pccard_devinfo *devi;
{
isicintr(devi->isahd.id_unit);
return(1);
}
#endif /* (NISIC > 0) && (NCARD > 0) */
#endif /* __FreeBSD__ */

447
sys/i4b/layer1/i4b_l1dmux.c Normal file
View File

@ -0,0 +1,447 @@
/*
* Copyright (c) 2000 Hellmuth Michaelis. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*---------------------------------------------------------------------------
*
* i4b_l1dmux.c - isdn4bsd layer 1 driver multiplexer
* --------------------------------------------------
*
* $Id: i4b_l1dmux.c,v 1.12 2000/06/02 16:14:36 hm Exp $
*
* $FreeBSD$
*
* last edit-date: [Fri Jun 2 14:37:39 2000]
*
*---------------------------------------------------------------------------*/
#include "isic.h"
#include "iwic.h"
#include "ifpi.h"
#include "ifpnp.h"
#include "ihfc.h"
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <net/if.h>
#include <machine/i4b_debug.h>
#include <machine/i4b_ioctl.h>
#include <machine/i4b_trace.h>
#include <i4b/layer1/i4b_l1.h>
#include <i4b/include/i4b_l1l2.h>
#include <i4b/include/i4b_mbuf.h>
#include <i4b/include/i4b_global.h>
/*
* this code is nothing but a big dynamic switch to multiplex and demultiplex
* layer 1 hardware isdn drivers to a common layer 2.
*
* when a card is successfully attached at system boot time, the driver for
* this card calls the routine i4b_l1_mph_status_ind() with status = STI_ATTACH.
*
* This command is used to setup the tables for converting a "driver unit" and
* "driver type" pair (encoded in the calls from the hardware driver to the
* routines in this source file) to a "unit number" used in layer 2 and the
* layers above (up to and including the isdnd daemon) and for converting
* layer 2 units back to calling the appropriate driver and driver unit
* number.
*
* Example: in my setup, a Winbond (iwic) card is probed first and gets
* driver unit number 0, driver type 1 in layer 1. This becomes unit
* number 0 in layer 2 and up. The second card probed is a Teles card
* (isic) and gets driver unit number 0, driver type 0 in layer 1. This
* becomes unit number 1 in layer 1 and up.
*
* To add support for a new driver, add a new driver number to i4b_l1.h:
* currently we have L1DRVR_ISIC and L1DRVR_IWIC, so you would add
* L1DRVR_FOO. More you would want to add a L0FOOUNIT to encode unit
* numbers in your driver. You then have to add a l1foounittab[] and
* add an entry to the getl1tab() routine for your driver. The only
* thing left now is to write your driver with the support functions
* for this multiplexer ;-)
*/
unsigned int i4b_l1_debug = L1_DEBUG_DEFAULT;
#if NISIC > 0
static int l1isicunittab[MAXL1UNITS];
#endif
#if NIWIC > 0
static int l1iwicunittab[MAXL1UNITS];
#endif
#if NIFPI > 0
static int l1ifpiunittab[MAXL1UNITS];
#endif
#if NIHFC > 0
static int l1ihfcunittab[MAXL1UNITS];
#endif
#if NIFPNP > 0
static int l1ifpnpunittab[MAXL1UNITS];
#endif
static int numl1units = 0;
static int l1drvunittab[MAXL1UNITS];
static struct i4b_l1mux_func *l1mux_func[MAXL1DRVR];
static int i4b_l1_ph_data_req(int, struct mbuf *, int);
static int i4b_l1_ph_activate_req(int);
/* from i4btrc driver i4b_trace.c */
int get_trace_data_from_l1(int unit, int what, int len, char *buf);
/* from layer 2 */
int i4b_ph_data_ind(int unit, struct mbuf *m);
int i4b_ph_activate_ind(int unit);
int i4b_ph_deactivate_ind(int unit);
int i4b_mph_status_ind(int, int, int);
/* layer 1 lme */
int i4b_l1_mph_command_req(int, int, void *);
/*---------------------------------------------------------------------------*
* jump table: interface function pointers L1/L2 interface
*---------------------------------------------------------------------------*/
struct i4b_l1l2_func i4b_l1l2_func = {
/* Layer 1 --> Layer 2 */
(int (*)(int, struct mbuf *)) i4b_ph_data_ind,
(int (*)(int)) i4b_ph_activate_ind,
(int (*)(int)) i4b_ph_deactivate_ind,
/* Layer 2 --> Layer 1 */
(int (*)(int, struct mbuf *, int)) i4b_l1_ph_data_req,
(int (*)(int)) i4b_l1_ph_activate_req,
/* Layer 1 --> trace interface driver, ISDN trace data */
(int (*)(i4b_trace_hdr_t *, int, u_char *)) get_trace_data_from_l1,
/* Driver control and status information */
(int (*)(int, int, int)) i4b_mph_status_ind,
(int (*)(int, int, void *)) i4b_l1_mph_command_req,
};
/*---------------------------------------------------------------------------*
* return a pointer to a layer 0 drivers unit tab
*---------------------------------------------------------------------------*/
static __inline int *
getl1tab(int drv)
{
switch(drv)
{
#if NISIC > 0
case L1DRVR_ISIC:
return(l1isicunittab);
break;
#endif
#if NIWIC > 0
case L1DRVR_IWIC:
return(l1iwicunittab);
break;
#endif
#if NIFPI > 0
case L1DRVR_IFPI:
return(l1ifpiunittab);
break;
#endif
#if NIHFC > 0
case L1DRVR_IHFC:
return(l1ihfcunittab);
break;
#endif
#if NIFPNP > 0
case L1DRVR_IFPNP:
return(l1ifpnpunittab);
break;
#endif
default:
return(NULL);
break;
}
}
/*===========================================================================*
* B - Channel (data transfer)
*===========================================================================*/
/*---------------------------------------------------------------------------*
* return the address of ISDN drivers linktab
*---------------------------------------------------------------------------*/
isdn_link_t *
i4b_l1_ret_linktab(int unit, int channel)
{
int drv_unit, ch_unit;
drv_unit = L0DRVR(l1drvunittab[unit]);
ch_unit = L0UNIT(l1drvunittab[unit]);
NDBGL1(L1_PRIM, "unit %d -> drv %d / drvunit %d", unit, drv_unit, ch_unit);
if (drv_unit >= MAXL1DRVR || l1mux_func[drv_unit] == NULL
|| l1mux_func[drv_unit]->ret_linktab == NULL)
panic("i4b_l1_ret_linktab: unknown driver type %d\n", drv_unit);
return(l1mux_func[drv_unit]->ret_linktab(ch_unit, channel));
}
/*---------------------------------------------------------------------------*
* set the ISDN driver linktab
*---------------------------------------------------------------------------*/
void
i4b_l1_set_linktab(int unit, int channel, drvr_link_t *dlt)
{
int drv_unit, ch_unit;
drv_unit = L0DRVR(l1drvunittab[unit]);
ch_unit = L0UNIT(l1drvunittab[unit]);
NDBGL1(L1_PRIM, "unit %d -> drv %d / drvunit %d", unit, drv_unit, ch_unit);
if (drv_unit >= MAXL1DRVR || l1mux_func[drv_unit] == NULL
|| l1mux_func[drv_unit]->set_linktab == NULL)
panic("i4b_l1_set_linktab: unknown driver type %d\n", drv_unit);
l1mux_func[drv_unit]->set_linktab(ch_unit, channel, dlt);
}
/*===========================================================================*
* trace D- and B-Channel support
*===========================================================================*/
/*---------------------------------------------------------------------------*
* L0 -> L1 trace information to trace driver
*---------------------------------------------------------------------------*/
int
i4b_l1_trace_ind(i4b_trace_hdr_t *hdr, int len, u_char *data)
{
register int *tab;
if((tab = getl1tab(L0DRVR(hdr->unit))) == NULL)
panic("i4b_l1_trace_ind: unknown driver type %d\n", L0DRVR(hdr->unit));
NDBGL1(L1_PRIM, "(drv %d / drvunit %d) -> unit %d", L0DRVR(hdr->unit), L0UNIT(hdr->unit), tab[L0UNIT(hdr->unit)]);
hdr->unit = tab[L0UNIT(hdr->unit)];
return(MPH_Trace_Ind(hdr, len, data));
}
/*===========================================================================*
* D - Channel (signalling)
*===========================================================================*/
/*---------------------------------------------------------------------------*
* L0 -> L1 status indication from hardware
*---------------------------------------------------------------------------*/
int
i4b_l1_mph_status_ind(int drv_unit, int status, int parm, struct i4b_l1mux_func *l1mux_func_p)
{
register int *tab;
/*
* in case the status STI_ATTACH is sent from the hardware, the
* driver has just attached itself and we need to initialize
* the tables and assorted variables.
*/
if(status == STI_ATTACH)
{
if (l1mux_func_p == (struct i4b_l1mux_func *)0)
panic("i4b_l1_mph_status_ind: i4b_l1mux_func pointer is NULL\n");
if(numl1units < MAXL1UNITS)
{
if((tab = getl1tab(L0DRVR(drv_unit))) == NULL)
panic("i4b_l1_mph_status_ind: unknown driver type %d\n", L0DRVR(drv_unit));
tab[L0UNIT(drv_unit)] = numl1units;
l1drvunittab[numl1units] = drv_unit;
l1mux_func[L0DRVR(drv_unit)] = l1mux_func_p;
switch(L0DRVR(drv_unit))
{
#if NISIC > 0
case L1DRVR_ISIC:
printf("isic%d: passive stack unit %d\n", L0UNIT(drv_unit), numl1units);
break;
#endif
#if NIWIC > 0
case L1DRVR_IWIC:
printf("iwic%d: passive stack unit %d\n", L0UNIT(drv_unit), numl1units);
break;
#endif
#if NIFPI > 0
case L1DRVR_IFPI:
printf("ifpi%d: passive stack unit %d\n", L0UNIT(drv_unit), numl1units);
break;
#endif
#if NIFPNP > 0
case L1DRVR_IFPNP:
printf("ifpnp%d: passive stack unit %d\n", L0UNIT(drv_unit), numl1units);
break;
#endif
#if NIHFC > 0
case L1DRVR_IHFC:
printf("ihfc%d: passive stack unit %d\n", L0UNIT(drv_unit), numl1units);
#endif
}
NDBGL1(L1_PRIM, "ATTACH drv %d, drvunit %d -> unit %d", L0DRVR(drv_unit), L0UNIT(drv_unit), numl1units);
numl1units++;
}
}
if((tab = getl1tab(L0DRVR(drv_unit))) == NULL)
panic("i4b_l1_mph_status_ind: unknown driver type %d\n", L0DRVR(drv_unit));
NDBGL1(L1_PRIM, "(drv %d / drvunit %d) -> unit %d\n", L0DRVR(drv_unit), L0UNIT(drv_unit), tab[L0UNIT(drv_unit)]);
return(MPH_Status_Ind(tab[L0UNIT(drv_unit)], status, parm));
}
/*---------------------------------------------------------------------------*
* L0 -> L1 data from hardware
*---------------------------------------------------------------------------*/
int
i4b_l1_ph_data_ind(int drv_unit, struct mbuf *data)
{
register int *tab;
if((tab = getl1tab(L0DRVR(drv_unit))) == NULL)
panic("i4b_l1_ph_data_ind: unknown driver type %d\n", L0DRVR(drv_unit));
#if 0
NDBGL1(L1_PRIM, "(drv %d / drvunit %d) -> unit %d", L0DRVR(drv_unit), L0UNIT(drv_unit), tab[L0UNIT(drv_unit)]);
#endif
return(PH_Data_Ind(tab[L0UNIT(drv_unit)], data));
}
/*---------------------------------------------------------------------------*
* L0 -> L1 activate indication from hardware
*---------------------------------------------------------------------------*/
int
i4b_l1_ph_activate_ind(int drv_unit)
{
register int *tab;
if((tab = getl1tab(L0DRVR(drv_unit))) == NULL)
panic("i4b_l1_ph_activate_ind: unknown driver type %d\n", L0DRVR(drv_unit));
NDBGL1(L1_PRIM, "(drv %d / drvunit %d) -> unit %d", L0DRVR(drv_unit), L0UNIT(drv_unit), tab[L0UNIT(drv_unit)]);
return(PH_Act_Ind(tab[L0UNIT(drv_unit)]));
}
/*---------------------------------------------------------------------------*
* L0 -> L1 deactivate indication from hardware
*---------------------------------------------------------------------------*/
int
i4b_l1_ph_deactivate_ind(int drv_unit)
{
register int *tab;
if((tab = getl1tab(L0DRVR(drv_unit))) == NULL)
panic("i4b_l1_ph_deactivate_ind: unknown driver type %d\n", L0DRVR(drv_unit));
NDBGL1(L1_PRIM, "(drv %d / drvunit %d) -> unit %d", L0DRVR(drv_unit), L0UNIT(drv_unit), tab[L0UNIT(drv_unit)]);
return(PH_Deact_Ind(tab[L0UNIT(drv_unit)]));
}
/*---------------------------------------------------------------------------*
* L2 -> L1 command to hardware
*---------------------------------------------------------------------------*/
int
i4b_l1_mph_command_req(int unit, int command, void * parm)
{
register int drv_unit = L0DRVR(l1drvunittab[unit]);
register int ch_unit = L0UNIT(l1drvunittab[unit]);
NDBGL1(L1_PRIM, "unit %d -> drv %d / drvunit %d", unit, drv_unit, ch_unit);
if (drv_unit >= MAXL1DRVR || l1mux_func[drv_unit] == NULL
|| l1mux_func[drv_unit]->mph_command_req == NULL)
panic("i4b_l1_mph_command_req: unknown driver type %d\n", drv_unit);
return(l1mux_func[drv_unit]->mph_command_req(ch_unit, command, parm));
}
/*---------------------------------------------------------------------------*
* L2 -> L1 data to be transmitted to hardware
*---------------------------------------------------------------------------*/
int
i4b_l1_ph_data_req(int unit, struct mbuf *data, int flag)
{
register int drv_unit = L0DRVR(l1drvunittab[unit]);
register int ch_unit = L0UNIT(l1drvunittab[unit]);
#if 0
NDBGL1(L1_PRIM, "unit %d -> drv %d / drvunit %d", unit, drv_unit, ch_unit);
#endif
if (drv_unit >= MAXL1DRVR || l1mux_func[drv_unit] == NULL
|| l1mux_func[drv_unit]->ph_data_req == NULL)
panic("i4b_l1_ph_data_req: unknown driver type %d\n", drv_unit);
return(l1mux_func[drv_unit]->ph_data_req(ch_unit, data, flag));
}
/*---------------------------------------------------------------------------*
* L2 -> L1 activate request to hardware
*---------------------------------------------------------------------------*/
int
i4b_l1_ph_activate_req(int unit)
{
register int drv_unit = L0DRVR(l1drvunittab[unit]);
register int ch_unit = L0UNIT(l1drvunittab[unit]);
NDBGL1(L1_PRIM, "unit %d -> drv %d / drvunit %d", unit, drv_unit, ch_unit);
if (drv_unit >= MAXL1DRVR || l1mux_func[drv_unit] == NULL
|| l1mux_func[drv_unit]->ph_activate_req == NULL)
panic("i4b_l1_ph_activate_req: unknown driver type %d\n", drv_unit);
return(l1mux_func[drv_unit]->ph_activate_req(ch_unit));
}
/* EOF */

View File

@ -0,0 +1,81 @@
/*
* Copyright (c) 2000 Hellmuth Michaelis. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*---------------------------------------------------------------------------
*
* i4b_l1lib.c - general useful L1 procedures
* ------------------------------------------
*
* $Id: i4b_l1lib.c,v 1.3 2000/05/29 15:41:41 hm Exp $
*
* $FreeBSD$
*
* last edit-date: [Mon May 29 15:24:21 2000]
*
*---------------------------------------------------------------------------*/
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <net/if.h>
#include <machine/i4b_debug.h>
#include <machine/i4b_ioctl.h>
#include <machine/i4b_trace.h>
#include <i4b/layer1/i4b_l1.h>
#define TEL_IDLE_MIN (BCH_MAX_DATALEN/2)
/*---------------------------------------------------------------------------*
* telephony silence detection
*---------------------------------------------------------------------------*/
int
i4b_l1_bchan_tel_silence(unsigned char *data, int len)
{
register int i = 0;
register int j = 0;
/* count idle bytes */
for(;i < len; i++)
{
if((*data >= 0xaa) && (*data <= 0xac))
j++;
data++;
}
#ifdef NOTDEF
printf("i4b_l1_bchan_tel_silence: got %d silence bytes in frame\n", j);
#endif
if(j < (TEL_IDLE_MIN))
return(0);
else
return(1);
}

View File

@ -0,0 +1,61 @@
/*
* Copyright (c) 2000 Gary Jennejohn. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*---------------------------------------------------------------------------
*
* i4b_ifpi - Fritz!Card PCI for split layers
* ------------------------------------------
*
* $Id: i4b_ifpi_ext.h,v 1.2 2000/06/02 16:14:36 hm Exp $
*
* $FreeBSD$
*
* last edit-date: [Fri Jun 2 14:53:31 2000]
*
*---------------------------------------------------------------------------*/
#ifndef _I4B_IFPI_EXT_H_
#define _I4B_IFPI_EXT_H_
#include <i4b/include/i4b_l3l4.h>
void ifpi_set_linktab(int unit, int channel, drvr_link_t * dlt);
isdn_link_t *ifpi_ret_linktab(int unit, int channel);
int ifpi_ph_data_req(int unit, struct mbuf *m, int freeflag);
int ifpi_ph_activate_req(int unit);
int ifpi_mph_command_req(int unit, int command, void *parm);
void ifpi_isac_irq(struct l1_softc *sc, int ista);
void ifpi_isac_l1_cmd(struct l1_softc *sc, int command);
int ifpi_isac_init(struct l1_softc *sc);
void ifpi_recover(struct l1_softc *sc);
char * ifpi_printstate(struct l1_softc *sc);
void ifpi_next_state(struct l1_softc *sc, int event);
#define IFPI_MAXUNIT 4
extern struct l1_softc *ifpi_scp[IFPI_MAXUNIT];
#endif /* _I4B_IFPI_EXT_H_ */

View File

@ -0,0 +1,669 @@
/*
* Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*---------------------------------------------------------------------------
*
* i4b_ifpi_isac.c - i4b Fritz PCI ISAC handler
* --------------------------------------------
*
* $Id: i4b_ifpi_isac.c,v 1.3 2000/05/29 15:41:41 hm Exp $
*
* $FreeBSD$
*
* last edit-date: [Mon May 29 15:22:52 2000]
*
*---------------------------------------------------------------------------*/
#include "ifpi.h"
#include "pci.h"
#if (NIFPI > 0) && (NPCI > 0)
#include "opt_i4b.h"
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <machine/stdarg.h>
#include <machine/clock.h>
#include <net/if.h>
#include <machine/i4b_debug.h>
#include <machine/i4b_ioctl.h>
#include <machine/i4b_trace.h>
#include <i4b/layer1/i4b_l1.h>
#include <i4b/layer1/isic/i4b_isic.h>
#include <i4b/layer1/isic/i4b_isac.h>
#include <i4b/layer1/isic/i4b_hscx.h>
#include <i4b/layer1/ifpi/i4b_ifpi_ext.h>
#include <i4b/include/i4b_global.h>
#include <i4b/include/i4b_mbuf.h>
static u_char ifpi_isac_exir_hdlr(register struct l1_softc *sc, u_char exir);
static void ifpi_isac_ind_hdlr(register struct l1_softc *sc, int ind);
/*---------------------------------------------------------------------------*
* ISAC interrupt service routine
*---------------------------------------------------------------------------*/
void
ifpi_isac_irq(struct l1_softc *sc, int ista)
{
register u_char c = 0;
NDBGL1(L1_F_MSG, "unit %d: ista = 0x%02x", sc->sc_unit, ista);
if(ista & ISAC_ISTA_EXI) /* extended interrupt */
{
c |= ifpi_isac_exir_hdlr(sc, ISAC_READ(I_EXIR));
}
if(ista & ISAC_ISTA_RME) /* receive message end */
{
register int rest;
u_char rsta;
/* get rx status register */
rsta = ISAC_READ(I_RSTA);
if((rsta & ISAC_RSTA_MASK) != 0x20)
{
int error = 0;
if(!(rsta & ISAC_RSTA_CRC)) /* CRC error */
{
error++;
NDBGL1(L1_I_ERR, "unit %d: CRC error", sc->sc_unit);
}
if(rsta & ISAC_RSTA_RDO) /* ReceiveDataOverflow */
{
error++;
NDBGL1(L1_I_ERR, "unit %d: Data Overrun error", sc->sc_unit);
}
if(rsta & ISAC_RSTA_RAB) /* ReceiveABorted */
{
error++;
NDBGL1(L1_I_ERR, "unit %d: Receive Aborted error", sc->sc_unit);
}
if(error == 0)
NDBGL1(L1_I_ERR, "unit %d: RME unknown error, RSTA = 0x%02x!", sc->sc_unit, rsta);
i4b_Dfreembuf(sc->sc_ibuf);
c |= ISAC_CMDR_RMC|ISAC_CMDR_RRES;
sc->sc_ibuf = NULL;
sc->sc_ib = NULL;
sc->sc_ilen = 0;
ISAC_WRITE(I_CMDR, ISAC_CMDR_RMC|ISAC_CMDR_RRES);
ISACCMDRWRDELAY();
return;
}
rest = (ISAC_READ(I_RBCL) & (ISAC_FIFO_LEN-1));
if(rest == 0)
rest = ISAC_FIFO_LEN;
if(sc->sc_ibuf == NULL)
{
if((sc->sc_ibuf = i4b_Dgetmbuf(rest)) != NULL)
sc->sc_ib = sc->sc_ibuf->m_data;
else
panic("ifpi_isac_irq: RME, i4b_Dgetmbuf returns NULL!\n");
sc->sc_ilen = 0;
}
if(sc->sc_ilen <= (MAX_DFRAME_LEN - rest))
{
ISAC_RDFIFO(sc->sc_ib, rest);
sc->sc_ilen += rest;
sc->sc_ibuf->m_pkthdr.len =
sc->sc_ibuf->m_len = sc->sc_ilen;
if(sc->sc_trace & TRACE_D_RX)
{
i4b_trace_hdr_t hdr;
hdr.unit = L0IFPIUNIT(sc->sc_unit);
hdr.type = TRC_CH_D;
hdr.dir = FROM_NT;
hdr.count = ++sc->sc_trace_dcount;
MICROTIME(hdr.time);
i4b_l1_trace_ind(&hdr, sc->sc_ibuf->m_len, sc->sc_ibuf->m_data);
}
c |= ISAC_CMDR_RMC;
if(sc->sc_enabled &&
(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S))
{
i4b_l1_ph_data_ind(L0IFPIUNIT(sc->sc_unit), sc->sc_ibuf);
}
else
{
i4b_Dfreembuf(sc->sc_ibuf);
}
}
else
{
NDBGL1(L1_I_ERR, "RME, input buffer overflow!");
i4b_Dfreembuf(sc->sc_ibuf);
c |= ISAC_CMDR_RMC|ISAC_CMDR_RRES;
}
sc->sc_ibuf = NULL;
sc->sc_ib = NULL;
sc->sc_ilen = 0;
}
if(ista & ISAC_ISTA_RPF) /* receive fifo full */
{
if(sc->sc_ibuf == NULL)
{
if((sc->sc_ibuf = i4b_Dgetmbuf(MAX_DFRAME_LEN)) != NULL)
sc->sc_ib= sc->sc_ibuf->m_data;
else
panic("ifpi_isac_irq: RPF, i4b_Dgetmbuf returns NULL!\n");
sc->sc_ilen = 0;
}
if(sc->sc_ilen <= (MAX_DFRAME_LEN - ISAC_FIFO_LEN))
{
ISAC_RDFIFO(sc->sc_ib, ISAC_FIFO_LEN);
sc->sc_ilen += ISAC_FIFO_LEN;
sc->sc_ib += ISAC_FIFO_LEN;
c |= ISAC_CMDR_RMC;
}
else
{
NDBGL1(L1_I_ERR, "RPF, input buffer overflow!");
i4b_Dfreembuf(sc->sc_ibuf);
sc->sc_ibuf = NULL;
sc->sc_ib = NULL;
sc->sc_ilen = 0;
c |= ISAC_CMDR_RMC|ISAC_CMDR_RRES;
}
}
if(ista & ISAC_ISTA_XPR) /* transmit fifo empty (XPR bit set) */
{
if((sc->sc_obuf2 != NULL) && (sc->sc_obuf == NULL))
{
sc->sc_freeflag = sc->sc_freeflag2;
sc->sc_obuf = sc->sc_obuf2;
sc->sc_op = sc->sc_obuf->m_data;
sc->sc_ol = sc->sc_obuf->m_len;
sc->sc_obuf2 = NULL;
#ifdef NOTDEF
printf("ob2=%x, op=%x, ol=%d, f=%d #",
sc->sc_obuf,
sc->sc_op,
sc->sc_ol,
sc->sc_state);
#endif
}
else
{
#ifdef NOTDEF
printf("ob=%x, op=%x, ol=%d, f=%d #",
sc->sc_obuf,
sc->sc_op,
sc->sc_ol,
sc->sc_state);
#endif
}
if(sc->sc_obuf)
{
ISAC_WRFIFO(sc->sc_op, min(sc->sc_ol, ISAC_FIFO_LEN));
if(sc->sc_ol > ISAC_FIFO_LEN) /* length > 32 ? */
{
sc->sc_op += ISAC_FIFO_LEN; /* bufferptr+32 */
sc->sc_ol -= ISAC_FIFO_LEN; /* length - 32 */
c |= ISAC_CMDR_XTF; /* set XTF bit */
}
else
{
if(sc->sc_freeflag)
{
i4b_Dfreembuf(sc->sc_obuf);
sc->sc_freeflag = 0;
}
sc->sc_obuf = NULL;
sc->sc_op = NULL;
sc->sc_ol = 0;
c |= ISAC_CMDR_XTF | ISAC_CMDR_XME;
}
}
else
{
sc->sc_state &= ~ISAC_TX_ACTIVE;
}
}
if(ista & ISAC_ISTA_CISQ) /* channel status change CISQ */
{
register u_char ci;
/* get command/indication rx register*/
ci = ISAC_READ(I_CIRR);
/* if S/Q IRQ, read SQC reg to clr SQC IRQ */
if(ci & ISAC_CIRR_SQC)
(void) ISAC_READ(I_SQRR);
/* C/I code change IRQ (flag already cleared by CIRR read) */
if(ci & ISAC_CIRR_CIC0)
ifpi_isac_ind_hdlr(sc, (ci >> 2) & 0xf);
}
if(c)
{
ISAC_WRITE(I_CMDR, c);
ISACCMDRWRDELAY();
}
}
/*---------------------------------------------------------------------------*
* ISAC L1 Extended IRQ handler
*---------------------------------------------------------------------------*/
static u_char
ifpi_isac_exir_hdlr(register struct l1_softc *sc, u_char exir)
{
u_char c = 0;
if(exir & ISAC_EXIR_XMR)
{
NDBGL1(L1_I_ERR, "EXIRQ Tx Message Repeat");
c |= ISAC_CMDR_XRES;
}
if(exir & ISAC_EXIR_XDU)
{
NDBGL1(L1_I_ERR, "EXIRQ Tx Data Underrun");
c |= ISAC_CMDR_XRES;
}
if(exir & ISAC_EXIR_PCE)
{
NDBGL1(L1_I_ERR, "EXIRQ Protocol Error");
}
if(exir & ISAC_EXIR_RFO)
{
NDBGL1(L1_I_ERR, "EXIRQ Rx Frame Overflow");
c |= ISAC_CMDR_RMC|ISAC_CMDR_RRES;
}
if(exir & ISAC_EXIR_SOV)
{
NDBGL1(L1_I_ERR, "EXIRQ Sync Xfer Overflow");
}
if(exir & ISAC_EXIR_MOS)
{
NDBGL1(L1_I_ERR, "EXIRQ Monitor Status");
}
if(exir & ISAC_EXIR_SAW)
{
/* cannot happen, STCR:TSF is set to 0 */
NDBGL1(L1_I_ERR, "EXIRQ Subscriber Awake");
}
if(exir & ISAC_EXIR_WOV)
{
/* cannot happen, STCR:TSF is set to 0 */
NDBGL1(L1_I_ERR, "EXIRQ Watchdog Timer Overflow");
}
return(c);
}
/*---------------------------------------------------------------------------*
* ISAC L1 Indication handler
*---------------------------------------------------------------------------*/
static void
ifpi_isac_ind_hdlr(register struct l1_softc *sc, int ind)
{
register int event;
switch(ind)
{
case ISAC_CIRR_IAI8:
NDBGL1(L1_I_CICO, "rx AI8 in state %s", ifpi_printstate(sc));
if(sc->sc_bustyp == BUS_TYPE_IOM2)
ifpi_isac_l1_cmd(sc, CMD_AR8);
event = EV_INFO48;
i4b_l1_mph_status_ind(L0IFPIUNIT(sc->sc_unit), STI_L1STAT, LAYER_ACTIVE, NULL);
break;
case ISAC_CIRR_IAI10:
NDBGL1(L1_I_CICO, "rx AI10 in state %s", ifpi_printstate(sc));
if(sc->sc_bustyp == BUS_TYPE_IOM2)
ifpi_isac_l1_cmd(sc, CMD_AR10);
event = EV_INFO410;
i4b_l1_mph_status_ind(L0IFPIUNIT(sc->sc_unit), STI_L1STAT, LAYER_ACTIVE, NULL);
break;
case ISAC_CIRR_IRSY:
NDBGL1(L1_I_CICO, "rx RSY in state %s", ifpi_printstate(sc));
event = EV_RSY;
break;
case ISAC_CIRR_IPU:
NDBGL1(L1_I_CICO, "rx PU in state %s", ifpi_printstate(sc));
event = EV_PU;
break;
case ISAC_CIRR_IDR:
NDBGL1(L1_I_CICO, "rx DR in state %s", ifpi_printstate(sc));
ifpi_isac_l1_cmd(sc, CMD_DIU);
event = EV_DR;
break;
case ISAC_CIRR_IDID:
NDBGL1(L1_I_CICO, "rx DID in state %s", ifpi_printstate(sc));
event = EV_INFO0;
i4b_l1_mph_status_ind(L0IFPIUNIT(sc->sc_unit), STI_L1STAT, LAYER_IDLE, NULL);
break;
case ISAC_CIRR_IDIS:
NDBGL1(L1_I_CICO, "rx DIS in state %s", ifpi_printstate(sc));
event = EV_DIS;
break;
case ISAC_CIRR_IEI:
NDBGL1(L1_I_CICO, "rx EI in state %s", ifpi_printstate(sc));
ifpi_isac_l1_cmd(sc, CMD_DIU);
event = EV_EI;
break;
case ISAC_CIRR_IARD:
NDBGL1(L1_I_CICO, "rx ARD in state %s", ifpi_printstate(sc));
event = EV_INFO2;
break;
case ISAC_CIRR_ITI:
NDBGL1(L1_I_CICO, "rx TI in state %s", ifpi_printstate(sc));
event = EV_INFO0;
break;
case ISAC_CIRR_IATI:
NDBGL1(L1_I_CICO, "rx ATI in state %s", ifpi_printstate(sc));
event = EV_INFO0;
break;
case ISAC_CIRR_ISD:
NDBGL1(L1_I_CICO, "rx SD in state %s", ifpi_printstate(sc));
event = EV_INFO0;
break;
default:
NDBGL1(L1_I_ERR, "UNKNOWN Indication 0x%x in state %s", ind, ifpi_printstate(sc));
event = EV_INFO0;
break;
}
ifpi_next_state(sc, event);
}
/*---------------------------------------------------------------------------*
* execute a layer 1 command
*---------------------------------------------------------------------------*/
void
ifpi_isac_l1_cmd(struct l1_softc *sc, int command)
{
u_char cmd;
#ifdef I4B_SMP_WORKAROUND
/* XXXXXXXXXXXXXXXXXXX */
/*
* patch from Wolfgang Helbig:
*
* Here is a patch that makes i4b work on an SMP:
* The card (TELES 16.3) didn't interrupt on an SMP machine.
* This is a gross workaround, but anyway it works *and* provides
* some information as how to finally fix this problem.
*/
HSCX_WRITE(0, H_MASK, 0xff);
HSCX_WRITE(1, H_MASK, 0xff);
ISAC_WRITE(I_MASK, 0xff);
DELAY(100);
HSCX_WRITE(0, H_MASK, HSCX_A_IMASK);
HSCX_WRITE(1, H_MASK, HSCX_B_IMASK);
ISAC_WRITE(I_MASK, ISAC_IMASK);
/* XXXXXXXXXXXXXXXXXXX */
#endif /* I4B_SMP_WORKAROUND */
if(command < 0 || command > CMD_ILL)
{
NDBGL1(L1_I_ERR, "illegal cmd 0x%x in state %s", command, ifpi_printstate(sc));
return;
}
if(sc->sc_bustyp == BUS_TYPE_IOM2)
cmd = ISAC_CIX0_LOW;
else
cmd = 0;
switch(command)
{
case CMD_TIM:
NDBGL1(L1_I_CICO, "tx TIM in state %s", ifpi_printstate(sc));
cmd |= (ISAC_CIXR_CTIM << 2);
break;
case CMD_RS:
NDBGL1(L1_I_CICO, "tx RS in state %s", ifpi_printstate(sc));
cmd |= (ISAC_CIXR_CRS << 2);
break;
case CMD_AR8:
NDBGL1(L1_I_CICO, "tx AR8 in state %s", ifpi_printstate(sc));
cmd |= (ISAC_CIXR_CAR8 << 2);
break;
case CMD_AR10:
NDBGL1(L1_I_CICO, "tx AR10 in state %s", ifpi_printstate(sc));
cmd |= (ISAC_CIXR_CAR10 << 2);
break;
case CMD_DIU:
NDBGL1(L1_I_CICO, "tx DIU in state %s", ifpi_printstate(sc));
cmd |= (ISAC_CIXR_CDIU << 2);
break;
}
ISAC_WRITE(I_CIXR, cmd);
}
/*---------------------------------------------------------------------------*
* L1 ISAC initialization
*---------------------------------------------------------------------------*/
int
ifpi_isac_init(struct l1_softc *sc)
{
ISAC_IMASK = 0xff; /* disable all irqs */
ISAC_WRITE(I_MASK, ISAC_IMASK);
if(sc->sc_bustyp != BUS_TYPE_IOM2)
{
NDBGL1(L1_I_SETUP, "configuring for IOM-1 mode");
/* ADF2: Select mode IOM-1 */
ISAC_WRITE(I_ADF2, 0x00);
/* SPCR: serial port control register:
* SPU - software power up = 0
* SAC - SIP port high Z
* SPM - timing mode 0
* TLP - test loop = 0
* C1C, C2C - B1 and B2 switched to/from SPa
*/
ISAC_WRITE(I_SPCR, ISAC_SPCR_C1C1|ISAC_SPCR_C2C1);
/* SQXR: S/Q channel xmit register:
* SQIE - S/Q IRQ enable = 0
* SQX1-4 - Fa bits = 1
*/
ISAC_WRITE(I_SQXR, ISAC_SQXR_SQX1|ISAC_SQXR_SQX2|ISAC_SQXR_SQX3|ISAC_SQXR_SQX4);
/* ADF1: additional feature reg 1:
* WTC - watchdog = 0
* TEM - test mode = 0
* PFS - pre-filter = 0
* CFS - IOM clock/frame always active
* FSC1/2 - polarity of 8kHz strobe
* ITF - interframe fill = idle
*/
ISAC_WRITE(I_ADF1, ISAC_ADF1_FC2); /* ADF1 */
/* STCR: sync transfer control reg:
* TSF - terminal secific functions = 0
* TBA - TIC bus address = 7
* STx/SCx = 0
*/
ISAC_WRITE(I_STCR, ISAC_STCR_TBA2|ISAC_STCR_TBA1|ISAC_STCR_TBA0);
/* MODE: Mode Register:
* MDSx - transparent mode 2
* TMD - timer mode = external
* RAC - Receiver enabled
* DIMx - digital i/f mode
*/
ISAC_WRITE(I_MODE, ISAC_MODE_MDS2|ISAC_MODE_MDS1|ISAC_MODE_RAC|ISAC_MODE_DIM0);
}
else
{
NDBGL1(L1_I_SETUP, "configuring for IOM-2 mode");
/* ADF2: Select mode IOM-2 */
ISAC_WRITE(I_ADF2, ISAC_ADF2_IMS);
/* SPCR: serial port control register:
* SPU - software power up = 0
* SPM - timing mode 0
* TLP - test loop = 0
* C1C, C2C - B1 + C1 and B2 + IC2 monitoring
*/
ISAC_WRITE(I_SPCR, 0x00);
/* SQXR: S/Q channel xmit register:
* IDC - IOM direction = 0 (master)
* CFS - Config Select = 0 (clock always active)
* CI1E - C/I channel 1 IRQ enable = 0
* SQIE - S/Q IRQ enable = 0
* SQX1-4 - Fa bits = 1
*/
ISAC_WRITE(I_SQXR, ISAC_SQXR_SQX1|ISAC_SQXR_SQX2|ISAC_SQXR_SQX3|ISAC_SQXR_SQX4);
/* ADF1: additional feature reg 1:
* WTC - watchdog = 0
* TEM - test mode = 0
* PFS - pre-filter = 0
* IOF - IOM i/f off = 0
* ITF - interframe fill = idle
*/
ISAC_WRITE(I_ADF1, 0x00);
/* STCR: sync transfer control reg:
* TSF - terminal secific functions = 0
* TBA - TIC bus address = 7
* STx/SCx = 0
*/
ISAC_WRITE(I_STCR, ISAC_STCR_TBA2|ISAC_STCR_TBA1|ISAC_STCR_TBA0);
/* MODE: Mode Register:
* MDSx - transparent mode 2
* TMD - timer mode = external
* RAC - Receiver enabled
* DIMx - digital i/f mode
*/
ISAC_WRITE(I_MODE, ISAC_MODE_MDS2|ISAC_MODE_MDS1|ISAC_MODE_RAC|ISAC_MODE_DIM0);
}
#ifdef NOTDEF
/*
* XXX a transmitter reset causes an ISAC tx IRQ which will not
* be serviced at attach time under some circumstances leaving
* the associated IRQ line on the ISA bus active. This prevents
* any further interrupts to be serviced because no low -> high
* transition can take place anymore. (-hm)
*/
/* command register:
* RRES - HDLC receiver reset
* XRES - transmitter reset
*/
ISAC_WRITE(I_CMDR, ISAC_CMDR_RRES|ISAC_CMDR_XRES);
ISACCMDRWRDELAY();
#endif
/* enabled interrupts:
* ===================
* RME - receive message end
* RPF - receive pool full
* XPR - transmit pool ready
* CISQ - CI or S/Q channel change
* EXI - extended interrupt
*/
ISAC_IMASK = ISAC_MASK_RSC | /* auto mode only */
ISAC_MASK_TIN | /* timer irq */
ISAC_MASK_SIN; /* sync xfer irq */
ISAC_WRITE(I_MASK, ISAC_IMASK);
return(0);
}
#endif /* NIFPI > 0 */

View File

@ -0,0 +1,248 @@
/*
* Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*---------------------------------------------------------------------------
*
* i4b_ifpi_l1.c - AVM Fritz PCI layer 1 handler
* ---------------------------------------------
*
* $Id: i4b_ifpi_l1.c,v 1.4 2000/06/02 16:14:36 hm Exp $
*
* $FreeBSD$
*
* last edit-date: [Fri Jun 2 14:54:30 2000]
*
*---------------------------------------------------------------------------*/
#include "ifpi.h"
#include "pci.h"
#if (NIFPI > 0) && (NPCI > 0)
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <machine/stdarg.h>
#include <machine/clock.h>
#include <net/if.h>
#include <machine/i4b_debug.h>
#include <machine/i4b_ioctl.h>
#include <machine/i4b_trace.h>
#include <i4b/layer1/isic/i4b_isic.h>
#include <i4b/layer1/isic/i4b_isac.h>
#include <i4b/layer1/isic/i4b_hscx.h>
#include <i4b/layer1/ifpi/i4b_ifpi_ext.h>
#include <i4b/layer1/i4b_l1.h>
#include <i4b/include/i4b_mbuf.h>
#include <i4b/include/i4b_global.h>
/*---------------------------------------------------------------------------*
*
* L2 -> L1: PH-DATA-REQUEST
* =========================
*
* parms:
* unit physical interface unit number
* m mbuf containing L2 frame to be sent out
* freeflag MBUF_FREE: free mbuf here after having sent
* it out
* MBUF_DONTFREE: mbuf is freed by Layer 2
* returns:
* ==0 fail, nothing sent out
* !=0 ok, frame sent out
*
*---------------------------------------------------------------------------*/
int
ifpi_ph_data_req(int unit, struct mbuf *m, int freeflag)
{
u_char cmd;
int s;
struct l1_softc *sc = ifpi_scp[unit];
#ifdef NOTDEF
NDBGL1(L1_PRIM, "PH-DATA-REQ, unit %d, freeflag=%d", unit, freeflag);
#endif
if(m == NULL) /* failsafe */
return (0);
s = SPLI4B();
if(sc->sc_I430state == ST_F3) /* layer 1 not running ? */
{
NDBGL1(L1_I_ERR, "still in state F3!");
ifpi_ph_activate_req(unit);
}
if(sc->sc_state & ISAC_TX_ACTIVE)
{
if(sc->sc_obuf2 == NULL)
{
sc->sc_obuf2 = m; /* save mbuf ptr */
if(freeflag)
sc->sc_freeflag2 = 1; /* IRQ must mfree */
else
sc->sc_freeflag2 = 0; /* IRQ must not mfree */
NDBGL1(L1_I_MSG, "using 2nd ISAC TX buffer, state = %s", ifpi_printstate(sc));
if(sc->sc_trace & TRACE_D_TX)
{
i4b_trace_hdr_t hdr;
hdr.unit = L0IFPIUNIT(unit);
hdr.type = TRC_CH_D;
hdr.dir = FROM_TE;
hdr.count = ++sc->sc_trace_dcount;
MICROTIME(hdr.time);
i4b_l1_trace_ind(&hdr, m->m_len, m->m_data);
}
splx(s);
return(1);
}
NDBGL1(L1_I_ERR, "No Space in TX FIFO, state = %s", ifpi_printstate(sc));
if(freeflag == MBUF_FREE)
i4b_Dfreembuf(m);
splx(s);
return (0);
}
if(sc->sc_trace & TRACE_D_TX)
{
i4b_trace_hdr_t hdr;
hdr.unit = L0IFPIUNIT(unit);
hdr.type = TRC_CH_D;
hdr.dir = FROM_TE;
hdr.count = ++sc->sc_trace_dcount;
MICROTIME(hdr.time);
i4b_l1_trace_ind(&hdr, m->m_len, m->m_data);
}
sc->sc_state |= ISAC_TX_ACTIVE; /* set transmitter busy flag */
NDBGL1(L1_I_MSG, "ISAC_TX_ACTIVE set");
sc->sc_freeflag = 0; /* IRQ must NOT mfree */
ISAC_WRFIFO(m->m_data, min(m->m_len, ISAC_FIFO_LEN)); /* output to TX fifo */
if(m->m_len > ISAC_FIFO_LEN) /* message > 32 bytes ? */
{
sc->sc_obuf = m; /* save mbuf ptr */
sc->sc_op = m->m_data + ISAC_FIFO_LEN; /* ptr for irq hdl */
sc->sc_ol = m->m_len - ISAC_FIFO_LEN; /* length for irq hdl */
if(freeflag)
sc->sc_freeflag = 1; /* IRQ must mfree */
cmd = ISAC_CMDR_XTF;
}
else
{
sc->sc_obuf = NULL;
sc->sc_op = NULL;
sc->sc_ol = 0;
if(freeflag)
i4b_Dfreembuf(m);
cmd = ISAC_CMDR_XTF | ISAC_CMDR_XME;
}
ISAC_WRITE(I_CMDR, cmd);
ISACCMDRWRDELAY();
splx(s);
return(1);
}
/*---------------------------------------------------------------------------*
*
* L2 -> L1: PH-ACTIVATE-REQUEST
* =============================
*
* parms:
* unit physical interface unit number
*
* returns:
* ==0
* !=0
*
*---------------------------------------------------------------------------*/
int
ifpi_ph_activate_req(int unit)
{
struct l1_softc *sc = ifpi_scp[unit];
NDBGL1(L1_PRIM, "PH-ACTIVATE-REQ, unit %d", unit);
ifpi_next_state(sc, EV_PHAR);
return(0);
}
/*---------------------------------------------------------------------------*
* command from the upper layers
*---------------------------------------------------------------------------*/
int
ifpi_mph_command_req(int unit, int command, void *parm)
{
struct l1_softc *sc = ifpi_scp[unit];
switch(command)
{
case CMR_DOPEN: /* daemon running */
NDBGL1(L1_PRIM, "unit %d, command = CMR_DOPEN", unit);
sc->sc_enabled = 1;
break;
case CMR_DCLOSE: /* daemon not running */
NDBGL1(L1_PRIM, "unit %d, command = CMR_DCLOSE", unit);
sc->sc_enabled = 0;
break;
case CMR_SETTRACE:
NDBGL1(L1_PRIM, "unit %d, command = CMR_SETTRACE, parm = %d", unit, (unsigned int)parm);
sc->sc_trace = (unsigned int)parm;
break;
default:
NDBGL1(L1_ERROR, "ERROR, unknown command = %d, unit = %d, parm = %d", command, unit, (unsigned int)parm);
break;
}
return(0);
}
#endif /* NIFPI > 0 */

View File

@ -0,0 +1,522 @@
/*
* Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*---------------------------------------------------------------------------
*
* i4b_ifpi_l1fsm.c - AVM Fritz PCI layer 1 I.430 state machine
* ------------------------------------------------------------
*
* $Id: i4b_ifpi_l1fsm.c,v 1.4 2000/05/29 15:41:41 hm Exp $
*
* $FreeBSD$
*
* last edit-date: [Mon May 29 15:23:15 2000]
*
*---------------------------------------------------------------------------*/
#include "ifpi.h"
#include "pci.h"
#if (NIFPI > 0) && (NPCI > 0)
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <machine/stdarg.h>
#include <machine/clock.h>
#include <net/if.h>
#include <machine/i4b_debug.h>
#include <machine/i4b_ioctl.h>
#include <machine/i4b_trace.h>
#include <i4b/layer1/isic/i4b_isic.h>
#include <i4b/layer1/isic/i4b_isac.h>
#include <i4b/layer1/isic/i4b_hscx.h>
#include <i4b/layer1/i4b_l1.h>
#include <i4b/include/i4b_global.h>
#include <i4b/include/i4b_mbuf.h>
#include <i4b/layer1/ifpi/i4b_ifpi_ext.h>
#if DO_I4B_DEBUG
static char *state_text[N_STATES] = {
"F3 Deactivated",
"F4 Awaiting Signal",
"F5 Identifying Input",
"F6 Synchronized",
"F7 Activated",
"F8 Lost Framing",
"Illegal State"
};
static char *event_text[N_EVENTS] = {
"EV_PHAR PH_ACT_REQ",
"EV_T3 Timer 3 expired",
"EV_INFO0 INFO0 received",
"EV_RSY Level Detected",
"EV_INFO2 INFO2 received",
"EV_INFO48 INFO4 received",
"EV_INFO410 INFO4 received",
"EV_DR Deactivate Req",
"EV_PU Power UP",
"EV_DIS Disconnected",
"EV_EI Error Ind",
"Illegal Event"
};
#endif
/* Function prototypes */
static void timer3_expired (struct l1_softc *sc);
static void T3_start (struct l1_softc *sc);
static void T3_stop (struct l1_softc *sc);
static void F_T3ex (struct l1_softc *sc);
static void timer4_expired (struct l1_softc *sc);
static void T4_start (struct l1_softc *sc);
static void T4_stop (struct l1_softc *sc);
static void F_AI8 (struct l1_softc *sc);
static void F_AI10 (struct l1_softc *sc);
static void F_I01 (struct l1_softc *sc);
static void F_I02 (struct l1_softc *sc);
static void F_I03 (struct l1_softc *sc);
static void F_I2 (struct l1_softc *sc);
static void F_ill (struct l1_softc *sc);
static void F_NULL (struct l1_softc *sc);
/*---------------------------------------------------------------------------*
* I.430 Timer T3 expire function
*---------------------------------------------------------------------------*/
static void
timer3_expired(struct l1_softc *sc)
{
if(sc->sc_I430T3)
{
NDBGL1(L1_T_ERR, "state = %s", ifpi_printstate(sc));
sc->sc_I430T3 = 0;
/* XXX try some recovery here XXX */
ifpi_recover(sc);
sc->sc_init_tries++; /* increment retry count */
/*XXX*/ if(sc->sc_init_tries > 4)
{
int s = SPLI4B();
sc->sc_init_tries = 0;
if(sc->sc_obuf2 != NULL)
{
i4b_Dfreembuf(sc->sc_obuf2);
sc->sc_obuf2 = NULL;
}
if(sc->sc_obuf != NULL)
{
i4b_Dfreembuf(sc->sc_obuf);
sc->sc_obuf = NULL;
sc->sc_freeflag = 0;
sc->sc_op = NULL;
sc->sc_ol = 0;
}
splx(s);
i4b_l1_mph_status_ind(L0IFPIUNIT(sc->sc_unit), STI_NOL1ACC, 0, NULL);
}
ifpi_next_state(sc, EV_T3);
}
else
{
NDBGL1(L1_T_ERR, "expired without starting it ....");
}
}
/*---------------------------------------------------------------------------*
* I.430 Timer T3 start
*---------------------------------------------------------------------------*/
static void
T3_start(struct l1_softc *sc)
{
NDBGL1(L1_T_MSG, "state = %s", ifpi_printstate(sc));
sc->sc_I430T3 = 1;
sc->sc_T3_callout = timeout((TIMEOUT_FUNC_T)timer3_expired,(struct l1_softc *)sc, 2*hz);
}
/*---------------------------------------------------------------------------*
* I.430 Timer T3 stop
*---------------------------------------------------------------------------*/
static void
T3_stop(struct l1_softc *sc)
{
NDBGL1(L1_T_MSG, "state = %s", ifpi_printstate(sc));
sc->sc_init_tries = 0; /* init connect retry count */
if(sc->sc_I430T3)
{
sc->sc_I430T3 = 0;
untimeout((TIMEOUT_FUNC_T)timer3_expired,(struct l1_softc *)sc, sc->sc_T3_callout);
}
}
/*---------------------------------------------------------------------------*
* I.430 Timer T3 expiry
*---------------------------------------------------------------------------*/
static void
F_T3ex(struct l1_softc *sc)
{
NDBGL1(L1_F_MSG, "FSM function F_T3ex executing");
if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S)
i4b_l1_ph_deactivate_ind(L0IFPIUNIT(sc->sc_unit));
}
/*---------------------------------------------------------------------------*
* Timer T4 expire function
*---------------------------------------------------------------------------*/
static void
timer4_expired(struct l1_softc *sc)
{
if(sc->sc_I430T4)
{
NDBGL1(L1_T_MSG, "state = %s", ifpi_printstate(sc));
sc->sc_I430T4 = 0;
i4b_l1_mph_status_ind(L0IFPIUNIT(sc->sc_unit), STI_PDEACT, 0, NULL);
}
else
{
NDBGL1(L1_T_ERR, "expired without starting it ....");
}
}
/*---------------------------------------------------------------------------*
* Timer T4 start
*---------------------------------------------------------------------------*/
static void
T4_start(struct l1_softc *sc)
{
NDBGL1(L1_T_MSG, "state = %s", ifpi_printstate(sc));
sc->sc_I430T4 = 1;
sc->sc_T4_callout = timeout((TIMEOUT_FUNC_T)timer4_expired,(struct l1_softc *)sc, hz);
}
/*---------------------------------------------------------------------------*
* Timer T4 stop
*---------------------------------------------------------------------------*/
static void
T4_stop(struct l1_softc *sc)
{
NDBGL1(L1_T_MSG, "state = %s", ifpi_printstate(sc));
if(sc->sc_I430T4)
{
sc->sc_I430T4 = 0;
untimeout((TIMEOUT_FUNC_T)timer4_expired,(struct l1_softc *)sc, sc->sc_T4_callout);
}
}
/*---------------------------------------------------------------------------*
* FSM function: received AI8
*---------------------------------------------------------------------------*/
static void
F_AI8(struct l1_softc *sc)
{
T4_stop(sc);
NDBGL1(L1_F_MSG, "FSM function F_AI8 executing");
if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S)
i4b_l1_ph_activate_ind(L0IFPIUNIT(sc->sc_unit));
T3_stop(sc);
if(sc->sc_trace & TRACE_I)
{
i4b_trace_hdr_t hdr;
char info = INFO4_8;
hdr.unit = L0IFPIUNIT(sc->sc_unit);
hdr.type = TRC_CH_I;
hdr.dir = FROM_NT;
hdr.count = 0;
MICROTIME(hdr.time);
i4b_l1_trace_ind(&hdr, 1, &info);
}
}
/*---------------------------------------------------------------------------*
* FSM function: received AI10
*---------------------------------------------------------------------------*/
static void
F_AI10(struct l1_softc *sc)
{
T4_stop(sc);
NDBGL1(L1_F_MSG, "FSM function F_AI10 executing");
if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S)
i4b_l1_ph_activate_ind(L0IFPIUNIT(sc->sc_unit));
T3_stop(sc);
if(sc->sc_trace & TRACE_I)
{
i4b_trace_hdr_t hdr;
char info = INFO4_10;
hdr.unit = L0IFPIUNIT(sc->sc_unit);
hdr.type = TRC_CH_I;
hdr.dir = FROM_NT;
hdr.count = 0;
MICROTIME(hdr.time);
i4b_l1_trace_ind(&hdr, 1, &info);
}
}
/*---------------------------------------------------------------------------*
* FSM function: received INFO 0 in states F3 .. F5
*---------------------------------------------------------------------------*/
static void
F_I01(struct l1_softc *sc)
{
NDBGL1(L1_F_MSG, "FSM function F_I01 executing");
if(sc->sc_trace & TRACE_I)
{
i4b_trace_hdr_t hdr;
char info = INFO0;
hdr.unit = L0IFPIUNIT(sc->sc_unit);
hdr.type = TRC_CH_I;
hdr.dir = FROM_NT;
hdr.count = 0;
MICROTIME(hdr.time);
i4b_l1_trace_ind(&hdr, 1, &info);
}
}
/*---------------------------------------------------------------------------*
* FSM function: received INFO 0 in state F6
*---------------------------------------------------------------------------*/
static void
F_I02(struct l1_softc *sc)
{
NDBGL1(L1_F_MSG, "FSM function F_I02 executing");
if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S)
i4b_l1_ph_deactivate_ind(L0IFPIUNIT(sc->sc_unit));
if(sc->sc_trace & TRACE_I)
{
i4b_trace_hdr_t hdr;
char info = INFO0;
hdr.unit = L0IFPIUNIT(sc->sc_unit);
hdr.type = TRC_CH_I;
hdr.dir = FROM_NT;
hdr.count = 0;
MICROTIME(hdr.time);
i4b_l1_trace_ind(&hdr, 1, &info);
}
}
/*---------------------------------------------------------------------------*
* FSM function: received INFO 0 in state F7 or F8
*---------------------------------------------------------------------------*/
static void
F_I03(struct l1_softc *sc)
{
NDBGL1(L1_F_MSG, "FSM function F_I03 executing");
if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S)
i4b_l1_ph_deactivate_ind(L0IFPIUNIT(sc->sc_unit));
T4_start(sc);
if(sc->sc_trace & TRACE_I)
{
i4b_trace_hdr_t hdr;
char info = INFO0;
hdr.unit = L0IFPIUNIT(sc->sc_unit);
hdr.type = TRC_CH_I;
hdr.dir = FROM_NT;
hdr.count = 0;
MICROTIME(hdr.time);
i4b_l1_trace_ind(&hdr, 1, &info);
}
}
/*---------------------------------------------------------------------------*
* FSM function: activate request
*---------------------------------------------------------------------------*/
static void
F_AR(struct l1_softc *sc)
{
NDBGL1(L1_F_MSG, "FSM function F_AR executing");
if(sc->sc_trace & TRACE_I)
{
i4b_trace_hdr_t hdr;
char info = INFO1_8;
hdr.unit = L0IFPIUNIT(sc->sc_unit);
hdr.type = TRC_CH_I;
hdr.dir = FROM_TE;
hdr.count = 0;
MICROTIME(hdr.time);
i4b_l1_trace_ind(&hdr, 1, &info);
}
ifpi_isac_l1_cmd(sc, CMD_AR8);
T3_start(sc);
}
/*---------------------------------------------------------------------------*
* FSM function: received INFO2
*---------------------------------------------------------------------------*/
static void
F_I2(struct l1_softc *sc)
{
NDBGL1(L1_F_MSG, "FSM function F_I2 executing");
if(sc->sc_trace & TRACE_I)
{
i4b_trace_hdr_t hdr;
char info = INFO2;
hdr.unit = L0IFPIUNIT(sc->sc_unit);
hdr.type = TRC_CH_I;
hdr.dir = FROM_NT;
hdr.count = 0;
MICROTIME(hdr.time);
i4b_l1_trace_ind(&hdr, 1, &info);
}
}
/*---------------------------------------------------------------------------*
* illegal state default action
*---------------------------------------------------------------------------*/
static void
F_ill(struct l1_softc *sc)
{
NDBGL1(L1_F_ERR, "FSM function F_ill executing");
}
/*---------------------------------------------------------------------------*
* No action
*---------------------------------------------------------------------------*/
static void
F_NULL(struct l1_softc *sc)
{
NDBGL1(L1_F_MSG, "FSM function F_NULL executing");
}
/*---------------------------------------------------------------------------*
* layer 1 state transition table
*---------------------------------------------------------------------------*/
struct ifpi_state_tab {
void (*func) (struct l1_softc *sc); /* function to execute */
int newstate; /* next state */
} ifpi_state_tab[N_EVENTS][N_STATES] = {
/* STATE: F3 F4 F5 F6 F7 F8 ILLEGAL STATE */
/* -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* EV_PHAR x*/ {{F_AR, ST_F4}, {F_NULL, ST_F4}, {F_NULL, ST_F5}, {F_NULL, ST_F6}, {F_ill, ST_ILL}, {F_NULL, ST_F8}, {F_ill, ST_ILL}},
/* EV_T3 x*/ {{F_NULL, ST_F3}, {F_T3ex, ST_F3}, {F_T3ex, ST_F3}, {F_T3ex, ST_F3}, {F_NULL, ST_F7}, {F_NULL, ST_F8}, {F_ill, ST_ILL}},
/* EV_INFO0 */ {{F_I01, ST_F3}, {F_I01, ST_F4}, {F_I01, ST_F5}, {F_I02, ST_F3}, {F_I03, ST_F3}, {F_I03, ST_F3}, {F_ill, ST_ILL}},
/* EV_RSY x*/ {{F_NULL, ST_F3}, {F_NULL, ST_F5}, {F_NULL, ST_F5}, {F_NULL, ST_F8}, {F_NULL, ST_F8}, {F_NULL, ST_F8}, {F_ill, ST_ILL}},
/* EV_INFO2 */ {{F_I2, ST_F6}, {F_I2, ST_F6}, {F_I2, ST_F6}, {F_I2, ST_F6}, {F_I2, ST_F6}, {F_I2, ST_F6}, {F_ill, ST_ILL}},
/* EV_INFO48*/ {{F_AI8, ST_F7}, {F_AI8, ST_F7}, {F_AI8, ST_F7}, {F_AI8, ST_F7}, {F_NULL, ST_F7}, {F_AI8, ST_F7}, {F_ill, ST_ILL}},
/* EV_INFO41*/ {{F_AI10, ST_F7}, {F_AI10, ST_F7}, {F_AI10, ST_F7}, {F_AI10, ST_F7}, {F_NULL, ST_F7}, {F_AI10, ST_F7}, {F_ill, ST_ILL}},
/* EV_DR */ {{F_NULL, ST_F3}, {F_NULL, ST_F4}, {F_NULL, ST_F5}, {F_NULL, ST_F6}, {F_NULL, ST_F7}, {F_NULL, ST_F8}, {F_ill, ST_ILL}},
/* EV_PU */ {{F_NULL, ST_F3}, {F_NULL, ST_F4}, {F_NULL, ST_F5}, {F_NULL, ST_F6}, {F_NULL, ST_F7}, {F_NULL, ST_F8}, {F_ill, ST_ILL}},
/* EV_DIS */ {{F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}},
/* EV_EI */ {{F_NULL, ST_F3}, {F_NULL, ST_F3}, {F_NULL, ST_F3}, {F_NULL, ST_F3}, {F_NULL, ST_F3}, {F_NULL, ST_F3}, {F_ill, ST_ILL}},
/* EV_ILL */ {{F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}}
};
/*---------------------------------------------------------------------------*
* event handler
*---------------------------------------------------------------------------*/
void
ifpi_next_state(struct l1_softc *sc, int event)
{
int currstate, newstate;
if(event >= N_EVENTS)
panic("i4b_l1fsm.c: event >= N_EVENTS\n");
currstate = sc->sc_I430state;
if(currstate >= N_STATES)
panic("i4b_l1fsm.c: currstate >= N_STATES\n");
newstate = ifpi_state_tab[event][currstate].newstate;
if(newstate >= N_STATES)
panic("i4b_l1fsm.c: newstate >= N_STATES\n");
NDBGL1(L1_F_MSG, "FSM event [%s]: [%s => %s]", event_text[event],
state_text[currstate],
state_text[newstate]);
(*ifpi_state_tab[event][currstate].func)(sc);
if(newstate == ST_ILL)
{
newstate = ST_F3;
NDBGL1(L1_F_ERR, "FSM Illegal State ERROR, oldstate = %s, newstate = %s, event = %s!",
state_text[currstate],
state_text[newstate],
event_text[event]);
}
sc->sc_I430state = newstate;
}
#if DO_I4B_DEBUG
/*---------------------------------------------------------------------------*
* return pointer to current state description
*---------------------------------------------------------------------------*/
char *
ifpi_printstate(struct l1_softc *sc)
{
return((char *) state_text[sc->sc_I430state]);
}
#endif
#endif /* NIFPI > 0 */

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999 Gary Jennejohn. All rights reserved.
* Copyright (c) 1999, 2000 Gary Jennejohn. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -29,26 +29,23 @@
* SUCH DAMAGE.
*
*---------------------------------------------------------------------------
* a lot of code was borrowed from i4b_bchan.c and i4b_hscx.c
*---------------------------------------------------------------------------
*
* Fritz!Card PCI specific routines for isic driver
* ------------------------------------------------
* i4b_ifpi_pci.c: AVM Fritz!Card PCI hardware 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 $
* $Id: i4b_ifpi_pci.c,v 1.4 2000/06/02 11:58:56 hm Exp $
*
* $FreeBSD$
*
* last edit-date: [Mon Dec 13 21:59:04 1999]
* last edit-date: [Fri Jun 2 13:58:02 2000]
*
*---------------------------------------------------------------------------*/
#include "isic.h"
#include "ifpi.h"
#include "opt_i4b.h"
#include "pci.h"
#if NISIC > 0 && defined(AVM_A1_PCI)
#if (NIFPI > 0) && (NPCI > 0)
#include <sys/param.h>
#include <sys/kernel.h>
@ -70,14 +67,17 @@
#include <machine/i4b_debug.h>
#include <machine/i4b_ioctl.h>
#include <machine/i4b_trace.h>
#include <i4b/include/i4b_global.h>
#include <i4b/include/i4b_l1l2.h>
#include <i4b/include/i4b_mbuf.h>
#include <i4b/layer1/i4b_l1.h>
#include <i4b/layer1/i4b_isac.h>
#include <i4b/layer1/i4b_hscx.h>
#include <i4b/layer1/isic/i4b_isic.h>
#include <i4b/layer1/isic/i4b_isac.h>
#include <i4b/layer1/isic/i4b_hscx.h>
#include <i4b/layer1/ifpi/i4b_ifpi_ext.h>
#define PCI_AVMA1_VID 0x1244
#define PCI_AVMA1_DID 0x0a00
@ -101,12 +101,14 @@ static void avma1pp_bchannel_stat(int, int, bchan_statistics_t *);
static void avma1pp_set_linktab(int, int, drvr_link_t *);
static isdn_link_t * avma1pp_ret_linktab(int, int);
static int avma1pp_pci_probe(device_t);
int isic_attach_avma1pp(device_t);
static int avma1pp_hscx_fifo(l1_bchan_state_t *, struct l1_softc *);
int avma1pp_attach_avma1pp(device_t);
static void ifpi_isac_intr(struct l1_softc *sc);
static device_method_t avma1pp_pci_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, avma1pp_pci_probe),
DEVMETHOD(device_attach, isic_attach_avma1pp),
DEVMETHOD(device_attach, avma1pp_attach_avma1pp),
DEVMETHOD(device_shutdown, avma1pp_disable),
/* bus interface */
@ -116,6 +118,7 @@ static device_method_t avma1pp_pci_methods[] = {
{ 0, 0 }
};
#if 0 /* use what's in l1_softc */
/* a minimal softc for the Fritz!Card PCI */
struct avma1pp_softc
{
@ -124,21 +127,33 @@ struct avma1pp_softc
void *avma1pp_intrhand;
struct resource *avma1pp_irq;
struct resource *avma1pp_res;
u_int8_t avma1pp_unit; /* interface number */
/* pointer to l1_sc */
/* pointer to ifpi_sc */
struct l1_softc *avma1pp_isc;
};
#endif
static driver_t avma1pp_pci_driver = {
"isic",
"ifpi",
avma1pp_pci_methods,
sizeof(struct avma1pp_softc)
sizeof(struct l1_softc)
};
static devclass_t avma1pp_pci_devclass;
DRIVER_MODULE(avma1pp, pci, avma1pp_pci_driver, avma1pp_pci_devclass, 0, 0);
/* jump table for multiplex routines */
struct i4b_l1mux_func avma1pp_l1mux_func = {
avma1pp_ret_linktab,
avma1pp_set_linktab,
ifpi_mph_command_req,
ifpi_ph_data_req,
ifpi_ph_activate_req,
};
struct l1_softc *ifpi_scp[IFPI_MAXUNIT];
/*---------------------------------------------------------------------------*
* AVM PCI Fritz!Card special registers
*---------------------------------------------------------------------------*/
@ -265,12 +280,13 @@ DRIVER_MODULE(avma1pp, pci, avma1pp_pci_driver, avma1pp_pci_devclass, 0, 0);
static void
avma1pp_read_fifo(struct l1_softc *sc, int what, void *buf, size_t size)
{
struct avma1pp_softc *asc = (struct avma1pp_softc *)sc->sc_ipacbase;
bus_space_handle_t bhandle = rman_get_bushandle(sc->sc_resources.io_base[0]);
bus_space_tag_t btag = rman_get_bustag(sc->sc_resources.io_base[0]);
switch (what) {
case ISIC_WHAT_ISAC:
bus_space_write_1(asc->avma1pp_btag, asc->avma1pp_bhandle, ADDR_REG_OFFSET, ISAC_FIFO);
bus_space_read_multi_1(asc->avma1pp_btag, asc->avma1pp_bhandle, ISAC_REG_OFFSET, buf, size);
bus_space_write_1(btag, bhandle, ADDR_REG_OFFSET, ISAC_FIFO);
bus_space_read_multi_1(btag, bhandle, ISAC_REG_OFFSET, buf, size);
break;
case ISIC_WHAT_HSCXA:
hscx_read_fifo(0, buf, size, sc);
@ -286,17 +302,17 @@ hscx_read_fifo(int chan, void *buf, size_t len, struct l1_softc *sc)
{
u_int32_t *ip;
size_t cnt;
struct avma1pp_softc *asc = (struct avma1pp_softc *)sc->sc_ipacbase;
bus_space_handle_t bhandle = rman_get_bushandle(sc->sc_resources.io_base[0]);
bus_space_tag_t btag = rman_get_bustag(sc->sc_resources.io_base[0]);
bus_space_write_4(asc->avma1pp_btag, asc->avma1pp_bhandle, ADDR_REG_OFFSET, chan);
bus_space_write_4(btag, bhandle, ADDR_REG_OFFSET, chan);
ip = (u_int32_t *)buf;
cnt = 0;
/* what if len isn't a multiple of sizeof(int) and buf is */
/* too small ???? */
while (cnt < len)
{
*ip++ = bus_space_read_4(asc->avma1pp_btag, asc->avma1pp_bhandle, ISAC_REG_OFFSET);
*ip++ = bus_space_read_4(btag, bhandle, ISAC_REG_OFFSET);
cnt += 4;
}
}
@ -307,12 +323,13 @@ hscx_read_fifo(int chan, void *buf, size_t len, struct l1_softc *sc)
static void
avma1pp_write_fifo(struct l1_softc *sc, int what, void *buf, size_t size)
{
struct avma1pp_softc *asc = (struct avma1pp_softc *)sc->sc_ipacbase;
bus_space_handle_t bhandle = rman_get_bushandle(sc->sc_resources.io_base[0]);
bus_space_tag_t btag = rman_get_bustag(sc->sc_resources.io_base[0]);
switch (what) {
case ISIC_WHAT_ISAC:
bus_space_write_1(asc->avma1pp_btag, asc->avma1pp_bhandle, ADDR_REG_OFFSET, ISAC_FIFO);
bus_space_write_multi_1(asc->avma1pp_btag, asc->avma1pp_bhandle, ISAC_REG_OFFSET, (u_int8_t*)buf, size);
bus_space_write_1(btag, bhandle, ADDR_REG_OFFSET, ISAC_FIFO);
bus_space_write_multi_1(btag, bhandle, ISAC_REG_OFFSET, (u_int8_t*)buf, size);
break;
case ISIC_WHAT_HSCXA:
hscx_write_fifo(0, buf, size, sc);
@ -329,7 +346,8 @@ hscx_write_fifo(int chan, void *buf, size_t len, struct l1_softc *sc)
u_int32_t *ip;
size_t cnt;
l1_bchan_state_t *Bchan = &sc->sc_chan[chan];
struct avma1pp_softc *asc = (struct avma1pp_softc *)sc->sc_ipacbase;
bus_space_handle_t bhandle = rman_get_bushandle(sc->sc_resources.io_base[0]);
bus_space_tag_t btag = rman_get_bustag(sc->sc_resources.io_base[0]);
sc->avma1pp_cmd &= ~HSCX_CMD_XME;
@ -350,7 +368,7 @@ hscx_write_fifo(int chan, void *buf, size_t len, struct l1_softc *sc)
cnt = 0;
while (cnt < len)
{
bus_space_write_4(asc->avma1pp_btag, asc->avma1pp_bhandle, ISAC_REG_OFFSET, *ip);
bus_space_write_4(btag, bhandle, ISAC_REG_OFFSET, *ip);
ip++;
cnt += 4;
}
@ -364,7 +382,8 @@ static void
avma1pp_write_reg(struct l1_softc *sc, int what, bus_size_t offs, u_int8_t data)
{
u_char reg_bank;
struct avma1pp_softc *asc = (struct avma1pp_softc *)sc->sc_ipacbase;
bus_space_handle_t bhandle = rman_get_bushandle(sc->sc_resources.io_base[0]);
bus_space_tag_t btag = rman_get_bustag(sc->sc_resources.io_base[0]);
switch (what) {
case ISIC_WHAT_ISAC:
@ -373,8 +392,8 @@ avma1pp_write_reg(struct l1_softc *sc, int what, bus_size_t offs, u_int8_t data)
printf("write_reg bank %d off %ld.. ", (int)reg_bank, (long)offs);
#endif
/* set the register bank */
bus_space_write_1(asc->avma1pp_btag, asc->avma1pp_bhandle, ADDR_REG_OFFSET, reg_bank);
bus_space_write_1(asc->avma1pp_btag, asc->avma1pp_bhandle, ISAC_REG_OFFSET + (offs & ISAC_REGSET_MASK), data);
bus_space_write_1(btag, bhandle, ADDR_REG_OFFSET, reg_bank);
bus_space_write_1(btag, bhandle, ISAC_REG_OFFSET + (offs & ISAC_REGSET_MASK), data);
break;
case ISIC_WHAT_HSCXA:
hscx_write_reg(0, offs, data, sc);
@ -388,14 +407,12 @@ avma1pp_write_reg(struct l1_softc *sc, int what, bus_size_t offs, u_int8_t data)
static void
hscx_write_reg(int chan, u_int off, u_int val, struct l1_softc *sc)
{
struct avma1pp_softc *asc = (struct avma1pp_softc *)sc->sc_ipacbase;
bus_space_handle_t bhandle = rman_get_bushandle(sc->sc_resources.io_base[0]);
bus_space_tag_t btag = rman_get_bustag(sc->sc_resources.io_base[0]);
/* HACK */
if (off == H_MASK)
return;
/* point at the correct channel */
bus_space_write_4(asc->avma1pp_btag, asc->avma1pp_bhandle, ADDR_REG_OFFSET, chan);
bus_space_write_4(asc->avma1pp_btag, asc->avma1pp_bhandle, ISAC_REG_OFFSET + off, val);
bus_space_write_4(btag, bhandle, ADDR_REG_OFFSET, chan);
bus_space_write_4(btag, bhandle, ISAC_REG_OFFSET + off, val);
}
/*---------------------------------------------------------------------------*
@ -405,7 +422,8 @@ static u_int8_t
avma1pp_read_reg(struct l1_softc *sc, int what, bus_size_t offs)
{
u_char reg_bank;
struct avma1pp_softc *asc = (struct avma1pp_softc *)sc->sc_ipacbase;
bus_space_handle_t bhandle = rman_get_bushandle(sc->sc_resources.io_base[0]);
bus_space_tag_t btag = rman_get_bustag(sc->sc_resources.io_base[0]);
switch (what) {
case ISIC_WHAT_ISAC:
@ -414,8 +432,8 @@ avma1pp_read_reg(struct l1_softc *sc, int what, bus_size_t offs)
printf("read_reg bank %d off %ld.. ", (int)reg_bank, (long)offs);
#endif
/* set the register bank */
bus_space_write_1(asc->avma1pp_btag, asc->avma1pp_bhandle, ADDR_REG_OFFSET, reg_bank);
return(bus_space_read_1(asc->avma1pp_btag, asc->avma1pp_bhandle, ISAC_REG_OFFSET +
bus_space_write_1(btag, bhandle, ADDR_REG_OFFSET, reg_bank);
return(bus_space_read_1(btag, bhandle, ISAC_REG_OFFSET +
(offs & ISAC_REGSET_MASK)));
case ISIC_WHAT_HSCXA:
return hscx_read_reg(0, offs, sc);
@ -438,14 +456,12 @@ hscx_read_reg(int chan, u_int off, struct l1_softc *sc)
static u_int
hscx_read_reg_int(int chan, u_int off, struct l1_softc *sc)
{
struct avma1pp_softc *asc = (struct avma1pp_softc *)sc->sc_ipacbase;
bus_space_handle_t bhandle = rman_get_bushandle(sc->sc_resources.io_base[0]);
bus_space_tag_t btag = rman_get_bustag(sc->sc_resources.io_base[0]);
/* HACK */
if (off == H_ISTA)
return(0);
/* point at the correct channel */
bus_space_write_4(asc->avma1pp_btag, asc->avma1pp_bhandle, ADDR_REG_OFFSET, chan);
return(bus_space_read_4(asc->avma1pp_btag, asc->avma1pp_bhandle, ISAC_REG_OFFSET + off));
bus_space_write_4(btag, bhandle, ADDR_REG_OFFSET, chan);
return(bus_space_read_4(btag, bhandle, ISAC_REG_OFFSET + off));
}
/*---------------------------------------------------------------------------*
@ -469,29 +485,31 @@ avma1pp_pci_probe(dev)
}
/*---------------------------------------------------------------------------*
* isic_attach_avma1pp - attach Fritz!Card PCI
* avma1pp_attach_avma1pp - attach Fritz!Card PCI
*---------------------------------------------------------------------------*/
int
isic_attach_avma1pp(device_t dev)
avma1pp_attach_avma1pp(device_t dev)
{
struct l1_softc *sc;
u_int v;
/* start of new-bus stuff */
struct avma1pp_softc *asc;
int unit, error = 0, rid;
int unit, error = 0;
int s;
u_int16_t did, vid;
void *ih = 0;
bus_space_handle_t bhandle;
bus_space_tag_t btag;
s = splimp();
vid = pci_get_vendor(dev);
did = pci_get_device(dev);
asc = device_get_softc(dev);
sc = device_get_softc(dev);
unit = device_get_unit(dev);
bzero(asc, sizeof(struct avma1pp_softc));
bzero(sc, sizeof(struct l1_softc));
if(unit > ISIC_MAXUNIT) {
printf("avma1pp%d: Error, unit > ISIC_MAXUNIT!\n", unit);
/* probably not really required */
if(unit > IFPI_MAXUNIT) {
printf("avma1pp%d: Error, unit > IFPI_MAXUNIT!\n", unit);
splx(s);
return(ENXIO);
}
@ -501,54 +519,49 @@ isic_attach_avma1pp(device_t dev)
goto fail;
}
asc->avma1pp_unit = unit;
ifpi_scp[unit] = sc;
rid = PCIR_MAPS+4;
asc->avma1pp_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
sc->sc_resources.io_rid[0] = PCIR_MAPS+4;
sc->sc_resources.io_base[0] = bus_alloc_resource(dev, SYS_RES_IOPORT,
&sc->sc_resources.io_rid[0],
0, ~0, 1, RF_ACTIVE);
if (asc->avma1pp_res == NULL) {
if (sc->sc_resources.io_base[0] == NULL) {
printf("avma1pp%d: couldn't map IO port\n", unit);
error = ENXIO;
goto fail;
}
asc->avma1pp_btag = rman_get_bustag(asc->avma1pp_res);
asc->avma1pp_bhandle = rman_get_bushandle(asc->avma1pp_res);
bhandle = rman_get_bushandle(sc->sc_resources.io_base[0]);
btag = rman_get_bustag(sc->sc_resources.io_base[0]);
/* Allocate interrupt */
rid = 0;
asc->avma1pp_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
RF_SHAREABLE | RF_ACTIVE);
sc->sc_resources.irq_rid = 0;
sc->sc_resources.irq = bus_alloc_resource(dev, SYS_RES_IRQ,
&sc->sc_resources.irq_rid, 0, ~0, 1, RF_SHAREABLE | RF_ACTIVE);
if (asc->avma1pp_irq == NULL) {
bus_release_resource(dev, SYS_RES_IOPORT, PCIR_MAPS+4, asc->avma1pp_res);
if (sc->sc_resources.irq == NULL) {
bus_release_resource(dev, SYS_RES_IOPORT, PCIR_MAPS+4, sc->sc_resources.io_base[0]);
printf("avma1pp%d: couldn't map interrupt\n", unit);
error = ENXIO;
goto fail;
}
error = bus_setup_intr(dev, asc->avma1pp_irq, INTR_TYPE_NET, avma1pp_intr, asc, &asc->avma1pp_intrhand);
error = bus_setup_intr(dev, sc->sc_resources.irq, INTR_TYPE_NET, avma1pp_intr, sc, &ih);
if (error) {
bus_release_resource(dev, SYS_RES_IRQ, 0, asc->avma1pp_res);
bus_release_resource(dev, SYS_RES_IOPORT, PCIR_MAPS+4, asc->avma1pp_res);
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_resources.irq);
bus_release_resource(dev, SYS_RES_IOPORT, PCIR_MAPS+4, sc->sc_resources.io_base[0]);
printf("avma1pp%d: couldn't set up irq\n", unit);
goto fail;
}
sc = asc->avma1pp_isc = &l1_sc[unit];
sc->sc_unit = unit;
/* mis-use sc_ipacbase to point at avma1pp_softc */
IPAC_BASE = (caddr_t)asc;
/* end of new-bus stuff */
/* the ISAC lives at offset 0x10, but we can't use that. */
/* instead, put the unit number into the lower byte - HACK */
ISAC_BASE = (caddr_t)ISIC_WHAT_ISAC;
/* this thing doesn't have an HSCX, so fake the base addresses */
HSCX_A_BASE = (caddr_t)ISIC_WHAT_HSCXA;
HSCX_B_BASE = (caddr_t)ISIC_WHAT_HSCXB;
@ -614,28 +627,28 @@ isic_attach_avma1pp(device_t dev)
printf("avma1pp_attach: 1 HSCX_STAT %x\n", v);
#endif
bus_space_write_1(asc->avma1pp_btag, asc->avma1pp_bhandle, STAT0_OFFSET, ASL_RESET_ALL|ASL_TIMERDISABLE);
bus_space_write_1(btag, bhandle, STAT0_OFFSET, ASL_RESET_ALL|ASL_TIMERDISABLE);
DELAY(SEC_DELAY/100); /* 10 ms */
bus_space_write_1(asc->avma1pp_btag, asc->avma1pp_bhandle, STAT0_OFFSET, ASL_TIMERRESET|ASL_ENABLE_INT|ASL_TIMERDISABLE);
bus_space_write_1(btag, bhandle, STAT0_OFFSET, ASL_TIMERRESET|ASL_ENABLE_INT|ASL_TIMERDISABLE);
DELAY(SEC_DELAY/100); /* 10 ms */
#ifdef AVMA1PCI_DEBUG
bus_space_write_1(asc->avma1pp_btag, asc->avma1pp_bhandle, STAT1_OFFSET, ASL1_ENABLE_IOM|sc->sc_irq);
bus_space_write_1(btag, bhandle, STAT1_OFFSET, ASL1_ENABLE_IOM|sc->sc_irq);
DELAY(SEC_DELAY/100); /* 10 ms */
v = bus_space_read_1(asc->avma1pp_btag, asc->avma1pp_bhandle, STAT1_OFFSET);
v = bus_space_read_1(btag, bhandle, STAT1_OFFSET);
printf("after reset: S1 %#x\n", v);
v = bus_space_read_4(asc->avma1pp_btag, asc->avma1pp_bhandle, 0);
printf("isic_attach_avma1pp: v %#x\n", v);
v = bus_space_read_4(btag, bhandle, 0);
printf("avma1pp_attach_avma1pp: v %#x\n", v);
#endif
/* from here to the end would normally be done in isic_pciattach */
printf("isic%d: ISAC %s (IOM-%c)\n", unit,
printf("ifpi%d: ISAC %s (IOM-%c)\n", unit,
"2085 Version A1/A2 or 2086/2186 Version 1.1",
sc->sc_bustyp == BUS_TYPE_IOM1 ? '1' : '2');
/* init the ISAC */
isic_isac_init(sc);
ifpi_isac_init(sc);
/* init the "HSCX" */
avma1pp_bchannel_setup(sc->sc_unit, HSCX_CH_A, BPROT_NONE, 0);
@ -663,14 +676,6 @@ isic_attach_avma1pp(device_t dev)
sc->sc_obuf2 = NULL;
sc->sc_freeflag2 = 0;
#ifdef USENEWFIELDS
/* new fields */
sc->recover = isic_recover;
sc->next_state = isic_next_state;
sc->ph_data_req = isic_isac_ph_data_req;
sc->l1_cmd = isic_isac_l1_cmd;
#endif
#if defined(__FreeBSD__) && __FreeBSD__ >=3
callout_handle_init(&sc->sc_T3_callout);
callout_handle_init(&sc->sc_T4_callout);
@ -678,7 +683,7 @@ isic_attach_avma1pp(device_t dev)
/* init higher protocol layers */
MPH_Status_Ind(sc->sc_unit, STI_ATTACH, sc->sc_cardtyp);
i4b_l1_mph_status_ind(L0IFPIUNIT(sc->sc_unit), STI_ATTACH, sc->sc_cardtyp, &avma1pp_l1mux_func);
fail:
splx(s);
@ -695,12 +700,12 @@ avma1pp_hscx_intr(int h_chan, u_int stat, struct l1_softc *sc)
int activity = -1;
u_int param = 0;
DBGL1(L1_H_IRQ, "avma1pp_hscx_intr", ("%#x\n", stat));
NDBGL1(L1_H_IRQ, "%#x", stat);
if((stat & HSCX_INT_XDU) && (chan->bprot != BPROT_NONE))/* xmit data underrun */
{
chan->stat_XDU++;
DBGL1(L1_H_XFRERR, "avma1pp_hscx_intr", ("xmit data underrun\n"));
NDBGL1(L1_H_XFRERR, "xmit data underrun");
/* abort the transmission */
sc->avma1pp_txl = 0;
sc->avma1pp_cmd |= HSCX_CMD_XRS;
@ -741,7 +746,7 @@ avma1pp_hscx_intr(int h_chan, u_int stat, struct l1_softc *sc)
if(stat & HSCX_STAT_RDO)
{
chan->stat_RDO++;
DBGL1(L1_H_XFRERR, "avma1pp_hscx_intr", ("receive data overflow\n"));
NDBGL1(L1_H_XFRERR, "receive data overflow");
error++;
}
@ -760,7 +765,7 @@ avma1pp_hscx_intr(int h_chan, u_int stat, struct l1_softc *sc)
*/
if (chan->state == HSCX_IDLE)
{
DBGL1(L1_H_XFRERR, "avma1pp_hscx_intr", ("toss data from %d\n", h_chan));
NDBGL1(L1_H_XFRERR, "toss data from %d", h_chan);
error++;
}
@ -801,19 +806,19 @@ avma1pp_hscx_intr(int h_chan, u_int stat, struct l1_softc *sc)
if(sc->sc_trace & TRACE_B_RX)
{
i4b_trace_hdr_t hdr;
hdr.unit = sc->sc_unit;
hdr.unit = L0IFPIUNIT(sc->sc_unit);
hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2);
hdr.dir = FROM_NT;
hdr.count = ++sc->sc_trace_bcount;
MICROTIME(hdr.time);
MPH_Trace_Ind(&hdr, chan->in_mbuf->m_len, chan->in_mbuf->m_data);
i4b_l1_trace_ind(&hdr, chan->in_mbuf->m_len, chan->in_mbuf->m_data);
}
if (stat & HSCX_STAT_RME)
{
if((stat & HSCX_STAT_CRCVFRRAB) == HSCX_STAT_CRCVFR)
{
(*chan->drvr_linktab->bch_rx_data_ready)(chan->drvr_linktab->unit);
(*chan->isic_drvr_linktab->bch_rx_data_ready)(chan->isic_drvr_linktab->unit);
activity = ACT_RX;
/* mark buffer ptr as unused */
@ -825,7 +830,7 @@ avma1pp_hscx_intr(int h_chan, u_int stat, struct l1_softc *sc)
else
{
chan->stat_CRC++;
DBGL1(L1_H_XFRERR, "avma1pp_hscx_intr", ("CRC/RAB\n"));
NDBGL1(L1_H_XFRERR, "CRC/RAB");
if (chan->in_mbuf != NULL)
{
i4b_Bfreembuf(chan->in_mbuf);
@ -848,15 +853,15 @@ avma1pp_hscx_intr(int h_chan, u_int stat, struct l1_softc *sc)
if(sc->sc_trace & TRACE_B_RX)
{
i4b_trace_hdr_t hdr;
hdr.unit = sc->sc_unit;
hdr.unit = L0IFPIUNIT(sc->sc_unit);
hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2);
hdr.dir = FROM_NT;
hdr.count = ++sc->sc_trace_bcount;
MICROTIME(hdr.time);
MPH_Trace_Ind(&hdr, chan->in_mbuf->m_len, chan->in_mbuf->m_data);
i4b_l1_trace_ind(&hdr, chan->in_mbuf->m_len, chan->in_mbuf->m_data);
}
if(!(isic_hscx_silence(chan->in_mbuf->m_data, chan->in_mbuf->m_len)))
if(!(i4b_l1_bchan_tel_silence(chan->in_mbuf->m_data, chan->in_mbuf->m_len)))
activity = ACT_RX;
/* move rx'd data to rx queue */
@ -871,7 +876,7 @@ avma1pp_hscx_intr(int h_chan, u_int stat, struct l1_softc *sc)
}
/* signal upper layer that data are available */
(*chan->drvr_linktab->bch_rx_data_ready)(chan->drvr_linktab->unit);
(*chan->isic_drvr_linktab->bch_rx_data_ready)(chan->isic_drvr_linktab->unit);
/* alloc new buffer */
@ -892,7 +897,7 @@ avma1pp_hscx_intr(int h_chan, u_int stat, struct l1_softc *sc)
}
else
{
DBGL1(L1_H_XFRERR, "avma1pp_hscx_intr", ("RAWHDLC rx buffer overflow in RPF, in_len=%d\n", chan->in_len));
NDBGL1(L1_H_XFRERR, "RAWHDLC rx buffer overflow in RPF, in_len=%d", chan->in_len);
chan->in_cbptr = chan->in_mbuf->m_data;
chan->in_len = 0;
}
@ -928,7 +933,7 @@ avma1pp_hscx_intr(int h_chan, u_int stat, struct l1_softc *sc)
* a look at isic_bchannel_start() in i4b_bchan.c !
*/
DBGL1(L1_H_IRQ, "avma1pp_hscx_intr", ("unit %d, chan %d - XPR, Tx Fifo Empty!\n", sc->sc_unit, h_chan));
NDBGL1(L1_H_IRQ, "unit %d, chan %d - XPR, Tx Fifo Empty!", sc->sc_unit, h_chan);
if(chan->out_mbuf_cur == NULL) /* last frame is transmitted */
{
@ -937,7 +942,7 @@ avma1pp_hscx_intr(int h_chan, u_int stat, struct l1_softc *sc)
if(chan->out_mbuf_head == NULL)
{
chan->state &= ~HSCX_TX_ACTIVE;
(*chan->drvr_linktab->bch_tx_queue_empty)(chan->drvr_linktab->unit);
(*chan->isic_drvr_linktab->bch_tx_queue_empty)(chan->isic_drvr_linktab->unit);
}
else
{
@ -949,17 +954,17 @@ avma1pp_hscx_intr(int h_chan, u_int stat, struct l1_softc *sc)
if(sc->sc_trace & TRACE_B_TX)
{
i4b_trace_hdr_t hdr;
hdr.unit = sc->sc_unit;
hdr.unit = L0IFPIUNIT(sc->sc_unit);
hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2);
hdr.dir = FROM_TE;
hdr.count = ++sc->sc_trace_bcount;
MICROTIME(hdr.time);
MPH_Trace_Ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data);
i4b_l1_trace_ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data);
}
if(chan->bprot == BPROT_NONE)
{
if(!(isic_hscx_silence(chan->out_mbuf_cur->m_data, chan->out_mbuf_cur->m_len)))
if(!(i4b_l1_bchan_tel_silence(chan->out_mbuf_cur->m_data, chan->out_mbuf_cur->m_len)))
activity = ACT_TX;
}
else
@ -969,13 +974,13 @@ avma1pp_hscx_intr(int h_chan, u_int stat, struct l1_softc *sc)
}
}
isic_hscx_fifo(chan, sc);
avma1pp_hscx_fifo(chan, sc);
}
/* call timeout handling routine */
if(activity == ACT_RX || activity == ACT_TX)
(*chan->drvr_linktab->bch_activity)(chan->drvr_linktab->unit, activity);
(*chan->isic_drvr_linktab->bch_activity)(chan->isic_drvr_linktab->unit, activity);
}
/*
@ -999,39 +1004,42 @@ avma1pp_hscx_int_handler(struct l1_softc *sc)
static void
avma1pp_disable(device_t dev)
{
struct avma1pp_softc *asc = device_get_softc(dev);
struct l1_softc *sc = device_get_softc(dev);
bus_space_handle_t bhandle = rman_get_bushandle(sc->sc_resources.io_base[0]);
bus_space_tag_t btag = rman_get_bustag(sc->sc_resources.io_base[0]);
bus_space_write_1(asc->avma1pp_btag, asc->avma1pp_bhandle, STAT0_OFFSET, ASL_RESET_ALL|ASL_TIMERDISABLE);
bus_space_write_1(btag, bhandle, STAT0_OFFSET, ASL_RESET_ALL|ASL_TIMERDISABLE);
}
static void
avma1pp_intr(void *xsc)
{
#define ISICINTR(sc) isicintr(sc)
u_char stat;
struct avma1pp_softc *asc;
struct l1_softc *sc;
bus_space_handle_t bhandle;
bus_space_tag_t btag;
asc = xsc;
sc = asc->avma1pp_isc;
sc = xsc;
bhandle = rman_get_bushandle(sc->sc_resources.io_base[0]);
btag = rman_get_bustag(sc->sc_resources.io_base[0]);
stat = bus_space_read_1(asc->avma1pp_btag, asc->avma1pp_bhandle, STAT0_OFFSET);
DBGL1(L1_H_IRQ, "avma1pp_intr", ("stat %x\n", stat));
stat = bus_space_read_1(btag, bhandle, STAT0_OFFSET);
NDBGL1(L1_H_IRQ, "stat %x", stat);
/* was there an interrupt from this card ? */
if ((stat & ASL_IRQ_Pending) == ASL_IRQ_Pending)
return; /* no */
/* interrupts are low active */
if (!(stat & ASL_IRQ_TIMER))
DBGL1(L1_H_IRQ, "avma1pp_intr", ("timer interrupt ???\n"));
NDBGL1(L1_H_IRQ, "timer interrupt ???");
if (!(stat & ASL_IRQ_HSCX))
{
DBGL1(L1_H_IRQ, "avma1pp_intr", ("HSCX\n"));
NDBGL1(L1_H_IRQ, "HSCX");
avma1pp_hscx_int_handler(sc);
}
if (!(stat & ASL_IRQ_ISAC))
{
DBGL1(L1_H_IRQ, "avma1pp_intr", ("ISAC\n"));
ISICINTR(sc);
NDBGL1(L1_H_IRQ, "ISAC");
ifpi_isac_intr(sc);
}
}
@ -1041,8 +1049,8 @@ avma1pp_hscx_init(struct l1_softc *sc, int h_chan, int activate)
l1_bchan_state_t *chan = &sc->sc_chan[h_chan];
u_int param = 0;
DBGL1(L1_BCHAN, "avma1pp_hscx_init", ("unit=%d, channel=%d, %s\n",
sc->sc_unit, h_chan, activate ? "activate" : "deactivate"));
NDBGL1(L1_BCHAN, "unit=%d, channel=%d, %s",
sc->sc_unit, h_chan, activate ? "activate" : "deactivate");
if (activate == 0)
{
@ -1060,7 +1068,7 @@ avma1pp_hscx_init(struct l1_softc *sc, int h_chan, int activate)
}
if(chan->bprot == BPROT_RHDLC)
{
DBGL1(L1_BCHAN, "avma1pp_hscx_init", ("BPROT_RHDLC\n"));
NDBGL1(L1_BCHAN, "BPROT_RHDLC");
/* HDLC Frames, transparent mode 0 */
sc->avma1pp_cmd = HSCX_CMD_XRS|HSCX_CMD_RRS;
@ -1074,7 +1082,7 @@ avma1pp_hscx_init(struct l1_softc *sc, int h_chan, int activate)
}
else
{
DBGL1(L1_BCHAN, "avma1pp_hscx_init", ("BPROT_NONE??\n"));
NDBGL1(L1_BCHAN, "BPROT_NONE??");
/* Raw Telephony, extended transparent mode 1 */
sc->avma1pp_cmd = HSCX_CMD_XRS|HSCX_CMD_RRS;
@ -1092,7 +1100,7 @@ static void
avma1pp_bchannel_setup(int unit, int h_chan, int bprot, int activate)
{
#ifdef __FreeBSD__
struct l1_softc *sc = &l1_sc[unit];
struct l1_softc *sc = ifpi_scp[unit];
#else
struct l1_softc *sc = isic_find_sc(unit);
#endif
@ -1107,8 +1115,8 @@ avma1pp_bchannel_setup(int unit, int h_chan, int bprot, int activate)
avma1pp_hscx_init(sc, h_chan, activate);
}
DBGL1(L1_BCHAN, "avma1pp_bchannel_setup", ("unit=%d, channel=%d, %s\n",
sc->sc_unit, h_chan, activate ? "activate" : "deactivate"));
NDBGL1(L1_BCHAN, "unit=%d, channel=%d, %s",
sc->sc_unit, h_chan, activate ? "activate" : "deactivate");
/* general part */
@ -1160,7 +1168,7 @@ static void
avma1pp_bchannel_start(int unit, int h_chan)
{
#ifdef __FreeBSD__
struct l1_softc *sc = &l1_sc[unit];
struct l1_softc *sc = ifpi_scp[unit];
#else
struct l1_softc *sc = isic_find_sc(unit);
#endif
@ -1195,7 +1203,7 @@ avma1pp_bchannel_start(int unit, int h_chan)
if(chan->bprot == BPROT_NONE)
{
if(!(isic_hscx_silence(chan->out_mbuf_cur->m_data, chan->out_mbuf_cur->m_len)))
if(!(i4b_l1_bchan_tel_silence(chan->out_mbuf_cur->m_data, chan->out_mbuf_cur->m_len)))
activity = ACT_TX;
}
else
@ -1208,20 +1216,20 @@ avma1pp_bchannel_start(int unit, int h_chan)
if(sc->sc_trace & TRACE_B_TX) /* if trace, send mbuf to trace dev */
{
i4b_trace_hdr_t hdr;
hdr.unit = unit;
hdr.unit = L0IFPIUNIT(sc->sc_unit);
hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2);
hdr.dir = FROM_TE;
hdr.count = ++sc->sc_trace_bcount;
MICROTIME(hdr.time);
MPH_Trace_Ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data);
i4b_l1_trace_ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data);
}
isic_hscx_fifo(chan, sc);
avma1pp_hscx_fifo(chan, sc);
/* call timeout handling routine */
if(activity == ACT_RX || activity == ACT_TX)
(*chan->drvr_linktab->bch_activity)(chan->drvr_linktab->unit, activity);
(*chan->isic_drvr_linktab->bch_activity)(chan->isic_drvr_linktab->unit, activity);
splx(s);
}
@ -1233,13 +1241,13 @@ static isdn_link_t *
avma1pp_ret_linktab(int unit, int channel)
{
#ifdef __FreeBSD__
struct l1_softc *sc = &l1_sc[unit];
struct l1_softc *sc = ifpi_scp[unit];
#else
struct l1_softc *sc = isic_find_sc(unit);
#endif
l1_bchan_state_t *chan = &sc->sc_chan[channel];
return(&chan->isdn_linktab);
return(&chan->isic_isdn_linktab);
}
/*---------------------------------------------------------------------------*
@ -1249,13 +1257,13 @@ static void
avma1pp_set_linktab(int unit, int channel, drvr_link_t *dlt)
{
#ifdef __FreeBSD__
struct l1_softc *sc = &l1_sc[unit];
struct l1_softc *sc = ifpi_scp[unit];
#else
struct l1_softc *sc = isic_find_sc(unit);
#endif
l1_bchan_state_t *chan = &sc->sc_chan[channel];
chan->drvr_linktab = dlt;
chan->isic_drvr_linktab = dlt;
}
@ -1266,7 +1274,7 @@ static void
avma1pp_init_linktab(struct l1_softc *sc)
{
l1_bchan_state_t *chan = &sc->sc_chan[HSCX_CH_A];
isdn_link_t *lt = &chan->isdn_linktab;
isdn_link_t *lt = &chan->isic_isdn_linktab;
/* make sure the hardware driver is known to layer 4 */
/* avoid overwriting if already set */
@ -1291,7 +1299,7 @@ avma1pp_init_linktab(struct l1_softc *sc)
lt->rx_mbuf = &chan->in_mbuf;
chan = &sc->sc_chan[HSCX_CH_B];
lt = &chan->isdn_linktab;
lt = &chan->isic_isdn_linktab;
lt->unit = sc->sc_unit;
lt->channel = HSCX_CH_B;
@ -1314,7 +1322,7 @@ static void
avma1pp_bchannel_stat(int unit, int h_chan, bchan_statistics_t *bsp)
{
#ifdef __FreeBSD__
struct l1_softc *sc = &l1_sc[unit];
struct l1_softc *sc = ifpi_scp[unit];
#else
struct l1_softc *sc = isic_find_sc(unit);
#endif
@ -1336,8 +1344,8 @@ avma1pp_bchannel_stat(int unit, int h_chan, bchan_statistics_t *bsp)
* fill HSCX fifo with data from the current mbuf
* Put this here until it can go into i4b_hscx.c
*---------------------------------------------------------------------------*/
int
isic_hscx_fifo(l1_bchan_state_t *chan, struct l1_softc *sc)
static int
avma1pp_hscx_fifo(l1_bchan_state_t *chan, struct l1_softc *sc)
{
int len;
int nextlen;
@ -1392,12 +1400,12 @@ isic_hscx_fifo(l1_bchan_state_t *chan, struct l1_softc *sc)
if(sc->sc_trace & TRACE_B_TX)
{
i4b_trace_hdr_t hdr;
hdr.unit = sc->sc_unit;
hdr.unit = L0IFPIUNIT(sc->sc_unit);
hdr.type = (chan->channel == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2);
hdr.dir = FROM_TE;
hdr.count = ++sc->sc_trace_bcount;
MICROTIME(hdr.time);
MPH_Trace_Ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data);
i4b_l1_trace_ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data);
}
}
else
@ -1415,4 +1423,65 @@ isic_hscx_fifo(l1_bchan_state_t *chan, struct l1_softc *sc)
return(cmd);
}
#endif /* NISIC > 0 && defined(AVM_A1_PCI) */
/*---------------------------------------------------------------------------*
* ifpi - ISAC interrupt routine
*---------------------------------------------------------------------------*/
static void
ifpi_isac_intr(struct l1_softc *sc)
{
register u_char isac_irq_stat;
for(;;)
{
/* get isac irq status */
isac_irq_stat = ISAC_READ(I_ISTA);
if(isac_irq_stat)
ifpi_isac_irq(sc, isac_irq_stat); /* isac handler */
else
break;
}
ISAC_WRITE(I_MASK, 0xff);
DELAY(100);
ISAC_WRITE(I_MASK, ISAC_IMASK);
}
/*---------------------------------------------------------------------------*
* ifpi_recover - try to recover from irq lockup
*---------------------------------------------------------------------------*/
void
ifpi_recover(struct l1_softc *sc)
{
u_char byte;
/* get isac irq status */
byte = ISAC_READ(I_ISTA);
NDBGL1(L1_ERROR, " ISAC: ISTA = 0x%x", byte);
if(byte & ISAC_ISTA_EXI)
NDBGL1(L1_ERROR, " ISAC: EXIR = 0x%x", (u_char)ISAC_READ(I_EXIR));
if(byte & ISAC_ISTA_CISQ)
{
byte = ISAC_READ(I_CIRR);
NDBGL1(L1_ERROR, " ISAC: CISQ = 0x%x", byte);
if(byte & ISAC_CIRR_SQC)
NDBGL1(L1_ERROR, " ISAC: SQRR = 0x%x", (u_char)ISAC_READ(I_SQRR));
}
NDBGL1(L1_ERROR, " ISAC: IMASK = 0x%x", ISAC_IMASK);
ISAC_WRITE(I_MASK, 0xff);
DELAY(100);
ISAC_WRITE(I_MASK, ISAC_IMASK);
}
#endif /* NIFPI > 0 */

View File

@ -0,0 +1,62 @@
/*
* Copyright (c) 2000 Gary Jennejohn. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*---------------------------------------------------------------------------
*
* i4b_ifpnp - Fritz!Card PnP for split layers
* -------------------------------------------
*
* $Id: i4b_ifpnp_ext.h,v 1.2 2000/06/02 16:14:36 hm Exp $
* $Ust: src/i4b/layer1-nb/ifpnp/i4b_ifpnp_ext.h,v 1.4 2000/04/18 08:03:05 ust Exp $
*
* $FreeBSD$
*
* last edit-date: [Fri Jun 2 14:54:57 2000]
*
*---------------------------------------------------------------------------*/
#ifndef _I4B_IFPNP_EXT_H_
#define _I4B_IFPNP_EXT_H_
#include <i4b/include/i4b_l3l4.h>
void ifpnp_set_linktab(int unit, int channel, drvr_link_t * dlt);
isdn_link_t *ifpnp_ret_linktab(int unit, int channel);
int ifpnp_ph_data_req(int unit, struct mbuf *m, int freeflag);
int ifpnp_ph_activate_req(int unit);
int ifpnp_mph_command_req(int unit, int command, void *parm);
void ifpnp_isac_irq(struct l1_softc *sc, int ista);
void ifpnp_isac_l1_cmd(struct l1_softc *sc, int command);
int ifpnp_isac_init(struct l1_softc *sc);
void ifpnp_recover(struct l1_softc *sc);
char * ifpnp_printstate(struct l1_softc *sc);
void ifpnp_next_state(struct l1_softc *sc, int event);
#define IFPNP_MAXUNIT 4
extern struct l1_softc *ifpnp_scp[IFPNP_MAXUNIT];
#endif /* _I4B_IFPNP_EXT_H_ */

View File

@ -0,0 +1,669 @@
/*
* Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*---------------------------------------------------------------------------
*
* i4b_ifpnp_isac.c - i4b Fritz PnP ISAC handler
* ---------------------------------------------
*
* $Id: i4b_ifpnp_isac.c,v 1.3 2000/05/29 15:41:41 hm Exp $
* $Ust: src/i4b/layer1-nb/ifpnp/i4b_ifpnp_isac.c,v 1.4 2000/04/18 08:03:05 ust Exp $
*
* $FreeBSD$
*
* last edit-date: [Mon May 29 15:24:49 2000]
*
*---------------------------------------------------------------------------*/
#include "ifpnp.h"
#if (NIFPNP > 0)
#include "opt_i4b.h"
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <machine/stdarg.h>
#include <machine/clock.h>
#include <net/if.h>
#include <machine/i4b_debug.h>
#include <machine/i4b_ioctl.h>
#include <machine/i4b_trace.h>
#include <i4b/layer1/i4b_l1.h>
#include <i4b/layer1/isic/i4b_isic.h>
#include <i4b/layer1/isic/i4b_isac.h>
#include <i4b/layer1/isic/i4b_hscx.h>
#include <i4b/layer1/ifpnp/i4b_ifpnp_ext.h>
#include <i4b/include/i4b_global.h>
#include <i4b/include/i4b_mbuf.h>
static u_char ifpnp_isac_exir_hdlr(register struct l1_softc *sc, u_char exir);
static void ifpnp_isac_ind_hdlr(register struct l1_softc *sc, int ind);
/*---------------------------------------------------------------------------*
* ISAC interrupt service routine
*---------------------------------------------------------------------------*/
void
ifpnp_isac_irq(struct l1_softc *sc, int ista)
{
register u_char c = 0;
NDBGL1(L1_F_MSG, "unit %d: ista = 0x%02x", sc->sc_unit, ista);
if(ista & ISAC_ISTA_EXI) /* extended interrupt */
{
c |= ifpnp_isac_exir_hdlr(sc, ISAC_READ(I_EXIR));
}
if(ista & ISAC_ISTA_RME) /* receive message end */
{
register int rest;
u_char rsta;
/* get rx status register */
rsta = ISAC_READ(I_RSTA);
if((rsta & ISAC_RSTA_MASK) != 0x20)
{
int error = 0;
if(!(rsta & ISAC_RSTA_CRC)) /* CRC error */
{
error++;
NDBGL1(L1_I_ERR, "unit %d: CRC error", sc->sc_unit);
}
if(rsta & ISAC_RSTA_RDO) /* ReceiveDataOverflow */
{
error++;
NDBGL1(L1_I_ERR, "unit %d: Data Overrun error", sc->sc_unit);
}
if(rsta & ISAC_RSTA_RAB) /* ReceiveABorted */
{
error++;
NDBGL1(L1_I_ERR, "unit %d: Receive Aborted error", sc->sc_unit);
}
if(error == 0)
NDBGL1(L1_I_ERR, "unit %d: RME unknown error, RSTA = 0x%02x!", sc->sc_unit, rsta);
i4b_Dfreembuf(sc->sc_ibuf);
c |= ISAC_CMDR_RMC|ISAC_CMDR_RRES;
sc->sc_ibuf = NULL;
sc->sc_ib = NULL;
sc->sc_ilen = 0;
ISAC_WRITE(I_CMDR, ISAC_CMDR_RMC|ISAC_CMDR_RRES);
ISACCMDRWRDELAY();
return;
}
rest = (ISAC_READ(I_RBCL) & (ISAC_FIFO_LEN-1));
if(rest == 0)
rest = ISAC_FIFO_LEN;
if(sc->sc_ibuf == NULL)
{
if((sc->sc_ibuf = i4b_Dgetmbuf(rest)) != NULL)
sc->sc_ib = sc->sc_ibuf->m_data;
else
panic("ifpnp_isac_irq: RME, i4b_Dgetmbuf returns NULL!\n");
sc->sc_ilen = 0;
}
if(sc->sc_ilen <= (MAX_DFRAME_LEN - rest))
{
ISAC_RDFIFO(sc->sc_ib, rest);
sc->sc_ilen += rest;
sc->sc_ibuf->m_pkthdr.len =
sc->sc_ibuf->m_len = sc->sc_ilen;
if(sc->sc_trace & TRACE_D_RX)
{
i4b_trace_hdr_t hdr;
hdr.unit = L0IFPNPUNIT(sc->sc_unit);
hdr.type = TRC_CH_D;
hdr.dir = FROM_NT;
hdr.count = ++sc->sc_trace_dcount;
MICROTIME(hdr.time);
i4b_l1_trace_ind(&hdr, sc->sc_ibuf->m_len, sc->sc_ibuf->m_data);
}
c |= ISAC_CMDR_RMC;
if(sc->sc_enabled &&
(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S))
{
i4b_l1_ph_data_ind(L0IFPNPUNIT(sc->sc_unit), sc->sc_ibuf);
}
else
{
i4b_Dfreembuf(sc->sc_ibuf);
}
}
else
{
NDBGL1(L1_I_ERR, "RME, input buffer overflow!");
i4b_Dfreembuf(sc->sc_ibuf);
c |= ISAC_CMDR_RMC|ISAC_CMDR_RRES;
}
sc->sc_ibuf = NULL;
sc->sc_ib = NULL;
sc->sc_ilen = 0;
}
if(ista & ISAC_ISTA_RPF) /* receive fifo full */
{
if(sc->sc_ibuf == NULL)
{
if((sc->sc_ibuf = i4b_Dgetmbuf(MAX_DFRAME_LEN)) != NULL)
sc->sc_ib= sc->sc_ibuf->m_data;
else
panic("ifpnp_isac_irq: RPF, i4b_Dgetmbuf returns NULL!\n");
sc->sc_ilen = 0;
}
if(sc->sc_ilen <= (MAX_DFRAME_LEN - ISAC_FIFO_LEN))
{
ISAC_RDFIFO(sc->sc_ib, ISAC_FIFO_LEN);
sc->sc_ilen += ISAC_FIFO_LEN;
sc->sc_ib += ISAC_FIFO_LEN;
c |= ISAC_CMDR_RMC;
}
else
{
NDBGL1(L1_I_ERR, "RPF, input buffer overflow!");
i4b_Dfreembuf(sc->sc_ibuf);
sc->sc_ibuf = NULL;
sc->sc_ib = NULL;
sc->sc_ilen = 0;
c |= ISAC_CMDR_RMC|ISAC_CMDR_RRES;
}
}
if(ista & ISAC_ISTA_XPR) /* transmit fifo empty (XPR bit set) */
{
if((sc->sc_obuf2 != NULL) && (sc->sc_obuf == NULL))
{
sc->sc_freeflag = sc->sc_freeflag2;
sc->sc_obuf = sc->sc_obuf2;
sc->sc_op = sc->sc_obuf->m_data;
sc->sc_ol = sc->sc_obuf->m_len;
sc->sc_obuf2 = NULL;
#ifdef NOTDEF
printf("ob2=%x, op=%x, ol=%d, f=%d #",
sc->sc_obuf,
sc->sc_op,
sc->sc_ol,
sc->sc_state);
#endif
}
else
{
#ifdef NOTDEF
printf("ob=%x, op=%x, ol=%d, f=%d #",
sc->sc_obuf,
sc->sc_op,
sc->sc_ol,
sc->sc_state);
#endif
}
if(sc->sc_obuf)
{
ISAC_WRFIFO(sc->sc_op, min(sc->sc_ol, ISAC_FIFO_LEN));
if(sc->sc_ol > ISAC_FIFO_LEN) /* length > 32 ? */
{
sc->sc_op += ISAC_FIFO_LEN; /* bufferptr+32 */
sc->sc_ol -= ISAC_FIFO_LEN; /* length - 32 */
c |= ISAC_CMDR_XTF; /* set XTF bit */
}
else
{
if(sc->sc_freeflag)
{
i4b_Dfreembuf(sc->sc_obuf);
sc->sc_freeflag = 0;
}
sc->sc_obuf = NULL;
sc->sc_op = NULL;
sc->sc_ol = 0;
c |= ISAC_CMDR_XTF | ISAC_CMDR_XME;
}
}
else
{
sc->sc_state &= ~ISAC_TX_ACTIVE;
}
}
if(ista & ISAC_ISTA_CISQ) /* channel status change CISQ */
{
register u_char ci;
/* get command/indication rx register*/
ci = ISAC_READ(I_CIRR);
/* if S/Q IRQ, read SQC reg to clr SQC IRQ */
if(ci & ISAC_CIRR_SQC)
(void) ISAC_READ(I_SQRR);
/* C/I code change IRQ (flag already cleared by CIRR read) */
if(ci & ISAC_CIRR_CIC0)
ifpnp_isac_ind_hdlr(sc, (ci >> 2) & 0xf);
}
if(c)
{
ISAC_WRITE(I_CMDR, c);
ISACCMDRWRDELAY();
}
}
/*---------------------------------------------------------------------------*
* ISAC L1 Extended IRQ handler
*---------------------------------------------------------------------------*/
static u_char
ifpnp_isac_exir_hdlr(register struct l1_softc *sc, u_char exir)
{
u_char c = 0;
if(exir & ISAC_EXIR_XMR)
{
NDBGL1(L1_I_ERR, "EXIRQ Tx Message Repeat");
c |= ISAC_CMDR_XRES;
}
if(exir & ISAC_EXIR_XDU)
{
NDBGL1(L1_I_ERR, "EXIRQ Tx Data Underrun");
c |= ISAC_CMDR_XRES;
}
if(exir & ISAC_EXIR_PCE)
{
NDBGL1(L1_I_ERR, "EXIRQ Protocol Error");
}
if(exir & ISAC_EXIR_RFO)
{
NDBGL1(L1_I_ERR, "EXIRQ Rx Frame Overflow");
c |= ISAC_CMDR_RMC|ISAC_CMDR_RRES;
}
if(exir & ISAC_EXIR_SOV)
{
NDBGL1(L1_I_ERR, "EXIRQ Sync Xfer Overflow");
}
if(exir & ISAC_EXIR_MOS)
{
NDBGL1(L1_I_ERR, "EXIRQ Monitor Status");
}
if(exir & ISAC_EXIR_SAW)
{
/* cannot happen, STCR:TSF is set to 0 */
NDBGL1(L1_I_ERR, "EXIRQ Subscriber Awake");
}
if(exir & ISAC_EXIR_WOV)
{
/* cannot happen, STCR:TSF is set to 0 */
NDBGL1(L1_I_ERR, "EXIRQ Watchdog Timer Overflow");
}
return(c);
}
/*---------------------------------------------------------------------------*
* ISAC L1 Indication handler
*---------------------------------------------------------------------------*/
static void
ifpnp_isac_ind_hdlr(register struct l1_softc *sc, int ind)
{
register int event;
switch(ind)
{
case ISAC_CIRR_IAI8:
NDBGL1(L1_I_CICO, "rx AI8 in state %s", ifpnp_printstate(sc));
if(sc->sc_bustyp == BUS_TYPE_IOM2)
ifpnp_isac_l1_cmd(sc, CMD_AR8);
event = EV_INFO48;
i4b_l1_mph_status_ind(L0IFPNPUNIT(sc->sc_unit), STI_L1STAT, LAYER_ACTIVE, NULL);
break;
case ISAC_CIRR_IAI10:
NDBGL1(L1_I_CICO, "rx AI10 in state %s", ifpnp_printstate(sc));
if(sc->sc_bustyp == BUS_TYPE_IOM2)
ifpnp_isac_l1_cmd(sc, CMD_AR10);
event = EV_INFO410;
i4b_l1_mph_status_ind(L0IFPNPUNIT(sc->sc_unit), STI_L1STAT, LAYER_ACTIVE, NULL);
break;
case ISAC_CIRR_IRSY:
NDBGL1(L1_I_CICO, "rx RSY in state %s", ifpnp_printstate(sc));
event = EV_RSY;
break;
case ISAC_CIRR_IPU:
NDBGL1(L1_I_CICO, "rx PU in state %s", ifpnp_printstate(sc));
event = EV_PU;
break;
case ISAC_CIRR_IDR:
NDBGL1(L1_I_CICO, "rx DR in state %s", ifpnp_printstate(sc));
ifpnp_isac_l1_cmd(sc, CMD_DIU);
event = EV_DR;
break;
case ISAC_CIRR_IDID:
NDBGL1(L1_I_CICO, "rx DID in state %s", ifpnp_printstate(sc));
event = EV_INFO0;
i4b_l1_mph_status_ind(L0IFPNPUNIT(sc->sc_unit), STI_L1STAT, LAYER_IDLE, NULL);
break;
case ISAC_CIRR_IDIS:
NDBGL1(L1_I_CICO, "rx DIS in state %s", ifpnp_printstate(sc));
event = EV_DIS;
break;
case ISAC_CIRR_IEI:
NDBGL1(L1_I_CICO, "rx EI in state %s", ifpnp_printstate(sc));
ifpnp_isac_l1_cmd(sc, CMD_DIU);
event = EV_EI;
break;
case ISAC_CIRR_IARD:
NDBGL1(L1_I_CICO, "rx ARD in state %s", ifpnp_printstate(sc));
event = EV_INFO2;
break;
case ISAC_CIRR_ITI:
NDBGL1(L1_I_CICO, "rx TI in state %s", ifpnp_printstate(sc));
event = EV_INFO0;
break;
case ISAC_CIRR_IATI:
NDBGL1(L1_I_CICO, "rx ATI in state %s", ifpnp_printstate(sc));
event = EV_INFO0;
break;
case ISAC_CIRR_ISD:
NDBGL1(L1_I_CICO, "rx SD in state %s", ifpnp_printstate(sc));
event = EV_INFO0;
break;
default:
NDBGL1(L1_I_ERR, "UNKNOWN Indication 0x%x in state %s", ind, ifpnp_printstate(sc));
event = EV_INFO0;
break;
}
ifpnp_next_state(sc, event);
}
/*---------------------------------------------------------------------------*
* execute a layer 1 command
*---------------------------------------------------------------------------*/
void
ifpnp_isac_l1_cmd(struct l1_softc *sc, int command)
{
u_char cmd;
#ifdef I4B_SMP_WORKAROUND
/* XXXXXXXXXXXXXXXXXXX */
/*
* patch from Wolfgang Helbig:
*
* Here is a patch that makes i4b work on an SMP:
* The card (TELES 16.3) didn't interrupt on an SMP machine.
* This is a gross workaround, but anyway it works *and* provides
* some information as how to finally fix this problem.
*/
HSCX_WRITE(0, H_MASK, 0xff);
HSCX_WRITE(1, H_MASK, 0xff);
ISAC_WRITE(I_MASK, 0xff);
DELAY(100);
HSCX_WRITE(0, H_MASK, HSCX_A_IMASK);
HSCX_WRITE(1, H_MASK, HSCX_B_IMASK);
ISAC_WRITE(I_MASK, ISAC_IMASK);
/* XXXXXXXXXXXXXXXXXXX */
#endif /* I4B_SMP_WORKAROUND */
if(command < 0 || command > CMD_ILL)
{
NDBGL1(L1_I_ERR, "illegal cmd 0x%x in state %s", command, ifpnp_printstate(sc));
return;
}
if(sc->sc_bustyp == BUS_TYPE_IOM2)
cmd = ISAC_CIX0_LOW;
else
cmd = 0;
switch(command)
{
case CMD_TIM:
NDBGL1(L1_I_CICO, "tx TIM in state %s", ifpnp_printstate(sc));
cmd |= (ISAC_CIXR_CTIM << 2);
break;
case CMD_RS:
NDBGL1(L1_I_CICO, "tx RS in state %s", ifpnp_printstate(sc));
cmd |= (ISAC_CIXR_CRS << 2);
break;
case CMD_AR8:
NDBGL1(L1_I_CICO, "tx AR8 in state %s", ifpnp_printstate(sc));
cmd |= (ISAC_CIXR_CAR8 << 2);
break;
case CMD_AR10:
NDBGL1(L1_I_CICO, "tx AR10 in state %s", ifpnp_printstate(sc));
cmd |= (ISAC_CIXR_CAR10 << 2);
break;
case CMD_DIU:
NDBGL1(L1_I_CICO, "tx DIU in state %s", ifpnp_printstate(sc));
cmd |= (ISAC_CIXR_CDIU << 2);
break;
}
ISAC_WRITE(I_CIXR, cmd);
}
/*---------------------------------------------------------------------------*
* L1 ISAC initialization
*---------------------------------------------------------------------------*/
int
ifpnp_isac_init(struct l1_softc *sc)
{
ISAC_IMASK = 0xff; /* disable all irqs */
ISAC_WRITE(I_MASK, ISAC_IMASK);
if(sc->sc_bustyp != BUS_TYPE_IOM2)
{
NDBGL1(L1_I_SETUP, "configuring for IOM-1 mode");
/* ADF2: Select mode IOM-1 */
ISAC_WRITE(I_ADF2, 0x00);
/* SPCR: serial port control register:
* SPU - software power up = 0
* SAC - SIP port high Z
* SPM - timing mode 0
* TLP - test loop = 0
* C1C, C2C - B1 and B2 switched to/from SPa
*/
ISAC_WRITE(I_SPCR, ISAC_SPCR_C1C1|ISAC_SPCR_C2C1);
/* SQXR: S/Q channel xmit register:
* SQIE - S/Q IRQ enable = 0
* SQX1-4 - Fa bits = 1
*/
ISAC_WRITE(I_SQXR, ISAC_SQXR_SQX1|ISAC_SQXR_SQX2|ISAC_SQXR_SQX3|ISAC_SQXR_SQX4);
/* ADF1: additional feature reg 1:
* WTC - watchdog = 0
* TEM - test mode = 0
* PFS - pre-filter = 0
* CFS - IOM clock/frame always active
* FSC1/2 - polarity of 8kHz strobe
* ITF - interframe fill = idle
*/
ISAC_WRITE(I_ADF1, ISAC_ADF1_FC2); /* ADF1 */
/* STCR: sync transfer control reg:
* TSF - terminal secific functions = 0
* TBA - TIC bus address = 7
* STx/SCx = 0
*/
ISAC_WRITE(I_STCR, ISAC_STCR_TBA2|ISAC_STCR_TBA1|ISAC_STCR_TBA0);
/* MODE: Mode Register:
* MDSx - transparent mode 2
* TMD - timer mode = external
* RAC - Receiver enabled
* DIMx - digital i/f mode
*/
ISAC_WRITE(I_MODE, ISAC_MODE_MDS2|ISAC_MODE_MDS1|ISAC_MODE_RAC|ISAC_MODE_DIM0);
}
else
{
NDBGL1(L1_I_SETUP, "configuring for IOM-2 mode");
/* ADF2: Select mode IOM-2 */
ISAC_WRITE(I_ADF2, ISAC_ADF2_IMS);
/* SPCR: serial port control register:
* SPU - software power up = 0
* SPM - timing mode 0
* TLP - test loop = 0
* C1C, C2C - B1 + C1 and B2 + IC2 monitoring
*/
ISAC_WRITE(I_SPCR, 0x00);
/* SQXR: S/Q channel xmit register:
* IDC - IOM direction = 0 (master)
* CFS - Config Select = 0 (clock always active)
* CI1E - C/I channel 1 IRQ enable = 0
* SQIE - S/Q IRQ enable = 0
* SQX1-4 - Fa bits = 1
*/
ISAC_WRITE(I_SQXR, ISAC_SQXR_SQX1|ISAC_SQXR_SQX2|ISAC_SQXR_SQX3|ISAC_SQXR_SQX4);
/* ADF1: additional feature reg 1:
* WTC - watchdog = 0
* TEM - test mode = 0
* PFS - pre-filter = 0
* IOF - IOM i/f off = 0
* ITF - interframe fill = idle
*/
ISAC_WRITE(I_ADF1, 0x00);
/* STCR: sync transfer control reg:
* TSF - terminal secific functions = 0
* TBA - TIC bus address = 7
* STx/SCx = 0
*/
ISAC_WRITE(I_STCR, ISAC_STCR_TBA2|ISAC_STCR_TBA1|ISAC_STCR_TBA0);
/* MODE: Mode Register:
* MDSx - transparent mode 2
* TMD - timer mode = external
* RAC - Receiver enabled
* DIMx - digital i/f mode
*/
ISAC_WRITE(I_MODE, ISAC_MODE_MDS2|ISAC_MODE_MDS1|ISAC_MODE_RAC|ISAC_MODE_DIM0);
}
#ifdef NOTDEF
/*
* XXX a transmitter reset causes an ISAC tx IRQ which will not
* be serviced at attach time under some circumstances leaving
* the associated IRQ line on the ISA bus active. This prevents
* any further interrupts to be serviced because no low -> high
* transition can take place anymore. (-hm)
*/
/* command register:
* RRES - HDLC receiver reset
* XRES - transmitter reset
*/
ISAC_WRITE(I_CMDR, ISAC_CMDR_RRES|ISAC_CMDR_XRES);
ISACCMDRWRDELAY();
#endif
/* enabled interrupts:
* ===================
* RME - receive message end
* RPF - receive pool full
* XPR - transmit pool ready
* CISQ - CI or S/Q channel change
* EXI - extended interrupt
*/
ISAC_IMASK = ISAC_MASK_RSC | /* auto mode only */
ISAC_MASK_TIN | /* timer irq */
ISAC_MASK_SIN; /* sync xfer irq */
ISAC_WRITE(I_MASK, ISAC_IMASK);
return(0);
}
#endif /* NIFPNP > 0 */

View File

@ -0,0 +1,248 @@
/*
* Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*---------------------------------------------------------------------------
*
* i4b_ifpnp_l1.c - AVM Fritz PnP layer 1 handler
* ----------------------------------------------
*
* $Id: i4b_ifpnp_l1.c,v 1.4 2000/06/02 16:14:36 hm Exp $
* $Ust: src/i4b/layer1-nb/ifpnp/i4b_ifpnp_l1.c,v 1.4 2000/04/18 08:03:05 ust Exp $
*
* $FreeBSD$
*
* last edit-date: [Fri Jun 2 14:55:49 2000]
*
*---------------------------------------------------------------------------*/
#include "ifpnp.h"
#if (NIFPNP > 0)
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <machine/stdarg.h>
#include <machine/clock.h>
#include <net/if.h>
#include <machine/i4b_debug.h>
#include <machine/i4b_ioctl.h>
#include <machine/i4b_trace.h>
#include <i4b/layer1/isic/i4b_isic.h>
#include <i4b/layer1/isic/i4b_isac.h>
#include <i4b/layer1/isic/i4b_hscx.h>
#include <i4b/layer1/ifpnp/i4b_ifpnp_ext.h>
#include <i4b/layer1/i4b_l1.h>
#include <i4b/include/i4b_mbuf.h>
#include <i4b/include/i4b_global.h>
/*---------------------------------------------------------------------------*
*
* L2 -> L1: PH-DATA-REQUEST
* =========================
*
* parms:
* unit physical interface unit number
* m mbuf containing L2 frame to be sent out
* freeflag MBUF_FREE: free mbuf here after having sent
* it out
* MBUF_DONTFREE: mbuf is freed by Layer 2
* returns:
* ==0 fail, nothing sent out
* !=0 ok, frame sent out
*
*---------------------------------------------------------------------------*/
int
ifpnp_ph_data_req(int unit, struct mbuf *m, int freeflag)
{
u_char cmd;
int s;
struct l1_softc *sc = ifpnp_scp[unit];
#ifdef NOTDEF
NDBGL1(L1_PRIM, "PH-DATA-REQ, unit %d, freeflag=%d", unit, freeflag);
#endif
if(m == NULL) /* failsafe */
return (0);
s = SPLI4B();
if(sc->sc_I430state == ST_F3) /* layer 1 not running ? */
{
NDBGL1(L1_I_ERR, "still in state F3!");
ifpnp_ph_activate_req(unit);
}
if(sc->sc_state & ISAC_TX_ACTIVE)
{
if(sc->sc_obuf2 == NULL)
{
sc->sc_obuf2 = m; /* save mbuf ptr */
if(freeflag)
sc->sc_freeflag2 = 1; /* IRQ must mfree */
else
sc->sc_freeflag2 = 0; /* IRQ must not mfree */
NDBGL1(L1_I_MSG, "using 2nd ISAC TX buffer, state = %s", ifpnp_printstate(sc));
if(sc->sc_trace & TRACE_D_TX)
{
i4b_trace_hdr_t hdr;
hdr.unit = L0IFPNPUNIT(unit);
hdr.type = TRC_CH_D;
hdr.dir = FROM_TE;
hdr.count = ++sc->sc_trace_dcount;
MICROTIME(hdr.time);
i4b_l1_trace_ind(&hdr, m->m_len, m->m_data);
}
splx(s);
return(1);
}
NDBGL1(L1_I_ERR, "No Space in TX FIFO, state = %s", ifpnp_printstate(sc));
if(freeflag == MBUF_FREE)
i4b_Dfreembuf(m);
splx(s);
return (0);
}
if(sc->sc_trace & TRACE_D_TX)
{
i4b_trace_hdr_t hdr;
hdr.unit = L0IFPNPUNIT(unit);
hdr.type = TRC_CH_D;
hdr.dir = FROM_TE;
hdr.count = ++sc->sc_trace_dcount;
MICROTIME(hdr.time);
i4b_l1_trace_ind(&hdr, m->m_len, m->m_data);
}
sc->sc_state |= ISAC_TX_ACTIVE; /* set transmitter busy flag */
NDBGL1(L1_I_MSG, "ISAC_TX_ACTIVE set");
sc->sc_freeflag = 0; /* IRQ must NOT mfree */
ISAC_WRFIFO(m->m_data, min(m->m_len, ISAC_FIFO_LEN)); /* output to TX fifo */
if(m->m_len > ISAC_FIFO_LEN) /* message > 32 bytes ? */
{
sc->sc_obuf = m; /* save mbuf ptr */
sc->sc_op = m->m_data + ISAC_FIFO_LEN; /* ptr for irq hdl */
sc->sc_ol = m->m_len - ISAC_FIFO_LEN; /* length for irq hdl */
if(freeflag)
sc->sc_freeflag = 1; /* IRQ must mfree */
cmd = ISAC_CMDR_XTF;
}
else
{
sc->sc_obuf = NULL;
sc->sc_op = NULL;
sc->sc_ol = 0;
if(freeflag)
i4b_Dfreembuf(m);
cmd = ISAC_CMDR_XTF | ISAC_CMDR_XME;
}
ISAC_WRITE(I_CMDR, cmd);
ISACCMDRWRDELAY();
splx(s);
return(1);
}
/*---------------------------------------------------------------------------*
*
* L2 -> L1: PH-ACTIVATE-REQUEST
* =============================
*
* parms:
* unit physical interface unit number
*
* returns:
* ==0
* !=0
*
*---------------------------------------------------------------------------*/
int
ifpnp_ph_activate_req(int unit)
{
struct l1_softc *sc = ifpnp_scp[unit];
NDBGL1(L1_PRIM, "PH-ACTIVATE-REQ, unit %d\n", unit);
ifpnp_next_state(sc, EV_PHAR);
return(0);
}
/*---------------------------------------------------------------------------*
* command from the upper layers
*---------------------------------------------------------------------------*/
int
ifpnp_mph_command_req(int unit, int command, void *parm)
{
struct l1_softc *sc = ifpnp_scp[unit];
switch(command)
{
case CMR_DOPEN: /* daemon running */
NDBGL1(L1_PRIM, "unit %d, command = CMR_DOPEN", unit);
sc->sc_enabled = 1;
break;
case CMR_DCLOSE: /* daemon not running */
NDBGL1(L1_PRIM, "unit %d, command = CMR_DCLOSE", unit);
sc->sc_enabled = 0;
break;
case CMR_SETTRACE:
NDBGL1(L1_PRIM, "unit %d, command = CMR_SETTRACE, parm = %d", unit, (unsigned int)parm);
sc->sc_trace = (unsigned int)parm;
break;
default:
NDBGL1(L1_ERROR, "ERROR, unknown command = %d, unit = %d, parm = %d", command, unit, (unsigned int)parm);
break;
}
return(0);
}
#endif /* NIFPNP > 0 */

View File

@ -0,0 +1,522 @@
/*
* Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*---------------------------------------------------------------------------
*
* i4b_ifpnp_l1fsm.c - AVM Fritz PnP layer 1 I.430 state machine
* -------------------------------------------------------------
*
* $Id: i4b_ifpnp_l1fsm.c,v 1.4 2000/05/29 15:41:41 hm Exp $
* $Ust: src/i4b/layer1-nb/ifpnp/i4b_ifpnp_l1fsm.c,v 1.4 2000/04/18 08:03:05 ust Exp $
*
* $FreeBSD$
*
* last edit-date: [Mon May 29 15:25:04 2000]
*
*---------------------------------------------------------------------------*/
#include "ifpnp.h"
#if (NIFPNP > 0)
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <machine/stdarg.h>
#include <machine/clock.h>
#include <net/if.h>
#include <machine/i4b_debug.h>
#include <machine/i4b_ioctl.h>
#include <machine/i4b_trace.h>
#include <i4b/layer1/isic/i4b_isic.h>
#include <i4b/layer1/isic/i4b_isac.h>
#include <i4b/layer1/isic/i4b_hscx.h>
#include <i4b/layer1/i4b_l1.h>
#include <i4b/include/i4b_global.h>
#include <i4b/include/i4b_mbuf.h>
#include <i4b/layer1/ifpnp/i4b_ifpnp_ext.h>
#if DO_I4B_DEBUG
static char *state_text[N_STATES] = {
"F3 Deactivated",
"F4 Awaiting Signal",
"F5 Identifying Input",
"F6 Synchronized",
"F7 Activated",
"F8 Lost Framing",
"Illegal State"
};
static char *event_text[N_EVENTS] = {
"EV_PHAR PH_ACT_REQ",
"EV_T3 Timer 3 expired",
"EV_INFO0 INFO0 received",
"EV_RSY Level Detected",
"EV_INFO2 INFO2 received",
"EV_INFO48 INFO4 received",
"EV_INFO410 INFO4 received",
"EV_DR Deactivate Req",
"EV_PU Power UP",
"EV_DIS Disconnected",
"EV_EI Error Ind",
"Illegal Event"
};
#endif
/* Function prototypes */
static void timer3_expired (struct l1_softc *sc);
static void T3_start (struct l1_softc *sc);
static void T3_stop (struct l1_softc *sc);
static void F_T3ex (struct l1_softc *sc);
static void timer4_expired (struct l1_softc *sc);
static void T4_start (struct l1_softc *sc);
static void T4_stop (struct l1_softc *sc);
static void F_AI8 (struct l1_softc *sc);
static void F_AI10 (struct l1_softc *sc);
static void F_I01 (struct l1_softc *sc);
static void F_I02 (struct l1_softc *sc);
static void F_I03 (struct l1_softc *sc);
static void F_I2 (struct l1_softc *sc);
static void F_ill (struct l1_softc *sc);
static void F_NULL (struct l1_softc *sc);
/*---------------------------------------------------------------------------*
* I.430 Timer T3 expire function
*---------------------------------------------------------------------------*/
static void
timer3_expired(struct l1_softc *sc)
{
if(sc->sc_I430T3)
{
NDBGL1(L1_T_ERR, "state = %s", ifpnp_printstate(sc));
sc->sc_I430T3 = 0;
/* XXX try some recovery here XXX */
ifpnp_recover(sc);
sc->sc_init_tries++; /* increment retry count */
/*XXX*/ if(sc->sc_init_tries > 4)
{
int s = SPLI4B();
sc->sc_init_tries = 0;
if(sc->sc_obuf2 != NULL)
{
i4b_Dfreembuf(sc->sc_obuf2);
sc->sc_obuf2 = NULL;
}
if(sc->sc_obuf != NULL)
{
i4b_Dfreembuf(sc->sc_obuf);
sc->sc_obuf = NULL;
sc->sc_freeflag = 0;
sc->sc_op = NULL;
sc->sc_ol = 0;
}
splx(s);
i4b_l1_mph_status_ind(L0IFPNPUNIT(sc->sc_unit), STI_NOL1ACC, 0, NULL);
}
ifpnp_next_state(sc, EV_T3);
}
else
{
NDBGL1(L1_T_ERR, "expired without starting it ....");
}
}
/*---------------------------------------------------------------------------*
* I.430 Timer T3 start
*---------------------------------------------------------------------------*/
static void
T3_start(struct l1_softc *sc)
{
NDBGL1(L1_T_MSG, "state = %s", ifpnp_printstate(sc));
sc->sc_I430T3 = 1;
sc->sc_T3_callout = timeout((TIMEOUT_FUNC_T)timer3_expired,(struct l1_softc *)sc, 2*hz);
}
/*---------------------------------------------------------------------------*
* I.430 Timer T3 stop
*---------------------------------------------------------------------------*/
static void
T3_stop(struct l1_softc *sc)
{
NDBGL1(L1_T_MSG, "state = %s", ifpnp_printstate(sc));
sc->sc_init_tries = 0; /* init connect retry count */
if(sc->sc_I430T3)
{
sc->sc_I430T3 = 0;
untimeout((TIMEOUT_FUNC_T)timer3_expired,(struct l1_softc *)sc, sc->sc_T3_callout);
}
}
/*---------------------------------------------------------------------------*
* I.430 Timer T3 expiry
*---------------------------------------------------------------------------*/
static void
F_T3ex(struct l1_softc *sc)
{
NDBGL1(L1_F_MSG, "FSM function F_T3ex executing");
if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S)
i4b_l1_ph_deactivate_ind(L0IFPNPUNIT(sc->sc_unit));
}
/*---------------------------------------------------------------------------*
* Timer T4 expire function
*---------------------------------------------------------------------------*/
static void
timer4_expired(struct l1_softc *sc)
{
if(sc->sc_I430T4)
{
NDBGL1(L1_T_MSG, "state = %s", ifpnp_printstate(sc));
sc->sc_I430T4 = 0;
i4b_l1_mph_status_ind(L0IFPNPUNIT(sc->sc_unit), STI_PDEACT, 0, NULL);
}
else
{
NDBGL1(L1_T_ERR, "expired without starting it ....");
}
}
/*---------------------------------------------------------------------------*
* Timer T4 start
*---------------------------------------------------------------------------*/
static void
T4_start(struct l1_softc *sc)
{
NDBGL1(L1_T_MSG, "state = %s", ifpnp_printstate(sc));
sc->sc_I430T4 = 1;
sc->sc_T4_callout = timeout((TIMEOUT_FUNC_T)timer4_expired,(struct l1_softc *)sc, hz);
}
/*---------------------------------------------------------------------------*
* Timer T4 stop
*---------------------------------------------------------------------------*/
static void
T4_stop(struct l1_softc *sc)
{
NDBGL1(L1_T_MSG, "state = %s", ifpnp_printstate(sc));
if(sc->sc_I430T4)
{
sc->sc_I430T4 = 0;
untimeout((TIMEOUT_FUNC_T)timer4_expired,(struct l1_softc *)sc, sc->sc_T4_callout);
}
}
/*---------------------------------------------------------------------------*
* FSM function: received AI8
*---------------------------------------------------------------------------*/
static void
F_AI8(struct l1_softc *sc)
{
T4_stop(sc);
NDBGL1(L1_F_MSG, "FSM function F_AI8 executing");
if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S)
i4b_l1_ph_activate_ind(L0IFPNPUNIT(sc->sc_unit));
T3_stop(sc);
if(sc->sc_trace & TRACE_I)
{
i4b_trace_hdr_t hdr;
char info = INFO4_8;
hdr.unit = L0IFPNPUNIT(sc->sc_unit);
hdr.type = TRC_CH_I;
hdr.dir = FROM_NT;
hdr.count = 0;
MICROTIME(hdr.time);
i4b_l1_trace_ind(&hdr, 1, &info);
}
}
/*---------------------------------------------------------------------------*
* FSM function: received AI10
*---------------------------------------------------------------------------*/
static void
F_AI10(struct l1_softc *sc)
{
T4_stop(sc);
NDBGL1(L1_F_MSG, "FSM function F_AI10 executing");
if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S)
i4b_l1_ph_activate_ind(L0IFPNPUNIT(sc->sc_unit));
T3_stop(sc);
if(sc->sc_trace & TRACE_I)
{
i4b_trace_hdr_t hdr;
char info = INFO4_10;
hdr.unit = L0IFPNPUNIT(sc->sc_unit);
hdr.type = TRC_CH_I;
hdr.dir = FROM_NT;
hdr.count = 0;
MICROTIME(hdr.time);
i4b_l1_trace_ind(&hdr, 1, &info);
}
}
/*---------------------------------------------------------------------------*
* FSM function: received INFO 0 in states F3 .. F5
*---------------------------------------------------------------------------*/
static void
F_I01(struct l1_softc *sc)
{
NDBGL1(L1_F_MSG, "FSM function F_I01 executing");
if(sc->sc_trace & TRACE_I)
{
i4b_trace_hdr_t hdr;
char info = INFO0;
hdr.unit = L0IFPNPUNIT(sc->sc_unit);
hdr.type = TRC_CH_I;
hdr.dir = FROM_NT;
hdr.count = 0;
MICROTIME(hdr.time);
i4b_l1_trace_ind(&hdr, 1, &info);
}
}
/*---------------------------------------------------------------------------*
* FSM function: received INFO 0 in state F6
*---------------------------------------------------------------------------*/
static void
F_I02(struct l1_softc *sc)
{
NDBGL1(L1_F_MSG, "FSM function F_I02 executing");
if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S)
i4b_l1_ph_deactivate_ind(L0IFPNPUNIT(sc->sc_unit));
if(sc->sc_trace & TRACE_I)
{
i4b_trace_hdr_t hdr;
char info = INFO0;
hdr.unit = L0IFPNPUNIT(sc->sc_unit);
hdr.type = TRC_CH_I;
hdr.dir = FROM_NT;
hdr.count = 0;
MICROTIME(hdr.time);
i4b_l1_trace_ind(&hdr, 1, &info);
}
}
/*---------------------------------------------------------------------------*
* FSM function: received INFO 0 in state F7 or F8
*---------------------------------------------------------------------------*/
static void
F_I03(struct l1_softc *sc)
{
NDBGL1(L1_F_MSG, "FSM function F_I03 executing");
if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S)
i4b_l1_ph_deactivate_ind(L0IFPNPUNIT(sc->sc_unit));
T4_start(sc);
if(sc->sc_trace & TRACE_I)
{
i4b_trace_hdr_t hdr;
char info = INFO0;
hdr.unit = L0IFPNPUNIT(sc->sc_unit);
hdr.type = TRC_CH_I;
hdr.dir = FROM_NT;
hdr.count = 0;
MICROTIME(hdr.time);
i4b_l1_trace_ind(&hdr, 1, &info);
}
}
/*---------------------------------------------------------------------------*
* FSM function: activate request
*---------------------------------------------------------------------------*/
static void
F_AR(struct l1_softc *sc)
{
NDBGL1(L1_F_MSG, "FSM function F_AR executing");
if(sc->sc_trace & TRACE_I)
{
i4b_trace_hdr_t hdr;
char info = INFO1_8;
hdr.unit = L0IFPNPUNIT(sc->sc_unit);
hdr.type = TRC_CH_I;
hdr.dir = FROM_TE;
hdr.count = 0;
MICROTIME(hdr.time);
i4b_l1_trace_ind(&hdr, 1, &info);
}
ifpnp_isac_l1_cmd(sc, CMD_AR8);
T3_start(sc);
}
/*---------------------------------------------------------------------------*
* FSM function: received INFO2
*---------------------------------------------------------------------------*/
static void
F_I2(struct l1_softc *sc)
{
NDBGL1(L1_F_MSG, "FSM function F_I2 executing");
if(sc->sc_trace & TRACE_I)
{
i4b_trace_hdr_t hdr;
char info = INFO2;
hdr.unit = L0IFPNPUNIT(sc->sc_unit);
hdr.type = TRC_CH_I;
hdr.dir = FROM_NT;
hdr.count = 0;
MICROTIME(hdr.time);
i4b_l1_trace_ind(&hdr, 1, &info);
}
}
/*---------------------------------------------------------------------------*
* illegal state default action
*---------------------------------------------------------------------------*/
static void
F_ill(struct l1_softc *sc)
{
NDBGL1(L1_F_ERR, "FSM function F_ill executing");
}
/*---------------------------------------------------------------------------*
* No action
*---------------------------------------------------------------------------*/
static void
F_NULL(struct l1_softc *sc)
{
NDBGL1(L1_F_MSG, "FSM function F_NULL executing");
}
/*---------------------------------------------------------------------------*
* layer 1 state transition table
*---------------------------------------------------------------------------*/
struct ifpnp_state_tab {
void (*func) (struct l1_softc *sc); /* function to execute */
int newstate; /* next state */
} ifpnp_state_tab[N_EVENTS][N_STATES] = {
/* STATE: F3 F4 F5 F6 F7 F8 ILLEGAL STATE */
/* -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* EV_PHAR x*/ {{F_AR, ST_F4}, {F_NULL, ST_F4}, {F_NULL, ST_F5}, {F_NULL, ST_F6}, {F_ill, ST_ILL}, {F_NULL, ST_F8}, {F_ill, ST_ILL}},
/* EV_T3 x*/ {{F_NULL, ST_F3}, {F_T3ex, ST_F3}, {F_T3ex, ST_F3}, {F_T3ex, ST_F3}, {F_NULL, ST_F7}, {F_NULL, ST_F8}, {F_ill, ST_ILL}},
/* EV_INFO0 */ {{F_I01, ST_F3}, {F_I01, ST_F4}, {F_I01, ST_F5}, {F_I02, ST_F3}, {F_I03, ST_F3}, {F_I03, ST_F3}, {F_ill, ST_ILL}},
/* EV_RSY x*/ {{F_NULL, ST_F3}, {F_NULL, ST_F5}, {F_NULL, ST_F5}, {F_NULL, ST_F8}, {F_NULL, ST_F8}, {F_NULL, ST_F8}, {F_ill, ST_ILL}},
/* EV_INFO2 */ {{F_I2, ST_F6}, {F_I2, ST_F6}, {F_I2, ST_F6}, {F_I2, ST_F6}, {F_I2, ST_F6}, {F_I2, ST_F6}, {F_ill, ST_ILL}},
/* EV_INFO48*/ {{F_AI8, ST_F7}, {F_AI8, ST_F7}, {F_AI8, ST_F7}, {F_AI8, ST_F7}, {F_NULL, ST_F7}, {F_AI8, ST_F7}, {F_ill, ST_ILL}},
/* EV_INFO41*/ {{F_AI10, ST_F7}, {F_AI10, ST_F7}, {F_AI10, ST_F7}, {F_AI10, ST_F7}, {F_NULL, ST_F7}, {F_AI10, ST_F7}, {F_ill, ST_ILL}},
/* EV_DR */ {{F_NULL, ST_F3}, {F_NULL, ST_F4}, {F_NULL, ST_F5}, {F_NULL, ST_F6}, {F_NULL, ST_F7}, {F_NULL, ST_F8}, {F_ill, ST_ILL}},
/* EV_PU */ {{F_NULL, ST_F3}, {F_NULL, ST_F4}, {F_NULL, ST_F5}, {F_NULL, ST_F6}, {F_NULL, ST_F7}, {F_NULL, ST_F8}, {F_ill, ST_ILL}},
/* EV_DIS */ {{F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}},
/* EV_EI */ {{F_NULL, ST_F3}, {F_NULL, ST_F3}, {F_NULL, ST_F3}, {F_NULL, ST_F3}, {F_NULL, ST_F3}, {F_NULL, ST_F3}, {F_ill, ST_ILL}},
/* EV_ILL */ {{F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}}
};
/*---------------------------------------------------------------------------*
* event handler
*---------------------------------------------------------------------------*/
void
ifpnp_next_state(struct l1_softc *sc, int event)
{
int currstate, newstate;
if(event >= N_EVENTS)
panic("i4b_l1fsm.c: event >= N_EVENTS\n");
currstate = sc->sc_I430state;
if(currstate >= N_STATES)
panic("i4b_l1fsm.c: currstate >= N_STATES\n");
newstate = ifpnp_state_tab[event][currstate].newstate;
if(newstate >= N_STATES)
panic("i4b_l1fsm.c: newstate >= N_STATES\n");
NDBGL1(L1_F_MSG, "FSM event [%s]: [%s => %s]", event_text[event],
state_text[currstate],
state_text[newstate]);
(*ifpnp_state_tab[event][currstate].func)(sc);
if(newstate == ST_ILL)
{
newstate = ST_F3;
NDBGL1(L1_F_ERR, "FSM Illegal State ERROR, oldstate = %s, newstate = %s, event = %s!",
state_text[currstate],
state_text[newstate],
event_text[event]);
}
sc->sc_I430state = newstate;
}
#if DO_I4B_DEBUG
/*---------------------------------------------------------------------------*
* return pointer to current state description
*---------------------------------------------------------------------------*/
char *
ifpnp_printstate(struct l1_softc *sc)
{
return((char *) state_text[sc->sc_I430state]);
}
#endif
#endif /* NIFPNP > 0 */

View File

@ -0,0 +1,337 @@
/*
* Copyright (c) 2000 Hans Petter Selasky. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*---------------------------------------------------------------------------
*
* i4b_ihfc.h - ihfc common header file
* ------------------------------------
*
* last edit-date: [Wed Jul 19 09:40:45 2000]
*
* $Id: i4b_ihfc.h,v 1.9 2000/09/19 13:50:36 hm Exp $
*
* $FreeBSD$
*
*---------------------------------------------------------------------------*/
#ifndef _I4B_IHFC_H_
#define _I4B_IHFC_H_
#include <i4b/include/i4b_l3l4.h>
/*---------------------------------------------------------------------------*
* global stuff (HFC-1/S/SP)
*---------------------------------------------------------------------------*/
#define DCH_MAX_LEN 264 /* max length of a D frame */
#define IHFC_ACTIVATION_TIMEOUT 3*hz /* S0-bus must activate before this time */
#define IHFC_IO_BASES 1
#define IHFC_DISBUSYTO 500 /* do at least 500 inb's before giving up */
#define IHFC_NONBUSYTO 8000 /* do at least 8000 inb's before giving up */
#define IHFC_NTMODE 0 /* use TE-mode as default */
#define IHFC_DLP 0 /* use (8/9) priority as default */
#define IHFC_MAXUNIT 4
/* #define IHFC_DEBUG internal debugging enabled *
* #undef IHFC_DEBUG internal debugging disabled */
/* chan: *
* 0 - D1 (tx) *
* 1 - D1 (rx) *
* 2 - B1 (tx) *
* 3 - B1 (rx) *
* 4 - B2 (tx) *
* 5 - B2 (rx) */
#define HFC_1 0x01 /* HFC 2B */
#define HFC_S 0x02 /* HFC - S 2BDS0 */
#define HFC_SP 0x04 /* HFC - SP 2BDS0 */
#define HFC_SPCI 0x08 /* HFC - SPCI 2BDS0 X */
#define HFC_S2M 0x10 /* HFC - S2M 2BDS0 X */
#define HFC_USB 0x20 /* HFC - USB 2BDS0 X */
/*---------------------------------------------------------------------------*
* "Help Fix Corruption" macros (HFC-1/S/SP)
*
* NOTE: If the code does not run at splhigh, we will sporadically
* lose bytes. On fast PC's (200 Mhz), this is very little noticable.
*---------------------------------------------------------------------------*/
#define HFC_VAR int _s_ /* declare variable */
#define HFC_BEG _s_ = splhigh() /* save spl */
#define HFC_END splx(_s_) /* restore spl */
/*---------------------------------------------------------------------------*
* macros related to i4b linking (HFC-1/S/SP)
*---------------------------------------------------------------------------*/
#define S_BLINK sc->sc_blinktab[(chan > 3) ? 1 : 0]
#define S_BDRVLINK sc->sc_bdrvlinktab[(chan > 3) ? 1 : 0]
/*---------------------------------------------------------------------------*
* macros related to ihfc_sc (HFC-1/S/SP)
*---------------------------------------------------------------------------*/
/* statemachine */
#define S_IOM2 (sc->sc_config.i_adf2 & 0x80)
/* 0x80: IOM2 mode selected */
#define S_DLP (sc->sc_config.dlp)
#define S_NTMODE (sc->sc_config.ntmode)
#define S_STDEL (sc->sc_config.stdel)
#define S_PHSTATE sc->sc_statemachine.state
#define S_STM_T3 sc->sc_statemachine.T3
#define S_STM_T3CALLOUT sc->sc_statemachine.T3callout
/* unitnumbers */
#define S_UNIT sc->sc_unit
#define S_FLAG sc->sc_flag
#define S_I4BUNIT sc->sc_i4bunit
#define S_I4BFLAG sc->sc_i4bflag
/* ISA bus setup */
#define S_IOBASE sc->sc_resources.io_base
#define S_IORID sc->sc_resources.io_rid
#define S_IRQ sc->sc_resources.irq
#define S_IRQRID sc->sc_resources.irq_rid
/* hardware setup */
#define S_HFC sc->sc_config.chiptype
#define S_IIO sc->sc_config.iio
#define S_IIRQ sc->sc_config.iirq
/* registers of the HFC-S/SP (write only) */
#define S_HFC_CONFIG sc->sc_config.cirm
#define S_CIRM sc->sc_config.cirm
#define S_CTMT sc->sc_config.ctmt
#define S_TEST sc->sc_config.test
#define S_SCTRL sc->sc_config.sctrl
#define S_CLKDEL sc->sc_config.clkdel
#define S_INT_M1 sc->sc_config.int_m1
#define S_INT_M2 sc->sc_config.int_m2
#define S_CONNECT sc->sc_config.connect
#define S_SCTRL_R sc->sc_config.sctrl_r
#define S_MST_MODE sc->sc_config.mst_mode
/* registers of the HFC-S/SP (read only) */
#define S_INT_S1 sc->sc_config.int_s1
/* registers of the ISAC (write only) */
#define S_ISAC_CONFIG sc->sc_config.i_adf2
#define S_ADF1 sc->sc_config.i_adf1
#define S_ADF2 sc->sc_config.i_adf2
#define S_MASK sc->sc_config.i_mask
#define S_MODE sc->sc_config.i_mode
#define S_SPCR sc->sc_config.i_spcr
#define S_SQXR sc->sc_config.i_sqxr
#define S_STCR sc->sc_config.i_stcr
#define S_STAR2 sc->sc_config.i_star2
/* registers of the ISAC (read only) */
#define S_ISTA sc->sc_config.i_ista
/* state of the softc */
#define S_ENABLED sc->sc_enabled
#define S_INTR_ACTIVE sc->sc_intr_active
/* SOFT-HDLC */
#define S_HDLC_IB sc->sc_fifo.chan[chan].hdlc.ib /* u_short */
#define S_HDLC_CRC sc->sc_fifo.chan[chan].hdlc.crc /* u_short */
#define S_HDLC_TMP sc->sc_fifo.chan[chan].hdlc.tmp /* u_int */
#define S_HDLC_FLAG sc->sc_fifo.chan[chan].hdlc.flag /* u_char */
#define S_HDLC_BLEVEL sc->sc_fifo.chan[chan].hdlc.blevel /* u_short */
/* stats */
#define S_BYTES sc->sc_fifo.chan[chan].bytes
/* "Z"-values */
#define S_HDLC_DZ_TAB sc->sc_fifo.dztable
/* filters */
#define S_PROT sc->sc_fifo.chan[chan].prot
#define S_FILTER sc->sc_fifo.chan[chan].filter
#define S_ACTIVITY sc->sc_fifo.chan[chan].activity
#define S_LAST_CHAN sc->sc_fifo.last_chan
/* soft reset */
#define RESET_SOFT_CHAN(sc, chan) bzero(&sc->sc_fifo.chan[chan], sizeof(sc->sc_fifo.chan[0]))
/* trace */
#define S_TRACE sc->sc_trace
#define S_DTRACECOUNT sc->sc_Dtracecount
#define S_BTRACECOUNT sc->sc_Btracecount
/* mbuf */
#define S_MBUF sc->sc_fifo.chan[chan].buffer.mbuf
#define S_MBUFDUMMY sc->sc_fifo.chan[chan].buffer.mbufdummy
#define S_MBUFLEN sc->sc_fifo.chan[chan].buffer.mbuf->m_len
#define S_MBUFPKTHDR sc->sc_fifo.chan[chan].buffer.mbuf->m_pkthdr
#define S_MBUFDATA sc->sc_fifo.chan[chan].buffer.mbuf->m_data
#define S_MBUFDAT sc->sc_fifo.chan[chan].buffer.mbuf->m_dat
#define S_IFQUEUE sc->sc_fifo.chan[chan].buffer.ifqueue
/* hfc control */
#define HFC_INIT ihfc_init
#define HFC_INTR ((S_HFC & HFC_1) ? ihfc_intr1 : ihfc_intr2)
#define HFC_FSM ihfc_fsm
#define HFC_CONTROL ihfc_control
/* softc parts */
struct ihfc_sc;
struct sc_resources {
struct resource * io_base[IHFC_IO_BASES];
int io_rid [IHFC_IO_BASES];
struct resource * irq;
int irq_rid;
};
struct hdlc {
u_char flag;
u_short blevel;
u_short crc;
u_short ib;
u_int tmp;
};
struct buffer {
struct ifqueue ifqueue; /* data queue */
struct mbuf *mbuf; /* current mbuf */
struct mbuf *mbufdummy; /* temporary */
};
struct chan {
struct hdlc hdlc;
u_int bytes;
u_int prot;
struct buffer buffer;
void (*filter)(struct ihfc_sc *sc, u_char chan);
};
struct sc_fifo {
struct chan chan[6];
u_short dztable[16];
u_char last_chan;
};
struct sc_config {
/* software only: */
u_short chiptype; /* chiptype (eg. HFC_1) */
u_char dlp; /* D-priority */
u_short iio; /* internal IO */
u_char iirq; /* internal IRQ */
u_char ntmode; /* mode */
u_char stdel; /* S/T delay */
/* write only: */
u_char cirm;
u_char ctmt;
u_char int_m1;
u_char int_m2;
u_char mst_mode;
u_char clkdel;
u_char sctrl;
u_char connect;
u_char test;
u_char sctrl_r;
/* isac write only - hfc-1: */
u_char i_adf2;
u_char i_spcr;
u_char i_sqxr;
u_char i_adf1;
u_char i_stcr;
u_char i_mode;
u_char i_mask;
u_char i_star2;
/* read only: */
u_char int_s1;
/* isac read only - hfc-1: */
u_char i_ista;
};
struct sc_statemachine {
u_char state; /* see i4b_ihfc_drv.h */
u_char usync;
u_char T3; /* T3 running */
struct callout_handle T3callout;
};
/*---------------------------------------------------------------------------*
* HFC softc
*---------------------------------------------------------------------------*/
typedef struct ihfc_sc
{ int sc_unit;
int sc_flag;
int sc_i4bunit; /* L0IHFCUNIT(sc_unit) */
int sc_i4bflag; /* FLAG_TEL_S0_16_3C .. */
u_char sc_enabled; /* daemon running if set */
u_char sc_intr_active; /* interrupt is active */
int sc_trace;
u_int sc_Btracecount;
u_int sc_Dtracecount;
struct sc_config sc_config;
struct sc_resources sc_resources;
struct sc_statemachine sc_statemachine;
isdn_link_t sc_blinktab[2];
drvr_link_t *sc_bdrvlinktab[2];
struct sc_fifo sc_fifo;
} ihfc_sc_t;
extern ihfc_sc_t ihfc_softc[];
#endif /* _I4B_IHFC_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -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_ */

View File

@ -0,0 +1,62 @@
/*
* Copyright (c) 2000 Hans Petter Selasky. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*---------------------------------------------------------------------------
*
* i4b_ihfc_ext.h - ihfc common prototypes
* ---------------------------------------
*
* last edit-date: [Wed Jul 19 09:40:59 2000]
*
* $Id: i4b_ihfc_ext.h,v 1.6 2000/08/20 07:14:08 hm Exp $
*
* $FreeBSD$
*
*---------------------------------------------------------------------------*/
#ifndef I4B_IHFC_EXT_H_
#define I4B_IHFC_EXT_H_
#include <i4b/include/i4b_l3l4.h>
/* prototypes from i4b_ihfc_l1if.c */
extern struct i4b_l1mux_func ihfc_l1mux_func;
void ihfc_B_linkinit (ihfc_sc_t *sc);
struct mbuf * ihfc_getmbuf (ihfc_sc_t *sc, u_char chan);
void ihfc_putmbuf (ihfc_sc_t *sc, u_char chan, struct mbuf *m);
/* prototypes from i4b_ihfc_drv.c */
void ihfc_intr1 (ihfc_sc_t *sc);
void ihfc_intr2 (ihfc_sc_t *sc);
int ihfc_control (ihfc_sc_t *sc, int flag);
void ihfc_fsm (ihfc_sc_t *sc, int flag);
int ihfc_init (ihfc_sc_t *sc, u_char chan, int prot, int activate);
#endif /* I4B_IHFC_EXT_H_ */

View File

@ -0,0 +1,517 @@
/*
* Copyright (c) 2000 Hans Petter Selasky. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*---------------------------------------------------------------------------
*
* i4b_ihfc_l1.c - hfc layer 1 handler
* -----------------------------------
*
* The idea of this file is to seperate hfcs/sp/pci data/signal
* handling and the I4B data/signal handling.
*
* Everything which has got anything to do with I4B has been put here!
*
* last edit-date: [Wed Jul 19 09:41:03 2000]
*
* $Id: i4b_ihfc_l1if.c,v 1.10 2000/09/19 13:50:36 hm Exp $
*
* $FreeBSD$
*
*---------------------------------------------------------------------------*/
#include "ihfc.h"
#if (NIHFC > 0)
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <machine/stdarg.h>
#include <machine/clock.h>
#include <net/if.h>
#include <machine/i4b_debug.h>
#include <machine/i4b_ioctl.h>
#include <machine/i4b_trace.h>
#include <i4b/include/i4b_mbuf.h>
#include <i4b/include/i4b_global.h>
#include <i4b/include/i4b_l1l2.h>
#include <i4b/layer1/i4b_l1.h>
#include <i4b/layer1/ihfc/i4b_ihfc.h>
#include <i4b/layer1/ihfc/i4b_ihfc_ext.h>
/*---------------------------------------------------------------------------*
* Local prototypes
*
* NOTE: The prototypes for get/putmbuf and B_linkinit
* have been put in i4b_hfc_ext.h for global hfc use.
*
* NOTE: channel != chan
*---------------------------------------------------------------------------*/
static
isdn_link_t * ihfc_B_ret_linktab (int unit, int channel);
static void ihfc_B_set_linktab (int unit, int channel, drvr_link_t *B_linktab);
static void ihfc_B_start (int unit, int chan);
static void ihfc_B_stat (int unit, int chan, bchan_statistics_t *bsp);
void ihfc_B_setup (int unit, int chan, int bprot, int activate);
static int ihfc_mph_command_req (int unit, int command, void *parm);
static int ihfc_ph_activate_req (int unit);
static int ihfc_ph_data_req (int unit, struct mbuf *m, int freeflag);
static void ihfc_T3_expired (ihfc_sc_t *sc);
/*---------------------------------------------------------------------------*
* Our I4B L1 mulitplexer link
*---------------------------------------------------------------------------*/
struct i4b_l1mux_func ihfc_l1mux_func = {
ihfc_B_ret_linktab,
ihfc_B_set_linktab,
ihfc_mph_command_req,
ihfc_ph_data_req,
ihfc_ph_activate_req,
};
/*---------------------------------------------------------------------------*
* L2 -> L1: PH-DATA-REQUEST (D-Channel)
*
* NOTE: We may get called here from ihfc_hdlc_Dread or isac_hdlc_Dread
* via the upper layers.
*---------------------------------------------------------------------------*/
int
ihfc_ph_data_req(int unit, struct mbuf *m, int freeflag)
{
ihfc_sc_t *sc = &ihfc_softc[unit];
u_char chan = 0;
HFC_VAR;
if (!m) return 0;
HFC_BEG;
if(S_PHSTATE != 3)
{
NDBGL1(L1_PRIM, "L1 was not running: "
"ihfc_ph_activate_req(unit = %d)!", unit);
ihfc_ph_activate_req(unit);
}
/* "Allow" I-frames (-hp) */
if (freeflag == MBUF_DONTFREE) m = m_copypacket(m, M_DONTWAIT);
if (!IF_QFULL(&S_IFQUEUE) && m)
{
IF_ENQUEUE(&S_IFQUEUE, m);
ihfc_B_start(unit, chan); /* (recycling) */
}
else
{
NDBGL1(L1_ERROR, "No frame out (unit = %d)", unit);
i4b_Dfreembuf(m);
}
if (S_INTR_ACTIVE) S_INT_S1 |= 0x04;
HFC_END;
return 1;
}
/*---------------------------------------------------------------------------*
* L2 -> L1: PH-ACTIVATE-REQUEST (B-channel and D-channel)
*---------------------------------------------------------------------------*/
int
ihfc_ph_activate_req(int unit)
{
ihfc_sc_t *sc = &ihfc_softc[unit];
HFC_VAR;
HFC_BEG;
if ((!S_STM_T3) && (S_PHSTATE != 3))
{
HFC_FSM(sc, 1);
S_STM_T3 = 1;
S_STM_T3CALLOUT = timeout((TIMEOUT_FUNC_T)
ihfc_T3_expired, (ihfc_sc_t *)sc,
IHFC_ACTIVATION_TIMEOUT);
}
HFC_END;
return 0;
}
/*---------------------------------------------------------------------------*
* T3 timeout - persistant deactivation
*---------------------------------------------------------------------------*/
void
ihfc_T3_expired(ihfc_sc_t *sc)
{
u_char chan = 0;
HFC_VAR;
HFC_BEG;
S_STM_T3 = 0;
if (S_PHSTATE != 3) /* line was not activated */
{
i4b_Dcleanifq(&S_IFQUEUE);
i4b_l1_ph_deactivate_ind(S_I4BUNIT);
i4b_l1_mph_status_ind(S_I4BUNIT, STI_PDEACT, 0, 0);
HFC_FSM(sc, 2); /* L1 deactivate */
}
HFC_END;
}
/*---------------------------------------------------------------------------*
* Command from the upper layers (B-channel and D-channel)
*---------------------------------------------------------------------------*/
int
ihfc_mph_command_req(int unit, int command, void *parm)
{
ihfc_sc_t *sc = &ihfc_softc[unit];
switch(command)
{
case CMR_DOPEN: /* daemon running */
NDBGL1(L1_PRIM,
"unit %d, command = CMR_DOPEN", unit);
S_ENABLED = 1;
break;
case CMR_DCLOSE: /* daemon not running */
NDBGL1(L1_PRIM,
"unit %d, command = CMR_DCLOSE", unit);
S_ENABLED = 0;
break;
case CMR_SETTRACE: /* set new trace mask */
NDBGL1(L1_PRIM,
"unit %d, command = CMR_SETTRACE, parm = %d",
unit, (unsigned int)parm);
S_TRACE = (unsigned int)parm;
break;
case CMR_GCST: /* get chip statistic */
NDBGL1(L1_PRIM,
"unit %d, command = CMR_GCST, parm = %d",
unit, (unsigned int)parm);
#define CST ((struct chipstat *)parm)
CST->driver_type = L1DRVR_IHFC;
/* XXX CST->xxxx_stat = xxx; */
#undef CST
break;
default:
NDBGL1(L1_ERROR,
"ERROR, unknown command = %d, unit = %d, parm = %d",
command, unit, (unsigned int)parm);
break;
}
return 0;
}
/*---------------------------------------------------------------------------*
* Data source switch for Read channels - 1, 3 and 5 (B and D-Channel)
*---------------------------------------------------------------------------*/
void
ihfc_putmbuf (ihfc_sc_t *sc, u_char chan, struct mbuf *m)
{
i4b_trace_hdr_t hdr;
if (chan < 2)
{
if(S_TRACE & TRACE_D_RX)
{
hdr.count = ++S_DTRACECOUNT;
hdr.dir = FROM_NT;
hdr.type = TRC_CH_D;
hdr.unit = S_I4BUNIT;
MICROTIME(hdr.time);
i4b_l1_trace_ind(&hdr, m->m_len, m->m_data);
}
if (!S_ENABLED) { i4b_Dfreembuf(m); return; }
m->m_pkthdr.len = m->m_len;
i4b_l1_ph_data_ind(S_I4BUNIT, m);
}
else
{
if(S_TRACE & TRACE_B_RX)
{
hdr.count = ++S_BTRACECOUNT;
hdr.dir = FROM_NT;
hdr.type = (chan < 4) ? TRC_CH_B1 : TRC_CH_B2;
hdr.unit = S_I4BUNIT;
MICROTIME(hdr.time);
i4b_l1_trace_ind(&hdr, m->m_len, m->m_data);
}
if (!S_ENABLED) { i4b_Bfreembuf(m); return; }
if (S_PROT == BPROT_NONE)
{
if(!i4b_l1_bchan_tel_silence(m->m_data, m->m_len))
{
S_BDRVLINK->bch_activity(S_BDRVLINK->unit, ACT_RX);
}
if (!IF_QFULL(&S_IFQUEUE))
{
S_BYTES += m->m_len;
IF_ENQUEUE(&S_IFQUEUE, m);
S_BDRVLINK->bch_rx_data_ready(S_BDRVLINK->unit);
}
return;
}
if (S_PROT == BPROT_RHDLC)
{
S_MBUFDUMMY = m;
S_BYTES += m->m_pkthdr.len = m->m_len;
S_BDRVLINK->bch_rx_data_ready(S_BDRVLINK->unit);
S_MBUFDUMMY = NULL;
return;
}
NDBGL1(L1_ERROR, "Unknown protocol: %d", S_PROT);
}
}
/*---------------------------------------------------------------------------*
* Data destinator switch for write channels - 0, 2 and 4
*---------------------------------------------------------------------------*/
struct mbuf *
ihfc_getmbuf (ihfc_sc_t *sc, u_char chan)
{
register struct mbuf *m;
i4b_trace_hdr_t hdr;
if (chan < 2)
{
IF_DEQUEUE(&S_IFQUEUE, m);
if((S_TRACE & TRACE_D_TX) && m)
{
hdr.count = ++S_DTRACECOUNT;
hdr.dir = FROM_TE;
hdr.type = TRC_CH_D;
hdr.unit = S_I4BUNIT;
MICROTIME(hdr.time);
i4b_l1_trace_ind(&hdr, m->m_len, m->m_data);
}
}
else
{
IF_DEQUEUE(&S_IFQUEUE, m);
if (!m)
{
S_BDRVLINK->bch_tx_queue_empty(S_BDRVLINK->unit);
IF_DEQUEUE(&S_IFQUEUE, m);
}
if (m)
{
if(!i4b_l1_bchan_tel_silence(m->m_data, m->m_len))
{
S_BDRVLINK->bch_activity(S_BDRVLINK->unit, ACT_TX);
}
S_BYTES += m->m_len;
if(S_TRACE & TRACE_B_TX)
{
hdr.count = ++S_BTRACECOUNT;
hdr.dir = FROM_TE;
hdr.type = (chan < 4) ? TRC_CH_B1 : TRC_CH_B2;
hdr.unit = S_I4BUNIT;
MICROTIME(hdr.time);
i4b_l1_trace_ind(&hdr, m->m_len, m->m_data);
}
}
}
return(m);
}
/*---------------------------------------------------------------------------*
* Initialize rx/tx data structures (B-channel)
*---------------------------------------------------------------------------*/
void
ihfc_B_setup(int unit, int chan, int bprot, int activate)
{
ihfc_sc_t *sc = &ihfc_softc[unit];
HFC_VAR;
if (((u_int)chan > 5) || ((u_int)chan < 2)) return;
HFC_BEG;
HFC_INIT(sc, chan, bprot, activate);
HFC_END;
}
/*---------------------------------------------------------------------------*
* Start transmission (B-channel or D-channel tx)
* NOTE: if "chan" variable is corrupted, it will not cause any harm,
* but data may be lost and there may be software sync. errors.
*---------------------------------------------------------------------------*/
void
ihfc_B_start(int unit, int chan)
{
ihfc_sc_t *sc = &ihfc_softc[unit];
HFC_VAR;
if ((u_int)chan > 5) return;
HFC_BEG;
if (S_FILTER && !S_MBUF && !S_INTR_ACTIVE)
{
S_INTR_ACTIVE |= 2; /* never know what *
* they put in the *
* L2 code */
S_FILTER(sc, chan); /* quick tx */
S_INTR_ACTIVE &= ~2;
}
HFC_END;
}
/*---------------------------------------------------------------------------*
* Fill statistics struct (B-channel)
*---------------------------------------------------------------------------*/
void
ihfc_B_stat(int unit, int chan, bchan_statistics_t *bsp)
{
ihfc_sc_t *sc = &ihfc_softc[unit];
HFC_VAR;
if ((u_int)chan > 5) return;
chan &= ~1;
HFC_BEG;
bsp->inbytes = S_BYTES; S_BYTES = 0;
chan++;
bsp->outbytes = S_BYTES; S_BYTES = 0;
HFC_END;
}
/*---------------------------------------------------------------------------*
* Return the address of IHFC linktab to I4B (B-channel)
*---------------------------------------------------------------------------*/
isdn_link_t *
ihfc_B_ret_linktab(int unit, int channel)
{
ihfc_sc_t *sc = &ihfc_softc[unit];
if (channel < 2)
return(&sc->sc_blinktab[channel]);
else
return 0;
}
/*---------------------------------------------------------------------------*
* Set the I4B driver linktab for IHFC use (B-channel)
*---------------------------------------------------------------------------*/
void
ihfc_B_set_linktab(int unit, int channel, drvr_link_t *B_linktab)
{
ihfc_sc_t *sc = &ihfc_softc[unit];
if (channel < 2)
sc->sc_bdrvlinktab[channel] = B_linktab;
}
/*---------------------------------------------------------------------------*
* Initialize linktab for I4B use (B-channel)
*---------------------------------------------------------------------------*/
void
ihfc_B_linkinit(ihfc_sc_t *sc)
{
u_char chan;
/* make sure the hardware driver is known to layer 4 */
ctrl_types[CTRL_PASSIVE].set_linktab = i4b_l1_set_linktab;
ctrl_types[CTRL_PASSIVE].get_linktab = i4b_l1_ret_linktab;
for (chan = 2; chan < 6; chan++)
{
S_BLINK.unit = S_UNIT;
S_BLINK.channel = chan; /* point to tx-chan */
S_BLINK.bch_config = ihfc_B_setup;
S_BLINK.bch_tx_start = ihfc_B_start;
S_BLINK.bch_stat = ihfc_B_stat;
/* This is a transmit channel (even) */
S_BLINK.tx_queue = &S_IFQUEUE;
chan++;
/* This is a receive channel (odd) */
S_BLINK.rx_queue = &S_IFQUEUE;
S_BLINK.rx_mbuf = &S_MBUFDUMMY;
}
}
#endif /* NIHFC > 0 */

View File

@ -0,0 +1,421 @@
/*
* Copyright (c) 2000 Hans Petter Selasky. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*---------------------------------------------------------------------------
*
* i4b_ihfc_pnp.c - common hfc ISA PnP-bus interface
* -------------------------------------------------
*
* - Everything which has got anything to to with "PnP" bus setup has
* been put here.
*
*
* last edit-date: [Wed Jul 19 09:41:07 2000]
*
* $Id: i4b_ihfc_pnp.c,v 1.9 2000/09/19 13:50:36 hm Exp $
*
* $FreeBSD$
*
*---------------------------------------------------------------------------*/
#include "ihfc.h"
#if (NIHFC > 0)
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/socket.h>
#include <net/if.h>
#include <sys/mbuf.h>
#include <machine/clock.h>
#include <i4b/include/i4b_global.h>
#include <i4b/include/i4b_mbuf.h>
#include <i4b/include/i4b_l1l2.h>
#include <machine/i4b_ioctl.h>
#include <machine/i4b_trace.h>
#include <i4b/layer1/i4b_l1.h>
#include <i4b/layer1/ihfc/i4b_ihfc.h>
#include <i4b/layer1/ihfc/i4b_ihfc_ext.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <sys/bus.h>
#include <sys/rman.h>
#include <isa/isavar.h>
/*---------------------------------------------------------------------------*
* Softc
*---------------------------------------------------------------------------*/
ihfc_sc_t ihfc_softc[IHFC_MAXUNIT];
/*---------------------------------------------------------------------------*
* Prototypes
*---------------------------------------------------------------------------*/
static int ihfc_isa_probe (device_t dev);
static int ihfc_pnp_probe (device_t dev);
static int ihfc_pnp_attach (device_t dev);
static int ihfc_pnp_detach (device_t dev, u_int flag);
static int ihfc_pnp_shutdown (device_t dev);
const struct ihfc_pnp_ids
{
u_long vid; /* vendor id */
int flag; /* */
u_char hfc; /* chip type */
u_char iirq; /* internal irq */
u_short iio; /* internal io-address */
u_char stdel; /* S/T delay compensation */
}
ihfc_pnp_ids[] =
{
{ 0x10262750, FLAG_TELES_S0_163C, HFC_S , 2, 0x200 , 0xd},
{ 0x20262750, FLAG_TELES_S0_163C, HFC_SP, 0, 0x000 , 0xf},
{ 0x1411d805, FLAG_ACER_P10 , HFC_S , 1, 0x300 , 0xe},
{ 0 }
};
typedef const struct ihfc_pnp_ids ihfc_id_t;
/*---------------------------------------------------------------------------*
* PCB layout
*
* IIRQx: Internal IRQ cross reference for a card
* IRQx : Supported IRQ's for a card
* IOx : Supported IO-bases for a card
*
* IO0, IRQ0, IIRQ0: TELEINT ISDN SPEED No. 1
* IIRQ3: Teles 16.3c PnP (B version)
*---------------------------------------------------------------------------*/
/* IRQ -> 0 1 2 3 4 5 6 7 8 9 a b c d e f */
#define IIRQ0 ((const u_char []){ 0, 0, 0, 1, 2, 3, 0, 4, 0, 0, 5, 6, 0, 0, 0, 0 })
#define IRQ0 ((const u_char []){ 3, 4, 5, 7, 0xa, 0xb, 0 })
#define IO0 ((const u_long []){ 0x300, 0x330, 0x278, 0x2e8, 0 })
#define IIRQ3 ((const u_char []){ 0, 0, 0, 7, 0, 1, 0, 0, 0, 2, 3, 4, 5, 0, 0, 6 })
/*---------------------------------------------------------------------------*
* ISA PnP setup
*---------------------------------------------------------------------------*/
static device_method_t ihfc_pnp_methods[] =
{
DEVMETHOD(device_probe, ihfc_pnp_probe),
DEVMETHOD(device_attach, ihfc_pnp_attach),
DEVMETHOD(device_shutdown, ihfc_pnp_shutdown),
{ 0, 0 }
};
static driver_t ihfc_pnp_driver =
{
"ihfc",
ihfc_pnp_methods,
0,
};
static devclass_t ihfc_devclass;
DRIVER_MODULE(ihfcpnp, isa, ihfc_pnp_driver, ihfc_devclass, 0, 0);
/*---------------------------------------------------------------------------*
* probe for ISA "PnP" card
*---------------------------------------------------------------------------*/
int
ihfc_pnp_probe(device_t dev)
{
u_int unit = device_get_unit(dev); /* get unit */
u_int32_t vid = isa_get_vendorid(dev); /* vendor id */
ihfc_id_t *ids = &ihfc_pnp_ids[0]; /* ids ptr */
ihfc_sc_t *sc = &ihfc_softc[unit]; /* softc */
HFC_VAR;
if (unit >= IHFC_MAXUNIT)
{
printf("ihfc%d: Error, unit %d >= IHFC_MAXUNIT", unit, unit);
return ENXIO;
}
if (!vid) return ihfc_isa_probe(dev);
HFC_BEG;
for ( ;(ids->vid); ids++)
{
if (ids->vid == vid)
{
bzero(sc, sizeof(ihfc_sc_t)); /* reset data structure */
S_IOBASE[0] = bus_alloc_resource(
dev, SYS_RES_IOPORT, &S_IORID[0],
0UL, ~0UL, 2, RF_ACTIVE
);
S_IRQ = bus_alloc_resource(
dev, SYS_RES_IRQ, &S_IRQRID,
0UL, ~0UL, 1, RF_ACTIVE
);
S_DLP = IHFC_DLP; /* set D-priority */
S_HFC = ids->hfc; /* set chip type */
S_I4BFLAG = ids->flag; /* set flag */
S_NTMODE = IHFC_NTMODE; /* set mode */
S_STDEL = ids->stdel; /* set delay */
S_I4BUNIT = L0IHFCUNIT(unit); /* set "i4b" unit */
S_TRACE = TRACE_OFF; /* set trace mask */
S_UNIT = unit; /* set up unit numbers */
if (S_IOBASE[0] && S_IRQ)
{
if (ids->iio)
{
S_IIO = ids->iio;
S_IIRQ = ids->iirq;
}
else
{
S_IIO = rman_get_start(S_IOBASE[0]) & 0x3ff;
S_IIRQ = IIRQ3[rman_get_start(S_IRQ) & 0xf];
}
if (!HFC_CONTROL(sc, 1))
{
HFC_END;
return 0; /* success */
}
else
{
printf("ihfc%d: Chip seems corrupted. "
"Please hard reboot your computer!\n",
unit);
}
}
ihfc_pnp_detach(dev, 0);
}
}
HFC_END;
return ENXIO; /* failure */
}
/*---------------------------------------------------------------------------*
* probe for "ISA" cards
*---------------------------------------------------------------------------*/
int
ihfc_isa_probe(device_t dev)
{
u_int unit = device_get_unit(dev); /* get unit */
ihfc_sc_t *sc = &ihfc_softc[unit]; /* softc */
const u_char *irq = &IRQ0[0]; /* irq's to try */
const u_long *iobase = &IO0[0]; /* iobases to try */
HFC_VAR;
bzero(sc, sizeof(ihfc_sc_t)); /* reset data structure *
* We must reset the *
* datastructure here, *
* else we risk zero-out *
* our gotten resources. */
HFC_BEG;
j0: while(*irq) /* get supported IRQ */
{
if ((S_IRQ = bus_alloc_resource(
dev, SYS_RES_IRQ, &S_IRQRID,
*irq, *irq, 1, RF_ACTIVE
)
))
break;
else
irq++;
}
while(*iobase) /* get supported IO-PORT */
{
if ((S_IOBASE[0] = bus_alloc_resource(
dev, SYS_RES_IOPORT, &S_IORID[0],
*iobase, *iobase, 2, RF_ACTIVE
)
))
break;
else
iobase++;
}
if (*irq && *iobase) /* we got our resources, now test chip */
{
S_DLP = IHFC_DLP; /* set D-priority */
S_HFC = HFC_1; /* set chip type */
S_I4BFLAG = FLAG_TELEINT_NO_1; /* set flag */
S_NTMODE = IHFC_NTMODE; /* set mode */
S_STDEL = 0x00; /* set delay (not used) */
S_I4BUNIT = L0IHFCUNIT(unit); /* set "i4b" unit */
S_TRACE = TRACE_OFF; /* set trace mask */
S_UNIT = unit; /* set up unit numbers */
S_IIRQ = IIRQ0[*irq]; /* set internal irq */
S_IIO = *iobase; /* set internal iobase */
if (!HFC_CONTROL(sc, 1))
{
device_set_desc(dev, "TELEINT ISDN SPEED No. 1");
HFC_END;
return 0; /* success */
}
}
ihfc_pnp_detach(dev, 0);
if (*irq && *++iobase) goto j0; /* try again */
HFC_END;
printf("ihfc%d: Chip not found. "
"A hard reboot may help!\n", unit);
return ENXIO; /* failure */
}
/*---------------------------------------------------------------------------*
* attach ISA "PnP" card
*---------------------------------------------------------------------------*/
int
ihfc_pnp_attach(device_t dev)
{
u_int unit = device_get_unit(dev); /* get unit */
ihfc_sc_t *sc = &ihfc_softc[unit]; /* softc */
void *dummy = 0; /* a dummy */
HFC_VAR;
HFC_BEG;
ihfc_B_linkinit(sc); /* Setup B-Channel linktabs */
i4b_l1_mph_status_ind(S_I4BUNIT, STI_ATTACH, S_I4BFLAG, &ihfc_l1mux_func);
HFC_INIT(sc, 0, 0, 1); /* Setup D - Channel */
HFC_INIT(sc, 2, 0, 0); /* Init B1 - Channel */
HFC_INIT(sc, 4, 0, 0); /* Init B2 - Channel */
bus_setup_intr(dev, S_IRQ, INTR_TYPE_NET, (void(*)(void*))
HFC_INTR, sc, &dummy);
HFC_END;
return 0; /* success */
HFC_END;
return ENXIO; /* failure */
}
/*---------------------------------------------------------------------------*
* shutdown for our ISA PnP card
*---------------------------------------------------------------------------*/
int
ihfc_pnp_shutdown(device_t dev)
{
u_int unit = device_get_unit(dev); /* get unit */
ihfc_sc_t *sc = &ihfc_softc[unit]; /* softc */
HFC_VAR;
HFC_BEG;
if (unit >= IHFC_MAXUNIT)
{
printf("ihfc%d: Error, unit %d >= IHFC_MAXUNIT", unit, unit);
goto f0;
}
HFC_CONTROL(sc, 2); /* shutdown chip */
HFC_END;
return 0;
f0:
HFC_END;
return ENXIO;
}
/*---------------------------------------------------------------------------*
* detach for our ISA PnP card
*
* flag: bit[0] set: teardown interrupt handler too
*---------------------------------------------------------------------------*/
int
ihfc_pnp_detach (device_t dev, u_int flag)
{
u_int unit = device_get_unit(dev); /* get unit */
ihfc_sc_t *sc = &ihfc_softc[unit]; /* softc */
u_char i;
if (unit >= IHFC_MAXUNIT)
{
printf("ihfc%d: Error, unit %d >= IHFC_MAXUNIT", unit, unit);
return 0;
}
/* free interrupt resources */
if(S_IRQ)
{
if (flag & 1)
{
/* tear down interrupt handler */
bus_teardown_intr(dev, S_IRQ, (void(*)(void *))HFC_INTR);
}
/* free irq */
bus_release_resource(dev, SYS_RES_IRQ, S_IRQRID, S_IRQ);
S_IRQRID = 0;
S_IRQ = 0;
}
/* free iobases */
for (i = IHFC_IO_BASES; i--;)
{
if(S_IOBASE[i])
{
bus_release_resource(dev, SYS_RES_IOPORT,
S_IORID[i], S_IOBASE[i]);
S_IORID[i] = 0;
S_IOBASE[i] = 0;
}
}
return 0;
}
#endif /* NIHFC > 0 */

View File

@ -1,836 +0,0 @@
/*
* Copyright (c) 1997, 1998 Martin Husemann. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* 4. Altered versions must be plainly marked as such, and must not be
* misrepresented as being the original software and/or documentation.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*---------------------------------------------------------------------------
*
* isa_isic.c - ISA bus frontend for i4b_isic driver
* --------------------------------------------------
*
* $FreeBSD$
*
* last edit-date: [Mon Jul 19 16:39:02 1999]
*
* -mh original implementation
* -hm NetBSD patches from Martin
*
*---------------------------------------------------------------------------*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/errno.h>
#include <sys/syslog.h>
#include <sys/device.h>
#include <sys/socket.h>
#include <net/if.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <machine/cpu.h>
#include <machine/intr.h>
#include <machine/bus.h>
#include <dev/isa/isavar.h>
#ifdef __FreeBSD__
#include <machine/i4b_ioctl.h>
#else
#include <i4b/i4b_ioctl.h>
#endif
#include <i4b/layer1/i4b_l1.h>
#if defined(__OpenBSD__)
#define __BROKEN_INDIRECT_CONFIG
#endif
/* local functions */
#ifdef __BROKEN_INDIRECT_CONFIG
static int isa_isic_probe __P((struct device *, void *, void *));
#else
static int isa_isic_probe __P((struct device *, struct cfdata *, void *));
#endif
static void isa_isic_attach __P((struct device *, struct device *, void *));
static int setup_io_map __P((int flags, bus_space_tag_t iot,
bus_space_tag_t memt, bus_size_t iobase, bus_size_t maddr,
int *num_mappings, struct isic_io_map *maps, int *iosize,
int *msize));
static void args_unmap __P((int *num_mappings, struct isic_io_map *maps));
struct cfattach isa_isic_ca = {
sizeof(struct isic_softc), isa_isic_probe, isa_isic_attach
};
/*
* Probe card
*/
static int
#ifdef __BROKEN_INDIRECT_CONFIG
isa_isic_probe(parent, match, aux)
#else
isa_isic_probe(parent, cf, aux)
#endif
struct device *parent;
#ifdef __BROKEN_INDIRECT_CONFIG
void *match;
#else
struct cfdata *cf;
#endif
void *aux;
{
#ifdef __BROKEN_INDIRECT_CONFIG
struct cfdata *cf = ((struct device*)match)->dv_cfdata;
#endif
struct isa_attach_args *ia = aux;
bus_space_tag_t memt = ia->ia_memt, iot = ia->ia_iot;
int flags = cf->cf_flags;
struct isic_attach_args args;
int ret = 0;
#if 0
printf("isic%d: enter isa_isic_probe\n", cf->cf_unit);
#endif
/* check irq */
if (ia->ia_irq == IRQUNK) {
printf("isic%d: config error: no IRQ specified\n", cf->cf_unit);
return 0;
}
/* setup MI attach args */
bzero(&args, sizeof(args));
args.ia_flags = flags;
/* if card type specified setup io map for that card */
switch(flags)
{
case FLAG_TELES_S0_8:
case FLAG_TELES_S0_16:
case FLAG_TELES_S0_163:
case FLAG_AVM_A1:
case FLAG_USR_ISDN_TA_INT:
case FLAG_ITK_IX1:
if (setup_io_map(flags, iot, memt, ia->ia_iobase, ia->ia_maddr,
&args.ia_num_mappings, &args.ia_maps[0],
&(ia->ia_iosize), &ia->ia_msize)) {
ret = 0;
goto done;
}
break;
default:
/* no io map now, will figure card type later */
break;
}
/* probe card */
switch(flags)
{
#ifdef DYNALINK
case FLAG_DYNALINK:
ret = isic_probe_Dyn(&args);
break;
#endif
#ifdef TEL_S0_8
case FLAG_TELES_S0_8:
ret = isic_probe_s08(&args);
break;
#endif
#ifdef TEL_S0_16
case FLAG_TELES_S0_16:
ret = isic_probe_s016(&args);
break;
#endif
#ifdef TEL_S0_16_3
case FLAG_TELES_S0_163:
ret = isic_probe_s0163(&args);
break;
#endif
#ifdef AVM_A1
case FLAG_AVM_A1:
ret = isic_probe_avma1(&args);
break;
#endif
#ifdef USR_STI
case FLAG_USR_ISDN_TA_INT:
ret = isic_probe_usrtai(&args);
break;
#endif
#ifdef ITKIX1
case FLAG_ITK_IX1:
ret = isic_probe_itkix1(&args);
break;
#endif
default:
/* No card type given, try to figure ... */
if (ia->ia_iobase == IOBASEUNK) {
ret = 0;
#ifdef TEL_S0_8
/* only Teles S0/8 will work without IO */
args.ia_flags = FLAG_TELES_S0_8;
if (setup_io_map(args.ia_flags, iot, memt, ia->ia_iobase, ia->ia_maddr,
&args.ia_num_mappings, &args.ia_maps[0],
&(ia->ia_iosize), &(ia->ia_msize)) == 0)
{
ret = isic_probe_s08(&args);
}
#endif /* TEL_S0_8 */
} else if (ia->ia_maddr == MADDRUNK) {
ret = 0;
#ifdef TEL_S0_16_3
/* no shared memory, only a 16.3 based card,
AVM A1, the usr sportster or an ITK would work */
args.ia_flags = FLAG_TELES_S0_163;
if (setup_io_map(args.ia_flags, iot, memt, ia->ia_iobase, ia->ia_maddr,
&args.ia_num_mappings, &args.ia_maps[0],
&(ia->ia_iosize), &(ia->ia_msize)) == 0)
{
ret = isic_probe_s0163(&args);
if (ret)
break;
}
#endif /* TEL_S0_16_3 */
#ifdef AVM_A1
args_unmap(&args.ia_num_mappings, &args.ia_maps[0]);
args.ia_flags = FLAG_AVM_A1;
if (setup_io_map(args.ia_flags, iot, memt, ia->ia_iobase, ia->ia_maddr,
&args.ia_num_mappings, &args.ia_maps[0],
&(ia->ia_iosize), &(ia->ia_msize)) == 0)
{
ret = isic_probe_avma1(&args);
if (ret)
break;
}
#endif /* AVM_A1 */
#ifdef USR_STI
args_unmap(&args.ia_num_mappings, &args.ia_maps[0]);
args.ia_flags = FLAG_USR_ISDN_TA_INT;
if (setup_io_map(args.ia_flags, iot, memt, ia->ia_iobase, ia->ia_maddr,
&args.ia_num_mappings, &args.ia_maps[0],
&(ia->ia_iosize), &(ia->ia_msize)) == 0)
{
ret = isic_probe_usrtai(&args);
if (ret)
break;
}
#endif /* USR_STI */
#ifdef ITKIX1
args_unmap(&args.ia_num_mappings, &args.ia_maps[0]);
args.ia_flags = FLAG_ITK_IX1;
if (setup_io_map(args.ia_flags, iot, memt, ia->ia_iobase, ia->ia_maddr,
&args.ia_num_mappings, &args.ia_maps[0],
&(ia->ia_iosize), &(ia->ia_msize)) == 0)
{
ret = isic_probe_itkix1(&args);
if (ret)
break;
}
#endif /* ITKIX1 */
} else {
#ifdef TEL_S0_16_3
/* could be anything */
args.ia_flags = FLAG_TELES_S0_163;
if (setup_io_map(args.ia_flags, iot, memt, ia->ia_iobase, ia->ia_maddr,
&args.ia_num_mappings, &args.ia_maps[0],
&(ia->ia_iosize), &(ia->ia_msize)) == 0)
{
ret = isic_probe_s0163(&args);
if (ret)
break;
}
#endif /* TEL_S0_16_3 */
#ifdef TEL_S0_16
args_unmap(&args.ia_num_mappings, &args.ia_maps[0]);
args.ia_flags = FLAG_TELES_S0_16;
if (setup_io_map(args.ia_flags, iot, memt, ia->ia_iobase, ia->ia_maddr,
&args.ia_num_mappings, &args.ia_maps[0],
&(ia->ia_iosize), &(ia->ia_msize)) == 0)
{
ret = isic_probe_s016(&args);
if (ret)
break;
}
#endif /* TEL_S0_16 */
#ifdef AVM_A1
args_unmap(&args.ia_num_mappings, &args.ia_maps[0]);
args.ia_flags = FLAG_AVM_A1;
if (setup_io_map(args.ia_flags, iot, memt, ia->ia_iobase, ia->ia_maddr,
&args.ia_num_mappings, &args.ia_maps[0],
&(ia->ia_iosize), &(ia->ia_msize)) == 0)
{
ret = isic_probe_avma1(&args);
if (ret)
break;
}
#endif /* AVM_A1 */
#ifdef TEL_S0_8
args_unmap(&args.ia_num_mappings, &args.ia_maps[0]);
args.ia_flags = FLAG_TELES_S0_8;
if (setup_io_map(args.ia_flags, iot, memt, ia->ia_iobase, ia->ia_maddr,
&args.ia_num_mappings, &args.ia_maps[0],
&(ia->ia_iosize), &(ia->ia_msize)) == 0)
{
ret = isic_probe_s08(&args);
}
#endif /* TEL_S0_8 */
}
break;
}
done:
/* unmap resources */
args_unmap(&args.ia_num_mappings, &args.ia_maps[0]);
#if 0
printf("isic%d: exit isa_isic_probe, return = %d\n", cf->cf_unit, ret);
#endif
return ret;
}
/*
* Attach the card
*/
static void
isa_isic_attach(parent, self, aux)
struct device *parent, *self;
void *aux;
{
struct isic_softc *sc = (void *)self;
struct isa_attach_args *ia = aux;
int flags = sc->sc_dev.dv_cfdata->cf_flags;
int ret = 0;
struct isic_attach_args args;
/* Setup parameters */
sc->sc_unit = sc->sc_dev.dv_unit;
sc->sc_irq = ia->ia_irq;
sc->sc_maddr = ia->ia_maddr;
sc->sc_num_mappings = 0;
sc->sc_maps = NULL;
switch(flags)
{
case FLAG_TELES_S0_8:
case FLAG_TELES_S0_16:
case FLAG_TELES_S0_163:
case FLAG_AVM_A1:
case FLAG_USR_ISDN_TA_INT:
setup_io_map(flags, ia->ia_iot, ia->ia_memt, ia->ia_iobase, ia->ia_maddr,
&(sc->sc_num_mappings), NULL, NULL, NULL);
MALLOC_MAPS(sc);
setup_io_map(flags, ia->ia_iot, ia->ia_memt, ia->ia_iobase, ia->ia_maddr,
&(sc->sc_num_mappings), &(sc->sc_maps[0]), NULL, NULL);
break;
default:
/* No card type given, try to figure ... */
/* setup MI attach args */
bzero(&args, sizeof(args));
args.ia_flags = flags;
/* Probe cards */
if (ia->ia_iobase == IOBASEUNK) {
ret = 0;
#ifdef TEL_S0_8
/* only Teles S0/8 will work without IO */
args.ia_flags = FLAG_TELES_S0_8;
setup_io_map(args.ia_flags, ia->ia_iot, ia->ia_memt, ia->ia_iobase, ia->ia_maddr,
&args.ia_num_mappings, &args.ia_maps[0], NULL, NULL);
ret = isic_probe_s08(&args);
if (ret)
goto found;
args_unmap(&args.ia_num_mappings, &args.ia_maps[0]);
#endif /* TEL_S0_8 */
} else if (ia->ia_maddr == MADDRUNK) {
/* no shared memory, only a 16.3 based card,
AVM A1, the usr sportster or an ITK would work */
ret = 0;
#ifdef TEL_S0_16_3
args.ia_flags = FLAG_TELES_S0_163;
setup_io_map(args.ia_flags, ia->ia_iot, ia->ia_memt, ia->ia_iobase, ia->ia_maddr,
&args.ia_num_mappings, &args.ia_maps[0], NULL, NULL);
ret = isic_probe_s0163(&args);
if (ret)
goto found;
args_unmap(&args.ia_num_mappings, &args.ia_maps[0]);
#endif /* TEL_S0_16_3 */
#ifdef AVM_A1
args.ia_flags = FLAG_AVM_A1;
setup_io_map(args.ia_flags, ia->ia_iot, ia->ia_memt, ia->ia_iobase, ia->ia_maddr,
&args.ia_num_mappings, &args.ia_maps[0], NULL, NULL);
ret = isic_probe_avma1(&args);
if (ret)
goto found;
args_unmap(&args.ia_num_mappings, &args.ia_maps[0]);
#endif /* AVM_A1 */
#ifdef USR_STI
args.ia_flags = FLAG_USR_ISDN_TA_INT;
setup_io_map(args.ia_flags, ia->ia_iot, ia->ia_memt, ia->ia_iobase, ia->ia_maddr,
&args.ia_num_mappings, &args.ia_maps[0], NULL, NULL);
ret = isic_probe_usrtai(&args);
if (ret)
goto found;
args_unmap(&args.ia_num_mappings, &args.ia_maps[0]);
#endif /* USR_STI */
#ifdef ITKIX1
args.ia_flags = FLAG_ITK_IX1;
setup_io_map(args.ia_flags, ia->ia_iot, ia->ia_memt, ia->ia_iobase, ia->ia_maddr,
&args.ia_num_mappings, &args.ia_maps[0], NULL, NULL);
ret = isic_probe_itkix1(&args);
if (ret)
goto found;
args_unmap(&args.ia_num_mappings, &args.ia_maps[0]);
#endif /* ITKIX1 */
} else {
/* could be anything */
ret = 0;
#ifdef TEL_S0_16_3
args.ia_flags = FLAG_TELES_S0_163;
setup_io_map(args.ia_flags, ia->ia_iot, ia->ia_memt, ia->ia_iobase, ia->ia_maddr,
&args.ia_num_mappings, &args.ia_maps[0], NULL, NULL);
ret = isic_probe_s0163(&args);
if (ret)
goto found;
args_unmap(&args.ia_num_mappings, &args.ia_maps[0]);
#endif /* TEL_S0_16_3 */
#ifdef TEL_S0_16
args.ia_flags = FLAG_TELES_S0_16;
setup_io_map(args.ia_flags, ia->ia_iot, ia->ia_memt, ia->ia_iobase, ia->ia_maddr,
&args.ia_num_mappings, &args.ia_maps[0], NULL, NULL);
ret = isic_probe_s016(&args);
if (ret)
goto found;
args_unmap(&args.ia_num_mappings, &args.ia_maps[0]);
#endif /* TEL_S0_16 */
#ifdef AVM_A1
args.ia_flags = FLAG_AVM_A1;
setup_io_map(args.ia_flags, ia->ia_iot, ia->ia_memt, ia->ia_iobase, ia->ia_maddr,
&args.ia_num_mappings, &args.ia_maps[0], NULL, NULL);
ret = isic_probe_avma1(&args);
if (ret)
goto found;
args_unmap(&args.ia_num_mappings, &args.ia_maps[0]);
#endif /* AVM_A1 */
#ifdef TEL_S0_8
args.ia_flags = FLAG_TELES_S0_8;
setup_io_map(args.ia_flags, ia->ia_iot, ia->ia_memt, ia->ia_iobase, ia->ia_maddr,
&args.ia_num_mappings, &args.ia_maps[0], NULL, NULL);
ret = isic_probe_s08(&args);
if (ret)
goto found;
args_unmap(&args.ia_num_mappings, &args.ia_maps[0]);
#endif /* TEL_S0_8 */
}
break;
found:
flags = args.ia_flags;
sc->sc_num_mappings = args.ia_num_mappings;
args_unmap(&args.ia_num_mappings, &args.ia_maps[0]);
if (ret) {
MALLOC_MAPS(sc);
setup_io_map(flags, ia->ia_iot, ia->ia_memt, ia->ia_iobase, ia->ia_maddr,
&(sc->sc_num_mappings), &(sc->sc_maps[0]), NULL, NULL);
} else {
printf(": could not determine card type - not configured!\n");
return;
}
break;
}
#if defined(__OpenBSD__)
isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE,
IPL_NET, isicintr, sc, sc->sc_dev.dv_xname);
/* MI initialization of card */
isicattach(flags, sc);
#else
/* MI initialization of card */
isicattach(flags, sc);
/*
* Try to get a level-triggered interrupt first. If that doesn't
* work (like on NetBSD/Atari, try to establish an edge triggered
* interrupt.
*/
if (isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_LEVEL,
IPL_NET, isicintr, sc) == NULL) {
if(isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE,
IPL_NET, isicintr, sc) == NULL) {
args_unmap(&(sc->sc_num_mappings), &(sc->sc_maps[0]));
free((sc)->sc_maps, M_DEVBUF);
}
else {
/*
* XXX: This is a hack that probably needs to be
* solved by setting an interrupt type in the sc
* structure. I don't feel familiar enough with the
* code to do this currently. Feel free to contact
* me about it (leo@netbsd.org).
*/
isicintr(sc);
}
}
#endif
}
/*
* Setup card specific io mapping. Return 0 on success,
* any other value on config error.
* Be prepared to get NULL as maps array.
* Make sure to keep *num_mappings in sync with the real
* mappings already setup when returning!
*/
static int
setup_io_map(flags, iot, memt, iobase, maddr, num_mappings, maps, iosize, msize)
int flags, *num_mappings, *iosize, *msize;
bus_size_t iobase, maddr;
bus_space_tag_t iot, memt;
struct isic_io_map *maps;
{
/* nothing mapped yet */
*num_mappings = 0;
/* which resources do we need? */
switch(flags)
{
case FLAG_TELES_S0_8:
if (maddr == MADDRUNK) {
printf("isic: config error: no shared memory specified for Teles S0/8!\n");
return 1;
}
if (iosize) *iosize = 0; /* no i/o ports */
if (msize) *msize = 0x1000; /* shared memory size */
/* this card uses a single memory mapping */
if (maps == NULL) {
*num_mappings = 1;
return 0;
}
*num_mappings = 0;
maps[0].t = memt;
maps[0].offset = 0;
maps[0].size = 0x1000;
if (bus_space_map(maps[0].t, maddr,
maps[0].size, 0, &maps[0].h)) {
return 1;
}
(*num_mappings)++;
break;
case FLAG_TELES_S0_16:
if (iobase == IOBASEUNK) {
printf("isic: config error: no i/o address specified for Teles S0/16!\n");
return 1;
}
if (maddr == MADDRUNK) {
printf("isic: config error: no shared memory specified for Teles S0/16!\n");
return 1;
}
if (iosize) *iosize = 8; /* i/o ports */
if (msize) *msize = 0x1000; /* shared memory size */
/* one io and one memory mapping */
if (maps == NULL) {
*num_mappings = 2;
return 0;
}
*num_mappings = 0;
maps[0].t = iot;
maps[0].offset = 0;
maps[0].size = 8;
if (bus_space_map(maps[0].t, iobase,
maps[0].size, 0, &maps[0].h)) {
return 1;
}
(*num_mappings)++;
maps[1].t = memt;
maps[1].offset = 0;
maps[1].size = 0x1000;
if (bus_space_map(maps[1].t, maddr,
maps[1].size, 0, &maps[1].h)) {
return 1;
}
(*num_mappings)++;
break;
case FLAG_TELES_S0_163:
if (iobase == IOBASEUNK) {
printf("isic: config error: no i/o address specified for Teles S0/16!\n");
return 1;
}
if (iosize) *iosize = 8; /* only some i/o ports shown */
if (msize) *msize = 0; /* no shared memory */
/* Four io mappings: config, isac, 2 * hscx */
if (maps == NULL) {
*num_mappings = 4;
return 0;
}
*num_mappings = 0;
maps[0].t = iot;
maps[0].offset = 0;
maps[0].size = 8;
if (bus_space_map(maps[0].t, iobase,
maps[0].size, 0, &maps[0].h)) {
return 1;
}
(*num_mappings)++;
maps[1].t = iot;
maps[1].offset = 0;
maps[1].size = 0x40; /* XXX - ??? */
if ((iobase - 0xd80 + 0x980) < 0 || (iobase - 0xd80 + 0x980) > 0x0ffff)
return 1;
if (bus_space_map(maps[1].t, iobase - 0xd80 + 0x980,
maps[1].size, 0, &maps[1].h)) {
return 1;
}
(*num_mappings)++;
maps[2].t = iot;
maps[2].offset = 0;
maps[2].size = 0x40; /* XXX - ??? */
if ((iobase - 0xd80 + 0x180) < 0 || (iobase - 0xd80 + 0x180) > 0x0ffff)
return 1;
if (bus_space_map(maps[2].t, iobase - 0xd80 + 0x180,
maps[2].size, 0, &maps[2].h)) {
return 1;
}
(*num_mappings)++;
maps[3].t = iot;
maps[3].offset = 0;
maps[3].size = 0x40; /* XXX - ??? */
if ((iobase - 0xd80 + 0x580) < 0 || (iobase - 0xd80 + 0x580) > 0x0ffff)
return 1;
if (bus_space_map(maps[3].t, iobase - 0xd80 + 0x580,
maps[3].size, 0, &maps[3].h)) {
return 1;
}
(*num_mappings)++;
break;
case FLAG_AVM_A1:
if (iobase == IOBASEUNK) {
printf("isic: config error: no i/o address specified for AVM A1/Fritz! card!\n");
return 1;
}
if (iosize) *iosize = 8; /* only some i/o ports shown */
if (msize) *msize = 0; /* no shared memory */
/* Seven io mappings: config, isac, 2 * hscx,
isac-fifo, 2 * hscx-fifo */
if (maps == NULL) {
*num_mappings = 7;
return 0;
}
*num_mappings = 0;
maps[0].t = iot; /* config */
maps[0].offset = 0;
maps[0].size = 8;
if ((iobase + 0x1800) < 0 || (iobase + 0x1800) > 0x0ffff)
return 1;
if (bus_space_map(maps[0].t, iobase + 0x1800, maps[0].size, 0, &maps[0].h))
return 1;
(*num_mappings)++;
maps[1].t = iot; /* isac */
maps[1].offset = 0;
maps[1].size = 0x80; /* XXX - ??? */
if ((iobase + 0x1400 - 0x20) < 0 || (iobase + 0x1400 - 0x20) > 0x0ffff)
return 1;
if (bus_space_map(maps[1].t, iobase + 0x1400 - 0x20, maps[1].size, 0, &maps[1].h))
return 1;
(*num_mappings)++;
maps[2].t = iot; /* hscx 0 */
maps[2].offset = 0;
maps[2].size = 0x40; /* XXX - ??? */
if ((iobase + 0x400 - 0x20) < 0 || (iobase + 0x400 - 0x20) > 0x0ffff)
return 1;
if (bus_space_map(maps[2].t, iobase + 0x400 - 0x20, maps[2].size, 0, &maps[2].h))
return 1;
(*num_mappings)++;
maps[3].t = iot; /* hscx 1 */
maps[3].offset = 0;
maps[3].size = 0x40; /* XXX - ??? */
if ((iobase + 0xc00 - 0x20) < 0 || (iobase + 0xc00 - 0x20) > 0x0ffff)
return 1;
if (bus_space_map(maps[3].t, iobase + 0xc00 - 0x20, maps[3].size, 0, &maps[3].h))
return 1;
(*num_mappings)++;
maps[4].t = iot; /* isac-fifo */
maps[4].offset = 0;
maps[4].size = 1;
if ((iobase + 0x1400 - 0x20 -0x3e0) < 0 || (iobase + 0x1400 - 0x20 -0x3e0) > 0x0ffff)
return 1;
if (bus_space_map(maps[4].t, iobase + 0x1400 - 0x20 -0x3e0, maps[4].size, 0, &maps[4].h))
return 1;
(*num_mappings)++;
maps[5].t = iot; /* hscx 0 fifo */
maps[5].offset = 0;
maps[5].size = 1;
if ((iobase + 0x400 - 0x20 -0x3e0) < 0 || (iobase + 0x400 - 0x20 -0x3e0) > 0x0ffff)
return 1;
if (bus_space_map(maps[5].t, iobase + 0x400 - 0x20 -0x3e0, maps[5].size, 0, &maps[5].h))
return 1;
(*num_mappings)++;
maps[6].t = iot; /* hscx 1 fifo */
maps[6].offset = 0;
maps[6].size = 1;
if ((iobase + 0xc00 - 0x20 -0x3e0) < 0 || (iobase + 0xc00 - 0x20 -0x3e0) > 0x0ffff)
return 1;
if (bus_space_map(maps[6].t, iobase + 0xc00 - 0x20 -0x3e0, maps[6].size, 0, &maps[6].h))
return 1;
(*num_mappings)++;
break;
case FLAG_USR_ISDN_TA_INT:
if (iobase == IOBASEUNK) {
printf("isic: config error: no I/O base specified for USR Sportster TA intern!\n");
return 1;
}
if (iosize) *iosize = 8; /* scattered ports, only some shown */
if (msize) *msize = 0; /* no shared memory */
/* 49 io mappings: 1 config and 48x8 registers */
if (maps == NULL) {
*num_mappings = 49;
return 0;
}
*num_mappings = 0;
{
int i, num;
bus_size_t base;
/* config at offset 0x8000 */
base = iobase + 0x8000;
maps[0].size = 1;
maps[0].t = iot;
maps[0].offset = 0;
if (base < 0 || base > 0x0ffff)
return 1;
if (bus_space_map(iot, base, 1, 0, &maps[0].h)) {
return 1;
}
*num_mappings = num = 1;
/* HSCX A at offset 0 */
base = iobase;
for (i = 0; i < 16; i++) {
maps[num].size = 8;
maps[num].offset = 0;
maps[num].t = iot;
if (base+i*1024 < 0 || base+i*1024+8 > 0x0ffff)
return 1;
if (bus_space_map(iot, base+i*1024, 8, 0, &maps[num].h)) {
return 1;
}
*num_mappings = ++num;
}
/* HSCX B at offset 0x4000 */
base = iobase + 0x4000;
for (i = 0; i < 16; i++) {
maps[num].size = 8;
maps[num].offset = 0;
maps[num].t = iot;
if (base+i*1024 < 0 || base+i*1024+8 > 0x0ffff)
return 1;
if (bus_space_map(iot, base+i*1024, 8, 0, &maps[num].h)) {
return 1;
}
*num_mappings = ++num;
}
/* ISAC at offset 0xc000 */
base = iobase + 0xc000;
for (i = 0; i < 16; i++) {
maps[num].size = 8;
maps[num].offset = 0;
maps[num].t = iot;
if (base+i*1024 < 0 || base+i*1024+8 > 0x0ffff)
return 1;
if (bus_space_map(iot, base+i*1024, 8, 0, &maps[num].h)) {
return 1;
}
*num_mappings = ++num;
}
}
break;
case FLAG_ITK_IX1:
if (iobase == IOBASEUNK) {
printf("isic: config error: no I/O base specified for ITK ix1 micro!\n");
return 1;
}
if (iosize) *iosize = 4;
if (msize) *msize = 0;
if (maps == NULL) {
*num_mappings = 1;
return 0;
}
*num_mappings = 0;
maps[0].size = 4;
maps[0].t = iot;
maps[0].offset = 0;
if (bus_space_map(iot, iobase, 4, 0, &maps[0].h)) {
return 1;
}
*num_mappings = 1;
break;
default:
printf("isic: config error: flags do not specify any known card!\n");
return 1;
break;
}
return 0;
}
static void
args_unmap(num_mappings, maps)
int *num_mappings;
struct isic_io_map *maps;
{
int i, n;
for (i = 0, n = *num_mappings; i < n; i++)
if (maps[i].size)
bus_space_unmap(maps[i].t, maps[i].h, maps[i].size);
*num_mappings = 0;
}

View File

@ -1,394 +0,0 @@
/*
* Copyright (c) 1997, 1998 Martin Husemann. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* 4. Altered versions must be plainly marked as such, and must not be
* misrepresented as being the original software and/or documentation.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*---------------------------------------------------------------------------
*
* isapnp_isic.c - ISA-P&P bus frontend for i4b_isic driver
* --------------------------------------------------------
*
* $FreeBSD$
*
* last edit-date: [Sun May 2 11:57:08 1999]
*
* -mh original implementation
* -hm NetBSD patches from Martin
*
*---------------------------------------------------------------------------*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/errno.h>
#include <sys/syslog.h>
#include <sys/device.h>
#include <sys/socket.h>
#include <net/if.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <machine/cpu.h>
#include <machine/intr.h>
#include <machine/bus.h>
#include <dev/isa/isavar.h>
#include <dev/isapnp/isapnpreg.h>
#include <dev/isapnp/isapnpvar.h>
#ifdef __FreeBSD__
#include <machine/i4b_ioctl.h>
#include <machine/i4b_trace.h>
#else
#include <i4b/i4b_ioctl.h>
#include <i4b/i4b_trace.h>
#endif
#include <i4b/layer1/i4b_l1.h>
#include <i4b/layer1/i4b_ipac.h>
#include <i4b/layer1/i4b_isac.h>
#include <i4b/layer1/i4b_hscx.h>
#include <i4b/include/i4b_l1l2.h>
#include <i4b/include/i4b_global.h>
#ifdef __BROKEN_INDIRECT_CONFIG
static int isapnp_isic_probe __P((struct device *, void *, void *));
#else
static int isapnp_isic_probe __P((struct device *, struct cfdata *, void *));
#endif
static void isapnp_isic_attach __P((struct device *, struct device *, void *));
struct cfattach isapnp_isic_ca = {
sizeof(struct isic_softc), isapnp_isic_probe, isapnp_isic_attach
};
typedef void (*allocmaps_func)(struct isapnp_attach_args *ipa, struct isic_softc *sc);
typedef void (*attach_func)(struct isic_softc *sc);
/* map allocators */
static void generic_pnp_mapalloc(struct isapnp_attach_args *ipa, struct isic_softc *sc);
#ifdef DRN_NGO
static void ngo_pnp_mapalloc(struct isapnp_attach_args *ipa, struct isic_softc *sc);
#endif
#if defined(CRTX_S0_P) || defined(TEL_S0_16_3_P)
static void tls_pnp_mapalloc(struct isapnp_attach_args *ipa, struct isic_softc *sc);
#endif
/* card attach functions */
extern void isic_attach_Cs0P __P((struct isic_softc *sc));
extern void isic_attach_Dyn __P((struct isic_softc *sc));
extern void isic_attach_s0163P __P((struct isic_softc *sc));
extern void isic_attach_drnngo __P((struct isic_softc *sc));
extern void isic_attach_sws __P((struct isic_softc *sc));
extern void isic_attach_Eqs1pi __P((struct isic_softc *sc));
struct isapnp_isic_card_desc {
char *devlogic; /* ISAPNP logical device ID */
char *name; /* Name of the card */
int card_type; /* isic card type identifier */
allocmaps_func allocmaps; /* map allocator function */
attach_func attach; /* card attach and init function */
};
static const struct isapnp_isic_card_desc
isapnp_isic_descriptions[] =
{
#ifdef CRTX_S0_P
{ "CTX0000", "Creatix ISDN S0-16 P&P", CARD_TYPEP_CS0P,
tls_pnp_mapalloc, isic_attach_Cs0P },
#endif
#ifdef TEL_S0_16_3_P
{ "TAG2110", "Teles S0/PnP", CARD_TYPEP_163P,
tls_pnp_mapalloc, isic_attach_s0163P },
#endif
#ifdef DRN_NGO
{ "SDA0150", "Dr. Neuhaus NICCY GO@", CARD_TYPEP_DRNNGO,
ngo_pnp_mapalloc, isic_attach_drnngo },
#endif
#ifdef ELSA_QS1ISA
{ "ELS0133", "Elsa QuickStep 1000 (ISA)", CARD_TYPEP_ELSAQS1ISA,
generic_pnp_mapalloc, isic_attach_Eqs1pi },
#endif
#ifdef SEDLBAUER
{ "SAG0001", "Sedlbauer WinSpeed", CARD_TYPEP_SWS,
generic_pnp_mapalloc, isic_attach_sws },
#endif
#ifdef DYNALINK
{ "ASU1688", "Dynalink IS64PH", CARD_TYPEP_DYNALINK,
generic_pnp_mapalloc, isic_attach_Dyn },
#endif
};
#define NUM_DESCRIPTIONS (sizeof(isapnp_isic_descriptions)/sizeof(isapnp_isic_descriptions[0]))
/*
* Probe card
*/
static int
#ifdef __BROKEN_INDIRECT_CONFIG
isapnp_isic_probe(parent, match, aux)
#else
isapnp_isic_probe(parent, cf, aux)
#endif
struct device *parent;
#ifdef __BROKEN_INDIRECT_CONFIG
void *match;
#else
struct cfdata *cf;
#endif
void *aux;
{
struct isapnp_attach_args *ipa = aux;
const struct isapnp_isic_card_desc *desc = isapnp_isic_descriptions;
int i;
for (i = 0; i < NUM_DESCRIPTIONS; i++, desc++)
if (strcmp(ipa->ipa_devlogic, desc->devlogic) == 0)
return 1;
return 0;
}
/*---------------------------------------------------------------------------*
* card independend attach for ISA P&P cards
*---------------------------------------------------------------------------*/
/* parameter and format for message producing e.g. "isic0: " */
#ifdef __FreeBSD__
#define ISIC_FMT "isic%d: "
#define ISIC_PARM dev->id_unit
#define TERMFMT " "
#else
#define ISIC_FMT "%s: "
#define ISIC_PARM sc->sc_dev.dv_xname
#define TERMFMT "\n"
#endif
static void
isapnp_isic_attach(parent, self, aux)
struct device *parent, *self;
void *aux;
{
static char *ISACversion[] = {
"2085 Version A1/A2 or 2086/2186 Version 1.1",
"2085 Version B1",
"2085 Version B2",
"2085 Version V2.3 (B3)",
"Unknown Version"
};
static char *HSCXversion[] = {
"82525 Version A1",
"Unknown (0x01)",
"82525 Version A2",
"Unknown (0x03)",
"82525 Version A3",
"82525 or 21525 Version 2.1",
"Unknown Version"
};
struct isic_softc *sc = (void *)self;
struct isapnp_attach_args *ipa = aux;
const struct isapnp_isic_card_desc *desc = isapnp_isic_descriptions;
int i;
for (i = 0; i < NUM_DESCRIPTIONS; i++, desc++)
if (strcmp(ipa->ipa_devlogic, desc->devlogic) == 0)
break;
if (i >= NUM_DESCRIPTIONS)
panic("could not identify isic PnP device");
/* setup parameters */
sc->sc_cardtyp = desc->card_type;
sc->sc_unit = sc->sc_dev.dv_unit;
sc->sc_irq = ipa->ipa_irq[0].num;
desc->allocmaps(ipa, sc);
/* announce card name */
printf(": %s\n", desc->name);
/* establish interrupt handler */
isa_intr_establish(ipa->ipa_ic, ipa->ipa_irq[0].num, IST_EDGE,
IPL_NET, isicintr, sc);
/* init card */
isic_sc[sc->sc_unit] = sc;
desc->attach(sc);
/* announce chip versions */
sc->sc_isac_version = 0;
sc->sc_isac_version = ((ISAC_READ(I_RBCH)) >> 5) & 0x03;
switch(sc->sc_isac_version)
{
case ISAC_VA:
case ISAC_VB1:
case ISAC_VB2:
case ISAC_VB3:
break;
default:
printf(ISIC_FMT "Error, ISAC version %d unknown!\n",
ISIC_PARM, sc->sc_isac_version);
return;
break;
}
sc->sc_hscx_version = HSCX_READ(0, H_VSTR) & 0xf;
switch(sc->sc_hscx_version)
{
case HSCX_VA1:
case HSCX_VA2:
case HSCX_VA3:
case HSCX_V21:
break;
default:
printf(ISIC_FMT "Error, HSCX version %d unknown!\n",
ISIC_PARM, sc->sc_hscx_version);
return;
break;
};
/* ISAC setup */
isic_isac_init(sc);
/* HSCX setup */
isic_bchannel_setup(sc->sc_unit, HSCX_CH_A, BPROT_NONE, 0);
isic_bchannel_setup(sc->sc_unit, HSCX_CH_B, BPROT_NONE, 0);
/* setup linktab */
isic_init_linktab(sc);
/* set trace level */
sc->sc_trace = TRACE_OFF;
sc->sc_state = ISAC_IDLE;
sc->sc_ibuf = NULL;
sc->sc_ib = NULL;
sc->sc_ilen = 0;
sc->sc_obuf = NULL;
sc->sc_op = NULL;
sc->sc_ol = 0;
sc->sc_freeflag = 0;
sc->sc_obuf2 = NULL;
sc->sc_freeflag2 = 0;
/* init higher protocol layers */
MPH_Status_Ind(sc->sc_unit, STI_ATTACH, sc->sc_cardtyp);
/* announce chip versions */
if(sc->sc_isac_version >= ISAC_UNKN)
{
printf(ISIC_FMT "ISAC Version UNKNOWN (VN=0x%x)" TERMFMT,
ISIC_PARM,
sc->sc_isac_version);
sc->sc_isac_version = ISAC_UNKN;
}
else
{
printf(ISIC_FMT "ISAC %s (IOM-%c)" TERMFMT,
ISIC_PARM,
ISACversion[sc->sc_isac_version],
sc->sc_bustyp == BUS_TYPE_IOM1 ? '1' : '2');
}
if(sc->sc_hscx_version >= HSCX_UNKN)
{
printf(ISIC_FMT "HSCX Version UNKNOWN (VN=0x%x)" TERMFMT,
ISIC_PARM,
sc->sc_hscx_version);
sc->sc_hscx_version = HSCX_UNKN;
}
else
{
printf(ISIC_FMT "HSCX %s" TERMFMT,
ISIC_PARM,
HSCXversion[sc->sc_hscx_version]);
}
}
static void
generic_pnp_mapalloc(struct isapnp_attach_args *ipa, struct isic_softc *sc)
{
sc->sc_num_mappings = 1; /* most cards have just one mapping */
MALLOC_MAPS(sc); /* malloc the maps */
sc->sc_maps[0].t = ipa->ipa_iot; /* copy the access handles */
sc->sc_maps[0].h = ipa->ipa_io[0].h;
sc->sc_maps[0].size = 0; /* foreign mapping, leave it alone */
}
#ifdef DRN_NGO
static void
ngo_pnp_mapalloc(struct isapnp_attach_args *ipa, struct isic_softc *sc)
{
sc->sc_num_mappings = 2; /* one data, one address mapping */
MALLOC_MAPS(sc); /* malloc the maps */
sc->sc_maps[0].t = ipa->ipa_iot; /* copy the access handles */
sc->sc_maps[0].h = ipa->ipa_io[0].h;
sc->sc_maps[0].size = 0; /* foreign mapping, leave it alone */
sc->sc_maps[1].t = ipa->ipa_iot;
sc->sc_maps[1].h = ipa->ipa_io[1].h;
sc->sc_maps[1].size = 0;
}
#endif
#if defined(CRTX_S0_P) || defined(TEL_S0_16_3_P)
static void
tls_pnp_mapalloc(struct isapnp_attach_args *ipa, struct isic_softc *sc)
{
sc->sc_num_mappings = 4; /* config, isac, 2 * hscx */
MALLOC_MAPS(sc); /* malloc the maps */
sc->sc_maps[0].t = ipa->ipa_iot; /* copy the access handles */
sc->sc_maps[0].h = ipa->ipa_io[0].h;
sc->sc_maps[0].size = 0; /* foreign mapping, leave it alone */
sc->sc_maps[1].t = ipa->ipa_iot;
sc->sc_maps[1].h = ipa->ipa_io[0].h;
sc->sc_maps[1].size = 0;
sc->sc_maps[1].offset = - 0x20;
sc->sc_maps[2].t = ipa->ipa_iot;
sc->sc_maps[2].offset = - 0x20;
sc->sc_maps[2].h = ipa->ipa_io[1].h;
sc->sc_maps[2].size = 0;
sc->sc_maps[3].t = ipa->ipa_iot;
sc->sc_maps[3].offset = 0;
sc->sc_maps[3].h = ipa->ipa_io[1].h;
sc->sc_maps[3].size = 0;
}
#endif

View File

@ -1,6 +1,7 @@
/*
* Copyright (c) 1999 Ari Suutari. All rights reserved.
* Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved.
*
* Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -39,11 +40,11 @@
* code is modeled after Linux i4l driver written by Karsten
* Keil.
*
* $Id: i4b_asuscom_ipac.c,v 1.4 1999/12/13 21:25:26 hm Exp $
* $Id: i4b_asuscom_ipac.c,v 1.3 2000/05/29 15:41:41 hm Exp $
*
* $FreeBSD$
*
* last edit-date: [Mon Dec 13 21:58:27 1999]
* last edit-date: [Mon May 29 16:41:56 2000]
*
*---------------------------------------------------------------------------*/
@ -53,7 +54,6 @@
#if (NISIC > 0) && defined (ASUSCOM_IPAC)
#include <sys/param.h>
#include <sys/ioccom.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
@ -67,13 +67,13 @@
#include <machine/i4b_ioctl.h>
#include <i4b/include/i4b_global.h>
#include <i4b/include/i4b_l1l2.h>
/* #include <i4b/include/i4b_l1l2.h> */
#include <i4b/include/i4b_mbuf.h>
#include <i4b/layer1/i4b_l1.h>
#include <i4b/layer1/i4b_ipac.h>
#include <i4b/layer1/i4b_isac.h>
#include <i4b/layer1/i4b_hscx.h>
#include <i4b/layer1/isic/i4b_isic.h>
#include <i4b/layer1/isic/i4b_ipac.h>
#include <i4b/layer1/isic/i4b_isac.h>
#include <i4b/layer1/isic/i4b_hscx.h>
/* masks for register encoded in base addr */

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 1996 Andrew Gordon. All rights reserved.
*
* Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved.
* Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -35,11 +35,11 @@
* i4b_avm_a1.c - AVM A1/Fritz passive card driver for isdn4bsd
* ------------------------------------------------------------
*
* $Id: i4b_avm_a1.c,v 1.2 1999/12/13 21:25:26 hm Exp $
* $Id: i4b_avm_a1.c,v 1.3 2000/05/29 15:41:41 hm Exp $
*
* $FreeBSD$
*
* last edit-date: [Mon Dec 13 21:58:36 1999]
* last edit-date: [Mon May 29 16:42:06 2000]
*
*---------------------------------------------------------------------------*/
@ -49,6 +49,7 @@
#if NISIC > 0 && defined(AVM_A1)
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
@ -62,9 +63,9 @@
#include <i4b/include/i4b_global.h>
#include <i4b/layer1/i4b_l1.h>
#include <i4b/layer1/i4b_isac.h>
#include <i4b/layer1/i4b_hscx.h>
#include <i4b/layer1/isic/i4b_isic.h>
#include <i4b/layer1/isic/i4b_isac.h>
#include <i4b/layer1/isic/i4b_hscx.h>
/*---------------------------------------------------------------------------*
* AVM A1 and AVM Fritz! Card special registers

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved.
* Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -27,11 +27,11 @@
* i4b_bchan.c - B channel handling L1 procedures
* ----------------------------------------------
*
* $Id: i4b_bchan.c,v 1.2 1999/12/13 21:25:26 hm Exp $
* $Id: i4b_bchan.c,v 1.6 2000/05/29 15:41:41 hm Exp $
*
* $FreeBSD$
*
* last edit-date: [Mon Dec 13 21:59:11 1999]
* last edit-date: [Mon May 29 16:42:26 2000]
*
*---------------------------------------------------------------------------*/
@ -40,6 +40,7 @@
#if NISIC > 0
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <machine/stdarg.h>
@ -54,17 +55,16 @@
#include <machine/i4b_trace.h>
#include <i4b/layer1/i4b_l1.h>
#include <i4b/layer1/i4b_isac.h>
#include <i4b/layer1/i4b_hscx.h>
#include <i4b/include/i4b_l1l2.h>
#include <i4b/layer1/isic/i4b_isic.h>
#include <i4b/layer1/isic/i4b_isac.h>
#include <i4b/layer1/isic/i4b_hscx.h>
#include <i4b/include/i4b_mbuf.h>
#include <i4b/include/i4b_global.h>
static void isic_bchannel_start(int unit, int h_chan);
static void isic_bchannel_stat(int unit, int h_chan, bchan_statistics_t *bsp);
static void isic_set_linktab(int unit, int channel, drvr_link_t *dlt);
static isdn_link_t *isic_ret_linktab(int unit, int channel);
/*---------------------------------------------------------------------------*
* initialize one B channels rx/tx data structures and init/deinit HSCX
@ -83,8 +83,8 @@ isic_bchannel_setup(int unit, int h_chan, int bprot, int activate)
isic_hscx_init(sc, h_chan, activate);
}
DBGL1(L1_BCHAN, "isic_bchannel_setup", ("unit=%d, channel=%d, %s\n",
sc->sc_unit, h_chan, activate ? "activate" : "deactivate"));
NDBGL1(L1_BCHAN, "unit=%d, channel=%d, %s",
sc->sc_unit, h_chan, activate ? "activate" : "deactivate");
/* general part */
@ -173,7 +173,7 @@ isic_bchannel_start(int unit, int h_chan)
if(chan->bprot == BPROT_NONE)
{
if(!(isic_hscx_silence(chan->out_mbuf_cur->m_data, chan->out_mbuf_cur->m_len)))
if(!(i4b_l1_bchan_tel_silence(chan->out_mbuf_cur->m_data, chan->out_mbuf_cur->m_len)))
activity = ACT_TX;
}
else
@ -186,12 +186,12 @@ isic_bchannel_start(int unit, int h_chan)
if(sc->sc_trace & TRACE_B_TX) /* if trace, send mbuf to trace dev */
{
i4b_trace_hdr_t hdr;
hdr.unit = unit;
hdr.unit = L0ISICUNIT(unit);
hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2);
hdr.dir = FROM_TE;
hdr.count = ++sc->sc_trace_bcount;
MICROTIME(hdr.time);
MPH_Trace_Ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data);
i4b_l1_trace_ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data);
}
len = 0; /* # of chars put into HSCX tx fifo this time */
@ -256,12 +256,12 @@ isic_bchannel_start(int unit, int h_chan)
if(sc->sc_trace & TRACE_B_TX)
{
i4b_trace_hdr_t hdr;
hdr.unit = unit;
hdr.unit = L0ISICUNIT(unit);
hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2);
hdr.dir = FROM_TE;
hdr.count = ++sc->sc_trace_bcount;
MICROTIME(hdr.time);
MPH_Trace_Ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data);
i4b_l1_trace_ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data);
}
}
}
@ -305,7 +305,7 @@ isic_bchannel_start(int unit, int h_chan)
/* call timeout handling routine */
if(activity == ACT_RX || activity == ACT_TX)
(*chan->drvr_linktab->bch_activity)(chan->drvr_linktab->unit, activity);
(*chan->isic_drvr_linktab->bch_activity)(chan->isic_drvr_linktab->unit, activity);
if(cmd)
isic_hscx_cmd(sc, h_chan, cmd);
@ -337,25 +337,25 @@ isic_bchannel_stat(int unit, int h_chan, bchan_statistics_t *bsp)
/*---------------------------------------------------------------------------*
* return the address of isic drivers linktab
*---------------------------------------------------------------------------*/
static isdn_link_t *
isdn_link_t *
isic_ret_linktab(int unit, int channel)
{
struct l1_softc *sc = &l1_sc[unit];
l1_bchan_state_t *chan = &sc->sc_chan[channel];
return(&chan->isdn_linktab);
return(&chan->isic_isdn_linktab);
}
/*---------------------------------------------------------------------------*
* set the driver linktab in the b channel softc
*---------------------------------------------------------------------------*/
static void
void
isic_set_linktab(int unit, int channel, drvr_link_t *dlt)
{
struct l1_softc *sc = &l1_sc[unit];
l1_bchan_state_t *chan = &sc->sc_chan[channel];
chan->drvr_linktab = dlt;
chan->isic_drvr_linktab = dlt;
}
/*---------------------------------------------------------------------------*
@ -365,11 +365,11 @@ void
isic_init_linktab(struct l1_softc *sc)
{
l1_bchan_state_t *chan = &sc->sc_chan[HSCX_CH_A];
isdn_link_t *lt = &chan->isdn_linktab;
isdn_link_t *lt = &chan->isic_isdn_linktab;
/* make sure the hardware driver is known to layer 4 */
ctrl_types[CTRL_PASSIVE].set_linktab = isic_set_linktab;
ctrl_types[CTRL_PASSIVE].get_linktab = isic_ret_linktab;
ctrl_types[CTRL_PASSIVE].set_linktab = i4b_l1_set_linktab;
ctrl_types[CTRL_PASSIVE].get_linktab = i4b_l1_ret_linktab;
/* local setup */
lt->unit = sc->sc_unit;
@ -386,7 +386,7 @@ isic_init_linktab(struct l1_softc *sc)
lt->rx_mbuf = &chan->in_mbuf;
chan = &sc->sc_chan[HSCX_CH_B];
lt = &chan->isdn_linktab;
lt = &chan->isic_isdn_linktab;
lt->unit = sc->sc_unit;
lt->channel = HSCX_CH_B;
@ -401,37 +401,5 @@ isic_init_linktab(struct l1_softc *sc)
/* used by HDLC data transfers, i.e. ipr and isp drivers */
lt->rx_mbuf = &chan->in_mbuf;
}
/*---------------------------------------------------------------------------*
* telephony silence detection
*---------------------------------------------------------------------------*/
#define TEL_IDLE_MIN (BCH_MAX_DATALEN/2)
int
isic_hscx_silence(unsigned char *data, int len)
{
register int i = 0;
register int j = 0;
/* count idle bytes */
for(;i < len; i++)
{
if((*data >= 0xaa) && (*data <= 0xac))
j++;
data++;
}
#ifdef NOTDEF
printf("isic_hscx_silence: got %d silence bytes in frame\n", j);
#endif
if(j < (TEL_IDLE_MIN))
return(0);
else
return(1);
}
#endif /* NISIC > 0 */

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved.
* Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -27,11 +27,11 @@
* isic - I4B Siemens ISDN Chipset Driver for Creatix/Teles PnP
* ============================================================
*
* $Id: i4b_ctx_s0P.c,v 1.4 1999/12/13 21:25:26 hm Exp $
* $Id: i4b_ctx_s0P.c,v 1.4 2000/08/22 11:30:04 hm Exp $
*
* $FreeBSD$
*
* last edit-date: [Mon Dec 13 21:59:23 1999]
* last edit-date: [Tue Aug 22 11:35:00 2000]
*
* Note: this driver works for the Creatix ISDN S0-16 P+P and
* for the Teles S0/16.3 PnP card. Although they are not
@ -48,6 +48,7 @@
#if (NISIC > 0) && (defined(CRTX_S0_P) || defined(TEL_S0_16_3_P))
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
@ -61,11 +62,11 @@
#include <i4b/include/i4b_global.h>
#include <i4b/layer1/i4b_l1.h>
#include <i4b/layer1/i4b_isac.h>
#include <i4b/layer1/i4b_hscx.h>
#include <i4b/layer1/isic/i4b_isic.h>
#include <i4b/layer1/isic/i4b_isac.h>
#include <i4b/layer1/isic/i4b_hscx.h>
#include <i4b/include/i4b_l1l2.h>
/* #include <i4b/include/i4b_l1l2.h> */
#include <i4b/include/i4b_mbuf.h>
/*---------------------------------------------------------------------------*
@ -190,7 +191,11 @@ isic_attach_Cs0P(device_t dev)
* overlapping each other.
*/
#if 0
bus_set_resource(dev, SYS_RES_IOPORT, 3, iobase2-0x20, 0x20);
#else
bus_set_resource(dev, SYS_RES_IOPORT, 3, iobase2-0x20, 0x10);
#endif
if(!(sc->sc_resources.io_base[3] =
bus_alloc_resource(dev,SYS_RES_IOPORT,

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved.
* Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -27,11 +27,11 @@
* i4b_drn_ngo.c - Dr. Neuhaus Niccy GO@ and SAGEM Cybermod
* --------------------------------------------------------
*
* $Id: i4b_drn_ngo.c,v 1.3 1999/12/13 21:25:26 hm Exp $
* $Id: i4b_drn_ngo.c,v 1.3 2000/05/29 15:41:41 hm Exp $
*
* $FreeBSD$
*
* last edit-date: [Mon Dec 13 21:59:30 1999]
* last edit-date: [Mon May 29 16:43:21 2000]
*
*---------------------------------------------------------------------------*/
@ -41,6 +41,7 @@
#if (NISIC > 0) && defined(DRN_NGO)
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
@ -54,9 +55,9 @@
#include <i4b/include/i4b_global.h>
#include <i4b/layer1/i4b_l1.h>
#include <i4b/layer1/i4b_isac.h>
#include <i4b/layer1/i4b_hscx.h>
#include <i4b/layer1/isic/i4b_isic.h>
#include <i4b/layer1/isic/i4b_isac.h>
#include <i4b/layer1/isic/i4b_hscx.h>
/*---------------------------------------------------------------------------*
* Niccy GO@ definitions

View File

@ -0,0 +1,239 @@
/*
* Copyright (c) 1998 Martijn Plak. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* 4. Altered versions must be plainly marked as such, and must not be
* misrepresented as being the original software and/or documentation.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*---------------------------------------------------------------------------
*
* isdn4bsd layer1 driver for Dynalink IS64PH isdn TA
* ==================================================
*
* $Id: i4b_dynalink.c,v 1.1 2000/09/04 09:17:26 hm Exp $
*
* $FreeBSD$
*
* last edit-date: [Mon Sep 4 09:47:18 2000]
*
*---------------------------------------------------------------------------*/
/* NOTES:
This driver was written for the Dynalink IS64PH ISDN TA, based on two
Siemens chips (HSCX 21525 and ISAC 2186). It is sold in the Netherlands.
model numbers found on (my) card:
IS64PH, TAS100H-N, P/N:89590555, TA200S100045521
chips:
Siemens PSB 21525N, HSCX TE V2.1
Siemens PSB 2186N, ISAC-S TE V1.1
95MS14, PNP
plug-and-play info:
device id "ASU1688"
vendor id 0x88167506
serial 0x00000044
i/o port 4 byte alignment, 4 bytes requested,
10 bit i/o decoding, 0x100-0x3f8 (?)
irq 3,4,5,9,10,11,12,15, high true, edge sensitive
At the moment I'm writing this Dynalink is replacing this card with
one based on a single Siemens chip (IPAC). It will apparently be sold
under the same model name.
This driver might also work for Asuscom cards.
*/
#include "isic.h"
#include "opt_i4b.h"
#if (NISIC > 0) && defined(DYNALINK)
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <machine/clock.h>
#include <net/if.h>
#include <machine/i4b_debug.h>
#include <machine/i4b_ioctl.h>
#include <i4b/layer1/isic/i4b_isic.h>
#include <i4b/layer1/isic/i4b_isac.h>
#include <i4b/layer1/isic/i4b_hscx.h>
/* io address mapping */
#define ISAC 0
#define HSCX 1
#define ADDR 2
/* ADDR bits */
#define ADDRMASK 0x7F
#define RESET 0x80
/* HSCX register offsets */
#define HSCXA 0x00
#define HSCXB 0x40
/* LOW-LEVEL DEVICE ACCESS
*/
static void
dynalink_read_fifo(struct l1_softc *sc, int what, void *buf, size_t size)
{
bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[0]);
bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
switch (what) {
case ISIC_WHAT_ISAC:
bus_space_write_1(t, h, ADDR, 0);
bus_space_read_multi_1(t, h, ISAC, buf, size);
break;
case ISIC_WHAT_HSCXA:
bus_space_write_1(t, h, ADDR, HSCXA);
bus_space_read_multi_1(t, h, HSCX, buf, size);
break;
case ISIC_WHAT_HSCXB:
bus_space_write_1(t, h, ADDR, HSCXB);
bus_space_read_multi_1(t, h, HSCX, buf, size);
break;
}
}
static void
dynalink_write_fifo(struct l1_softc *sc, int what, void *buf, size_t size)
{
bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[0]);
bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
switch (what) {
case ISIC_WHAT_ISAC:
bus_space_write_1(t, h, ADDR, 0);
bus_space_write_multi_1(t, h, ISAC, (u_int8_t*)buf, size);
break;
case ISIC_WHAT_HSCXA:
bus_space_write_1(t, h, ADDR, HSCXA);
bus_space_write_multi_1(t, h, HSCX, (u_int8_t*)buf, size);
break;
case ISIC_WHAT_HSCXB:
bus_space_write_1(t, h, ADDR, HSCXB);
bus_space_write_multi_1(t, h, HSCX, (u_int8_t*)buf, size);
break;
}
}
static void
dynalink_write_reg(struct l1_softc *sc, int what, bus_size_t reg, u_int8_t data)
{
bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[0]);
bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
switch (what) {
case ISIC_WHAT_ISAC:
bus_space_write_1(t, h, ADDR, reg);
bus_space_write_1(t, h, ISAC, data);
break;
case ISIC_WHAT_HSCXA:
bus_space_write_1(t, h, ADDR, HSCXA+reg);
bus_space_write_1(t, h, HSCX, data);
break;
case ISIC_WHAT_HSCXB:
bus_space_write_1(t, h, ADDR, HSCXB+reg);
bus_space_write_1(t, h, HSCX, data);
break;
}
}
static u_int8_t
dynalink_read_reg(struct l1_softc *sc, int what, bus_size_t reg)
{
bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[0]);
bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
switch (what) {
case ISIC_WHAT_ISAC:
bus_space_write_1(t, h, ADDR, reg);
return bus_space_read_1(t, h, ISAC);
case ISIC_WHAT_HSCXA:
bus_space_write_1(t, h, ADDR, HSCXA+reg);
return bus_space_read_1(t, h, HSCX);
case ISIC_WHAT_HSCXB:
bus_space_write_1(t, h, ADDR, HSCXB+reg);
return bus_space_read_1(t, h, HSCX);
}
return 0;
}
/* attach callback routine */
int
isic_attach_Dyn(device_t dev)
{
int unit = device_get_unit(dev); /* get unit */
struct l1_softc *sc = &l1_sc[unit]; /* pointer to softc */
struct i4b_info * info = &(sc->sc_resources);
bus_space_tag_t t = rman_get_bustag(info->io_base[0]);
bus_space_handle_t h = rman_get_bushandle(info->io_base[0]);
/* fill in l1_softc structure */
sc->readreg = dynalink_read_reg;
sc->writereg = dynalink_write_reg;
sc->readfifo = dynalink_read_fifo;
sc->writefifo = dynalink_write_fifo;
sc->clearirq = NULL;
sc->sc_cardtyp = CARD_TYPEP_DYNALINK;
sc->sc_bustyp = BUS_TYPE_IOM2;
sc->sc_ipac = 0;
sc->sc_bfifolen = HSCX_FIFO_LEN;
/* Read HSCX A/B VSTR. Expected value is 0x05 (V2.1). */
if( ((HSCX_READ(0, H_VSTR) & 0xf) != 0x5) ||
((HSCX_READ(1, H_VSTR) & 0xf) != 0x5) )
{
printf("isic%d: HSCX VSTR test failed for Dynalink\n",
sc->sc_unit);
printf("isic%d: HSC0: VSTR: %#x\n",
sc->sc_unit, HSCX_READ(0, H_VSTR));
printf("isic%d: HSC1: VSTR: %#x\n",
sc->sc_unit, HSCX_READ(1, H_VSTR));
return ENXIO;
}
/* reset card */
bus_space_write_1(t,h,ADDR,RESET);
DELAY(SEC_DELAY / 10);
bus_space_write_1(t,h,ADDR,0);
DELAY(SEC_DELAY / 10);
return 0;
}
#endif /* (NISIC > 0) && defined(DYNALINK) */

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999 Hellmuth Michaelis. All rights reserved.
* Copyright (c) 1999, 2000 Hellmuth Michaelis. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -27,11 +27,13 @@
* isic - I4B Siemens ISDN Chipset Driver for ELSA MicroLink ISDN/PCC-16
* =====================================================================
*
* $Id: i4b_elsa_pcc16.c,v 1.2 1999/12/13 21:25:26 hm Exp $
* This should now also work for an ELSA PCFpro.
*
* $Id: i4b_elsa_pcc16.c,v 1.4 2000/07/19 07:51:22 hm Exp $
*
* $FreeBSD$
*
* last edit-date: [Mon Dec 13 21:59:36 1999]
* last edit-date: [Wed Jul 19 09:53:35 2000]
*
*---------------------------------------------------------------------------*/
@ -41,6 +43,7 @@
#if (NISIC > 0) && defined(ELSA_PCC16)
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
@ -52,12 +55,12 @@
#include <machine/i4b_ioctl.h>
#include <i4b/include/i4b_global.h>
#include <i4b/include/i4b_l1l2.h>
/* #include <i4b/include/i4b_l1l2.h> */
#include <i4b/include/i4b_mbuf.h>
#include <i4b/layer1/i4b_l1.h>
#include <i4b/layer1/i4b_isac.h>
#include <i4b/layer1/i4b_hscx.h>
#include <i4b/layer1/isic/i4b_isic.h>
#include <i4b/layer1/isic/i4b_isac.h>
#include <i4b/layer1/isic/i4b_hscx.h>
static void i4b_epcc16_clrirq(struct l1_softc *sc);
@ -308,15 +311,30 @@ isic_probe_Epcc16(device_t dev)
if( ((HSCX_READ(0, H_VSTR) & 0xf) != 0x5) ||
((HSCX_READ(1, H_VSTR) & 0xf) != 0x5) )
{
printf("isic%d: HSCX VSTR test failed for ELSA MicroLink ISDN/PCC-16\n",
unit);
printf("isic%d: HSC0: VSTR: %#x\n",
unit, HSCX_READ(0, H_VSTR));
printf("isic%d: HSC1: VSTR: %#x\n",
unit, HSCX_READ(1, H_VSTR));
isic_detach_Epcc16(dev);
return (ENXIO);
}
/* patch from "Doobee R . Tzeck" <drt@ailis.de>:
* I own an ELSA PCFpro. To my knowledge, the ELSA PCC16 is
* a stripped down Version on the PCFpro. By patching the
* card detection routine for the PPC16 I was able to use
* the PPC16 driver for the PCFpro.
*/
if( ((HSCX_READ(0, H_VSTR) & 0xf) != 0x85) ||
((HSCX_READ(1, H_VSTR) & 0xf) != 0x85) )
{
printf("isic%d: HSCX VSTR test failed for ELSA MicroLink ISDN/PCC-16\n",
unit);
isic_detach_Epcc16(dev);
printf("isic%d: HSC0: VSTR: %#x\n",
unit, HSCX_READ(0, H_VSTR));
printf("isic%d: HSC1: VSTR: %#x\n",
unit, HSCX_READ(1, H_VSTR));
return (ENXIO);
}
else
{
printf("isic%d: ELSA MicroLink ISDN/PCFpro found, going to tread it as PCC-16\n",
unit);
}
}
/* get our irq */

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved.
* Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -27,11 +27,11 @@
* isic - I4B Siemens ISDN Chipset Driver for ELSA Quickstep 1000pro ISA
* =====================================================================
*
* $Id: i4b_elsa_qs1i.c,v 1.3 1999/12/13 21:25:26 hm Exp $
* $Id: i4b_elsa_qs1i.c,v 1.3 2000/05/29 15:41:41 hm Exp $
*
* $FreeBSD$
*
* last edit-date: [Mon Dec 13 21:59:44 1999]
* last edit-date: [Mon May 29 16:44:08 2000]
*
*---------------------------------------------------------------------------*/
@ -41,6 +41,7 @@
#if (NISIC > 0) && defined(ELSA_QS1ISA)
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
@ -52,12 +53,12 @@
#include <machine/i4b_ioctl.h>
#include <i4b/include/i4b_global.h>
#include <i4b/include/i4b_l1l2.h>
/* #include <i4b/include/i4b_l1l2.h> */
#include <i4b/include/i4b_mbuf.h>
#include <i4b/layer1/i4b_l1.h>
#include <i4b/layer1/i4b_isac.h>
#include <i4b/layer1/i4b_hscx.h>
#include <i4b/layer1/isic/i4b_isic.h>
#include <i4b/layer1/isic/i4b_isac.h>
#include <i4b/layer1/isic/i4b_hscx.h>
static void i4b_eq1i_clrirq(struct l1_softc *sc);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved.
* Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -27,11 +27,11 @@
* isic - I4B Siemens ISDN Chipset Driver for ELSA MicroLink ISDN/PCI
* ==================================================================
*
* $Id: i4b_elsa_qs1p.c,v 1.2 1999/12/13 21:25:26 hm Exp $
* $Id: i4b_elsa_qs1p.c,v 1.4 2000/06/02 11:58:56 hm Exp $
*
* $FreeBSD$
*
* last edit-date: [Mon Dec 13 21:59:51 1999]
* last edit-date: [Fri Jun 2 13:57:26 2000]
*
* Note: ELSA Quickstep 1000pro PCI = ELSA MicroLink ISDN/PCI
*
@ -64,13 +64,13 @@
#include <machine/i4b_ioctl.h>
#include <i4b/include/i4b_global.h>
#include <i4b/include/i4b_l1l2.h>
/* #include <i4b/include/i4b_l1l2.h> */
#include <i4b/include/i4b_mbuf.h>
#include <i4b/layer1/i4b_l1.h>
#include <i4b/layer1/i4b_isac.h>
#include <i4b/layer1/i4b_hscx.h>
#include <i4b/layer1/i4b_ipac.h>
#include <i4b/layer1/isic/i4b_isic.h>
#include <i4b/layer1/isic/i4b_isac.h>
#include <i4b/layer1/isic/i4b_hscx.h>
#include <i4b/layer1/isic/i4b_ipac.h>
#define MEM0_MAPOFF 0
#define PORT0_MAPOFF 4

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved.
* Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -27,11 +27,11 @@
* i4b - Siemens HSCX chip (B-channel) handling
* --------------------------------------------
*
* $Id: i4b_hscx.c,v 1.2 1999/12/13 21:25:26 hm Exp $
* $Id: i4b_hscx.c,v 1.7 2000/05/29 15:41:41 hm Exp $
*
* $FreeBSD$
*
* last edit-date: [Mon Dec 13 21:59:58 1999]
* last edit-date: [Mon May 29 16:44:50 2000]
*
*---------------------------------------------------------------------------*/
@ -40,6 +40,7 @@
#if NISIC > 0
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
@ -53,11 +54,12 @@
#include <machine/i4b_ioctl.h>
#include <machine/i4b_trace.h>
#include <i4b/layer1/i4b_l1.h>
#include <i4b/layer1/i4b_isac.h>
#include <i4b/layer1/i4b_hscx.h>
#include <i4b/layer1/isic/i4b_isic.h>
#include <i4b/layer1/isic/i4b_isac.h>
#include <i4b/layer1/isic/i4b_hscx.h>
#include <i4b/layer1/i4b_l1.h>
#include <i4b/include/i4b_l1l2.h>
#include <i4b/include/i4b_global.h>
#include <i4b/include/i4b_mbuf.h>
@ -71,8 +73,8 @@ isic_hscx_irq(register struct l1_softc *sc, u_char ista, int h_chan, u_char ex_i
u_char exir = 0;
int activity = -1;
u_char cmd = 0;
DBGL1(L1_H_IRQ, "isic_hscx_irq", ("%#x\n", ista));
NDBGL1(L1_H_IRQ, "%#x", ista);
if(ex_irq)
{
@ -83,13 +85,13 @@ isic_hscx_irq(register struct l1_softc *sc, u_char ista, int h_chan, u_char ex_i
if(exir & HSCX_EXIR_RFO)
{
chan->stat_RFO++;
DBGL1(L1_H_XFRERR, "isic_hscx_irq", ("ex_irq: receive data overflow\n"));
NDBGL1(L1_H_XFRERR, "ex_irq: receive data overflow");
}
if((exir & HSCX_EXIR_XDU) && (chan->bprot != BPROT_NONE))/* xmit data underrun */
{
chan->stat_XDU++;
DBGL1(L1_H_XFRERR, "isic_hscx_irq", ("ex_irq: xmit data underrun\n"));
NDBGL1(L1_H_XFRERR, "ex_irq: xmit data underrun");
isic_hscx_cmd(sc, h_chan, HSCX_CMDR_XRES);
if (chan->out_mbuf_head != NULL) /* don't continue to transmit this buffer */
@ -117,14 +119,14 @@ isic_hscx_irq(register struct l1_softc *sc, u_char ista, int h_chan, u_char ex_i
{
chan->stat_VFR++;
cmd |= (HSCX_CMDR_RHR);
DBGL1(L1_H_XFRERR, "isic_hscx_irq", ("received invalid Frame\n"));
NDBGL1(L1_H_XFRERR, "received invalid Frame");
error++;
}
if(rsta & HSCX_RSTA_RDO)
{
chan->stat_RDO++;
DBGL1(L1_H_XFRERR, "isic_hscx_irq", ("receive data overflow\n"));
NDBGL1(L1_H_XFRERR, "receive data overflow");
error++;
}
@ -132,14 +134,14 @@ isic_hscx_irq(register struct l1_softc *sc, u_char ista, int h_chan, u_char ex_i
{
chan->stat_CRC++;
cmd |= (HSCX_CMDR_RHR);
DBGL1(L1_H_XFRERR, "isic_hscx_irq", ("CRC check failed\n"));
NDBGL1(L1_H_XFRERR, "CRC check failed");
error++;
}
if(rsta & HSCX_RSTA_RAB)
{
chan->stat_RAB++;
DBGL1(L1_H_XFRERR, "isic_hscx_irq", ("Receive message aborted\n"));
NDBGL1(L1_H_XFRERR, "Receive message aborted");
error++;
}
}
@ -185,15 +187,15 @@ isic_hscx_irq(register struct l1_softc *sc, u_char ista, int h_chan, u_char ex_i
if(sc->sc_trace & TRACE_B_RX)
{
i4b_trace_hdr_t hdr;
hdr.unit = sc->sc_unit;
hdr.unit = L0ISICUNIT(sc->sc_unit);
hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2);
hdr.dir = FROM_NT;
hdr.count = ++sc->sc_trace_bcount;
MICROTIME(hdr.time);
MPH_Trace_Ind(&hdr, chan->in_mbuf->m_len, chan->in_mbuf->m_data);
i4b_l1_trace_ind(&hdr, chan->in_mbuf->m_len, chan->in_mbuf->m_data);
}
(*chan->drvr_linktab->bch_rx_data_ready)(chan->drvr_linktab->unit);
(*chan->isic_drvr_linktab->bch_rx_data_ready)(chan->isic_drvr_linktab->unit);
activity = ACT_RX;
@ -205,7 +207,7 @@ isic_hscx_irq(register struct l1_softc *sc, u_char ista, int h_chan, u_char ex_i
}
else
{
DBGL1(L1_H_XFRERR, "isic_hscx_irq", ("RAWHDLC rx buffer overflow in RME, in_len=%d, fifolen=%d\n", chan->in_len, fifo_data_len));
NDBGL1(L1_H_XFRERR, "RAWHDLC rx buffer overflow in RME, in_len=%d, fifolen=%d", chan->in_len, fifo_data_len);
chan->in_cbptr = chan->in_mbuf->m_data;
chan->in_len = 0;
cmd |= (HSCX_CMDR_RHR | HSCX_CMDR_RMC);
@ -259,17 +261,17 @@ isic_hscx_irq(register struct l1_softc *sc, u_char ista, int h_chan, u_char ex_i
if(sc->sc_trace & TRACE_B_RX)
{
i4b_trace_hdr_t hdr;
hdr.unit = sc->sc_unit;
hdr.unit = L0ISICUNIT(sc->sc_unit);
hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2);
hdr.dir = FROM_NT;
hdr.count = ++sc->sc_trace_bcount;
MICROTIME(hdr.time);
MPH_Trace_Ind(&hdr, chan->in_mbuf->m_len, chan->in_mbuf->m_data);
i4b_l1_trace_ind(&hdr, chan->in_mbuf->m_len, chan->in_mbuf->m_data);
}
/* silence detection */
if(!(isic_hscx_silence(chan->in_mbuf->m_data, chan->in_mbuf->m_len)))
if(!(i4b_l1_bchan_tel_silence(chan->in_mbuf->m_data, chan->in_mbuf->m_len)))
activity = ACT_RX;
if(!(IF_QFULL(&chan->rx_queue)))
@ -283,7 +285,7 @@ isic_hscx_irq(register struct l1_softc *sc, u_char ista, int h_chan, u_char ex_i
/* signal upper driver that data is available */
(*chan->drvr_linktab->bch_rx_data_ready)(chan->drvr_linktab->unit);
(*chan->isic_drvr_linktab->bch_rx_data_ready)(chan->isic_drvr_linktab->unit);
/* alloc new buffer */
@ -305,7 +307,7 @@ isic_hscx_irq(register struct l1_softc *sc, u_char ista, int h_chan, u_char ex_i
}
else
{
DBGL1(L1_H_XFRERR, "isic_hscx_irq", ("RAWHDLC rx buffer overflow in RPF, in_len=%d\n", chan->in_len));
NDBGL1(L1_H_XFRERR, "RAWHDLC rx buffer overflow in RPF, in_len=%d", chan->in_len);
chan->in_cbptr = chan->in_mbuf->m_data;
chan->in_len = 0;
cmd |= (HSCX_CMDR_RHR);
@ -330,7 +332,7 @@ isic_hscx_irq(register struct l1_softc *sc, u_char ista, int h_chan, u_char ex_i
int len;
int nextlen;
DBGL1(L1_H_IRQ, "isic_hscx_irq", ("unit %d, chan %d - XPR, Tx Fifo Empty!\n", sc->sc_unit, h_chan));
NDBGL1(L1_H_IRQ, "unit %d, chan %d - XPR, Tx Fifo Empty!", sc->sc_unit, h_chan);
if(chan->out_mbuf_cur == NULL) /* last frame is transmitted */
{
@ -339,7 +341,7 @@ isic_hscx_irq(register struct l1_softc *sc, u_char ista, int h_chan, u_char ex_i
if(chan->out_mbuf_head == NULL)
{
chan->state &= ~HSCX_TX_ACTIVE;
(*chan->drvr_linktab->bch_tx_queue_empty)(chan->drvr_linktab->unit);
(*chan->isic_drvr_linktab->bch_tx_queue_empty)(chan->isic_drvr_linktab->unit);
}
else
{
@ -351,17 +353,17 @@ isic_hscx_irq(register struct l1_softc *sc, u_char ista, int h_chan, u_char ex_i
if(sc->sc_trace & TRACE_B_TX)
{
i4b_trace_hdr_t hdr;
hdr.unit = sc->sc_unit;
hdr.unit = L0ISICUNIT(sc->sc_unit);
hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2);
hdr.dir = FROM_TE;
hdr.count = ++sc->sc_trace_bcount;
MICROTIME(hdr.time);
MPH_Trace_Ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data);
i4b_l1_trace_ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data);
}
if(chan->bprot == BPROT_NONE)
{
if(!(isic_hscx_silence(chan->out_mbuf_cur->m_data, chan->out_mbuf_cur->m_len)))
if(!(i4b_l1_bchan_tel_silence(chan->out_mbuf_cur->m_data, chan->out_mbuf_cur->m_len)))
activity = ACT_TX;
}
else
@ -408,12 +410,12 @@ isic_hscx_irq(register struct l1_softc *sc, u_char ista, int h_chan, u_char ex_i
if(sc->sc_trace & TRACE_B_TX)
{
i4b_trace_hdr_t hdr;
hdr.unit = sc->sc_unit;
hdr.unit = L0ISICUNIT(sc->sc_unit);
hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2);
hdr.dir = FROM_TE;
hdr.count = ++sc->sc_trace_bcount;
MICROTIME(hdr.time);
MPH_Trace_Ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data);
i4b_l1_trace_ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data);
}
}
else
@ -436,7 +438,7 @@ isic_hscx_irq(register struct l1_softc *sc, u_char ista, int h_chan, u_char ex_i
/* call timeout handling routine */
if(activity == ACT_RX || activity == ACT_TX)
(*chan->drvr_linktab->bch_activity)(chan->drvr_linktab->unit, activity);
(*chan->isic_drvr_linktab->bch_activity)(chan->isic_drvr_linktab->unit, activity);
}
/*---------------------------------------------------------------------------*
@ -541,8 +543,11 @@ isic_hscx_init(struct l1_softc *sc, int h_chan, int activate)
HSCX_WRITE(h_chan, H_MODE,
HSCX_MODE_MDS1|HSCX_MODE_MDS0|HSCX_MODE_ADM|HSCX_MODE_RTS);
}
#if 0
isic_hscx_cmd(sc, h_chan, HSCX_CMDR_RHR|HSCX_CMDR_XRES);
#else
isic_hscx_cmd(sc, h_chan, HSCX_CMDR_RHR);
#endif
}
else
{
@ -625,7 +630,7 @@ isic_hscx_cmd(struct l1_softc *sc, int h_chan, unsigned char cmd)
if(timeout == 0)
{
DBGL1(L1_H_ERR, "isic_hscx_cmd", ("HSCX wait for CEC timeout!\n"));
NDBGL1(L1_H_ERR, "HSCX wait for CEC timeout!");
}
HSCX_WRITE(h_chan, H_CMDR, cmd);
@ -651,11 +656,11 @@ isic_hscx_waitxfw(struct l1_softc *sc, int h_chan)
if(timeout == 0)
{
DBGL1(L1_H_ERR, "isic_hscx_waitxfw", ("HSCX wait for XFW timeout!\n"));
NDBGL1(L1_H_ERR, "HSCX wait for XFW timeout!");
}
else if (timeout != WAITTO)
{
DBGL1(L1_H_XFRERR, "isic_hscx_waitxfw", ("HSCX wait for XFW time: %d uS\n", (WAITTO-timeout)*50));
NDBGL1(L1_H_XFRERR, "HSCX wait for XFW time: %d uS", (WAITTO-timeout)*50);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 1998 Gary Jennejohn. All rights reserved.
* Copyright (c) 1996, 2000 Gary Jennejohn. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -30,7 +30,7 @@
*
*---------------------------------------------------------------------------
*
* $Id: i4b_hscx.h,v 1.2 1999/12/13 21:25:26 hm Exp $
* $Id: i4b_hscx.h,v 1.2 2000/03/09 16:12:51 hm Exp $
*
* $FreeBSD$
*

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved.
* Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -27,7 +27,7 @@
* i4b_ipac.h - definitions for the Siemens IPAC PSB2115 chip
* ==========================================================
*
* $Id: i4b_ipac.h,v 1.2 1999/12/13 21:25:26 hm Exp $
* $Id: i4b_ipac.h,v 1.1 2000/03/07 14:12:26 hm Exp $
*
* $FreeBSD$
*
@ -49,6 +49,7 @@
/* chip version */
#define IPAC_V11 0x01 /* IPAC Version 1.1 */
#define IPAC_V12 0x02 /* IPAC Version 1.2 */
/*
* definitions of registers and bits for the IPAC ISDN chip.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved.
* Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -27,11 +27,11 @@
* i4b_isac.c - i4b siemens isdn chipset driver ISAC handler
* ---------------------------------------------------------
*
* $Id: i4b_isac.c,v 1.2 1999/12/13 21:25:26 hm Exp $
* $Id: i4b_isac.c,v 1.7 2000/05/29 15:41:41 hm Exp $
*
* $FreeBSD$
*
* last edit-date: [Mon Dec 13 22:01:05 1999]
* last edit-date: [Mon May 29 16:45:08 2000]
*
*---------------------------------------------------------------------------*/
@ -42,6 +42,7 @@
#include "opt_i4b.h"
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
@ -56,11 +57,12 @@
#include <machine/i4b_trace.h>
#include <i4b/layer1/i4b_l1.h>
#include <i4b/layer1/i4b_isac.h>
#include <i4b/layer1/i4b_hscx.h>
#include <i4b/layer1/isic/i4b_isic.h>
#include <i4b/layer1/isic/i4b_isac.h>
#include <i4b/layer1/isic/i4b_hscx.h>
#include <i4b/include/i4b_global.h>
#include <i4b/include/i4b_l1l2.h>
#include <i4b/include/i4b_mbuf.h>
static u_char isic_isac_exir_hdlr(register struct l1_softc *sc, u_char exir);
@ -73,7 +75,7 @@ void
isic_isac_irq(struct l1_softc *sc, int ista)
{
register u_char c = 0;
DBGL1(L1_F_MSG, "isic_isac_irq", ("unit %d: ista = 0x%02x\n", sc->sc_unit, ista));
NDBGL1(L1_F_MSG, "unit %d: ista = 0x%02x", sc->sc_unit, ista);
if(ista & ISAC_ISTA_EXI) /* extended interrupt */
{
@ -96,23 +98,23 @@ isic_isac_irq(struct l1_softc *sc, int ista)
if(!(rsta & ISAC_RSTA_CRC)) /* CRC error */
{
error++;
DBGL1(L1_I_ERR, "isic_isac_irq", ("unit %d: CRC error\n", sc->sc_unit));
NDBGL1(L1_I_ERR, "unit %d: CRC error", sc->sc_unit);
}
if(rsta & ISAC_RSTA_RDO) /* ReceiveDataOverflow */
{
error++;
DBGL1(L1_I_ERR, "isic_isac_irq", ("unit %d: Data Overrun error\n", sc->sc_unit));
NDBGL1(L1_I_ERR, "unit %d: Data Overrun error", sc->sc_unit);
}
if(rsta & ISAC_RSTA_RAB) /* ReceiveABorted */
{
error++;
DBGL1(L1_I_ERR, "isic_isac_irq", ("unit %d: Receive Aborted error\n", sc->sc_unit));
NDBGL1(L1_I_ERR, "unit %d: Receive Aborted error", sc->sc_unit);
}
if(error == 0)
DBGL1(L1_I_ERR, "isic_isac_irq", ("unit %d: RME unknown error, RSTA = 0x%02x!\n", sc->sc_unit, rsta));
NDBGL1(L1_I_ERR, "unit %d: RME unknown error, RSTA = 0x%02x!", sc->sc_unit, rsta);
i4b_Dfreembuf(sc->sc_ibuf);
@ -153,12 +155,12 @@ isic_isac_irq(struct l1_softc *sc, int ista)
if(sc->sc_trace & TRACE_D_RX)
{
i4b_trace_hdr_t hdr;
hdr.unit = sc->sc_unit;
hdr.unit = L0ISICUNIT(sc->sc_unit);
hdr.type = TRC_CH_D;
hdr.dir = FROM_NT;
hdr.count = ++sc->sc_trace_dcount;
MICROTIME(hdr.time);
MPH_Trace_Ind(&hdr, sc->sc_ibuf->m_len, sc->sc_ibuf->m_data);
i4b_l1_trace_ind(&hdr, sc->sc_ibuf->m_len, sc->sc_ibuf->m_data);
}
c |= ISAC_CMDR_RMC;
@ -166,7 +168,7 @@ isic_isac_irq(struct l1_softc *sc, int ista)
if(sc->sc_enabled &&
(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S))
{
PH_Data_Ind(sc->sc_unit, sc->sc_ibuf);
i4b_l1_ph_data_ind(L0ISICUNIT(sc->sc_unit), sc->sc_ibuf);
}
else
{
@ -175,7 +177,7 @@ isic_isac_irq(struct l1_softc *sc, int ista)
}
else
{
DBGL1(L1_I_ERR, "isic_isac_irq", ("RME, input buffer overflow!\n"));
NDBGL1(L1_I_ERR, "RME, input buffer overflow!");
i4b_Dfreembuf(sc->sc_ibuf);
c |= ISAC_CMDR_RMC|ISAC_CMDR_RRES;
}
@ -205,7 +207,7 @@ isic_isac_irq(struct l1_softc *sc, int ista)
}
else
{
DBGL1(L1_I_ERR, "isic_isac_irq", ("RPF, input buffer overflow!\n"));
NDBGL1(L1_I_ERR, "RPF, input buffer overflow!");
i4b_Dfreembuf(sc->sc_ibuf);
sc->sc_ibuf = NULL;
sc->sc_ib = NULL;
@ -308,52 +310,52 @@ isic_isac_exir_hdlr(register struct l1_softc *sc, u_char exir)
if(exir & ISAC_EXIR_XMR)
{
DBGL1(L1_I_ERR, "isic_isac_exir_hdlr", ("EXIRQ Tx Message Repeat\n"));
NDBGL1(L1_I_ERR, "EXIRQ Tx Message Repeat");
c |= ISAC_CMDR_XRES;
}
if(exir & ISAC_EXIR_XDU)
{
DBGL1(L1_I_ERR, "isic_isac_exir_hdlr", ("EXIRQ Tx Data Underrun\n"));
NDBGL1(L1_I_ERR, "EXIRQ Tx Data Underrun");
c |= ISAC_CMDR_XRES;
}
if(exir & ISAC_EXIR_PCE)
{
DBGL1(L1_I_ERR, "isic_isac_exir_hdlr", ("EXIRQ Protocol Error\n"));
NDBGL1(L1_I_ERR, "EXIRQ Protocol Error");
}
if(exir & ISAC_EXIR_RFO)
{
DBGL1(L1_I_ERR, "isic_isac_exir_hdlr", ("EXIRQ Rx Frame Overflow\n"));
NDBGL1(L1_I_ERR, "EXIRQ Rx Frame Overflow");
c |= ISAC_CMDR_RMC|ISAC_CMDR_RRES;
}
if(exir & ISAC_EXIR_SOV)
{
DBGL1(L1_I_ERR, "isic_isac_exir_hdlr", ("EXIRQ Sync Xfer Overflow\n"));
NDBGL1(L1_I_ERR, "EXIRQ Sync Xfer Overflow");
}
if(exir & ISAC_EXIR_MOS)
{
DBGL1(L1_I_ERR, "L1 isic_isac_exir_hdlr", ("EXIRQ Monitor Status\n"));
NDBGL1(L1_I_ERR, "EXIRQ Monitor Status");
}
if(exir & ISAC_EXIR_SAW)
{
/* cannot happen, STCR:TSF is set to 0 */
DBGL1(L1_I_ERR, "isic_isac_exir_hdlr", ("EXIRQ Subscriber Awake\n"));
NDBGL1(L1_I_ERR, "EXIRQ Subscriber Awake");
}
if(exir & ISAC_EXIR_WOV)
{
/* cannot happen, STCR:TSF is set to 0 */
DBGL1(L1_I_ERR, "isic_isac_exir_hdlr", ("EXIRQ Watchdog Timer Overflow\n"));
NDBGL1(L1_I_ERR, "EXIRQ Watchdog Timer Overflow");
}
return(c);
@ -370,76 +372,76 @@ isic_isac_ind_hdlr(register struct l1_softc *sc, int ind)
switch(ind)
{
case ISAC_CIRR_IAI8:
DBGL1(L1_I_CICO, "isic_isac_ind_hdlr", ("rx AI8 in state %s\n", isic_printstate(sc)));
NDBGL1(L1_I_CICO, "rx AI8 in state %s", isic_printstate(sc));
if(sc->sc_bustyp == BUS_TYPE_IOM2)
isic_isac_l1_cmd(sc, CMD_AR8);
event = EV_INFO48;
MPH_Status_Ind(sc->sc_unit, STI_L1STAT, LAYER_ACTIVE);
i4b_l1_mph_status_ind(L0ISICUNIT(sc->sc_unit), STI_L1STAT, LAYER_ACTIVE, NULL);
break;
case ISAC_CIRR_IAI10:
DBGL1(L1_I_CICO, "isic_isac_ind_hdlr", ("rx AI10 in state %s\n", isic_printstate(sc)));
NDBGL1(L1_I_CICO, "rx AI10 in state %s", isic_printstate(sc));
if(sc->sc_bustyp == BUS_TYPE_IOM2)
isic_isac_l1_cmd(sc, CMD_AR10);
event = EV_INFO410;
MPH_Status_Ind(sc->sc_unit, STI_L1STAT, LAYER_ACTIVE);
i4b_l1_mph_status_ind(L0ISICUNIT(sc->sc_unit), STI_L1STAT, LAYER_ACTIVE, NULL);
break;
case ISAC_CIRR_IRSY:
DBGL1(L1_I_CICO, "isic_isac_ind_hdlr", ("rx RSY in state %s\n", isic_printstate(sc)));
NDBGL1(L1_I_CICO, "rx RSY in state %s", isic_printstate(sc));
event = EV_RSY;
break;
case ISAC_CIRR_IPU:
DBGL1(L1_I_CICO, "isic_isac_ind_hdlr", ("rx PU in state %s\n", isic_printstate(sc)));
NDBGL1(L1_I_CICO, "rx PU in state %s", isic_printstate(sc));
event = EV_PU;
break;
case ISAC_CIRR_IDR:
DBGL1(L1_I_CICO, "isic_isac_ind_hdlr", ("rx DR in state %s\n", isic_printstate(sc)));
NDBGL1(L1_I_CICO, "rx DR in state %s", isic_printstate(sc));
isic_isac_l1_cmd(sc, CMD_DIU);
event = EV_DR;
break;
case ISAC_CIRR_IDID:
DBGL1(L1_I_CICO, "isic_isac_ind_hdlr", ("rx DID in state %s\n", isic_printstate(sc)));
NDBGL1(L1_I_CICO, "rx DID in state %s", isic_printstate(sc));
event = EV_INFO0;
MPH_Status_Ind(sc->sc_unit, STI_L1STAT, LAYER_IDLE);
i4b_l1_mph_status_ind(L0ISICUNIT(sc->sc_unit), STI_L1STAT, LAYER_IDLE, NULL);
break;
case ISAC_CIRR_IDIS:
DBGL1(L1_I_CICO, "isic_isac_ind_hdlr", ("rx DIS in state %s\n", isic_printstate(sc)));
NDBGL1(L1_I_CICO, "rx DIS in state %s", isic_printstate(sc));
event = EV_DIS;
break;
case ISAC_CIRR_IEI:
DBGL1(L1_I_CICO, "isic_isac_ind_hdlr", ("rx EI in state %s\n", isic_printstate(sc)));
NDBGL1(L1_I_CICO, "rx EI in state %s", isic_printstate(sc));
isic_isac_l1_cmd(sc, CMD_DIU);
event = EV_EI;
break;
case ISAC_CIRR_IARD:
DBGL1(L1_I_CICO, "isic_isac_ind_hdlr", ("rx ARD in state %s\n", isic_printstate(sc)));
NDBGL1(L1_I_CICO, "rx ARD in state %s", isic_printstate(sc));
event = EV_INFO2;
break;
case ISAC_CIRR_ITI:
DBGL1(L1_I_CICO, "isic_isac_ind_hdlr", ("rx TI in state %s\n", isic_printstate(sc)));
NDBGL1(L1_I_CICO, "rx TI in state %s", isic_printstate(sc));
event = EV_INFO0;
break;
case ISAC_CIRR_IATI:
DBGL1(L1_I_CICO, "isic_isac_ind_hdlr", ("rx ATI in state %s\n", isic_printstate(sc)));
NDBGL1(L1_I_CICO, "rx ATI in state %s", isic_printstate(sc));
event = EV_INFO0;
break;
case ISAC_CIRR_ISD:
DBGL1(L1_I_CICO, "isic_isac_ind_hdlr", ("rx SD in state %s\n", isic_printstate(sc)));
NDBGL1(L1_I_CICO, "rx SD in state %s", isic_printstate(sc));
event = EV_INFO0;
break;
default:
DBGL1(L1_I_ERR, "isic_isac_ind_hdlr", ("UNKNOWN Indication 0x%x in state %s\n", ind, isic_printstate(sc)));
NDBGL1(L1_I_ERR, "UNKNOWN Indication 0x%x in state %s", ind, isic_printstate(sc));
event = EV_INFO0;
break;
}
@ -481,7 +483,7 @@ isic_isac_l1_cmd(struct l1_softc *sc, int command)
if(command < 0 || command > CMD_ILL)
{
DBGL1(L1_I_ERR, "isic_isac_l1_cmd", ("illegal cmd 0x%x in state %s\n", command, isic_printstate(sc)));
NDBGL1(L1_I_ERR, "illegal cmd 0x%x in state %s", command, isic_printstate(sc));
return;
}
@ -493,27 +495,27 @@ isic_isac_l1_cmd(struct l1_softc *sc, int command)
switch(command)
{
case CMD_TIM:
DBGL1(L1_I_CICO, "isic_isac_l1_cmd", ("tx TIM in state %s\n", isic_printstate(sc)));
NDBGL1(L1_I_CICO, "tx TIM in state %s", isic_printstate(sc));
cmd |= (ISAC_CIXR_CTIM << 2);
break;
case CMD_RS:
DBGL1(L1_I_CICO, "isic_isac_l1_cmd", ("tx RS in state %s\n", isic_printstate(sc)));
NDBGL1(L1_I_CICO, "tx RS in state %s", isic_printstate(sc));
cmd |= (ISAC_CIXR_CRS << 2);
break;
case CMD_AR8:
DBGL1(L1_I_CICO, "isic_isac_l1_cmd", ("tx AR8 in state %s\n", isic_printstate(sc)));
NDBGL1(L1_I_CICO, "tx AR8 in state %s", isic_printstate(sc));
cmd |= (ISAC_CIXR_CAR8 << 2);
break;
case CMD_AR10:
DBGL1(L1_I_CICO, "isic_isac_l1_cmd", ("tx AR10 in state %s\n", isic_printstate(sc)));
NDBGL1(L1_I_CICO, "tx AR10 in state %s", isic_printstate(sc));
cmd |= (ISAC_CIXR_CAR10 << 2);
break;
case CMD_DIU:
DBGL1(L1_I_CICO, "isic_isac_l1_cmd", ("tx DIU in state %s\n", isic_printstate(sc)));
NDBGL1(L1_I_CICO, "tx DIU in state %s", isic_printstate(sc));
cmd |= (ISAC_CIXR_CDIU << 2);
break;
}
@ -532,7 +534,7 @@ isic_isac_init(struct l1_softc *sc)
if(sc->sc_bustyp != BUS_TYPE_IOM2)
{
DBGL1(L1_I_SETUP, "isic_isac_setup", ("configuring for IOM-1 mode\n"));
NDBGL1(L1_I_SETUP, "configuring for IOM-1 mode");
/* ADF2: Select mode IOM-1 */
ISAC_WRITE(I_ADF2, 0x00);
@ -579,7 +581,7 @@ isic_isac_init(struct l1_softc *sc)
}
else
{
DBGL1(L1_I_SETUP, "isic_isac_setup", ("configuring for IOM-2 mode\n"));
NDBGL1(L1_I_SETUP, "configuring for IOM-2 mode");
/* ADF2: Select mode IOM-2 */
ISAC_WRITE(I_ADF2, ISAC_ADF2_IMS);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 1998 Gary Jennejohn. All rights reserved.
* Copyright (c) 1996, 2000 Gary Jennejohn. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -30,7 +30,7 @@
*
*---------------------------------------------------------------------------
*
* $Id: i4b_isac.h,v 1.2 1999/12/13 21:25:26 hm Exp $
* $Id: i4b_isac.h,v 1.2 2000/03/09 16:12:51 hm Exp $
*
* $FreeBSD$
*

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved.
* Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -27,11 +27,11 @@
* i4b_isic.c - global isic stuff
* ==============================
*
* $Id: i4b_isic.c,v 1.3 1999/12/13 21:25:26 hm Exp $
* $Id: i4b_isic.c,v 1.6 2000/05/29 15:41:41 hm Exp $
*
* $FreeBSD$
*
* last edit-date: [Mon Dec 13 22:01:33 1999]
* last edit-date: [Mon May 29 16:45:24 2000]
*
*---------------------------------------------------------------------------*/
@ -41,6 +41,7 @@
#if NISIC > 0
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
@ -53,17 +54,16 @@
#include <machine/i4b_trace.h>
#include <i4b/layer1/i4b_l1.h>
#include <i4b/layer1/i4b_ipac.h>
#include <i4b/layer1/i4b_isac.h>
#include <i4b/layer1/i4b_hscx.h>
#include <i4b/include/i4b_l1l2.h>
#include <i4b/layer1/isic/i4b_isic.h>
#include <i4b/layer1/isic/i4b_isic_ext.h>
#include <i4b/layer1/isic/i4b_ipac.h>
#include <i4b/layer1/isic/i4b_isac.h>
#include <i4b/layer1/isic/i4b_hscx.h>
#include <i4b/include/i4b_mbuf.h>
#include <i4b/include/i4b_global.h>
void isic_settrace(int unit, int val);
int isic_gettrace(int unit);
static char *ISACversion[] = {
"2085 Version A1/A2 or 2086/2186 Version 1.1",
"2085 Version B1",
@ -82,6 +82,15 @@ static char *HSCXversion[] = {
"Unknown Version"
};
/* jump table for multiplex routines */
struct i4b_l1mux_func isic_l1mux_func = {
isic_ret_linktab,
isic_set_linktab,
isic_mph_command_req,
isic_ph_data_req,
isic_ph_activate_req,
};
/*---------------------------------------------------------------------------*
* isic - device driver interrupt routine
*---------------------------------------------------------------------------*/
@ -207,26 +216,6 @@ isicintr(struct l1_softc *sc)
}
}
/*---------------------------------------------------------------------------*
* isic_settrace
*---------------------------------------------------------------------------*/
void
isic_settrace(int unit, int val)
{
struct l1_softc *sc = &l1_sc[unit];
sc->sc_trace = val;
}
/*---------------------------------------------------------------------------*
* isic_gettrace
*---------------------------------------------------------------------------*/
int
isic_gettrace(int unit)
{
struct l1_softc *sc = &l1_sc[unit];
return(sc->sc_trace);
}
/*---------------------------------------------------------------------------*
* isic_recover - try to recover from irq lockup
*---------------------------------------------------------------------------*/
@ -239,38 +228,38 @@ isic_recover(struct l1_softc *sc)
byte = HSCX_READ(HSCX_CH_B, H_ISTA);
DBGL1(L1_ERROR, "isic_recover", ("HSCX B: ISTA = 0x%x\n", byte));
NDBGL1(L1_ERROR, "HSCX B: ISTA = 0x%x", byte);
if(byte & HSCX_ISTA_ICA)
DBGL1(L1_ERROR, "isic_recover", ("HSCX A: ISTA = 0x%x\n", (u_char)HSCX_READ(HSCX_CH_A, H_ISTA)));
NDBGL1(L1_ERROR, "HSCX A: ISTA = 0x%x", (u_char)HSCX_READ(HSCX_CH_A, H_ISTA));
if(byte & HSCX_ISTA_EXB)
DBGL1(L1_ERROR, "isic_recover", ("HSCX B: EXIR = 0x%x\n", (u_char)HSCX_READ(HSCX_CH_B, H_EXIR)));
NDBGL1(L1_ERROR, "HSCX B: EXIR = 0x%x", (u_char)HSCX_READ(HSCX_CH_B, H_EXIR));
if(byte & HSCX_ISTA_EXA)
DBGL1(L1_ERROR, "isic_recover", ("HSCX A: EXIR = 0x%x\n", (u_char)HSCX_READ(HSCX_CH_A, H_EXIR)));
NDBGL1(L1_ERROR, "HSCX A: EXIR = 0x%x", (u_char)HSCX_READ(HSCX_CH_A, H_EXIR));
/* get isac irq status */
byte = ISAC_READ(I_ISTA);
DBGL1(L1_ERROR, "isic_recover", (" ISAC: ISTA = 0x%x\n", byte));
NDBGL1(L1_ERROR, " ISAC: ISTA = 0x%x", byte);
if(byte & ISAC_ISTA_EXI)
DBGL1(L1_ERROR, "isic_recover", (" ISAC: EXIR = 0x%x\n", (u_char)ISAC_READ(I_EXIR)));
NDBGL1(L1_ERROR, " ISAC: EXIR = 0x%x", (u_char)ISAC_READ(I_EXIR));
if(byte & ISAC_ISTA_CISQ)
{
byte = ISAC_READ(I_CIRR);
DBGL1(L1_ERROR, "isic_recover", (" ISAC: CISQ = 0x%x\n", byte));
NDBGL1(L1_ERROR, " ISAC: CISQ = 0x%x", byte);
if(byte & ISAC_CIRR_SQC)
DBGL1(L1_ERROR, "isic_recover", (" ISAC: SQRR = 0x%x\n", (u_char)ISAC_READ(I_SQRR)));
NDBGL1(L1_ERROR, " ISAC: SQRR = 0x%x", (u_char)ISAC_READ(I_SQRR));
}
DBGL1(L1_ERROR, "isic_recover", ("HSCX B: IMASK = 0x%x\n", HSCX_B_IMASK));
DBGL1(L1_ERROR, "isic_recover", ("HSCX A: IMASK = 0x%x\n", HSCX_A_IMASK));
NDBGL1(L1_ERROR, "HSCX B: IMASK = 0x%x", HSCX_B_IMASK);
NDBGL1(L1_ERROR, "HSCX A: IMASK = 0x%x", HSCX_A_IMASK);
HSCX_WRITE(0, H_MASK, 0xff);
HSCX_WRITE(1, H_MASK, 0xff);
@ -279,7 +268,7 @@ isic_recover(struct l1_softc *sc)
HSCX_WRITE(1, H_MASK, HSCX_B_IMASK);
DELAY(100);
DBGL1(L1_ERROR, "isic_recover", (" ISAC: IMASK = 0x%x\n", ISAC_IMASK));
NDBGL1(L1_ERROR, " ISAC: IMASK = 0x%x", ISAC_IMASK);
ISAC_WRITE(I_MASK, 0xff);
DELAY(100);
@ -292,7 +281,6 @@ isic_recover(struct l1_softc *sc)
int
isic_attach_common(device_t dev)
{
int ret;
char *drvid = NULL;
int unit = device_get_unit(dev);
struct l1_softc *sc = &l1_sc[unit];
@ -304,19 +292,19 @@ isic_attach_common(device_t dev)
if(sc->sc_ipac)
{
ret = IPAC_READ(IPAC_ID);
switch(ret)
{
case 0x01:
break;
default:
printf("isic%d: Error, IPAC version %d unknown!\n",
unit, ret);
return ENXIO;
break;
sc->sc_ipac_version = IPAC_READ(IPAC_ID);
switch(sc->sc_ipac_version)
{
case IPAC_V11:
case IPAC_V12:
break;
default:
printf("isic%d: Error, IPAC version %d unknown!\n",
unit, sc->sc_ipac_version);
return(0);
break;
}
}
else
@ -389,8 +377,8 @@ isic_attach_common(device_t dev)
/* init higher protocol layers */
MPH_Status_Ind(sc->sc_unit, STI_ATTACH, sc->sc_cardtyp);
i4b_l1_mph_status_ind(L0ISICUNIT(sc->sc_unit), STI_ATTACH, sc->sc_cardtyp, &isic_l1mux_func);
/* announce manufacturer and card type for ISA cards */
switch(sc->sc_flags)
@ -441,7 +429,10 @@ isic_attach_common(device_t dev)
if(sc->sc_ipac)
{
printf("isic%d: IPAC PSB2115 Version 1.1\n", unit);
if(sc->sc_ipac_version == IPAC_V11)
printf("isic%d: IPAC PSB2115 Version 1.1\n", unit);
else
printf("isic%d: IPAC PSB2115 Version 1.2\n", unit);
}
else
{

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved.
* Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -27,16 +27,16 @@
* i4b_l1.h - isdn4bsd layer 1 header file
* ---------------------------------------
*
* $Id: i4b_l1.h,v 1.3 1999/12/13 21:25:26 hm Exp $
* $Id: i4b_isic.h,v 1.4 2000/09/04 09:17:26 hm Exp $
*
* $FreeBSD$
*
* last edit-date: [Mon Dec 13 22:02:07 1999]
* last edit-date: [Mon Sep 4 09:34:38 2000]
*
*---------------------------------------------------------------------------*/
#ifndef I4B_L1_H_
#define I4B_L1_H_
#ifndef _I4B_ISIC_H_
#define _I4B_ISIC_H_
#include <sys/resource.h>
#include <sys/bus.h>
@ -46,6 +46,16 @@
#include <i4b/include/i4b_l3l4.h>
#include <i4b/layer1/isic/i4b_isic_ext.h>
/*---------------------------------------------------------------------------
* isic driver: max no of units
* Teles/Creatix/Neuhaus cards have a hardware limitation
* as one is able to set 3 (sometimes 4) different configurations by
* jumpers so a maximum of 3 (4) cards per ISA bus is possible.
*---------------------------------------------------------------------------*/
#define ISIC_MAXUNIT 3 /* max no of supported units 0..3 */
/*---------------------------------------------------------------------------
* kernel config file flags definition
*---------------------------------------------------------------------------*/
@ -127,8 +137,8 @@ typedef struct
/* link between b channel and driver */
isdn_link_t isdn_linktab; /* b channel addresses */
drvr_link_t *drvr_linktab; /* ptr to driver linktab*/
isdn_link_t isic_isdn_linktab; /* b channel addresses */
drvr_link_t *isic_drvr_linktab; /* ptr to driver linktab*/
/* statistics */
@ -204,7 +214,8 @@ struct l1_softc
int sc_isac_version; /* version number of ISAC */
int sc_hscx_version; /* version number of HSCX */
int sc_ipac_version; /* version number of IPAC */
int sc_I430state; /* I.430 state F3 .... F8 */
int sc_I430T3; /* I.430 Timer T3 running */
@ -297,7 +308,6 @@ enum I430commands {
#define N_COMMANDS CMD_ILL
extern struct l1_softc l1_sc[];
extern void isicintr(struct l1_softc *sc);
@ -336,12 +346,18 @@ extern int isic_attach_s0163 (device_t dev);
extern int isic_probe_avma1 (device_t dev);
extern int isic_attach_avma1 (device_t dev);
extern int isic_probe_usrtai (device_t dev);
extern int isic_attach_usrtai (device_t dev);
extern int isic_probe_itkix1 (device_t dev);
extern int isic_attach_itkix1 (device_t dev);
extern int isic_attach_drnngo (device_t dev);
extern int isic_attach_Cs0P (device_t dev);
extern int isic_attach_Eqs1pi(device_t dev);
extern int isic_attach_sws(device_t dev);
extern int isic_attach_siemens_isurf(device_t dev);
extern int isic_attach_asi(device_t dev);
extern int isic_attach_Dyn(device_t dev);
#endif /* I4B_L1_H_ */
#endif /* _I4B_ISIC_H_ */

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*---------------------------------------------------------------------------*
*
* i4b_l1.h - isdn4bsd layer 1 header file
* ---------------------------------------
*
* $Id: i4b_isic_ext.h,v 1.3 2000/06/02 16:14:36 hm Exp $
*
* $FreeBSD$
*
* last edit-date: [Fri Jun 2 14:43:57 2000]
*
*---------------------------------------------------------------------------*/
#ifndef _I4B_ISIC_EXT_H_
#define _I4B_ISIC_EXT_H_
#include <i4b/include/i4b_l3l4.h>
int isic_ph_data_req(int unit, struct mbuf *m, int freeflag);
int isic_ph_activate_req(int unit);
int isic_mph_command_req(int unit, int command, void *parm);
void isic_set_linktab(int unit, int channel, drvr_link_t *dlt);
isdn_link_t *isic_ret_linktab(int unit, int channel);
#endif /* _I4B_ISIC_H_ */

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved.
* Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -27,11 +27,11 @@
* i4b_isic_isa.c - ISA bus interface
* ==================================
*
* $Id: i4b_isic_isa.c,v 1.4 1999/12/13 21:25:26 hm Exp $
* $Id: i4b_isic_isa.c,v 1.3 2000/05/29 15:41:41 hm Exp $
*
* $FreeBSD$
*
* last edit-date: [Mon Dec 13 22:01:39 1999]
* last edit-date: [Mon May 29 16:45:34 2000]
*
*---------------------------------------------------------------------------*/
@ -53,12 +53,12 @@
#include <machine/i4b_ioctl.h>
#include <machine/i4b_trace.h>
#include <i4b/layer1/i4b_l1.h>
#include <i4b/layer1/i4b_ipac.h>
#include <i4b/layer1/i4b_isac.h>
#include <i4b/layer1/i4b_hscx.h>
#include <i4b/layer1/isic/i4b_isic.h>
#include <i4b/layer1/isic/i4b_ipac.h>
#include <i4b/layer1/isic/i4b_isac.h>
#include <i4b/layer1/isic/i4b_hscx.h>
#include <i4b/include/i4b_l1l2.h>
/* #include <i4b/include/i4b_l1l2.h> */
#include <i4b/include/i4b_mbuf.h>
#include <i4b/include/i4b_global.h>

View File

@ -3,7 +3,7 @@
*
* Copyright (c) 1998, 1999 German Tischler. All rights reserved.
*
* Copyright (c) 1998, 1999 Hellmuth Michaelis. All rights reserved.
* Copyright (c) 1998, 2000 Hellmuth Michaelis. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -37,11 +37,11 @@
* i4b_isic_pnp.c - i4b pnp support
* --------------------------------
*
* $Id: i4b_isic_pnp.c,v 1.5 1999/12/13 21:25:26 hm Exp $
* $Id: i4b_isic_pnp.c,v 1.2 2000/03/09 16:12:51 hm Exp $
*
* $FreeBSD$
*
* last edit-date: [Mon Dec 13 22:01:48 1999]
* last edit-date: [Thu Mar 9 16:04:10 2000]
*
*---------------------------------------------------------------------------*/
@ -60,7 +60,7 @@
#include <i4b/include/i4b_global.h>
#include <machine/i4b_ioctl.h>
#include <i4b/layer1/i4b_l1.h>
#include <i4b/layer1/isic/i4b_isic.h>
#include <isa/isavar.h>

View File

@ -26,14 +26,12 @@
* 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$
*
* 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
@ -64,48 +62,30 @@
*
*---------------------------------------------------------------------------*/
#if defined(__FreeBSD__)
#include "isic.h"
#include "opt_i4b.h"
#else
#define NISIC 1
#endif
#if NISIC > 0 && defined(ITKIX1)
#include <sys/param.h>
#if defined(__FreeBSD__) && __FreeBSD__ >= 3
#include <sys/ioccom.h>
#else
#include <sys/ioctl.h>
#endif
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#ifdef __FreeBSD__
#include <machine/clock.h>
#include <i386/isa/isa_device.h>
#else
#include <machine/bus.h>
#include <sys/device.h>
#endif
#include <sys/socket.h>
#include <machine/clock.h>
#include <net/if.h>
#ifdef __FreeBSD__
#include <machine/i4b_debug.h>
#include <machine/i4b_ioctl.h>
#else
#include <i4b/i4b_debug.h>
#include <i4b/i4b_ioctl.h>
#endif
#include <i4b/layer1/i4b_l1.h>
#include <i4b/layer1/i4b_isac.h>
#include <i4b/layer1/i4b_hscx.h>
#include <i4b/layer1/isic/i4b_isic.h>
#include <i4b/layer1/isic/i4b_isac.h>
#include <i4b/layer1/isic/i4b_hscx.h>
#include <i4b/include/i4b_global.h>
#include <i4b/include/i4b_mbuf.h>
/* Register offsets */
#define ITK_ISAC_DATA 0
@ -120,228 +100,13 @@
#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)
itkix1_read_fifo(struct l1_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) {
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);
@ -356,34 +121,14 @@ itkix1_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size)
break;
}
}
#endif
#ifdef __FreeBSD__
static void
itkix1_write_fifo(void *base, const void *buf, size_t len)
itkix1_write_fifo(struct l1_softc *sc, int what, void *buf, size_t size)
{
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) {
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);
@ -398,34 +143,14 @@ static void itkix1_write_fifo(struct isic_softc *sc, int what, const void *buf,
break;
}
}
#endif
#ifdef __FreeBSD__
static void
itkix1_write_reg(u_char *base, u_int offset, u_int v)
itkix1_write_reg(struct l1_softc *sc, int what, bus_size_t offs, u_int8_t data)
{
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) {
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);
@ -440,31 +165,14 @@ static void itkix1_write_reg(struct isic_softc *sc, int what, bus_size_t offs, u
break;
}
}
#endif
#ifdef __FreeBSD__
static u_char
itkix1_read_reg(u_char *base, u_int offset)
static u_int8_t
itkix1_read_reg(struct l1_softc *sc, int what, bus_size_t offs)
{
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) {
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);
@ -477,6 +185,225 @@ static u_int8_t itkix1_read_reg(struct isic_softc *sc, int what, bus_size_t offs
}
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 */

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved.
* Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -27,11 +27,11 @@
* i4b_l1.c - isdn4bsd layer 1 handler
* -----------------------------------
*
* $Id: i4b_l1.c,v 1.2 1999/12/13 21:25:26 hm Exp $
* $Id: i4b_l1.c,v 1.7 2000/06/02 16:14:36 hm Exp $
*
* $FreeBSD$
*
* last edit-date: [Mon Dec 13 22:01:55 1999]
* last edit-date: [Fri Jun 2 18:09:53 2000]
*
*---------------------------------------------------------------------------*/
@ -40,6 +40,7 @@
#if NISIC > 0
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
@ -53,56 +54,15 @@
#include <machine/i4b_ioctl.h>
#include <machine/i4b_trace.h>
#include <i4b/layer1/i4b_l1.h>
#include <i4b/layer1/i4b_isac.h>
#include <i4b/layer1/i4b_hscx.h>
#include <i4b/layer1/isic/i4b_isic.h>
#include <i4b/layer1/isic/i4b_isac.h>
#include <i4b/layer1/isic/i4b_hscx.h>
#include <i4b/layer1/i4b_l1.h>
#include <i4b/include/i4b_l1l2.h>
#include <i4b/include/i4b_mbuf.h>
#include <i4b/include/i4b_global.h>
unsigned int i4b_l1_debug = L1_DEBUG_DEFAULT;
static int ph_data_req(int, struct mbuf *, int);
static int ph_activate_req(int);
/* from i4btrc driver i4b_trace.c */
extern int get_trace_data_from_l1(int unit, int what, int len, char *buf);
/* from layer 2 */
extern int i4b_ph_data_ind(int unit, struct mbuf *m);
extern int i4b_ph_activate_ind(int unit);
extern int i4b_ph_deactivate_ind(int unit);
extern int i4b_mph_attach_ind(int unit);
extern int i4b_mph_status_ind(int, int, int);
/* layer 1 lme */
static int i4b_mph_command_req(int, int, int);
/* jump table */
struct i4b_l1l2_func i4b_l1l2_func = {
/* Layer 1 --> Layer 2 */
(int (*)(int, struct mbuf *)) i4b_ph_data_ind,
(int (*)(int)) i4b_ph_activate_ind,
(int (*)(int)) i4b_ph_deactivate_ind,
/* Layer 2 --> Layer 1 */
(int (*)(int, struct mbuf *, int)) ph_data_req,
(int (*)(int)) ph_activate_req,
/* Layer 1 --> upstream, ISDN trace data */
(int (*)(i4b_trace_hdr_t *, int, u_char *)) get_trace_data_from_l1,
/* Driver control and status information */
(int (*)(int, int, int)) i4b_mph_status_ind,
(int (*)(int, int, int)) i4b_mph_command_req,
};
/*---------------------------------------------------------------------------*
*
* L2 -> L1: PH-DATA-REQUEST
@ -119,15 +79,15 @@ struct i4b_l1l2_func i4b_l1l2_func = {
* !=0 ok, frame sent out
*
*---------------------------------------------------------------------------*/
static int
ph_data_req(int unit, struct mbuf *m, int freeflag)
int
isic_ph_data_req(int unit, struct mbuf *m, int freeflag)
{
u_char cmd;
int s;
struct l1_softc *sc = &l1_sc[unit];
#ifdef NOTDEF
DBGL1(L1_PRIM, "PH-DATA-REQ", ("unit %d, freeflag=%d\n", unit, freeflag));
NDBGL1(L1_PRIM, "unit %d, freeflag=%d", unit, freeflag);
#endif
if(m == NULL) /* failsafe */
@ -137,8 +97,8 @@ ph_data_req(int unit, struct mbuf *m, int freeflag)
if(sc->sc_I430state == ST_F3) /* layer 1 not running ? */
{
DBGL1(L1_I_ERR, "ph_data_req", ("still in state F3!\n"));
ph_activate_req(unit);
NDBGL1(L1_I_ERR, "still in state F3!");
isic_ph_activate_req(unit);
}
if(sc->sc_state & ISAC_TX_ACTIVE)
@ -152,23 +112,23 @@ ph_data_req(int unit, struct mbuf *m, int freeflag)
else
sc->sc_freeflag2 = 0; /* IRQ must not mfree */
DBGL1(L1_I_MSG, "ph_data_req", ("using 2nd ISAC TX buffer, state = %s\n", isic_printstate(sc)));
NDBGL1(L1_I_MSG, "using 2nd ISAC TX buffer, state = %s", isic_printstate(sc));
if(sc->sc_trace & TRACE_D_TX)
{
i4b_trace_hdr_t hdr;
hdr.unit = unit;
hdr.unit = L0ISICUNIT(unit);
hdr.type = TRC_CH_D;
hdr.dir = FROM_TE;
hdr.count = ++sc->sc_trace_dcount;
MICROTIME(hdr.time);
MPH_Trace_Ind(&hdr, m->m_len, m->m_data);
i4b_l1_trace_ind(&hdr, m->m_len, m->m_data);
}
splx(s);
return(1);
}
DBGL1(L1_I_ERR, "ph_data_req", ("No Space in TX FIFO, state = %s\n", isic_printstate(sc)));
NDBGL1(L1_I_ERR, "No Space in TX FIFO, state = %s", isic_printstate(sc));
if(freeflag == MBUF_FREE)
i4b_Dfreembuf(m);
@ -180,17 +140,17 @@ ph_data_req(int unit, struct mbuf *m, int freeflag)
if(sc->sc_trace & TRACE_D_TX)
{
i4b_trace_hdr_t hdr;
hdr.unit = unit;
hdr.unit = L0ISICUNIT(unit);
hdr.type = TRC_CH_D;
hdr.dir = FROM_TE;
hdr.count = ++sc->sc_trace_dcount;
MICROTIME(hdr.time);
MPH_Trace_Ind(&hdr, m->m_len, m->m_data);
i4b_l1_trace_ind(&hdr, m->m_len, m->m_data);
}
sc->sc_state |= ISAC_TX_ACTIVE; /* set transmitter busy flag */
DBGL1(L1_I_MSG, "ph_data_req", ("ISAC_TX_ACTIVE set\n"));
NDBGL1(L1_I_MSG, "ISAC_TX_ACTIVE set");
sc->sc_freeflag = 0; /* IRQ must NOT mfree */
@ -240,11 +200,11 @@ ph_data_req(int unit, struct mbuf *m, int freeflag)
* !=0
*
*---------------------------------------------------------------------------*/
static int
ph_activate_req(int unit)
int
isic_ph_activate_req(int unit)
{
struct l1_softc *sc = &l1_sc[unit];
DBGL1(L1_PRIM, "PH-ACTIVATE-REQ", ("unit %d\n", unit));
NDBGL1(L1_PRIM, "unit %d", unit);
isic_next_state(sc, EV_PHAR);
return(0);
}
@ -252,25 +212,46 @@ ph_activate_req(int unit)
/*---------------------------------------------------------------------------*
* command from the upper layers
*---------------------------------------------------------------------------*/
static int
i4b_mph_command_req(int unit, int command, int parm)
int
isic_mph_command_req(int unit, int command, void *parm)
{
struct l1_softc *sc = &l1_sc[unit];
switch(command)
{
case CMR_DOPEN: /* daemon running */
DBGL1(L1_PRIM, "MPH-COMMAND-REQ", ("unit %d, command = CMR_DOPEN\n", unit));
NDBGL1(L1_PRIM, "unit %d, command = CMR_DOPEN", unit);
sc->sc_enabled = 1;
break;
case CMR_DCLOSE: /* daemon not running */
DBGL1(L1_PRIM, "MPH-COMMAND-REQ", ("unit %d, command = CMR_DCLOSE\n", unit));
NDBGL1(L1_PRIM, "unit %d, command = CMR_DCLOSE", unit);
sc->sc_enabled = 0;
break;
case CMR_SETTRACE:
NDBGL1(L1_PRIM, "unit %d, command = CMR_SETTRACE, parm = %d", unit, (unsigned int)parm);
sc->sc_trace = (unsigned int)parm;
break;
case CMR_GCST:
{
struct chipstat *cst;
NDBGL1(L1_PRIM, "unit %d, command = CMR_GCST, parm = %d", unit, (unsigned int)parm);
cst = (struct chipstat *)parm;
cst->driver_type = L1DRVR_ISIC;
cst->stats.hscxstat.unit = sc->sc_unit;
cst->stats.hscxstat.chan = cst->driver_bchannel;
cst->stats.hscxstat.vfr = sc->sc_chan[cst->driver_bchannel].stat_VFR;
cst->stats.hscxstat.rdo = sc->sc_chan[cst->driver_bchannel].stat_RDO;
cst->stats.hscxstat.crc = sc->sc_chan[cst->driver_bchannel].stat_CRC;
cst->stats.hscxstat.rab = sc->sc_chan[cst->driver_bchannel].stat_RAB;
cst->stats.hscxstat.xdu = sc->sc_chan[cst->driver_bchannel].stat_XDU;
cst->stats.hscxstat.rfo = sc->sc_chan[cst->driver_bchannel].stat_RFO;
break;
}
default:
DBGL1(L1_ERROR, "i4b_mph_command_req", ("ERROR, unknown command = %d, unit = %d, parm = %d\n", command, unit, parm));
NDBGL1(L1_ERROR, "ERROR, unknown command = %d, unit = %d, parm = %d", command, unit, (unsigned int)parm);
break;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved.
* Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -27,11 +27,11 @@
* i4b_l1fsm.c - isdn4bsd layer 1 I.430 state machine
* --------------------------------------------------
*
* $Id: i4b_l1fsm.c,v 1.2 1999/12/13 21:25:26 hm Exp $
* $Id: i4b_l1fsm.c,v 1.8 2000/05/29 15:41:41 hm Exp $
*
* $FreeBSD$
*
* last edit-date: [Mon Dec 13 22:02:16 1999]
* last edit-date: [Mon May 29 16:46:03 2000]
*
*---------------------------------------------------------------------------*/
@ -52,16 +52,19 @@
#include <machine/i4b_debug.h>
#include <machine/i4b_ioctl.h>
#include <machine/i4b_trace.h>
#include <i4b/layer1/isic/i4b_isic.h>
#include <i4b/layer1/isic/i4b_isac.h>
#include <i4b/layer1/isic/i4b_hscx.h>
#include <i4b/layer1/i4b_l1.h>
#include <i4b/layer1/i4b_isac.h>
#include <i4b/layer1/i4b_hscx.h>
#include <i4b/include/i4b_global.h>
#include <i4b/include/i4b_l1l2.h>
#include <i4b/include/i4b_mbuf.h>
#if DO_I4B_DEBUG
static char *state_text[N_STATES] = {
"F3 Deactivated",
"F4 Awaiting Signal",
@ -86,6 +89,7 @@ static char *event_text[N_EVENTS] = {
"EV_EI Error Ind",
"Illegal Event"
};
#endif
/* Function prototypes */
@ -113,7 +117,7 @@ timer3_expired(struct l1_softc *sc)
{
if(sc->sc_I430T3)
{
DBGL1(L1_T_ERR, "timer3_expired", ("state = %s\n", isic_printstate(sc)));
NDBGL1(L1_T_ERR, "state = %s", isic_printstate(sc));
sc->sc_I430T3 = 0;
/* XXX try some recovery here XXX */
@ -144,14 +148,14 @@ timer3_expired(struct l1_softc *sc)
splx(s);
MPH_Status_Ind(sc->sc_unit, STI_NOL1ACC, 0);
i4b_l1_mph_status_ind(L0ISICUNIT(sc->sc_unit), STI_NOL1ACC, 0, NULL);
}
isic_next_state(sc, EV_T3);
}
else
{
DBGL1(L1_T_ERR, "timer3_expired", ("expired without starting it ....\n"));
NDBGL1(L1_T_ERR, "expired without starting it ....");
}
}
@ -161,7 +165,7 @@ timer3_expired(struct l1_softc *sc)
static void
T3_start(struct l1_softc *sc)
{
DBGL1(L1_T_MSG, "T3_start", ("state = %s\n", isic_printstate(sc)));
NDBGL1(L1_T_MSG, "state = %s", isic_printstate(sc));
sc->sc_I430T3 = 1;
sc->sc_T3_callout = timeout((TIMEOUT_FUNC_T)timer3_expired,(struct l1_softc *)sc, 2*hz);
}
@ -172,7 +176,7 @@ T3_start(struct l1_softc *sc)
static void
T3_stop(struct l1_softc *sc)
{
DBGL1(L1_T_MSG, "T3_stop", ("state = %s\n", isic_printstate(sc)));
NDBGL1(L1_T_MSG, "state = %s", isic_printstate(sc));
sc->sc_init_tries = 0; /* init connect retry count */
@ -189,9 +193,9 @@ T3_stop(struct l1_softc *sc)
static void
F_T3ex(struct l1_softc *sc)
{
DBGL1(L1_F_MSG, "F_T3ex", ("FSM function F_T3ex executing\n"));
NDBGL1(L1_F_MSG, "FSM function F_T3ex executing");
if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S)
PH_Deact_Ind(sc->sc_unit);
i4b_l1_ph_deactivate_ind(L0ISICUNIT(sc->sc_unit));
}
/*---------------------------------------------------------------------------*
@ -202,13 +206,13 @@ timer4_expired(struct l1_softc *sc)
{
if(sc->sc_I430T4)
{
DBGL1(L1_T_MSG, "timer4_expired", ("state = %s\n", isic_printstate(sc)));
NDBGL1(L1_T_MSG, "state = %s", isic_printstate(sc));
sc->sc_I430T4 = 0;
MPH_Status_Ind(sc->sc_unit, STI_PDEACT, 0);
i4b_l1_mph_status_ind(L0ISICUNIT(sc->sc_unit), STI_PDEACT, 0, NULL);
}
else
{
DBGL1(L1_T_ERR, "timer4_expired", ("expired without starting it ....\n"));
NDBGL1(L1_T_ERR, "expired without starting it ....");
}
}
@ -218,7 +222,7 @@ timer4_expired(struct l1_softc *sc)
static void
T4_start(struct l1_softc *sc)
{
DBGL1(L1_T_MSG, "T4_start", ("state = %s\n", isic_printstate(sc)));
NDBGL1(L1_T_MSG, "state = %s", isic_printstate(sc));
sc->sc_I430T4 = 1;
sc->sc_T4_callout = timeout((TIMEOUT_FUNC_T)timer4_expired,(struct l1_softc *)sc, hz);
}
@ -229,7 +233,7 @@ T4_start(struct l1_softc *sc)
static void
T4_stop(struct l1_softc *sc)
{
DBGL1(L1_T_MSG, "T4_stop", ("state = %s\n", isic_printstate(sc)));
NDBGL1(L1_T_MSG, "state = %s", isic_printstate(sc));
if(sc->sc_I430T4)
{
@ -246,10 +250,10 @@ F_AI8(struct l1_softc *sc)
{
T4_stop(sc);
DBGL1(L1_F_MSG, "F_AI8", ("FSM function F_AI8 executing\n"));
NDBGL1(L1_F_MSG, "FSM function F_AI8 executing");
if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S)
PH_Act_Ind(sc->sc_unit);
i4b_l1_ph_activate_ind(L0ISICUNIT(sc->sc_unit));
T3_stop(sc);
@ -258,12 +262,12 @@ F_AI8(struct l1_softc *sc)
i4b_trace_hdr_t hdr;
char info = INFO4_8;
hdr.unit = sc->sc_unit;
hdr.unit = L0ISICUNIT(sc->sc_unit);
hdr.type = TRC_CH_I;
hdr.dir = FROM_NT;
hdr.count = 0;
MICROTIME(hdr.time);
MPH_Trace_Ind(&hdr, 1, &info);
i4b_l1_trace_ind(&hdr, 1, &info);
}
}
@ -275,10 +279,10 @@ F_AI10(struct l1_softc *sc)
{
T4_stop(sc);
DBGL1(L1_F_MSG, "F_AI10", ("FSM function F_AI10 executing\n"));
NDBGL1(L1_F_MSG, "FSM function F_AI10 executing");
if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S)
PH_Act_Ind(sc->sc_unit);
i4b_l1_ph_activate_ind(L0ISICUNIT(sc->sc_unit));
T3_stop(sc);
@ -287,12 +291,12 @@ F_AI10(struct l1_softc *sc)
i4b_trace_hdr_t hdr;
char info = INFO4_10;
hdr.unit = sc->sc_unit;
hdr.unit = L0ISICUNIT(sc->sc_unit);
hdr.type = TRC_CH_I;
hdr.dir = FROM_NT;
hdr.count = 0;
MICROTIME(hdr.time);
MPH_Trace_Ind(&hdr, 1, &info);
i4b_l1_trace_ind(&hdr, 1, &info);
}
}
@ -302,19 +306,19 @@ F_AI10(struct l1_softc *sc)
static void
F_I01(struct l1_softc *sc)
{
DBGL1(L1_F_MSG, "F_I01", ("FSM function F_I01 executing\n"));
NDBGL1(L1_F_MSG, "FSM function F_I01 executing");
if(sc->sc_trace & TRACE_I)
{
i4b_trace_hdr_t hdr;
char info = INFO0;
hdr.unit = sc->sc_unit;
hdr.unit = L0ISICUNIT(sc->sc_unit);
hdr.type = TRC_CH_I;
hdr.dir = FROM_NT;
hdr.count = 0;
MICROTIME(hdr.time);
MPH_Trace_Ind(&hdr, 1, &info);
i4b_l1_trace_ind(&hdr, 1, &info);
}
}
@ -324,22 +328,22 @@ F_I01(struct l1_softc *sc)
static void
F_I02(struct l1_softc *sc)
{
DBGL1(L1_F_MSG, "F_I02", ("FSM function F_I02 executing\n"));
NDBGL1(L1_F_MSG, "FSM function F_I02 executing");
if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S)
PH_Deact_Ind(sc->sc_unit);
i4b_l1_ph_deactivate_ind(L0ISICUNIT(sc->sc_unit));
if(sc->sc_trace & TRACE_I)
{
i4b_trace_hdr_t hdr;
char info = INFO0;
hdr.unit = sc->sc_unit;
hdr.unit = L0ISICUNIT(sc->sc_unit);
hdr.type = TRC_CH_I;
hdr.dir = FROM_NT;
hdr.count = 0;
MICROTIME(hdr.time);
MPH_Trace_Ind(&hdr, 1, &info);
i4b_l1_trace_ind(&hdr, 1, &info);
}
}
@ -349,10 +353,10 @@ F_I02(struct l1_softc *sc)
static void
F_I03(struct l1_softc *sc)
{
DBGL1(L1_F_MSG, "F_I03", ("FSM function F_I03 executing\n"));
NDBGL1(L1_F_MSG, "FSM function F_I03 executing");
if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S)
PH_Deact_Ind(sc->sc_unit);
i4b_l1_ph_deactivate_ind(L0ISICUNIT(sc->sc_unit));
T4_start(sc);
@ -361,12 +365,12 @@ F_I03(struct l1_softc *sc)
i4b_trace_hdr_t hdr;
char info = INFO0;
hdr.unit = sc->sc_unit;
hdr.unit = L0ISICUNIT(sc->sc_unit);
hdr.type = TRC_CH_I;
hdr.dir = FROM_NT;
hdr.count = 0;
MICROTIME(hdr.time);
MPH_Trace_Ind(&hdr, 1, &info);
i4b_l1_trace_ind(&hdr, 1, &info);
}
}
@ -376,19 +380,19 @@ F_I03(struct l1_softc *sc)
static void
F_AR(struct l1_softc *sc)
{
DBGL1(L1_F_MSG, "F_AR", ("FSM function F_AR executing\n"));
NDBGL1(L1_F_MSG, "FSM function F_AR executing");
if(sc->sc_trace & TRACE_I)
{
i4b_trace_hdr_t hdr;
char info = INFO1_8;
hdr.unit = sc->sc_unit;
hdr.unit = L0ISICUNIT(sc->sc_unit);
hdr.type = TRC_CH_I;
hdr.dir = FROM_TE;
hdr.count = 0;
MICROTIME(hdr.time);
MPH_Trace_Ind(&hdr, 1, &info);
i4b_l1_trace_ind(&hdr, 1, &info);
}
isic_isac_l1_cmd(sc, CMD_AR8);
@ -402,19 +406,19 @@ F_AR(struct l1_softc *sc)
static void
F_I2(struct l1_softc *sc)
{
DBGL1(L1_F_MSG, "F_I2", ("FSM function F_I2 executing\n"));
NDBGL1(L1_F_MSG, "FSM function F_I2 executing");
if(sc->sc_trace & TRACE_I)
{
i4b_trace_hdr_t hdr;
char info = INFO2;
hdr.unit = sc->sc_unit;
hdr.unit = L0ISICUNIT(sc->sc_unit);
hdr.type = TRC_CH_I;
hdr.dir = FROM_NT;
hdr.count = 0;
MICROTIME(hdr.time);
MPH_Trace_Ind(&hdr, 1, &info);
i4b_l1_trace_ind(&hdr, 1, &info);
}
}
@ -425,7 +429,7 @@ F_I2(struct l1_softc *sc)
static void
F_ill(struct l1_softc *sc)
{
DBGL1(L1_F_ERR, "F_ill", ("FSM function F_ill executing\n"));
NDBGL1(L1_F_ERR, "FSM function F_ill executing");
}
/*---------------------------------------------------------------------------*
@ -434,7 +438,7 @@ F_ill(struct l1_softc *sc)
static void
F_NULL(struct l1_softc *sc)
{
DBGL1(L1_F_MSG, "F_NULL", ("FSM function F_NULL executing\n"));
NDBGL1(L1_F_MSG, "FSM function F_NULL executing");
}
@ -483,24 +487,25 @@ isic_next_state(struct l1_softc *sc, int event)
if(newstate >= N_STATES)
panic("i4b_l1fsm.c: newstate >= N_STATES\n");
DBGL1(L1_F_MSG, "isic_next_state", ("FSM event [%s]: [%s => %s]\n", event_text[event],
NDBGL1(L1_F_MSG, "FSM event [%s]: [%s => %s]", event_text[event],
state_text[currstate],
state_text[newstate]));
state_text[newstate]);
(*isic_state_tab[event][currstate].func)(sc);
if(newstate == ST_ILL)
{
newstate = ST_F3;
DBGL1(L1_F_ERR, "isic_next_state", ("FSM Illegal State ERROR, oldstate = %s, newstate = %s, event = %s!\n",
NDBGL1(L1_F_ERR, "FSM Illegal State ERROR, oldstate = %s, newstate = %s, event = %s!",
state_text[currstate],
state_text[newstate],
event_text[event]));
event_text[event]);
}
sc->sc_I430state = newstate;
}
#if DO_I4B_DEBUG
/*---------------------------------------------------------------------------*
* return pointer to current state description
*---------------------------------------------------------------------------*/
@ -509,6 +514,7 @@ isic_printstate(struct l1_softc *sc)
{
return((char *) state_text[sc->sc_I430state]);
}
#endif
#endif /* NISIC > 0 */

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999 Udo Schweigert. All rights reserved.
* Copyright (c) 1999, 2000 Udo Schweigert. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -37,11 +37,11 @@
* Siemens I-Surf 2.0 PnP specific routines for isic driver
* --------------------------------------------------------
*
* $Id: i4b_siemens_isurf.c,v 1.2 1999/12/13 21:25:26 hm Exp $
* $Id: i4b_siemens_isurf.c,v 1.3 2000/05/29 15:41:41 hm Exp $
*
* $FreeBSD$
*
* last edit-date: [Mon Dec 13 22:02:28 1999]
* last edit-date: [Mon May 29 16:46:31 2000]
*
*---------------------------------------------------------------------------*/
@ -51,6 +51,7 @@
#if NISIC > 0 && defined(SIEMENS_ISURF2)
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
@ -63,13 +64,13 @@
#include <machine/i4b_ioctl.h>
#include <i4b/include/i4b_global.h>
#include <i4b/include/i4b_l1l2.h>
/* #include <i4b/include/i4b_l1l2.h> */
#include <i4b/include/i4b_mbuf.h>
#include <i4b/layer1/i4b_l1.h>
#include <i4b/layer1/i4b_ipac.h>
#include <i4b/layer1/i4b_isac.h>
#include <i4b/layer1/i4b_hscx.h>
#include <i4b/layer1/isic/i4b_isic.h>
#include <i4b/layer1/isic/i4b_ipac.h>
#include <i4b/layer1/isic/i4b_isac.h>
#include <i4b/layer1/isic/i4b_hscx.h>
/* masks for register encoded in base addr */

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998 German Tischler. All rights reserved.
* Copyright (c) 1998, 2000 German Tischler. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -44,11 +44,11 @@
* isic - I4B Siemens ISDN Chipset Driver for SWS cards
* ====================================================
*
* $Id: i4b_sws.c,v 1.2 1999/12/13 21:25:26 hm Exp $
* $Id: i4b_sws.c,v 1.3 2000/05/29 15:41:41 hm Exp $
*
* $FreeBSD$
*
* last edit-date: [Mon Dec 13 22:02:39 1999]
* last edit-date: [Mon May 29 16:46:49 2000]
*
*---------------------------------------------------------------------------*/
@ -68,6 +68,7 @@
#define SWS_REGS 8 /* we use an area of 8 bytes for io */
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
@ -79,12 +80,12 @@
#include <machine/i4b_debug.h>
#include <machine/i4b_ioctl.h>
#include <i4b/layer1/i4b_l1.h>
#include <i4b/layer1/i4b_isac.h>
#include <i4b/layer1/i4b_hscx.h>
#include <i4b/layer1/isic/i4b_isic.h>
#include <i4b/layer1/isic/i4b_isac.h>
#include <i4b/layer1/isic/i4b_hscx.h>
#include <i4b/include/i4b_global.h>
#include <i4b/include/i4b_l1l2.h>
/* #include <i4b/include/i4b_l1l2.h> */
#include <i4b/include/i4b_mbuf.h>
/*---------------------------------------------------------------------------*

View File

@ -3,7 +3,7 @@
*
* Copyright (c) 1996 Gary Jennejohn. All rights reserved.
*
* Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved.
* Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -37,11 +37,11 @@
* isic - I4B Siemens ISDN Chipset Driver for Teles S0/16 and clones
* =================================================================
*
* $Id: i4b_tel_s016.c,v 1.3 1999/12/13 21:25:26 hm Exp $
* $Id: i4b_tel_s016.c,v 1.3 2000/05/29 15:41:41 hm Exp $
*
* $FreeBSD$
*
* last edit-date: [Mon Dec 13 22:02:47 1999]
* last edit-date: [Mon May 29 16:46:56 2000]
*
*---------------------------------------------------------------------------*/
@ -51,6 +51,7 @@
#if NISIC > 0 && defined(TEL_S0_16)
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
@ -63,12 +64,12 @@
#include <machine/i4b_debug.h>
#include <machine/i4b_ioctl.h>
#include <i4b/layer1/i4b_l1.h>
#include <i4b/layer1/i4b_isac.h>
#include <i4b/layer1/i4b_hscx.h>
#include <i4b/layer1/isic/i4b_isic.h>
#include <i4b/layer1/isic/i4b_isac.h>
#include <i4b/layer1/isic/i4b_hscx.h>
#include <i4b/include/i4b_global.h>
#include <i4b/include/i4b_l1l2.h>
/* #include <i4b/include/i4b_l1l2.h> */
#include <i4b/include/i4b_mbuf.h>
#define TELES_S016_MEMSIZE 0x1000

View File

@ -3,7 +3,7 @@
*
* Copyright (c) 1996 Gary Jennejohn. All rights reserved.
*
* Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved.
* Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -37,11 +37,11 @@
* isic - I4B Siemens ISDN Chipset Driver for Teles S0/16.3
* ========================================================
*
* $Id: i4b_tel_s0163.c,v 1.2 1999/12/13 21:25:27 hm Exp $
* $Id: i4b_tel_s0163.c,v 1.4 2000/05/29 15:41:41 hm Exp $
*
* $FreeBSD$
*
* last edit-date: [Mon Dec 13 22:02:55 1999]
* last edit-date: [Mon May 29 16:47:08 2000]
*
*---------------------------------------------------------------------------*/
@ -51,6 +51,7 @@
#if NISIC > 0 && defined(TEL_S0_16_3)
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
@ -62,12 +63,12 @@
#include <machine/i4b_debug.h>
#include <machine/i4b_ioctl.h>
#include <i4b/layer1/i4b_l1.h>
#include <i4b/layer1/i4b_isac.h>
#include <i4b/layer1/i4b_hscx.h>
#include <i4b/layer1/isic/i4b_isic.h>
#include <i4b/layer1/isic/i4b_isac.h>
#include <i4b/layer1/isic/i4b_hscx.h>
#include <i4b/include/i4b_global.h>
#include <i4b/include/i4b_l1l2.h>
/* #include <i4b/include/i4b_l1l2.h> */
#include <i4b/include/i4b_mbuf.h>
static u_char intr_no[] = { 1, 1, 0, 2, 4, 6, 1, 1, 1, 0, 8, 10, 12, 1, 1, 14 };
@ -291,8 +292,8 @@ isic_probe_s0163(device_t dev)
isic_detach_common(dev);
return ENXIO;
}
if ( b2 != 0x1c ) {
printf("isic%d: Error, signature 3 0x%x != 0x1c for Teles S0/16.3!\n",
if (( b2 != 0x1c ) && ( b2 != 0x1f )) {
printf("isic%d: Error, signature 3 0x%x != (0x1c || 0x1f) for Teles S0/16.3!\n",
unit, b2);
isic_detach_common(dev);
return ENXIO;

View File

@ -3,7 +3,7 @@
*
* Copyright (c) 1996 Gary Jennejohn. All rights reserved.
*
* Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved.
* Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -37,11 +37,11 @@
* isic - I4B Siemens ISDN Chipset Driver for Teles S0/8 and clones
* ================================================================
*
* $Id: i4b_tel_s08.c,v 1.2 1999/12/13 21:25:27 hm Exp $
* $Id: i4b_tel_s08.c,v 1.3 2000/05/29 15:41:41 hm Exp $
*
* $FreeBSD$
*
* last edit-date: [Mon Dec 13 22:03:06 1999]
* last edit-date: [Mon May 29 16:47:20 2000]
*
*---------------------------------------------------------------------------*/
@ -51,6 +51,7 @@
#if NISIC > 0 && defined(TEL_S0_8)
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
@ -63,12 +64,12 @@
#include <machine/i4b_debug.h>
#include <machine/i4b_ioctl.h>
#include <i4b/layer1/i4b_l1.h>
#include <i4b/layer1/i4b_isac.h>
#include <i4b/layer1/i4b_hscx.h>
#include <i4b/layer1/isic/i4b_isic.h>
#include <i4b/layer1/isic/i4b_isac.h>
#include <i4b/layer1/isic/i4b_hscx.h>
#include <i4b/include/i4b_global.h>
#include <i4b/include/i4b_l1l2.h>
/* #include <i4b/include/i4b_l1l2.h> */
#include <i4b/include/i4b_mbuf.h>
#define TELES_S08_MEMSIZE 0x1000

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved.
* Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -27,9 +27,11 @@
* i4b_usr_sti.c - USRobotics Sportster ISDN TA intern (Tina-pp)
* -------------------------------------------------------------
*
* $FreeBSD$
* $Id: i4b_usr_sti.c,v 1.3 2000/05/29 15:41:42 hm Exp $
*
* last edit-date: [Sun Feb 14 10:29:05 1999]
* $FreeBSD$
*
* last edit-date: [Mon May 29 16:47:26 2000]
*
*---------------------------------------------------------------------------*/
@ -37,16 +39,12 @@
#include "isic.h"
#include "opt_i4b.h"
#else
#define NISIC 1
#define NISIC 1
#endif
#if NISIC > 0 && defined(USR_STI)
#if (NISIC > 0) && defined(USR_STI)
#include <sys/param.h>
#if defined(__FreeBSD__) && __FreeBSD__ >= 3
#include <sys/ioccom.h>
#else
#include <sys/ioctl.h>
#endif
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
@ -74,9 +72,9 @@
#include <i4b/i4b_ioctl.h>
#endif
#include <i4b/layer1/i4b_l1.h>
#include <i4b/layer1/i4b_isac.h>
#include <i4b/layer1/i4b_hscx.h>
#include <i4b/layer1/isic/i4b_isic.h>
#include <i4b/layer1/isic/i4b_isac.h>
#include <i4b/layer1/isic/i4b_hscx.h>
#include <i4b/include/i4b_global.h>
@ -96,10 +94,6 @@ static u_char intr_no[] = { 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 3, 4, 5, 0, 6, 7 };
#ifdef __FreeBSD__
/* prototypes */
int isic_probe_usrtai __P((device_t));
int isic_attach_usrtai __P((device_t));
#define ADDR(reg) \
(((reg/4) * 1024) + ((reg%4) * 2))

View File

@ -1,386 +0,0 @@
/*
* Copyright (c) 1998 Ignatios Souvatzis. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* 4. Altered versions must be plainly marked as such, and must not be
* misrepresented as being the original software and/or documentation.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*---------------------------------------------------------------------------
*
* isic_supio.c - Amiga supio pseudo bus frontend for i4b_isic driver
* supports:
* - ISDN Blaster 5001/1
* - ISDN MasterII 5000/1
* - ISDN Master 2092/64
* But we attach to the supio, so just see "isic" or "isicII".
* -----------------------------------------------------------
*
* $FreeBSD$
*
* last edit-date: [Mon Mar 22 22:49:20 MET 1999]
*
* -is ISDN Master II support added.
* -is original implementation [Sun Feb 14 10:29:19 1999]
*
*---------------------------------------------------------------------------*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/errno.h>
#include <sys/syslog.h>
#include <sys/device.h>
#include <sys/socket.h>
#include <net/if.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <machine/cpu.h>
#include <machine/intr.h>
#include <machine/bus.h>
#include <amiga/dev/supio.h>
#include <i4b/i4b_ioctl.h>
#include <i4b/i4b_trace.h>
#include <i4b/include/i4b_global.h>
#include <i4b/include/i4b_l1l2.h>
#include <i4b/layer1/i4b_l1.h>
#include <i4b/layer1/i4b_hscx.h>
#include <i4b/layer1/i4b_isac.h>
/*static*/ int isic_supio_match __P((struct device *, struct cfdata *, void *));
/*static*/ void isic_supio_attach __P((struct device *, struct device *, void *));
/*static*/ u_int8_t aster_read_reg __P((struct isic_softc *sc, int what,
bus_size_t offs));
/*static*/ void aster_write_reg __P((struct isic_softc *sc, int what,
bus_size_t offs, u_int8_t data));
/*static*/ void aster_read_fifo __P((struct isic_softc *sc, int what,
void *buf, size_t size));
/*static*/ void aster_write_fifo __P((struct isic_softc *sc, int what,
const void *data, size_t size));
static int supio_isicattach __P((struct isic_softc *sc));
struct isic_supio_softc {
struct isic_softc sc_isic;
struct isr sc_isr;
struct bus_space_tag sc_bst;
};
struct cfattach isic_supio_ca = {
sizeof(struct isic_supio_softc), isic_supio_match, isic_supio_attach
};
/*
* Probe card
*/
/*static*/ int
isic_supio_match(parent, cf, aux)
struct device *parent;
struct cfdata *cf;
void *aux;
{
struct supio_attach_args *sap = aux;
/* ARGSUSED */
return (!strcmp("isic", sap->supio_name) ||
!strcmp("isicII", sap->supio_name));
}
int isic_supio_ipl = 2;
/*
* Attach the card
*/
/*static*/ void
isic_supio_attach(parent, self, aux)
struct device *parent, *self;
void *aux;
{
struct isic_supio_softc *ssc = (void *)self;
struct isic_softc *sc = &ssc->sc_isic;
struct supio_attach_args *sap = aux;
bus_space_tag_t bst;
bus_space_handle_t h;
int o1, o2;
/* setup parameters */
sc->sc_cardtyp = CARD_TYPEP_BLMASTER;
sc->sc_num_mappings = 3;
sc->sc_unit = sc->sc_dev.dv_unit; /* XXX ??? */
/* create io mappings */
MALLOC_MAPS(sc);
if (!strcmp(sap->supio_name, "isic")) {
o1 = 0x300;
o2 = 0x100;
} else /* "isic-II" */ {
o1 = 0x100;
o2 = 0x300;
}
bst = sap->supio_iot;
bus_space_map(bst, sap->supio_iobase, 0x400, 0, &h);
/* ISAC */
sc->sc_maps[0].t = bst;
sc->sc_maps[0].h = h;
sc->sc_maps[0].offset = o1/2;
sc->sc_maps[0].size = 0; /* foreign mapping, leave it alone */
/* HSCX A */
sc->sc_maps[1].t = bst;
sc->sc_maps[1].h = h;
sc->sc_maps[1].offset = o2/2;
sc->sc_maps[1].size = 0; /* foreign mapping, leave it alone */
/* HSCX B */
sc->sc_maps[2].t = bst;
sc->sc_maps[2].h = h;
sc->sc_maps[2].offset = (o2 + 0x80)/2;
sc->sc_maps[2].size = 0; /* foreign mapping, leave it alone */
sc->clearirq = NULL;
sc->readreg = aster_read_reg;
sc->writereg = aster_write_reg;
sc->readfifo = aster_read_fifo;
sc->writefifo = aster_write_fifo;
/* setup card type */
sc->sc_cardtyp = CARD_TYPEP_BLMASTER;
sc->sc_bustyp = BUS_TYPE_IOM2;
sc->sc_ipac = 0;
sc->sc_bfifolen = HSCX_FIFO_LEN;
/* enable RTS on HSCX A */
aster_write_reg(sc, ISIC_WHAT_HSCXA, H_MODE, HSCX_MODE_RTS);
/* MI initialization of card */
printf("\n");
supio_isicattach(sc);
ssc->sc_isr.isr_intr = isicintr;
ssc->sc_isr.isr_arg = sc;
ssc->sc_isr.isr_ipl = isic_supio_ipl; /* XXX */
add_isr(&ssc->sc_isr);
}
#if 0
int
isic_supiointr(p)
void *p;
{
/* XXX should test whether it is our interupt at all */
add_sicallback((sifunc_t)isicintr, p, NULL);
return 1;
}
#endif
/*static*/ void
aster_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size)
{
bus_space_tag_t t = sc->sc_maps[what].t;
bus_space_handle_t h = sc->sc_maps[what].h;
bus_size_t o = sc->sc_maps[what].offset;
bus_space_read_multi_1(t, h, o, buf, size);
}
/*static*/ void
aster_write_fifo(struct isic_softc *sc, int what, const void *buf, size_t size)
{
bus_space_tag_t t = sc->sc_maps[what].t;
bus_space_handle_t h = sc->sc_maps[what].h;
bus_size_t o = sc->sc_maps[what].offset;
bus_space_write_multi_1(t, h, o, (u_int8_t*)buf, size);
}
/*static*/ u_int8_t
aster_read_reg(struct isic_softc *sc, int what, bus_size_t offs)
{
bus_space_tag_t t = sc->sc_maps[what].t;
bus_space_handle_t h = sc->sc_maps[what].h;
bus_size_t o = sc->sc_maps[what].offset;
return bus_space_read_1(t, h, o + offs);
}
/*static*/ void
aster_write_reg(struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data)
{
bus_space_tag_t t = sc->sc_maps[what].t;
bus_space_handle_t h = sc->sc_maps[what].h;
bus_size_t o = sc->sc_maps[what].offset;
bus_space_write_1(t, h, o + offs, data);
}
/*---------------------------------------------------------------------------*
* card independend attach for pcmcia^Wsupio cards
* XXX this should be centralized!
*---------------------------------------------------------------------------*/
/*
* parameter and format for message producing e.g. "isic0: "
* there is no FreeBSD/Amiga, so just:
*/
#define ISIC_FMT "%s: "
#define ISIC_PARM sc->sc_dev.dv_xname
#define TERMFMT "\n"
int
supio_isicattach(struct isic_softc *sc)
{
static char *ISACversion[] = {
"2085 Version A1/A2 or 2086/2186 Version 1.1",
"2085 Version B1",
"2085 Version B2",
"2085 Version V2.3 (B3)",
"Unknown Version"
};
static char *HSCXversion[] = {
"82525 Version A1",
"Unknown (0x01)",
"82525 Version A2",
"Unknown (0x03)",
"82525 Version A3",
"82525 or 21525 Version 2.1",
"Unknown Version"
};
isic_sc[sc->sc_unit] = sc;
sc->sc_isac_version = 0;
sc->sc_isac_version = ((ISAC_READ(I_RBCH)) >> 5) & 0x03;
switch(sc->sc_isac_version)
{
case ISAC_VA:
case ISAC_VB1:
case ISAC_VB2:
case ISAC_VB3:
break;
default:
printf(ISIC_FMT "Error, ISAC version %d unknown!\n",
ISIC_PARM, sc->sc_isac_version);
return(0);
break;
}
sc->sc_hscx_version = HSCX_READ(0, H_VSTR) & 0xf;
switch(sc->sc_hscx_version)
{
case HSCX_VA1:
case HSCX_VA2:
case HSCX_VA3:
case HSCX_V21:
break;
default:
printf(ISIC_FMT "Error, HSCX version %d unknown!\n",
ISIC_PARM, sc->sc_hscx_version);
return(0);
break;
};
/* ISAC setup */
isic_isac_init(sc);
/* HSCX setup */
isic_bchannel_setup(sc->sc_unit, HSCX_CH_A, BPROT_NONE, 0);
isic_bchannel_setup(sc->sc_unit, HSCX_CH_B, BPROT_NONE, 0);
/* setup linktab */
isic_init_linktab(sc);
/* set trace level */
sc->sc_trace = TRACE_OFF;
sc->sc_state = ISAC_IDLE;
sc->sc_ibuf = NULL;
sc->sc_ib = NULL;
sc->sc_ilen = 0;
sc->sc_obuf = NULL;
sc->sc_op = NULL;
sc->sc_ol = 0;
sc->sc_freeflag = 0;
sc->sc_obuf2 = NULL;
sc->sc_freeflag2 = 0;
/* init higher protocol layers */
MPH_Status_Ind(sc->sc_unit, STI_ATTACH, sc->sc_cardtyp);
/* announce chip versions */
if(sc->sc_isac_version >= ISAC_UNKN)
{
printf(ISIC_FMT "ISAC Version UNKNOWN (VN=0x%x)" TERMFMT,
ISIC_PARM,
sc->sc_isac_version);
sc->sc_isac_version = ISAC_UNKN;
}
else
{
printf(ISIC_FMT "ISAC %s (IOM-%c)" TERMFMT,
ISIC_PARM,
ISACversion[sc->sc_isac_version],
sc->sc_bustyp == BUS_TYPE_IOM1 ? '1' : '2');
}
if(sc->sc_hscx_version >= HSCX_UNKN)
{
printf(ISIC_FMT "HSCX Version UNKNOWN (VN=0x%x)" TERMFMT,
ISIC_PARM,
sc->sc_hscx_version);
sc->sc_hscx_version = HSCX_UNKN;
}
else
{
printf(ISIC_FMT "HSCX %s" TERMFMT,
ISIC_PARM,
HSCXversion[sc->sc_hscx_version]);
}
return(1);
}

View File

@ -0,0 +1,224 @@
/*
* Copyright (c) 1999, 2000 Dave Boyce. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*---------------------------------------------------------------------------
*
* i4b_iwic - isdn4bsd Winbond W6692 driver
* ----------------------------------------
*
* $Id: i4b_iwic.h,v 1.5 2000/03/13 15:23:43 hm Exp $
*
* $FreeBSD$
*
* last edit-date: [Mon Mar 13 16:23:15 2000]
*
*---------------------------------------------------------------------------*/
#ifndef _I4B_IWIC_H_
#define _I4B_IWIC_H_
#include <i4b/layer1/iwic/i4b_iwic_ext.h>
/*---------------------------------------------------------------------------*
* PCI resources used
*---------------------------------------------------------------------------*/
#define INFO_IO_BASES 2
struct i4b_info {
struct resource * io_base[INFO_IO_BASES];
int io_rid [INFO_IO_BASES];
struct resource * irq;
int irq_rid;
struct resource * mem;
int mem_rid;
};
/*---------------------------------------------------------------------------*
* state of a B channel
*---------------------------------------------------------------------------*/
struct iwic_bchan
{
int unit; /* unit number */
int channel; /* channel number */
int offset; /* offset from iobase */
int bprot; /* b channel protocol used */
int state; /* transceiver state: */
#define ST_IDLE 0x00 /* channel idle */
#define ST_TX_ACTIVE 0x01 /* tx running */
int sc_trace_bcount;
/* receive data from ISDN */
struct ifqueue rx_queue; /* receiver queue */
int rxcount; /* rx statistics counter*/
struct mbuf *in_mbuf; /* rx input buffer */
u_char *in_cbptr; /* curr buffer pointer */
int in_len; /* rx input buffer len */
/* transmit data to ISDN */
struct ifqueue tx_queue; /* transmitter queue */
int txcount; /* tx statistics counter */
struct mbuf *out_mbuf_head; /* first mbuf in possible chain */
struct mbuf *out_mbuf_cur; /* current mbuf in possbl chain */
unsigned char *out_mbuf_cur_ptr; /* data pointer into mbuf */
int out_mbuf_cur_len; /* remaining bytes in mbuf */
/* linktab */
isdn_link_t iwic_isdn_linktab;
drvr_link_t *iwic_drvr_linktab;
};
/*---------------------------------------------------------------------------*
* state of a D channel
*---------------------------------------------------------------------------*/
struct iwic_dchan
{
int enabled;
int trace_count;
struct mbuf *ibuf;
u_char *ibuf_ptr; /* Input buffer pointer */
int ibuf_len; /* Current length of input buffer */
int ibuf_max_len; /* Max length in input buffer */
int rx_count;
int tx_ready; /* Can send next 64 bytes of data. */
int tx_count;
struct mbuf *obuf;
int free_obuf;
u_char *obuf_ptr;
int obuf_len;
struct mbuf *obuf2;
int free_obuf2;
};
/*---------------------------------------------------------------------------*
* state of one iwic unit
*---------------------------------------------------------------------------*/
struct iwic_softc
{
int sc_unit;
u_int32_t sc_iobase;
int sc_trace;
int sc_cardtyp;
int sc_I430state;
int sc_I430T3;
int enabled;
struct iwic_dchan sc_dchan;
struct iwic_bchan sc_bchan[2];
struct i4b_info sc_resources;
};
/*---------------------------------------------------------------------------*
* rd/wr register/fifo macros
*---------------------------------------------------------------------------*/
#define IWIC_READ(sc,reg) (inb ((sc)->sc_iobase + (u_int32_t)(reg)))
#define IWIC_WRITE(sc,reg,val) (outb ((sc)->sc_iobase + (u_int32_t)(reg), (val)))
#define IWIC_WRDFIFO(sc,p,l) (outsb ((sc)->sc_iobase + D_XFIFO, (p), (l)))
#define IWIC_RDDFIFO(sc,p,l) (insb ((sc)->sc_iobase + D_RFIFO, (p), (l)))
#define IWIC_WRBFIFO(sc,b,p,l) (outsb (((sc)->sc_iobase + (b)->offset + B_XFIFO), (p), (l)))
#define IWIC_RDBFIFO(sc,b,p,l) (insb (((sc)->sc_iobase + (b)->offset + B_RFIFO), (p), (l)))
/*---------------------------------------------------------------------------*
* possible I.430 states
*---------------------------------------------------------------------------*/
enum I430states
{
ST_F3N, /* F3 Deactivated, no clock */
ST_F3, /* F3 Deactivated */
ST_F4, /* F4 Awaiting Signal */
ST_F5, /* F5 Identifying Input */
ST_F6, /* F6 Synchronized */
ST_F7, /* F7 Activated */
ST_F8, /* F8 Lost Framing */
ST_ILL, /* Illegal State */
N_STATES
};
/*---------------------------------------------------------------------------*
* possible I.430 events
*---------------------------------------------------------------------------*/
enum I430events
{
EV_PHAR, /* PH ACTIVATE REQUEST */
EV_CE, /* Clock enabled */
EV_T3, /* Timer 3 expired */
EV_INFO0, /* receiving INFO0 */
EV_RSY, /* receiving any signal */
EV_INFO2, /* receiving INFO2 */
EV_INFO48, /* receiving INFO4 pri 8/9 */
EV_INFO410, /* receiving INFO4 pri 10/11 */
EV_DR, /* Deactivate Request */
EV_PU, /* Power UP */
EV_DIS, /* Disconnected (only 2085) */
EV_EI, /* Error Indication */
EV_ILL, /* Illegal Event */
N_EVENTS
};
/*---------------------------------------------------------------------------*
* available commands
*---------------------------------------------------------------------------*/
enum I430commands
{
CMD_ECK, /* Enable clock */
CMD_TIM, /* Timing */
CMD_RT, /* Reset */
CMD_AR8, /* Activation request pri 8 */
CMD_AR10, /* Activation request pri 10 */
CMD_DIU, /* Deactivate Indication Upstream */
CMD_ILL /* Illegal command */
};
extern struct iwic_softc iwic_sc[];
#define iwic_find_sc(unit) (&iwic_sc[(unit)])
extern void iwic_init(struct iwic_softc *);
extern void iwic_next_state(struct iwic_softc *, int);
extern void iwic_dchan_init(struct iwic_softc *);
extern void iwic_dchan_xirq(struct iwic_softc *);
extern void iwic_dchan_xfer_irq(struct iwic_softc *, int);
extern void iwic_dchan_disable(struct iwic_softc *sc);
extern int iwic_dchan_data_req(struct iwic_softc *sc, struct mbuf *m, int freeflag);
extern void iwic_dchan_transmit(struct iwic_softc *sc);
char *iwic_printstate(struct iwic_softc *sc);
void iwic_init_linktab(struct iwic_softc *sc);
void iwic_bchan_xirq(struct iwic_softc *, int);
void iwic_bchannel_setup(int unit, int h_chan, int bprot, int activate);
#endif /* _I4B_IWIC_H_ */

View File

@ -0,0 +1,749 @@
/*
* Copyright (c) 1999, 2000 Dave Boyce. All rights reserved.
*
* Copyright (c) 2000 Hellmuth Michaelis. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*---------------------------------------------------------------------------
*
* i4b_iwic - isdn4bsd Winbond W6692 driver
* ----------------------------------------
*
* $Id: i4b_iwic_bchan.c,v 1.8 2000/05/29 15:41:42 hm Exp $
*
* $FreeBSD$
*
* last edit-date: [Mon May 29 16:48:56 2000]
*
*---------------------------------------------------------------------------*/
#include "iwic.h"
#include "opt_i4b.h"
#include "pci.h"
#if (NIWIC > 0) && (NPCI > 0)
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <net/if.h>
#include <machine/clock.h>
#include <machine/i4b_debug.h>
#include <machine/i4b_ioctl.h>
#include <machine/i4b_trace.h>
#include <i4b/layer1/i4b_l1.h>
#include <i4b/layer1/iwic/i4b_iwic.h>
#include <i4b/layer1/iwic/i4b_w6692.h>
#include <i4b/include/i4b_global.h>
#include <i4b/include/i4b_mbuf.h>
static void iwic_bchan_init(struct iwic_softc *sc, int chan_no, int activate);
/*---------------------------------------------------------------------------*
* B-channel interrupt handler
*---------------------------------------------------------------------------*/
void
iwic_bchan_xirq(struct iwic_softc *sc, int chan_no)
{
int irq_stat;
struct iwic_bchan *chan;
int cmd = 0;
int activity = 0;
chan = &sc->sc_bchan[chan_no];
irq_stat = IWIC_READ(sc, chan->offset + B_EXIR);
NDBGL1(L1_H_IRQ, "irq_stat = 0x%x", irq_stat);
if((irq_stat & (B_EXIR_RMR | B_EXIR_RME | B_EXIR_RDOV | B_EXIR_XFR | B_EXIR_XDUN)) == 0)
{
NDBGL1(L1_H_XFRERR, "spurious IRQ!");
return;
}
if (irq_stat & B_EXIR_RDOV)
{
NDBGL1(L1_H_XFRERR, "RDOV");
}
if (irq_stat & B_EXIR_XDUN)
{
NDBGL1(L1_H_XFRERR, "XDUN");
}
/* RX message end interrupt */
if(irq_stat & B_EXIR_RME)
{
/* XXXX */ int error = 0;
register int fifo_data_len;
NDBGL1(L1_H_IRQ, "B_EXIR_RME");
fifo_data_len = ((IWIC_READ(sc,chan->offset+B_RBCL)) &
((IWIC_BCHAN_FIFO_LEN)-1));
if(fifo_data_len == 0)
fifo_data_len = IWIC_BCHAN_FIFO_LEN;
/* all error conditions checked, now decide and take action */
if(error == 0)
{
if(chan->in_mbuf == NULL)
{
if((chan->in_mbuf = i4b_Bgetmbuf(BCH_MAX_DATALEN)) == NULL)
panic("L1 iwic_bchan_irq: RME, cannot allocate mbuf!\n");
chan->in_cbptr = chan->in_mbuf->m_data;
chan->in_len = 0;
}
if((chan->in_len + fifo_data_len) <= BCH_MAX_DATALEN)
{
/* read data from fifo */
NDBGL1(L1_H_IRQ, "B_EXIR_RME, rd fifo, len = %d", fifo_data_len);
IWIC_RDBFIFO(sc, chan, chan->in_cbptr, fifo_data_len);
cmd |= (B_CMDR_RACK | B_CMDR_RACT);
IWIC_WRITE(sc, chan->offset + B_CMDR, cmd);
cmd = 0;
chan->in_len += fifo_data_len;
chan->rxcount += fifo_data_len;
/* setup mbuf data length */
chan->in_mbuf->m_len = chan->in_len;
chan->in_mbuf->m_pkthdr.len = chan->in_len;
if(sc->sc_trace & TRACE_B_RX)
{
i4b_trace_hdr_t hdr;
hdr.unit = L0IWICUNIT(sc->sc_unit);
hdr.type = (chan_no == IWIC_BCH_A ? TRC_CH_B1 : TRC_CH_B2);
hdr.dir = FROM_NT;
hdr.count = ++sc->sc_bchan[chan_no].sc_trace_bcount;
MICROTIME(hdr.time);
i4b_l1_trace_ind(&hdr, chan->in_mbuf->m_len, chan->in_mbuf->m_data);
}
(*chan->iwic_drvr_linktab->bch_rx_data_ready)(chan->iwic_drvr_linktab->unit);
activity = ACT_RX;
/* mark buffer ptr as unused */
chan->in_mbuf = NULL;
chan->in_cbptr = NULL;
chan->in_len = 0;
}
else
{
NDBGL1(L1_H_XFRERR, "RAWHDLC rx buffer overflow in RME, in_len=%d, fifolen=%d", chan->in_len, fifo_data_len);
chan->in_cbptr = chan->in_mbuf->m_data;
chan->in_len = 0;
cmd |= (B_CMDR_RRST | B_CMDR_RACK);
}
}
else
{
if (chan->in_mbuf != NULL)
{
i4b_Bfreembuf(chan->in_mbuf);
chan->in_mbuf = NULL;
chan->in_cbptr = NULL;
chan->in_len = 0;
}
cmd |= (B_CMDR_RRST | B_CMDR_RACK);
}
}
/* RX fifo full interrupt */
if(irq_stat & B_EXIR_RMR)
{
NDBGL1(L1_H_IRQ, "B_EXIR_RMR");
if(chan->in_mbuf == NULL)
{
if((chan->in_mbuf = i4b_Bgetmbuf(BCH_MAX_DATALEN)) == NULL)
panic("L1 iwic_bchan_irq: RMR, cannot allocate mbuf!\n");
chan->in_cbptr = chan->in_mbuf->m_data;
chan->in_len = 0;
}
chan->rxcount += IWIC_BCHAN_FIFO_LEN;
if((chan->in_len + IWIC_BCHAN_FIFO_LEN) <= BCH_MAX_DATALEN)
{
/* read data from fifo */
NDBGL1(L1_H_IRQ, "B_EXIR_RMR, rd fifo, len = max (64)");
IWIC_RDBFIFO(sc, chan, chan->in_cbptr, IWIC_BCHAN_FIFO_LEN);
chan->in_cbptr += IWIC_BCHAN_FIFO_LEN;
chan->in_len += IWIC_BCHAN_FIFO_LEN;
}
else
{
if(chan->bprot == BPROT_NONE)
{
/* setup mbuf data length */
chan->in_mbuf->m_len = chan->in_len;
chan->in_mbuf->m_pkthdr.len = chan->in_len;
if(sc->sc_trace & TRACE_B_RX)
{
i4b_trace_hdr_t hdr;
hdr.unit = L0IWICUNIT(sc->sc_unit);
hdr.type = (chan_no == IWIC_BCH_A ? TRC_CH_B1 : TRC_CH_B2);
hdr.dir = FROM_NT;
hdr.count = ++sc->sc_bchan[chan_no].sc_trace_bcount;
MICROTIME(hdr.time);
i4b_l1_trace_ind(&hdr, chan->in_mbuf->m_len, chan->in_mbuf->m_data);
}
/* silence detection */
if(!(i4b_l1_bchan_tel_silence(chan->in_mbuf->m_data, chan->in_mbuf->m_len)))
activity = ACT_RX;
if(!(IF_QFULL(&chan->rx_queue)))
{
IF_ENQUEUE(&chan->rx_queue, chan->in_mbuf);
}
else
{
i4b_Bfreembuf(chan->in_mbuf);
}
/* signal upper driver that data is available */
(*chan->iwic_drvr_linktab->bch_rx_data_ready)(chan->iwic_drvr_linktab->unit);
/* alloc new buffer */
if((chan->in_mbuf = i4b_Bgetmbuf(BCH_MAX_DATALEN)) == NULL)
panic("L1 iwic_bchan_irq: RMR, cannot allocate new mbuf!\n");
/* setup new data ptr */
chan->in_cbptr = chan->in_mbuf->m_data;
/* read data from fifo */
NDBGL1(L1_H_IRQ, "B_EXIR_RMR, rd fifo1, len = max (64)");
IWIC_RDBFIFO(sc, chan, chan->in_cbptr, IWIC_BCHAN_FIFO_LEN);
chan->in_cbptr += IWIC_BCHAN_FIFO_LEN;
chan->in_len = IWIC_BCHAN_FIFO_LEN;
chan->rxcount += IWIC_BCHAN_FIFO_LEN;
}
else
{
NDBGL1(L1_H_XFRERR, "RAWHDLC rx buffer overflow in RPF, in_len=%d", chan->in_len);
chan->in_cbptr = chan->in_mbuf->m_data;
chan->in_len = 0;
cmd |= (B_CMDR_RRST | B_CMDR_RACK);
}
}
/* command to release fifo space */
cmd |= B_CMDR_RACK;
}
/* TX interrupt */
if (irq_stat & B_EXIR_XFR)
{
/* transmit fifo empty, new data can be written to fifo */
int activity = -1;
int len;
int nextlen;
NDBGL1(L1_H_IRQ, "B_EXIR_XFR");
if(chan->out_mbuf_cur == NULL) /* last frame is transmitted */
{
IF_DEQUEUE(&chan->tx_queue, chan->out_mbuf_head);
if(chan->out_mbuf_head == NULL)
{
chan->state &= ~ST_TX_ACTIVE;
(*chan->iwic_drvr_linktab->bch_tx_queue_empty)(chan->iwic_drvr_linktab->unit);
}
else
{
chan->state |= ST_TX_ACTIVE;
chan->out_mbuf_cur = chan->out_mbuf_head;
chan->out_mbuf_cur_ptr = chan->out_mbuf_cur->m_data;
chan->out_mbuf_cur_len = chan->out_mbuf_cur->m_len;
if(sc->sc_trace & TRACE_B_TX)
{
i4b_trace_hdr_t hdr;
hdr.unit = L0IWICUNIT(sc->sc_unit);
hdr.type = (chan_no == IWIC_BCH_A ? TRC_CH_B1 : TRC_CH_B2);
hdr.dir = FROM_TE;
hdr.count = ++sc->sc_bchan[chan_no].sc_trace_bcount;
MICROTIME(hdr.time);
i4b_l1_trace_ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data);
}
if(chan->bprot == BPROT_NONE)
{
if(!(i4b_l1_bchan_tel_silence(chan->out_mbuf_cur->m_data, chan->out_mbuf_cur->m_len)))
activity = ACT_TX;
}
else
{
activity = ACT_TX;
}
}
}
len = 0;
while(chan->out_mbuf_cur && len != IWIC_BCHAN_FIFO_LEN)
{
nextlen = min(chan->out_mbuf_cur_len, IWIC_BCHAN_FIFO_LEN - len);
NDBGL1(L1_H_IRQ, "B_EXIR_XFR, wr fifo, len = %d", nextlen);
IWIC_WRBFIFO(sc, chan, chan->out_mbuf_cur_ptr, nextlen);
cmd |= B_CMDR_XMS;
len += nextlen;
chan->txcount += nextlen;
chan->out_mbuf_cur_ptr += nextlen;
chan->out_mbuf_cur_len -= nextlen;
if(chan->out_mbuf_cur_len == 0)
{
if((chan->out_mbuf_cur = chan->out_mbuf_cur->m_next) != NULL)
{
chan->out_mbuf_cur_ptr = chan->out_mbuf_cur->m_data;
chan->out_mbuf_cur_len = chan->out_mbuf_cur->m_len;
if(sc->sc_trace & TRACE_B_TX)
{
i4b_trace_hdr_t hdr;
hdr.unit = L0IWICUNIT(sc->sc_unit);
hdr.type = (chan_no == IWIC_BCH_A ? TRC_CH_B1 : TRC_CH_B2);
hdr.dir = FROM_TE;
hdr.count = ++sc->sc_bchan[chan_no].sc_trace_bcount;
MICROTIME(hdr.time);
i4b_l1_trace_ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data);
}
}
else
{
if (chan->bprot != BPROT_NONE)
cmd |= B_CMDR_XME;
i4b_Bfreembuf(chan->out_mbuf_head);
chan->out_mbuf_head = NULL;
}
}
}
}
if(cmd)
{
cmd |= B_CMDR_RACT;
IWIC_WRITE(sc, chan->offset + B_CMDR, cmd);
}
}
/*---------------------------------------------------------------------------*
* initialize one B channels rx/tx data structures
*---------------------------------------------------------------------------*/
void
iwic_bchannel_setup(int unit, int chan_no, int bprot, int activate)
{
struct iwic_softc *sc = &iwic_sc[unit];
struct iwic_bchan *chan = &sc->sc_bchan[chan_no];
int s = SPLI4B();
NDBGL1(L1_BCHAN, "unit %d, chan %d, bprot %d, activate %d", unit, chan_no, bprot, activate);
/* general part */
chan->bprot = bprot; /* B channel protocol */
chan->state = ST_IDLE; /* B channel state */
if(activate == 0)
{
/* deactivation */
iwic_bchan_init(sc, chan_no, activate);
}
/* receiver part */
i4b_Bcleanifq(&chan->rx_queue); /* clean rx queue */
chan->rx_queue.ifq_maxlen = IFQ_MAXLEN;
chan->rxcount = 0; /* reset rx counter */
i4b_Bfreembuf(chan->in_mbuf); /* clean rx mbuf */
chan->in_mbuf = NULL; /* reset mbuf ptr */
chan->in_cbptr = NULL; /* reset mbuf curr ptr */
chan->in_len = 0; /* reset mbuf data len */
/* transmitter part */
i4b_Bcleanifq(&chan->tx_queue); /* clean tx queue */
chan->tx_queue.ifq_maxlen = IFQ_MAXLEN;
chan->txcount = 0; /* reset tx counter */
i4b_Bfreembuf(chan->out_mbuf_head); /* clean tx mbuf */
chan->out_mbuf_head = NULL; /* reset head mbuf ptr */
chan->out_mbuf_cur = NULL; /* reset current mbuf ptr */
chan->out_mbuf_cur_ptr = NULL; /* reset current mbuf data ptr */
chan->out_mbuf_cur_len = 0; /* reset current mbuf data cnt */
if(activate != 0)
{
/* activation */
iwic_bchan_init(sc, chan_no, activate);
}
splx(s);
}
/*---------------------------------------------------------------------------*
* initalize / deinitialize B-channel hardware
*---------------------------------------------------------------------------*/
static void
iwic_bchan_init(struct iwic_softc *sc, int chan_no, int activate)
{
struct iwic_bchan *bchan = &sc->sc_bchan[chan_no];
NDBGL1(L1_BCHAN, "chan %d, activate %d", chan_no, activate);
if(activate)
{
if(bchan->bprot == BPROT_NONE)
{
/* Extended transparent mode */
IWIC_WRITE(sc, bchan->offset + B_MODE, B_MODE_MMS);
}
else
{
/* Transparent mode */
IWIC_WRITE(sc, bchan->offset + B_MODE, 0);
/* disable address comparation */
IWIC_WRITE (sc, bchan->offset+B_ADM1, 0xff);
IWIC_WRITE (sc, bchan->offset+B_ADM2, 0xff);
}
/* reset & start receiver */
IWIC_WRITE(sc, bchan->offset + B_CMDR, B_CMDR_RRST|B_CMDR_RACT);
/* clear irq mask */
IWIC_WRITE(sc, bchan->offset + B_EXIM, 0);
}
else
{
/* mask all irqs */
IWIC_WRITE(sc, bchan->offset + B_EXIM, 0xff);
/* reset mode */
IWIC_WRITE(sc, bchan->offset + B_MODE, 0);
/* Bring interface down */
IWIC_WRITE(sc, bchan->offset + B_CMDR, B_CMDR_RRST | B_CMDR_XRST);
/* Flush pending interrupts */
IWIC_READ(sc, bchan->offset + B_EXIR);
}
}
/*---------------------------------------------------------------------------*
* start transmission on a b channel
*---------------------------------------------------------------------------*/
static void
iwic_bchannel_start(int unit, int chan_no)
{
struct iwic_softc *sc = &iwic_sc[unit];
register struct iwic_bchan *chan = &sc->sc_bchan[chan_no];
register int next_len;
register int len;
int s;
int activity = -1;
int cmd = 0;
s = SPLI4B(); /* enter critical section */
NDBGL1(L1_BCHAN, "unit %d, channel %d", unit, chan_no);
if(chan->state & ST_TX_ACTIVE) /* already running ? */
{
splx(s);
return; /* yes, leave */
}
/* get next mbuf from queue */
IF_DEQUEUE(&chan->tx_queue, chan->out_mbuf_head);
if(chan->out_mbuf_head == NULL) /* queue empty ? */
{
splx(s); /* leave critical section */
return; /* yes, exit */
}
/* init current mbuf values */
chan->out_mbuf_cur = chan->out_mbuf_head;
chan->out_mbuf_cur_len = chan->out_mbuf_cur->m_len;
chan->out_mbuf_cur_ptr = chan->out_mbuf_cur->m_data;
/* activity indicator for timeout handling */
if(chan->bprot == BPROT_NONE)
{
if(!(i4b_l1_bchan_tel_silence(chan->out_mbuf_cur->m_data, chan->out_mbuf_cur->m_len)))
activity = ACT_TX;
}
else
{
activity = ACT_TX;
}
chan->state |= ST_TX_ACTIVE; /* we start transmitting */
if(sc->sc_trace & TRACE_B_TX) /* if trace, send mbuf to trace dev */
{
i4b_trace_hdr_t hdr;
hdr.unit = L0IWICUNIT(unit);
hdr.type = (chan_no == IWIC_BCH_A ? TRC_CH_B1 : TRC_CH_B2);
hdr.dir = FROM_TE;
hdr.count = ++sc->sc_bchan[chan_no].sc_trace_bcount;
MICROTIME(hdr.time);
i4b_l1_trace_ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data);
}
len = 0; /* # of chars put into tx fifo this time */
/*
* fill the tx fifo with data from the current mbuf. if
* current mbuf holds less data than fifo length, try to
* get the next mbuf from (a possible) mbuf chain. if there is
* not enough data in a single mbuf or in a chain, then this
* is the last mbuf and we tell the chip that it has to send
* CRC and closing flag
*/
while((len < IWIC_BCHAN_FIFO_LEN) && chan->out_mbuf_cur)
{
/*
* put as much data into the fifo as is
* available from the current mbuf
*/
if((len + chan->out_mbuf_cur_len) >= IWIC_BCHAN_FIFO_LEN)
next_len = IWIC_BCHAN_FIFO_LEN - len;
else
next_len = chan->out_mbuf_cur_len;
/* write what we have from current mbuf to fifo */
IWIC_WRBFIFO(sc, chan, chan->out_mbuf_cur_ptr, next_len);
len += next_len; /* update # of bytes written */
chan->txcount += next_len; /* statistics */
chan->out_mbuf_cur_ptr += next_len; /* data ptr */
chan->out_mbuf_cur_len -= next_len; /* data len */
/*
* in case the current mbuf (of a possible chain) data
* has been put into the fifo, check if there is a next
* mbuf in the chain. If there is one, get ptr to it
* and update the data ptr and the length
*/
if((chan->out_mbuf_cur_len <= 0) &&
((chan->out_mbuf_cur = chan->out_mbuf_cur->m_next) != NULL))
{
chan->out_mbuf_cur_ptr = chan->out_mbuf_cur->m_data;
chan->out_mbuf_cur_len = chan->out_mbuf_cur->m_len;
if(sc->sc_trace & TRACE_B_TX)
{
i4b_trace_hdr_t hdr;
hdr.unit = L0IWICUNIT(unit);
hdr.type = (chan_no == IWIC_BCH_A ? TRC_CH_B1 : TRC_CH_B2);
hdr.dir = FROM_TE;
hdr.count = ++sc->sc_bchan[chan_no].sc_trace_bcount;
MICROTIME(hdr.time);
i4b_l1_trace_ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data);
}
}
}
/*
* if there is either still data in the current mbuf and/or
* there is a successor on the chain available issue just
* a XTF (transmit) command to teh chip. if ther is no more
* data available from the current mbuf (-chain), issue
* an XTF and an XME (message end) command which will then
* send the CRC and the closing HDLC flag sequence
*/
if(chan->out_mbuf_cur && (chan->out_mbuf_cur_len > 0))
{
/*
* more data available, send current fifo out.
* next xfer to tx fifo is done in the
* interrupt routine.
*/
cmd |= B_CMDR_XMS;
}
else
{
/* end of mbuf chain */
if(chan->bprot == BPROT_NONE)
cmd |= B_CMDR_XMS;
else
cmd |= (B_CMDR_XMS | B_CMDR_XME);
i4b_Bfreembuf(chan->out_mbuf_head); /* free mbuf chain */
chan->out_mbuf_head = NULL;
chan->out_mbuf_cur = NULL;
chan->out_mbuf_cur_ptr = NULL;
chan->out_mbuf_cur_len = 0;
}
/* call timeout handling routine */
if(activity == ACT_RX || activity == ACT_TX)
(*chan->iwic_drvr_linktab->bch_activity)(chan->iwic_drvr_linktab->unit, activity);
if(cmd)
{
cmd |= B_CMDR_RACT;
IWIC_WRITE(sc, chan->offset + B_CMDR, cmd);
}
splx(s);
}
/*---------------------------------------------------------------------------*
*
*---------------------------------------------------------------------------*/
static void
iwic_bchannel_stat(int unit, int chan_no, bchan_statistics_t *bsp)
{
struct iwic_softc *sc = iwic_find_sc(unit);
struct iwic_bchan *bchan = &sc->sc_bchan[chan_no];
int s = SPLI4B();
bsp->outbytes = bchan->txcount;
bsp->inbytes = bchan->rxcount;
bchan->txcount = 0;
bchan->rxcount = 0;
splx(s);
}
/*---------------------------------------------------------------------------*
* initialize our local linktab
*---------------------------------------------------------------------------*/
void
iwic_init_linktab(struct iwic_softc *sc)
{
struct iwic_bchan *chan;
isdn_link_t *lt;
/* make sure the hardware driver is known to layer 4 */
ctrl_types[CTRL_PASSIVE].set_linktab = i4b_l1_set_linktab;
ctrl_types[CTRL_PASSIVE].get_linktab = i4b_l1_ret_linktab;
/* channel A */
chan = &sc->sc_bchan[IWIC_BCH_A];
lt = &chan->iwic_isdn_linktab;
lt->unit = sc->sc_unit;
lt->channel = IWIC_BCH_A;
lt->bch_config = iwic_bchannel_setup;
lt->bch_tx_start = iwic_bchannel_start;
lt->bch_stat = iwic_bchannel_stat;
lt->tx_queue = &chan->tx_queue;
/* used by non-HDLC data transfers, i.e. telephony drivers */
lt->rx_queue = &chan->rx_queue;
/* used by HDLC data transfers, i.e. ipr and isp drivers */
lt->rx_mbuf = &chan->in_mbuf;
/* channel B */
chan = &sc->sc_bchan[IWIC_BCH_B];
lt = &chan->iwic_isdn_linktab;
lt->unit = sc->sc_unit;
lt->channel = IWIC_BCH_B;
lt->bch_config = iwic_bchannel_setup;
lt->bch_tx_start = iwic_bchannel_start;
lt->bch_stat = iwic_bchannel_stat;
lt->tx_queue = &chan->tx_queue;
/* used by non-HDLC data transfers, i.e. telephony drivers */
lt->rx_queue = &chan->rx_queue;
/* used by HDLC data transfers, i.e. ipr and isp drivers */
lt->rx_mbuf = &chan->in_mbuf;
}
#endif /* NIWIC > 0 */

View File

@ -0,0 +1,494 @@
/*
* Copyright (c) 1999, 2000 Dave Boyce. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*---------------------------------------------------------------------------
*
* i4b_iwic - isdn4bsd Winbond W6692 driver
* ----------------------------------------
*
* $Id: i4b_iwic_dchan.c,v 1.5 2000/05/29 15:41:42 hm Exp $
*
* $FreeBSD$
*
* last edit-date: [Wed Mar 8 16:17:16 2000]
*
*---------------------------------------------------------------------------*/
#include "iwic.h"
#include "opt_i4b.h"
#include "pci.h"
#if (NIWIC > 0) && (NPCI > 0)
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <net/if.h>
#include <machine/clock.h>
#include <machine/i4b_debug.h>
#include <machine/i4b_ioctl.h>
#include <machine/i4b_trace.h>
#include <i4b/layer1/i4b_l1.h>
#include <i4b/include/i4b_global.h>
#include <i4b/include/i4b_l3l4.h>
#include <i4b/include/i4b_mbuf.h>
#include <i4b/layer1/iwic/i4b_iwic.h>
#include <i4b/layer1/iwic/i4b_w6692.h>
#define MAX_DFRAME_LEN 264
static void dchan_receive(struct iwic_softc *sc, int ista);
#ifdef NOTDEF
static void output_bytes(char *prefix, u_char * ptr, int len);
#endif
/*---------------------------------------------------------------------------*
*
*---------------------------------------------------------------------------*/
void
iwic_dchan_init(struct iwic_softc *sc)
{
sc->sc_dchan.ibuf = NULL;
sc->sc_dchan.rx_count = 0;
sc->sc_dchan.obuf = NULL;
sc->sc_dchan.obuf2 = NULL;
sc->sc_dchan.tx_count = 0;
sc->sc_dchan.tx_ready = 0;
IWIC_WRITE(sc, D_CTL, D_CTL_SRST);
DELAY(5000);
IWIC_WRITE(sc, D_CTL, 0);
IWIC_WRITE(sc, SQX, SQX_SCIE);
IWIC_WRITE(sc, PCTL, 0x00);
IWIC_WRITE(sc, MOCR, 0x00);
IWIC_WRITE(sc, GCR, 0x00);
IWIC_WRITE(sc, D_CMDR, D_CMDR_RRST | D_CMDR_XRST);
IWIC_WRITE(sc, D_MODE, D_MODE_RACT);
IWIC_WRITE(sc, D_SAM, 0xff);
IWIC_WRITE(sc, D_TAM, 0xff);
IWIC_WRITE(sc, D_EXIM, 0x00);
}
/*---------------------------------------------------------------------------*
*
*---------------------------------------------------------------------------*/
void
iwic_dchan_xirq(struct iwic_softc *sc)
{
int irq_stat;
int stat;
irq_stat = IWIC_READ(sc, D_EXIR);
if (irq_stat & D_EXIR_RDOV)
{
NDBGL1(L1_I_ERR, "RDOV in state %s", iwic_printstate(sc));
}
if (irq_stat & D_EXIR_XDUN)
{
NDBGL1(L1_I_ERR, "XDUN in state %s", iwic_printstate(sc));
sc->sc_dchan.tx_ready = 0;
}
if (irq_stat & D_EXIR_XCOL)
{
NDBGL1(L1_I_ERR, "XCOL in state %s", iwic_printstate(sc));
sc->sc_dchan.tx_ready = 0;
}
if (irq_stat & D_EXIR_TIN2)
{
NDBGL1(L1_I_ERR, "TIN2 in state %s", iwic_printstate(sc));
}
if (irq_stat & D_EXIR_MOC)
{
stat = IWIC_READ(sc, MOR);
NDBGL1(L1_I_ERR, "MOC in state %s, byte = 0x%x", iwic_printstate(sc), stat);
}
if (irq_stat & D_EXIR_ISC)
{
stat = (IWIC_READ(sc, CIR)) & 0x0f;
switch (stat)
{
case CIR_CE:
NDBGL1(L1_I_CICO, "rx CE in state %s", iwic_printstate(sc));
iwic_next_state(sc, EV_CE);
break;
case CIR_DRD:
NDBGL1(L1_I_CICO, "rx DRD in state %s", iwic_printstate(sc));
iwic_next_state(sc, EV_INFO0);
i4b_l1_mph_status_ind(L0IWICUNIT(sc->sc_unit), STI_L1STAT, LAYER_IDLE, NULL);
break;
case CIR_LD:
NDBGL1(L1_I_CICO, "rx LD in state %s", iwic_printstate(sc));
iwic_next_state(sc, EV_RSY);
break;
case CIR_ARD:
NDBGL1(L1_I_CICO, "rx ARD in state %s", iwic_printstate(sc));
iwic_next_state(sc, EV_INFO2);
break;
case CIR_TI:
NDBGL1(L1_I_CICO, "rx TI in state %s", iwic_printstate(sc));
iwic_next_state(sc, EV_INFO0);
break;
case CIR_ATI:
NDBGL1(L1_I_CICO, "rx ATI in state %s", iwic_printstate(sc));
iwic_next_state(sc, EV_INFO0);
break;
case CIR_AI8:
NDBGL1(L1_I_CICO, "rx AI8 in state %s", iwic_printstate(sc));
i4b_l1_mph_status_ind(L0IWICUNIT(sc->sc_unit), STI_L1STAT, LAYER_ACTIVE, NULL);
iwic_next_state(sc, EV_INFO48);
break;
case CIR_AI10:
NDBGL1(L1_I_CICO, "rx AI10 in state %s", iwic_printstate(sc));
i4b_l1_mph_status_ind(L0IWICUNIT(sc->sc_unit), STI_L1STAT, LAYER_ACTIVE, NULL);
iwic_next_state(sc, EV_INFO410);
break;
case CIR_CD:
NDBGL1(L1_I_CICO, "rx DIS in state %s", iwic_printstate(sc));
iwic_next_state(sc, EV_DIS);
break;
default:
NDBGL1(L1_I_ERR, "ERROR, unknown indication 0x%x in state %s", stat, iwic_printstate(sc));
iwic_next_state(sc, EV_INFO0);
break;
}
}
if (irq_stat & D_EXIR_TEXP)
{
NDBGL1(L1_I_ERR, "TEXP in state %s", iwic_printstate(sc));
}
if (irq_stat & D_EXIR_WEXP)
{
NDBGL1(L1_I_ERR, "WEXP in state %s", iwic_printstate(sc));
}
}
/*---------------------------------------------------------------------------*
* All receiving and transmitting takes place here.
*---------------------------------------------------------------------------*/
void
iwic_dchan_xfer_irq(struct iwic_softc *sc, int ista)
{
NDBGL1(L1_I_MSG, "ISTA = 0x%x", ista);
if (ista & (ISTA_D_RMR | ISTA_D_RME))
{
/* Receive message ready */
dchan_receive(sc, ista);
}
if (ista & ISTA_D_XFR)
{
/* Transmitter ready */
sc->sc_dchan.tx_ready = 1;
iwic_dchan_transmit(sc);
}
}
/*---------------------------------------------------------------------------*
*
*---------------------------------------------------------------------------*/
void
iwic_dchan_disable(struct iwic_softc *sc)
{
int s;
s = SPLI4B();
if (sc->sc_dchan.obuf)
{
if (sc->sc_dchan.free_obuf)
i4b_Dfreembuf(sc->sc_dchan.obuf);
sc->sc_dchan.obuf = NULL;
}
if (sc->sc_dchan.obuf2)
{
if (sc->sc_dchan.free_obuf2)
i4b_Dfreembuf(sc->sc_dchan.obuf2);
sc->sc_dchan.obuf2 = NULL;
}
splx(s);
IWIC_WRITE(sc, CIX, CIX_DRC);
}
/*---------------------------------------------------------------------------*
*
*---------------------------------------------------------------------------*/
int
iwic_dchan_data_req(struct iwic_softc *sc, struct mbuf *m, int freeflag)
{
int s;
if (!m)
return 0;
s = SPLI4B();
/* Queue message */
if (sc->sc_dchan.obuf)
{
if (sc->sc_dchan.obuf2)
{
NDBGL1(L1_I_ERR, "no buffer space!");
}
else
{
sc->sc_dchan.obuf2 = m;
sc->sc_dchan.free_obuf2 = freeflag;
}
}
else
{
sc->sc_dchan.obuf = m;
sc->sc_dchan.obuf_ptr = m->m_data;
sc->sc_dchan.obuf_len = m->m_len;
sc->sc_dchan.free_obuf = freeflag;
}
iwic_dchan_transmit(sc);
splx(s);
return (0);
}
/*---------------------------------------------------------------------------*
*
*---------------------------------------------------------------------------*/
static void
dchan_get_mbuf(struct iwic_softc *sc, int len)
{
sc->sc_dchan.ibuf = i4b_Dgetmbuf(len);
if (!sc->sc_dchan.ibuf)
panic("dchan_get_mbuf: unable to allocate %d bytes for mbuf!\n", len);
sc->sc_dchan.ibuf_ptr = sc->sc_dchan.ibuf->m_data;
sc->sc_dchan.ibuf_max_len = sc->sc_dchan.ibuf->m_len;
sc->sc_dchan.ibuf_len = 0;
}
/*---------------------------------------------------------------------------*
*
*---------------------------------------------------------------------------*/
static void
dchan_receive(struct iwic_softc *sc, int ista)
{
if (ista & ISTA_D_RMR)
{
/* Got 64 bytes in FIFO */
if (!sc->sc_dchan.ibuf)
{
dchan_get_mbuf(sc, MAX_DFRAME_LEN);
}
else if ((sc->sc_dchan.ibuf_len + MAX_DFRAME_LEN) >
sc->sc_dchan.ibuf_max_len)
{
/*XXX*/ panic("dchan_receive: not enough space in buffer!\n");
}
IWIC_RDDFIFO(sc, sc->sc_dchan.ibuf_ptr, 64);
sc->sc_dchan.ibuf_ptr += 64;
sc->sc_dchan.ibuf_len += 64;
sc->sc_dchan.rx_count += 64;
}
if (ista & ISTA_D_RME)
{
/* Got end of frame */
int hi, lo;
int total_frame_len;
int status;
lo = IWIC_READ(sc, D_RBCL);
hi = IWIC_READ(sc, D_RBCH);
total_frame_len = D_RBC(hi, lo);
lo = lo & 0x3f;
if (lo == 0)
lo = IWIC_DCHAN_FIFO_LEN;
if (!sc->sc_dchan.ibuf)
{
dchan_get_mbuf(sc, lo);
}
else if ((sc->sc_dchan.ibuf_len + lo) >
sc->sc_dchan.ibuf_max_len)
{
panic("dchan_receive: buffer not long enough");
}
IWIC_RDDFIFO(sc, sc->sc_dchan.ibuf_ptr, lo);
sc->sc_dchan.ibuf_len += lo;
sc->sc_dchan.rx_count += lo;
status = IWIC_READ(sc, D_RSTA);
if (status & (D_RSTA_RDOV | D_RSTA_CRCE | D_RSTA_RMB))
{
NDBGL1(L1_I_ERR, "bad read status 0x%x", status);
}
sc->sc_dchan.ibuf->m_len = sc->sc_dchan.ibuf_len;
if(sc->sc_trace & TRACE_D_RX)
{
i4b_trace_hdr_t hdr;
hdr.unit = L0IWICUNIT(sc->sc_unit);
hdr.type = TRC_CH_D;
hdr.dir = FROM_NT;
hdr.count = ++sc->sc_dchan.trace_count;
MICROTIME(hdr.time);
i4b_l1_trace_ind(&hdr, sc->sc_dchan.ibuf->m_len, sc->sc_dchan.ibuf->m_data);
}
i4b_l1_ph_data_ind(L0IWICUNIT(sc->sc_unit), sc->sc_dchan.ibuf);
sc->sc_dchan.ibuf = NULL;
}
IWIC_WRITE(sc, D_CMDR, D_CMDR_RACK);
}
/*---------------------------------------------------------------------------*
*
*---------------------------------------------------------------------------*/
void
iwic_dchan_transmit(struct iwic_softc *sc)
{
int cmd;
u_char *ptr;
int len;
if (!sc->sc_dchan.tx_ready)
return;
if (!sc->sc_dchan.obuf)
return;
if (sc->sc_I430state != ST_F7)
return;
ptr = sc->sc_dchan.obuf_ptr;
len = min(sc->sc_dchan.obuf_len, IWIC_DCHAN_FIFO_LEN);
if(sc->sc_trace & TRACE_D_TX)
{
i4b_trace_hdr_t hdr;
hdr.unit = L0IWICUNIT(sc->sc_unit);
hdr.type = TRC_CH_D;
hdr.dir = FROM_TE;
hdr.count = ++sc->sc_dchan.trace_count;
MICROTIME(hdr.time);
i4b_l1_trace_ind(&hdr, len, ptr);
}
IWIC_WRDFIFO(sc, ptr, len);
sc->sc_dchan.tx_count += len;
if (len < sc->sc_dchan.obuf_len)
{
sc->sc_dchan.obuf_ptr += len;
sc->sc_dchan.obuf_len -= len;
cmd = D_CMDR_XMS;
}
else
{
if (sc->sc_dchan.free_obuf)
i4b_Dfreembuf(sc->sc_dchan.obuf);
sc->sc_dchan.obuf = NULL;
sc->sc_dchan.obuf_ptr = NULL;
sc->sc_dchan.obuf_len = 0;
if (sc->sc_dchan.obuf2)
{
sc->sc_dchan.obuf = sc->sc_dchan.obuf2;
sc->sc_dchan.obuf_ptr = sc->sc_dchan.obuf->m_data;
sc->sc_dchan.obuf_len = sc->sc_dchan.obuf->m_len;
sc->sc_dchan.free_obuf = sc->sc_dchan.free_obuf2;
sc->sc_dchan.obuf2 = NULL;
}
cmd = D_CMDR_XMS | D_CMDR_XME;
}
sc->sc_dchan.tx_ready = 0;
IWIC_WRITE(sc, D_CMDR, cmd);
}
#ifdef NOTDEF
/*---------------------------------------------------------------------------*
*
*---------------------------------------------------------------------------*/
static void
output_bytes(char *prefix, u_char * ptr, int len)
{
char buf[400];
char tmp[10];
int i;
sprintf(buf, "%s bytes ", prefix);
for (i = 0; i < len; i++)
{
if (i != (len - 1))
sprintf(tmp, "0x%x, ", ptr[i] & 0xff);
else
sprintf(tmp, "0x%x", ptr[i] & 0xff);
strcat(buf, tmp);
}
strcat(buf, "\n";
printf(buf);
}
#endif
#endif

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2000 Hellmuth Michaelis. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*---------------------------------------------------------------------------
*
* i4b_iwic - isdn4bsd Winbond W6692 driver
* ----------------------------------------
*
* $Id: i4b_iwic_ext.h,v 1.4 2000/06/02 16:14:36 hm Exp $
*
* $FreeBSD$
*
* last edit-date: [Fri Jun 2 14:52:10 2000]
*
*---------------------------------------------------------------------------*/
#ifndef _I4B_IWIC_EXT_H_
#define _I4B_IWIC_EXT_H_
#include <i4b/include/i4b_l3l4.h>
void iwic_set_linktab(int unit, int channel, drvr_link_t * dlt);
isdn_link_t *iwic_ret_linktab(int unit, int channel);
int iwic_ph_data_req(int unit, struct mbuf *m, int freeflag);
int iwic_ph_activate_req(int unit);
int iwic_mph_command_req(int unit, int command, void *parm);
#endif /* _I4B_IWIC_EXT_H_ */

View File

@ -0,0 +1,235 @@
/*
* Copyright (c) 1999, 2000 Dave Boyce. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*---------------------------------------------------------------------------
*
* i4b_iwic - isdn4bsd Winbond W6692 driver
* ----------------------------------------
*
* $Id: i4b_iwic_fsm.c,v 1.4 2000/05/29 15:41:42 hm Exp $
*
* $FreeBSD$
*
* last edit-date: [Thu Apr 27 14:56:54 2000]
*
*---------------------------------------------------------------------------*/
#include "iwic.h"
#include "opt_i4b.h"
#include "pci.h"
#if (NIWIC > 0) && (NPCI > 0)
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <net/if.h>
#include <machine/clock.h>
#include <machine/i4b_debug.h>
#include <machine/i4b_ioctl.h>
#include <machine/i4b_trace.h>
#include <i4b/layer1/i4b_l1.h>
#include <i4b/include/i4b_global.h>
#include <i4b/include/i4b_l3l4.h>
#include <i4b/include/i4b_mbuf.h>
#include <i4b/layer1/iwic/i4b_iwic.h>
#include <i4b/layer1/iwic/i4b_w6692.h>
#if DO_I4B_DEBUG
static char *state_names[] = {
"F3N",
"F3",
"F4",
"F5",
"F6",
"F7",
"F8",
"ILLEGAL",
};
static char *event_names[] = {
"PHAR",
"CE",
"T3",
"INFO0",
"RSY",
"INFO2",
"INFO48",
"INFO410",
"DR",
"PU",
"DIS",
"EI",
"ILLEGAL"
};
#endif
/*---------------------------------------------------------------------------*
*
*---------------------------------------------------------------------------*/
static void
F_NULL(struct iwic_softc *sc)
{
NDBGL1(L1_F_MSG, "FSM function F_NULL executing");
}
/*---------------------------------------------------------------------------*
*
*---------------------------------------------------------------------------*/
static void
F_AR(struct iwic_softc *sc)
{
NDBGL1(L1_F_MSG, "FSM function F_AR executing");
IWIC_WRITE(sc, CIX, CIX_ECK);
}
/*---------------------------------------------------------------------------*
*
*---------------------------------------------------------------------------*/
static void
F_AR3(struct iwic_softc *sc)
{
NDBGL1(L1_F_MSG, "FSM function F_AR3 executing");
IWIC_WRITE(sc, CIX, CIX_AR8);
}
/*---------------------------------------------------------------------------*
*
*---------------------------------------------------------------------------*/
static void
F_I0I(struct iwic_softc *sc)
{
NDBGL1(L1_F_MSG, "FSM function F_IOI executing");
}
/*---------------------------------------------------------------------------*
*
*---------------------------------------------------------------------------*/
static void
F_I0A(struct iwic_softc *sc)
{
NDBGL1(L1_F_MSG, "FSM function F_IOA executing");
iwic_dchan_disable(sc);
i4b_l1_ph_deactivate_ind(L0IWICUNIT(sc->sc_unit));
}
/*---------------------------------------------------------------------------*
*
*---------------------------------------------------------------------------*/
static void
F_AI8(struct iwic_softc *sc)
{
NDBGL1(L1_F_MSG, "FSM function F_AI8 executing");
iwic_dchan_transmit(sc);
i4b_l1_ph_activate_ind(L0IWICUNIT(sc->sc_unit));
}
/*---------------------------------------------------------------------------*
*
*---------------------------------------------------------------------------*/
static void
F_AI10(struct iwic_softc *sc)
{
NDBGL1(L1_F_MSG, "FSM function F_AI10 executing");
iwic_dchan_transmit(sc);
i4b_l1_ph_activate_ind(L0IWICUNIT(sc->sc_unit));
}
/*---------------------------------------------------------------------------*
*
*---------------------------------------------------------------------------*/
struct iwic_state_tab {
void (*func) (struct iwic_softc *sc); /* function to execute */
int newstate; /* next state */
} iwic_state_tab[N_EVENTS][N_STATES] = {
/* STATE: F3N F3 F4 F5 F6 F7 F8 ILLEGAL STATE */
/* ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ */
/* EV_PHAR */ {{F_AR, ST_F3 }, {F_AR3, ST_F4 }, {F_NULL, ST_F4 }, {F_NULL, ST_F5 }, {F_NULL, ST_F6 }, {F_NULL, ST_F7 }, {F_NULL, ST_F8 }, {F_NULL, ST_ILL }},
/* EV_CE */ {{F_NULL, ST_F3 }, {F_AR3, ST_F4 }, {F_NULL, ST_F4 }, {F_NULL, ST_F4 }, {F_NULL, ST_F4 }, {F_NULL, ST_F4 }, {F_NULL, ST_F4 }, {F_NULL, ST_ILL }},
/* EV_T3 */ {{F_NULL, ST_F3N }, {F_NULL, ST_F3 }, {F_NULL, ST_F3 }, {F_NULL, ST_F3 }, {F_NULL, ST_F3 }, {F_NULL, ST_F7 }, {F_NULL, ST_F8 }, {F_NULL, ST_ILL }},
/* EV_INFO0 */ {{F_I0I, ST_F3 }, {F_I0I, ST_F3 }, {F_I0I, ST_F3 }, {F_I0I, ST_F3 }, {F_I0A, ST_F3 }, {F_I0A, ST_F3 }, {F_I0A, ST_F3 }, {F_NULL, ST_ILL }},
/* EV_RSY */ {{F_NULL, ST_F3 }, {F_NULL, ST_F5 }, {F_NULL, ST_F5 }, {F_NULL, ST_F5 }, {F_NULL, ST_F8 }, {F_NULL, ST_F8 }, {F_NULL, ST_F8 }, {F_NULL, ST_ILL }},
/* EV_INFO2 */ {{F_NULL, ST_F6 }, {F_NULL, ST_F6 }, {F_NULL, ST_F6 }, {F_NULL, ST_F6 }, {F_NULL, ST_F6 }, {F_NULL, ST_F6 }, {F_NULL, ST_F6 }, {F_NULL, ST_ILL }},
/* EV_INFO48 */ {{F_AI8 , ST_F7 }, {F_AI8, ST_F7 }, {F_AI8, ST_F7 }, {F_AI8, ST_F7 }, {F_AI8, ST_F7 }, {F_AI8, ST_F7 }, {F_AI8, ST_F7 }, {F_NULL, ST_ILL }},
/* EV_INFO410*/ {{F_AI10, ST_F7 }, {F_AI10, ST_F7 }, {F_AI10, ST_F7 }, {F_AI10, ST_F7 }, {F_AI10, ST_F7 }, {F_AI10, ST_F7 }, {F_AI10, ST_F7 }, {F_NULL, ST_ILL }},
/* EV_DR */ {{F_NULL, ST_F3 }, {F_NULL, ST_F3 }, {F_NULL, ST_F4 }, {F_NULL, ST_F5 }, {F_NULL, ST_F6 }, {F_NULL, ST_F7 }, {F_NULL, ST_F8 }, {F_NULL, ST_ILL }},
/* EV_PU */ {{F_NULL, ST_F3 }, {F_NULL, ST_F3 }, {F_NULL, ST_F4 }, {F_NULL, ST_F5 }, {F_NULL, ST_F6 }, {F_NULL, ST_F7 }, {F_NULL, ST_F8 }, {F_NULL, ST_ILL }},
/* EV_DIS */ {{F_NULL, ST_F3N }, {F_NULL, ST_F3N }, {F_NULL, ST_F3N }, {F_NULL, ST_F3N }, {F_NULL, ST_F3N }, {F_I0A, ST_F3N }, {F_I0A, ST_F3N }, {F_NULL, ST_ILL }},
/* EV_EI */ {{F_NULL, ST_F3 }, {F_NULL, ST_F3 }, {F_NULL, ST_F3 }, {F_NULL, ST_F3 }, {F_NULL, ST_F3 }, {F_NULL, ST_F3 }, {F_NULL, ST_F3 }, {F_NULL, ST_ILL }},
/* EV_ILL */ {{F_NULL, ST_ILL }, {F_NULL, ST_ILL }, {F_NULL, ST_ILL }, {F_NULL, ST_ILL }, {F_NULL, ST_ILL }, {F_NULL, ST_ILL }, {F_NULL, ST_ILL }, {F_NULL, ST_ILL }},
};
/*---------------------------------------------------------------------------*
*
*---------------------------------------------------------------------------*/
void
iwic_next_state(struct iwic_softc *sc, int event)
{
int currstate, newstate;
NDBGL1(L1_F_MSG, "event %s", event_names[event]);
if (event >= N_EVENTS)
{
printf("iwic_next_state: event >= N_EVENTS\n");
return;
}
currstate = sc->sc_I430state;
newstate = iwic_state_tab[event][currstate].newstate;
if (newstate >= N_STATES)
{
printf("iwic_next_state: newstate >= N_STATES\n");
return;
}
NDBGL1(L1_F_MSG, "state %s -> %s",
state_names[currstate], state_names[newstate]);
sc->sc_I430state = newstate;
(*iwic_state_tab[event][currstate].func) (sc);
}
#if DO_I4B_DEBUG
/*---------------------------------------------------------------------------*
* return pointer to current state description
*---------------------------------------------------------------------------*/
char *
iwic_printstate(struct iwic_softc *sc)
{
return((char *)state_names[sc->sc_I430state]);
}
#endif
#endif

View File

@ -0,0 +1,166 @@
/*
* Copyright (c) 1999, 2000 Dave Boyce. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*---------------------------------------------------------------------------
*
* i4b_iwic - isdn4bsd Winbond W6692 driver
* ----------------------------------------
*
* $Id: i4b_iwic_l1if.c,v 1.3 2000/06/02 16:14:36 hm Exp $
*
* $FreeBSD$
*
* last edit-date: [Fri Jun 2 14:52:39 2000]
*
*---------------------------------------------------------------------------*/
#include "iwic.h"
#include "opt_i4b.h"
#include "pci.h"
#if (NIWIC > 0) && (NPCI > 0)
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <net/if.h>
#include <machine/clock.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <sys/bus.h>
#include <sys/rman.h>
#include <pci/pcireg.h>
#include <pci/pcivar.h>
#include <machine/i4b_debug.h>
#include <machine/i4b_ioctl.h>
#include <machine/i4b_trace.h>
#include <i4b/include/i4b_global.h>
#include <i4b/include/i4b_l3l4.h>
#include <i4b/include/i4b_mbuf.h>
#include <i4b/layer1/i4b_l1.h>
#include <i4b/layer1/iwic/i4b_iwic.h>
#include <i4b/layer1/iwic/i4b_iwic_ext.h>
#include <i4b/layer1/iwic/i4b_w6692.h>
/* jump table for multiplex routines */
struct i4b_l1mux_func iwic_l1mux_func = {
iwic_ret_linktab,
iwic_set_linktab,
iwic_mph_command_req,
iwic_ph_data_req,
iwic_ph_activate_req,
};
/*---------------------------------------------------------------------------*
*
*---------------------------------------------------------------------------*/
int
iwic_ph_data_req(int unit, struct mbuf *m, int freeflag)
{
struct iwic_softc *sc = iwic_find_sc(unit);
return iwic_dchan_data_req(sc, m, freeflag);
}
/*---------------------------------------------------------------------------*
*
*---------------------------------------------------------------------------*/
int
iwic_ph_activate_req(int unit)
{
struct iwic_softc *sc = iwic_find_sc(unit);
iwic_next_state(sc, EV_PHAR);
return 0;
}
/*---------------------------------------------------------------------------*
*
*---------------------------------------------------------------------------*/
int
iwic_mph_command_req(int unit, int command, void *parm)
{
struct iwic_softc *sc = iwic_find_sc(unit);
switch (command)
{
case CMR_DOPEN: /* Daemon running */
NDBGL1(L1_PRIM, "CMR_DOPEN");
sc->enabled = TRUE;
break;
case CMR_DCLOSE: /* Daemon not running */
NDBGL1(L1_PRIM, "CMR_DCLOSE");
sc->enabled = FALSE;
break;
case CMR_SETTRACE:
NDBGL1(L1_PRIM, "CMR_SETTRACE, parm = %d", (unsigned int)parm);
sc->sc_trace = (unsigned int)parm;
break;
default:
NDBGL1(L1_PRIM, "unknown command = %d", command);
break;
}
return 0;
}
/*---------------------------------------------------------------------------*
*
*---------------------------------------------------------------------------*/
isdn_link_t *
iwic_ret_linktab(int unit, int channel)
{
struct iwic_softc *sc = iwic_find_sc(unit);
struct iwic_bchan *bchan = &sc->sc_bchan[channel];
return &bchan->iwic_isdn_linktab;
}
/*---------------------------------------------------------------------------*
*
*---------------------------------------------------------------------------*/
void
iwic_set_linktab (int unit, int channel, drvr_link_t *dlt)
{
struct iwic_softc *sc = iwic_find_sc(unit);
struct iwic_bchan *bchan = &sc->sc_bchan[channel];
bchan->iwic_drvr_linktab = dlt;
}
#endif

View File

@ -0,0 +1,317 @@
/*
* Copyright (c) 1999, 2000 Dave Boyce. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*---------------------------------------------------------------------------
*
* i4b_iwic - isdn4bsd Winbond W6692 driver
* ----------------------------------------
*
* $Id: i4b_iwic_pci.c,v 1.14 2000/09/04 09:08:45 hm Exp $
*
* $FreeBSD$
*
* last edit-date: [Mon Sep 4 09:49:03 2000]
*
*---------------------------------------------------------------------------*/
#include "iwic.h"
#include "opt_i4b.h"
#include "pci.h"
#if (NIWIC > 0) && (NPCI > 0)
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <net/if.h>
#include <machine/clock.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <sys/bus.h>
#include <sys/rman.h>
#include <pci/pcireg.h>
#include <pci/pcivar.h>
#include <machine/i4b_debug.h>
#include <machine/i4b_ioctl.h>
#include <machine/i4b_trace.h>
#include <i4b/include/i4b_global.h>
#include <i4b/include/i4b_l3l4.h>
#include <i4b/include/i4b_mbuf.h>
#include <i4b/layer1/i4b_l1.h>
#include <i4b/layer1/iwic/i4b_iwic.h>
#include <i4b/layer1/iwic/i4b_iwic_ext.h>
#include <i4b/layer1/iwic/i4b_w6692.h>
extern struct i4b_l1mux_func iwic_l1mux_func;
/* Winbond PCI Configuration Space */
#define BASEREG0_MAPOFF 0x00
#define BASEREG1_MAPOFF 0x04
#define BADDR0 (PCIR_MAPS + BASEREG0_MAPOFF)
#define BADDR1 (PCIR_MAPS + BASEREG1_MAPOFF)
static void iwic_pci_intr(struct iwic_softc *sc);
static int iwic_pci_probe(device_t dev);
static int iwic_pci_attach(device_t dev);
static device_method_t iwic_pci_methods[] =
{
DEVMETHOD(device_probe, iwic_pci_probe),
DEVMETHOD(device_attach, iwic_pci_attach),
{ 0, 0 }
};
static driver_t iwic_pci_driver =
{
"iwic",
iwic_pci_methods,
0
};
static devclass_t iwic_pci_devclass;
DRIVER_MODULE(iwic, pci, iwic_pci_driver, iwic_pci_devclass, 0, 0);
#define IWIC_MAXUNIT 4
struct iwic_softc iwic_sc[IWIC_MAXUNIT];
/*---------------------------------------------------------------------------*
* PCI ID list for ASUSCOM card got from Asuscom in March 2000:
*
* Vendor ID: 0675 Device ID: 1702
* Vendor ID: 0675 Device ID: 1703
* Vendor ID: 0675 Device ID: 1707
* Vendor ID: 10CF Device ID: 105E
* Vendor ID: 1043 Device ID: 0675 SubVendor: 144F SubDevice ID: 2000
* Vendor ID: 1043 Device ID: 0675 SubVendor: 144F SubDevice ID: 1702
* Vendor ID: 1043 Device ID: 0675 SubVendor: 144F SubDevice ID: 1707
* Vendor ID: 1043 Device ID: 0675 SubVendor: 1043 SubDevice ID: 1702
* Vendor ID: 1043 Device ID: 0675 SubVendor: 1043 SubDevice ID: 1707
* Vendor ID: 1050 Device ID: 6692 SubVendor: 0675 SubDevice ID: 1702
*---------------------------------------------------------------------------*/
static struct winids {
u_int32_t type;
int sv;
int sd;
const char *desc;
} win_ids[] = {
{ 0x66921050, -1, -1, "Generic Winbond W6692 ISDN PCI (0x66921050)" },
{ 0x17020675, -1, -1, "ASUSCOM P-IN100-ST-D (Winbond W6692, 0x17020675)" },
{ 0x17030675, -1, -1, "ASUSCOM P-IN100-ST-D (Winbond W6692, 0x17030675)" },
{ 0x17070675, -1, -1, "ASUSCOM P-IN100-ST-D (Winbond W6692, 0x17070675)" },
{ 0x105e10cf, -1, -1, "ASUSCOM P-IN100-ST-D (Winbond W6692, 0x105e10cf)" },
{ 0x06751043, 0x144F, 0x2000, "ASUSCOM P-IN100-ST-D (Winbond W6692, 0x06751043)" },
{ 0x06751043, 0x144F, 0x1702, "ASUSCOM P-IN100-ST-D (Winbond W6692, 0x06751043)" },
{ 0x06751043, 0x144F, 0x1707, "ASUSCOM P-IN100-ST-D (Winbond W6692, 0x06751043)" },
{ 0x06751043, 0x1443, 0x1702, "ASUSCOM P-IN100-ST-D (Winbond W6692, 0x06751043)" },
{ 0x06751043, 0x1443, 0x1707, "ASUSCOM P-IN100-ST-D (Winbond W6692, 0x06751043)" },
{ 0x06751043, 0x144F, 0x2000, "ASUSCOM P-IN100-ST-D (Winbond W6692, 0x06751043)" },
{ 0x06751043, 0x144F, 0x2000, "ASUSCOM P-IN100-ST-D (Winbond W6692, 0x06751043)" },
{ 0x06751043, 0x144F, 0x2000, "ASUSCOM P-IN100-ST-D (Winbond W6692, 0x06751043)" },
{ 0x00000000, 0, 0, NULL }
};
/*---------------------------------------------------------------------------*
* iwic PCI probe
*---------------------------------------------------------------------------*/
static int
iwic_pci_probe(device_t dev)
{
u_int32_t type = pci_get_devid(dev);
u_int32_t sv = pci_get_subvendor(dev);
u_int32_t sd = pci_get_subdevice(dev);
struct winids *wip = win_ids;
while(wip->type)
{
if(wip->type == type)
{
if(((wip->sv == -1) && (wip->sd == -1)) ||
((wip->sv == sv) && (wip->sd == sd)))
break;
}
++wip;
}
if(wip->desc)
{
if(bootverbose)
{
printf("iwic_pci_probe: vendor = 0x%x, device = 0x%x\n", pci_get_vendor(dev), pci_get_device(dev));
printf("iwic_pci_probe: subvendor = 0x%x, subdevice = 0x%x\n", sv, sd);
}
device_set_desc(dev, wip->desc);
return(0);
}
else
{
return(ENXIO);
}
}
/*---------------------------------------------------------------------------*
* PCI attach
*---------------------------------------------------------------------------*/
static int
iwic_pci_attach(device_t dev)
{
unsigned short iobase;
struct iwic_softc *sc;
void *ih = 0;
int unit = device_get_unit(dev);
struct iwic_bchan *bchan;
/* check max unit range */
if(unit >= IWIC_MAXUNIT)
{
printf("iwic%d: Error, unit %d >= IWIC_MAXUNIT!\n", unit, unit);
return(ENXIO);
}
sc = iwic_find_sc(unit); /* get softc */
sc->sc_unit = unit;
/* use the i/o mapped base address */
sc->sc_resources.io_rid[0] = BADDR1;
if(!(sc->sc_resources.io_base[0] =
bus_alloc_resource(dev, SYS_RES_IOPORT,
&sc->sc_resources.io_rid[0],
0UL, ~0UL, 1, RF_ACTIVE)))
{
printf("iwic%d: Couldn't alloc io port!\n", unit);
return(ENXIO);
}
iobase = rman_get_start(sc->sc_resources.io_base[0]);
if(!(sc->sc_resources.irq =
bus_alloc_resource(dev, SYS_RES_IRQ,
&sc->sc_resources.irq_rid,
0UL, ~0UL, 1, RF_SHAREABLE|RF_ACTIVE)))
{
printf("iwic%d: Couldn't alloc irq!\n",unit);
return(ENXIO);
}
/* setup card type */
sc->sc_cardtyp = CARD_TYPEP_WINB6692;
sc->sc_iobase = (u_int32_t) iobase;
sc->sc_trace = TRACE_OFF;
sc->sc_I430state = ST_F3N; /* Deactivated */
sc->enabled = FALSE;
if(bus_setup_intr(dev, sc->sc_resources.irq, INTR_TYPE_NET,
(void(*)(void*))iwic_pci_intr,
sc, &ih))
{
printf("iwic%d: Couldn't set up irq!\n", unit);
return(ENXIO);
}
/* disable interrupts */
IWIC_WRITE(sc, IMASK, 0xff);
iwic_dchan_init(sc);
bchan = &sc->sc_bchan[IWIC_BCH_A];
bchan->unit = unit;
bchan->offset = B1_CHAN_OFFSET;
bchan->channel = IWIC_BCH_A;
bchan->state = ST_IDLE;
iwic_bchannel_setup(unit, IWIC_BCH_A, BPROT_NONE, 0);
bchan = &sc->sc_bchan[IWIC_BCH_B];
bchan->unit = unit;
bchan->offset = B2_CHAN_OFFSET;
bchan->channel = IWIC_BCH_B;
bchan->state = ST_IDLE;
iwic_bchannel_setup(unit, IWIC_BCH_B, BPROT_NONE, 0);
iwic_init_linktab(sc);
i4b_l1_mph_status_ind(L0IWICUNIT(sc->sc_unit), STI_ATTACH, sc->sc_cardtyp, &iwic_l1mux_func);
IWIC_READ(sc, ISTA);
/* Enable interrupts */
IWIC_WRITE(sc, IMASK, IMASK_XINT0 | IMASK_XINT1);
return(0);
}
/*---------------------------------------------------------------------------*
* IRQ handler
*---------------------------------------------------------------------------*/
static void
iwic_pci_intr(struct iwic_softc *sc)
{
while (1)
{
int irq_stat = IWIC_READ(sc, ISTA);
if (irq_stat == 0)
break;
if (irq_stat & (ISTA_D_RME | ISTA_D_RMR | ISTA_D_XFR))
{
iwic_dchan_xfer_irq(sc, irq_stat);
}
if (irq_stat & ISTA_D_EXI)
{
iwic_dchan_xirq(sc);
}
if (irq_stat & ISTA_B1_EXI)
{
iwic_bchan_xirq(sc, 0);
}
if (irq_stat & ISTA_B2_EXI)
{
iwic_bchan_xirq(sc, 1);
}
}
}
#endif

View File

@ -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_ */

View File

@ -1,339 +0,0 @@
/*
* Copyright (c) 1998,1999 Martin Husemann. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* 4. Altered versions must be plainly marked as such, and must not be
* misrepresented as being the original software and/or documentation.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*---------------------------------------------------------------------------
*
* pci_isic.c - pcmcia bus frontend for i4b_isic driver
* -------------------------------------------------------
*
* $FreeBSD$
*
* last edit-date: [Wed Mar 10 07:22:08 1999]
*
* -mh original implementation
* -mh added support for Fritz! PCI card
*
*---------------------------------------------------------------------------*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/errno.h>
#include <sys/syslog.h>
#include <sys/device.h>
#include <sys/socket.h>
#include <net/if.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <machine/cpu.h>
#include <machine/intr.h>
#include <machine/bus.h>
#include <machine/bus.h>
#include <machine/intr.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcidevs.h>
#ifdef __FreeBSD__
#include <machine/i4b_ioctl.h>
#else
#include <i4b/i4b_ioctl.h>
#endif
#include <i4b/layer1/i4b_l1.h>
#include <i4b/layer1/i4b_ipac.h>
#include <i4b/layer1/i4b_isac.h>
#include <i4b/layer1/i4b_hscx.h>
#include <i4b/layer1/pci_isic.h>
#include <i4b/include/i4b_global.h>
#include <i4b/include/i4b_l1l2.h>
static int pci_isic_match __P((struct device *, struct cfdata *, void *));
static void pci_isic_attach __P((struct device *, struct device *, void *));
static const struct isic_pci_product * find_matching_card __P((struct pci_attach_args *pa));
static void isic_pciattach __P((struct pci_isic_softc *psc, struct pci_attach_args *pa));
struct cfattach pci_isic_ca = {
sizeof(struct pci_isic_softc), pci_isic_match, pci_isic_attach
};
static const struct isic_pci_product {
pci_vendor_id_t npp_vendor;
pci_product_id_t npp_product;
int cardtype;
const char * name;
void (*attach)(struct pci_isic_softc *psc, struct pci_attach_args *pa);
void (*pciattach)(struct pci_isic_softc *psc, struct pci_attach_args *pa);
} isic_pci_products[] = {
#ifdef ELSA_QS1PCI
#ifndef PCI_PRODUCT_ELSA_QS1PCI
#define PCI_PRODUCT_ELSA_QS1PCI 0x1000 /* added to pcidevs in 1.3K, earlier versions missing it */
#endif
{ PCI_VENDOR_ELSA, PCI_PRODUCT_ELSA_QS1PCI,
CARD_TYPEP_ELSAQS1PCI,
"ELSA QuickStep 1000pro/PCI",
isic_attach_Eqs1pp, /* card specific initialization */
isic_pciattach /* generic setup for ISAC/HSCX or IPAC boards */
},
#endif
#ifdef AVM_A1_PCI
#ifndef PCI_VENDOR_AVM
#define PCI_VENDOR_AVM 0x1244 /* earlier versions missing this */
#define PCI_PRODUCT_AVM_FRITZ_CARD 0x0a00
#endif
{ PCI_VENDOR_AVM, PCI_PRODUCT_AVM_FRITZ_CARD,
CARD_TYPEP_AVMA1PCI,
"Fritz!Card",
isic_attach_fritzPci,
NULL /* card rolls its own setup */
},
#endif
{ 0, 0, 0, NULL, NULL },
};
static const struct isic_pci_product * find_matching_card(pa)
struct pci_attach_args *pa;
{
const struct isic_pci_product * pp = NULL;
for (pp = isic_pci_products; pp->npp_vendor; pp++)
if (PCI_VENDOR(pa->pa_id) == pp->npp_vendor &&
PCI_PRODUCT(pa->pa_id) == pp->npp_product)
return pp;
return NULL;
}
/*
* Match card
*/
static int
pci_isic_match(parent, match, aux)
struct device *parent;
struct cfdata *match;
void *aux;
{
struct pci_attach_args *pa = aux;
if (!find_matching_card(pa))
return 0;
return 1;
}
/*
* Attach the card
*/
static void
pci_isic_attach(parent, self, aux)
struct device *parent, *self;
void *aux;
{
struct pci_isic_softc *psc = (void*) self;
struct isic_softc *sc = &psc->sc_isic;
struct pci_attach_args *pa = aux;
const struct isic_pci_product * prod;
/* Redo probe */
prod = find_matching_card(pa);
if (prod == NULL) return; /* oops - not found?!? */
sc->sc_unit = sc->sc_dev.dv_unit;
printf(": %s\n", prod->name);
/* card initilization and sc setup */
prod->attach(psc, pa);
/* generic setup, if needed for this card */
if (prod->pciattach) prod->pciattach(psc, pa);
}
/*---------------------------------------------------------------------------*
* isic - pci device driver attach routine
*---------------------------------------------------------------------------*/
static void
isic_pciattach(psc, pa)
struct pci_isic_softc *psc;
struct pci_attach_args *pa;
{
struct isic_softc *sc = &psc->sc_isic;
pci_chipset_tag_t pc = pa->pa_pc;
pci_intr_handle_t ih;
const char *intrstr;
static char *ISACversion[] = {
"2085 Version A1/A2 or 2086/2186 Version 1.1",
"2085 Version B1",
"2085 Version B2",
"2085 Version V2.3 (B3)",
"Unknown Version"
};
static char *HSCXversion[] = {
"82525 Version A1",
"Unknown (0x01)",
"82525 Version A2",
"Unknown (0x03)",
"82525 Version A3",
"82525 or 21525 Version 2.1",
"Unknown Version"
};
isic_sc[sc->sc_unit] = sc; /* XXX - hack! */
sc->sc_isac_version = 0;
sc->sc_hscx_version = 0;
if(sc->sc_ipac)
{
u_int ret = IPAC_READ(IPAC_ID);
switch(ret)
{
case 0x01:
printf("%s: IPAC PSB2115 Version 1.1\n", sc->sc_dev.dv_xname);
break;
default:
printf("%s: Error, IPAC version %d unknown!\n",
sc->sc_dev.dv_xname, ret);
return;
}
}
else
{
sc->sc_isac_version = ((ISAC_READ(I_RBCH)) >> 5) & 0x03;
switch(sc->sc_isac_version)
{
case ISAC_VA:
case ISAC_VB1:
case ISAC_VB2:
case ISAC_VB3:
printf("%s: ISAC %s (IOM-%c)\n",
sc->sc_dev.dv_xname,
ISACversion[sc->sc_isac_version],
sc->sc_bustyp == BUS_TYPE_IOM1 ? '1' : '2');
break;
default:
printf("%s: Error, ISAC version %d unknown!\n",
sc->sc_dev.dv_xname, sc->sc_isac_version);
return;
}
sc->sc_hscx_version = HSCX_READ(0, H_VSTR) & 0xf;
switch(sc->sc_hscx_version)
{
case HSCX_VA1:
case HSCX_VA2:
case HSCX_VA3:
case HSCX_V21:
printf("%s: HSCX %s\n",
sc->sc_dev.dv_xname,
HSCXversion[sc->sc_hscx_version]);
break;
default:
printf("%s: Error, HSCX version %d unknown!\n",
sc->sc_dev.dv_xname, sc->sc_hscx_version);
return;
}
}
/* ISAC setup */
isic_isac_init(sc);
/* HSCX setup */
isic_bchannel_setup(sc->sc_unit, HSCX_CH_A, BPROT_NONE, 0);
isic_bchannel_setup(sc->sc_unit, HSCX_CH_B, BPROT_NONE, 0);
/* setup linktab */
isic_init_linktab(sc);
/* set trace level */
sc->sc_trace = TRACE_OFF;
sc->sc_state = ISAC_IDLE;
sc->sc_ibuf = NULL;
sc->sc_ib = NULL;
sc->sc_ilen = 0;
sc->sc_obuf = NULL;
sc->sc_op = NULL;
sc->sc_ol = 0;
sc->sc_freeflag = 0;
sc->sc_obuf2 = NULL;
sc->sc_freeflag2 = 0;
#if defined(__FreeBSD__) && __FreeBSD__ >=3
callout_handle_init(&sc->sc_T3_callout);
callout_handle_init(&sc->sc_T4_callout);
#endif
/* init higher protocol layers */
MPH_Status_Ind(sc->sc_unit, STI_ATTACH, sc->sc_cardtyp);
/* Map and establish the interrupt. */
if (pci_intr_map(pc, pa->pa_intrtag, pa->pa_intrpin,
pa->pa_intrline, &ih)) {
printf("%s: couldn't map interrupt\n", sc->sc_dev.dv_xname);
return;
}
intrstr = pci_intr_string(pc, ih);
psc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, isicintr, sc);
if (psc->sc_ih == NULL) {
printf("%s: couldn't establish interrupt",
sc->sc_dev.dv_xname);
if (intrstr != NULL)
printf(" at %s", intrstr);
printf("\n");
return;
}
printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr);
}

View File

@ -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));

View File

@ -1,358 +0,0 @@
/*
* Copyright (c) 1998 Martin Husemann. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* 4. Altered versions must be plainly marked as such, and must not be
* misrepresented as being the original software and/or documentation.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*---------------------------------------------------------------------------
*
* pcmcia_isic.c - pcmcia bus frontend for i4b_isic driver
* -------------------------------------------------------
*
* $FreeBSD$
*
* last edit-date: [Tue Apr 20 14:09:16 1999]
*
* -mh original implementation
*
*---------------------------------------------------------------------------*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/errno.h>
#include <sys/syslog.h>
#include <sys/device.h>
#include <sys/socket.h>
#include <net/if.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <machine/cpu.h>
#include <machine/intr.h>
#include <machine/bus.h>
#include <dev/pcmcia/pcmciareg.h>
#include <dev/pcmcia/pcmciavar.h>
#include <dev/pcmcia/pcmciadevs.h>
#ifdef __FreeBSD__
#include <machine/i4b_ioctl.h>
#include <machine/i4b_trace.h>
#else
#include <i4b/i4b_ioctl.h>
#include <i4b/i4b_trace.h>
#endif
#include <i4b/layer1/i4b_l1.h>
#include <i4b/layer1/i4b_ipac.h>
#include <i4b/layer1/i4b_isac.h>
#include <i4b/layer1/i4b_hscx.h>
#include <i4b/include/i4b_l1l2.h>
#include <i4b/include/i4b_global.h>
#include <i4b/layer1/pcmcia_isic.h>
static int pcmcia_isic_match __P((struct device *, struct cfdata *, void *));
static void pcmcia_isic_attach __P((struct device *, struct device *, void *));
static const struct isic_pcmcia_card_entry * find_matching_card __P((struct pcmcia_attach_args *pa));
static int pcmcia_isicattach __P((struct isic_softc *sc));
struct cfattach pcmcia_isic_ca = {
sizeof(struct pcmcia_isic_softc), pcmcia_isic_match, pcmcia_isic_attach
};
struct isic_pcmcia_card_entry {
int32_t vendor; /* vendor ID */
int32_t product; /* product ID */
char *cis1_info[4]; /* CIS info to match */
char *name; /* name of controller */
int function; /* expected PCMCIA function type */
int card_type; /* card type found */
isic_pcmcia_attach_func attach; /* card initialization */
};
static const struct isic_pcmcia_card_entry card_list[] = {
#ifdef AVM_A1_PCMCIA
{ PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
{ "AVM", "ISDN A", NULL, NULL },
"AVM Fritz!Card", PCMCIA_FUNCTION_NETWORK,
CARD_TYPEP_PCFRITZ, isic_attach_fritzpcmcia },
#endif
#ifdef ELSA_ISDNMC
{ PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
{ "ELSA GmbH, Aachen", "MicroLink ISDN/MC ", NULL, NULL },
"ELSA MicroLink ISDN/MC", PCMCIA_FUNCTION_NETWORK,
CARD_TYPEP_ELSAMLIMC, isic_attach_elsaisdnmc },
{ PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
{ "ELSA AG, Aachen", "MicroLink ISDN/MC ", NULL, NULL },
"ELSA MicroLink ISDN/MC", PCMCIA_FUNCTION_NETWORK,
CARD_TYPEP_ELSAMLIMC, isic_attach_elsaisdnmc },
#endif
#ifdef ELSA_MCALL
{ 0x105, 0x410a,
{ "ELSA", "MicroLink MC all", NULL, NULL },
"ELSA MicroLink MCall", PCMCIA_FUNCTION_NETWORK,
CARD_TYPEP_ELSAMLMCALL, isic_attach_elsamcall },
#endif
};
#define NUM_MATCH_ENTRIES (sizeof(card_list)/sizeof(card_list[0]))
static const struct isic_pcmcia_card_entry *
find_matching_card(pa)
struct pcmcia_attach_args *pa;
{
int i, j;
for (i = 0; i < NUM_MATCH_ENTRIES; i++) {
if (card_list[i].vendor != PCMCIA_VENDOR_INVALID && pa->card->manufacturer != card_list[i].vendor)
continue;
if (card_list[i].product != PCMCIA_PRODUCT_INVALID && pa->card->product != card_list[i].product)
continue;
if (pa->pf->function != card_list[i].function)
continue;
for (j = 0; j < 4; j++) {
if (card_list[i].cis1_info[j] == NULL)
continue; /* wildcard */
if (pa->card->cis1_info[j] == NULL)
break; /* not available */
if (strcmp(pa->card->cis1_info[j], card_list[i].cis1_info[j]) != 0)
break; /* mismatch */
}
if (j >= 4)
break;
}
if (i >= NUM_MATCH_ENTRIES)
return NULL;
return &card_list[i];
}
/*
* Match card
*/
static int
pcmcia_isic_match(parent, match, aux)
struct device *parent;
struct cfdata *match;
void *aux;
{
struct pcmcia_attach_args *pa = aux;
if (!find_matching_card(pa))
return 0;
return 1;
}
/*
* Attach the card
*/
static void
pcmcia_isic_attach(parent, self, aux)
struct device *parent, *self;
void *aux;
{
struct pcmcia_isic_softc *psc = (void*) self;
struct isic_softc *sc = &psc->sc_isic;
struct pcmcia_attach_args *pa = aux;
struct pcmcia_config_entry *cfe;
const struct isic_pcmcia_card_entry * cde;
/* Which card is it? */
cde = find_matching_card(pa);
if (cde == NULL) return; /* oops - not found?!? */
psc->sc_pf = pa->pf;
cfe = pa->pf->cfe_head.sqh_first;
/* Enable the card */
pcmcia_function_init(pa->pf, cfe);
pcmcia_function_enable(pa->pf);
if (!cde->attach(psc, cfe, pa))
return; /* Ooops ? */
sc->sc_unit = sc->sc_dev.dv_unit;
/* Announce card name */
printf(": %s\n", cde->name);
/* MI initilization */
pcmcia_isicattach(sc);
/* setup interrupt */
psc->sc_ih = pcmcia_intr_establish(pa->pf, IPL_NET, isicintr, sc);
}
/*---------------------------------------------------------------------------*
* card independend attach for pcmicia cards
*---------------------------------------------------------------------------*/
/* parameter and format for message producing e.g. "isic0: " */
#ifdef __FreeBSD__
#define ISIC_FMT "isic%d: "
#define ISIC_PARM dev->id_unit
#define TERMFMT " "
#else
#define ISIC_FMT "%s: "
#define ISIC_PARM sc->sc_dev.dv_xname
#define TERMFMT "\n"
#endif
int
pcmcia_isicattach(struct isic_softc *sc)
{
static char *ISACversion[] = {
"2085 Version A1/A2 or 2086/2186 Version 1.1",
"2085 Version B1",
"2085 Version B2",
"2085 Version V2.3 (B3)",
"Unknown Version"
};
static char *HSCXversion[] = {
"82525 Version A1",
"Unknown (0x01)",
"82525 Version A2",
"Unknown (0x03)",
"82525 Version A3",
"82525 or 21525 Version 2.1",
"Unknown Version"
};
isic_sc[sc->sc_unit] = sc;
sc->sc_isac_version = 0;
sc->sc_isac_version = ((ISAC_READ(I_RBCH)) >> 5) & 0x03;
switch(sc->sc_isac_version)
{
case ISAC_VA:
case ISAC_VB1:
case ISAC_VB2:
case ISAC_VB3:
break;
default:
printf(ISIC_FMT "Error, ISAC version %d unknown!\n",
ISIC_PARM, sc->sc_isac_version);
return(0);
break;
}
sc->sc_hscx_version = HSCX_READ(0, H_VSTR) & 0xf;
switch(sc->sc_hscx_version)
{
case HSCX_VA1:
case HSCX_VA2:
case HSCX_VA3:
case HSCX_V21:
break;
default:
printf(ISIC_FMT "Error, HSCX version %d unknown!\n",
ISIC_PARM, sc->sc_hscx_version);
return(0);
break;
};
/* ISAC setup */
isic_isac_init(sc);
/* HSCX setup */
isic_bchannel_setup(sc->sc_unit, HSCX_CH_A, BPROT_NONE, 0);
isic_bchannel_setup(sc->sc_unit, HSCX_CH_B, BPROT_NONE, 0);
/* setup linktab */
isic_init_linktab(sc);
/* set trace level */
sc->sc_trace = TRACE_OFF;
sc->sc_state = ISAC_IDLE;
sc->sc_ibuf = NULL;
sc->sc_ib = NULL;
sc->sc_ilen = 0;
sc->sc_obuf = NULL;
sc->sc_op = NULL;
sc->sc_ol = 0;
sc->sc_freeflag = 0;
sc->sc_obuf2 = NULL;
sc->sc_freeflag2 = 0;
/* init higher protocol layers */
MPH_Status_Ind(sc->sc_unit, STI_ATTACH, sc->sc_cardtyp);
/* announce chip versions */
if(sc->sc_isac_version >= ISAC_UNKN)
{
printf(ISIC_FMT "ISAC Version UNKNOWN (VN=0x%x)" TERMFMT,
ISIC_PARM,
sc->sc_isac_version);
sc->sc_isac_version = ISAC_UNKN;
}
else
{
printf(ISIC_FMT "ISAC %s (IOM-%c)" TERMFMT,
ISIC_PARM,
ISACversion[sc->sc_isac_version],
sc->sc_bustyp == BUS_TYPE_IOM1 ? '1' : '2');
}
if(sc->sc_hscx_version >= HSCX_UNKN)
{
printf(ISIC_FMT "HSCX Version UNKNOWN (VN=0x%x)" TERMFMT,
ISIC_PARM,
sc->sc_hscx_version);
sc->sc_hscx_version = HSCX_UNKN;
}
else
{
printf(ISIC_FMT "HSCX %s" TERMFMT,
ISIC_PARM,
HSCXversion[sc->sc_hscx_version]);
}
return(1);
}

View File

@ -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);