static pwr_tStatus IoCardInit ( io_tCtx ctx, io_sAgent *ap, io_sRack *rp, io_sCard *cp ) { pwr_tStatus sts; pwr_sClass_Ssab_CO4uP *op; io_sLocal *local; int i; pwr_tUInt16 wr_data[2]; pwr_tUInt32 *wr_data_p; qbus_io_write wb; io_sRackLocal *r_local = (io_sRackLocal *)(rp->Local); op = (pwr_sClass_Ssab_CO4uP *) cp->op; local = calloc( 1, sizeof(*local)); for ( i = 0; i < IO_MAXCHAN; i++) local->FirstScan[i] = 1; cp->Local = local; local->Address = op->RegAddress; local->Qbus_fp = ((io_sRackLocal *)(rp->Local))->Qbus_fp; errh_Info( "Init of co card '%s'", cp->Name); /* Configure card */ for ( i = 0; i < op->MaxNoOfCounters; i++) { if ( !cp->chanlist[i].cop || !cp->chanlist[i].sop) continue; wr_data_p = (pwr_tUInt32 *) &wr_data; *wr_data_p = op->SyncRawValue[i]; if ( op->SpeedMeasurement[i] == 1) wr_data[1] |= (1 << 8); if ( op->LengthMeasurement[i] == 1) wr_data[1] |= (1 << 10); if ( op->MulCount[i] == 2) wr_data[1] |= (1 << 11); if ( op->DivCount[i] == 16) wr_data[1] |= (1 << 9); if ( op->NoOfBits[i] == 16) wr_data[1] |= (1 << 12); if ( op->CopWrRough[i] == 1) wr_data[1] |= (1 << 13); if ( op->CopWrFine[i] == 1) wr_data[1] |= (1 << 14); if ( op->LoadWrReg[i] == 1) wr_data[1] |= (1 << 15); if (r_local->Qbus_fp != 0 && r_local->s == 0) { /* Write to local Q-bus */ wb.Address = local->Address + 4*i; wb.Data = wr_data[0]; sts = write( local->Qbus_fp, &wb, sizeof(wb)); if ( sts != -1) { wb.Address += 2; wb.Data = wr_data[1]; 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 + 4*i), wr_data[0]); bfbeth_set_write_req(r_local, (pwr_tUInt16) (local->Address + 4*i + 2), wr_data[1]); sts = 1; } if ( sts == -1) { errh_Error( "IO init, Fatal write error, card '%s', IO i stopped", cp->Name); return IO__ERRDEVICE; } if ( op->LoadWrReg[i] == 1) { * (pwr_tUInt32 *) cp->chanlist[i].vbp = op->SyncRawValue[i]; * (pwr_tUInt32 *) cp->chanlist[i].abs_vbp = op->SyncRawValue[i]; } else { * (pwr_tUInt32 *) cp->chanlist[i].vbp = 0; } /* Data is written to device */ op->COWrFlag[i] = 0; } return 1; }
/*----------------------------------------------------------------------------*\ \*----------------------------------------------------------------------------*/ static pwr_tStatus IoCardRead ( io_tCtx ctx, io_sAgent *ap, io_sRack *rp, io_sCard *cp ) { io_sLocal *local; pwr_tUInt16 wr_data[2]; pwr_tUInt16 re_data[2]; pwr_tUInt32 *wr_data_p; pwr_tUInt32 *re_data_p; pwr_sClass_Ssab_CO4uP *op; pwr_tInt32 numofword; int i; pwr_tInt16 co16_data; pwr_tInt32 newdiff,diff,co24_data; int sts, sts1, sts2; qbus_io_read rb; qbus_io_write wb; io_sRackLocal *r_local = (io_sRackLocal *)(rp->Local); pwr_tTime now; local = (io_sLocal *) cp->Local; op = (pwr_sClass_Ssab_CO4uP *) cp->op; for ( i = 0; i < op->MaxNoOfCounters; i++) { if ( !cp->chanlist[i].cop || !cp->chanlist[i].sop) continue; if ( op->ConvMask & (1 << i)) { /* Conversion is on */ if ( op->COWrFlag[i]) { /* New configuration of card */ wr_data_p = (pwr_tUInt32 *) &wr_data; *wr_data_p = op->SyncRawValue[i]; if ( op->SpeedMeasurement[i] == 1) wr_data[1] |= (1 << 8); if ( op->LengthMeasurement[i] == 1) wr_data[1] |= (1 << 10); if ( op->MulCount[i] == 2) wr_data[1] |= (1 << 11); if ( op->DivCount[i] == 16) wr_data[1] |= (1 << 9); if ( op->NoOfBits[i] == 16) wr_data[1] |= (1 << 12); if ( op->CopWrRough[i] == 1) wr_data[1] |= (1 << 13); if ( op->CopWrFine[i] == 1) wr_data[1] |= (1 << 14); if ( op->LoadWrReg[i] == 1) wr_data[1] |= (1 << 15); if (r_local->Qbus_fp != 0 && r_local->s == 0) { /* Write to local Q-bus */ wb.Address = local->Address + 4*i; wb.Data = wr_data[0]; sts = write( local->Qbus_fp, &wb, sizeof(wb)); if ( sts != -1) { wb.Address += 2; wb.Data = wr_data[1]; 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 + 4*i), wr_data[0]); bfbeth_set_write_req(r_local, (pwr_tUInt16) (local->Address + 4*i + 2), wr_data[1]); sts = 1; } if ( sts == -1) { errh_Error( "IO init, Fatal write error, card '%s', IO i stopped", cp->Name); } op->COWrFlag[i] = 0; } if ( op->NoOfBits[i] == 24) numofword = 2; else numofword = 1; /* 16 bitscounter */ re_data_p = (pwr_tUInt32 *) &re_data; if (r_local->Qbus_fp != 0 && r_local->s == 0) { /* Read from local Q-bus */ rb.Address = local->Address + 4*i; sts1 = read( local->Qbus_fp, &rb, sizeof(rb)); re_data[0] = (unsigned short) rb.Data; } else { /* Ethernet I/O, Get data from current address */ re_data[0] = bfbeth_get_data(r_local, (pwr_tUInt16) (local->Address + 4*i), &sts1); /* Yes, we want to read this address the next time aswell */ bfbeth_set_read_req(r_local, (pwr_tUInt16) (local->Address + 4*i)); } if ( numofword == 2) { if (r_local->Qbus_fp != 0 && r_local->s == 0) { /* Read from local Q-bus */ rb.Address += 2; sts2 = read( local->Qbus_fp, &rb, sizeof(rb)); re_data[1] = (unsigned short) rb.Data; } else { /* Ethernet I/O, Get data from current address */ re_data[1] = bfbeth_get_data(r_local, (pwr_tUInt16) (local->Address + 4*i + 2), &sts2); /* Yes, we want to read this address the next time aswell */ bfbeth_set_read_req(r_local, (pwr_tUInt16) (local->Address + 4*i + 2)); } } else sts2 = 0; if ( sts1 == -1 || sts2 == -1) { #if 0 if ( io_fatal_error) { /* Activate emergency break */ errh_Error( "Fatal read error, card '%s', IO i 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; } } /* No faults detected calculate countervalue and store them */ if (numofword == 1) /* 16 bits counter */ { co16_data = re_data[0]; /* If this is the first lap we dont have any correct saved countvalues. Therefor we save the new value. */ if ( local->FirstScan[i]) local->OldValue[i] = co16_data; /* Store the counter values into RTDB */ *(pwr_tUInt32 *) cp->chanlist[i].vbp = co16_data; /* Test if an abs-value should be calculated and stored */ if ( op->COAbsFlag[i] == TRUE) { /* Calculate difference between two readings*/ diff = co16_data - local->OldValue[i]; local->OldValue[i] = co16_data; /* Store new value */ /* Check if the counter is passing zero or max, and calculate if it is counting up or down */ if (diff < MIN16) /* Up count over maxlimit */ newdiff = MAXCO16 + diff; else if (diff > MAX16) newdiff = diff - MAXCO16; else newdiff = diff; /* Store the counter abs-values into RTDB */ *(pwr_tUInt32 *) cp->chanlist[i].abs_vbp += newdiff; } } else if (numofword == 2) /* 24 bits counter */ { co24_data = *re_data_p; /* If this is the first lap we dont have any correct saved countvalues. Therefor we save the new value. */ if ( local->FirstScan[i]) local->OldValue[i] = co24_data; /* Store the counter values into RTDB */ *(pwr_tUInt32 *) cp->chanlist[i].vbp = co24_data; /* Test if an abs-value should be calaulated and stored */ if ( op->COAbsFlag[i] == TRUE) { /* Calculate difference between two readings */ diff = co24_data - local->OldValue[i]; local->OldValue[i] = co24_data; /* Store new value */ /* Check if the counter is passing zero or max, and calculate if it is counting up or down */ if (diff < MIN24) /* Up count over maxlimit */ newdiff = MAXCO24 + diff; else if (diff > MAX24 ) newdiff = diff - MAXCO24 ; else newdiff = diff ; /* Store the counter abs-values into RTDB */ *(pwr_tUInt32 *) cp->chanlist[i].abs_vbp += newdiff; } } local->FirstScan[i] = 0; } 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_sRackLocal *r_local = (io_sRackLocal *)(rp->Local); pwr_sClass_Ao_HVAO4 *op; int i; io_sChannel *chanp; pwr_sClass_ChanAo *cop; pwr_sClass_Ao *sop; pwr_tFloat32 value; int fixout; pwr_tUInt16 data; pwr_tFloat32 rawvalue; qbus_io_write wb; int sts; pwr_tTime now; local = (io_sLocal *) cp->Local; op = (pwr_sClass_Ao_HVAO4 *) cp->op; fixout = ctx->Node->EmergBreakTrue && ctx->Node->EmergBreakSelect == FIXOUT; chanp = &cp->chanlist[0]; for ( i = 0; i < cp->ChanListSize; i++) { if ( !chanp->cop) { chanp++; continue; } cop = (pwr_sClass_ChanAo *) chanp->cop; sop = (pwr_sClass_Ao *) chanp->sop; if ( *(pwr_tFloat32 *)chanp->vbp != local->OldValue[i] || local->WriteFirst > 0 || cop->CalculateNewCoef || fixout || cop->TestOn || local->OldTestOn[i] != cop->TestOn) { if ( fixout) value = cop->FixedOutValue; else if ( cop->TestOn) value = cop->TestValue; else value = *(pwr_tFloat32 *) chanp->vbp; if ( cop->CalculateNewCoef) AoRangeToCoef( chanp); /* Convert to rawvalue */ if ( value > cop->ActValRangeHigh) value = cop->ActValRangeHigh; else if ( value < cop->ActValRangeLow) value = cop->ActValRangeLow; rawvalue = cop->OutPolyCoef1 * value + cop->OutPolyCoef0; if ( rawvalue > 0) sop->RawValue = rawvalue + 0.5; else sop->RawValue = rawvalue - 0.5; data = sop->RawValue; #if defined(OS_ELN) vaxc$establish(machfailwrite); #endif if (r_local->Qbus_fp != 0 && r_local->s == 0) { wb.Data = data; wb.Address = local->Address + 2*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 + 2*i), data); sts = 1; } if ( sts == -1) { /* Exceptionhandler was called */ #if 0 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; } chanp++; continue; } else local->OldValue[i] = value; } local->OldTestOn[i] = cop->TestOn; chanp++; } if ( local->WriteFirst) local->WriteFirst--; 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; }
/*----------------------------------------------------------------------------*\ \*----------------------------------------------------------------------------*/ 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_sClass_Ssab_BaseACard *op; int i; io_sChannel *chanp; pwr_sClass_ChanAo *cop; pwr_sClass_Ao *sop; pwr_tFloat32 value; int fixout; pwr_tUInt16 data; pwr_tFloat32 rawvalue; qbus_io_write wb; int sts; int bfb_error = 0; pwr_sClass_Ssab_RemoteRack *rrp; int remote; local = (io_sLocal *) cp->Local; op = (pwr_sClass_Ssab_BaseACard *) cp->op; fixout = ctx->Node->EmergBreakTrue && ctx->Node->EmergBreakSelect == FIXOUT; remote = !r_local->Qbus_fp && r_local->s; chanp = &cp->chanlist[0]; for ( i = 0; i < cp->ChanListSize; i++) { if ( !chanp->cop || !chanp->sop) { chanp++; continue; } cop = (pwr_sClass_ChanAo *) chanp->cop; sop = (pwr_sClass_Ao *) chanp->sop; /* Error handling for remote rack */ if ( remote) { sts = 0; if ( local->CheckWrite[i]) { local->CheckWrite[i] = 0; bfbeth_get_write_status(r_local, (pwr_tUInt16) (local->Address + 2*i), &sts); 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); ctx->IOHandler->CardErrorSoftLimit = 1; ctx->IOHandler->ErrorSoftLimitObject = cdh_ObjidToAref( cp->Objid); } if ( op->ErrorCount == op->ErrorHardLimit) { errh_Error( "IO Error hard limit reached on card '%s', stall action %d", cp->Name, rrp->StallAction); ctx->IOHandler->CardErrorHardLimit = 1; ctx->IOHandler->ErrorHardLimitObject = cdh_ObjidToAref( cp->Objid); } 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; } } } } } /* Convert and write */ if ( *(pwr_tFloat32 *)chanp->vbp != local->OldValue[i] || local->WriteFirst > 0 || cop->CalculateNewCoef || fixout || cop->TestOn || local->OldTestOn[i] != cop->TestOn) { if ( fixout) value = cop->FixedOutValue; else if ( cop->TestOn) value = cop->TestValue; else value = *(pwr_tFloat32 *) chanp->vbp; if ( cop->CalculateNewCoef) AoRangeToCoef( chanp); /* Convert to rawvalue */ if ( value > cop->ActValRangeHigh) value = cop->ActValRangeHigh; else if ( value < cop->ActValRangeLow) value = cop->ActValRangeLow; rawvalue = cop->OutPolyCoef1 * value + cop->OutPolyCoef0; if ( rawvalue > 0) sop->RawValue = rawvalue + 0.5; else sop->RawValue = rawvalue - 0.5; data = sop->RawValue; if ( !remote) { wb.Data = data; wb.Address = local->Address + 2*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 + 2*i), data); local->CheckWrite[i] = 1; if ( sts == 1) { op->ErrorCount = 0; local->OldValue[i] = value; local->OldTestOn[i] = cop->TestOn; } chanp++; continue; } /* Error handling for local rack */ if ( sts == -1) { /* Exceptionhandler was called */ #if 0 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); ctx->IOHandler->CardErrorSoftLimit = 1; ctx->IOHandler->ErrorSoftLimitObject = cdh_ObjidToAref( cp->Objid); } if ( op->ErrorCount >= op->ErrorHardLimit) { errh_Error( "IO Error hard limit reached on card '%s', IO stopped", cp->Name); ctx->Node->EmergBreakTrue = 1; ctx->IOHandler->CardErrorHardLimit = 1; ctx->IOHandler->ErrorHardLimitObject = cdh_ObjidToAref( cp->Objid); return IO__ERRDEVICE; } chanp++; continue; } else local->OldValue[i] = value; } local->OldTestOn[i] = cop->TestOn; chanp++; } if ( local->WriteFirst) local->WriteFirst--; if ( local->FirstScan) local->FirstScan = 0; /* Fix for qbus errors */ local->ErrScanCnt++; if ( local->ErrScanCnt >= local->ErrReset) { local->ErrScanCnt = 0; if ( op->ErrorCount > op->ErrorSoftLimit) op->ErrorCount--; } return 1; }