/* $Id: logsub.c,v 2.5 91/09/24 13:53:14 don Exp $ */
/****************************************************************/
/* logsub.c:  HPS Statistics Log Reporter			   			*/
/****************************************************************/
/*																*/
/*                 Confidential Information                     */
/*      Limited Distribution to Authorized Persons Only         */
/*     Created 1986 and Protected as an Unpublished Work        */
/*          Under the U.S. Copyright Act of 1976.               */
/*         Copyright (c) 1986, 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 log table from the specified    	*/
/*        host adapter, and clears it if requested to do so    	*/
/*                                                             	*/
/****************************************************************/

/* #define DEBUG */

#include <stdio.h>
#include "hps.types.h"
#include "hps.iocb.h"
#include "hps.ioctl.h"
#include "hps.conf.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

extern char hps_intel;
extern int errno;


bit32 logsub(table, clear, rawdev, pname)
long *table;
int clear;
char *rawdev;
char *pname;
{
	char *devname;
	int result, i, hpsfd;
	long *ptr;

	/* Raw driver IOCB and table area */
	struct
	{
		LOADER_IOCB 	raw_iocb;
		long 		l_table[50];
	} iocb_buf;

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

	if (rawdev != NULL)
		devname = rawdev;
	else
		devname = RAW_DEVNAME;

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

	/* Get the log table */
	iocb_buf.raw_iocb.header.len = sizeof(LOADER_IOCB);
	iocb_buf.raw_iocb.header.maj_dev = 1;  
	iocb_buf.raw_iocb.header.min_dev = 0;
	iocb_buf.raw_iocb.header.int_enab = 1;
	iocb_buf.raw_iocb.header.data.hps_addr = (bit32)iocb_buf.l_table;
	iocb_buf.raw_iocb.header.data_len = sizeof(iocb_buf.l_table);
	iocb_buf.raw_iocb.header.data_dir = FROM_HPS;

	if (hps_intel)
	{
		iocb_buf.raw_iocb.command = (IOCTL<<8)|(IOCTL>>8); 
		iocb_buf.raw_iocb.cmd_modifier = (clear) ? (LOGCLR<<8)|(LOGCLR>>8)
												 : (LOG<<8)|(LOG>>8);
		iocb_buf.raw_iocb.mode = 0x0100;
	}
	else
	{
		iocb_buf.raw_iocb.command = IOCTL; 
		iocb_buf.raw_iocb.cmd_modifier = (clear) ? LOGCLR : LOG;
		iocb_buf.raw_iocb.mode = 1;
	}
	iocb_buf.raw_iocb.hpsadr.hps_addr = 0;
	iocb_buf.raw_iocb.priority = 0;
	iocb_buf.raw_iocb.tid = 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_buf);
	datbuf.buf    = (char *)&iocb_buf;

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

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

	if ((result = getmsg(hpsfd,&ctlbuf,&datbuf,&gflags)) != 0)
		printf("logsub(): getmsg failed \n");

#elif BSD
		result = read(hpsfd, &iocb_buf, sizeof( iocb_buf ) );
#	else
		result = ioctl(hpsfd, DO_IOCB, &iocb_buf);
#	endif

	close(hpsfd);

	if (result < 0)
		return(result);
	else
	{
		ptr = iocb_buf.l_table;
		for (i = sizeof(iocb_buf.l_table)/sizeof(long); i--;)
		{
#			ifdef DEBUG
				printf("%02d: %08x <-- %04x\n", i, table, *ptr);
#			endif
			*table++ = *ptr++;
		}
		if (iocb_buf.raw_iocb.header.mail.hps_addr != 0)
			return(iocb_buf.raw_iocb.header.mail.hps_addr);
		else
			return(0);
	}
}

/*
 * MODIFICATION HISTORY:
 *
 * $Log:	logsub.c,v $
 * Revision 1.1.2.1  92/06/24  13:53:47  marker
 * Branch RISCOS_5_01_2_FIXES off of trunk.
 * 
 * Revision 2.5  91/09/24  13:53:14  don
 * Added line to explicitly set the data_dir to FROM_HPS.
 * INTERNAL
 * 
 * Revision 2.4  91/09/03  17:41:02  annette
 * Changed error message handling.
 * INTERNAL
 * 
 * Revision 2.3  91/01/10  17:24:10  dave
 * Modify header; add footer.
 * COSMETIC
 * 
 */
