/* $Id: vmeio-xl-test.c,v 1.2 90/12/28 17:32:26 sharakan Exp $ */
/*****************************************************************************
* 	  (c) Copyright  1990 Thinking Machines Corporation, Inc.,	     *
*		of Cambridge, Mass.   All rights reserved.		     *
*									     *
*  This notice is intended as a precaution against inadvertent publication   *
*  and does not constitute an admission or acknowledgement that publication  *
*  has occurred or constitute a waiver of confidentiality.		     *
*									     *
*  Connection Machine software is the proprietary and confidential property  *
*  of Thinking Machines Corporation.					     *
*****************************************************************************/

#include <sys/types.h>
#include <sys/ioctl.h>
#include <tmc/vmeio-ioctl.h>

#include <stdio.h>

#define MYNAME av[0]

extern int errno;

main(ac, av)
char **av;
{
    int cc, fd, bs;
    char *buf1, *buf2;
    register int count = 1;
    register int iteration;
    register int docompare = 1;
    int cpid;
    struct vmeio_target_set ts;
    struct vmeio_config vcf;

    if (ac < 2) {
	printf("usage: %s blocksize [count] [nocompare]\n", av[0]);
	exit(1);
    }

    bs = atoi(av[1]);
    if (bs < 256 || bs > 8192) {
	printf("invalid blocksize %d\n", bs);
	exit(1);
    }

    if (ac > 2)
	count = atoi(av[2]);

    if (ac > 3)
	docompare = 0;
	
	
    if (cpid=fork()) {
	/* parent */
	while(wait(0) != cpid)
	    ;
	exit(0);
    }

    /* child */

    if ((fd = open("/dev/cmio0", 2)) < 0) {
	perror("open /dev/cmio0");
	exit(1);
    }


    if ((buf1 = (char *)valloc(bs)) == 0) {
	perror("valloc");
	exit(1);
    }

    if ((buf2 = (char *)valloc(bs)) == 0) {
	perror("valloc");
	exit(1);
    }

    { register long *n;
    for(n = (long *)buf1; n < (long *)&buf1[bs]; n++)
	*n = /*random()*/ 0xa5a5a5a5;
    }

    /* set up for external loopback */

    if (ioctl(fd, VMEIO_GET_CONFIGURATION, &vcf) < 0) {
	perror("vmeio_get_configuration");
	exit(1);
    }

    ts.ts_ntargets = 1;
    ts.ts_target_id[0] = vcf.cf_sta_id;

    if (ioctl(fd, VMEIO_SET_TARGETS, &ts) < 0) {
	perror("vmeio_set_targets");
	exit(1);
    }
    if (ioctl(fd, VMEIO_SET_SOURCES, &ts) < 0) {
	perror("vmeio_set_sources");
	exit(1);
    }
    if (ioctl(fd, VMEIO_RECEIVE_ENABLE, 0) < 0) {
	perror("vmeio_receive_enable");
	exit(1);
    }


    iteration = 0;
    while(count < 0 || count-- > 0) {
	iteration++;
	if ((iteration % 100) == 0) {
	    printf("    %d\r", iteration);
	    fflush(stdout);
	}
	if ((cc = write(fd, buf1, bs)) < 0) {
	    printf("write buf1=0x%x bs=%d failed iteration %d (errno %d)\n", 
		   buf1, bs, iteration, errno & 0xff);
	    perror("write");
	    exit(1);
	}


	if ((cc = read(fd, buf2, bs)) < 0) {
	    printf("read buf2=0x%x bs=%d failed iteration %d (errno %d)\n", 
		   buf2, bs, iteration, errno & 0xff);
	    perror("read");
	    exit(1);
	}

	if (docompare) {
	    register long *n, *m;
	    for(n = (long *)buf1, m = (long *)buf2; 
		n < (long *)&buf1[bs]; n++, m++)
		if (*n != *m)
		    printf("data compare error, iteration %d, offset 0x%x, \nwrote 0x%x got 0x%x, diff 0x%x\n",
			   iteration,
			   (int)n - (int)buf1,
			   *n, *m, *m^*n);
	}
	
    }

}
	
