/* * This is a very simple loop-back test program for the IKON 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 * * 4 February, 2004 minor updates for readability * * 5 October, 2005 added includes to keep Linux happy, * converted ioctl arg to __u32 to preserve size in 64 bit mode */ #include #include #include #include #include #include "./idr_io.h" /* will pick up to get __u32 type */ u_short datarray[10000]; int ii, i, f; extern errno; char devname[16]; char devpath[32] = "/dev/\0"; __u32 arg; int pass_count = 0; int count_by_100 = 0; main() { printf("\nIKON 10116/10118 PCI bus DR11-W emulator loop-back test\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 10 seconds each and test */ arg = 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 = 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 = 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"); /* * pulse term to set ready again */ arg = IDR_TERM; 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 = 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 = 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 = 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 = 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 != (IDR_STTA | IDR_STTB | IDR_STTC | IDR_REDY | IDR_ATTN | IDR_ATTF)) { printf("test# 10.30: incorrect status bits: status = 0x%x\n", arg); exit(0); } /* * clear function bits */ arg = 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 != (IDR_REDY | IDR_ATTF)) { printf("test# 10.60: incorrect status bits: status = 0x%x\n", arg); 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 != IDR_REDY) { printf("test# 10.90: incorrect status bits: status = 0x%x\n", arg); 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 = 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 != (IDR_REDY | IDR_ATTF)) { printf("test# 20.30: incorrect status bits: status = 0x%x\n", arg); exit(0); } /* * test data out and in registers */ arg = 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 != 0x5555) { printf("test# 30.30: incorrect data in: data = 0x%x\n", arg); exit(0); } arg = 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 != 0xaaaa) { printf("test# 30.60: incorrect data in: data = 0x%x\n", arg); 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 = 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 != 0xfff) { printf("test# 40.30: incorrect data in: data = 0x%x, should be 0xfff\n", arg); 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 = 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 = 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); } }