summaryrefslogtreecommitdiffstats
path: root/sys/i4b/driver/i4b_ing.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/i4b/driver/i4b_ing.c')
-rw-r--r--sys/i4b/driver/i4b_ing.c856
1 files changed, 0 insertions, 856 deletions
diff --git a/sys/i4b/driver/i4b_ing.c b/sys/i4b/driver/i4b_ing.c
deleted file mode 100644
index 4c3aa6a..0000000
--- a/sys/i4b/driver/i4b_ing.c
+++ /dev/null
@@ -1,856 +0,0 @@
-/*-
- * Copyright (c) 1999, 2002 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_ing.c - isdn4bsd B-channel to netgraph driver
- * -------------------------------------------------
- * last edit-date: [Sat Mar 9 14:09:53 2002]
- *
- *---------------------------------------------------------------------------*/
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include "opt_i4b.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/mbuf.h>
-#include <sys/socket.h>
-#include <sys/errno.h>
-#include <sys/malloc.h>
-
-#include <net/if.h>
-
-#include <netgraph/ng_message.h>
-#include <netgraph/ng_parse.h>
-#include <netgraph/netgraph.h>
-
-#include <i4b/include/i4b_ioctl.h>
-#include <i4b/include/i4b_debug.h>
-
-#include <i4b/include/i4b_global.h>
-#include <i4b/include/i4b_l3l4.h>
-
-#include <i4b/layer4/i4b_l4.h>
-
-#error "Cannot be used until I4B is locked."
-
-#define I4BINGACCT 1 /* enable accounting messages */
-#define I4BINGACCTINTVL 2 /* accounting msg interval in secs */
-
-#define I4BINGMAXQLEN 50 /* max queue length */
-
-/* initialized by L4 */
-
-static drvr_link_t ing_drvr_linktab[NI4BING];
-static isdn_link_t *isdn_linktab[NI4BING];
-
-struct ing_softc {
- int sc_unit; /* unit number */
- int sc_state; /* state of the interface */
- call_desc_t *sc_cdp; /* ptr to call descriptor */
- int sc_updown; /* soft state of interface */
- struct ifqueue sc_fastq; /* interactive traffic */
- int sc_dialresp; /* dialresponse */
- int sc_lastdialresp;/* last dialresponse */
-
-#if I4BINGACCT
- struct callout_handle sc_callout;
- int sc_iinb; /* isdn driver # of inbytes */
- int sc_ioutb; /* isdn driver # of outbytes */
- int sc_inb; /* # of bytes rx'd */
- int sc_outb; /* # of bytes tx'd */
- int sc_linb; /* last # of bytes rx'd */
- int sc_loutb; /* last # of bytes tx'd */
- int sc_fn; /* flag, first null acct */
-#endif
-
- int sc_inpkt; /* incoming packets */
- int sc_outpkt; /* outgoing packets */
-
- struct ifqueue xmitq_hipri; /* hi-priority transmit queue */
- struct ifqueue xmitq; /* transmit queue */
-
- node_p node; /* back pointer to node */
- char nodename[NG_NODESIZ]; /* store our node name */
- hook_p debughook;
- hook_p hook;
-
- u_int packets_in; /* packets in from downstream */
- u_int packets_out; /* packets out towards downstream */
- u_int32_t flags;
-
-} ing_softc[NI4BING];
-
-enum ing_states {
- ST_IDLE, /* initialized, ready, idle */
- ST_DIALING, /* dialling out to remote */
- ST_CONNECTED /* connected to remote */
-};
-
-static void i4bingattach(void *);
-
-PSEUDO_SET(i4bingattach, i4b_ing);
-
-static void ing_init_linktab(int unit);
-static void ing_tx_queue_empty(int unit);
-
-/* ========= NETGRAPH ============= */
-
-#define NG_ING_NODE_TYPE "i4bing" /* node type name */
-#define NGM_ING_COOKIE 947513046 /* node type cookie */
-
-/* Hook names */
-#define NG_ING_HOOK_DEBUG "debug"
-#define NG_ING_HOOK_RAW "rawdata"
-
-/* Netgraph commands understood by this node type */
-enum {
- NGM_ING_SET_FLAG = 1,
- NGM_ING_GET_STATUS,
-};
-
-/* This structure is returned by the NGM_ING_GET_STATUS command */
-struct ngingstat {
- u_int packets_in; /* packets in from downstream */
- u_int packets_out; /* packets out towards downstream */
-};
-
-/*
- * This is used to define the 'parse type' for a struct ngingstat, which
- * is bascially a description of how to convert a binary struct ngingstat
- * to an ASCII string and back. See ng_parse.h for more info.
- *
- * This needs to be kept in sync with the above structure definition
- */
-#define NG_ING_STATS_TYPE_INFO { \
- { "packets_in", &ng_parse_int32_type }, \
- { "packets_out", &ng_parse_int32_type }, \
- { NULL }, \
-}
-
-/*
- * This section contains the netgraph method declarations for the
- * sample node. These methods define the netgraph 'type'.
- */
-
-static ng_constructor_t ng_ing_constructor;
-static ng_rcvmsg_t ng_ing_rcvmsg;
-static ng_shutdown_t ng_ing_shutdown;
-static ng_newhook_t ng_ing_newhook;
-static ng_connect_t ng_ing_connect;
-static ng_rcvdata_t ng_ing_rcvdata;
-static ng_disconnect_t ng_ing_disconnect;
-
-/* Parse type for struct ngingstat */
-static const struct
- ng_parse_struct_field ng_ing_stat_type_fields[] =
- NG_ING_STATS_TYPE_INFO;
-
-static const struct ng_parse_type ng_ing_stat_type = {
- &ng_parse_struct_type,
- &ng_ing_stat_type_fields
-};
-
-/* List of commands and how to convert arguments to/from ASCII */
-
-static const struct ng_cmdlist ng_ing_cmdlist[] = {
- {
- NGM_ING_COOKIE,
- NGM_ING_GET_STATUS,
- "getstatus",
- NULL,
- &ng_ing_stat_type,
- },
- {
- NGM_ING_COOKIE,
- NGM_ING_SET_FLAG,
- "setflag",
- &ng_parse_int32_type,
- NULL
- },
- { 0 }
-};
-
-/* Netgraph node type descriptor */
-static struct ng_type typestruct = {
- .version = NG_ABI_VERSION,
- .name = NG_ING_NODE_TYPE,
- .constructor = ng_ing_constructor,
- .rcvmsg = ng_ing_rcvmsg,
- .shutdown = ng_ing_shutdown,
- .newhook = ng_ing_newhook,
- .connect = ng_ing_connect,
- .rcvdata = ng_ing_rcvdata,
- .disconnect = ng_ing_disconnect,
- .cmdlist = ng_ing_cmdlist,
-};
-
-NETGRAPH_INIT_ORDERED(ing, &typestruct, SI_SUB_DRIVERS, SI_ORDER_ANY);
-
-/*===========================================================================*
- * DEVICE DRIVER ROUTINES
- *===========================================================================*/
-
-/*---------------------------------------------------------------------------*
- * interface attach routine at kernel boot time
- *---------------------------------------------------------------------------*/
-static void
-i4bingattach(void *dummy)
-{
- struct ing_softc *sc = ing_softc;
- int i;
- int ret;
-
- printf("i4bing: %d i4b NetGraph ISDN B-channel device(s) attached\n", NI4BING);
-
- for(i=0; i < NI4BING; sc++, i++)
- {
- sc->sc_unit = i;
-
- ing_init_linktab(i);
-
- NDBGL4(L4_DIALST, "setting dial state to ST_IDLE");
-
- sc->sc_state = ST_IDLE;
-
- sc->sc_fastq.ifq_maxlen = I4BINGMAXQLEN;
- if(!mtx_initialized(&sc->sc_fastq.ifq_mtx))
- mtx_init(&sc->sc_fastq.ifq_mtx, "i4b_ing_fastq", NULL, MTX_DEF);
-
-#if I4BINGACCT
- callout_handle_init(&sc->sc_callout);
- sc->sc_iinb = 0;
- sc->sc_ioutb = 0;
- sc->sc_inb = 0;
- sc->sc_outb = 0;
- sc->sc_linb = 0;
- sc->sc_loutb = 0;
- sc->sc_fn = 1;
-#endif
-
- sc->sc_inpkt = 0;
- sc->sc_outpkt = 0;
-
- sc->sc_updown = SOFT_ENA; /* soft enabled */
-
- sc->sc_dialresp = DSTAT_NONE; /* no response */
- sc->sc_lastdialresp = DSTAT_NONE;
-
- /* setup a netgraph node */
-
- if ((ret = ng_make_node_common(&typestruct, &sc->node)))
- {
- printf("ing: ng_make_node_common, ret = %d\n!", ret);
- }
-
- /* name the netgraph node */
-
- sprintf(sc->nodename, "%s%d", NG_ING_NODE_TYPE, sc->sc_unit);
- if((ret = ng_name_node(sc->node, sc->nodename)))
- {
- printf("ing: ng_name node, ret = %d\n!", ret);
- NG_NODE_UNREF(sc->node);
- break;
- }
-
- NG_NODE_SET_PRIVATE(sc->node, sc);
-
- sc->xmitq.ifq_maxlen = IFQ_MAXLEN;
- sc->xmitq_hipri.ifq_maxlen = IFQ_MAXLEN;
- if(!mtx_initialized(&sc->xmitq.ifq_mtx))
- mtx_init(&sc->xmitq.ifq_mtx, "i4b_ing_xmitq", NULL, MTX_DEF);
- if(!mtx_initialized(&sc->xmitq_hipri.ifq_mtx))
- mtx_init(&sc->xmitq_hipri.ifq_mtx, "i4b_ing_hipri", NULL, MTX_DEF);
- }
-}
-
-#ifdef I4BINGACCT
-/*---------------------------------------------------------------------------*
- * accounting timeout routine
- *---------------------------------------------------------------------------*/
-static void
-ing_timeout(struct ing_softc *sc)
-{
- bchan_statistics_t bs;
- int unit = sc->sc_unit;
-
- /* get # of bytes in and out from the HSCX driver */
-
- (*isdn_linktab[unit]->bch_stat)
- (isdn_linktab[unit]->unit, isdn_linktab[unit]->channel, &bs);
-
- sc->sc_ioutb += bs.outbytes;
- sc->sc_iinb += bs.inbytes;
-
- if((sc->sc_iinb != sc->sc_linb) || (sc->sc_ioutb != sc->sc_loutb) || sc->sc_fn)
- {
- int ri = (sc->sc_iinb - sc->sc_linb)/I4BINGACCTINTVL;
- int ro = (sc->sc_ioutb - sc->sc_loutb)/I4BINGACCTINTVL;
-
- if((sc->sc_iinb == sc->sc_linb) && (sc->sc_ioutb == sc->sc_loutb))
- sc->sc_fn = 0;
- else
- sc->sc_fn = 1;
-
- sc->sc_linb = sc->sc_iinb;
- sc->sc_loutb = sc->sc_ioutb;
-
- i4b_l4_accounting(BDRV_ING, unit, ACCT_DURING,
- sc->sc_ioutb, sc->sc_iinb, ro, ri, sc->sc_ioutb, sc->sc_iinb);
- }
-
- sc->sc_callout = timeout((TIMEOUT_FUNC_T)ing_timeout,
- (void *)sc, I4BINGACCTINTVL*hz);
-}
-#endif /* I4BINGACCT */
-
-#if 0
-/*---------------------------------------------------------------------------*
- * clear the interface's send queues
- *---------------------------------------------------------------------------*/
-static void
-ingclearqueue(struct ifqueue *iq)
-{
- int x;
-
- x = splimp();
- IF_DRAIN(iq);
- splx(x);
-}
-#endif
-
-/*===========================================================================*
- * ISDN INTERFACE ROUTINES
- *===========================================================================*/
-
-/*---------------------------------------------------------------------------*
- * this routine is called from L4 handler at connect time
- *---------------------------------------------------------------------------*/
-static void
-ing_connect(int unit, void *cdp)
-{
- struct ing_softc *sc = &ing_softc[unit];
- int s;
-
- sc->sc_cdp = (call_desc_t *)cdp;
-
- s = SPLI4B();
-
- NDBGL4(L4_DIALST, "ing%d: setting dial state to ST_CONNECTED", unit);
-
- sc->sc_dialresp = DSTAT_NONE;
- sc->sc_lastdialresp = DSTAT_NONE;
-
-#if I4BINGACCT
- sc->sc_iinb = 0;
- sc->sc_ioutb = 0;
- sc->sc_inb = 0;
- sc->sc_outb = 0;
- sc->sc_linb = 0;
- sc->sc_loutb = 0;
- sc->sc_callout = timeout((TIMEOUT_FUNC_T)ing_timeout,
- (void *)sc, I4BINGACCTINTVL*hz);
-#endif
-
- sc->sc_state = ST_CONNECTED;
-
- splx(s);
-}
-
-/*---------------------------------------------------------------------------*
- * this routine is called from L4 handler at disconnect time
- *---------------------------------------------------------------------------*/
-static void
-ing_disconnect(int unit, void *cdp)
-{
- call_desc_t *cd = (call_desc_t *)cdp;
- struct ing_softc *sc = &ing_softc[unit];
-
- /* new stuff to check that the active channel is being closed */
-
- if (cd != sc->sc_cdp)
- {
- NDBGL4(L4_INGDBG, "ing%d: channel %d not active",
- cd->driver_unit, cd->channelid);
- return;
- }
-
-#if I4BINGACCT
- untimeout((TIMEOUT_FUNC_T)ing_timeout,
- (void *)sc, sc->sc_callout);
-#endif
-
- i4b_l4_accounting(BDRV_ING, cd->driver_unit, ACCT_FINAL,
- sc->sc_ioutb, sc->sc_iinb, 0, 0, sc->sc_outb, sc->sc_inb);
-
- sc->sc_cdp = (call_desc_t *)0;
-
- NDBGL4(L4_DIALST, "setting dial state to ST_IDLE");
-
- sc->sc_dialresp = DSTAT_NONE;
- sc->sc_lastdialresp = DSTAT_NONE;
-
- sc->sc_state = ST_IDLE;
-}
-
-/*---------------------------------------------------------------------------*
- * this routine is used to give a feedback from userland daemon
- * in case of dial problems
- *---------------------------------------------------------------------------*/
-static void
-ing_dialresponse(int unit, int status, cause_t cause)
-{
- struct ing_softc *sc = &ing_softc[unit];
- sc->sc_dialresp = status;
-
- NDBGL4(L4_INGDBG, "ing%d: last=%d, this=%d",
- unit, sc->sc_lastdialresp, sc->sc_dialresp);
-
- if(status != DSTAT_NONE)
- {
- NDBGL4(L4_INGDBG, "ing%d: clearing queues", unit);
-/* ingclearqueues(sc); */
- }
-}
-
-/*---------------------------------------------------------------------------*
- * interface soft up/down
- *---------------------------------------------------------------------------*/
-static void
-ing_updown(int unit, int updown)
-{
- struct ing_softc *sc = &ing_softc[unit];
- sc->sc_updown = updown;
-}
-
-/*---------------------------------------------------------------------------*
- * this routine is called from the HSCX interrupt handler
- * when a new frame (mbuf) has been received and was put on
- * the rx queue. It is assumed that this routines runs at
- * pri level splimp() ! Keep it short !
- *---------------------------------------------------------------------------*/
-static void
-ing_rx_data_rdy(int unit)
-{
- register struct ing_softc *sc = &ing_softc[unit];
- register struct mbuf *m;
- int error;
-
- if((m = *isdn_linktab[unit]->rx_mbuf) == NULL)
- return;
-
-#if I4BINGACCT
- sc->sc_inb += m->m_pkthdr.len;
-#endif
-
- m->m_pkthdr.rcvif = NULL;
-
- sc->sc_inpkt++;
-
- NG_SEND_DATA_ONLY(error, sc->hook, m);
-}
-
-/*---------------------------------------------------------------------------*
- * this routine is called from the HSCX interrupt handler
- * when the last frame has been sent out and there is no
- * further frame (mbuf) in the tx queue.
- *---------------------------------------------------------------------------*/
-static void
-ing_tx_queue_empty(int unit)
-{
- register struct ing_softc *sc = &ing_softc[unit];
- register struct mbuf *m;
- int x = 0;
-
- if(sc->sc_state != ST_CONNECTED)
- return;
-
- for(;;)
- {
- IF_DEQUEUE(&sc->xmitq_hipri, m);
-
- if(m == NULL)
- {
- IF_DEQUEUE(&sc->xmitq, m);
- if(m == NULL)
- break;
- }
-
-#if I4BINGACCT
- sc->sc_outb += m->m_pkthdr.len;
-#endif
-
- x = 1;
-
- if(! IF_HANDOFF(isdn_linktab[unit]->tx_queue, m, NULL))
- {
- NDBGL4(L4_INGDBG, "ing%d: tx queue full!", unit);
- }
- }
-
- if(x)
- (*isdn_linktab[unit]->bch_tx_start)(isdn_linktab[unit]->unit, isdn_linktab[unit]->channel);
-}
-
-/*---------------------------------------------------------------------------*
- * this routine is called from the HSCX interrupt handler
- * each time a packet is received or transmitted. It should
- * be used to implement an activity timeout mechanism.
- *---------------------------------------------------------------------------*/
-static void
-ing_activity(int unit, int rxtx)
-{
- ing_softc[unit].sc_cdp->last_active_time = SECOND;
-}
-
-/*---------------------------------------------------------------------------*
- * return this drivers linktab address
- *---------------------------------------------------------------------------*/
-drvr_link_t *
-ing_ret_linktab(int unit)
-{
- return(&ing_drvr_linktab[unit]);
-}
-
-/*---------------------------------------------------------------------------*
- * setup the isdn_linktab for this driver
- *---------------------------------------------------------------------------*/
-void
-ing_set_linktab(int unit, isdn_link_t *ilt)
-{
- isdn_linktab[unit] = ilt;
-}
-
-/*---------------------------------------------------------------------------*
- * initialize this drivers linktab
- *---------------------------------------------------------------------------*/
-static void
-ing_init_linktab(int unit)
-{
- ing_drvr_linktab[unit].unit = unit;
- ing_drvr_linktab[unit].bch_rx_data_ready = ing_rx_data_rdy;
- ing_drvr_linktab[unit].bch_tx_queue_empty = ing_tx_queue_empty;
- ing_drvr_linktab[unit].bch_activity = ing_activity;
- ing_drvr_linktab[unit].line_connected = ing_connect;
- ing_drvr_linktab[unit].line_disconnected = ing_disconnect;
- ing_drvr_linktab[unit].dial_response = ing_dialresponse;
- ing_drvr_linktab[unit].updown_ind = ing_updown;
-}
-
-/*===========================================================================*
- * NETGRAPH INTERFACE ROUTINES
- *===========================================================================*/
-
-/*---------------------------------------------------------------------------*
- * It is not possible or allowable to create a node of this type.
- * If the hardware exists, it will already have created it.
- *---------------------------------------------------------------------------*/
-static int
-ng_ing_constructor(node_p node)
-{
- return(EINVAL);
-}
-
-/*---------------------------------------------------------------------------*
- * Give our ok for a hook to be added...
- * Add the hook's private info to the hook structure.
- *---------------------------------------------------------------------------*/
-static int
-ng_ing_newhook(node_p node, hook_p hook, const char *name)
-{
- struct ing_softc *sc = NG_NODE_PRIVATE(node);
-
- /*
- * check if it's our friend the debug hook
- */
- if(strcmp(name, NG_ING_HOOK_DEBUG) == 0)
- {
- NG_HOOK_SET_PRIVATE(hook, NULL); /* paranoid */
- sc->debughook = hook;
- return (0);
- }
- /*
- * Check for raw mode hook.
- */
- if(strcmp(name, NG_ING_HOOK_RAW) == 0)
- {
- NG_HOOK_SET_PRIVATE(hook, sc);
- sc->hook = hook;
- return (0);
- }
-
- return (EINVAL);
-}
-
-/*---------------------------------------------------------------------------*
- * Get a netgraph control message.
- * Check it is one we understand. If needed, send a response.
- * We could save the address for an async action later, but don't here.
- * Always free the message.
- * The response should be in a malloc'd region that the caller can 'free'.
- * A response is not required.
- *---------------------------------------------------------------------------*/
-static int
-ng_ing_rcvmsg(node_p node, item_p item, hook_p lasthook)
-{
- struct ing_softc *sc = NG_NODE_PRIVATE(node);
-
- struct ng_mesg *resp = NULL;
- int error = 0;
- struct ng_mesg *msg;
-
- NGI_GET_MSG(item, msg);
-
- if(msg->header.typecookie == NGM_GENERIC_COOKIE)
- {
- switch(msg->header.cmd)
- {
- case NGM_TEXT_STATUS:
- {
- char *arg;
- char *p;
- int pos = 0;
-
- NG_MKRESPONSE(resp, msg, sizeof(struct ng_mesg) + NG_TEXTRESPONSE, M_NOWAIT);
-
- if (resp == NULL)
- {
- error = ENOMEM;
- break;
- }
- arg = (char *) resp->data;
-
- switch(sc->sc_state)
- {
- case ST_IDLE:
- p = "idle";
- break;
- case ST_DIALING:
- p = "dialing";
- break;
- case ST_CONNECTED:
- p = "connected";
- break;
- default:
- p = "???";
- break;
- }
-
- pos = sprintf(arg, "state = %s (%d)\n", p, sc->sc_state);
-#if I4BINGACCT
- pos += sprintf(arg + pos, "%d bytes in, %d bytes out\n", sc->sc_inb, sc->sc_outb);
-#endif
- pos += sprintf(arg + pos, "%d pkts in, %d pkts out\n", sc->sc_inpkt, sc->sc_outpkt);
-
- resp->header.arglen = pos + 1;
- break;
- }
-
- default:
- error = EINVAL;
- break;
- }
- }
- else if(msg->header.typecookie == NGM_ING_COOKIE)
- {
- switch (msg->header.cmd)
- {
- case NGM_ING_GET_STATUS:
- {
- struct ngingstat *stats;
-
- NG_MKRESPONSE(resp, msg, sizeof(*stats), M_NOWAIT);
-
- if (!resp)
- {
- error = ENOMEM;
- break;
- }
-
- stats = (struct ngingstat *) resp->data;
- stats->packets_in = sc->packets_in;
- stats->packets_out = sc->packets_out;
- break;
- }
-
- case NGM_ING_SET_FLAG:
- if (msg->header.arglen != sizeof(u_int32_t))
- {
- error = EINVAL;
- break;
- }
- sc->flags = *((u_int32_t *) msg->data);
- break;
-
- default:
- error = EINVAL; /* unknown command */
- break;
- }
- }
- else
- {
- error = EINVAL; /* unknown cookie type */
- }
-
- /* Take care of synchronous response, if any */
- NG_RESPOND_MSG(error, node, item, resp);
- /* Free the message and return */
- NG_FREE_MSG(msg);
- return(error);
-}
-
-/*---------------------------------------------------------------------------*
- * get data from another node and transmit it out on a B-channel
- *---------------------------------------------------------------------------*/
-static int
-ng_ing_rcvdata(hook_p hook, item_p item)
-{
- struct ing_softc *sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
- struct ifqueue *xmitq_p;
- int s;
- struct mbuf *m;
- struct ng_tag_prio *ptag;
-
- NGI_GET_M(item, m);
- NG_FREE_ITEM(item);
-
- if(NG_HOOK_PRIVATE(hook) == NULL)
- {
- NG_FREE_M(m);
- return(ENETDOWN);
- }
-
- if(sc->sc_state == ST_IDLE || sc->sc_state == ST_DIALING)
- {
- i4b_l4_dialout(BDRV_ING, sc->sc_unit);
- sc->sc_state = ST_DIALING;
- }
-
- sc->sc_outpkt++;
-
- /*
- * Now queue the data for when it can be sent
- */
- if ((ptag = (struct ng_tag_prio *)m_tag_locate(m, NGM_GENERIC_COOKIE,
- NG_TAG_PRIO, NULL)) != NULL && (ptag->priority > NG_PRIO_CUTOFF) )
- xmitq_p = (&sc->xmitq_hipri);
- else
- xmitq_p = (&sc->xmitq);
-
- s = splimp();
-
- IF_LOCK(xmitq_p);
- if (_IF_QFULL(xmitq_p))
- {
- _IF_DROP(xmitq_p);
- IF_UNLOCK(xmitq_p);
- splx(s);
- NG_FREE_M(m);
- return(ENOBUFS);
- }
-
- _IF_ENQUEUE(xmitq_p, m);
- IF_UNLOCK(xmitq_p);
-
- ing_tx_queue_empty(sc->sc_unit);
-
- splx(s);
- return (0);
-}
-
-/*---------------------------------------------------------------------------*
- * Do local shutdown processing..
- * If we are a persistant device, we might refuse to go away, and
- * we'd only remove our links and reset ourself.
- *---------------------------------------------------------------------------*/
-static int
-ng_ing_shutdown(node_p node)
-{
- struct ing_softc *sc = NG_NODE_PRIVATE(node);
- int ret;
-
- NG_NODE_UNREF(node);
-
- sc->packets_in = 0; /* reset stats */
- sc->packets_out = 0;
-
- if ((ret = ng_make_node_common(&typestruct, &sc->node)))
- {
- printf("ing: ng_make_node_common, ret = %d\n!", ret);
- }
-
- /* name the netgraph node */
- sprintf(sc->nodename, "%s%d", NG_ING_NODE_TYPE, sc->sc_unit);
- if((ret = ng_name_node(sc->node, sc->nodename)))
- {
- printf("ing: ng_name node, ret = %d\n!", ret);
- NG_NODE_UNREF(sc->node);
- return (0);
- }
-
- NG_NODE_SET_PRIVATE(sc->node, sc);
-
- return (0);
-}
-
-/*---------------------------------------------------------------------------*
- * This is called once we've already connected a new hook to the other node.
- *---------------------------------------------------------------------------*/
-static int
-ng_ing_connect(hook_p hook)
-{
- /* probably not at splnet, force outward queueing */
- NG_HOOK_FORCE_QUEUE(NG_HOOK_PEER(hook));
- return (0);
-}
-
-/*
- * Dook disconnection
- *
- * For this type, removal of the last link destroys the node
- */
-static int
-ng_ing_disconnect(hook_p hook)
-{
- struct ing_softc *sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
- int s;
-
- if(NG_HOOK_PRIVATE(hook))
- {
- s = splimp();
- splx(s);
- }
- else
- {
- sc->debughook = NULL;
- }
- return (0);
-}
-
-/*===========================================================================*/
OpenPOWER on IntegriCloud