/* $Id: hps_netc.c,v 2.7 91/09/06 10:27:00 annette Exp $ */
/****************************************************************/
/* hps_netc.c:  Display Current Network Configuration			*/
/****************************************************************/
/*																*/
/*                 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.									*/
/****************************************************************/
/*																*/
/*   This program requests the current network configuration	*/
/*   from the on-board network interface task and displays it	*/
/*   on the screen.												*/
/*   The raw device name is the only input parameter.			*/
/*																*/
/****************************************************************/

/* #define DEBUG */

#include <stdio.h>
#include <a.out.h>
#include "hps.types.h"
#include "hps.iocb.h"
#include "hps.ioctl.h"
#include "hps.conf.h"
#include "hps.onb.h"
#include "hps.net.h"
#include "hps.ccdl.h"
#include "hps.dev_type.h"

char  hps_intel		= 0;				/* host byte ordering	*/

int hpsfd;

AST astbuf[64];

char *sstate[] = {
	"Offline            ",
	"Primitive Idle     ",
	"Primitive Connected",
	"Normal Online      ",
	"Disconnect         ",
	"Host               ",
	"Primitive Idle w/FP"
	};

struct dtcc
{
	char	dtcode;
	char *dtstr;
};

struct dtcc sdtha [] =
{
	HPS_6840,	"HPS 6840",
	HPS_6860,	"HPS 6860",
	HPS_6830,	"HPS 6830",
	HPS_6945,	"HPS 6945",
	HPS_6825,	"HPS 6825",
	HPS_6834,	"HPS 6834",
	HPS_6940,	"HPS 6940",
	HPS_6960,	"HPS 6960",
	HPS_6236,	"HPS 6236",
	HPS_6237,	"HPS 6237",
	HPS_6850,	"HPS 6850",
	HPS_6950,	"HPS 6950",
	HPS_6240,	"HPS 6240",
	HPS_6245,	"HPS 6245",
	HPS_6270,	"HPS 6270",
	HPS_6276,	"HPS 6276",
	HPS_6180,	"HPS 6180",
	HPS_6280,	"HPS 6280"
};

#define MAX_HA (sizeof(sdtha) / sizeof(struct dtcc))


struct dtcc sdtcc [] = 
{
	HPS_7080,   "HPS 7080    ",
	HPS_7082,   "HPS 7082    ",
	HPS_7088,   "HPS 7088    ",
	HPS_708020, "HPS 7080-020",
	HPS_708220, "HPS 7082-020",
	HPS_708820, "HPS 7088-020",
	HPS_7080_030, "HPS 7080-030",
	HPS_7082_030, "HPS 7082-030",
	HPS_7088_030, "HPS 7088-030",
	HPS_7080_040, "HPS 7080-040",
	HPS_7082_040, "HPS 7082-040",
	HPS_7088_040, "HPS 7088-040"
};

#define NCCDT (sizeof(sdtcc) / sizeof(struct dtcc))

char *sdevt[10];

static long mailbox = 0;				/* Holds iocb errors */
extern int errno;

main(argc, argv)
int argc;
char **argv;
{
	char *dldev;
	int ast_len, cd;
	int aststat;
	AST *astp;
	int i, host_adapter;
	short tmp;

	tmp = 0;
	hps_intel = *(char *)&tmp;

	if (argc > 1 )
		dldev = argv[1];
	else
		dldev = RAW_DEVNAME;

	/* Open HPS raw driver */
	if ((hpsfd = open(dldev, 2)) < 0)
	{
		fprintf(stderr, "%s: Cannot open device %s\n", argv[0], dldev);
		if (errno)
			perror(argv[0]);
		exit(1);
	}

#	ifdef DEBUG
		fprintf(stderr, "%s: Open nif net config\n", pname);
#	endif

	/*
	 * Open network configuration minor device of network interface task
	 * to get a channel descriptor for AST requests.
	 */
	cd = nif_open(hpsfd, NET_AST, &mailbox);
	if ( cd < 0 || mailbox >> 16 )
	{
		fprintf(stderr, "%s: Cannot retrieve active station table from network interface module\n", argv[0]);
		if (errno)
			perror(argv[0]);
		else
			errtab(mailbox >> 16, argv[0]);

		exit(1);
	}
	cd &= 0xff;	/* channel descriptor */

	/* Print a header */
	printf ( "     NET ADDR\t     STATE\t\tDEV TYPE\tFW REV\tHOST ID\n" );
	printf ( "     --------\t     -----\t\t--------\t------\t-------\n" );

#	ifdef DEBUG
		fprintf(stderr, "%s: Read AST: cd = %d\n", pname, cd);
#	endif

	/*
	 * Get Active Station Table.
	 * As long as upper word of returned mail is set to E_OVERFLOW,
	 * complete AST has not been read.  Start by faking it.
	 */
	aststat = E_OVERFLOW;

	while ( aststat )
	{

#	ifdef DEBUG
		fprintf(stderr, "%s: Read AST\n", pname);
#	endif

		host_adapter = 0;
		ast_len = nif_read(hpsfd, cd, astbuf, sizeof(astbuf), &mailbox);

		/* return code is in upper word, length of AST in lower 
		   word */
		aststat = ast_len >> 16;

#	ifdef DEBUG
		fprintf(stderr, "%s: AST stat = %x, len = %x\n", pname, 
					aststat, ast_len);
#	endif

		if (aststat && aststat != E_OVERFLOW)
		{
			fprintf(stderr, "%s: Cannot read active station table.\n", argv[0]);
			if (errno)
				perror(argv[0]);
			else
				errtab(mailbox >> 16, argv[0]);

			nif_close(hpsfd, 0, NET_STNTFY);
			nif_close(hpsfd, cd, NET_AST);
			exit(1);
		}

		/* If the AST is empty, do nothing */
		if ( !( ast_len &= 0xffff ))
			break;

		/*
		 * Go through the AST, formatting each entry.
		 */
		astp = astbuf;

		while ( ast_len )
		{

#	ifdef DEBUG
			fprintf(stderr, "%s: astp = %x, ast_len = %x\n", pname, 
				astp, ast_len); 
#	endif

			for ( i = 0; i < MAX_HA; ++i )
			{
				if ( astp->dev_type == sdtha[i].dtcode )
				{
					host_adapter = 1;
					strcpy ( sdevt, sdtha[i].dtstr );
					break;
				}
			}
			if (!host_adapter)
			{
				if ( !astp->dev_type )
					strcpy ( sdevt, "HPS 708X" );
				else
				{
					for ( i = 0; i < NCCDT; ++i )
						if ( astp->dev_type == sdtcc[i].dtcode )
						{
							strcpy ( sdevt, sdtcc[i].dtstr );
							break;
						}
					if ( i == NCCDT )
					{
						sprintf ( sdevt, "unknown (0x%x)", astp->dev_type );
					}
				}
			}

			if ( astp->state <= PRIMIDLEFP )
				printf ( "\t%x\t%s\t%s\t %s", astp->net_addr & 0xff, 
					sstate[astp->state], sdevt, astp->fw_rev );
			else
				printf ( "\t%x\tUnknown state %x\t%s\t %s",
					astp->net_addr & 0xff, astp->state, sdevt,
					astp->fw_rev );

#ifdef OLDWAY
			if ( astp->dev_type && (unsigned char)astp->dev_type < 15 )
#endif
			if ( host_adapter)
				printf ( "\t  %x\n", astp->host_id & 0xff );
			else
				printf ( "\t  n/a\n" );

			++astp;
			ast_len -= sizeof(AST);

		}	/* end while processing this portion of the AST */
	}		/* end while more of AST to read from HPS */

#	ifdef DEBUG
	fprintf(stderr, "%s: Read complete AST\n", pname); 
#	endif

	nif_close ( hpsfd, cd, NET_AST );
}

/*
 * MODIFICATION HISTORY:
 *
 * $Log:	hps_netc.c,v $
 * Revision 1.1.2.1  92/06/24  13:53:35  marker
 * Branch RISCOS_5_01_2_FIXES off of trunk.
 * 
 * Revision 2.7  91/09/06  10:27:00  annette
 * Changed mailbox to &mailbox.
 * INTERNAL
 * 
 * Revision 2.6  91/09/03  17:37:47  annette
 * Changed error message handling.
 * INTERNAL
 * 
 * Revision 2.5  91/07/29  15:40:34  annette
 * Updated hps_netc to work with new host adapters.
 * ENHANCEMENT
 * 
 * Revision 2.4  91/07/24  12:52:26  annette
 * Made one sdtcc array for both host adapters and clusters because host adapter
 * dev_types are no longer consecutive numbers.
 * ENHANCEMENT
 * 
 * Revision 2.3  91/07/18  10:28:54  annette
 * Added 6180, 6280 into host adapter table.
 * 
 * Revision 2.2  91/01/10  17:22:43  dave
 * Modify header; add footer.
 * COSMETIC
 * 
 */
