/*----------------------------------------------------------------------------*\ \*----------------------------------------------------------------------------*/ static pwr_tStatus IoCardRead ( 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_BaseDiCard *op; pwr_sClass_Ssab_RemoteRack *rrp; pwr_tUInt16 invmask; pwr_tUInt16 convmask; int i; int sts; qbus_io_read rb; int bfb_error = 0; pwr_tTime now; local = (io_sLocal *) cp->Local; op = (pwr_sClass_Ssab_BaseDiCard *) cp->op; for ( i = 0; i < 2; i++) { if ( i == 0) { convmask = op->ConvMask1; invmask = op->InvMask1; } else { convmask = op->ConvMask2; invmask = op->InvMask2; if ( !convmask) break; if ( op->MaxNoOfChannels == 16) break; } if (r_local->Qbus_fp != 0 && r_local->s == 0) { /* Read from local Q-bus */ rb.Address = local->Address[i]; sts = read( local->Qbus_fp, &rb, sizeof(rb)); data = (unsigned short) rb.Data; } else { /* Ethernet I/O, Get data from current address */ data = bfbeth_get_data(r_local, (pwr_tUInt16) local->Address[i], &sts); /* Yes, we want to read this address the next time aswell */ bfbeth_set_read_req(r_local, (pwr_tUInt16) local->Address[i]); 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 ) { data = 0; sts = 1; } if ( op->ErrorCount >= op->ErrorHardLimit && rrp->StallAction == pwr_eSsabStallAction_EmergencyBreak ) { ctx->Node->EmergBreakTrue = 1; return IO__ERRDEVICE; } } if (sts == -1) continue; } else { op->ErrorCount = 0; } } if ( sts == -1) /* Error handling for local Qbus-I/O */ { /* 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; } /* Invert */ data = data ^ invmask; /* Filter ... */ if ( local->Filter[i].Found) io_DiFilter( local->Filter[i].sop, &data, local->Filter[i].Data); /* Move data to valuebase */ io_DiUnpackWord( cp, data, convmask, i); } return 1; }
/*----------------------------------------------------------------------------*\ \*----------------------------------------------------------------------------*/ static pwr_tStatus IoCardRead ( io_tCtx ctx, io_sAgent *ap, io_sRack *rp, io_sCard *cp ) { io_sLocal *local; pwr_tUInt16 data = 0; pwr_sClass_Di_DIX2 *op; pwr_tUInt16 invmask; pwr_tUInt16 convmask; int i; int sts; qbus_io_read rb; local = (io_sLocal *) cp->Local; op = (pwr_sClass_Di_DIX2 *) cp->op; for ( i = 0; i < 2; i++) { if ( i == 0) { convmask = op->ConvMask1; invmask = op->InvMask1; } else { convmask = op->ConvMask2; invmask = op->InvMask2; if ( !convmask) break; if ( op->MaxNoOfChannels == 16) break; } #if defined(OS_ELN) vaxc$establish(machfailread); #endif rb.Address = local->Address[i]; sts = read( local->Qbus_fp, &rb, sizeof(rb)); data = (unsigned short) rb.Data; if ( sts == -1) { #if 0 /* Exceptionhandler was called */ 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 */ 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; } /* Invert */ data = data ^ invmask; /* Filter ... */ if ( local->Filter[i].Found) io_DiFilter( local->Filter[i].sop, &data, local->Filter[i].Data); /* Move data to valuebase */ io_DiUnpackWord( cp, data, convmask, i); } return 1; }