controller.c 4.34 KB

/**************************************************************************
 *                                                                        *
 *               Copyright (C) 1995, Silicon Graphics, Inc.               *
 *                                                                        *
 *  These coded instructions, statements, and computer programs  contain  *
 *  unpublished  proprietary  information of Silicon Graphics, Inc., and  *
 *  are protected by Federal copyright law.  They  may  not be disclosed  *
 *  to  third  parties  or copied or duplicated in any form, in whole or  *
 *  in part, without the prior written consent of Silicon Graphics, Inc.  *
 *                                                                        *
 **************************************************************************/

#include "osint.h"
#include "controller.h"
#include "siint.h"

#if __GNUC__
OSPifRam		__osContPifRam __attribute__((aligned (16)));
#else
OSPifRam		__osContPifRam;		/* PIF RAM buffer */
#endif

u8		 	__osContLastCmd;	/* last pifmacro command */
u8			__osMaxControllers;	/* # of connected controllers */
OSTimer			__osEepromTimer;
OSMesgQueue		__osEepromTimerQ;
OSMesg			__osEepromTimerMsg;
int			__osContinitialized=0;


/*
 * This call resets all the controllers and returns 
 * a bit pattern to indicate which controllers are connected.
 * It also returns controller's type and status for all the connected
 * controllers
 */
s32
osContInit(OSMesgQueue *mq, u8 *bitpattern, OSContStatus *data)
{
	OSMesg	dummy;
	s32	ret = 0;
	OSTime t;
	OSTimer mytimer;
	OSMesgQueue timerMesgQueue;

	if (__osContinitialized != 0)
		return(0);

	__osContinitialized = 1;
	/* need to wait for .5 sec */

	t = osGetTime();
	if (t < OS_USEC_TO_CYCLES(500000)) {
		osCreateMesgQueue(&timerMesgQueue, &dummy, 1);
		osSetTimer(&mytimer,OS_USEC_TO_CYCLES(500000)-t, 0, 
			&timerMesgQueue,&dummy);
		(void)osRecvMesg(&timerMesgQueue, &dummy, OS_MESG_BLOCK);
	}

	__osMaxControllers = MAXCONTROLLERS;

	/* Set up request command format for all channels */

	__osPackRequestData(CONT_REQUEST);
	ret = __osSiRawStartDma(OS_WRITE, &__osContPifRam);
	(void)osRecvMesg(mq, &dummy, OS_MESG_BLOCK);

	/* trigger pifmacro */

	ret = __osSiRawStartDma(OS_READ, &__osContPifRam);
	(void)osRecvMesg(mq, &dummy, OS_MESG_BLOCK);

	/* reformat the 64 bytes RAM data and save in data array */

	__osContGetInitData(bitpattern, data);
	__osContLastCmd = CONT_REQUEST;
	__osSiCreateAccessQueue();

	osCreateMesgQueue(&__osEepromTimerQ, &__osEepromTimerMsg, 1);

	return(ret);
}

/*
 * Reformat the 64 bytes RAM data into RequestData format 
 * and check error code.
 */
void
__osContGetInitData(u8 *pattern, OSContStatus *data)
{
	u8 			*ptr;
	__OSContRequesFormat 	requestformat;
	int 			i;
	u8			bits = 0;


	ptr = (u8 *)(&__osContPifRam);

        for (i = 0; i < __osMaxControllers; i++, 
		ptr += sizeof(requestformat), data++) {

                /* read request format for all the channel */

                requestformat = *((__OSContRequesFormat *)ptr);
#ifndef _HW_VERSION_1
                data->errno = (u8)((requestformat.rxsize & CON_ERR_MASK) >> 4);
#else
                data->errno = (u8)(((requestformat.txsize & CON_ERR_MASK) >> 4)
                | ((requestformat.rxsize & CON_ERR_MASK) >> 6));
#endif
                if (data->errno)
                        continue;
                data->type =(u16)((requestformat.typel<<8)|requestformat.typeh);
                data->status = requestformat.status;
                bits |= (1<<i);
        }
        *pattern = bits;
}

void
__osPackRequestData(u8 cmd)
{
	u8 			*ptr;
	__OSContRequesFormat 	requestformat;
	int 			i;


	/* clear pif ram */

	for (i = 0; i < PIFRAMSIZE-1 ; i++)
		__osContPifRam.ramarray[i] = 0;
#ifndef _HW_VERSION_1
	__osContPifRam.pifstatus = CONT_FORMAT;
#else
	__osContPifRam.pifstatus = 0;
#endif 

	ptr = (u8 *)(&__osContPifRam);

	/* Setup request format for each channel */

	requestformat.dummy = 0xff;
	requestformat.txsize = 1;
	requestformat.rxsize = 3;
	requestformat.cmd = cmd;
	requestformat.typeh = 0xff;
	requestformat.typel = 0xff;
	requestformat.status = 0xff;
	requestformat.dummy1 = 0xff;

	for (i = 0; i < __osMaxControllers; i++) {

		/* setup request format for all the channel */

		*((__OSContRequesFormat *)ptr) = requestformat;
		ptr += sizeof(requestformat);
	}
#ifndef _HW_VERSION_1
	*((u8 *)ptr) = FORMAT_END;
#endif
}