/*
 * @DEC_COPYRIGHT@
 */
/*
 * HISTORY
 * $Log:	presto.h,v $
 * Revision 4.2.2.2  92/02/26  15:49:16  Charles_Briggs
 * 	Pool merge
 * 	[92/02/23  12:48:27  Charles_Briggs]
 * 
 * 	UBC merge.
 * 	[92/02/22  14:44:31  Charles_Briggs]
 * 
 * Revision 4.2  91/09/19  23:03:40  devbld
 * 	Adding ODE Headers
 * 
 * $EndLog$
 */
/*	
 *	@(#)$RCSfile: presto.h,v $ $Revision: 4.2.2.2 $ (DEC) $Date: 92/02/26 15:49:16 $
 */ 
/*
 */
/*
 * (c) Copyright 1990, OPEN SOFTWARE FOUNDATION, INC.
 * ALL RIGHTS RESERVED
 */
/*
 * OSF/1 Release 1.0
 */
/*
 * derived from  presto.h	4.4	(ULTRIX)	1/10/91
 */


/*
 *	Portions of this software have been licensed to 
 *	Digital Equipment Company, Maynard, MA.
 *	Copyright (c) 1990 Legato Systems, Inc.  ALL RIGHTS RESERVED.
 */

/*
 *
 *   Modification history:
 *
 *  19 Aug 90 -- chet
 *      V4.1 version.
 *
 *  25 May 90 -- chet
 *	Added this file; it was derived from Legato sources.
 *
 */

/*
 * Definitions for the ``presto'' device driver.
 */

/*
 * Presto is initially down until an PRSETSTATE ioctl cmd
 * with arg = PRUP is done.  When presto is down, nothing is
 * being cached and everything is sync'd back to the real disk.
 */

#ifndef _PRESTO_H_
#define _PRESTO_H_
#include <sys/prestoioctl.h>

/*
 * Presto buffer management code.
 */
#define PRBQUEUES	3		/* number of free buffers queues */

#define PR_DIRTY	0		/* dirty buffers */
#define PR_CLEAN	1		/* clean buffers */
#define PR_INVAL	2		/* buffers without valid data */

#define PRBUFHSZ	64
#define PRRND		(PRBSIZE / DEV_BSIZE)

extern struct bufhd prbufhash[PRBUFHSZ];
extern struct diskhd prbfreelist[PRBQUEUES];
extern struct buf *prbufs;
extern int prnbufs;
extern struct presto_status prstatus;

/*
 * Diskhd structures used at the head of the disk unit queues.
 * We only need a few elements for these, so this abbreviated
 * definition saves some space.
 */
struct diskhd {
      long b_flags;                   /* not used, needed for consistency */
      struct  buf *b_forw, *b_back;   /* queue of unit queues */
      struct  buf *av_forw, *av_back; /* queue of bufs for this unit */
      long    b_bcount;               /* active flag */
};

#define PRBUFHASH(dev, dblkno) \
	((struct buf *)&prbufhash \
		[((u_int)(dev)+(((int)(dblkno))/PRRND)) & (PRBUFHSZ-1)])

/*
 * The nvbuf structure defines the parts of the buffer structure
 * that must be kept in non-volatile memory so that buffers can
 * survive reboots.  These fields are merely copies of the
 * corresponding fields kept in the presto buffers in main memory.
 */
struct nvbuf {
	int	nb_flags;
	daddr_t	nb_blkno;
	dev_t	nb_dev;
	u_short	nb_bcount;
};

/*
 * PRBSIZE and PRFSIZE are the basic size for presto buffering.
 * PRBSIZE is the largest block size we buffer.  PRFSIZE is the
 * "fragment" size of the smallest request we will buffer.
 *
 * We choose 8k/1K for these values; this corresponds
 * to the default ufs blocks sizes.
*/
#define PRBSIZE		MAXBSIZE		/* largest presto bsize */
#define PRFSIZE		1024			/* smallest presto bsize */
#define	NCHKSUMS	(PRBSIZE / PRFSIZE)	/* # of chksums per buffer */

#define PRMINSIZE	roundup((sizeof (struct nv) + PRBSIZE), PRBSIZE)
#define PRMAXSIZE	0x200000
#define PRMAXBUFS	((PRMAXSIZE / PRBSIZE) - 1)

#define PRBALIGN(x)	(((u_int)(x) + PRBSIZE - 1) & ~(PRBSIZE - 1))

struct nvh {
	u_int nvh_dirty;		/* value of PRESTO_DIRTY means
					 * cache contains dirty data */
	u_int nvh_magic;		/* magic number */
	u_int nvh_size;			/* total bytes being used */
	u_int nvh_version;		/* version number for validation */
	u_int nvh_bsize;		/* holds PRBSIZE for validation */
	u_int nvh_fsize;		/* holds PRFSIZE for validation */
	u_int nvh_machineid;		/* holds machine id for validation */
	u_int nvh_nbufs;		/* number of presto buffers */
};

struct nv {
	struct 	nvh nv_nvh;
	struct 	nvbuf nv_bufs[PRMAXBUFS];
	char 	nv_scratch[DEV_BSIZE + sizeof (long)];
};

/*
 * The data buffers are PRBSIZE aligned below the nv structure; since the
 * position of the header in the "pr" device space is different on various
 * boards, we have to dynamically calculate the page aligned start of the
 * data buffers.
 */
struct nvbd {
	char 		nvbd_data[PRMAXBUFS][PRBSIZE];
};

/*
 * The PRVERSION number should be increased everytime
 * the nvh or nv structure contents or layout changes.
 */
#define PRVERSION	0xc		/* version number for above */
#define PRMAGIC		0x031758	/* presto non-volatile magic number */

/* Clean/Dirty word (first word of presto NVRAM cache) value */
#define PRESTO_DIRTY	0xbd100248	/* cache contains dirty data */
					/* anything else means it does not */ 

/* Status of NVRAM diagnostics */
#define NVRAM_BAD	0	/* either read/write or read-only diagnostics
				 * run unsuccessfully */
#define NVRAM_RDWR	1	/* read/write diagnostics run successfully */
#define NVRAM_RDONLY	2	/* read-only diagnostics run successfully */

/* Array of pointers to NVRAM cache interface routines */
struct presto_interface {
	int (*nvram_status)();		/* MANDATORY */
	      /* returns diagnostic status of NVRAM */
	int (*nvram_battery_enable)();	/* OPTIONAL */
	      /* enables the use of the battery subsystem upon powerfail */
	int (*nvram_battery_disable)();	/* OPTIONAL */
	      /* disables the use of the battery subsystem upon powerfail */
	int (*nvram_battery_status)();	/* MANDATORY */
	      /* returns battery subsystem status */
	      /*
	       * A dichotomy between small transfers (e.g. 32 bytes or less)
	       * and large transfers (1KB or more) exists within the Presto
	       * driver. The following routines and restrictions are used
	       * to "program" Presto NVRAM transfers.
	       *
	       * The following routines take an argument list identical
	       * to bcopy(), i.e. (fromaddr, toaddr, len).
	       */
	void (*nvram_ioreg_read)();	/* MANDATORY */
	      /* routine to read "small" pieces of NVRAM */
	void (*nvram_ioreg_write)();	/* MANDATORY */
	      /* routine to write "small" pieces of NVRAM */
	void (*nvram_block_read)();	/* MANDATORY */
	      /* routine to read "large" pieces of NVRAM */
	void (*nvram_block_write)();	/* MANDATORY */
	      /* routine to write "large" pieces of NVRAM */
	      /*
	       * The following routines takes an argument list identical
	       * to bzero(), i.e. (addr, len).
	       */
	void (*nvram_ioreg_zero)();	/* MANDATORY */
	      /* routine to clear "small" pieces of NVRAM */
	void (*nvram_block_zero)();	/* MANDATORY */
	      /* routine to clear "large" pieces of NVRAM */
	      /*
	       * Alignment and granularity information.
	       */
	int nvram_min_ioreg;		/* MANDATORY */
	      /* minimum size of a "small" piece (in bytes) */
	u_int nvram_ioreg_align;		/* MANDATORY */
	      /* byte alignment restriction for a "small" piece */
	      /* (e.g. 4 byte boundary = 4) */
	int nvram_min_block;		/* MANDATORY */
	      /* minimum size of a "large" piece (in bytes) */
	u_int nvram_block_align;		/* MANDATORY */
	      /* byte alignment restriction for a "large" piece */
	      /* (e.g. 4 byte boundary = 4) */
        };

#ifdef KERNEL
/* declare interface routine array for /dev/pr0 */
extern struct presto_interface presto_interface0;
#endif /* KERNEL */

/*
/* Battery information for NVRAM cache
 * In this structure:
 *
 * nv_nbatteries is the number of batteries supported
 * by the platform. This number of status fields will be inspected by
 * presto software in priority sequence (nv_batt_status[0] = primary,
 * nv_batt_status[1] = first secondary, ...). 
 *
 * Presto software will either not start normal operation, or will
 * shut itself down, if a "bad battery condition" is detected. This is
 * defined to be the case that there are less than nv_minimum_ok
 * batteries with sufficient power (BATT_OK).
 */
#define BATTCNT		4		/* a maximum of four batteries */
struct nvram_battery_info {
  	int	nv_nbatteries;		/* number of batteries supported */
	int	nv_test_retries;	/* number of successive calls
					 * to nvram_battery_status() for
					 * each presto battery check */
	int	nv_minimum_ok;	    	/* minimal # of BATT_OK batteries
					 * for normal operation */
	int	nv_primary_mandatory;	/* primary must be good */
  	int	nv_status[BATTCNT]; 	/* see status bits below */
        };

#define BATT_NONE	0	/* either no battery or completely bad */
#define BATT_ENABLED 	0x1	/* battery enabled,
				 * i.e. will back up NVRAM on power fail */
#define BATT_HIGH	0x2	/* battery has minimal energy stored,
				 * i.e. has enough power for Prestoserve use */
#define BATT_OK		0x3	/* battery is enabled AND has enough power
				 * i.e. is usable for Prestoserve */
#ifdef KERNEL
/* declare battery info structure for /dev/pr0 */
extern struct nvram_battery_info nvram_batteries0;
#endif /* KERNEL */

#endif /* _PRESTO_H_ */
