/* $Id: xlogsub.c,v 2.3 91/09/03 17:43:02 annette Exp $ */
/****************************************************************/
/* xlogsub.c:  HPS Statistics Log Reporter			   			*/
/****************************************************************/
/*																*/
/*                 Confidential Information                     */
/*      Limited Distribution to Authorized Persons Only         */
/*     Created 1988 and Protected as an Unpublished Work        */
/*          Under the U.S. Copyright Act of 1976.               */
/*         Copyright (c) 1988, 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.									*/
/****************************************************************/
/*																*/
/*	This routine requests the number of data bytes written and	*/
/*		read (for both multi-channel and single-channel) from	*/
/*		the specified host adapter, and clears it if requested	*/
/*		to do so.												*/
/*																*/
/****************************************************************/

#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.asynch.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 SUCCESS	0				/* sucess for ioctl() */

extern char hps_intel;

/*
 * xlogsub():
 *		returns  0 for success
 *				-1 if unable to open device raw_device
 *				-2 if unable to get xbyte information
 */
int xlogsub(xbytes, clear, raw_device, pname)
A_XBYTES *xbytes;		/* xbyte information */
int  clear;				/* clear xbyte info in TCS ? */
char *raw_device;		/* raw device name */
char *pname;			/* calling program name */
{
	int hpsfd;  			/* file descriptor for the rew device */
	int res;
	A_IOCB iocb;   			/* the IOCB */
	bit32 ltmp;

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

#if (BSD || HPS_STREAMS)
	int i;
	struct
	{
		A_IOCB	xiocb;
		A_XBYTES	xbytes;
	} x;
#define iocb x.xiocb
#endif

	/* Open HPS interface (raw device) */
	if (raw_device == NULL)
		raw_device = RAW_DEVNAME;
	if ((hpsfd = open(raw_device, 2)) < 0)
	{
		fprintf(stderr, "%s: Cannot open device %s\n", pname, raw_device);
		return (-1);
	}

	/* Format the iocb */
	iocb.hdr.len = sizeof(A_IOCB);
	iocb.hdr.maj_dev = ASYNCH_DEV;			/* TCS */
	iocb.hdr.min_dev = 0;					/* must always be 0 */
	iocb.hdr.int_enab = ENABLED;
	iocb.hdr.return_msg.hps_addr = (bit32)&iocb;
	iocb.hdr.data_len = sizeof(A_XBYTES);
#if (HPS_STREAMS || BSD)
	iocb.hdr.data.hps_addr = (bit32)&(x.xbytes);
#else
	iocb.hdr.data.hps_addr = (bit32)xbytes;
#endif
	iocb.hdr.data_dir = FROM_HPS;  			/* data comes FROM the HPS */
/* 	iocb.hdr.mode = not used; */
	iocb.hdr.mail.hps_addr = 0xFFFFFFFF; 
/* 	iocb.hdr.next = not used; */
/* 	iocb.hdr.finished = not used; */
	if (hps_intel)
	{
		iocb.command = (IOCTL<<8)|(IOCTL>>8);
		iocb.cmd_modifier = (AIOC_GETB<<8)|(AIOC_GETB>>8);
		ltmp = clear ? GETB_CLEAR : GETB_NCLEAR;
		SWAP_4BYTE(&iocb.cmd_param, &ltmp);
	}
	else
	{
		iocb.command = IOCTL;
		iocb.cmd_modifier = AIOC_GETB;
		if (clear)
			iocb.cmd_param = GETB_CLEAR;		/* clear info */
		else
			iocb.cmd_param = GETB_NCLEAR;		/* do not clear info */
	}
	iocb.link = NULL;

	/* send iocb on its way to the hps */
#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 *)&iocb;

	if (putmsg(hpsfd,&ctlbuf,&datbuf,0) < 0)
	{
		printf("Error: 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 *)&iocb;
	gflags        = 0;
	ctlcmd        = 0;
	bzero((char *)&iocb,sizeof(x));

	if ((res = getmsg(hpsfd,&ctlbuf,&datbuf,&gflags)) != 0)
		printf("Error: getmsg failed \n");
#elif BSD
	res = read(hpsfd, &iocb, sizeof(iocb));
#else
	res = ioctl(hpsfd, DO_IOCB, &iocb);
#endif
	if ((res != SUCCESS) || ((iocb.hdr.mail.hps_addr>>16) != 0))
	{
#ifdef DEBUG
		fprintf(stderr, "xlogsub() error: ioctl result=%d  iocb mail=%d\n", 
				res, iocb.hdr.mail.hps_addr>>16);
#endif	/* DEBUG */
		close(hpsfd);	/* close raw device */
		return (-2);	/* ioctl xbytes request failed */
	}
#ifdef DEBUG
	else
	{
		printf("TCS bytes transferred are:\n");
		printf("\tSingle channel read: %d\n",  xbytes->sc_read);
		printf("\tMulti channel read: %d\n",   xbytes->mc_read);
		printf("\tSingle channel write: %d\n", xbytes->sc_write);
		printf("\tMulti channel write: %d\n",  xbytes->mc_write);
	}
#endif	/* DEBUG */
#if (HPS_STREAMS || BSD)
	xbytes->sc_read = x.xbytes.sc_read;
	xbytes->mc_read = x.xbytes.mc_read;
	xbytes->sc_write = x.xbytes.sc_write;
	xbytes->mc_write = x.xbytes.mc_write;
#endif

	close(hpsfd);  	/* close raw device */
	return (0);		/* ioctl xbytes request succeeded */
#undef iocb
}

/*
 * MODIFICATION HISTORY:
 *
 * $Log:	xlogsub.c,v $
 * Revision 1.1.2.1  92/06/24  13:54:05  marker
 * Branch RISCOS_5_01_2_FIXES off of trunk.
 * 
 * Revision 2.3  91/09/03  17:43:02  annette
 * Changed error message handling.
 * INTERNAL
 * 
 * Revision 2.2  91/01/10  17:24:56  dave
 * Modify header; add footer.
 * COSMETIC
 * 
 */
