/* * idr.loop.test.c * * Test Tahoma Tech 10116/10118 PCI DR11-W in loopback mode * * Tahoma Technology * (formerly Ikon Corporation) * 107 2nd Avenue North * Seattle, WA, USA 98109 * * 206.728.6465 * http://www.tahomatech.com * tahoma@tahomatech.com * * 9 July, 1998 * 4 May, 2004 Change IKON to Tahoma * This is a very simple loop-back test program for the Tahoma Technology * 10116 or 10118 PCI bus 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. After each 10 successful passes, * it outputs a pass count . In the event of a failure, it prints a brief * message describing the test that failed, and halts. * * THIS VERSION FOR LATER 10116 & 10118 BOARDS THAT CAN "UN-SWAP" THE BYTE LANE SWAPPING * THAT OCCURS BETWEEN THE SPARC PROCESSOR AND THE PCI BUS * This version modified to compile correctly in 32 and 64 bit modes. The arg array used with * the ioctl call must be an array of 32 bit values (u_long compiles to 64 bits in 64 bit mode) */ #include #include #include #include "./idr_io.h" uint16_t datarray[10000] ; int ii, i, f ; extern errno ; char devname[16]; char devpath[32] = "/dev/\0"; uint32_t arg[16] ; int pass_count = 0; int count_by_100 = 0; main() { printf("\nTahoma Tech (formerly IKON) 10116/10118 PCI bus DR11-W emulator loop-back test\n") ; printf("4 May, 2004\n\n"); printf("THIS VERSION FOR LATER 10116 AND ALL 10118 BOARDS THAT CAN UN-SWAP DMA BYTES IN SPARC INSTALLATIONS\n\n"); printf("A 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 every 100 successfull passes, the pass count 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\n") ; printf("Please enter the name of the device to be tested: (idr0...idr9, quit) "); scanf("%15s", devname); if(strcmp(devname, "quit\0") == 0) exit(0); strcat(devpath, devname); printf("\ntesting device %s\n", devpath); /* open the device */ f = open(devpath,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) { for(count_by_100 = 0; count_by_100 < 100; count_by_100++,pass_count++) { /* "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("pass count = %d\n", pass_count); } }