📄 if_dp.c
字号:
/* * Copyright (c) 1990 Regents of the University of California. * 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. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)if_dp.c 7.10 (Berkeley) 5/4/92 */#include "dp.h"#if NDP > 0/* * DPV-11 device driver, X.25 version * * Derived from dmc-11 driver: * * Bill Nesheim * Cornell University * * Lou Salkind * New York University *//* #define DEBUG /* for base table dump on fatal error */#include "../include/pte.h"#include "sys/param.h"#include "sys/systm.h"#include "sys/mbuf.h"#include "sys/buf.h"#include "sys/ioctl.h" /* must precede tty.h */#include "sys/protosw.h"#include "sys/socket.h"#include "sys/socketvar.h"#include "sys/syslog.h"#include "sys/vmmac.h"#include "sys/errno.h"#include "sys/time.h"#include "sys/kernel.h"#include "net/if.h"#include "net/if_types.h"#include "net/netisr.h"#include "net/route.h"#include "../include/cpu.h"#include "../include/mtpr.h"#define dzdevice dpdevice#include "../uba/pdma.h"#include "../uba/ubavar.h"#include "netccitt/x25.h"#include "netccitt/pk.h"#include "netccitt/pk_var.h"#include "if_dpreg.h"/* * Driver information for auto-configuration stuff. */int dpprobe(), dpattach(), dpinit(), dpioctl(), dprint(), dpxint();int dpoutput(), dpreset(), dptimeout(), dpstart(), dptestoutput();int x25_ifoutput(), x25_rtrequest();struct uba_device *dpinfo[NDP];u_short dpstd[] = { 0 };struct uba_driver dpdriver = { dpprobe, 0, dpattach, 0, dpstd, "dp", dpinfo };/* * Pdma structures for fast interrupts. */struct pdma dppdma[2*NDP];/* * DP software status per interface. * * Each interface is referenced by a network interface structure, * dp_if, which the routing code uses to locate the interface. * This structure contains the output queue for the interface, its address, ... */struct dp_softc { struct ifnet dp_if; /* network-visible interface */ int dp_ipl; struct dpdevice *dp_addr; /* dpcsr address */ short dp_iused; /* input buffers given to DP */ short dp_flags; /* flags */#define DPF_RUNNING 0x01 /* device initialized */#define DPF_ONLINE 0x02 /* device running (had a RDYO) */#define DPF_RESTART 0x04 /* software restart in progress */#define DPF_FLUSH 0x08 /* had a ROVR, flush ipkt when done */#define DPF_X25UP 0x10 /* XXX -- someday we'll do PPP also */ short dp_ostate; /* restarting, etc. */ short dp_istate; /* not sure this is necessary */#define DPS_IDLE 0#define DPS_RESTART 1#define DPS_ACTIVE 2#define DPS_XEM 3 /* transmitting CRC, etc. */ short dp_olen; /* length of last packet sent */ short dp_ilen; /* length of last packet recvd */ char dp_obuf[DP_MTU+8]; char dp_ibuf[DP_MTU+8];} dp_softc[NDP];/* * Debug info */struct dpstat { long start; long nohdr; long init; long rint; long xint; long reset; long ioctl; long down; long mchange; long timeout; long rsm; long rem; long remchr; long rga; long xem; long rovr;} dpstat;short dp_ilb = 0;short dp_log = 0;#define _offsetof(t, m) ((int)((caddr_t)&((t *)0)->m))int dp_sizes[] = { sizeof(dp_softc[0]), sizeof(struct ifnet), _offsetof(struct dp_softc, dp_obuf[0]), _offsetof(struct dp_softc, dp_ibuf[0]), };dpprobe(reg, ui) caddr_t reg; struct uba_device *ui;{ register int br, cvec; register struct dpdevice *addr = (struct dpdevice *)reg; register int unit = ui->ui_unit;#ifdef lint br = 0; cvec = br; br = cvec; dprint(0); dpxint(0);#endif (void) spl6(); addr->dpclr = DP_CLR; addr->dpclr = DP_XIE|DP_XE; DELAY(100000); dp_softc[unit].dp_ipl = br = qbgetpri(); dp_softc[unit].dp_addr = addr; addr->dpclr = 0; if (cvec && cvec != 0x200){ cvec -= 4; } return (1);}/* * Interface exists: make available by filling in network interface * record. System will initialize the interface when it is ready * to accept packets. */dpattach(ui) register struct uba_device *ui;{ register struct dp_softc *dp = &dp_softc[ui->ui_unit]; dp->dp_if.if_unit = ui->ui_unit; dp->dp_if.if_name = "dp"; dp->dp_if.if_mtu = DP_MTU; dp->dp_if.if_init = dpinit; dp->dp_if.if_output = x25_ifoutput; dp->dp_if.if_type = IFT_X25; dp->dp_if.if_hdrlen = 5; dp->dp_if.if_addrlen = 8; dp->dp_if.if_start = dpstart; dp->dp_if.if_ioctl = dpioctl; dp->dp_if.if_reset = dpreset; dp->dp_if.if_watchdog = dptimeout; dp->dp_if.if_flags = 0; if_attach(&dp->dp_if);}/* * Reset of interface after UNIBUS reset. * If interface is on specified UBA, reset its state. */dpreset(unit, uban) int unit, uban;{ register struct uba_device *ui; register struct dp_softc *dp = &dp_softc[unit]; register struct dpdevice *addr; dpstat.reset++; if (unit >= NDP || (ui = dpinfo[unit]) == 0 || ui->ui_alive == 0 || ui->ui_ubanum != uban) return; dpdown(unit); dpinit(unit); printf(" dp%d", unit);}/* * Initialization of interface. */dpinit(unit) int unit;{ register struct dp_softc *dp = &dp_softc[unit]; register struct dpdevice *addr; register struct ifaddr *ifa; register struct pdma *pdp = &dppdma[unit*2]; int base, s; dpstat.init++; /* * Check to see that an address has been set. */ for (ifa = dp->dp_if.if_addrlist; ifa; ifa = ifa->ifa_next) if (ifa->ifa_addr->sa_family != AF_LINK) break; if (ifa == (struct ifaddr *) 0) return; addr = dp->dp_addr; s = splimp(); dp->dp_iused = 0; dp->dp_istate = dp->dp_ostate = DPS_IDLE; dp->dp_if.if_flags |= IFF_RUNNING; dp->dp_if.if_flags &= ~IFF_OACTIVE; pdp->p_addr = addr; pdp->p_fcn = dpxint; pdp->p_mem = pdp->p_end = dp->dp_obuf; pdp++; pdp->p_addr = addr; pdp->p_fcn = dprint; /* force initial interrupt to come to dprint */ pdp->p_mem = pdp->p_end = dp->dp_ibuf + DP_MTU + 8; addr->dpclr = DP_CLR; DELAY(5000); /* DP_ATA = 0, DP_CHRM = 0, DP_SSLM = 1, (enable aborts), CRC = CCIIT, initially all ones, 2nd addr = 0 */ addr->dpsar = DP_SSLM | DP_IDLE; addr->dpclr = DP_XE | dp_ilb; addr->dptdsr = DP_XSM; /* enable receiver, receive interrupt, DTR, RTS */ addr->dprcsr = DP_RIE | DP_MIE | DP_RE | DP_DTR | DP_RTS; dpstart(&dp->dp_if); splx(s);}/* * Start output on interface. Get another datagram * to send from the interface queue and map it to * the interface before starting output. * */dpstart(ifp) struct ifnet *ifp;{ int s, unit = ifp->if_unit, error = 0, len; register struct dp_softc *dp = &dp_softc[unit]; register struct dpdevice *addr = dp->dp_addr; register struct mbuf *m; register char *cp; char *cplim; /* * If already doing output, go away and depend on transmit * complete or error. */ dpstat.start++; if ((dp->dp_if.if_flags & IFF_OACTIVE) || (dp->dp_if.if_flags & IFF_RUNNING) == 0) goto out; IF_DEQUEUE(&dp->dp_if.if_snd, m); if (m == 0) goto out; dp->dp_if.if_collisions++; if (m->m_flags & M_PKTHDR) len = m->m_pkthdr.len; else { struct mbuf *m0 = m; for (len = 0; m; m = m->m_next) len += m->m_len;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -