/* $Id: chps_lib.c,v 2.4 91/09/03 17:35:01 annette Exp $ */
/****************************************************************/
/* chps_lib.c:  HPS-6816 Cluster Download I/O Library           */
/****************************************************************/
/*																*/
/*                 Confidential Information                     */
/*      Limited Distribution to Authorized Persons Only         */
/*     Created 1987 and Protected as an Unpublished Work        */
/*          Under the U.S. Copyright Act of 1976.               */
/*         Copyright (c) 1987,'88, Systech Corporation          */
/*                  All Rights Reserved                         */
/*																*/
/*	THIS SOFTWARE IS LICENSED BY AND IS THE	CONFIDENTIAL AND 	*/
/*	PROPRIETARY PROPERTY OF SYSTECH COMPUTER CORPORATION AND 	*/
/*	MAY NOT, WITHOUT THE PRIOR WRITTEN CONSENT OF SYSTECH 		*/
/*	COMPUTER CORPORATION, BE REPRODUCED, USED OR DISCLOSED 		*/
/*	EXCEPT IN ACCORDANCE WITH A SYSTECH COMPUTER CORPORATION 	*/
/*	SOFTWARE LICENSE AGREEMENT.									*/
/****************************************************************/
/*																*/
/*	These routines provide a convenient interface to the		*/
/*	raw HPS device driver in order to access the network		*/
/*	interface and cluster download tasks on the host adapter.	*/
/*																*/
/*****************************************************************/

/* This library defines eight entry points:
 *
 *	nif_open()
 *	nif_close()
 *	nif_read()
 *	cdl_stload()
 *	cdl_write()
 *	cdl_endld()
 *	cdl_abtld()
 *	nif_setid()
 *
 * These calls give a UNIX application program access to applicaitons
 * executing on-board the HPS controller.  The UNIX application must
 * open() the HPS raw device (/dev/rhps), and use the resulting file
 * descriptor in all calls to these library routines.
 */

#include <stdio.h>
#include "hps.types.h"
#include "hps.iocb.h"
#include "hps.ioctl.h"
#include "hps.onb.h"
#include "hps.net.h"
#include "hps.diag.h"
#include "hps.ccdl.h"
#include "hps.swap.h"

#ifdef HPS_STREAMS
#include <sys/types.h>
#include <sys/stream.h>
#include <sys/stropts.h>
#include "hps_svcintf.h"
#endif

/* #define DEBUG */

#ifdef BSD
#define S_DO_DL_IOCB (DO_IOCB | (0xC0000000|(sizeof(DL_IOCB)<<16)))
#define S_DO_NIF_IOCB (DO_IOCB | (0xC0000000|(sizeof(NIF_IOCB)<<16)))
#define DBUFSIZE 512
#endif

#ifdef HPS_STREAMS
#define DBUFSIZE 512
#endif

#ifndef NULL
#define NULL 0
#endif

extern char hps_intel;

nif_open(fd, min, userbox)
int fd, min;
bit32 *userbox;
{
	int result;
	NIF_IOCB	iocb;

#ifdef HPS_STREAMS
	struct strbuf	ctlbuf;
	struct strbuf	datbuf;
	long			ctlcmd;
	int				gflags;
#endif	

#	ifdef DEBUG
		fprintf(stderr, "nif_open: Enter\n");
#	endif
	iocb.hdr.len = sizeof(NIF_IOCB);
	iocb.hdr.maj_dev = NIF_DEV;
	iocb.hdr.min_dev = min;
	iocb.hdr.int_enab = ENABLED;
	iocb.hdr.data_len = 0; 
	iocb.hdr.data_dir = 0;
	iocb.hdr.data.hps_addr = 0;

	iocb.command = OPEN;
	iocb.connection = 0;

#ifdef HPS_STREAMS
	ctlbuf.maxlen = 0;
	ctlbuf.len    = sizeof(long);
	ctlbuf.buf    = (char *)&ctlcmd;
	ctlcmd        = HPS_DOIOCB;
	datbuf.maxlen = 0;
	datbuf.len    = sizeof(iocb);
	datbuf.buf    = (char *)&iocb;

	if (putmsg(fd,&ctlbuf,&datbuf,0) < 0)
	{
		printf("nif_open: putmsg failed\n");
		return(-1);
	}

	ctlbuf.len    = 0;
	ctlbuf.maxlen = sizeof(long);
	ctlbuf.buf    = (char *)&ctlcmd;
	datbuf.len    = 0;
	datbuf.maxlen = sizeof(iocb);
	datbuf.buf    = (char *)&iocb;
	gflags        = 0;
	ctlcmd        = 0;
	bzero((char *)&iocb,sizeof(iocb));

	if ((result = getmsg(fd,&ctlbuf,&datbuf,&gflags)) != 0)
#elif BSD
	if ((result = ioctl(fd, S_DO_NIF_IOCB, &iocb)) != 0)
#else
	if ((result = ioctl(fd, DO_IOCB, &iocb)) != 0)
#endif
	{
#		ifdef DEBUG
			fprintf(stderr, "nif_open: ioctl() == 0x%04x\n",
				result & 0xFFFF);
#		endif
		if (userbox)
			*userbox = iocb.hdr.mail.hps_addr;
		return(-1);
	}

#	ifdef DEBUG
		fprintf(stderr, "nif_open: Done, mail == 0x%08x\n", 
			iocb.hdr.mail.hps_addr);
#	endif

	if (userbox)
		*userbox = iocb.hdr.mail.hps_addr;

	return(iocb.hdr.mail.hps_addr);
}

nif_close(fd, cd, min, userbox)
int fd, cd, min;
bit32 *userbox;
{
	int result;
	NIF_IOCB	iocb;

#ifdef HPS_STREAMS
	struct strbuf	ctlbuf;
	struct strbuf	datbuf;
	long			ctlcmd;
	int				gflags;
#endif	

#	ifdef DEBUG
		fprintf(stderr, "nif_close: Enter\n");
#	endif
	iocb.hdr.len = sizeof(NIF_IOCB);
	iocb.hdr.maj_dev = NIF_DEV;
	iocb.hdr.min_dev = min;
	iocb.hdr.int_enab = ENABLED;
	iocb.hdr.data_len = 0; 
	iocb.hdr.data_dir = 0;
	iocb.hdr.data.hps_addr = 0;

	iocb.command = CLOSE;
	iocb.connection = cd;

#ifdef HPS_STREAMS
	ctlbuf.maxlen = 0;
	ctlbuf.len    = sizeof(long);
	ctlbuf.buf    = (char *)&ctlcmd;
	ctlcmd        = HPS_DOIOCB;
	datbuf.maxlen = 0;
	datbuf.len    = sizeof(iocb);
	datbuf.buf    = (char *)&iocb;

	if (putmsg(fd,&ctlbuf,&datbuf,0) < 0)
	{
		printf("nif_close: putmsg failed\n");
		return(-1);
	}

	ctlbuf.len    = 0;
	ctlbuf.maxlen = sizeof(long);
	ctlbuf.buf    = (char *)&ctlcmd;
	datbuf.len    = 0;
	datbuf.maxlen = sizeof(iocb);
	datbuf.buf    = (char *)&iocb;
	gflags        = 0;
	ctlcmd        = 0;
	bzero((char *)&iocb,sizeof(iocb));

	if ((result = getmsg(fd,&ctlbuf,&datbuf,&gflags)) != 0)
#elif BSD
	if ((result = ioctl(fd, S_DO_NIF_IOCB, &iocb)) != 0)
#else
	if ((result = ioctl(fd, DO_IOCB, &iocb)) != 0)
#endif
	{
#		ifdef DEBUG
			fprintf(stderr, "nif_close: ioctl() == 0x%04x\n",
				result & 0xFFFF);
#		endif
		return(-1);
	}

#	ifdef DEBUG
		fprintf(stderr, "nif_close: Done, mail == 0x%08x\n", 
			iocb.hdr.mail.hps_addr);
#	endif
	return(iocb.hdr.mail.hps_addr);
}

nif_read(fd, cd, buffer, nbytes, userbox)
int fd, cd, nbytes;
char *buffer;
bit32 *userbox;
{
	long result;

#if (BSD || HPS_STREAMS)
	int i;
	struct
	{
		NIF_IOCB	xiocb;
		char 	buffer[DBUFSIZE];
	} x;
#define iocb x.xiocb
#else
	NIF_IOCB	iocb;
#endif

#ifdef HPS_STREAMS
	struct strbuf	ctlbuf;
	struct strbuf	datbuf;
	long			ctlcmd;
	int				gflags;
#endif	

#ifdef BSD
	if (nbytes > DBUFSIZE)
	{
		fprintf(stderr, "nif_read: nbytes too big.  Requested %d, max %d\n", 
			nbytes, DBUFSIZE);
		return(-1);
	}
#endif

	iocb.hdr.len = sizeof(NIF_IOCB);
	iocb.hdr.maj_dev = NIF_DEV;
	iocb.hdr.min_dev = NET_AST;
	iocb.hdr.data_len = (bit16) nbytes;
#if (HPS_STREAMS || BSD)
	iocb.hdr.data.hps_addr = (bit32) x.buffer;
#else
	iocb.hdr.data.hps_addr = (bit32) buffer;
#endif
	iocb.hdr.data_dir = 0;
	iocb.hdr.int_enab = ENABLED;

	iocb.command = READ;
	iocb.connection = cd;

#ifdef HPS_STREAMS 
	ctlbuf.maxlen = 0;
	ctlbuf.len    = sizeof(long);
	ctlbuf.buf    = (char *)&ctlcmd;
	ctlcmd        = HPS_DOIOCB;
	datbuf.maxlen = 0;
	datbuf.len    = sizeof(x);
	datbuf.buf    = (char *)&x;

	if (putmsg(fd,&ctlbuf,&datbuf,0) < 0)
	{
		printf("nif_read: putmsg failed\n");
		return(-1);
	}

	ctlbuf.len    = 0;
	ctlbuf.maxlen = sizeof(long);
	ctlbuf.buf    = (char *)&ctlcmd;
	datbuf.len    = 0;
	datbuf.maxlen = sizeof(x);
	datbuf.buf    = (char *)&x;
	gflags        = 0;
	ctlcmd        = 0;
	bzero((char *)&x,sizeof(x));

	if ((result = getmsg(fd,&ctlbuf,&datbuf,&gflags)) != 0)
#elif BSD
	i = nbytes + sizeof(NIF_IOCB);
	if ((result = read(fd, &x, i)) < 0)
#else
	if ((result = ioctl(fd, DO_IOCB, &iocb)) != 0)
#endif
	{
#ifdef DEBUG
		printf("read/ioctl failed.  Result == 0x%08X\n", result);
		perror("nif_read");
#endif
		if (userbox)
			*userbox = iocb.hdr.mail.hps_addr;
		return(-1);
	}

#if (BSD || HPS_STREAMS)
	for (i = 0; i < nbytes; i++)
	  buffer[i] = x.buffer[i];
#endif

#	ifdef DEBUG
		fprintf(stderr, "nif_read: Done, mail == 0x%08x\n", 
			iocb.hdr.mail.hps_addr);
#	endif

	if (userbox)
		*userbox = iocb.hdr.mail.hps_addr;

	return(iocb.hdr.mail.hps_addr);

#undef iocb 
}

cdl_stload(fd, buffer, nbytes, addr, size, userbox)
int fd, nbytes;
char *buffer;
long addr;
long size;
bit32 *userbox;
{
	int result;
	bit16 tmp;
#if (BSD || HPS_STREAMS)
	int i;
	struct
	{
		DL_IOCB	xiocb;
		char 		buffer[DBUFSIZE];
	} x;
#define iocb x.xiocb
#else
	DL_IOCB	iocb;
#endif

#ifdef HPS_STREAMS
	struct strbuf	ctlbuf;
	struct strbuf	datbuf;
	long			ctlcmd;
	int				gflags;
#endif	

#ifdef BSD
	if (nbytes > DBUFSIZE)
	{
		fprintf(stderr, "cdl_stload: nbytes too big.  Requested %d, max %d\n", 
			nbytes, DBUFSIZE);
		return(-1);
	}
#endif

	iocb.hdr.len = sizeof(DL_IOCB);
	iocb.hdr.maj_dev = CLD_DEV;
	iocb.hdr.min_dev = 0;
	iocb.hdr.data_len = (bit16) nbytes;
	iocb.hdr.data.hps_addr = (bit32) buffer;
	iocb.hdr.data_dir = 1;
	iocb.hdr.int_enab = ENABLED;
	iocb.command = CD_STLOAD;

	if (hps_intel)
	{
		SWAP_4BYTE(&iocb.st_addr, &addr);
		tmp = (bit16)((size >> 10) + ((size & 0x3FF) ? 1 : 0));
		SWAP_2BYTE(&iocb.chksum, &tmp);
	}
	else
	{
		iocb.st_addr = (bit32)addr;
		iocb.chksum = (bit16)((size >> 10) + ((size & 0x3FF) ? 1 : 0));
	}


#ifdef HPS_STREAMS
	for (i=0; i < nbytes; i++)
		x.buffer[i] = buffer[i];

	ctlbuf.maxlen = 0;
	ctlbuf.len    = sizeof(long);
	ctlbuf.buf    = (char *)&ctlcmd;
	ctlcmd        = HPS_DOIOCB;
	datbuf.maxlen = 0;
	datbuf.len    = sizeof(x);
	datbuf.buf    = (char *)&x;

	if (putmsg(fd,&ctlbuf,&datbuf,0) < 0)
	{
		printf("cdl_stload: putmsg failed\n");
		return(-1);
	}

	ctlbuf.len    = 0;
	ctlbuf.maxlen = sizeof(long);
	ctlbuf.buf    = (char *)&ctlcmd;
	datbuf.len    = 0;
	datbuf.maxlen = sizeof(x);
	datbuf.buf    = (char *)&x;
	gflags        = 0;
	ctlcmd        = 0;
	bzero((char *)&x,sizeof(x));

	if ((result = getmsg(fd,&ctlbuf,&datbuf,&gflags)) != 0)
#elif BSD
	for (i=0; i < nbytes; i++)
		x.buffer[i] = buffer[i];
	i = nbytes + sizeof(DL_IOCB);
	if ((result = write(fd, &x, i)) != i)
#else
	if ((result = ioctl(fd, DO_IOCB, &iocb)) != 0)
#endif
	{
#ifdef DEBUG
		printf("write/ioctl failed.  Result == %d\n", result);
		perror("cdl_stload");
#endif
		if (userbox)
			*userbox = iocb.hdr.mail.hps_addr;
		return(-1);
	}

#	ifdef DEBUG
		fprintf(stderr, "cdl_stload: Done, mail == 0x%08x\n", 
			iocb.hdr.mail.hps_addr);
#	endif

	if (userbox)
		*userbox = iocb.hdr.mail.hps_addr;

	return(iocb.hdr.mail.hps_addr);

#undef iocb 
}


cdl_endld(fd, buffer, nbytes, loadid, staddr, userbox)
int fd, nbytes, staddr;
char loadid;
char *buffer;
bit32 *userbox;
{
#if (BSD || HPS_STREAMS)
	int i;
	struct
	{
		DL_IOCB	xiocb;
		char 	buffer[DBUFSIZE];
	} x;
#define iocb x.xiocb
#else
	DL_IOCB	iocb;
#endif

#ifdef HPS_STREAMS
	struct strbuf	ctlbuf;
	struct strbuf	datbuf;
	long			ctlcmd;
	int				gflags;
#endif	

#ifdef BSD
	if (nbytes > DBUFSIZE)
	{
		fprintf(stderr, "cdl_endld: nbytes too big.  Requested %d, max %d\n", 
			nbytes, DBUFSIZE);
		return(-1);
	}
#endif

	iocb.hdr.len = sizeof(DL_IOCB);
	iocb.hdr.maj_dev = CLD_DEV;
	iocb.hdr.min_dev = 0;
	iocb.hdr.data_len = (bit16) nbytes;
	iocb.hdr.data.hps_addr = (bit32) buffer;
	iocb.hdr.data_dir = 0;
	iocb.hdr.int_enab = ENABLED;

	iocb.command = CD_ENDLD;
	iocb.load_id = loadid;
	if (hps_intel)
	{
		SWAP_4BYTE(&iocb.st_addr, &staddr);
	}
	else
	{
		iocb.st_addr = staddr;
	}

#ifdef HPS_STREAMS
	ctlbuf.maxlen = 0;
	ctlbuf.len    = sizeof(long);
	ctlbuf.buf    = (char *)&ctlcmd;
	ctlcmd        = HPS_DOIOCB;
	datbuf.maxlen = 0;
	datbuf.len    = sizeof(x);
	datbuf.buf    = (char *)&x;

	if (putmsg(fd,&ctlbuf,&datbuf,0) < 0)
	{
		printf("cdl_stload: putmsg failed\n");
		return(-1);
	}

	ctlbuf.len    = 0;
	ctlbuf.maxlen = sizeof(long);
	ctlbuf.buf    = (char *)&ctlcmd;
	datbuf.len    = 0;
	datbuf.maxlen = sizeof(x);
	datbuf.buf    = (char *)&x;
	gflags        = 0;
	ctlcmd        = 0;
	bzero((char *)&x,sizeof(x));

	if (getmsg(fd,&ctlbuf,&datbuf,&gflags) != 0)
#elif BSD
	i = nbytes + sizeof(DL_IOCB);
#ifdef DEBUG
	printf("chps_lib: reading from HPS\n");
#endif
	if (read(fd, &x, i) != i)
#else
	if (ioctl(fd, DO_IOCB, &iocb) != 0)
#endif
	{
		if (userbox)
			*userbox = iocb.hdr.mail.hps_addr;
		return(-1);
	}

#if (BSD || HPS_STREAMS)
	for (i = 0; i < nbytes; i++)
	  buffer[i] = x.buffer[i];
#endif

#	ifdef DEBUG
		fprintf(stderr, "cdl_endld: Done, mail == 0x%08x\n", 
			iocb.hdr.mail.hps_addr);
#	endif

	if (userbox)
		*userbox = iocb.hdr.mail.hps_addr;

	return(iocb.hdr.mail.hps_addr);
#undef iocb 
}

cdl_write(fd, buffer, nbytes, loadid, staddr, chksum, userbox)
int fd, nbytes, staddr;
char loadid;
short chksum;
char *buffer;
bit32 *userbox;
{
#if (BSD || HPS_STREAMS)
	int i;
	int result;
	struct
	{
		DL_IOCB	xiocb;
		char 		buffer[DBUFSIZE];
	} x;
#define iocb x.xiocb
#else
	DL_IOCB	iocb;
#endif

#ifdef HPS_STREAMS
	struct strbuf	ctlbuf;
	struct strbuf	datbuf;
	long			ctlcmd;
	int				gflags;
#endif	

#ifdef BSD
	if (nbytes > DBUFSIZE)
	{
		fprintf(stderr, "cdl_write: nbytes too big.  Requested %d, max %d\n", 
			nbytes, DBUFSIZE);
		return(-1);
	}
#endif

	iocb.hdr.len = sizeof(DL_IOCB);
	iocb.hdr.maj_dev = CLD_DEV;
	iocb.hdr.min_dev = 0;
	iocb.hdr.data_len = (bit16) nbytes;
	iocb.hdr.data.hps_addr = (bit32) buffer;
	iocb.hdr.data_dir = 1;
	iocb.hdr.int_enab = ENABLED;

	iocb.command = CD_WRITE;
	iocb.load_id = loadid;
	if (hps_intel)
	{
		SWAP_4BYTE(&iocb.st_addr, &staddr);
		SWAP_2BYTE(&iocb.chksum, &chksum);
	}
	else
	{
		iocb.st_addr = staddr;
		iocb.chksum = chksum;
	}

#ifdef HPS_STREAMS
	for (i=0; i < nbytes; i++)
		x.buffer[i] = buffer[i];

	ctlbuf.maxlen = 0;
	ctlbuf.len    = sizeof(long);
	ctlbuf.buf    = (char *)&ctlcmd;
	ctlcmd        = HPS_DOIOCB;
	datbuf.maxlen = 0;
	datbuf.len    = sizeof(x);
	datbuf.buf    = (char *)&x;

	if (putmsg(fd,&ctlbuf,&datbuf,0) < 0)
	{
		printf("cdl_write: putmsg failed\n");
		return(-1);
	}

	ctlbuf.len    = 0;
	ctlbuf.maxlen = sizeof(long);
	ctlbuf.buf    = (char *)&ctlcmd;
	datbuf.len    = 0;
	datbuf.maxlen = sizeof(x);
	datbuf.buf    = (char *)&x;
	gflags        = 0;
	ctlcmd        = 0;
	bzero((char *)&x,sizeof(x));

	if ((result = getmsg(fd,&ctlbuf,&datbuf,&gflags)) != 0)
#elif BSD
	for (i=0; i < nbytes; i++)
		x.buffer[i] = buffer[i];
	i = nbytes + sizeof(DL_IOCB);
	if ((result = write(fd, &x, i)) != i)
#else
	if (ioctl(fd, DO_IOCB, &iocb) != 0)
#endif
	{
		if (userbox)
			*userbox = iocb.hdr.mail.hps_addr;
		return(-1);
	}

#	ifdef DEBUG
		fprintf(stderr, "cdl_write: Done, mail == 0x%08x\n", 
			iocb.hdr.mail.hps_addr);
#	endif

	if (userbox)
		*userbox = iocb.hdr.mail.hps_addr;

	return(iocb.hdr.mail.hps_addr);

#undef iocb 
}

cdl_abtld(fd, loadid, userbox)
int fd;
char loadid;
bit32 *userbox;
{
	int result;
	DL_IOCB	iocb;

#ifdef HPS_STREAMS
	struct strbuf	ctlbuf;
	struct strbuf	datbuf;
	long			ctlcmd;
	int				gflags;
#endif

	iocb.hdr.len = sizeof(DL_IOCB);
	iocb.hdr.maj_dev = CLD_DEV;
	iocb.hdr.min_dev = 0;
	iocb.hdr.int_enab = ENABLED;

	iocb.command = CD_ABTLD;
	iocb.load_id = loadid;

#ifdef HPS_STREAMS
	ctlbuf.maxlen = 0;
	ctlbuf.len    = sizeof(long);
	ctlbuf.buf    = (char *)&ctlcmd;
	ctlcmd        = HPS_DOIOCB;
	datbuf.maxlen = 0;
	datbuf.len    = sizeof(iocb);
	datbuf.buf    = (char *)&iocb;

	if (putmsg(fd,&ctlbuf,&datbuf,0) < 0)
	{
		printf("nif_open: putmsg failed\n");
		return(-1);
	}

	ctlbuf.len    = 0;
	ctlbuf.maxlen = sizeof(long);
	ctlbuf.buf    = (char *)&ctlcmd;
	datbuf.len    = 0;
	datbuf.maxlen = sizeof(iocb);
	datbuf.buf    = (char *)&iocb;
	gflags        = 0;
	ctlcmd        = 0;
	bzero((char *)&iocb,sizeof(iocb));

	if ((result = getmsg(fd,&ctlbuf,&datbuf,&gflags)) != 0)
#elif BSD
	if ((ioctl(fd, S_DO_DL_IOCB, &iocb)) != 0)
#else
	if ((ioctl(fd, DO_IOCB, &iocb)) != 0)
#endif
	{
		if (userbox)
			*userbox = iocb.hdr.mail.hps_addr;
		return(-1);
	}

#	ifdef DEBUG
		fprintf(stderr, "hps_ioctl: Done, mail == 0x%08x\n", 
			iocb.hdr.mail.hps_addr);
#	endif
	if (userbox)
		*userbox = iocb.hdr.mail.hps_addr;

	return(iocb.hdr.mail.hps_addr);
}

nif_setid(fd, hostid, userbox)
int fd;
char hostid;
bit32 *userbox;
{
	int result;
	NIF_IOCB	iocb;
#ifdef HPS_STREAMS
	struct strbuf	ctlbuf;
	struct strbuf	datbuf;
	long			ctlcmd;
	int				gflags;
#endif

#	ifdef DEBUG
		fprintf(stderr, "nif_setid: Enter\n");
#	endif
	iocb.hdr.len = sizeof(NIF_IOCB);
	iocb.hdr.maj_dev = NIF_DEV;
	iocb.hdr.min_dev = NET_SETID;
	iocb.hdr.int_enab = ENABLED;
	iocb.hdr.data_len = 0; 
	iocb.hdr.data_dir = 0;
	iocb.hdr.data.hps_addr = 0;

	iocb.command = OPEN;
	iocb.connection = hostid;

#ifdef HPS_STREAMS 
	ctlbuf.maxlen = 0;
	ctlbuf.len    = sizeof(long);
	ctlbuf.buf    = (char *)&ctlcmd;
	ctlcmd        = HPS_DOIOCB;
	datbuf.maxlen = 0;
	datbuf.len    = sizeof(iocb);
	datbuf.buf    = (char *)&iocb;

	if (putmsg(fd,&ctlbuf,&datbuf,0) < 0)
	{
		printf("nif_open: putmsg failed\n");
		return(-1);
	}

	ctlbuf.len    = 0;
	ctlbuf.maxlen = sizeof(long);
	ctlbuf.buf    = (char *)&ctlcmd;
	datbuf.len    = 0;
	datbuf.maxlen = sizeof(iocb);
	datbuf.buf    = (char *)&iocb;
	gflags        = 0;
	ctlcmd        = 0;
	bzero((char *)&iocb,sizeof(iocb));

	if ((result = getmsg(fd,&ctlbuf,&datbuf,&gflags)) != 0)
#elif BSD
	if ((result = ioctl(fd, S_DO_NIF_IOCB, &iocb)) != 0)
#else
	if ((result = ioctl(fd, DO_IOCB, &iocb)) != 0)
#endif
	{
#		ifdef DEBUG
			fprintf(stderr, "nif_setid: ioctl() == 0x%04x\n",
				result & 0xFFFF);
#		endif
		if (userbox)
			*userbox = iocb.hdr.mail.hps_addr;
		return(-1);
	}

#	ifdef DEBUG
		fprintf(stderr, "nif_setid: Done, mail == 0x%08x\n", 
			iocb.hdr.mail.hps_addr);
#	endif
	if (userbox)
		*userbox = iocb.hdr.mail.hps_addr;

	return(iocb.hdr.mail.hps_addr);
}

/*
 * MODIFICATION HISTORY:
 *
 * $Log:	chps_lib.c,v $
 * Revision 1.1.2.1  92/06/24  13:53:13  marker
 * Branch RISCOS_5_01_2_FIXES off of trunk.
 * 
 * Revision 2.4  91/09/03  17:35:01  annette
 * Changed error message handling.
 * INTERNAL
 * 
 * Revision 2.3  91/01/10  17:21:29  dave
 * Modify header; add footer.
 * COSMETIC
 * 
 */
