pfsisplug.c 4.43 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"
#ifdef BBPLAYER
#include "bbint.h"
#endif

#if __GNUC__
OSPifRam             __osPfsPifRam __attribute__((aligned (16)));
#else
OSPifRam             __osPfsPifRam;
#endif

s32
osPfsIsPlug(OSMesgQueue *queue, u8 *pattern)
{
  s32		ret = 0;
  OSMesg	dummy;
  u8		bitpattern;
  OSContStatus	data[MAXCONTROLLERS];
  int		channel;
  int		crc_error_cnt = 3;
  u8 		bits = 0;

	/* Block to get resource token */
  __osSiGetAccess();

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

    __osPfsRequestData(CONT_REQUEST);

    ret = __osSiRawStartDma(OS_WRITE, &__osPfsPifRam);
    (void)osRecvMesg(queue, &dummy, OS_MESG_BLOCK);

    /* trigger pifmacro */

    ret = __osSiRawStartDma(OS_READ, &__osPfsPifRam);
    (void)osRecvMesg(queue, &dummy, OS_MESG_BLOCK);

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

    __osPfsGetInitData(&bitpattern, &data[0]);

    /* check crc error and loop if there is an error */

    for (channel = 0; channel < __osMaxControllers; channel++) {
      if ((data[channel].status & CONT_ADDR_CRC_ER) == 0) {
	crc_error_cnt --;
	break;
      }
    }
    if (channel== __osMaxControllers) {
      crc_error_cnt = 0;
    }
  } while (crc_error_cnt > 0);

  /* loop through data array to check error bits */

  for (channel = 0; channel < __osMaxControllers; channel++) {
    if ((data[channel].errno == 0) && 
	((data[channel].status & CONT_CARD_ON) != 0))
      bits |= (1<<channel);
  }

  __osSiRelAccess();

  *pattern = bits;
  return(ret);
}

void
__osPfsRequestData(u8 cmd)
{
  u8 			*ptr = (u8 *)(&__osPfsPifRam);
  __OSContRequesFormat 	requestformat;
  int 			i;

  __osContLastCmd = cmd;

  /* set format flag */

#ifndef _HW_VERSION_1
  __osPfsPifRam.pifstatus = CONT_FORMAT;
#else
  __osPfsPifRam.pifstatus = 0;
#endif 

  /* 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
}

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

  ptr = (u8 *)(&__osPfsPifRam);

  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);
#ifdef BBPLAYER
    data->status = CONT_CARD_ON & (__osBbPakAddress[i]!=0);
#else
    data->status = requestformat.status;
#endif
    bits |= (1<<i);
  }
#ifdef BBPLAYER
  if (__osBbIsBb && __osBbHackFlags) {
    OSContStatus tmp;
    bits = (bits & ~(1|(1<<__osBbHackFlags))) | ((bits & 1) << __osBbHackFlags) | ((bits & (1<<__osBbHackFlags)) >> __osBbHackFlags);
    data -= __osMaxControllers;
    tmp = data[0];
    data[0] = data[__osBbHackFlags];
    data[__osBbHackFlags] = tmp;
  }
#endif

  *pattern = bits;
}