/* * link.slave.c * * Test link data transfers to/from another DR11 (slave end of link) * * 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 * * modified to compile correctly in 64 bit mode * arg.ulg must be an array of 32 bit values! */ #include #include #include #include "./idr_io.h" char datarray[16000]; int ii, i, filedes, pass_count; extern errno; char devname[16]; char devpath[32] = "/dev/\0"; static union { char ch[256]; uint32_t ulg[64]; } arg; /* This is a very simple example of a DR11 interprocessor link using the Tahoma Technology (formerly IKON) model 10103 Sbus or 10116/10118 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 Tahoma Tech for factory link testing of various DR11 emulators This is the slave end of the link - it waits for an attention from the other end of the link, then sets up to receive a block of data. Once the data has been received, it sends an attention to the other dr11, waits for an attention back, then sends back the block of data. In order for handshaking to begin correctly, the slave end of the link must be started before the master end. */ main() { printf("\nSlave Link Test for Tahoma Tech (formerly IKON) 10116/10118 PCI bus DR11-W emulators.\n"); printf("4 May, 2004\n"); printf("This program provides the slave end of an interprocessor link test.\n"); printf("When used with the Master Link Test program running in this or another host,\n"); printf("it allows two Tahoma Tech 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("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); /* pre-configure the read and write logic to send an attention (clear to send) to the other end when DVMA reads are enabled, and to force a local cycle when writes are started */ arg.ulg[0] = IDR_ACF2; if(ioctl(filedes,IDRIO_READ_PULSE,arg.ulg) == -1) { printf("error on READ_PULSE, errno = %d, pass count = %d\n", errno, pass_count); exit(0); } arg.ulg[0] = IDR_CYCL; if(ioctl(filedes,IDRIO_WRITE_PULSE,arg.ulg) == -1) { printf("error on WRITE_PULSE, errno = %d, pass count = %d\n", errno, pass_count); exit(0); } arg.ulg[0] = IDR_FCN3 | IDR_FCN1; if(ioctl(filedes,IDRIO_READ_FCN,arg.ulg) == -1) { printf("error on READ_FCN, errno = %d, pass count = %d\n", errno, pass_count); exit(0); } arg.ulg[0] = 0; if(ioctl(filedes,IDRIO_WRITE_FCN,arg.ulg) == -1) { printf("error on WRITE_FCN, errno = %d, pass count = %d\n", errno, pass_count); exit(0); } arg.ulg[0] = 30; if(ioctl(filedes,IDRIO_SET_ATTN_TIME,arg.ulg) == -1) { printf("error on SET_ATTN_TIME, errno = %d, pass count = %d\n", errno, pass_count); exit(0); } arg.ulg[0] = 30; if(ioctl(filedes,IDRIO_SET_DMA_TIME,arg.ulg) == -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++) { /* wait for the request to send from the other end */ if(ioctl(filedes,IDRIO_ATTN_WAIT,arg.ulg) == -1) { printf("error ATTN_WAIT, errno = %d, pass count = %d\n", errno, pass_count); exit(0); } /* issue the read (and clear to send) */ if(read(filedes,datarray,0x2002) == -1) { printf("error on read, errno = %d, pass count = %d\n", errno, pass_count); exit(0); } /* issue a request to send */ arg.ulg[0] = IDR_ACF2; if(ioctl(filedes,IDRIO_IMM_PULSE,arg.ulg) == -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.ulg) == -1) { printf("error at ATTN_WAIT, errno = %d, pass_count = %d\n", errno, pass_count); exit(0); } /* do the write */ if(write(filedes,datarray,0x2002) == -1) { printf("error on write, errno = %d, pass_count = %d\n",errno, pass_count); exit(0); } } printf("slave pass count = %d\n", pass_count); } }