1: /*
   2:  * Copyright (c) 1986 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  *
   6:  *	@(#)if_uba.c	1.2 (2.11BSD GTE) 4/3/93
   7:  *
   8:  *	2.11BSD - uballoc and ubmalloc calling conventions changed.
   9:  *		  ubmalloc now only performs address computation, the
  10:  *		  necessary UMRs are allocated at network startup.
  11:  *		  sms@wlv.imsd.contel.com - 9/8/90
  12:  */
  13: 
  14: #include "param.h"
  15: #include "../machine/seg.h"
  16: 
  17: #include "systm.h"
  18: #include "domain.h"
  19: #include "protosw.h"
  20: #include "mbuf.h"
  21: #include "buf.h"
  22: #include "pdpuba/ubavar.h"
  23: #include "map.h"
  24: #include "uba.h"
  25: #include "socket.h"
  26: #include "netinet/in.h"
  27: #include "netinet/in_systm.h"
  28: #include "net/if.h"
  29: #include "pdpif/if_uba.h"
  30: 
  31: /*
  32:  * Routines supporting UNIBUS network interfaces.
  33:  */
  34: 
  35: if_ubainit(ifu, uban, hlen, nmr)
  36:     register struct ifuba *ifu;
  37:     int uban, hlen, nmr;        /* nmr in 64 byte clicks */
  38: {
  39:     if (ifu->ifu_r.ifrw_click)
  40:         return(1);
  41:     nmr = ctob(nmr);        /* convert clicks back to bytes */
  42:     ifu->ifu_r.ifrw_click = m_ioget(nmr+hlen);
  43:     ifu->ifu_w.ifrw_click = m_ioget(nmr+hlen);
  44:     if (ifu->ifu_r.ifrw_click == 0 || ifu->ifu_w.ifrw_click == 0) {
  45:         ifu->ifu_r.ifrw_click = ifu->ifu_w.ifrw_click = 0;
  46:         return(0);
  47:     }
  48:     ifu->ifu_r.ifrw_info = ubmalloc(ifu->ifu_r.ifrw_click);
  49:     ifu->ifu_w.ifrw_info = ubmalloc(ifu->ifu_w.ifrw_click);
  50:     ifu->ifu_hlen = hlen;
  51:     return(1);
  52: }
  53: 
  54: /*
  55:  * Pull read data off a interface.
  56:  * Len is length of data, with local net header stripped.
  57:  * Off is non-zero if a trailer protocol was used, and
  58:  * gives the offset of the trailer information.
  59:  * We copy the trailer information and then all the normal
  60:  * data into mbufs.
  61:  */
  62: struct mbuf *
  63: if_rubaget(ifu, totlen, off0, ifp)
  64:     register struct ifuba *ifu;
  65:     int totlen, off0;
  66:     struct ifnet *ifp;
  67: {
  68:     register caddr_t cp = (caddr_t)ifu->ifu_hlen;
  69:     register struct mbuf *m;
  70:     struct mbuf *top, **mp;
  71:     int click = ifu->ifu_r.ifrw_click;
  72:     int off = off0, len;
  73: 
  74:     top = 0;
  75:     mp = ⊤
  76:     while (totlen > 0) {
  77:         MGET(m, M_DONTWAIT, MT_DATA);
  78:         if (m == 0) {
  79:             m_freem(top);
  80:             top = 0;
  81:             goto out;
  82:         }
  83:         if (off) {
  84:             len = totlen - off;
  85:             cp = (caddr_t) (ifu->ifu_hlen + off);
  86:         } else
  87:             len = totlen;
  88:         if (len >= NBPG) {
  89:             if (ifp)
  90:                 goto nopage;
  91:             MCLGET(m);
  92:             if (m->m_len != CLBYTES)
  93:                 goto nopage;
  94:             m->m_len = MIN(len, CLBYTES);
  95:             goto copy;
  96:         }
  97: nopage:
  98:         m->m_off = MMINOFF;
  99:         if (ifp) {
 100:             /*
 101: 			 *	Leave room for ifp.
 102: 			 */
 103:             m->m_len = MIN(MLEN - sizeof(ifp), len);
 104:             m->m_off += sizeof(ifp);
 105:         } else
 106:             m->m_len = MIN(MLEN, len);
 107: copy:
 108:         mbcopyin(click, cp, mtod(m, char *), (u_int)m->m_len);
 109:         cp += m->m_len;
 110: nocopy:
 111:         *mp = m;
 112:         mp = &m->m_next;
 113:         if (off) {
 114:             /* sort of an ALGOL-W style for statement... */
 115:             off += m->m_len;
 116:             if (off == totlen) {
 117:                 cp = (caddr_t) ifu->ifu_hlen;
 118:                 off = 0;
 119:                 totlen = off0;
 120:             }
 121:         } else
 122:             totlen -= m->m_len;
 123:         if (ifp) {
 124:             /*
 125: 			 *	Prepend interface pointer to first mbuf.
 126: 			 */
 127:             m->m_len += sizeof(ifp);
 128:             m->m_off -= sizeof(ifp);
 129:             *(mtod(m, struct ifnet **)) = ifp;
 130:             ifp = NULL;
 131:         }
 132:     }
 133: out:
 134:     return(top);
 135: }
 136: 
 137: /*
 138:  * Map a chain of mbufs onto a network interface
 139:  * in preparation for an i/o operation.
 140:  * The argument chain of mbufs includes the local network
 141:  * header.
 142:  */
 143: if_wubaput(ifu, m)
 144:     struct ifuba *ifu;
 145:     register struct mbuf *m;
 146: {
 147:     register struct mbuf *mp;
 148:     register u_short off = 0;
 149:     u_short click = ifu->ifu_w.ifrw_click;
 150: 
 151:     while (m) {
 152:         mbcopyout(mtod(m, char *), click, off, (u_int)m->m_len);
 153:         off += m->m_len;
 154:         MFREE(m, mp);
 155:         m = mp;
 156:     }
 157:     return(off);
 158: }
 159: 
 160: #define KDSA    ((u_short *)0172260)    /* supervisor - was 172360.KERNEL */
 161: 
 162: /*
 163:  *	Map UNIBUS virtual memory over some address in supervisor data
 164:  *	space.  We're similar to the "mapalloc" routine used for
 165:  *	raw I/O, but for different objects.  The kernel's 'ubmap' is
 166:  *	tested since the network's "fake" 'ubmap' has gone away (this
 167:  *	routine was the only one to use it).
 168:  */
 169: ubadr_t
 170: uballoc(addr, size)
 171:     caddr_t addr;
 172:     u_int size;
 173: {
 174:     register int nregs;
 175:     register struct ubmap *ubp;
 176:     ubadr_t paddr, vaddr;
 177:     u_int click, first;
 178:     int page, offset;
 179: 
 180:     page = (((int)addr >> 13) & 07);
 181:     offset = ((int)addr & 017777);
 182:     click = KDSA[page];
 183:     paddr = (ubadr_t)click << 6;
 184:     paddr += offset;
 185:     if (!mfkd(&ubmap))
 186:         return(paddr);
 187:     nregs = (int)btoub(size);
 188:     first = MALLOC(ub_map, nregs);
 189: #ifdef  DIAGNOSTIC
 190: /*
 191:  * Should never happen since this is only called by initialization routines
 192:  * in the network drivers.
 193: */
 194:     if  (!first)
 195:         panic("uballoc");
 196: #endif
 197:     ubp = &UBMAP[first];
 198:     vaddr = (ubadr_t)first << 13;
 199:     while (nregs--) {
 200:         ubp->ub_lo = loint(paddr);
 201:         ubp->ub_hi = hiint(paddr);
 202:         ubp++;
 203:         paddr += (ubadr_t) UBPAGE;
 204:     }
 205:     return(vaddr);
 206: }
 207: 
 208: /*
 209:  *	Computes a physical address within the mapped I/O area managed by
 210:  *	m_ioget.  For a UNIBUS machine, the m_ioget arena is
 211:  *	already mapped by UMRs and mioumr and miostart have the base
 212:  *	virtual and click addresses of the mapped arena.  For Q22 machines
 213:  *	mioumr and miostart are 0, turning the calculation into a ctob
 214:  * 	of the input click address.
 215:  */
 216: ubadr_t
 217: ubmalloc(addr)
 218:     memaddr addr;       /* pdp11 "clicks" */
 219: {
 220:     extern ubadr_t mioumr;
 221:     extern memaddr miostart;
 222: 
 223:     return(((ubadr_t)(addr - miostart) << 6) + mioumr);
 224: }

Defined functions

if_rubaget defined in line 62; never used
if_ubainit defined in line 35; never used
if_wubaput defined in line 143; never used
uballoc defined in line 169; never used
ubmalloc defined in line 216; used 2 times

Defined macros

KDSA defined in line 160; used 1 times
Last modified: 1993-04-04
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3275
Valid CSS Valid XHTML 1.0 Strict