Remove all knowledge about specific application (layer 4) drivers from

the generic layer 4 and layer 3 management system.

This should make the layer 4 driver API LKM clean - finaly.

Make the Fritz!PCI driver work again after resent changes (oops!),
noted by Frank Kardel (PR 15948) and Matthias Scheeler.
This commit is contained in:
martin 2002-03-17 20:54:04 +00:00
parent 26500cdfcd
commit e2c42aeaa8
14 changed files with 410 additions and 506 deletions

View File

@ -27,14 +27,14 @@
* i4b - Siemens HSCX chip (B-channel) handling
* --------------------------------------------
*
* $Id: hscx.c,v 1.4 2002/03/17 09:45:58 martin Exp $
* $Id: hscx.c,v 1.5 2002/03/17 20:54:04 martin Exp $
*
* last edit-date: [Fri Jan 5 11:36:10 2001]
*
*---------------------------------------------------------------------------*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: hscx.c,v 1.4 2002/03/17 09:45:58 martin Exp $");
__KERNEL_RCSID(0, "$NetBSD: hscx.c,v 1.5 2002/03/17 20:54:04 martin Exp $");
#include <sys/param.h>
#if defined(__FreeBSD_version) && __FreeBSD_version >= 300001
@ -212,7 +212,7 @@ isic_hscx_irq(register struct l1_softc *sc, u_char ista, int h_chan, u_char ex_i
isdn_layer2_trace_ind(sc->sc_l2, &hdr, chan->in_mbuf->m_len, chan->in_mbuf->m_data);
}
(*chan->drvr_linktab->l4_driver->bch_rx_data_ready)(chan->drvr_linktab->l4_driver_softc);
(*chan->l4_driver->bch_rx_data_ready)(chan->l4_driver_softc);
activity = ACT_RX;
@ -300,7 +300,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->l4_driver->bch_rx_data_ready)(chan->drvr_linktab->l4_driver_softc);
(*chan->l4_driver->bch_rx_data_ready)(chan->l4_driver_softc);
/* alloc new buffer */
@ -356,7 +356,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->l4_driver->bch_tx_queue_empty)(chan->drvr_linktab->l4_driver_softc);
(*chan->l4_driver->bch_tx_queue_empty)(chan->l4_driver_softc);
}
else
{
@ -449,7 +449,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->l4_driver->bch_activity)(chan->drvr_linktab->l4_driver_softc, activity);
(*chan->l4_driver->bch_activity)(chan->l4_driver_softc, activity);
}
/*---------------------------------------------------------------------------*

View File

@ -27,14 +27,14 @@
* i4b_bchan.c - B channel handling L1 procedures
* ----------------------------------------------
*
* $Id: isic_bchan.c,v 1.5 2002/03/17 09:45:59 martin Exp $
* $Id: isic_bchan.c,v 1.6 2002/03/17 20:54:04 martin Exp $
*
* last edit-date: [Fri Jan 5 11:36:11 2001]
*
*---------------------------------------------------------------------------*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: isic_bchan.c,v 1.5 2002/03/17 09:45:59 martin Exp $");
__KERNEL_RCSID(0, "$NetBSD: isic_bchan.c,v 1.6 2002/03/17 20:54:04 martin Exp $");
#include <sys/param.h>
#if defined(__FreeBSD__) && __FreeBSD__ >= 3
@ -78,7 +78,7 @@ __KERNEL_RCSID(0, "$NetBSD: isic_bchan.c,v 1.5 2002/03/17 09:45:59 martin Exp $"
static void isic_bchannel_start(isdn_layer1token, int h_chan);
static void isic_bchannel_stat(isdn_layer1token, int h_chan, bchan_statistics_t *bsp);
static void isic_set_linktab(isdn_layer1token, int channel, drvr_link_t *dlt);
static void isic_set_link(isdn_layer1token, int channel, const struct isdn_l4_driver_functions *l4_driver, void *l4_driver_softc);
static isdn_link_t *isic_ret_linktab(isdn_layer1token, int channel);
/*---------------------------------------------------------------------------*
@ -322,8 +322,8 @@ isic_bchannel_start(isdn_layer1token t, int h_chan)
/* call timeout handling routine */
if(activity == ACT_RX || activity == ACT_TX)
(*chan->drvr_linktab->l4_driver->bch_activity)(
chan->drvr_linktab->l4_driver_softc, activity);
(*chan->l4_driver->bch_activity)(
chan->l4_driver_softc, activity);
if(cmd)
isic_hscx_cmd(sc, h_chan, cmd);
@ -368,12 +368,13 @@ isic_ret_linktab(isdn_layer1token t, int channel)
* set the driver linktab in the b channel softc
*---------------------------------------------------------------------------*/
static void
isic_set_linktab(isdn_layer1token t, int channel, drvr_link_t *dlt)
isic_set_link(isdn_layer1token t, int channel, const struct isdn_l4_driver_functions *l4_driver, void *l4_driver_softc)
{
struct l1_softc *sc = (struct l1_softc*)t;
l1_bchan_state_t *chan = &sc->sc_chan[channel];
chan->drvr_linktab = dlt;
chan->l4_driver = l4_driver;
chan->l4_driver_softc = l4_driver_softc;
}
static const struct isdn_l4_bchannel_functions
@ -393,7 +394,7 @@ isic_init_linktab(struct l1_softc *sc)
isdn_link_t *lt = &chan->isdn_linktab;
/* make sure the hardware driver is known to layer 4 */
ctrl_types[CTRL_PASSIVE].set_linktab = isic_set_linktab;
ctrl_types[CTRL_PASSIVE].set_l4_driver = isic_set_link;
ctrl_types[CTRL_PASSIVE].get_linktab = isic_ret_linktab;
/* local setup */

View File

@ -1,4 +1,4 @@
/* $NetBSD: isic_l1.h,v 1.2 2001/03/24 12:40:29 martin Exp $ */
/* $NetBSD: isic_l1.h,v 1.3 2002/03/17 20:54:04 martin Exp $ */
/*
* Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
@ -129,8 +129,10 @@ 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 isdn_linktab; /* b channel driver data */
const struct isdn_l4_driver_functions
*l4_driver; /* layer 4 driver */
void *l4_driver_softc; /* layer 4 driver instance */
/* statistics */

View File

@ -35,14 +35,14 @@
* Fritz!Card PCI specific routines for isic driver
* ------------------------------------------------
*
* $Id: isic_pci_avm_fritz_pci.c,v 1.5 2001/11/13 07:48:45 lukem Exp $
* $Id: isic_pci_avm_fritz_pci.c,v 1.6 2002/03/17 20:54:04 martin Exp $
*
* last edit-date: [Fri Jan 5 11:38:58 2001]
*
*---------------------------------------------------------------------------*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: isic_pci_avm_fritz_pci.c,v 1.5 2001/11/13 07:48:45 lukem Exp $");
__KERNEL_RCSID(0, "$NetBSD: isic_pci_avm_fritz_pci.c,v 1.6 2002/03/17 20:54:04 martin Exp $");
#include "opt_isicpci.h"
#ifdef ISICPCI_AVM_A1
@ -1045,7 +1045,7 @@ avma1pp_hscx_intr(int h_chan, u_int stat, struct l1_softc *sc)
{
if((stat & HSCX_STAT_CRCVFRRAB) == HSCX_STAT_CRCVFR)
{
(*chan->drvr_linktab->bch_rx_data_ready)(chan->drvr_linktab->unit);
(*chan->l4_driver->bch_rx_data_ready)(chan->l4_driver_softc);
activity = ACT_RX;
/* mark buffer ptr as unused */
@ -1101,7 +1101,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->l4_driver->bch_rx_data_ready)(chan->l4_driver_softc);
/* alloc new buffer */
@ -1167,7 +1167,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->l4_driver->bch_tx_queue_empty)(chan->l4_driver_softc);
}
else
{
@ -1203,7 +1203,7 @@ avma1pp_hscx_intr(int h_chan, u_int stat, struct l1_softc *sc)
/* call timeout handling routine */
if(activity == ACT_RX || activity == ACT_TX)
(*chan->drvr_linktab->bch_activity)(chan->drvr_linktab->unit, activity);
(*chan->l4_driver->bch_activity)(chan->l4_driver_softc, activity);
}
/*
@ -1521,7 +1521,7 @@ avma1pp_bchannel_start(isdn_layer1token t, 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->l4_driver->bch_activity)(chan->l4_driver_softc, activity);
splx(s);
}
@ -1542,14 +1542,21 @@ avma1pp_ret_linktab(isdn_layer1token t, int channel)
* set the driver linktab in the b channel softc
*---------------------------------------------------------------------------*/
static void
avma1pp_set_linktab(isdn_layer1token t, int channel, drvr_link_t *dlt)
avma1pp_set_link(isdn_layer1token t, int channel, const struct isdn_l4_driver_functions *l4_driver, void *l4_driver_softc)
{
struct l1_softc *sc = (struct l1_softc*)t;
l1_bchan_state_t *chan = &sc->sc_chan[channel];
chan->drvr_linktab = dlt;
chan->l4_driver = l4_driver;
chan->l4_driver_softc = l4_driver_softc;
}
static const struct isdn_l4_bchannel_functions
avma1pp_l4_bchannel_functions = {
avma1pp_bchannel_setup,
avma1pp_bchannel_start,
avma1pp_bchannel_stat
};
/*---------------------------------------------------------------------------*
* initialize our local linktab
@ -1562,18 +1569,16 @@ avma1pp_init_linktab(struct l1_softc *sc)
/* make sure the hardware driver is known to layer 4 */
/* avoid overwriting if already set */
if (ctrl_types[CTRL_PASSIVE].set_linktab == NULL)
if (ctrl_types[CTRL_PASSIVE].set_l4_driver == NULL)
{
ctrl_types[CTRL_PASSIVE].set_linktab = avma1pp_set_linktab;
ctrl_types[CTRL_PASSIVE].set_l4_driver = avma1pp_set_link;
ctrl_types[CTRL_PASSIVE].get_linktab = avma1pp_ret_linktab;
}
/* local setup */
lt->l1token = sc;
lt->channel = HSCX_CH_A;
lt->bch_config = avma1pp_bchannel_setup;
lt->bch_tx_start = avma1pp_bchannel_start;
lt->bch_stat = avma1pp_bchannel_stat;
lt->bchannel_driver = &avma1pp_l4_bchannel_functions;
lt->tx_queue = &chan->tx_queue;
/* used by non-HDLC data transfers, i.e. telephony drivers */
@ -1587,9 +1592,7 @@ avma1pp_init_linktab(struct l1_softc *sc)
lt->l1token = sc;
lt->channel = HSCX_CH_B;
lt->bch_config = avma1pp_bchannel_setup;
lt->bch_tx_start = avma1pp_bchannel_start;
lt->bch_stat = avma1pp_bchannel_stat;
lt->bchannel_driver = &avma1pp_l4_bchannel_functions;
lt->tx_queue = &chan->tx_queue;
/* used by non-HDLC data transfers, i.e. telephony drivers */

View File

@ -27,7 +27,7 @@
* i4b_i4bdrv.c - i4b userland interface driver
* --------------------------------------------
*
* $Id: i4b_i4bdrv.c,v 1.11 2002/03/17 11:08:31 martin Exp $
* $Id: i4b_i4bdrv.c,v 1.12 2002/03/17 20:54:05 martin Exp $
*
* $FreeBSD$
*
@ -36,11 +36,9 @@
*---------------------------------------------------------------------------*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: i4b_i4bdrv.c,v 1.11 2002/03/17 11:08:31 martin Exp $");
__KERNEL_RCSID(0, "$NetBSD: i4b_i4bdrv.c,v 1.12 2002/03/17 20:54:05 martin Exp $");
#include "isdn.h"
#include "irip.h"
#include "isdntel.h"
#if NISDN > 0
@ -64,10 +62,6 @@ __KERNEL_RCSID(0, "$NetBSD: i4b_i4bdrv.c,v 1.11 2002/03/17 11:08:31 martin Exp $
#include <sys/select.h>
#include <net/if.h>
#if defined(__FreeBSD__)
#include "i4bing.h"
#endif
#ifdef __FreeBSD__
#if defined(__FreeBSD__) && __FreeBSD__ == 3
@ -538,46 +532,17 @@ isdnioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
case I4B_DIALOUT_RESP:
{
drvr_link_t *dlt = NULL;
const struct isdn_l4_driver_functions *drv;
msg_dialout_resp_t *mdrsp;
void * l4_softc;
mdrsp = (msg_dialout_resp_t *)data;
drv = isdn_l4_get_driver(mdrsp->driver, mdrsp->driver_unit);
switch(mdrsp->driver)
{
#if NIRIP > 0
case BDRV_IPR:
dlt = ipr_ret_linktab(mdrsp->driver_unit);
break;
#endif
#if NIPPP > 0
case BDRV_ISPPP:
dlt = i4bisppp_ret_linktab(mdrsp->driver_unit);
break;
#endif
#if NISDNTEL > 0
case BDRV_TEL:
dlt = tel_ret_linktab(mdrsp->driver_unit);
break;
#endif
#if NISDNBCHAN > 0
case BDRV_IBC:
dlt = ibc_ret_linktab(mdrsp->driver_unit);
break;
#endif
#if NI4BING > 0
case BDRV_ING:
dlt = ing_ret_linktab(mdrsp->driver_unit);
break;
#endif
if(drv != NULL) {
l4_softc = (*drv->get_softc)(mdrsp->driver_unit);
(*drv->dial_response)(l4_softc, mdrsp->stat, mdrsp->cause);
}
if(dlt != NULL)
(*dlt->l4_driver->dial_response)(dlt->l4_driver_softc, mdrsp->stat, mdrsp->cause);
break;
}
@ -662,17 +627,17 @@ isdnioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
case I4B_UPDOWN_IND:
{
msg_updown_ind_t *mui;
mui = (msg_updown_ind_t *)data;
const struct isdn_l4_driver_functions *drv;
void * l4_softc;
#if NIRIP > 0
if(mui->driver == BDRV_IPR)
mui = (msg_updown_ind_t *)data;
drv = isdn_l4_get_driver(mui->driver, mui->driver_unit);
if (drv)
{
drvr_link_t *dlt;
dlt = ipr_ret_linktab(mui->driver_unit);
(*dlt->l4_driver->updown_ind)(dlt->l4_driver_softc, mui->updown);
l4_softc = drv->get_softc(mui->driver_unit);
(*drv->updown_ind)(l4_softc, mui->updown);
}
#endif
break;
}
@ -724,6 +689,14 @@ isdnioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
break;
}
case I4B_L4DRIVER_LOOKUP:
{
msg_l4driver_lookup_t *lookup = (msg_l4driver_lookup_t*)data;
lookup->name[L4DRIVER_NAME_SIZ-1] = 0;
lookup->driver_id = isdn_l4_find_driverid(lookup->name);
break;
}
/* Download request */
#if 0 /* XXX */

View File

@ -27,7 +27,7 @@
* i4b_ioctl.h - messages kernel <--> userland
* -------------------------------------------
*
* $Id: i4b_ioctl.h,v 1.3 2002/03/17 11:08:32 martin Exp $
* $Id: i4b_ioctl.h,v 1.4 2002/03/17 20:54:05 martin Exp $
*
* $FreeBSD$
*
@ -170,19 +170,6 @@
*---------------------------------------------------------------------------*/
#define BCH_MAX_DATALEN 2048 /* max length of a B channel frame */
/*---------------------------------------------------------------------------*
* userland driver types
* ---------------------
* a "driver" is defined here as a piece of software interfacing an
* ISDN B channel with a userland service, such as IP, Telephony etc.
*---------------------------------------------------------------------------*/
#define BDRV_RBCH 0 /* raw b-channel interface driver */
#define BDRV_TEL 1 /* telephone (speech) interface driver */
#define BDRV_IPR 2 /* IP over raw HDLC interface driver */
#define BDRV_ISPPP 3 /* sync Kernel PPP interface driver */
#define BDRV_IBC 4 /* BSD/OS point to point driver */
#define BDRV_ING 5 /* NetGraph ing driver */
/*---------------------------------------------------------------------------*
* B channel protocol
*---------------------------------------------------------------------------*/
@ -458,8 +445,6 @@ typedef struct {
*---------------------------------------------------------------------------*/
typedef struct {
msg_hdr_t header; /* common header */
int driver; /* driver type */
int driver_unit; /* driver unit number */
} msg_drvrdisc_req_t;
/*---------------------------------------------------------------------------*
@ -663,6 +648,17 @@ typedef struct {
#define I4B_PROT_IND _IOW('4', 10, msg_prot_ind_t)
/*---------------------------------------------------------------------------*
* Query the identifier for a B channel driver
*---------------------------------------------------------------------------*/
#define L4DRIVER_NAME_SIZ 16
typedef struct {
char name[L4DRIVER_NAME_SIZ]; /* lookup this driver */
int driver_id; /* returned driver id */
} msg_l4driver_lookup_t;
#define I4B_L4DRIVER_LOOKUP _IOWR('4', 11, msg_l4driver_lookup_t)
/*---------------------------------------------------------------------------*
* Protocol download to active cards
*---------------------------------------------------------------------------*/

View File

@ -27,7 +27,7 @@
* i4b_ipr.c - isdn4bsd IP over raw HDLC ISDN network driver
* ---------------------------------------------------------
*
* $Id: i4b_ipr.c,v 1.10 2002/03/17 11:08:32 martin Exp $
* $Id: i4b_ipr.c,v 1.11 2002/03/17 20:54:05 martin Exp $
*
* $FreeBSD$
*
@ -59,7 +59,7 @@
*---------------------------------------------------------------------------*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: i4b_ipr.c,v 1.10 2002/03/17 11:08:32 martin Exp $");
__KERNEL_RCSID(0, "$NetBSD: i4b_ipr.c,v 1.11 2002/03/17 20:54:05 martin Exp $");
#include "irip.h"
@ -172,20 +172,15 @@ __KERNEL_RCSID(0, "$NetBSD: i4b_ipr.c,v 1.10 2002/03/17 11:08:32 martin Exp $");
#define I4BIPRACCTINTVL 2 /* accounting msg interval in secs */
#define I4BIPRADJFRXP 1 /* adjust 1st rxd packet */
/* initialized by L4 */
static drvr_link_t ipr_drvr_linktab[NIRIP];
static isdn_link_t *isdn_linktab[NIRIP];
struct ipr_softc {
struct ifnet sc_if; /* network-visible interface */
int sc_state; /* state of the interface */
#ifndef __FreeBSD__
int sc_unit; /* unit number for Net/OpenBSD */
#endif
call_desc_t *sc_cdp; /* ptr to call descriptor */
isdn_link_t *sc_ilt; /* ptr to B channel driver/state */
int sc_unit; /* which instance are we? */
int sc_updown; /* soft state of interface */
struct ifqueue sc_fastq; /* interactive traffic */
int sc_dialresp; /* dialresponse */
@ -260,10 +255,33 @@ static int iprwatchdog(int unit);
#else
static void iprwatchdog(struct ifnet *ifp);
#endif
static void ipr_init_linktab(int unit);
static void ipr_tx_queue_empty(void *);
static int iripoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, struct rtentry *rtp);
static void iripclearqueues(struct ipr_softc *sc);
static void ipr_set_linktab(void *softc, isdn_link_t *ilt);
static void ipr_activity(void *softc, int rxtx);
static void ipr_rx_data_rdy(void *softc);
static void ipr_disconnect(void *softc, void *cdp);
static void ipr_connect(void *softc, void *cdp);
static void ipr_dialresponse(void *softc, int status, cause_t cause);
static void ipr_updown(void *softc, int updown);
static void* ipr_get_softc(int unit);
static const struct isdn_l4_driver_functions
ipr_l4_functions = {
ipr_rx_data_rdy,
ipr_tx_queue_empty,
ipr_activity,
ipr_connect,
ipr_disconnect,
ipr_dialresponse,
ipr_updown,
ipr_get_softc,
ipr_set_linktab,
NULL
};
static int irip_driver_id = -1;
/*===========================================================================*
* DEVICE DRIVER ROUTINES
@ -281,14 +299,15 @@ iripattach()
{
struct ipr_softc *sc = ipr_softc;
int i;
irip_driver_id = isdn_l4_driver_attach("irip", NIRIP, &ipr_l4_functions);
for(i=0; i < NIRIP; sc++, i++)
{
ipr_init_linktab(i);
NDBGL4(L4_DIALST, "setting dial state to ST_IDLE");
sc->sc_state = ST_IDLE;
sc->sc_unit = i;
#ifdef __FreeBSD__
sc->sc_if.if_name = "irip";
@ -302,7 +321,6 @@ iripattach()
#else
sprintf(sc->sc_if.if_xname, "irip%d", i);
sc->sc_if.if_softc = sc;
sc->sc_unit = i;
#endif
#ifdef IPR_VJ
@ -411,7 +429,6 @@ iripoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
sc = &ipr_softc[unit];
#else
sc = ifp->if_softc;
unit = sc->sc_unit;
#endif
/* check for IP */
@ -430,7 +447,7 @@ iripoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
if(!(ifp->if_flags & IFF_UP))
{
NDBGL4(L4_IPRDBG, "irip%d: interface is DOWN!", unit);
NDBGL4(L4_IPRDBG, "%s: interface is DOWN!", sc->sc_if.if_xname);
m_freem(m);
splx(s);
sc->sc_if.if_oerrors++;
@ -446,7 +463,7 @@ iripoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
switch(sc->sc_dialresp)
{
case DSTAT_TFAIL: /* transient failure */
NDBGL4(L4_IPRDBG, "irip%d: transient dial failure!", unit);
NDBGL4(L4_IPRDBG, "%s: transient dial failure!", sc->sc_if.if_xname);
m_freem(m);
iripclearqueues(sc);
sc->sc_dialresp = DSTAT_NONE;
@ -456,7 +473,7 @@ iripoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
break;
case DSTAT_PFAIL: /* permanent failure */
NDBGL4(L4_IPRDBG, "irip%d: permanent dial failure!", unit);
NDBGL4(L4_IPRDBG, "%s: permanent dial failure!", sc->sc_if.if_xname);
m_freem(m);
iripclearqueues(sc);
sc->sc_dialresp = DSTAT_NONE;
@ -466,7 +483,7 @@ iripoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
break;
case DSTAT_INONLY: /* no dialout allowed*/
NDBGL4(L4_IPRDBG, "irip%d: dialout not allowed failure!", unit);
NDBGL4(L4_IPRDBG, "%s: dialout not allowed failure!", sc->sc_if.if_xname);
m_freem(m);
iripclearqueues(sc);
sc->sc_dialresp = DSTAT_NONE;
@ -477,9 +494,9 @@ iripoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
}
#endif
NDBGL4(L4_IPRDBG, "irip%d: send dial request message!", unit);
NDBGL4(L4_DIALST, "irip%d: setting dial state to ST_DIALING", unit);
i4b_l4_dialout(BDRV_IPR, unit);
NDBGL4(L4_IPRDBG, "%s: send dial request message!", sc->sc_if.if_xname);
NDBGL4(L4_DIALST, "%s: setting dial state to ST_DIALING", sc->sc_if.if_xname);
i4b_l4_dialout(irip_driver_id, unit);
sc->sc_state = ST_DIALING;
}
@ -580,11 +597,7 @@ iripioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
if(sc->sc_if.if_flags & IFF_RUNNING)
{
/* disconnect ISDN line */
#if defined(__FreeBSD__) || defined(__bsdi__)
i4b_l4_drvrdisc(BDRV_IPR, ifp->if_unit);
#else
i4b_l4_drvrdisc(BDRV_IPR, sc->sc_unit);
#endif
i4b_l4_drvrdisc(sc->sc_cdp->cdid);
sc->sc_if.if_flags &= ~IFF_RUNNING;
}
@ -700,14 +713,13 @@ iprwatchdog(struct ifnet *ifp)
struct ifnet *ifp = &ipr_softc[unit].sc_if;
#else
struct ipr_softc *sc = ifp->if_softc;
int unit = sc->sc_unit;
#endif
bchan_statistics_t bs;
/* get # of bytes in and out from the HSCX driver */
(*isdn_linktab[unit]->bchannel_driver->bch_stat)
(isdn_linktab[unit]->l1token, isdn_linktab[unit]->channel, &bs);
(*sc->sc_ilt->bchannel_driver->bch_stat)
(sc->sc_ilt->l1token, sc->sc_ilt->channel, &bs);
sc->sc_ioutb += bs.outbytes;
sc->sc_iinb += bs.inbytes;
@ -916,7 +928,7 @@ ipr_rx_data_rdy(void *softc)
int len, c;
#endif
if((m = *isdn_linktab[sc->sc_unit]->rx_mbuf) == NULL)
if((m = *sc->sc_ilt->rx_mbuf) == NULL)
return;
m->m_pkthdr.rcvif = &sc->sc_if;
@ -1156,14 +1168,14 @@ ipr_tx_queue_empty(void *softc)
#endif
x = 1;
if(IF_QFULL(isdn_linktab[sc->sc_unit]->tx_queue))
if(IF_QFULL(sc->sc_ilt->tx_queue))
{
NDBGL4(L4_IPRDBG, "%s: tx queue full!", sc->sc_if.if_xname);
m_freem(m);
}
else
{
IF_ENQUEUE(isdn_linktab[sc->sc_unit]->tx_queue, m);
IF_ENQUEUE(sc->sc_ilt->tx_queue, m);
sc->sc_if.if_obytes += m->m_pkthdr.len;
@ -1172,7 +1184,7 @@ ipr_tx_queue_empty(void *softc)
}
if(x)
(*isdn_linktab[sc->sc_unit]->bchannel_driver->bch_tx_start)(isdn_linktab[sc->sc_unit]->l1token, isdn_linktab[sc->sc_unit]->channel);
(*sc->sc_ilt->bchannel_driver->bch_tx_start)(sc->sc_ilt->l1token, sc->sc_ilt->channel);
}
/*---------------------------------------------------------------------------*
@ -1190,40 +1202,20 @@ ipr_activity(void *softc, int rxtx)
/*---------------------------------------------------------------------------*
* return this drivers linktab address
*---------------------------------------------------------------------------*/
drvr_link_t *
ipr_ret_linktab(int unit)
static void*
ipr_get_softc(int unit)
{
return(&ipr_drvr_linktab[unit]);
return &ipr_softc[unit];
}
/*---------------------------------------------------------------------------*
* setup the isdn_linktab for this driver
*---------------------------------------------------------------------------*/
void
ipr_set_linktab(int unit, isdn_link_t *ilt)
{
isdn_linktab[unit] = ilt;
}
static const struct isdn_l4_driver_functions
ipr_l4_functions = {
ipr_rx_data_rdy,
ipr_tx_queue_empty,
ipr_activity,
ipr_connect,
ipr_disconnect,
ipr_dialresponse,
ipr_updown
};
/*---------------------------------------------------------------------------*
* initialize this drivers linktab
*---------------------------------------------------------------------------*/
static void
ipr_init_linktab(int unit)
ipr_set_linktab(void *softc, isdn_link_t *ilt)
{
ipr_drvr_linktab[unit].l4_driver_softc = &ipr_softc[unit];
ipr_drvr_linktab[unit].l4_driver = &ipr_l4_functions;
struct ipr_softc *sc = softc;
sc->sc_ilt = ilt;
}
/*===========================================================================*/

View File

@ -34,7 +34,7 @@
* the "cx" driver for Cronyx's HDLC-in-hardware device). This driver
* is only the glue between sppp and i4b.
*
* $Id: i4b_isppp.c,v 1.14 2002/03/17 11:08:32 martin Exp $
* $Id: i4b_isppp.c,v 1.15 2002/03/17 20:54:05 martin Exp $
*
* $FreeBSD$
*
@ -43,7 +43,7 @@
*---------------------------------------------------------------------------*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: i4b_isppp.c,v 1.14 2002/03/17 11:08:32 martin Exp $");
__KERNEL_RCSID(0, "$NetBSD: i4b_isppp.c,v 1.15 2002/03/17 20:54:05 martin Exp $");
#ifndef __NetBSD__
#define USE_ISPPP
@ -119,7 +119,6 @@ __KERNEL_RCSID(0, "$NetBSD: i4b_isppp.c,v 1.14 2002/03/17 11:08:32 martin Exp $"
#define ISPPP_FMT "ippp%d: "
#define ISPPP_ARG(sc) ((sc)->sc_if.if_unit)
#define PDEVSTATIC static
#define IFP2UNIT(ifp) (ifp)->if_unit
# if __FreeBSD_version >= 300001
# define CALLOUT_INIT(chan) callout_handle_init(chan)
@ -138,7 +137,6 @@ __KERNEL_RCSID(0, "$NetBSD: i4b_isppp.c,v 1.14 2002/03/17 11:08:32 martin Exp $"
#define ISPPP_ARG(sc) ((sc)->sc_sp.pp_if.if_xname)
#define PDEVSTATIC /* not static */
#define IOCTL_CMD_T u_long
#define IFP2UNIT(ifp) ((struct i4bisppp_softc *)ifp->if_softc)->sc_unit
#else
# error "What system are you using?"
#endif
@ -166,6 +164,7 @@ struct i4bisppp_softc {
#endif
call_desc_t *sc_cdp; /* ptr to call descriptor */
isdn_link_t *sc_ilt; /* B channel driver and state */
#ifdef I4BISPPPACCT
int sc_iinb; /* isdn driver # of inbytes */
@ -183,7 +182,6 @@ struct i4bisppp_softc {
} i4bisppp_softc[NIPPP];
static void i4bisppp_init_linktab(int unit);
static int i4bisppp_ioctl(struct ifnet *ifp, IOCTL_CMD_T cmd, caddr_t data);
#if 0
@ -202,11 +200,33 @@ static void i4bisppp_state_changed(struct sppp *sp, int new_state);
static void i4bisppp_negotiation_complete(struct sppp *sp);
static void i4bisppp_watchdog(struct ifnet *ifp);
time_t i4bisppp_idletime(void *softc);
static void i4bisppp_rx_data_rdy(void *softc);
static void i4bisppp_tx_queue_empty(void *softc);
static void i4bisppp_activity(void *softc, int rxtx);
static void i4bisppp_connect(void *softc, void *cdp);
static void i4bisppp_disconnect(void *softc, void *cdp);
static void i4bisppp_dialresponse(void *softc, int status, cause_t cause);
static void i4bisppp_updown(void *softc, int updown);
static void* i4bisppp_ret_softc(int unit);
static void i4bisppp_set_linktab(void *softc, isdn_link_t *ilt);
/* initialized by L4 */
static const struct isdn_l4_driver_functions
ippp_l4_functions = {
/* L4<->B-channel functions */
i4bisppp_rx_data_rdy,
i4bisppp_tx_queue_empty,
i4bisppp_activity,
i4bisppp_connect,
i4bisppp_disconnect,
i4bisppp_dialresponse,
i4bisppp_updown,
/* Management functions */
i4bisppp_ret_softc,
i4bisppp_set_linktab,
i4bisppp_idletime
};
static drvr_link_t i4bisppp_drvr_linktab[NIPPP];
static isdn_link_t *isdn_linktab[NIPPP];
static int ippp_drvr_id = -1;
enum i4bisppp_states {
ST_IDLE, /* initialized, ready, idle */
@ -231,10 +251,11 @@ ipppattach()
struct i4bisppp_softc *sc = i4bisppp_softc;
int i;
for(i = 0; i < NIPPP; sc++, i++) {
i4bisppp_init_linktab(i);
ippp_drvr_id = isdn_l4_driver_attach("ippp", NIPPP, &ippp_l4_functions);
for(i = 0; i < NIPPP; sc++, i++) {
sc->sc_sp.pp_if.if_softc = sc;
sc->sc_ilt = NULL;
#ifdef __FreeBSD__
sc->sc_sp.pp_if.if_name = "ippp";
@ -364,8 +385,6 @@ i4bisppp_start(struct ifnet *ifp)
{
struct i4bisppp_softc *sc = ifp->if_softc;
struct mbuf *m;
/* int s; */
int unit = IFP2UNIT(ifp);
#ifndef USE_ISPPP
if (sppp_isempty(ifp))
@ -402,14 +421,14 @@ i4bisppp_start(struct ifnet *ifp)
#endif
#endif /* NBPFILTER > 0 || NBPF > 0 */
if(IF_QFULL(isdn_linktab[unit]->tx_queue))
if(IF_QFULL(sc->sc_ilt->tx_queue))
{
NDBGL4(L4_ISPDBG, "ippp%d, tx queue full!", unit);
NDBGL4(L4_ISPDBG, "%s, tx queue full!", sc->sc_sp.pp_if.if_xname);
m_freem(m);
}
else
{
IF_ENQUEUE(isdn_linktab[unit]->tx_queue, m);
IF_ENQUEUE(sc->sc_ilt->tx_queue, m);
#if 0
sc->sc_sp.pp_if.if_obytes += m->m_pkthdr.len;
#endif
@ -417,9 +436,8 @@ i4bisppp_start(struct ifnet *ifp)
sc->sc_sp.pp_if.if_opackets++;
}
}
isdn_linktab[unit]->bchannel_driver->
bch_tx_start(isdn_linktab[unit]->l1token,
isdn_linktab[unit]->channel);
sc->sc_ilt->bchannel_driver->bch_tx_start(sc->sc_ilt->l1token,
sc->sc_ilt->channel);
}
#ifdef I4BISPPPACCT
@ -430,11 +448,10 @@ static void
i4bisppp_watchdog(struct ifnet *ifp)
{
struct i4bisppp_softc *sc = ifp->if_softc;
int unit = IFP2UNIT(ifp);
bchan_statistics_t bs;
(*isdn_linktab[unit]->bchannel_driver->bch_stat)
(isdn_linktab[unit]->l1token, isdn_linktab[unit]->channel, &bs);
(*sc->sc_ilt->bchannel_driver->bch_stat)
(sc->sc_ilt->l1token, sc->sc_ilt->channel, &bs);
sc->sc_ioutb += bs.outbytes;
sc->sc_iinb += bs.inbytes;
@ -479,12 +496,11 @@ static void
i4bisppp_tls(struct sppp *sp)
{
struct i4bisppp_softc *sc = sp->pp_if.if_softc;
struct ifnet *ifp = &sc->sc_sp.pp_if;
if(sc->sc_state == ST_CONNECTED)
return;
i4b_l4_dialout(BDRV_ISPPP, IFP2UNIT(ifp));
i4b_l4_dialout(ippp_drvr_id, sc->sc_unit);
}
/*---------------------------------------------------------------------------*
@ -495,12 +511,11 @@ static void
i4bisppp_tlf(struct sppp *sp)
{
struct i4bisppp_softc *sc = sp->pp_if.if_softc;
struct ifnet *ifp = &sp->pp_if;
if(sc->sc_state != ST_CONNECTED)
return;
i4b_l4_drvrdisc(BDRV_ISPPP, IFP2UNIT(ifp));
i4b_l4_drvrdisc(sc->sc_cdp->cdid);
}
/*---------------------------------------------------------------------------*
* PPP interface phase change
@ -658,9 +673,9 @@ i4bisppp_rx_data_rdy(void *softc)
{
struct i4bisppp_softc *sc = softc;
struct mbuf *m;
int s, unit = sc->sc_unit;
int s;
if((m = *isdn_linktab[unit]->rx_mbuf) == NULL)
if((m = *sc->sc_ilt->rx_mbuf) == NULL)
return;
m->m_pkthdr.rcvif = &sc->sc_sp.pp_if;
@ -726,12 +741,7 @@ i4bisppp_idletime(void *softc)
{
struct sppp *sp = &((struct i4bisppp_softc *)softc)->sc_sp;
#ifdef __NetBSD__
return sp->pp_last_activity;
#else
return((sp->pp_last_recv < sp->pp_last_sent) ?
sp->pp_last_sent : sp->pp_last_recv);
#endif
return sp->pp_last_activity;
}
/*---------------------------------------------------------------------------*
@ -749,40 +759,20 @@ i4bisppp_activity(void *softc, int rxtx)
/*---------------------------------------------------------------------------*
* return this drivers linktab address
*---------------------------------------------------------------------------*/
drvr_link_t *
i4bisppp_ret_linktab(int unit)
static void *
i4bisppp_ret_softc(int unit)
{
return(&i4bisppp_drvr_linktab[unit]);
return &i4bisppp_softc[unit];
}
/*---------------------------------------------------------------------------*
* setup the isdn_linktab for this driver
*---------------------------------------------------------------------------*/
void
i4bisppp_set_linktab(int unit, isdn_link_t *ilt)
{
isdn_linktab[unit] = ilt;
}
static const struct isdn_l4_driver_functions
ippp_l4_functions = {
i4bisppp_rx_data_rdy,
i4bisppp_tx_queue_empty,
i4bisppp_activity,
i4bisppp_connect,
i4bisppp_disconnect,
i4bisppp_dialresponse,
i4bisppp_updown
};
/*---------------------------------------------------------------------------*
* initialize this drivers linktab
*---------------------------------------------------------------------------*/
static void
i4bisppp_init_linktab(int unit)
i4bisppp_set_linktab(void *softc, isdn_link_t *ilt)
{
i4bisppp_drvr_linktab[unit].l4_driver_softc = &i4bisppp_softc[unit];
i4bisppp_drvr_linktab[unit].l4_driver = &ippp_l4_functions;
struct i4bisppp_softc *sc = softc;
sc->sc_ilt = ilt;
}
/*===========================================================================*/

View File

@ -27,7 +27,7 @@
* i4b_l3l4.h - layer 3 / layer 4 interface
* ------------------------------------------
*
* $Id: i4b_l3l4.h,v 1.4 2002/03/17 11:08:32 martin Exp $
* $Id: i4b_l3l4.h,v 1.5 2002/03/17 20:54:05 martin Exp $
*
* $FreeBSD$
*
@ -55,31 +55,6 @@ typedef struct bchan_statistics {
int inbytes;
} bchan_statistics_t;
/*
* Set of functions layer 4 drivers calls to manipulate the B channel
* they are using.
*/
struct isdn_l4_bchannel_functions {
void (*bch_config)(void*, int channel, int bprot, int updown);
void (*bch_tx_start)(void*, int channel);
void (*bch_stat)(void*, int channel, bchan_statistics_t *bsp);
};
/*
* Functions the B channel driver calls in the layer 4 driver.
*/
struct isdn_l4_driver_functions {
void (*bch_rx_data_ready)(void *softc);
void (*bch_tx_queue_empty)(void *softc);
void (*bch_activity)(void *softc, int rxtx);
#define ACT_RX 0
#define ACT_TX 1
void (*line_connected)(void *softc, void *cde);
void (*line_disconnected)(void *softc, void *cde);
void (*dial_response)(void *softc, int stat, cause_t cause);
void (*updown_ind)(void *softc, int updown);
};
/*---------------------------------------------------------------------------*
* table of things the driver needs to know about the b channel
* it is connected to for data transfer
@ -93,43 +68,15 @@ typedef struct i4b_isdn_bchan_linktab {
struct mbuf **rx_mbuf; /* data xfer for HDLC based traffic */
} isdn_link_t;
/*---------------------------------------------------------------------------*
* table of things the b channel handler needs to know about
* the driver it is connected to for data transfer
*---------------------------------------------------------------------------*/
typedef struct i4b_driver_bchan_linktab {
void *l4_driver_softc;
const struct isdn_l4_driver_functions *l4_driver;
} drvr_link_t;
struct isdn_l4_driver_functions;
/* global linktab functions for controller types (aka hardware drivers) */
struct ctrl_type_desc {
isdn_link_t* (*get_linktab)(void*, int channel);
void (*set_linktab)(void*, int channel, drvr_link_t *dlt);
void (*set_l4_driver)(void*, int channel, const struct isdn_l4_driver_functions *l4_driver, void *l4_driver_softc);
};
extern struct ctrl_type_desc ctrl_types[];
/* global linktab functions for RBCH userland driver */
drvr_link_t *rbch_ret_linktab(int unit);
void rbch_set_linktab(int unit, isdn_link_t *ilt);
/* global linktab functions for IPR network driver */
drvr_link_t *ipr_ret_linktab(int);
void ipr_set_linktab(int, isdn_link_t *ilt);
/* global linktab functions for TEL userland driver */
drvr_link_t *tel_ret_linktab(int);
void tel_set_linktab(int, isdn_link_t *ilt);
/* global linktab functions for ISPPP userland driver */
drvr_link_t *i4bisppp_ret_linktab(int);
void i4bisppp_set_linktab(int, isdn_link_t *ilt);
/*---------------------------------------------------------------------------*
* this structure describes one call/connection on one B-channel
* and all its parameters
@ -184,8 +131,9 @@ typedef struct
int T400; /* L4 timeout */
isdn_link_t *ilt; /* isdn B channel linktab */
drvr_link_t *dlt; /* driver linktab */
isdn_link_t *ilt; /* isdn B channel driver/state */
const struct isdn_l4_driver_functions *l4_driver; /* layer 4 driver */
void *l4_driver_softc; /* layer 4 driver instance */
int dir; /* outgoing or incoming call */
#define DIR_OUTGOING 0
@ -233,6 +181,50 @@ typedef struct
extern call_desc_t call_desc[N_CALL_DESC];
/*
* Set of functions layer 4 drivers calls to manipulate the B channel
* they are using.
*/
struct isdn_l4_bchannel_functions {
void (*bch_config)(void*, int channel, int bprot, int updown);
void (*bch_tx_start)(void*, int channel);
void (*bch_stat)(void*, int channel, bchan_statistics_t *bsp);
};
/*
* Functions a layer 4 application driver exports
*/
struct isdn_l4_driver_functions {
/*
* Functions for use by the B channel driver
*/
void (*bch_rx_data_ready)(void *softc);
void (*bch_tx_queue_empty)(void *softc);
void (*bch_activity)(void *softc, int rxtx);
#define ACT_RX 0
#define ACT_TX 1
void (*line_connected)(void *softc, void *cde);
void (*line_disconnected)(void *softc, void *cde);
void (*dial_response)(void *softc, int stat, cause_t cause);
void (*updown_ind)(void *softc, int updown);
/*
* Functions used by the ISDN management system
*/
void* (*get_softc)(int unit);
void (*set_linktab)(void *softc, isdn_link_t *ilt);
/*
* Optional accounting function
*/
time_t (*get_idletime)(void* softc);
};
/* global registry of layer 4 drivers */
int isdn_l4_driver_attach(const char *name, int units, const struct isdn_l4_driver_functions *driver);
int isdn_l4_driver_detatch(const char *name);
int isdn_l4_find_driverid(const char *name);
const struct isdn_l4_driver_functions *isdn_l4_find_driver(const char *name, int unit);
const struct isdn_l4_driver_functions *isdn_l4_get_driver(int driver_id, int unit);
/* forward decl. */
struct isdn_diagnostic_request;
struct isdn_dr_prot;

View File

@ -27,7 +27,7 @@
* i4b_l4.c - kernel interface to userland
* -----------------------------------------
*
* $Id: i4b_l4.c,v 1.10 2002/03/17 11:08:32 martin Exp $
* $Id: i4b_l4.c,v 1.11 2002/03/17 20:54:05 martin Exp $
*
* $FreeBSD$
*
@ -36,7 +36,7 @@
*---------------------------------------------------------------------------*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: i4b_l4.c,v 1.10 2002/03/17 11:08:32 martin Exp $");
__KERNEL_RCSID(0, "$NetBSD: i4b_l4.c,v 1.11 2002/03/17 20:54:05 martin Exp $");
#include "isdn.h"
#include "irip.h"
@ -57,20 +57,6 @@ __KERNEL_RCSID(0, "$NetBSD: i4b_l4.c,v 1.10 2002/03/17 11:08:32 martin Exp $");
#include <sys/callout.h>
#endif
#if defined(__FreeBSD__)
#include "i4bing.h"
#endif
#ifdef __bsdi__
#define NI4BISPPP 0
#include "ibc.h"
#else
#include "ippp.h"
#endif
#include "isdnbchan.h"
#include "isdntel.h"
#ifdef __FreeBSD__
#include <machine/i4b_debug.h>
#include <machine/i4b_ioctl.h>
@ -104,6 +90,69 @@ static time_t i4b_get_idletime(call_desc_t *cd);
extern time_t i4bisppp_idletime(int);
#endif
static int next_l4_driver_id = 0;
struct l4_driver_desc {
SIMPLEQ_ENTRY(l4_driver_desc) l4drvq;
char name[L4DRIVER_NAME_SIZ];
int driver_id;
const struct isdn_l4_driver_functions *driver;
int units;
};
static SIMPLEQ_HEAD(, l4_driver_desc) l4_driver_registry
= SIMPLEQ_HEAD_INITIALIZER(l4_driver_registry);
int isdn_l4_driver_attach(const char *name, int units, const struct isdn_l4_driver_functions *driver)
{
struct l4_driver_desc * new_driver;
new_driver = malloc(sizeof(struct l4_driver_desc), M_DEVBUF, 0);
memset(new_driver, 0, sizeof(struct l4_driver_desc));
strncpy(new_driver->name, name, L4DRIVER_NAME_SIZ);
new_driver->name[L4DRIVER_NAME_SIZ-1] = 0;
new_driver->driver_id = next_l4_driver_id++;
new_driver->driver = driver;
new_driver->units = units;
SIMPLEQ_INSERT_HEAD(&l4_driver_registry, new_driver, l4drvq);
return new_driver->driver_id;
}
int isdn_l4_driver_detatch(const char *name)
{
/* XXX - not yet implemented */
return 0;
}
const struct isdn_l4_driver_functions *isdn_l4_find_driver(const char *name, int unit)
{
struct l4_driver_desc * d;
SIMPLEQ_FOREACH(d, &l4_driver_registry, l4drvq)
if (strcmp(d->name, name) == 0) {
return d->driver;
}
return NULL;
}
int isdn_l4_find_driverid(const char *name)
{
struct l4_driver_desc * d;
SIMPLEQ_FOREACH(d, &l4_driver_registry, l4drvq)
if (strcmp(d->name, name) == 0) {
return d->driver_id;
}
return -1;
}
const struct isdn_l4_driver_functions *isdn_l4_get_driver(int driver_id, int unit)
{
struct l4_driver_desc * d;
SIMPLEQ_FOREACH(d, &l4_driver_registry, l4drvq)
if (d->driver_id == driver_id) {
return d->driver;
}
return NULL;
}
/*---------------------------------------------------------------------------*
* send MSG_PDEACT_IND message to userland
*---------------------------------------------------------------------------*/
@ -125,9 +174,9 @@ i4b_l4_pdeact(int controller, int numactive)
STOP_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd);
}
if(cd->dlt != NULL)
if (cd->l4_driver != NULL && cd->l4_driver_softc != NULL)
{
(*cd->dlt->l4_driver->line_disconnected)(cd->dlt->l4_driver_softc, (void *)cd);
(*cd->l4_driver->line_disconnected)(cd->l4_driver_softc, (void *)cd);
i4b_unlink_bchandrvr(cd);
}
@ -291,7 +340,7 @@ i4b_l4_ifstate_changed(call_desc_t *cd, int new_state)
* send MSG_DRVRDISC_REQ message to userland
*---------------------------------------------------------------------------*/
void
i4b_l4_drvrdisc(int driver, int driver_unit)
i4b_l4_drvrdisc(int cdid)
{
struct mbuf *m;
@ -300,10 +349,7 @@ i4b_l4_drvrdisc(int driver, int driver_unit)
msg_drvrdisc_req_t *md = (msg_drvrdisc_req_t *)m->m_data;
md->header.type = MSG_DRVRDISC_REQ;
md->header.cdid = -1;
md->driver = driver;
md->driver_unit = driver_unit;
md->header.cdid = cdid;
i4bputqueue(m);
}
@ -396,7 +442,7 @@ i4b_l4_connect_active_ind(call_desc_t *cd)
i4b_link_bchandrvr(cd);
(*cd->dlt->l4_driver->line_connected)(cd->dlt->l4_driver_softc, (void *)cd);
(*cd->l4_driver->line_connected)(cd->l4_driver_softc, cd);
i4b_l4_setup_timeout(cd);
@ -429,9 +475,9 @@ i4b_l4_disconnect_ind(call_desc_t *cd)
if(cd->timeout_active)
STOP_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd);
if(cd->dlt != NULL)
if (cd->l4_driver != NULL && cd->l4_driver_softc != NULL)
{
(*cd->dlt->l4_driver->line_disconnected)(cd->dlt->l4_driver_softc, (void *)cd);
(*cd->l4_driver->line_disconnected)(cd->l4_driver_softc, (void *)cd);
i4b_unlink_bchandrvr(cd);
}
@ -601,102 +647,24 @@ i4b_link_bchandrvr(call_desc_t *cd)
cd->channelid);
}
switch(cd->bchan_driver_index)
{
#if NISDNBCHAN > 0
case BDRV_RBCH:
cd->dlt = rbch_ret_linktab(cd->bchan_driver_unit);
break;
#endif
#if NISDNTEL > 0
case BDRV_TEL:
cd->dlt = tel_ret_linktab(cd->bchan_driver_unit);
break;
#endif
cd->l4_driver = isdn_l4_get_driver(cd->bchan_driver_index, cd->bchan_driver_unit);
if (cd->l4_driver != NULL)
cd->l4_driver_softc = cd->l4_driver->get_softc(cd->bchan_driver_unit);
else
cd->l4_driver_softc = NULL;
#if NIRIP > 0
case BDRV_IPR:
cd->dlt = ipr_ret_linktab(cd->bchan_driver_unit);
break;
#endif
#if NIPPP > 0
case BDRV_ISPPP:
cd->dlt = i4bisppp_ret_linktab(cd->bchan_driver_unit);
break;
#endif
#if defined(__bsdi__) && NIBC > 0
case BDRV_IBC:
cd->dlt = ibc_ret_linktab(cd->bchan_driver_unit);
break;
#endif
#if NI4BING > 0
case BDRV_ING:
cd->dlt = ing_ret_linktab(cd->bchan_driver_unit);
break;
#endif
default:
cd->dlt = NULL;
break;
}
if(cd->dlt == NULL || cd->ilt == NULL)
if(cd->l4_driver == NULL || cd->l4_driver_softc == NULL || cd->ilt == NULL)
return(-1);
if(t >= 0 && t < CTRL_NUMTYPES && ctrl_types[t].set_linktab != NULL)
if(t >= 0 && t < CTRL_NUMTYPES && ctrl_types[t].set_l4_driver != NULL)
{
ctrl_types[t].set_linktab(
ctrl_types[t].set_l4_driver(
ctrl_desc[cd->bri].l1_token,
cd->channelid,
cd->dlt);
cd->l4_driver, cd->l4_driver_softc);
}
switch(cd->bchan_driver_index)
{
#if NISDNBCHAN > 0
case BDRV_RBCH:
rbch_set_linktab(cd->bchan_driver_unit, cd->ilt);
break;
#endif
#if NISDNTEL > 0
case BDRV_TEL:
tel_set_linktab(cd->bchan_driver_unit, cd->ilt);
break;
#endif
#if NIRIP > 0
case BDRV_IPR:
ipr_set_linktab(cd->bchan_driver_unit, cd->ilt);
break;
#endif
#if NIPPP > 0
case BDRV_ISPPP:
i4bisppp_set_linktab(cd->bchan_driver_unit, cd->ilt);
break;
#endif
#if defined(__bsdi__) && NIBC > 0
case BDRV_IBC:
ibc_set_linktab(cd->bchan_driver_unit, cd->ilt);
break;
#endif
#if NI4BING > 0
case BDRV_ING:
ing_set_linktab(cd->bchan_driver_unit, cd->ilt);
break;
#endif
default:
return(0);
break;
}
cd->l4_driver->set_linktab(cd->l4_driver_softc, cd->ilt);
/* activate B channel */
@ -775,17 +743,11 @@ idletime_state: IST_NONCHK IST_CHECK IST_SAFE
static time_t
i4b_get_idletime(call_desc_t *cd)
{
switch (cd->bchan_driver_index) {
#if NIPPP > 0
case BDRV_ISPPP:
return i4bisppp_idletime(cd->bchan_driver_unit);
break;
#endif
default:
return cd->last_active_time;
break;
}
if (cd->l4_driver->get_idletime)
return cd->l4_driver->get_idletime(cd->l4_driver_softc);
return cd->last_active_time;
}
/*---------------------------------------------------------------------------*
* B channel idle check timeout setup
*---------------------------------------------------------------------------*/

View File

@ -27,7 +27,7 @@
* i4b_l4.h - kernel interface to userland header file
* ---------------------------------------------------
*
* $Id: i4b_l4.h,v 1.2 2002/03/17 11:08:32 martin Exp $
* $Id: i4b_l4.h,v 1.3 2002/03/17 20:54:05 martin Exp $
*
* $FreeBSD$
*
@ -50,7 +50,7 @@ extern void i4b_l4_daemon_detached(void);
extern void i4b_l4_dialout( int driver, int driver_unit );
extern void i4b_l4_dialoutnumber(int driver, int driver_unit, int cmdlen, char *cmd);
extern void i4b_l4_disconnect_ind ( call_desc_t *cd );
extern void i4b_l4_drvrdisc (int driver, int driver_unit );
extern void i4b_l4_drvrdisc (int cdid);
extern void i4b_l4_negcomplete( call_desc_t *cd );
extern void i4b_l4_ifstate_changed( call_desc_t *cd, int new_state );
extern void i4b_l4_idle_timeout_ind( call_desc_t *cd );

View File

@ -27,7 +27,7 @@
* i4b_q931.c - Q931 received messages handling
* --------------------------------------------
*
* $Id: i4b_q931.c,v 1.6 2002/02/14 16:17:05 drochner Exp $
* $Id: i4b_q931.c,v 1.7 2002/03/17 20:54:05 martin Exp $
*
* $FreeBSD$
*
@ -36,7 +36,7 @@
*---------------------------------------------------------------------------*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: i4b_q931.c,v 1.6 2002/02/14 16:17:05 drochner Exp $");
__KERNEL_RCSID(0, "$NetBSD: i4b_q931.c,v 1.7 2002/03/17 20:54:05 martin Exp $");
#ifdef __FreeBSD__
#include "i4bq931.h"
@ -190,8 +190,8 @@ i4b_decode_q931(int bri, int msg_len, u_char *msg_ptr)
cd->bri = bri;
cd->cr = crval;
cd->crflag = CRF_DEST; /* we are the dest side */
cd->ilt = NULL; /* reset link tab ptrs */
cd->dlt = NULL;
cd->l4_driver = NULL; /* reset link tab ptrs */
cd->l4_driver_softc = NULL;
}
else
{

View File

@ -27,7 +27,7 @@
* i4b_rbch.c - device driver for raw B channel data
* ---------------------------------------------------
*
* $Id: i4b_rbch.c,v 1.7 2002/03/17 11:08:32 martin Exp $
* $Id: i4b_rbch.c,v 1.8 2002/03/17 20:54:05 martin Exp $
*
* $FreeBSD$
*
@ -36,7 +36,7 @@
*---------------------------------------------------------------------------*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: i4b_rbch.c,v 1.7 2002/03/17 11:08:32 martin Exp $");
__KERNEL_RCSID(0, "$NetBSD: i4b_rbch.c,v 1.8 2002/03/17 20:54:05 martin Exp $");
#include "isdnbchan.h"
@ -111,9 +111,6 @@ extern cc_t ttydefchars;
#include <sys/filio.h>
#endif
static drvr_link_t rbch_drvr_linktab[NISDNBCHAN];
static isdn_link_t *isdn_linktab[NISDNBCHAN];
#define I4BRBCHACCT 1 /* enable accounting messages */
#define I4BRBCHACCTINTVL 2 /* accounting msg interval in secs */
@ -132,6 +129,7 @@ static struct rbch_softc {
int sc_bprot; /* B-ch protocol used */
call_desc_t *sc_cd; /* Call Descriptor */
isdn_link_t *sc_ilt; /* B-channel driver/state */
struct termios it_in;
@ -166,8 +164,13 @@ static void rbch_rx_data_rdy(void *softc);
static void rbch_tx_queue_empty(void *softc);
static void rbch_connect(void *softc, void *cdp);
static void rbch_disconnect(void *softc, void *cdp);
static void rbch_init_linktab(int unit);
static void rbch_clrq(void *softc);
static void rbch_activity(void *softc, int rxtx);
static void rbch_dialresponse(void *softc, int status, cause_t cause);
static void rbch_updown(void *softc, int updown);
static void rbch_set_linktab(void *softc, isdn_link_t *ilt);
static void* rbch_get_softc(int unit);
#ifndef __FreeBSD__
#define PDEVSTATIC /* - not static - */
@ -285,6 +288,23 @@ dummy_isdnbchanattach(struct device *parent, struct device *self, void *aux)
}
#endif /* __bsdi__ */
static const struct isdn_l4_driver_functions
rbch_driver_functions = {
rbch_rx_data_rdy,
rbch_tx_queue_empty,
rbch_activity,
rbch_connect,
rbch_disconnect,
rbch_dialresponse,
rbch_updown,
rbch_get_softc,
rbch_set_linktab,
NULL
};
static int rbch_driver_id = -1;
/*---------------------------------------------------------------------------*
* interface attach routine
*---------------------------------------------------------------------------*/
@ -297,6 +317,8 @@ isdnbchanattach()
{
int i;
rbch_driver_id = isdn_l4_driver_attach("isdnbchan", NISDNBCHAN, &rbch_driver_functions);
for(i=0; i < NISDNBCHAN; i++)
{
#if defined(__FreeBSD__)
@ -329,7 +351,6 @@ isdnbchanattach()
rbch_softc[i].sc_hdlcq.ifq_maxlen = I4BRBCHMAXQLEN;
rbch_softc[i].it_in.c_ispeed = rbch_softc[i].it_in.c_ospeed = 64000;
termioschars(&rbch_softc[i].it_in);
rbch_init_linktab(i);
}
}
@ -368,7 +389,7 @@ isdnbchanclose(dev_t dev, int flag, int fmt, struct proc *p)
struct rbch_softc *sc = &rbch_softc[unit];
if(sc->sc_devstate & ST_CONNECTED)
i4b_l4_drvrdisc(BDRV_RBCH, unit);
i4b_l4_drvrdisc(sc->sc_cd->cdid);
sc->sc_devstate &= ~ST_ISOPEN;
@ -413,7 +434,7 @@ isdnbchanread(dev_t dev, struct uio *uio, int ioflag)
if(sc->sc_bprot == BPROT_RHDLC)
iqp = &sc->sc_hdlcq;
else
iqp = isdn_linktab[unit]->rx_queue;
iqp = sc->sc_ilt->rx_queue;
if(IF_QEMPTY(iqp) && (sc->sc_devstate & ST_ISOPEN)) {
splx(s);
@ -439,7 +460,7 @@ isdnbchanread(dev_t dev, struct uio *uio, int ioflag)
if(sc->sc_bprot == BPROT_RHDLC)
iqp = &sc->sc_hdlcq;
else
iqp = isdn_linktab[unit]->rx_queue;
iqp = sc->sc_ilt->rx_queue;
while(IF_QEMPTY(iqp) && (sc->sc_devstate & ST_ISOPEN))
{
@ -447,7 +468,7 @@ isdnbchanread(dev_t dev, struct uio *uio, int ioflag)
NDBGL4(L4_RBCHDBG, "unit %d, wait read data", unit);
if((error = tsleep((caddr_t) &isdn_linktab[unit]->rx_queue,
if((error = tsleep((caddr_t) &sc->sc_ilt->rx_queue,
TTIPRI | PCATCH,
"rrbch", 0 )) != 0)
{
@ -510,7 +531,7 @@ isdnbchanwrite(dev_t dev, struct uio * uio, int ioflag)
splx(s);
return(EWOULDBLOCK);
}
if(IF_QFULL(isdn_linktab[unit]->tx_queue) && (sc->sc_devstate & ST_ISOPEN)) {
if(IF_QFULL(sc->sc_ilt->tx_queue) && (sc->sc_devstate & ST_ISOPEN)) {
splx(s);
return(EWOULDBLOCK);
}
@ -543,13 +564,13 @@ isdnbchanwrite(dev_t dev, struct uio * uio, int ioflag)
tsleep((caddr_t) &rbch_softc[unit], TTIPRI | PCATCH, "xrbch", (hz*1));
}
while(IF_QFULL(isdn_linktab[unit]->tx_queue) && (sc->sc_devstate & ST_ISOPEN))
while(IF_QFULL(sc->sc_ilt->tx_queue) && (sc->sc_devstate & ST_ISOPEN))
{
sc->sc_devstate |= ST_WRWAITEMPTY;
NDBGL4(L4_RBCHDBG, "unit %d, write queue full", unit);
if ((error = tsleep((caddr_t) &isdn_linktab[unit]->tx_queue,
if ((error = tsleep((caddr_t) &sc->sc_ilt->tx_queue,
TTIPRI | PCATCH,
"wrbch", 0)) != 0) {
sc->sc_devstate &= ~ST_WRWAITEMPTY;
@ -589,16 +610,16 @@ isdnbchanwrite(dev_t dev, struct uio * uio, int ioflag)
error = uiomove(m->m_data, m->m_len, uio);
if(IF_QFULL(isdn_linktab[unit]->tx_queue))
if(IF_QFULL(sc->sc_ilt->tx_queue))
{
m_freem(m);
}
else
{
IF_ENQUEUE(isdn_linktab[unit]->tx_queue, m);
IF_ENQUEUE(sc->sc_ilt->tx_queue, m);
}
(*isdn_linktab[unit]->bchannel_driver->bch_tx_start)(isdn_linktab[unit]->l1token, isdn_linktab[unit]->channel);
(*sc->sc_ilt->bchannel_driver->bch_tx_start)(sc->sc_ilt->l1token, sc->sc_ilt->channel);
}
splx(s);
@ -646,7 +667,7 @@ isdnbchanioctl(dev_t dev, IOCTL_CMD_T cmd, caddr_t data, int flag, struct proc *
if(sc->sc_devstate & ST_CONNECTED)
{
NDBGL4(L4_RBCHDBG, "unit %d, disconnecting for DTR down", unit);
i4b_l4_drvrdisc(BDRV_RBCH, unit);
i4b_l4_drvrdisc(sc->sc_cd->cdid);
}
break;
@ -658,8 +679,8 @@ isdnbchanioctl(dev_t dev, IOCTL_CMD_T cmd, caddr_t data, int flag, struct proc *
;
if (l)
{
NDBGL4(L4_RBCHDBG, "unit %d, attempting dialout to %s", unit, (char *)data);
i4b_l4_dialoutnumber(BDRV_RBCH, unit, l, (char *)data);
NDBGL4(L4_RBCHDBG, "%d, attempting dialout to %s", unit, (char *)data);
i4b_l4_dialoutnumber(rbch_driver_id, unit, l, (char *)data);
break;
}
/* fall through to SDTR */
@ -667,7 +688,7 @@ isdnbchanioctl(dev_t dev, IOCTL_CMD_T cmd, caddr_t data, int flag, struct proc *
case TIOCSDTR: /* Set DTR */
NDBGL4(L4_RBCHDBG, "unit %d, attempting dialout (DTR)", unit);
i4b_l4_dialout(BDRV_RBCH, unit);
i4b_l4_dialout(rbch_driver_id, unit);
break;
case TIOCSETA: /* Set termios struct */
@ -733,7 +754,7 @@ isdnbchanpoll(dev_t dev, int events, struct proc *p)
if((events & (POLLOUT|POLLWRNORM)) &&
(sc->sc_devstate & ST_CONNECTED) &&
!IF_QFULL(isdn_linktab[unit]->tx_queue))
!IF_QFULL(sc->sc_ilt->tx_queue))
{
revents |= (events & (POLLOUT|POLLWRNORM));
}
@ -748,7 +769,7 @@ isdnbchanpoll(dev_t dev, int events, struct proc *p)
if(sc->sc_bprot == BPROT_RHDLC)
iqp = &sc->sc_hdlcq;
else
iqp = isdn_linktab[unit]->rx_queue;
iqp = sc->sc_ilt->rx_queue;
if(!IF_QEMPTY(iqp))
revents |= (events & (POLLIN|POLLRDNORM));
@ -829,12 +850,11 @@ static void
rbch_timeout(struct rbch_softc *sc)
{
bchan_statistics_t bs;
int unit = sc->sc_unit;
/* get # of bytes in and out from the HSCX driver */
(*isdn_linktab[unit]->bchannel_driver->bch_stat)
(isdn_linktab[unit]->l1token, isdn_linktab[unit]->channel, &bs);
(*sc->sc_ilt->bchannel_driver->bch_stat)
(sc->sc_ilt->l1token, sc->sc_ilt->channel, &bs);
sc->sc_ioutb += bs.outbytes;
sc->sc_iinb += bs.inbytes;
@ -964,7 +984,7 @@ rbch_rx_data_rdy(void *softc)
{
register struct mbuf *m;
if((m = *isdn_linktab[sc->sc_unit]->rx_mbuf) == NULL)
if((m = *sc->sc_ilt->rx_mbuf) == NULL)
return;
m->m_pkthdr.len = m->m_len;
@ -984,7 +1004,7 @@ rbch_rx_data_rdy(void *softc)
{
NDBGL4(L4_RBCHDBG, "(minor=%d) wakeup", sc->sc_unit);
sc->sc_devstate &= ~ST_RDWAITDATA;
wakeup((caddr_t) &isdn_linktab[sc->sc_unit]->rx_queue);
wakeup((caddr_t) &sc->sc_ilt->rx_queue);
}
else
{
@ -1007,7 +1027,7 @@ rbch_tx_queue_empty(void *softc)
{
NDBGL4(L4_RBCHDBG, "(minor=%d): wakeup", sc->sc_unit);
sc->sc_devstate &= ~ST_WRWAITEMPTY;
wakeup((caddr_t) &isdn_linktab[sc->sc_unit]->tx_queue);
wakeup((caddr_t) &sc->sc_ilt->tx_queue);
}
else
{
@ -1052,45 +1072,24 @@ rbch_clrq(void *softc)
break;
}
}
/*---------------------------------------------------------------------------*
* return this drivers linktab address
*---------------------------------------------------------------------------*/
drvr_link_t *
rbch_ret_linktab(int unit)
{
rbch_init_linktab(unit);
return(&rbch_drvr_linktab[unit]);
}
/*---------------------------------------------------------------------------*
* setup the isdn_linktab for this driver
*---------------------------------------------------------------------------*/
void
rbch_set_linktab(int unit, isdn_link_t *ilt)
static void
rbch_set_linktab(void *softc, isdn_link_t *ilt)
{
isdn_linktab[unit] = ilt;
struct rbch_softc *sc = softc;
sc->sc_ilt = ilt;
}
static const struct isdn_l4_driver_functions
rbch_driver_functions = {
rbch_rx_data_rdy,
rbch_tx_queue_empty,
rbch_activity,
rbch_connect,
rbch_disconnect,
rbch_dialresponse,
rbch_updown
};
/*---------------------------------------------------------------------------*
* initialize this drivers linktab
*---------------------------------------------------------------------------*/
static void
rbch_init_linktab(int unit)
static void*
rbch_get_softc(int unit)
{
rbch_drvr_linktab[unit].l4_driver_softc = &rbch_softc[unit];
rbch_drvr_linktab[unit].l4_driver = &rbch_driver_functions;
return &rbch_softc[unit];
}
/*===========================================================================*/

View File

@ -27,7 +27,7 @@
* i4b_tel.c - device driver for ISDN telephony
* --------------------------------------------
*
* $Id: i4b_tel.c,v 1.8 2002/03/17 09:46:02 martin Exp $
* $Id: i4b_tel.c,v 1.9 2002/03/17 20:54:05 martin Exp $
*
* $FreeBSD$
*
@ -36,7 +36,7 @@
*---------------------------------------------------------------------------*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: i4b_tel.c,v 1.8 2002/03/17 09:46:02 martin Exp $");
__KERNEL_RCSID(0, "$NetBSD: i4b_tel.c,v 1.9 2002/03/17 20:54:05 martin Exp $");
#include "isdntel.h"
@ -118,7 +118,6 @@ typedef struct tel_softc {
/* used only in func = FUNCTEL */
drvr_link_t drvr_linktab; /* driver linktab */
isdn_link_t *isdn_linktab; /* isdn linktab */
int audiofmt; /* audio format conversion */
u_char *rcvttab; /* conversion table on read */
@ -162,10 +161,14 @@ static tel_sc_t tel_sc[NISDNTEL][NOFUNCS];
static void tel_rx_data_rdy(void *softc);
static void tel_tx_queue_empty(void *softc);
static void tel_init_linktab(int unit);
static void tel_connect(void *softc, void *cdp);
static void tel_disconnect(void *softc, void *cdp);
static void tel_tone(tel_sc_t *sc);
static void tel_activity(void *softc, int rxtx);
static void tel_updown(void *softc, int updown);
static void tel_dialresponse(void *softc, int status, cause_t cause);
static void* tel_get_softc(int unit);
static void tel_set_linktab(void *softc, isdn_link_t *ilt);
/* audio format conversion tables */
static unsigned char a2u_tab[];
@ -297,6 +300,22 @@ dummy_i4btelattach(struct device *parent, struct device *self, void *aux)
#endif /* __bsdi__ */
static const struct isdn_l4_driver_functions
tel_driver = {
tel_rx_data_rdy,
tel_tx_queue_empty,
tel_activity,
tel_connect,
tel_disconnect,
tel_dialresponse,
tel_updown,
tel_get_softc,
tel_set_linktab,
NULL
};
static int isdntel_driver_id = -1;
/*---------------------------------------------------------------------------*
* interface attach routine
*---------------------------------------------------------------------------*/
@ -309,6 +328,8 @@ isdntelattach()
{
int i, j;
isdntel_driver_id = isdn_l4_driver_attach("isdntel", NISDNTEL, &tel_driver);
for(i=0; i < NISDNTEL; i++)
{
for(j=0; j < NOFUNCS; j++)
@ -353,7 +374,6 @@ isdntelattach()
#endif
#endif
}
tel_init_linktab(i);
}
}
@ -766,11 +786,11 @@ isdntelwrite(dev_t dev, struct uio * uio, int ioflag)
if(cmdbuf[0] == CMD_DIAL)
{
i4b_l4_dialoutnumber(BDRV_TEL, unit, len-1, &cmdbuf[1]);
i4b_l4_dialoutnumber(isdntel_driver_id, unit, len-1, &cmdbuf[1]);
}
else if(cmdbuf[0] == CMD_HUP)
{
i4b_l4_drvrdisc(BDRV_TEL, unit);
i4b_l4_drvrdisc(sc->cdp->cdid);
}
}
else
@ -1157,49 +1177,23 @@ tel_activity(void *softc, int rxtx)
sc->cdp->last_active_time = SECOND;
}
/*---------------------------------------------------------------------------*
* return this drivers linktab address
*---------------------------------------------------------------------------*/
drvr_link_t *
tel_ret_linktab(int unit)
{
tel_sc_t *sc = &tel_sc[unit][FUNCTEL];
tel_init_linktab(unit);
return(&sc->drvr_linktab);
}
/*---------------------------------------------------------------------------*
* setup the isdn_linktab for this driver
*---------------------------------------------------------------------------*/
void
tel_set_linktab(int unit, isdn_link_t *ilt)
static void
tel_set_linktab(void *softc, isdn_link_t *ilt)
{
tel_sc_t *sc = &tel_sc[unit][FUNCTEL];
tel_sc_t *sc = softc;
sc->isdn_linktab = ilt;
}
static const struct isdn_l4_driver_functions
tel_driver = {
tel_rx_data_rdy,
tel_tx_queue_empty,
tel_activity,
tel_connect,
tel_disconnect,
tel_dialresponse,
tel_updown
};
/*---------------------------------------------------------------------------*
* initialize this drivers linktab
* return the instance
*---------------------------------------------------------------------------*/
static void
tel_init_linktab(int unit)
static void*
tel_get_softc(int unit)
{
tel_sc_t *sc = &tel_sc[unit][FUNCTEL];
sc->drvr_linktab.l4_driver_softc = sc;
sc->drvr_linktab.l4_driver = &tel_driver;
return &tel_sc[unit][FUNCTEL];
}
/*===========================================================================*