Annotation of 43BSDReno/sys/tahoeif/if_vba.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1989 The Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution is only permitted until one year after the first shipment
                      6:  * of 4.4BSD by the Regents.  Otherwise, redistribution and use in source and
                      7:  * binary forms are permitted provided that: (1) source distributions retain
                      8:  * this entire copyright notice and comment, and (2) distributions including
                      9:  * binaries display the following acknowledgement:  This product includes
                     10:  * software developed by the University of California, Berkeley and its
                     11:  * contributors'' in the documentation or other materials provided with the
                     12:  * distribution and in all advertising materials mentioning features or use
                     13:  * of this software.  Neither the name of the University nor the names of
                     14:  * its contributors may be used to endorse or promote products derived from
                     15:  * this software without specific prior written permission.
                     16:  * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
                     17:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
                     18:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     19:  *
                     20:  *     @(#)if_vba.c    1.3 (Berkeley) 6/28/90
                     21:  */
                     22: 
                     23: #include "param.h"
                     24: #include "systm.h"
                     25: #include "mbuf.h"
                     26: #include "buf.h"
                     27: #include "cmap.h"
                     28: #include "vmmac.h"
                     29: #include "socket.h"
                     30: 
                     31: #include "../tahoe/mtpr.h"
                     32: #include "../tahoe/pte.h"
                     33: 
                     34: #include "../tahoevba/vbavar.h"
                     35: 
                     36: #include "../net/if.h"
                     37: #include "../netinet/in.h"
                     38: #include "../netinet/if_ether.h"
                     39: 
                     40: #include "if_vba.h"
                     41: 
                     42: if_vbareserve(ifvba0, n, bufsize, extra, extrasize)
                     43: struct ifvba *ifvba0;
                     44: register int n;
                     45: int bufsize;
                     46: caddr_t *extra;
                     47: int extrasize;
                     48: {
                     49:        register caddr_t cp;
                     50:        register struct pte *pte;
                     51:        register struct ifvba *ifvba = ifvba0;
                     52:        struct ifvba *vlim  = ifvba + n;
                     53: 
                     54:        n = roundup(extrasize + (n * bufsize), NBPG);
                     55:        cp = (caddr_t)malloc((u_long)n, M_DEVBUF, M_NOWAIT);
                     56:        if ((n + kvtophys(cp)) > VB_MAXADDR24) {
                     57:                free(cp, M_DEVBUF);
                     58:                cp = 0;
                     59:        }
                     60:        if (cp == 0) {
                     61:                printf("No memory for device buffer(s)\n");
                     62:                return (0);
                     63:        }
                     64:        /*
                     65:         * Make raw buffer pages uncacheable.
                     66:         */
                     67:        pte = kvtopte(cp);
                     68:        for (n = btoc(n); n--; pte++)
                     69:                pte->pg_nc = 1;
                     70:        mtpr(TBIA, 0);
                     71:        if (extra) {
                     72:                *extra = cp;
                     73:                cp += extrasize;
                     74:        }
                     75:        for (; ifvba < vlim; ifvba++) {
                     76:                ifvba->iff_buffer = cp;
                     77:                ifvba->iff_physaddr = kvtophys(cp);
                     78:                cp += bufsize;
                     79:        }
                     80:        return (1);
                     81: }
                     82: /*
                     83:  * Routine to copy from VERSAbus memory into mbufs.
                     84:  *
                     85:  * Warning: This makes the fairly safe assumption that
                     86:  * mbufs have even lengths.
                     87:  */
                     88: struct mbuf *
                     89: if_vbaget(rxbuf, totlen, off, ifp, flags)
                     90:        caddr_t rxbuf;
                     91:        int totlen, off, flags;
                     92:        struct ifnet *ifp;
                     93: {
                     94:        register caddr_t cp;
                     95:        register struct mbuf *m;
                     96:        struct mbuf *top = 0, **mp = &top;
                     97:        int len;
                     98:        caddr_t packet_end;
                     99: 
                    100:        rxbuf += sizeof (struct ether_header);
                    101:        cp = rxbuf;
                    102:        packet_end = cp + totlen;
                    103:        if (off) {
                    104:                off += 2 * sizeof(u_short);
                    105:                totlen -= 2 *sizeof(u_short);
                    106:                cp = rxbuf + off;
                    107:        }
                    108: 
                    109:        MGETHDR(m, M_DONTWAIT, MT_DATA);
                    110:        if (m == 0)
                    111:                return (0);
                    112:        m->m_pkthdr.rcvif = ifp;
                    113:        m->m_pkthdr.len = totlen;
                    114:        m->m_len = MHLEN;
                    115: 
                    116:        while (totlen > 0) {
                    117:                if (top) {
                    118:                        MGET(m, M_DONTWAIT, MT_DATA);
                    119:                        if (m == 0) {
                    120:                                m_freem(top);
                    121:                                return (0);
                    122:                        }
                    123:                        m->m_len = MLEN;
                    124:                }
                    125:                len = min(totlen, (packet_end - cp));
                    126:                if (len >= MINCLSIZE) {
                    127:                        MCLGET(m, M_DONTWAIT);
                    128:                        if (m->m_flags & M_EXT)
                    129:                                m->m_len = len = min(len, MCLBYTES);
                    130:                        else
                    131:                                len = m->m_len;
                    132:                } else {
                    133:                        /*
                    134:                         * Place initial small packet/header at end of mbuf.
                    135:                         */
                    136:                        if (len < m->m_len) {
                    137:                                if (top == 0 && len + max_linkhdr <= m->m_len)
                    138:                                        m->m_data += max_linkhdr;
                    139:                                m->m_len = len;
                    140:                        } else
                    141:                                len = m->m_len;
                    142:                }
                    143:                if (flags)
                    144:                        if_vba16copy(cp, mtod(m, caddr_t), (u_int)len);
                    145:                else
                    146:                        bcopy(cp, mtod(m, caddr_t), (u_int)len);
                    147: 
                    148:                *mp = m;
                    149:                mp = &m->m_next;
                    150:                totlen -= len;
                    151:                cp += len;
                    152:                if (cp == packet_end)
                    153:                        cp = rxbuf;
                    154:        }
                    155:        return (top);
                    156: }
                    157: 
                    158: if_vbaput(ifu, m0, flags)
                    159: caddr_t ifu;
                    160: struct mbuf *m0;
                    161: {
                    162:        register struct mbuf *m = m0;
                    163:        register caddr_t cp = ifu;
                    164: 
                    165:        while (m) {
                    166:                if (flags)
                    167:                        if_vba16copy(mtod(m, caddr_t), cp, (u_int)m->m_len);
                    168:                else
                    169:                        bcopy(mtod(m, caddr_t), cp, (u_int)m->m_len);
                    170:                cp += m->m_len;
                    171:                MFREE(m, m0);
                    172:                m = m0;
                    173:        }
                    174:        if ((int)cp & 1)
                    175:                *cp++ = 0;
                    176:        return (cp - ifu);
                    177: }
                    178: 
                    179: if_vba16copy(from, to, cnt)
                    180:        register caddr_t from, to;
                    181:        register unsigned cnt;
                    182: {
                    183:        register c;
                    184:        register short *f, *t;
                    185: 
                    186:        if (((int)from&01) && ((int)to&01)) {
                    187:                /* source & dest at odd addresses */
                    188:                *to++ = *from++;
                    189:                --cnt;
                    190:        }
                    191:        if (cnt > 1 && (((int)to&01) == 0) && (((int)from&01) == 0)) {
                    192:                t = (short *)to;
                    193:                f = (short *)from;
                    194:                for (c = cnt>>1; c; --c)        /* even address copy */
                    195:                        *t++ = *f++;
                    196:                cnt &= 1;
                    197:                if (cnt) {                      /* odd len */
                    198:                        from = (caddr_t)f;
                    199:                        to = (caddr_t)t;
                    200:                        *to = *from;
                    201:                }
                    202:        }
                    203:        while ((int)cnt-- > 0)  /* one of the address(es) must be odd */
                    204:                *to++ = *from++;
                    205: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.