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: * @(#)kern_subr.c 1.2 (2.11BSD GTE) 11/26/94 7: */ 8: 9: #include "param.h" 10: #include "../machine/seg.h" 11: 12: #include "systm.h" 13: #include "user.h" 14: #include "buf.h" 15: #include "uio.h" 16: 17: /* copied, for supervisory networking, to sys_net.c */ 18: uiomove(cp, n, uio) 19: caddr_t cp; 20: u_int n; 21: register struct uio *uio; 22: { 23: register struct iovec *iov; 24: int error = 0; 25: register u_int cnt; 26: 27: while (n > 0 && uio->uio_resid) { 28: iov = uio->uio_iov; 29: cnt = iov->iov_len; 30: if (cnt == 0) { 31: uio->uio_iov++; 32: uio->uio_iovcnt--; 33: continue; 34: } 35: if (cnt > n) 36: cnt = n; 37: switch (uio->uio_segflg) { 38: 39: case UIO_USERSPACE: 40: if (cnt > 100 && cp + cnt < SEG6) 41: error = uiofmove(cp, cnt, uio, iov); 42: else if ((cnt | (int)cp | (int)iov->iov_base) & 1) 43: if (uio->uio_rw == UIO_READ) 44: error = vcopyout(cp,iov->iov_base, cnt); 45: else 46: error = vcopyin(iov->iov_base, cp, cnt); 47: else { 48: if (uio->uio_rw == UIO_READ) 49: error = copyout(cp, iov->iov_base, cnt); 50: else 51: error = copyin(iov->iov_base, cp, cnt); 52: } 53: if (error) 54: return (error); 55: break; 56: 57: case UIO_USERISPACE: 58: if (cnt > 100 && cp + cnt < SEG6) 59: error = uiofmove(cp, cnt, uio, iov); 60: else if (uio->uio_rw == UIO_READ) 61: error = copyiout(cp, iov->iov_base, cnt); 62: else 63: error = copyiin(iov->iov_base, cp, cnt); 64: if (error) 65: return (error); 66: break; 67: 68: case UIO_SYSSPACE: 69: if (uio->uio_rw == UIO_READ) 70: bcopy((caddr_t)cp, iov->iov_base, cnt); 71: else 72: bcopy(iov->iov_base, (caddr_t)cp, cnt); 73: break; 74: } 75: iov->iov_base += cnt; 76: iov->iov_len -= cnt; 77: uio->uio_resid -= cnt; 78: uio->uio_offset += cnt; 79: cp += cnt; 80: n -= cnt; 81: } 82: return (error); 83: } 84: 85: /* copied, for supervisory networking, to sys_net.c */ 86: /* 87: * Give next character to user as result of read. 88: */ 89: ureadc(c, uio) 90: register int c; 91: register struct uio *uio; 92: { 93: register struct iovec *iov; 94: 95: again: 96: if (uio->uio_iovcnt == 0) 97: panic("ureadc"); 98: iov = uio->uio_iov; 99: if (iov->iov_len == 0 || uio->uio_resid == 0) { 100: uio->uio_iovcnt--; 101: uio->uio_iov++; 102: goto again; 103: } 104: switch (uio->uio_segflg) { 105: 106: case UIO_USERSPACE: 107: if (subyte(iov->iov_base, c) < 0) 108: return (EFAULT); 109: break; 110: 111: case UIO_SYSSPACE: 112: *iov->iov_base = c; 113: break; 114: 115: case UIO_USERISPACE: 116: if (suibyte(iov->iov_base, c) < 0) 117: return (EFAULT); 118: break; 119: } 120: iov->iov_base++; 121: iov->iov_len--; 122: uio->uio_resid--; 123: uio->uio_offset++; 124: return (0); 125: } 126: 127: /* copied, for supervisory networking, to sys_net.c */ 128: /* 129: * Get next character written in by user from uio. 130: */ 131: uwritec(uio) 132: register struct uio *uio; 133: { 134: register struct iovec *iov; 135: register int c; 136: 137: if (uio->uio_resid == 0) 138: return (-1); 139: again: 140: if (uio->uio_iovcnt <= 0) 141: panic("uwritec"); 142: iov = uio->uio_iov; 143: if (iov->iov_len == 0) { 144: uio->uio_iov++; 145: if (--uio->uio_iovcnt == 0) 146: return (-1); 147: goto again; 148: } 149: switch (uio->uio_segflg) { 150: 151: case UIO_USERSPACE: 152: c = fubyte(iov->iov_base); 153: break; 154: 155: case UIO_SYSSPACE: 156: c = *iov->iov_base & 0377; 157: break; 158: 159: case UIO_USERISPACE: 160: c = fuibyte(iov->iov_base); 161: break; 162: } 163: if (c < 0) 164: return (-1); 165: iov->iov_base++; 166: iov->iov_len--; 167: uio->uio_resid--; 168: uio->uio_offset++; 169: return (c & 0377); 170: } 171: 172: /* 173: * Copy bytes to/from the kernel and the user. Uiofmove assumes the kernel 174: * area being copied to or from does not overlap segment 6 - the assembly 175: * language helper routine, fmove, uses segment register 6 to map in the 176: * user's memory. 177: */ 178: uiofmove(cp, n, uio, iov) 179: caddr_t cp; 180: register int n; 181: struct uio *uio; 182: struct iovec *iov; 183: { 184: register short c; 185: short on; 186: register short segr; /* seg register (0 - 7) */ 187: u_short *segd; /* PDR map array */ 188: u_short *sega; /* PAR map array */ 189: int error; 190: 191: #ifdef NONSEPARATE 192: segd = UISD; 193: sega = UISA; 194: #else 195: if (uio->uio_segflg == UIO_USERSPACE && u.u_sep) { 196: segd = UDSD; 197: sega = UDSA; 198: } 199: else { 200: segd = UISD; 201: sega = UISA; 202: } 203: #endif 204: 205: segr = (short)iov->iov_base >> 13 & 07; 206: on = (short)iov->iov_base & 017777; 207: c = MIN(n, 8192-on); 208: for (;;) { 209: if (uio->uio_rw == UIO_READ) 210: error = fmove(sega[segr], segd[segr], cp, SEG6+on, c); 211: else 212: error = fmove(sega[segr], segd[segr], SEG6+on, cp, c); 213: if (error) 214: return(error); 215: n -= c; 216: if (!n) 217: return(0); 218: cp += c; 219: segr++; 220: segr &= 07; 221: on = 0; 222: c = MIN(n, 8192); 223: } 224: /*NOTREACHED*/ 225: }