/*
 * @DEC_COPYRIGHT@
 */
/*
 * HISTORY
 * $Log:	tc.h,v $
 * Revision 1.1.3.5  92/04/10  11:53:47  Jeff_Anuszczyk
 * 	Change tc_intr_info structure (used by interrupt mechansim)
 * 	to allow either a bus or controller structure.
 * 	[92/04/02  14:43:57  Jeff_Anuszczyk]
 * 
 * 	Add new `active' flag to tc_slot table flag field.
 * 	[92/03/31  11:20:39  Jeff_Anuszczyk]
 * 
 * Revision 1.1.3.4  92/03/24  09:08:10  Jeff_Anuszczyk
 * 	Added loadable driver support.
 * 	[92/03/20  13:07:51  Jeff_Anuszczyk]
 * 
 * Revision 1.1.3.3  91/12/16  10:52:42  Gary_Dupuis
 * 
 * 	91/12/06	Gary Dupuis
 * 	Added support for Maxine (PERSONAL_DECstation)
 * 	Increase the definition of TC_IOSLOTS to 11 to accomadate
 * 	additional base board functionality on the MAXine.
 * 	[91/12/12  09:37:31  Gary_Dupuis]
 * 
 * Revision 1.1.3.2  91/11/20  14:04:00  Hal_Project
 * 	Moved from dec/io/...; pool reorg
 * 	[91/11/18  08:54:22  Donald_Dutile]
 * 
 * Revision 4.2  91/09/19  23:20:15  devbld
 * 	Adding ODE Headers
 * 
 * $EndLog$
 */
/*	
 *	@(#)$RCSfile: tc.h,v $ $Revision: 1.1.3.5 $ (DEC) $Date: 92/04/10 11:53:47 $
 */ 
/*
 * (c) Copyright 1990, OPEN SOFTWARE FOUNDATION, INC.
 * ALL RIGHTS RESERVED
 */
/*
 * OSF/1 Release 1.0
 */
/* 
 * derived from tc.h	4.6	(ULTRIX)	1/22/91
 */

/*
 * Modification History: tc.h
 *
 * 06-Mar-91	Mark Parenti
 *	Modify to use new I/O data structures.
 *
 * 21-Jan-91	Randall Brown
 *	Added tc_memerr_status struct for use in tc_isolate_memerr()
 *	routine.
 *
 * 15-Oct-90	Randall Brown
 *	Added defines for ROM header offsets.
 *
 *  6-Sep-90	Randall Brown
 *	Changed slot_order to be config_order. 
 *
 *  5-Jul-90	Randall Brown
 *	Added the routine tc_ui_to_name() for drivers to determine
 *	the name of the specific option module.
 *
 * 27-Mar-90	Randall Brown
 *	Added #defines for TC_OPTION_SLOT_*
 *
 * 22-Jan-90	Randall Brown
 *	Created this file for TURBOchannel support
 *
 */


#include <sys/types.h>

#define TC_IOSLOTS 11			/* number of TURBOchannel slots */
#define TC_OPTION_SLOTS 3		/* number of optional tc slots */

#define TC_OPTION_SLOT_0	0
#define TC_OPTION_SLOT_1	1
#define TC_OPTION_SLOT_2	2

#define TC_ROMOFFSET	0x003c0000	/* offset in slot to IO ROM */

#define TC_VERSION_OFFSET	0x400
#define TC_VENDOR_OFFSET	0x420
#define TC_NAME_OFFSET		0x440

#define TC_ROMNAMLEN 8			/* length of module name in rom */

struct tc_option {
	char modname[TC_ROMNAMLEN+1];	/* the module name */
	char confname[TC_ROMNAMLEN+1];	/* device or ctlr name (config file) */
	int  intr_b4_probe;		/* enable intr before probe routine */
	int  intr_aft_attach;		/* enable intr after attach routine */
	char type;			/* D = dev, C = ctrlr, A = adpt */
	int (*adpt_config)();		/* adpater config routine to call */
};

/* Define the tc_info structure used to contain tc-specific bus information */
/* This is passed to the configuration routine of any bus connected to the  */
/* TURBOchannel.							    */

struct	tc_info {
	caddr_t	addr;			/* virtual address of slot	*/
	caddr_t	physaddr;		/* physical address of slot	*/
	int	slot;			/* slot number			*/
	int	unit;			/* logical unit number		*/
	int (**intr)();		/* intr routine for device (from config file)*/
	struct bus *bus_hd;		/* pointer to bus head structure */
};


#define	tcindx	conn_priv[1]

/* Define the tc interrupt handler structure for use by loadable device
 * drivers.
 */

struct tc_intr_info {
	caddr_t configuration_st;	/* Pointer to bus/controller struct */
	int (*intr)();			/* Interrupt handler */
	caddr_t param;			/* param for interrupt handler */
	unsigned int config_type;	/* Driver type, TC_ADPT or TC_CTLR */
};

/*
 *	The following are used to describe the class attribute of the
 *	module.  These will be filled in during auto-configuration.
 *	These are also used to specify driver type in the config_type field
 *	of the tc_intr_info data structure.
 */
#define TC_CTLR 	1
#define TC_DEV 		2
#define TC_ADPT 	3
#define TC_UNKNOWN	4	/* Module exists but we don't know what kind */
				/* it is.  Provided for loadable support.    */

/* Definitions for flags field in tc_slot structure */

#define	TC_INTR_ADD	0x1	/* Handler add performed */
#define	TC_INTR_ENAB	0x2	/* Handler enable performed */
#define TC_ACTIVE	0x4	/* Slot is controlled by a driver */

struct tc_slot {
	char version[TC_ROMNAMLEN+1];	/* the version in the ROM */
	char vendor[TC_ROMNAMLEN+1];	/* the vendor in the ROM */
	char modulename[TC_ROMNAMLEN+1];	/* the module name in the ROM */
	char devname[TC_ROMNAMLEN+1];	/* the controller or device name */
	int slot;		/* the TURBOchannel IO slot number */
	int module_width;	/* how many slots the IO module takes */
	int (*intr)();		/* intr routine for device (from config file)*/
	int unit;		/* device unit number (from config file) */
	int physaddr;		/* the physical addr of the device */
	int class;		/* ctlr or dev: to call right config routine */
	int intr_b4_probe;	/* enable intr before probe routine */
	int intr_aft_attach;	/* enable intr after attach routine */
	int (*adpt_config)();	/* config routine for adapters
				   (from tc_option_data table) */
	caddr_t dev_str;	/* controller structure	*/
	caddr_t param;		/* interrupt parameter */
	int flags;		/* various flags	*/
};

extern struct tc_slot tc_slot[];	/* table with IO device info */
extern u_int   tc_slotaddr[];		/* table with slot address info */

struct tc_sw {
        int *config_order;	/* order to probe slots of TURBOchannel */
        int (*enable_option)();	/* routine to enable interrupt */
	int (*disable_option)();/* routine to disable interrupt */
	int (*clear_errors)();	/* routine to clear errors caused by probe */
	int (*isolate_memerr)();/* routine to isolate memory errors */
};

extern struct tc_sw tc_sw;
/*
 *	tc_enable_option(ctlr)
 *		struct controller *ctlr;
 *
 *	Takes controller structure for this controller.
 *
 *	This function enables an option's interrupt on the TURBOchannel
 *	to interrupt the system at the I/O interrupt level.  
 *	This is done calling the system specific routine to allow the
 *	option's slot to interrupt the system.
 */

int tc_enable_option();

/*
 *	tc_disable_option(ctlr)
 *		struct controller *ctlr;
 *
 *	Takes controller structure for this controller.
 *
 *	This function disables an option's interrupt on the TURBOchannel from
 *	interrupting the system at the I/O interrupt level.  
 *	This is done by calling the system specific routine to reset the 
 *	option's slot from interrupting the system.
 */	

int tc_disable_option();

/*
 *	tc_module_name(ctlr, cp)
 *		struct controller *ctlr;
 *		char *cp; ( cp[TC_ROMNAMLEN + 1] )
 *
 *	Takes a pointer to a controller struct.
 *
 *	This function will fill in the character array 'cp' with the ascii
 *	string of the TURBOchannel option's module name refered to by the
 *	 'ctlr' pointer. The array 'cp' must be declared by the caller
 *	of this routine to be the size defined above.
 *
 *	The function will return a (-1) if it was unable to use the 'cp'
 *	pointer that it was given.
 */

int	tc_module_name();

/*
 *	tc_addr_to_name(addr, cp)
 *		u_int	addr;
 *		char	*cp; ( cp[TC_ROMNAMLEN + 1] )
 *
 *	Takes the address passed to the device driver's probe routine
 *	which is the base address of the device.
 *
 *	This function will fill in the character array 'cp' with the ascii
 *	string of the TURBOchannel option's module name refered to by the
 *	base address 'addr'.  The array 'cp' must be declared by the caller
 *	of the routine to be the size defined above.
 *
 *	This function would be used in a driver's probe routine, since the
 *	'ctlr' pointer required by the above routine 'tc_module_name' is
 *	not valid in the probe routine.
 *
 *	The function will return a (-1) if it was unable to use the 'cp'
 *	pointer that it was given.
 */

int	tc_addr_to_name();

struct tc_memerr_status {
    caddr_t	pa;		/* physical address of error */
    caddr_t	va;		/* virtual address, 0 if not know */
    int		log;		/* flag whether to log error */
    int		blocksize;	/* size of DMA block */
    u_int	errtype;	/* error type status */
};

/*
 *	tc_isolate_memerr(memerr_status)
 *	    struct tc_memerr_status *memerr_status;
 *
 *	Takes a pointer to a tc_memerr_status struct.
 *
 *	Takes the physical address (pa) of the error, the virtual
 *	address of the error (va), flag for logging, and a pointer
 *	to a status int.  If the va is 0, a K1 address is formed from
 *	the physical address and is used as the virtual address.
 *	
 *	This function will fill in the u_int 'errtype' with
 *	the information about the memory error of 'pa' as defined below.
 *	This is done by calling a system specific routine to determine the 
 *	exact error based on the physical address and virtual address.  If
 *	the parameter 'log' is set to TC_LOG_MEMERR, the system 
 *	specific routine will log the error in the same manner a memory
 *	error is logged as if it came directly into the CPU.
 *
 *	The function will return a (-1) if it the physical address supplied
 *	is bad, or if the system specific routine does not exist.
 */

/*
 * 	The following defines are used for the 'log' parameter in the
 * 	tc_memerr_status struct passed to tc_isolate_memerr().
 */
#define	TC_NOLOG_MEMERR		0	/* do not log error info */
#define	TC_LOG_MEMERR		1	/* log error information */

/* 
 *	The following defines are used for the 'errtype' return status
 *	in the tc_memerr_status struct passed to tc_isolate_memerr().
 *
 *	NOTE: As other systems are produced that have different
 *	      memory subsystems, additional defines will be added to the
 *	      list below.
 */
#define TC_MEMERR_NOERROR	0	/* no error found */
#define TC_MEMERR_TRANS		1	/* transient parity error */
#define TC_MEMERR_SOFT		2	/* soft parity error */
#define TC_MEMERR_HARD		3	/* hard parity error */

int	tc_isolate_memerr();
