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