on uba reset remap already allocated pages
[unix-history] / usr / src / sys / vax / if / if_uba.c
index 9294c8c..c9298a2 100644 (file)
@@ -1,4 +1,4 @@
-/*     if_uba.c        4.4     81/12/03        */
+/*     if_uba.c        4.11    82/05/19        */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
@@ -11,6 +11,7 @@
 #include "../h/cmap.h"
 #include "../h/mtpr.h"
 #include "../h/vmmac.h"
 #include "../h/cmap.h"
 #include "../h/mtpr.h"
 #include "../h/vmmac.h"
+#include "../h/socket.h"
 #include "../net/in.h"
 #include "../net/in_systm.h"
 #include "../net/if.h"
 #include "../net/in.h"
 #include "../net/in_systm.h"
 #include "../net/if.h"
@@ -34,36 +35,43 @@ if_ubainit(ifu, uban, hlen, nmr)
        register struct ifuba *ifu;
        int uban, hlen, nmr;
 {
        register struct ifuba *ifu;
        int uban, hlen, nmr;
 {
-       register caddr_t cp = (caddr_t)m_pgalloc(2 * (nmr + 1));
-       int i;
+       register caddr_t cp;
+       int i, ncl;
 
 COUNT(IF_UBAINIT);
 
 COUNT(IF_UBAINIT);
-       if (cp == 0)
-               return (0);
-       ifu->ifu_hlen = hlen;
-       ifu->ifu_uban = uban;
-       ifu->ifu_uba = uba_hd[uban].uh_uba;
-       ifu->ifu_r.ifrw_addr = cp + NBPG - hlen;
-       ifu->ifu_w.ifrw_addr = ifu->ifu_r.ifrw_addr + (nmr + 1) * NBPG;
+       ncl = clrnd(nmr + CLSIZE) / CLSIZE;
+       if (ifu->ifu_r.ifrw_addr)
+               cp = ifu->ifu_r.ifrw_addr - (CLBYTES - hlen);
+       else {
+               cp = m_clalloc(2 * ncl, MPG_SPACE);
+               if (cp == 0)
+                       return (0);
+               ifu->ifu_r.ifrw_addr = cp + CLBYTES - hlen;
+               ifu->ifu_w.ifrw_addr = ifu->ifu_r.ifrw_addr + ncl * CLBYTES;
+               ifu->ifu_hlen = hlen;
+               ifu->ifu_uban = uban;
+               ifu->ifu_uba = uba_hd[uban].uh_uba;
+       }
        if (if_ubaalloc(ifu, &ifu->ifu_r, nmr) == 0)
                goto bad;
        if (if_ubaalloc(ifu, &ifu->ifu_w, nmr) == 0)
                goto bad2;
        for (i = 0; i < nmr; i++)
        if (if_ubaalloc(ifu, &ifu->ifu_r, nmr) == 0)
                goto bad;
        if (if_ubaalloc(ifu, &ifu->ifu_w, nmr) == 0)
                goto bad2;
        for (i = 0; i < nmr; i++)
-               ifu->ifu_wmap[i] = ifu->ifu_w.ifrw_mr[i+1];
+               ifu->ifu_wmap[i] = ifu->ifu_w.ifrw_mr[i];
        ifu->ifu_xswapd = 0;
        return (1);
 bad2:
        ubarelse(ifu->ifu_uban, &ifu->ifu_r.ifrw_info);
 bad:
        ifu->ifu_xswapd = 0;
        return (1);
 bad2:
        ubarelse(ifu->ifu_uban, &ifu->ifu_r.ifrw_info);
 bad:
-       m_pgfree(cp, 2 * (nmr + 1));
+       m_pgfree(cp, 2 * ncl);
+       ifu->ifu_r.ifrw_addr = 0;
        return (0);
 }
 
 /*
  * Setup either a ifrw structure by allocating UNIBUS map registers,
        return (0);
 }
 
 /*
  * Setup either a ifrw structure by allocating UNIBUS map registers,
- * a buffered data path, and initializing the fields of the ifrw structure
- * to minimize run-time overhead.
+ * possibly a buffered data path, and initializing the fields of
+ * the ifrw structure to minimize run-time overhead.
  */
 static
 if_ubaalloc(ifu, ifrw, nmr)
  */
 static
 if_ubaalloc(ifu, ifrw, nmr)
@@ -76,12 +84,12 @@ if_ubaalloc(ifu, ifrw, nmr)
 COUNT(IF_UBAALLOC);
        info =
            uballoc(ifu->ifu_uban, ifrw->ifrw_addr, nmr*NBPG + ifu->ifu_hlen,
 COUNT(IF_UBAALLOC);
        info =
            uballoc(ifu->ifu_uban, ifrw->ifrw_addr, nmr*NBPG + ifu->ifu_hlen,
-               UBA_NEED16|UBA_NEEDBDP);
+               ifu->ifu_flags);
        if (info == 0)
                return (0);
        ifrw->ifrw_info = info;
        ifrw->ifrw_bdp = UBAI_BDP(info);
        if (info == 0)
                return (0);
        ifrw->ifrw_info = info;
        ifrw->ifrw_bdp = UBAI_BDP(info);
-       ifrw->ifrw_proto = UBAMR_MRV | (UBAI_MR(info) << UBAMR_DPSHIFT);
+       ifrw->ifrw_proto = UBAMR_MRV | (UBAI_BDP(info) << UBAMR_DPSHIFT);
        ifrw->ifrw_mr = &ifu->ifu_uba->uba_map[UBAI_MR(info) + 1];
        return (1);
 }
        ifrw->ifrw_mr = &ifu->ifu_uba->uba_map[UBAI_MR(info) + 1];
        return (1);
 }
@@ -103,7 +111,7 @@ if_rubaget(ifu, totlen, off0)
 {
        struct mbuf *top, **mp, *m;
        int off = off0, len;
 {
        struct mbuf *top, **mp, *m;
        int off = off0, len;
-       register caddr_t cp;
+       register caddr_t cp = ifu->ifu_r.ifrw_addr + ifu->ifu_hlen;
 
 COUNT(IF_RUBAGET);
 
 
 COUNT(IF_RUBAGET);
 
@@ -118,7 +126,7 @@ COUNT(IF_RUBAGET);
                        cp = ifu->ifu_r.ifrw_addr + ifu->ifu_hlen + off;
                } else
                        len = totlen;
                        cp = ifu->ifu_r.ifrw_addr + ifu->ifu_hlen + off;
                } else
                        len = totlen;
-               if (len >= CLSIZE) {
+               if (len >= CLBYTES) {
                        struct mbuf *p;
                        struct pte *cpte, *ppte;
                        int x, *ip, i;
                        struct mbuf *p;
                        struct pte *cpte, *ppte;
                        int x, *ip, i;
@@ -126,7 +134,7 @@ COUNT(IF_RUBAGET);
                        MCLGET(p, 1);
                        if (p == 0)
                                goto nopage;
                        MCLGET(p, 1);
                        if (p == 0)
                                goto nopage;
-                       m->m_len = CLSIZE;
+                       len = m->m_len = CLBYTES;
                        m->m_off = (int)p - (int)m;
                        if (!claligned(cp))
                                goto copy;
                        m->m_off = (int)p - (int)m;
                        if (!claligned(cp))
                                goto copy;
@@ -138,7 +146,7 @@ COUNT(IF_RUBAGET);
                        cpte = &Mbmap[mtocl(cp)*CLSIZE];
                        ppte = &Mbmap[mtocl(p)*CLSIZE];
                        x = btop(cp - ifu->ifu_r.ifrw_addr);
                        cpte = &Mbmap[mtocl(cp)*CLSIZE];
                        ppte = &Mbmap[mtocl(p)*CLSIZE];
                        x = btop(cp - ifu->ifu_r.ifrw_addr);
-                       ip = (int *)&ifu->ifu_r.ifrw_mr[x+1];
+                       ip = (int *)&ifu->ifu_r.ifrw_mr[x];
                        for (i = 0; i < CLSIZE; i++) {
                                struct pte t;
                                t = *ppte; *ppte++ = *cpte; *cpte = t;
                        for (i = 0; i < CLSIZE; i++) {
                                struct pte t;
                                t = *ppte; *ppte++ = *cpte; *cpte = t;
@@ -166,9 +174,10 @@ nocopy:
                        if (off == totlen) {
                                cp = ifu->ifu_r.ifrw_addr + ifu->ifu_hlen;
                                off = 0;
                        if (off == totlen) {
                                cp = ifu->ifu_r.ifrw_addr + ifu->ifu_hlen;
                                off = 0;
-                               totlen -= off0;
+                               totlen = off0;
                        }
                        }
-               }
+               } else
+                       totlen -= m->m_len;
        }
        return (top);
 bad:
        }
        return (top);
 bad:
@@ -194,19 +203,18 @@ if_wubaput(ifu, m)
        int x, cc;
 
 COUNT(IF_WUBAPUT);
        int x, cc;
 
 COUNT(IF_WUBAPUT);
-       ifu->ifu_xswapd = 0;
        cp = ifu->ifu_w.ifrw_addr;
        while (m) {
                dp = mtod(m, char *);
        cp = ifu->ifu_w.ifrw_addr;
        while (m) {
                dp = mtod(m, char *);
-               if (claligned(cp) && claligned(dp)) {
+               if (claligned(cp) && claligned(dp) && m->m_len == CLBYTES) {
                        struct pte *pte; int *ip;
                        pte = &Mbmap[mtocl(dp)*CLSIZE];
                        x = btop(cp - ifu->ifu_w.ifrw_addr);
                        struct pte *pte; int *ip;
                        pte = &Mbmap[mtocl(dp)*CLSIZE];
                        x = btop(cp - ifu->ifu_w.ifrw_addr);
-                       ip = (int *)&ifu->ifu_w.ifrw_mr[x + 1];
+                       ip = (int *)&ifu->ifu_w.ifrw_mr[x];
                        for (i = 0; i < CLSIZE; i++)
                                *ip++ =
                                    ifu->ifu_w.ifrw_proto | pte++->pg_pfnum;
                        for (i = 0; i < CLSIZE; i++)
                                *ip++ =
                                    ifu->ifu_w.ifrw_proto | pte++->pg_pfnum;
-                       ifu->ifu_xswapd |= 1 << (x>>(CLSHIFT-PGSHIFT));
+                       xswapd |= 1 << (x>>(CLSHIFT-PGSHIFT));
                        mp = m->m_next;
                        m->m_next = ifu->ifu_xtofree;
                        ifu->ifu_xtofree = m;
                        mp = m->m_next;
                        m->m_next = ifu->ifu_xtofree;
                        ifu->ifu_xtofree = m;
@@ -228,19 +236,19 @@ COUNT(IF_WUBAPUT);
         */
        cc = cp - ifu->ifu_w.ifrw_addr;
        x = ((cc - ifu->ifu_hlen) + CLBYTES - 1) >> CLSHIFT;
         */
        cc = cp - ifu->ifu_w.ifrw_addr;
        x = ((cc - ifu->ifu_hlen) + CLBYTES - 1) >> CLSHIFT;
+       ifu->ifu_xswapd &= ~xswapd;
        xswapd &= ~ifu->ifu_xswapd;
        xswapd &= ~ifu->ifu_xswapd;
-       if (xswapd)
-               while (i = ffs(xswapd)) {
-                       i--;
-                       if (i >= x)
-                               break;
-                       xswapd &= ~(1<<i);
-                       i *= CLSIZE;
-                       for (x = 0; x < CLSIZE; x++) {
-                               ifu->ifu_w.ifrw_mr[i] = ifu->ifu_wmap[i];
-                               i++;
-                       }
+       while (i = ffs(ifu->ifu_xswapd)) {
+               i--;
+               if (i >= x)
+                       break;
+               ifu->ifu_xswapd &= ~(1<<i);
+               i *= CLSIZE;
+               for (x = 0; x < CLSIZE; x++) {
+                       ifu->ifu_w.ifrw_mr[i] = ifu->ifu_wmap[i];
+                       i++;
                }
                }
+       }
        ifu->ifu_xswapd |= xswapd;
        return (cc);
 }
        ifu->ifu_xswapd |= xswapd;
        return (cc);
 }