/* * Copyright (c) 1982, 1986 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * * @(#)imptst.c 6.2 (Berkeley) 6/8/85 */ #include "../machine/pte.h" #include "param.h" #include "inode.h" #include "fs.h" #include "../vaxuba/ubareg.h" #include "../netinet/in.h" #include "../netinet/in_systm.h" #define IMPLEADERS #include "../netimp/if_imp.h" #include "../vaxif/if_accreg.h" #include "saio.h" #include "savax.h" #define min(a,b) (a<b ? a : b) #define BUFSIZ (1006+sizeof(struct imp_leader)) char input[132]; char inbuf[BUFSIZ]; char outbuf[BUFSIZ]; struct imp_leader *oip = (struct imp_leader *)outbuf; struct imp_leader *iip = (struct imp_leader *)inbuf; int verbose = 1; int datalen = 0; main() { register error = 0, i, len; short type, host, impno, link; register struct accdevice *addr = (struct accdevice *)ubamem(0, 0767700); register char *p, pattern = 0; printf("imp interface loopback diagnostic\n"); printf("verbose(y or n)? "); gets(input); verbose = (*input != 'n'); printf("enter destination host number: "); gets(input); while ((host = (short)atol(input)) < 0 || host > 255) { printf("range [0, 255], re-enter: "); gets(input); } printf("imp number: "); gets(input); while ((impno = (short)atol(input)) < 0 || impno > 32767) { printf("range [0, 32767], re-enter: "); gets(input); } printf("link number: "); gets(input); while ((link = (short)atol(input)) < 0 || link > 255) { printf("range [0, 255], re-enter: "); gets(input); } printf("initialization starting...\n"); impinit(); oip->il_format = IMP_NFF; oip->il_mtype = IMPTYPE_NOOP; #define noop #ifdef noop /* send 3 noops and init imp leader buffer */ impnoops((struct control_leader *)oip); #endif printf("initialization complete\n"); while (1) { if (verbose) printf("starting write test...\n"); oip->il_host = host; oip->il_imp = htons((u_short)impno); oip->il_link = link; for (p = (char *)(oip + 1), i = datalen; i--; ) *p = pattern++; error = impwrite(oip, datalen + sizeof (*oip)); if (error) printf("imp write error, ocsr=%b\n", (short)error, ACC_OUTBITS); if (verbose) printf("starting read test...\n"); if (verbose) printf("impread(%d)\n", sizeof (*iip)); bzero(inbuf, sizeof(inbuf)); error = impread(iip, sizeof (inbuf)); if (verbose) printf("impread, error=%b\n", error, ACC_INBITS); if (verbose) printleader(iip); if (bcmp(iip, oip, sizeof(*iip) != 0)) printf("leader data error\n"); len = ntohs(iip->il_length); if (len != datalen) printf("length mismatch, got %d instead of %d\n", len, datalen); /* read any data */ p = (char *)(iip + 1); while ((error & IN_EOM) == 0 && (error & ~IN_EOM) == 0 && len > 0) { i = min(len, BUFSIZ); printf("impread(%d)\n", i); error = impread(p, i); len -= i; p += i; printf("error=%b, len=%d\n", error, ACC_INBITS, len); } error &= ~IN_EOM; if (error == 0 && (len > 0 || addr->iwc)) printf("imp input length mismatch\n"); if (error) printf("imp read error, icsr=%b\n", (short)error, ACC_INBITS); else if (bcmp(iip + 1, oip + 1, datalen)) printf("data comparison error\n"); } } impnoops(cp) register struct control_leader *cp; { register i, error; bzero((caddr_t)cp, sizeof (struct control_leader)); cp->dl_format = IMP_NFF; cp->dl_mtype = IMPTYPE_NOOP; for (i = 0; i < IMP_DROPCNT + 1; i++ ) { cp->dl_link = i; if ((error = impwrite(cp, sizeof (*cp))) != 0) { printf("imp init error, ocsr=%b\n", (short)error, ACC_OUTBITS); _stop(); } } for (i = 0; i < IMP_DROPCNT + 1; i++ ) { bzero((caddr_t)iip, sizeof(*iip)); error = impread(iip, sizeof (inbuf)); if (verbose) printf("impread, error=%b\n", error, ACC_INBITS); if (verbose) printleader(iip); } } impwrite(buf, len) register struct imp *buf; register len; { register uba, error; struct iob io; register struct accdevice *addr = (struct accdevice *)ubamem(0, 0767600); /* set up uba mapping */ io.i_ma = (caddr_t)buf; io.i_cc = len; uba = ubasetup(&io, 0); /* set regs and perform i/o */ addr->oba = (u_short)uba; addr->owc = -((io.i_cc + 1) >> 1); addr->ocsr = ((short) ((uba & 0x30000) >> 12) | OUT_ENLB | ACC_GO); while ((addr->ocsr & ACC_RDY) == 0) ; error = addr->ocsr & (ACC_NXM|ACC_ERR); ubafree(uba); return(error); } impread(buf, len) register struct imp *buf; register len; { register uba, error; struct iob io; register struct accdevice *addr = (struct accdevice *)ubamem(0, 0767600); /* set up uba mapping */ io.i_ma = (caddr_t)buf; io.i_cc = len; uba = ubasetup(&io, 0); /* set regs and perform i/o */ addr->iba = (u_short)uba; addr->iwc = -(io.i_cc >> 1); addr->icsr = IN_MRDY | IN_WEN | ((uba & 0x30000) >> 12) | ACC_GO; while ((addr->icsr & ACC_RDY) == 0) ; error = addr->icsr & (IN_EOM|ACC_ERR|IN_RMR|ACC_NXM); ubafree(uba); return(error); } impinit() { register struct accdevice *addr = (struct accdevice *)ubamem(0, 0767600); register int i; /* * Reset the imp interface; * the delays are pure guesswork. */ addr->icsr = ACC_RESET; DELAY(5000); addr->ocsr = ACC_RESET; DELAY(5000); addr->ocsr = OUT_BBACK; DELAY(5000); /* reset host master ready */ addr->ocsr = 0; addr->icsr = IN_MRDY | IN_WEN; /* close the relay */ DELAY(10000); /* YECH!!! */ for (i = 0; i < 500; i++) { if ((addr->icsr & IN_HRDY) && (addr->icsr & (IN_RMR | IN_IMPBSY)) == 0) return; addr->icsr = IN_MRDY | IN_WEN; DELAY(10000); /* keep turning IN_RMR off */ } printf("impinit: imp doesn't respond, icsr=%b, ocsr=%b\n", addr->icsr, ACC_INBITS, addr->ocsr, ACC_OUTBITS); } /* * Convert null-terminated ascii string to binary * and return value. * 1st char in string : * 0 -> octal * x -> hex * else decimal */ atol(as) register char *as; { register value = 0; register base = 10; register sign = 1; register digit = 0; aloop : if ((digit = (*as++)) == 0) return(value) ; /* null */ if (digit == '-') { sign = -sign; goto aloop ; } if (digit == '0') base = 8 ; else if (digit == 'x') base = 16 ; else value = digit - '0'; while (digit = (*as++)) { if (digit < '0') return(0); switch (base) { case 8 : if (digit > '7') return(0); digit -= '0'; break; case 10 : if (digit > '9') return(0); digit -= '0'; break; case 16 : if (digit <= '9') { digit -= 060 ; break; } if ((digit >= 'A') && (digit <= 'F')) { digit -= 'A' + 10; break; } if ((digit >= 'a') && (digit <= 'f')) { digit -= 'a' + 10 ; break; } return(0); } value = (value * base) + digit; } return (value * sign); } printleader(ip) register struct imp_leader *ip; { printbyte((char *)ip, 12); printf("<fmt=%x,net=%x,flags=%x,mtype=", ip->il_format, ip->il_network, ip->il_flags); if (ip->il_mtype <= IMPTYPE_READY) printf("%s,", impleaders[ip->il_mtype]); else printf("%x,", ip->il_mtype); printf("htype=%x,host=%x,imp=%x,link=", ip->il_htype, ip->il_host, ntohs(ip->il_imp)); if (ip->il_link == IMPLINK_IP) printf("ip,"); else printf("%x,", ip->il_link); printf("subtype=%x,len=%x>\n",ip->il_subtype,ntohs(ip->il_length)>>3); } printbyte(cp, n) register char *cp; int n; { register i, j, c; for (i=0; i<n; i++) { c = *cp++; for (j=0; j<2; j++) putchar("0123456789abcdef"[(c>>((1-j)*4))&0xf]); putchar(' '); } putchar('\n'); }