Пример #1
0
/*----------------------------------------------------------------------------*\
  
\*----------------------------------------------------------------------------*/
static pwr_tStatus IoCardWrite (
  io_tCtx	ctx,
  io_sAgent	*ap,
  io_sRack	*rp,
  io_sCard	*cp  
) 
{
  io_sLocal 		*local;
  pwr_tUInt16		data = 0;
  pwr_sClass_Do_HVDO32	*op;
  pwr_tUInt16		invmask;
  pwr_tUInt16		testmask;
  pwr_tUInt16		testvalue;
  int			i;
  qbus_io_write		wb;
  int			sts;

  local = (io_sLocal *) cp->Local;
  op = (pwr_sClass_Do_HVDO32 *) cp->op;

#if defined(OS_ELN)
  vaxc$establish(machfailwrite);
#endif

  for ( i = 0; i < 2; i++)
  { 
    if ( ctx->Node->EmergBreakTrue && ctx->Node->EmergBreakSelect == FIXOUT)
    {
      if ( i == 0)
        data = op->FixedOutValue1;
      else
        data = op->FixedOutValue2;
    }
    else
      io_DoPackWord( cp, &data, i);

    if ( i == 0)
    {
      testmask = op->TestMask1;
      invmask = op->InvMask1;
    }
    else
    {
      testmask = op->TestMask2;
      invmask = op->InvMask2;
      if ( op->MaxNoOfChannels == 16)
        break;
    }

    /* Invert */
    data = data ^ invmask;

    /* Filter Po signals */
    if ( local->Filter[i].Found)
      io_PoFilter( local->Filter[i].sop, &data, local->Filter[i].Data);

    /* Testvalues */
    if ( testmask)
    {
      if ( i == 0)
        testvalue = op->TestValue1;
      else
        testvalue = op->TestValue2;
      data = (data & ~ testmask) | (testmask & testvalue);
    }

    wb.Data = data;
    wb.Address = local->Address[i];
    sts = write( local->Qbus_fp, &wb, sizeof(wb));
    if ( sts == -1)
    {
#if 0
      /* Exceptionhandler was called */
      if ( io_fatal_error)
      {
        /* Activate emergency break */
        errh_Error( "Fatal write error, card '%s', IO is stopped", cp->Name);
        ctx->Node->EmergBreakTrue = 1;
        return IO__ERRDEVICE;
      }
#endif
      /* Increase error count and check error limits */
      op->ErrorCount++;

      if ( op->ErrorCount == op->ErrorSoftLimit)
        errh_Error( "IO Error soft limit reached on card '%s'", cp->Name);
      if ( op->ErrorCount >= op->ErrorHardLimit)
      {
        errh_Error( "IO Error hard limit reached on card '%s', IO stopped", cp->Name);
        ctx->Node->EmergBreakTrue = 1;
        return IO__ERRDEVICE;
      }
      continue;
    }
  }
  return 1;
}
Пример #2
0
/*----------------------------------------------------------------------------*\
  
\*----------------------------------------------------------------------------*/
static pwr_tStatus IoCardWrite (
  io_tCtx	ctx,
  io_sAgent	*ap,
  io_sRack	*rp,
  io_sCard	*cp  
) 
{
  io_sLocal 		*local;
  io_sRackLocal		*r_local = (io_sRackLocal *)(rp->Local);
  pwr_tUInt16		data = 0;
  pwr_sClass_Ssab_BaseDoCard *op;
  pwr_tUInt16		invmask;
  pwr_tUInt16		testmask;
  pwr_tUInt16		testvalue;
  int			i;
  qbus_io_write		wb;
  int			sts;
  pwr_tTime             now;
  int			bfb_error = 0;
  pwr_sClass_Ssab_RemoteRack	*rrp;

  local = (io_sLocal *) cp->Local;
  op = (pwr_sClass_Ssab_BaseDoCard *) cp->op;

#if defined(OS_ELN)
  vaxc$establish(machfailwrite);
#endif

  for ( i = 0; i < 2; i++)
  { 
    if ( i == 1 && op->MaxNoOfChannels <= 16)
      break;

    if ( ctx->Node->EmergBreakTrue && ctx->Node->EmergBreakSelect == FIXOUT)
    {
      if ( i == 0)
        data = op->FixedOutValue1;
      else
        data = op->FixedOutValue2;
    }
    else
      io_DoPackWord( cp, &data, i);

    if ( i == 0)
    {
      testmask = op->TestMask1;
      invmask = op->InvMask1;
    }
    else
    {
      testmask = op->TestMask2;
      invmask = op->InvMask2;
      if ( op->MaxNoOfChannels == 16)
        break;
    }

    /* Invert */
    data = data ^ invmask;

    /* Filter Po signals */
    if ( local->Filter[i].Found)
      io_PoFilter( local->Filter[i].sop, &data, local->Filter[i].Data);

    /* Testvalues */
    if ( testmask)
    {
      if ( i == 0)
        testvalue = op->TestValue1;
      else
        testvalue = op->TestValue2;
      data = (data & ~ testmask) | (testmask & testvalue);
    }

    if (r_local->Qbus_fp != 0 && r_local->s == 0) {
      /* Write to local Q-bus */
      wb.Data = data;
      wb.Address = local->Address[i];
      sts = write( local->Qbus_fp, &wb, sizeof(wb));
    }
    else {
      /* Ethernet I/O, Request a write to current address */
      sts = 0;
      if ( !local->FirstScan)
	bfbeth_get_write_status(r_local, (pwr_tUInt16) local->Address[i], &sts);

      bfbeth_set_write_req(r_local, (pwr_tUInt16) local->Address[i], data);

      if (sts == -1) {
	/* Error handling for ethernet Qbus-I/O */
  	rrp = (pwr_sClass_Ssab_RemoteRack *) rp->op;
	if (bfb_error == 0) {
          op->ErrorCount++;
	  bfb_error = 1;
          if ( op->ErrorCount == op->ErrorSoftLimit)
            errh_Error( "IO Error soft limit reached on card '%s'", cp->Name);
          if ( op->ErrorCount == op->ErrorHardLimit)
            errh_Error( "IO Error hard limit reached on card '%s', stall action %d", cp->Name, rrp->StallAction);
          if ( op->ErrorCount >= op->ErrorHardLimit && rrp->StallAction == pwr_eSsabStallAction_ResetInputs ) {
	    sts = 1;
          }
          if ( op->ErrorCount >= op->ErrorHardLimit && rrp->StallAction == pwr_eSsabStallAction_EmergencyBreak ) {
            ctx->Node->EmergBreakTrue = 1;
            return IO__ERRDEVICE;
          }
	}
	if (sts == -1) continue;
      }
      else if ( sts == 1) {
	op->ErrorCount = 0;
      }
    }
    
    
    /* Error handling for local Qbus-I/O */
    if ( sts == -1)
    {
      /* Increase error count and check error limits */
      time_GetTime( &now);

      if (op->ErrorCount > op->ErrorSoftLimit) {
        /* Ignore if some time has expired */
        if (now.tv_sec - local->ErrTime.tv_sec < 600)
          op->ErrorCount++;
      }
      else
        op->ErrorCount++;
      local->ErrTime = now;


      if ( op->ErrorCount == op->ErrorSoftLimit)
        errh_Error( "IO Error soft limit reached on card '%s'", cp->Name);
      if ( op->ErrorCount >= op->ErrorHardLimit)
      {
        errh_Error( "IO Error hard limit reached on card '%s', IO stopped", cp->Name);
        ctx->Node->EmergBreakTrue = 1;
        return IO__ERRDEVICE;
      }
      continue;
    }
  }
  if ( local->FirstScan)
    local->FirstScan = 0;
  return 1;
}
Пример #3
0
/*----------------------------------------------------------------------------*\
  
\*----------------------------------------------------------------------------*/
static pwr_tStatus IoCardWrite (
  io_tCtx	ctx,
  io_sAgent	*ap,
  io_sRack	*rp,
  io_sCard	*cp  
) 
{
  io_sLocal 		*local = (io_sLocal *) cp->Local;
  io_sRackLocal		*r_local = (io_sRackLocal *)(rp->Local);
  pwr_tUInt16		data = 0;
  pwr_tUInt16		invmask;
  pwr_tUInt16		testmask;
  pwr_tUInt16		testvalue;
  int			i;
  qbus_io_write		wb;
  int			sts;
  pwr_tTime             now;
  pwr_sClass_Do_HVDO32	*op = (pwr_sClass_Do_HVDO32 *) cp->op;
  int 			words = op->MaxNoOfChannels <= 16 ? 1 : 2;


#if defined(OS_ELN)
  vaxc$establish(machfailwrite);
#endif

  for ( i = 0; i < words; i++)
  { 
    if ( i == 1 && op->MaxNoOfChannels <= 16)
      break;

    if ( ctx->Node->EmergBreakTrue && ctx->Node->EmergBreakSelect == FIXOUT)
    {
      if ( i == 0)
        data = op->FixedOutValue1;
      else
        data = op->FixedOutValue2;
    }
    else
      io_DoPackWord( cp, &data, i);

    if ( i == 0)
    {
      testmask = op->TestMask1;
      invmask = op->InvMask1;
    }
    else
    {
      testmask = op->TestMask2;
      invmask = op->InvMask2;
      if ( op->MaxNoOfChannels == 16)
        break;
    }

    /* Invert */
    data = data ^ invmask;

    /* Filter Po signals */
    if ( local->Filter[i].Found)
      io_PoFilter( local->Filter[i].sop, &data, local->Filter[i].Data);

    /* Testvalues */
    if ( testmask)
    {
      if ( i == 0)
        testvalue = op->TestValue1;
      else
        testvalue = op->TestValue2;
      data = (data & ~ testmask) | (testmask & testvalue);
    }

    if (r_local->Qbus_fp != 0 && r_local->s == 0) {
      /* Write to local Q-bus */
      wb.Data = data;
      wb.Address = local->Address[i];
      sts = write( local->Qbus_fp, &wb, sizeof(wb));
    }
    else {
      /* Ethernet I/O, Request a write to current address */
      bfbeth_set_write_req(r_local, (pwr_tUInt16) local->Address[i], data);
      sts = 1;      
    }

    if ( sts <= 0)
    {
#if 0
      /* Exceptionhandler was called */
      if ( io_fatal_error)
      {
        /* Activate emergency break */
        errh_Error( "Fatal write error, card '%s', IO is stopped", cp->Name);
        ctx->Node->EmergBreakTrue = 1;
        return IO__ERRDEVICE;
      }
#endif
      /* Increase error count and check error limits */
      time_GetTime(&now);

      if (op->ErrorCount > op->ErrorSoftLimit) {
        /* Ignore if some time has expired */
        if (now.tv_sec - local->ErrTime.tv_sec < 600)
          op->ErrorCount++;
      }
      else
        op->ErrorCount++;
      local->ErrTime = now;

      if ( op->ErrorCount == op->ErrorSoftLimit)
        errh_Error( "IO Error soft limit reached on card '%s'", cp->Name);
      if ( op->ErrorCount >= op->ErrorHardLimit)
      {
        errh_Error( "IO Error hard limit reached on card '%s', IO stopped", cp->Name);
        ctx->Node->EmergBreakTrue = 1;
        return IO__ERRDEVICE;
      }
      continue;
    }
  }
  return 1;
}