1: /* 2: * Copyright (c) 1988 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: * @(#)sys_net.c 1.5 (2.11BSD GTE) 1997/2/16 7: * 8: * Print the csr of attached ethernet cards. sms - 1997/2/16 9: * 10: * Initialize the supervisor mode 'hz' variable via a call from the kernel 11: * rather compiling in a constant. sms - 1997/2/14 12: * 13: * Change uiomove calling convention. The r/w type is now encapsulated 14: * in the uio structure now. sms - 11/26/94 15: * 16: * 2.11BSD - map the I/O region with sufficient UMRs. this precludes 17: * drivers such as the DEUNA from allocating a UMR per packet. 18: * sms - 9/8/90 19: */ 20: 21: #include "param.h" 22: #include "../machine/cons.h" 23: #include "../machine/psl.h" 24: 25: #include "user.h" 26: #include "uio.h" 27: #include "map.h" 28: #include "uba.h" 29: #include "mbuf.h" 30: #include "acct.h" 31: #include "ioctl.h" 32: #include "tty.h" 33: 34: #include "../pdpuba/ubavar.h" 35: 36: #include "acc.h" 37: #if NACC > 0 38: extern struct uba_driver accdriver; 39: #endif 40: 41: #include "css.h" 42: #if NCSS > 0 43: extern struct uba_driver cssdriver; 44: #endif 45: 46: #include "de.h" 47: #if NDE > 0 48: extern struct uba_driver dedriver; 49: #endif 50: 51: #include "ec.h" 52: #if NEC > 0 53: extern struct uba_driver ecdriver; 54: #endif 55: 56: #include "il.h" 57: #if NIL > 0 58: extern struct uba_driver ildriver; 59: #endif 60: 61: #include "qe.h" 62: #if NQE > 0 63: extern struct uba_driver qedriver; 64: #endif 65: 66: #include "qt.h" 67: #if NQT > 0 68: extern struct uba_driver qtdriver; 69: #endif 70: 71: #include "sri.h" 72: #if NSRI > 0 73: extern struct uba_driver sridriver; 74: #endif 75: 76: #include "vv.h" 77: #if NVV > 0 78: extern struct uba_driver vvdriver; 79: #endif 80: 81: static struct uba_device ubdinit[] = { 82: #if NDE > 0 83: { &dedriver, 0,0, (caddr_t)0174510 }, 84: #endif 85: #if NIL > 0 86: { &ildriver, 0,0, (caddr_t)0164000 }, 87: #endif 88: #if NQE > 0 89: { &qedriver, 0,0, (caddr_t)0174440, 0, 0 }, 90: #endif 91: #if NQE > 1 92: { &qedriver, 1,0, (caddr_t)0174460, 0, 0 }, 93: #endif 94: #if NQT > 0 95: { &qtdriver, 0,0, (caddr_t)0174440, 0, 0 }, 96: #endif 97: #if NQT > 1 98: { &qtdriver, 1,0, (caddr_t)0174460, 0, 0 }, 99: #endif 100: #if NSRI > 0 101: { &sridriver, 0,0, (caddr_t)0167770 }, 102: #endif 103: #if NVV > 0 104: { &vvdriver, 0,0, (caddr_t)0161000 }, 105: #endif 106: #if NEC > 0 107: { &ecdriver, 0,0, (caddr_t)0164330 }, 108: #endif 109: #if NACC > 0 110: { &accdriver, 0,0, (caddr_t)0000000 }, 111: #endif 112: #if NCSS > 0 113: { &cssdriver, 0,0, (caddr_t)0000000 }, 114: #endif 115: NULL, 116: }; 117: 118: int hz; /* kernel calls netsethz() to initialize */ 119: long startnet; /* start of network data space */ 120: 121: void 122: netsethz(ticks) 123: int ticks; 124: { 125: 126: hz = ticks; 127: } 128: 129: netstart() 130: { 131: extern memaddr miobase, miostart, netdata; 132: extern ubadr_t mioumr; 133: extern u_short miosize; 134: register struct uba_driver *udp; 135: register struct uba_device *ui = ubdinit; 136: register int s; 137: char *attaching = "attaching "; 138: int first; 139: struct ubmap *ubp; 140: ubadr_t paddr; 141: 142: /* 143: * The networking uses a mapped region as the DMA area for 144: * network interface drivers. Allocate this latter region. 145: */ 146: if ((miobase = MALLOC(coremap, btoc(miosize))) == 0) 147: panic("miobase"); 148: 149: /* 150: * Allocate sufficient UMRs to map the DMA region. Save the 151: * starting click and UNIBUS addresses for use in ubmalloc later. 152: * This is early in the systems life, so there had better be 153: * sufficient UMRs available! 154: */ 155: if (mfkd(&ubmap)) { 156: miostart = miobase; 157: s = (int)btoub(miosize); 158: first = MALLOC(ub_map, s); 159: #ifdef DIAGNOSTIC 160: if (!first) 161: panic("ub_map"); 162: #endif 163: mioumr = (ubadr_t)first << 13; 164: ubp = &UBMAP[first]; 165: paddr = ctob((ubadr_t)miostart); 166: while (s--) { 167: ubp->ub_lo = loint(paddr); 168: ubp->ub_hi = hiint(paddr); 169: ubp++; 170: paddr += (ubadr_t)UBPAGE; 171: } 172: } 173: 174: startnet = ctob((long)mfkd(&netdata)); 175: 176: mbinit(); 177: for (ui = ubdinit; udp = ui->ui_driver; ++ui) { 178: if (badaddr(ui->ui_addr, 2)) 179: continue; 180: ui->ui_alive = 1; 181: udp->ud_dinfo[ui->ui_unit] = ui; 182: printf("%s%s%d csr %o\n", attaching,udp->ud_dname,ui->ui_unit, 183: ui->ui_addr); 184: (*udp->ud_attach)(ui); 185: } 186: #include "sl.h" 187: #if NSL > 0 188: printf("%ssl\n", attaching); 189: slattach(); 190: #endif 191: 192: #include "loop.h" 193: #if NLOOP > 0 194: printf("%slo0\n", attaching); 195: loattach(); 196: #endif 197: 198: s = splimp(); 199: ifinit(); 200: domaininit(); /* must follow interfaces */ 201: splx(s); 202: } 203: 204: /* 205: * Panic is called on fatal errors. It prints "net panic: mesg" and 206: * then calls the kernel entry netcrash() to bring down the net. 207: */ 208: panic(s) 209: register char *s; 210: { 211: printf("net panic: %s\n", s); 212: NETCRASH(); 213: /* NOTREACHED */ 214: } 215: 216: netcopyout(m, to, len) 217: struct mbuf *m; 218: char *to; 219: int *len; 220: { 221: if (*len > m->m_len) 222: *len = m->m_len; 223: return(copyout(mtod(m, caddr_t), to, *len)); 224: } 225: 226: /* 227: * These routines are copies of various kernel routines that are required in 228: * the supervisor space by the networking. DO NOT MODIFY THESE ROUTINES! 229: * Modify the kernel version and bring a copy here. The "#ifdef notdef" 230: * modifications simplify by eliminating portions of routines not required 231: * by the networking. 232: */ 233: 234: /* copied from kern_descrip.c */ 235: ufavail() 236: { 237: register int i, avail = 0; 238: 239: for (i = 0; i < NOFILE; i++) 240: if (u.u_ofile[i] == NULL) 241: avail++; 242: return (avail); 243: } 244: 245: /* copied from kern_descrip.c */ 246: ufalloc(i) 247: register int i; 248: { 249: 250: for (; i < NOFILE; i++) 251: if (u.u_ofile[i] == NULL) { 252: u.u_r.r_val1 = i; 253: u.u_pofile[i] = 0; 254: if (i > u.u_lastfile) 255: u.u_lastfile = i; 256: return (i); 257: } 258: u.u_error = EMFILE; 259: return (-1); 260: } 261: 262: /* copied from ufs_fio.c */ 263: suser() 264: { 265: 266: if (u.u_uid == 0) { 267: u.u_acflag |= ASU; 268: return (1); 269: } 270: u.u_error = EPERM; 271: return (0); 272: } 273: 274: /* copied from kern_sysctl.c */ 275: sysctl_int(oldp, oldlenp, newp, newlen, valp) 276: void *oldp; 277: size_t *oldlenp; 278: void *newp; 279: size_t newlen; 280: int *valp; 281: { 282: int error = 0; 283: 284: if (oldp && *oldlenp < sizeof(int)) 285: return (ENOMEM); 286: if (newp && newlen != sizeof(int)) 287: return (EINVAL); 288: *oldlenp = sizeof(int); 289: if (oldp) 290: error = copyout(valp, oldp, sizeof(int)); 291: if (error == 0 && newp) 292: error = copyin(newp, valp, sizeof(int)); 293: return (error); 294: } 295: 296: /* 297: * An old version of uiomove, as uiofmove() and vcopy{in,out}() don't 298: * exist in supervisor space. Note, we assume that all transfers will 299: * be to/from user D space. Probably safe, until someone decides to 300: * put NFS into the kernel. 301: * 302: * The 4.3BSD uio/iovec paradigm adopted, ureadc() and uwritec() inlined 303: * at that time to speed things up. 3/90 sms 304: */ 305: uiomove(cp, n, uio) 306: caddr_t cp; 307: u_int n; 308: register struct uio *uio; 309: { 310: register struct iovec *iov; 311: int error, count, ch; 312: register u_int cnt; 313: 314: #ifdef DIAGNOSTIC 315: if (uio->uio_segflg != UIO_USERSPACE) 316: panic("net uiomove"); 317: #endif 318: while (n && uio->uio_resid) { 319: iov = uio->uio_iov; 320: cnt = iov->iov_len; 321: if (cnt == 0) { 322: uio->uio_iov++; 323: uio->uio_iovcnt--; 324: continue; 325: } 326: if (cnt > n) 327: cnt = n; 328: count = cnt; 329: if ((cnt | (int)cp | (int)iov->iov_base) & 1) { 330: if (uio->uio_rw == UIO_READ) { 331: while (cnt--) 332: if (subyte(iov->iov_base++, *cp++) < 0) 333: return (EFAULT); 334: } 335: else { 336: while (cnt--) { 337: if ((ch = fubyte(iov->iov_base++)) < 0) 338: return (EFAULT); 339: *cp++ = ch; 340: } 341: } 342: cnt = count; /* use register */ 343: } 344: else { 345: if (uio->uio_rw == UIO_READ) 346: error = copyout(cp, iov->iov_base, cnt); 347: else 348: error = copyin(iov->iov_base, cp, cnt); 349: if (error) 350: return (error); 351: iov->iov_base += cnt; 352: cp += cnt; 353: } 354: iov->iov_len -= cnt; 355: uio->uio_resid -= cnt; 356: uio->uio_offset += cnt; 357: n -= cnt; 358: } 359: return (0); 360: } 361: 362: #define TOCONS 0x1 363: #define TOTTY 0x2 364: #define TOLOG 0x4 365: 366: /* copied from subr_prf.c */ 367: /*VARARGS1*/ 368: printf(fmt, x1) 369: char *fmt; 370: unsigned x1; 371: { 372: prf(fmt, &x1, TOCONS | TOLOG); 373: } 374: 375: /* copied from subr_prf.c */ 376: prf(fmt, adx, flags) 377: register char *fmt; 378: register u_int *adx; 379: int flags; 380: { 381: register int c; 382: u_int b; 383: char *s; 384: int i, any; 385: 386: loop: 387: while ((c = *fmt++) != '%') { 388: if (c == '\0') 389: return; 390: _pchar(c, flags); 391: } 392: c = *fmt++; 393: switch (c) { 394: 395: case 'l': 396: c = *fmt++; 397: switch(c) { 398: case 'x': 399: b = 16; 400: goto lnumber; 401: case 'd': 402: b = 10; 403: goto lnumber; 404: case 'o': 405: b = 8; 406: goto lnumber; 407: default: 408: _pchar('%', flags); 409: _pchar('l', flags); 410: _pchar(c, flags); 411: } 412: break; 413: case 'X': 414: b = 16; 415: goto lnumber; 416: case 'D': 417: b = 10; 418: goto lnumber; 419: case 'O': 420: b = 8; 421: lnumber: printn(*(long *)adx, b, flags); 422: adx += (sizeof(long) / sizeof(int)) - 1; 423: break; 424: case 'x': 425: b = 16; 426: goto number; 427: case 'd': 428: case 'u': /* what a joke */ 429: b = 10; 430: goto number; 431: case 'o': 432: b = 8; 433: number: printn((long)*adx, b, flags); 434: break; 435: case 'c': 436: _pchar(*adx, flags); 437: break; 438: case 'b': 439: b = *adx++; 440: s = (char *)*adx; 441: printn((long)b, *s++, flags); 442: any = 0; 443: if (b) { 444: while (i = *s++) { 445: if (b & (1 << (i - 1))) { 446: _pchar(any? ',' : '<', flags); 447: any = 1; 448: for (; (c = *s) > 32; s++) 449: _pchar(c, flags); 450: } else 451: for (; *s > 32; s++) 452: ; 453: } 454: if (any) 455: _pchar('>', flags); 456: } 457: break; 458: case 's': 459: s = (char *)*adx; 460: while (c = *s++) 461: _pchar(c, flags); 462: break; 463: case '%': 464: _pchar(c, flags); 465: break; 466: default: 467: _pchar('%', flags); 468: _pchar(c, flags); 469: break; 470: } 471: adx++; 472: goto loop; 473: } 474: 475: /* copied from subr_prf.c */ 476: printn(n, b, flags) 477: long n; 478: u_int b; 479: { 480: char prbuf[12]; 481: register char *cp = prbuf; 482: register int offset = 0; 483: 484: if (n<0) 485: switch(b) { 486: case 8: /* unchecked, but should be like hex case */ 487: case 16: 488: offset = b-1; 489: n++; 490: break; 491: case 10: 492: _pchar('-', flags); 493: n = -n; 494: break; 495: } 496: do { 497: *cp++ = "0123456789ABCDEF"[offset + n%b]; 498: } while (n = n/b); /* Avoid n /= b, since that requires alrem */ 499: do 500: _pchar(*--cp, flags); 501: while (cp > prbuf); 502: } 503: 504: extern int putchar(); 505: 506: _pchar(c, flg) 507: int c, flg; 508: { 509: return(SKcall(putchar, sizeof(int)+sizeof(int)+sizeof(struct tty *), 510: c, flg, (struct tty *)0)); 511: }