#include #include #include #include "./idr_io.h" u_short inarray[0x2000], outarray[0x2000]; int i, j, filedes, pass_count; u_short pattern; extern errno; char devname[16]; char devpath[32] = "/dev/\0"; u_long arg; /* This is a very simple example of a DR11 interprocessor link using the IKON model 10103 Sbus or 10116 PCI bus dr11 emulator. It uses the standard interprocessor link protocol, although without some of the bells and whistles that a robust link would probably incporate. The strange block size of 0x2002 bytes matches the block size used at IKON for factory link testing of various DR11 emulators This is the master end of the link - it generates a pattern in a buffer, then sends an attention to the slave end of the link (as a request to send). It waits for an attention back (clear to send), then sends the data block. It then waits for an attention from the slave indicating that the slave wants to send the block back. The master then starts a block read (with an attention at the start of the read previously enabled) and waits for the data block. The master compares the two buffers, and halts if there is a data error. If not, the process continues indefinitely, with a changing data pattern. In order for handshaking to begin correctly, the slave end of the link must be started before the master end. */ main() { printf("\nMaster Link Test for IKON 10116/10118 PCI bus DR11-W emulators.\n\n"); printf("This program provides the master end of an interprocessor link test.\n"); printf("When used with the Slave Link Test program running in this or another host,\n"); printf("it allows two IKON DR11-W emulators to be tested in link mode.\n\n"); printf("Link mode requires that two DR11s be connected J1 to J2, and J2 to J1 using\n"); printf("appropriate link cable(s)\n\n"); printf("The master end of the link generates a changing data buffer, which is sent to\n"); printf("the slave end of the link, which returns it. The master compares the buffer\n"); printf("with the buffer received, and flags any errors. This test will thoroughly\n"); printf("exercise and test both boards, and the interconnecting cable, and runs\n"); printf("indefinitely, until terminated with control-C.\n\n"); printf("This version of Link Master operates the board in manual mode - it is intended\n"); printf("as an example of how to use the board and driver in manual mode (see source code)\n\n"); printf("THE SLAVE END OF THE LINK MUST BE STARTED FIRST!!\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 */ if((filedes = open(devpath,O_RDWR)) == -1) { printf("error on open, errno = %d\n", errno); exit(0); } printf("file descriptor = 0x%x\n",filedes); /* set to manual mode & set timeout values */ if(ioctl(filedes,IDRIO_MANUAL,&arg) == -1) { printf("error on MANUAL, errno = %d, pass count = %d\n", errno, pass_count); exit(0); } arg = 30; if(ioctl(filedes,IDRIO_SET_ATTN_TIME,&arg) == -1) { printf("error on SET_ATTN_TIME, errno = %d, pass count = %d\n", errno, pass_count); exit(0); } arg = 30; if(ioctl(filedes,IDRIO_SET_RDY_TIME,&arg) == -1) { printf("error on SET_RDY_TIME, errno = %d, pass count = %d\n", errno, pass_count); exit(0); } arg = 30; if(ioctl(filedes,IDRIO_SET_DMA_TIME,&arg) == -1){ printf("error on SET_DMA_TIME, errno = %d, pass count = %d\n", errno, pass_count); exit(0); } /* loop forever */ while(1) { /* we must reset the invisible UNIX counter to 0 every so often at least, we had to with SunOS */ lseek(filedes,(off_t)0,0); for(i=0;i<100;i++, pass_count++) { /* generate a pattern since the buffer size is not a power of two, the pattern in each buffer will be somewhat different */ for(j=0;j<0x1001;j++,pattern++) outarray[j] = pattern; /* issue a request to send */ arg = IDR_ACF2; if(ioctl(filedes,IDRIO_IMM_PULSE,&arg) == -1) { printf("error at IMM_PULSE, errno = %d, pass count = %d\n", errno, pass_count); exit(0); } /* wait for clear to send */ if(ioctl(filedes,IDRIO_ATTN_WAIT,&arg) == -1) { printf("error at ATTN_WAIT, errno = %d, pass_count = %d\n", errno, pass_count); exit(0); } /* do the write in manual mode using two write calls */ arg = 0x1000; if(ioctl(filedes,IDRIO_SET_RANGE,&arg) == -1) { printf("error on set range, errno = %d\n", errno); exit(0); } if(ioctl(filedes,IDRIO_START_WRITE,&arg) == -1) { printf("error on start write, errno = %d\n", errno); exit(0); } arg = IDR_GO | IDR_CYCL ; if(ioctl(filedes,IDRIO_IMM_PULSE,&arg) == -1) { printf("error on write pulse ioctl, errno = %d\n",errno) ; exit(0); } if(write(filedes,outarray,0x1000) == -1) { printf("error on write #1, errno = %d\n", errno); exit(0); } if(write(filedes,(u_short *)(outarray + 0x800),0x1002) == -1) { printf("error on write #2, errno = %d\n", errno); exit(0); } if(ioctl(filedes,IDRIO_RDY_WAIT,&arg) == -1) { printf("error on rdy wait, errno = %d\n", errno); exit(0); } if(ioctl(filedes,IDRIO_BLOCK_END,&arg) == -1) { printf("error on block end, errno = %d\n", errno); exit(0); } /* wait for the request to send from the other end */ if(ioctl(filedes,IDRIO_ATTN_WAIT,&arg) == -1) { printf("error ATTN_WAIT, errno = %d, pass count = %d\n", errno, pass_count); exit(0); } /* do the read in manual mode using two read calls issue acf2 (clear to send) to the other side of the link */ arg = 0x1000; if(ioctl(filedes,IDRIO_SET_RANGE,&arg) == -1) { printf("error on set range, errno = %d\n", errno); exit(0); } if(ioctl(filedes,IDRIO_START_READ,&arg) == -1) { printf("error on start read, errno = %d\n", errno); exit(0); } arg = IDR_GO | IDR_ACF2 ; if(ioctl(filedes,IDRIO_IMM_PULSE,&arg) == -1) { printf("error on write pulse ioctl, errno = %d\n",errno) ; exit(0); } if(read(filedes,inarray,0x1000) == -1) { printf("error on read #1, errno = %d\n", errno); exit(0); } if(read(filedes,(u_short *)(inarray + 0x800),0x1002) == -1) { printf("error on read #2, errno = %d\n", errno); exit(0); } if(ioctl(filedes,IDRIO_RDY_WAIT,&arg) == -1) { printf("error on rdy wait, errno = %d\n", errno); exit(0); } if(ioctl(filedes,IDRIO_BLOCK_END,&arg) == -1) { printf("error on block end, errno = %d\n", errno); exit(0); } /* compare the two buffers */ for(j=0;j<0x1001;j++) if(inarray[j] != outarray[j]) { printf("data mismatch! index = 0x%x, inarray[index] = 0x%x, outarray[index] = 0x%x\n", j, inarray[j], outarray[j]); exit(0); } } printf("master pass count = %d\n", pass_count); } }