X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/f1b2fa5b8a62e80603e6c83b87eaf0b06db3818e..176c481f62876316668544ff7b26e7956a4243de:/usr/src/sys/vax/if/if_uba.c diff --git a/usr/src/sys/vax/if/if_uba.c b/usr/src/sys/vax/if/if_uba.c index d08870f3c3..c9298a25d0 100644 --- a/usr/src/sys/vax/if/if_uba.c +++ b/usr/src/sys/vax/if/if_uba.c @@ -1,4 +1,4 @@ -/* if_uba.c 4.3 81/11/29 */ +/* if_uba.c 4.11 82/05/19 */ #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/socket.h" #include "../net/in.h" #include "../net/in_systm.h" #include "../net/if.h" @@ -34,52 +35,61 @@ if_ubainit(ifu, 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); - if (cp == 0) - return (0); - 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; - if (if_ubaalloc(ifu, &ifu->ifu_r) == 0) + 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) == 0) + if (if_ubaalloc(ifu, &ifu->ifu_w, nmr) == 0) goto bad2; - for (i = 0; i < IF_NUBAMR; i++) - ifu->ifu_wmap[i] = ifu->ifu_w.ifrw_mr[i+1]; + for (i = 0; i < nmr; i++) + 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: - 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, - * 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) +if_ubaalloc(ifu, ifrw, nmr) struct ifuba *ifu; register struct ifrw *ifrw; + int nmr; { register int info; COUNT(IF_UBAALLOC); info = - uballoc(ifu->ifu_uban, ifrw->ifrw_addr, IF_NUBAMR*NBPG + ifu->ifu_hlen, - UBA_NEED16|UBA_NEEDBDP); + uballoc(ifu->ifu_uban, ifrw->ifrw_addr, nmr*NBPG + ifu->ifu_hlen, + ifu->ifu_flags); 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); } @@ -99,10 +109,9 @@ if_rubaget(ifu, totlen, off0) register struct ifuba *ifu; int totlen, off0; { - register struct mbuf *m; - register caddr_t cp; - struct mbuf **mp, *p, *top; - int len, off = off0; + struct mbuf *top, **mp, *m; + int off = off0, len; + register caddr_t cp = ifu->ifu_r.ifrw_addr + ifu->ifu_hlen; COUNT(IF_RUBAGET); @@ -117,46 +126,30 @@ COUNT(IF_RUBAGET); 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 i, x, *ip; + int x, *ip, i; 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 ((int)cp & CLOFF) + if (!claligned(cp)) goto copy; /* - * Cluster size data on cluster size boundary. - * Input by remapping newly allocated pages to - * UNIBUS, and taking pages with data already - * in them. - * - * Cpte is the pte of the virtual memory which - * is mapped to the UNIBUS, and ppte is the pte - * for the fresh pages. We switch the memory - * copies of these pte's, to make the allocated - * virtual memory contain the data (using the old - * physical pages). We have to rewrite - * the UNIBUS map so that the newly allocated - * pages will be used for the next UNIBUS read, - * and invalidate the kernel translations - * for the virtual addresses of the pages - * we are flipping. - * - * The idea here is that this is supposed - * to take less time than copying the data. + * Switch pages mapped to UNIBUS with new page p, + * as quick form of copy. Remap UNIBUS and invalidate. */ - cpte = &Mbmap[mtocl(cp)]; - ppte = &Mbmap[mtocl(p)]; + 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; + t = *ppte; *ppte++ = *cpte; *cpte = t; *ip++ = cpte++->pg_pfnum|ifu->ifu_r.ifrw_proto; mtpr(TBIS, cp); @@ -176,13 +169,15 @@ nocopy: *mp = m; mp = &m->m_next; if (off) { + /* sort of an ALGOL-W style for statement... */ off += m->m_len; 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: @@ -204,39 +199,56 @@ if_wubaput(ifu, m) register struct mbuf *mp; register caddr_t cp, dp; register int i; - int xswapd = ifu->ifu_xswapd; - int x; + int xswapd = 0; + int x, cc; COUNT(IF_WUBAPUT); - ifu->ifu_xswapd = 0; 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)]; + 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; - ifu->ifu_xswapd |= 1 << (x>>CLSHIFT); - } else + xswapd |= 1 << (x>>(CLSHIFT-PGSHIFT)); + mp = m->m_next; + m->m_next = ifu->ifu_xtofree; + ifu->ifu_xtofree = m; + cp += m->m_len; + } else { bcopy(mtod(m, caddr_t), cp, (unsigned)m->m_len); - cp += m->m_len; - MFREE(m, mp); /* XXX too soon! */ + cp += m->m_len; + MFREE(m, mp); + } m = mp; } + + /* + * Xswapd is the set of clusters we just mapped out. Ifu->ifu_xswapd + * is the set of clusters mapped out from before. We compute + * the number of clusters involved in this operation in x. + * Clusters mapped out before and involved in this operation + * should be unmapped so original pages will be accessed by the device. + */ + cc = cp - ifu->ifu_w.ifrw_addr; + x = ((cc - ifu->ifu_hlen) + CLBYTES - 1) >> CLSHIFT; + ifu->ifu_xswapd &= ~xswapd; xswapd &= ~ifu->ifu_xswapd; - if (xswapd) - while (i = ffs(xswapd)) { - i--; - xswapd &= ~(1<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<ifu_w.ifrw_mr[i] = ifu->ifu_wmap[i]; + i++; } - return (cp - ifu->ifu_w.ifrw_addr); + } + ifu->ifu_xswapd |= xswapd; + return (cc); }