/* This is a very simple loop-back test program for the IKON 10103 Sbus DR11-W emulator and its driver. It first tests the software timeout functions, and then loops continuously on tests of various board and driver functions. With each successful pass, it outputs an asterisk "*". In the event of a failure, it prints a brief message describing the test that failed, and halts. */ #include #include #include /* for sunos 4.1.1 and later (Solaris 1.x) use #include "./idrio.h" for Solaris 2.x use #include "./idr_io.h" */ #include "./idrio.h" u_short datarray[10000] ; int ii, i, f ; extern errno ; char devname[31]; u_long arg[16] ; main() { printf("\nIKON 10103 Sbus DR11-W emulator loop-back test\n") ; printf("\na suitable loop-back cable must be installed before this test is run\n\n") ; printf("three timeout test will be done first - each takes 10 seconds\n") ; printf("the timeout tests will cause a DMA timeout message on the console\n") ; printf("following that an endless loop of loop-back tests will be performed\n") ; printf("at the end of each successful pass an asterisk \"*\" will be output\n") ; printf("an error will print a message and halt the tests\n") ; printf("use control-C to terminate the tests\n") ; printf("\n") ; /* open the device */ strcpy(devname,"/dev/idr0\0") ; f = open(devname,O_RDWR) ; if(f == -1) { printf("could not open device, errno = 0x%x\n",errno) ; exit(0) ; } /* set the timeout values to 5 seconds each and test */ arg[0] = 10 ; if(ioctl(f,IDRIO_SET_ATTN_TIME,arg) == -1) { printf("test# 00.10: error setting attention timeout, errno = 0x%x\n",errno) ; exit(0) ; } /* do a wait for attention - should time out */ if(ioctl(f,IDRIO_ATTN_WAIT,arg) != -1) { printf("test#00.20: attention wait timeout test did not time out\n") ; exit(0) ; } printf("attention wait timeout test OK\n") ; arg[0] = 10 ; if(ioctl(f,IDRIO_SET_RDY_TIME,arg) == -1) { printf("test# 00.30: error setting ready timeout, errno = 0x%x\n",errno) ; exit(0) ; } /* issue a go - to clear ready */ arg[0] = IDR_GO ; if(ioctl(f,IDRIO_IMM_PULSE,arg) == -1) { printf("test# 00.40: error sending go pulse, errno = 0x%x\n",errno) ; exit(0) ; } /* do a ready wait - should time out */ if(ioctl(f,IDRIO_RDY_WAIT,arg) != -1) { printf("test# 00.50: ready wait timeout test did not time out\n") ; exit(0) ; } printf("ready wait timeout test OK\n") ; /* loop back an attention pulse to set ready again */ arg[0] = IDR_ATTN ; if(ioctl(f,IDRIO_IMM_PULSE,arg) == -1) {printf("test# 00.60: error issuing aclo-fnct2 pulse, errno = 0x%x\n",errno) ; exit(0) ; } arg[0] = 10 ; if(ioctl(f,IDRIO_SET_DMA_TIME,arg) == -1) { printf("test# 00.70: error setting dma timeout, errno = 0x%x\n",errno) ; exit(0) ; } /* make sure that the cycle bit will not be set during dma - to ensure a timeout */ arg[0] = IDR_GO ; if(ioctl(f,IDRIO_READ_PULSE,arg) == -1) { printf("test# 00.80: error setting read pulses, errno = 0x%x\n",errno) ; exit(0) ; } /* do a dma input - should time out */ if(read(f,datarray,10) != -1) { printf("test# 00.90: dma timeout test did not time out\n") ; exit(0) ; } printf("dma timeout test OK\n") ; /* loop forever on other tests */ printf("starting endless loop-back tests\n") ; while(1) { /* "rewind" the driver - some versions of unix count total bytes transferred and block further reads/writes when some giant number overflows */ if(lseek(f,(off_t)0,0) == -1) { printf("test# 10.00: lseek error, errno = 0x%x\n",errno) ; exit(0) ; } /* clear dr11 logic - MASTER CLEAR SHOULD NOT BE USED BY MOST PROGRAMS!!!!! */ arg[0] = IDR_MCLR ; if(ioctl(f,IDRIO_IMM_PULSE,arg) == -1) { printf("test# 10.01: error issuing master clear pulse, errno = 0x%x\n",errno) ; exit(0) ; } /* test function/status bits */ /* set function bits */ arg[0] = IDR_FCN1 | IDR_FCN2 | IDR_FCN3 ; if(ioctl(f,IDRIO_IMM_FCN,arg) == -1) { printf("test# 10.10: error setting function bits, errno = 0x%x\n",errno) ; exit(0) ; } /* read status bits */ if(ioctl(f,IDRIO_GET_STATUS,arg) == -1) { printf("test# 10.20: error reading status, errno = 0x%x\n",errno) ; exit(0) ; } /* should have status a, b, and c, ready, attention, and attention flag set */ if(arg[0] != (IDR_STTA | IDR_STTB | IDR_STTC | IDR_REDY | IDR_ATTN | IDR_ATTF)) { printf("test# 10.30: incorrect status bits: status = 0x%x\n", arg[0]) ; exit(0) ; } /* clear function bits */ arg[0] = 0 ; if(ioctl(f,IDRIO_IMM_FCN,arg) == -1) { printf("test# 10.40: error setting function bits, errno = 0x%x\n",errno) ; exit(0) ; } /* attention flag should still be set */ if(ioctl(f,IDRIO_GET_STATUS,arg) == -1) { printf("test# 10.50: error reading status, errno = 0x%x\n",errno) ; exit(0) ; } if(arg[0] != (IDR_REDY | IDR_ATTF)) { printf("test# 10.60: incorrect status bits: status = 0x%x\n", arg[0]) ; exit(0) ; } /* do a wait for attention flag - it should find the ATTF and clear it */ if(ioctl(f,IDRIO_ATTN_WAIT,arg) == -1) { printf("test# 10.70: error waiting for attention, errno = 0x%x\n",errno) ; exit(0) ; } if(ioctl(f,IDRIO_GET_STATUS,arg) == -1) { printf("test# 10.80: error reading status, errno = 0x%x\n",errno) ; exit(0) ; } if(arg[0] != IDR_REDY ) { printf("test# 10.90: incorrect status bits: status = 0x%x\n", arg[0]) ; exit(0) ; } /* test pulse commands - actually most pulses are used in normal operation of other portions of the driver - particularly for dma transfers and interrupts the only testable pulses in loopback are aclo-fnct2 and cycl (which is used for dma) */ arg[0] = IDR_ACF2 ; if(ioctl(f,IDRIO_IMM_PULSE,arg) == -1) { printf("test# 20.10: error pulsing acf2, errno = 0x%x\n",errno) ; exit(0) ; } /* should have caused an attention pulse - and set attention flag */ if(ioctl(f,IDRIO_GET_STATUS,arg) == -1) { printf("test# 20.20: error reading status, errno = 0x%x\n",errno) ; exit(0) ; } if(arg[0] != ( IDR_REDY | IDR_ATTF )) { printf("test# 20.30: incorrect status bits: status = 0x%x\n", arg[0]) ; exit(0) ; } /* test data out and in registers */ arg[0] = 0x5555 ; if(ioctl(f,IDRIO_DATA_OUT,arg) == -1) { printf("test# 30.10: error writing data out, errno = 0x%x\n",errno) ; exit(0) ; } if(ioctl(f,IDRIO_DATA_IN,arg) == -1) { printf("test# 30.20: error reading data in, errno = 0x%x\n",errno) ; exit(0) ; } if(arg[0] != 0x5555) { printf("test# 30.30: incorrect data in: data = 0x%x\n", arg[0]) ; exit(0) ; } arg[0] = 0xaaaa ; if(ioctl(f,IDRIO_DATA_OUT,arg) == -1) { printf("test# 30.40: error writing data out, errno = 0x%x\n",errno) ; exit(0) ; } if(ioctl(f,IDRIO_DATA_IN,arg) == -1) { printf("test# 30.50: error reading data in, errno = 0x%x\n",errno) ; exit(0) ; } if(arg[0] != 0xaaaa) { printf("test# 30.60: incorrect data in: data = 0x%x\n", arg[0]) ; exit(0) ; } /* test dma output we will write a counting pattern to the buffer, and output it after the block transfer, the last value sent should be readable in the input data register */ for(i=0;i<0x1000;i++) datarray[i] = i ; arg[0] = IDR_GO | IDR_CYCL ; if(ioctl(f,IDRIO_WRITE_PULSE,arg) == -1) { printf("test# 40.01: error setting write pulse, errno = 0x%x\n",errno) ; exit(0) ; } if(write(f,datarray,0x2000) == -1) { printf("test# 40.10: error doing dma write, errno = 0x%x\n",errno) ; exit(0) ; } if(ioctl(f,IDRIO_DATA_IN,arg) == -1) { printf("test# 40.20: error reading data in, errno = 0x%x\n",errno) ; exit(0) ; } if(arg[0] != 0xfff) { printf("test# 40.30: incorrect data in: data = 0x%x, should be 0xfff\n", arg[0]) ; exit(0) ; } /* test dma input we will write a fixed value to the data in register and then do a dma input the value written should be duplicated throughout the input buffer */ arg[0] = 0x1234 ; if(ioctl(f,IDRIO_DATA_OUT,arg) == -1) { printf("test# 50.10: error writing data out, errno = 0x%x\n",errno) ; exit(0) ; } arg[0] = IDR_GO | IDR_CYCL ; if(ioctl(f,IDRIO_READ_PULSE,arg) == -1) { printf("test# 50.11: error setting read pulse, errno = 0x%x\n",errno) ; exit(0) ; } if(read(f,datarray,0x2000) == -1) { printf("test# 50.10: error doing dma read, errno = 0x%x\n",errno) ; exit(0) ; } for(i=0;i<0x1000;i++) if(datarray[i] != 0x1234) { printf("test# 50.20: incorrect read buffer data: datarray[0x%x]=0x%x, should be 0x1234\n",i,datarray[i]) ; exit(0) ; } printf("*") ; } }