void evgMrm::init_cb(CALLBACK *ptr, int priority, void(*fn)(CALLBACK*), void* valptr) { callbackSetPriority(priority, ptr); callbackSetCallback(fn, ptr); callbackSetUser(valptr, ptr); (ptr)->timer=NULL; }
static long init_record(aiRecord *pao) { struct prngState* priv; unsigned long start; priv=malloc(sizeof(struct prngState)); if(!priv){ recGblRecordError(S_db_noMemory, (void*)pao, "devAoTimebase failed to allocate private struct"); return S_db_noMemory; } /* New */ callbackSetCallback(prng_cb,&priv->cb); callbackSetPriority(priorityLow,&priv->cb); callbackSetUser(pao,&priv->cb); priv->cb.timer=NULL; recGblInitConstantLink(&pao->inp,DBF_ULONG,&start); priv->seed=start; pao->dpvt=priv; return 0; }
static void notifyInit(processNotify *ppn) { notifyPvt *pnotifyPvt; pnotifyPvt = (notifyPvt *) ellFirst(&pnotifyGlobal->freeList); if (pnotifyPvt) { ellDelete(&pnotifyGlobal->freeList, &pnotifyPvt->node); } else { pnotifyPvt = dbCalloc(1,sizeof(notifyPvt)); pnotifyPvt->cancelEvent = epicsEventCreate(epicsEventEmpty); pnotifyPvt->userCallbackEvent = epicsEventCreate(epicsEventEmpty); pnotifyPvt->magic = MAGIC; pnotifyPvt->state = notifyNotActive; } pnotifyPvt->state = notifyNotActive; callbackSetCallback(notifyCallback,&pnotifyPvt->callback); callbackSetUser(ppn,&pnotifyPvt->callback); callbackSetPriority(priorityLow,&pnotifyPvt->callback); ellInit(&pnotifyPvt->waitList); ppn->status = notifyOK; ppn->wasProcessed = 0; pnotifyPvt->state = notifyNotActive; pnotifyPvt->cancelWait = pnotifyPvt->userCallbackWait = 0; ppn->pnotifyPvt = pnotifyPvt; }
static void ntpshminit(void*) { ntpShm.ntplock = epicsMutexMustCreate(); callbackSetPriority(priorityLow, &ntpShm.ntpcb); callbackSetCallback(&ntpsetup, &ntpShm.ntpcb); callbackSetUser(0, &ntpShm.ntpcb); }
/*CODE that interacts with drvAb*/ LOCAL void drvCallback(void *drvPvt) { ab1771IXRecord *precord; recordPvt *precordPvt; /*run myCallback under general purpose callback task*/ precord = (*pabDrv->getUserPvt)(drvPvt); precordPvt = precord->dpvt; callbackSetPriority(precord->prio,&precordPvt->callback); callbackRequest(&precordPvt->callback); }
long asSubProcess(subRecord *precord) { ASDBCALLBACK *pcallback = (ASDBCALLBACK *)precord->dpvt; if(!precord->pact && precord->val==1.0) { db_post_events(precord,&precord->val,DBE_VALUE); callbackSetPriority(precord->prio,&pcallback->callback); asInitAsyn(pcallback); precord->pact=TRUE; return(1); } db_post_events(precord,&precord->val,DBE_VALUE); return(0); }
/***************************************************************************** * * Initialize a sequence record. * * Allocate the callback request structure (tacked on dpvt.) * Initialize watch-dog ID * Initialize SELN based on the link-type of SELL * If SELL is a CA_LINK, inform CA about it * For each constant input link, fill in the DOV field * ******************************************************************************/ static long init_record(seqRecord *prec, int pass) { int index; linkDesc *plink; callbackSeq *pcallbackSeq; if (pass==0) return(0); if (seqRecDebug > 5) printf("init_record(%s) entered\n", prec->name); /* Allocate a callback structure for use in processing */ pcallbackSeq = (callbackSeq *)calloc(1,sizeof(callbackSeq)); pcallbackSeq->pseqRecord = prec; callbackSetCallback(processCallback,&pcallbackSeq->callback); callbackSetUser(pcallbackSeq,&pcallbackSeq->callback); callbackSetPriority(prec->prio,&pcallbackSeq->callback); prec->dpvt = (void *)pcallbackSeq; /* Get link selection if sell is a constant and nonzero */ if (prec->sell.type==CONSTANT) { if (seqRecDebug > 5) printf("init_record(%s) SELL is a constant\n", prec->name); recGblInitConstantLink(&prec->sell,DBF_USHORT,&prec->seln); } /* Copy over ALL the input link constants here */ plink = (linkDesc *)(&(prec->dly1)); index = 0; while (index < NUM_LINKS) { if (plink->dol.type == CONSTANT) recGblInitConstantLink(&plink->dol,DBF_DOUBLE,&plink->dov); index++; plink++; } return(0); }
static void myCallbackFunc(CALLBACK *arg) { myCallback *pcallback; boRecord *prec; callbackGetUser(pcallback,arg); prec=(boRecord *)pcallback->precord; dbScanLock((struct dbCommon *)prec); if(prec->pact) { if((prec->val==1) && (prec->high>0)){ myCallback *pcallback; pcallback = (myCallback *)(prec->rpvt); callbackSetPriority(prec->prio, &pcallback->callback); callbackRequestDelayed(&pcallback->callback,(double)prec->high); } } else { prec->val = 0; dbProcess((struct dbCommon *)prec); } dbScanUnlock((struct dbCommon *)prec); }
void scanIoInit(IOSCANPVT *pioscanpvt) { ioscan_head *piosh = dbCalloc(1, sizeof(ioscan_head)); int prio; ioscanInit(); for (prio = 0; prio < NUM_CALLBACK_PRIORITIES; prio++) { io_scan_list *piosl = &piosh->iosl[prio]; callbackSetCallback(ioscanCallback, &piosl->callback); callbackSetPriority(prio, &piosl->callback); callbackSetUser(piosh, &piosl->callback); ellInit(&piosl->scan_list.list); piosl->scan_list.lock = epicsMutexMustCreate(); } epicsMutexMustLock(ioscan_lock); piosh->next = pioscan_list; pioscan_list = piosh; epicsMutexUnlock(ioscan_lock); *pioscanpvt = piosh; }
event_list *eventNameToHandle(const char *eventname) { int prio; event_list *pel; static epicsThreadOnceId onceId = EPICS_THREAD_ONCE_INIT; if (!eventname || eventname[0] == 0) return NULL; epicsThreadOnce(&onceId, eventOnce, NULL); epicsMutexMustLock(event_lock); for (pel = pevent_list[0]; pel; pel=pel->next) { if (strcmp(pel->event_name, eventname) == 0) break; } if (pel == NULL) { pel = dbCalloc(1, sizeof(event_list)); strcpy(pel->event_name, eventname); for (prio = 0; prio < NUM_CALLBACK_PRIORITIES; prio++) { callbackSetUser(&pel->scan_list[prio], &pel->callback[prio]); callbackSetPriority(prio, &pel->callback[prio]); callbackSetCallback(eventCallback, &pel->callback[prio]); pel->scan_list[prio].lock = epicsMutexMustCreate(); ellInit(&pel->scan_list[prio].list); } pel->next=pevent_list[0]; pevent_list[0]=pel; { /* backward compatibility */ char* p; long e = strtol(eventname, &p, 0); if (*p == 0 && e > 0 && e <= 255) pevent_list[e] = pel; } } epicsMutexUnlock(event_lock); return pel; }
void callbackSetProcess(CALLBACK *pcallback, int Priority, void *pRec) { callbackSetCallback(ProcessCallback, pcallback); callbackSetPriority(Priority, pcallback); callbackSetUser(pRec, pcallback); }
static long init_record(acalcoutRecord *pcalc, int pass) { DBLINK *plink; int i; double *pvalue; unsigned short *plinkValid; short error_number; acalcoutDSET *pacalcoutDSET; dbAddr Addr; dbAddr *pAddr = &Addr; rpvtStruct *prpvt; if (pass==0) { pcalc->vers = VERSION; pcalc->rpvt = (void *)calloc(1, sizeof(struct rpvtStruct)); if ((pcalc->nuse < 0) || (pcalc->nuse > pcalc->nelm)) { pcalc->nuse = pcalc->nelm; db_post_events(pcalc,&pcalc->nuse,DBE_VALUE|DBE_LOG); } return(0); } if (!(pacalcoutDSET = (acalcoutDSET *)pcalc->dset)) { recGblRecordError(S_dev_noDSET,(void *)pcalc,"acalcout:init_record"); return(S_dev_noDSET); } /* must have write defined */ if ((pacalcoutDSET->number < 5) || (pacalcoutDSET->write == NULL)) { recGblRecordError(S_dev_missingSup,(void *)pcalc,"acalcout:init_record"); return(S_dev_missingSup); } prpvt = (rpvtStruct *)pcalc->rpvt; plink = &pcalc->inpa; pvalue = &pcalc->a; plinkValid = &pcalc->inav; for (i=0; i<(MAX_FIELDS+ARRAY_MAX_FIELDS+1); i++, plink++, pvalue++, plinkValid++) { if (plink->type == CONSTANT) { /* Don't InitConstantLink the array links or the output link. */ if (i < MAX_FIELDS) { recGblInitConstantLink(plink,DBF_DOUBLE,pvalue); db_post_events(pcalc,pvalue,DBE_VALUE); } *plinkValid = acalcoutINAV_CON; if (plink == &pcalc->out) prpvt->outlink_field_type = DBF_NOACCESS; } else if (!dbNameToAddr(plink->value.pv_link.pvname, pAddr)) { /* the PV we're linked to resides on this ioc */ *plinkValid = acalcoutINAV_LOC; if (plink == &pcalc->out) { prpvt->outlink_field_type = pAddr->field_type; if ((pAddr->field_type >= DBF_INLINK) && (pAddr->field_type <= DBF_FWDLINK)) { if (!(plink->value.pv_link.pvlMask & pvlOptCA)) { printf("aCalcoutRecord(%s):init_record:non-CA link to link field\n", plink->value.pv_link.pvname); } } if (pcalc->wait && !(plink->value.pv_link.pvlMask & pvlOptCA)) { printf("aCalcoutRecord(%s):init_record: Can't wait with non-CA link attribute\n", plink->value.pv_link.pvname); } } } else { /* pv is not on this ioc. Callback later for connection stat */ *plinkValid = acalcoutINAV_EXT_NC; prpvt->caLinkStat = CA_LINKS_NOT_OK; if (plink == &pcalc->out) prpvt->outlink_field_type = DBF_NOACCESS; /* don't know field type */ } db_post_events(pcalc,plinkValid,DBE_VALUE); } pcalc->clcv = aCalcPostfix(pcalc->calc,pcalc->rpcl,&error_number); if (pcalc->clcv) { recGblRecordError(S_db_badField,(void *)pcalc, "acalcout: init_record: Illegal CALC field"); if (aCalcoutRecordDebug >= 10) printf("acalcPostfix returns: %d\n", error_number); } db_post_events(pcalc,&pcalc->clcv,DBE_VALUE); pcalc->oclv = aCalcPostfix(pcalc->ocal, pcalc->orpc,&error_number); if (pcalc->oclv) { recGblRecordError(S_db_badField,(void *)pcalc, "acalcout: init_record: Illegal OCAL field"); if (aCalcoutRecordDebug >= 10) printf("acalcPostfix returns: %d\n", error_number); } db_post_events(pcalc,&pcalc->oclv,DBE_VALUE); callbackSetCallback(checkLinksCallback, &prpvt->checkLinkCb); callbackSetPriority(0, &prpvt->checkLinkCb); callbackSetUser(pcalc, &prpvt->checkLinkCb); prpvt->wd_id_1_LOCK = 0; if (prpvt->caLinkStat == CA_LINKS_NOT_OK) { callbackRequestDelayed(&prpvt->checkLinkCb,1.0); prpvt->wd_id_1_LOCK = 1; } if (pacalcoutDSET->init_record ) { return (*pacalcoutDSET->init_record)(pcalc); } return(0); }
static long initCommon(dbCommon *pr, DBLINK *plink, userCallback processCallback,interruptCallbackFloat64 interruptCallback) { devPvt *pPvt; asynStatus status; asynUser *pasynUser; asynInterface *pasynInterface; static const char *functionName="initCommon"; pPvt = callocMustSucceed(1, sizeof(*pPvt), "%s::%s"); pr->dpvt = pPvt; pPvt->pr = pr; /* Create asynUser */ pasynUser = pasynManager->createAsynUser(processCallback, 0); pasynUser->userPvt = pPvt; pPvt->pasynUser = pasynUser; pPvt->devPvtLock = epicsMutexCreate(); /* Parse the link to get addr and port */ status = pasynEpicsUtils->parseLink(pasynUser, plink, &pPvt->portName, &pPvt->addr,&pPvt->userParam); if (status != asynSuccess) { printf("%s %s::%s %s\n", pr->name, driverName, functionName,pasynUser->errorMessage); goto bad; } /* Connect to device */ status = pasynManager->connectDevice(pasynUser, pPvt->portName, pPvt->addr); if (status != asynSuccess) { printf("%s %s::%s connectDevice failed %s\n", pr->name, driverName, functionName,pasynUser->errorMessage); goto bad; } status = pasynManager->canBlock(pPvt->pasynUser, &pPvt->canBlock); if (status != asynSuccess) { printf("%s %s::%s canBlock failed %s\n", pr->name, driverName, functionName,pasynUser->errorMessage); goto bad; } /*call drvUserCreate*/ pasynInterface = pasynManager->findInterface(pasynUser,asynDrvUserType,1); if(pasynInterface && pPvt->userParam) { asynDrvUser *pasynDrvUser; void *drvPvt; pasynDrvUser = (asynDrvUser *)pasynInterface->pinterface; drvPvt = pasynInterface->drvPvt; status = pasynDrvUser->create(drvPvt,pasynUser,pPvt->userParam,0,0); if(status!=asynSuccess) { printf("%s %s::%s drvUserCreate %s\n", pr->name, driverName, functionName,pasynUser->errorMessage); goto bad; } } /* Get interface asynFloat64 */ pasynInterface = pasynManager->findInterface(pasynUser, asynFloat64Type, 1); if (!pasynInterface) { printf("%s %s::%s findInterface asynFloat64Type %s\n", pr->name, driverName, functionName,pasynUser->errorMessage); goto bad; } pPvt->pfloat64 = pasynInterface->pinterface; pPvt->float64Pvt = pasynInterface->drvPvt; /* Initialize synchronous interface */ status = pasynFloat64SyncIO->connect(pPvt->portName, pPvt->addr, &pPvt->pasynUserSync, pPvt->userParam); if (status != asynSuccess) { printf("%s %s::%s Float64SyncIO->connect failed %s\n", pr->name, driverName, functionName,pPvt->pasynUserSync->errorMessage); goto bad; } scanIoInit(&pPvt->ioScanPvt); pPvt->interruptCallback = interruptCallback; /* If the info field "asyn:READBACK" is 1 and interruptCallback is not NULL * then register for callbacks on output records */ if (interruptCallback) { int enableCallbacks=0; const char *callbackString; DBENTRY *pdbentry = dbAllocEntry(pdbbase); status = dbFindRecord(pdbentry, pr->name); if (status) { asynPrint(pPvt->pasynUser, ASYN_TRACE_ERROR, "%s %s::%s error finding record\n", pr->name, driverName, functionName); goto bad; } callbackString = dbGetInfo(pdbentry, "asyn:READBACK"); if (callbackString) enableCallbacks = atoi(callbackString); if (enableCallbacks) { status = createRingBuffer(pr); if (status!=asynSuccess) goto bad; status = pPvt->pfloat64->registerInterruptUser( pPvt->float64Pvt,pPvt->pasynUser, pPvt->interruptCallback,pPvt,&pPvt->registrarPvt); if(status!=asynSuccess) { printf("%s %s::initRecord error calling registerInterruptUser %s\n", pr->name, driverName,pPvt->pasynUser->errorMessage); } /* Initialize the interrupt callback */ callbackSetCallback(outputCallbackCallback, &pPvt->outputCallback); callbackSetPriority(pr->prio, &pPvt->outputCallback); callbackSetUser(pPvt, &pPvt->outputCallback); } } return INIT_OK; bad: recGblSetSevr(pr,LINK_ALARM,INVALID_ALARM); pr->pact=1; return INIT_ERROR; }
static long init_record(calcoutRecord *prec, int pass) { DBLINK *plink; int i; double *pvalue; epicsEnum16 *plinkValid; short error_number; calcoutDSET *pcalcoutDSET; DBADDR dbaddr; DBADDR *pAddr = &dbaddr; rpvtStruct *prpvt; if (pass == 0) { prec->rpvt = (rpvtStruct *) callocMustSucceed(1, sizeof(rpvtStruct), "calcoutRecord"); return 0; } if (!(pcalcoutDSET = (calcoutDSET *)prec->dset)) { recGblRecordError(S_dev_noDSET, (void *)prec, "calcout:init_record"); return S_dev_noDSET; } /* must have write defined */ if ((pcalcoutDSET->number < 5) || (pcalcoutDSET->write ==NULL)) { recGblRecordError(S_dev_missingSup, (void *)prec, "calcout:init_record"); return S_dev_missingSup; } prpvt = prec->rpvt; plink = &prec->inpa; pvalue = &prec->a; plinkValid = &prec->inav; for (i = 0; i <= CALCPERFORM_NARGS; i++, plink++, pvalue++, plinkValid++) { if (plink->type == CONSTANT) { /* Don't InitConstantLink the .OUT link */ if (i < CALCPERFORM_NARGS) { recGblInitConstantLink(plink, DBF_DOUBLE, pvalue); } *plinkValid = calcoutINAV_CON; } else if (!dbNameToAddr(plink->value.pv_link.pvname, pAddr)) { /* PV resides on this ioc */ *plinkValid = calcoutINAV_LOC; } else { /* pv is not on this ioc. Callback later for connection stat */ *plinkValid = calcoutINAV_EXT_NC; prpvt->caLinkStat = CA_LINKS_NOT_OK; } } prec->clcv = postfix(prec->calc, prec->rpcl, &error_number); if (prec->clcv){ recGblRecordError(S_db_badField, (void *)prec, "calcout: init_record: Illegal CALC field"); errlogPrintf("%s.CALC: %s in expression \"%s\"\n", prec->name, calcErrorStr(error_number), prec->calc); } prec->oclv = postfix(prec->ocal, prec->orpc, &error_number); if (prec->dopt == calcoutDOPT_Use_OVAL && prec->oclv){ recGblRecordError(S_db_badField, (void *)prec, "calcout: init_record: Illegal OCAL field"); errlogPrintf("%s.OCAL: %s in expression \"%s\"\n", prec->name, calcErrorStr(error_number), prec->ocal); } prpvt = prec->rpvt; callbackSetCallback(checkLinksCallback, &prpvt->checkLinkCb); callbackSetPriority(0, &prpvt->checkLinkCb); callbackSetUser(prec, &prpvt->checkLinkCb); prpvt->cbScheduled = 0; prec->epvt = eventNameToHandle(prec->oevt); if (pcalcoutDSET->init_record) pcalcoutDSET->init_record(prec); prec->pval = prec->val; prec->mlst = prec->val; prec->alst = prec->val; prec->lalm = prec->val; prec->povl = prec->oval; return 0; }
void xycom566setup( int id, int cbase, int dbase, int level, int vec, int bipol ){ xy566 *card; volatile epicsUInt8 **cb; volatile epicsUInt16 **db; epicsUInt16 junk; if(cbase<0 || cbase>0xffff){ printf("config (A16) out of range\n"); return; } if(dbase<0 || dbase>0xffffff){ printf("data (A24) out of range\n"); return; } if(level<0 || level>7){ printf("Level out of range (0->7)\n"); return; } if(vec<0 || vec>0xff){ printf("Vector out of range (0->255)\n"); return; } card=get566(id); if(!!card){ printf("ID %d already exists\n",id); return; } card=malloc(sizeof(xy566)); if(!card){ printf("Out of memory!\n"); return; } memset(&card->dlen,0,sizeof(card->dlen)); memset(&card->cb_irq,0,sizeof(card->cb_irq)); card->id=id; card->fail=0; card->clk_div=0; /* stc uninitialized */ card->use_seq_clk=0; ellInit(&card->seq_ctor); if(!bipol) card->nchan=32; else card->nchan=16; card->ivec=vec; card->base_addr=cbase; card->data_addr=dbase; cb=&card->base; db=&card->data_base; if(devBusToLocalAddr(atVMEA16, card->base_addr, (volatile void **)cb)){ printf("Failed to map A16 %lx for card %x\n", (unsigned long)card->base_addr,id); free(card); return; } if(devBusToLocalAddr(atVMEA24, card->data_addr, (volatile void **)db)){ printf("Failed to map A24 %lx for card %x\n", (unsigned long)card->data_base,id); free(card); return; } if(devReadProbe(2, card->base+U16_XY566_CSR, &junk)){ printf("Failed to read A16 %lx for card %x\n", (unsigned long)(card->base+U16_XY566_CSR),id); free(card); return; } if(devReadProbe(2, card->data_base, &junk)){ printf("Failed to read A24 %lx for card %x\n", (unsigned long)(card->data_base),id); free(card); return; } WRITE16(card->base, XY566_CSR, XY566_CSR_RST); /* Reset */ /* turn on green and red to indicate init start */ WRITE16(card->base, XY566_CSR, XY566_CSR_GRN); WRITE16(card->base, XY566_RAM, 0); WRITE8(card->base, XY566_SEQ, 0); card->guard=epicsMutexMustCreate(); scanIoInit(&card->seq_irq); callbackSetCallback(xycom566isrcb, &card->cb_irq); callbackSetPriority(priorityHigh, &card->cb_irq); callbackSetUser(card, &card->cb_irq); WRITE8(card->base, XY566_VEC, vec); devEnableInterruptLevelVME(level); assert(devConnectInterruptVME(vec, xycom566isr, card)==0); /* Configure card * Mode: continuous sequence (default) * 16 bit conversion (default) * sequence controller disable (will be enabled during drvsup init) */ WRITE16(card->base, XY566_CSR, XY566_CSR_GRN); ellAdd(&xy566s,&card->node); }
/***************************************************************************** * * Process a sequence record. * * If is async completion phase * call asyncFinish() to finish things up * else * figure out selection mechanism * build the correct mask value using the mode and the selection value * build a list of pointers to the selected link-group structures * If there are no links to process * call asyncFinish() to finish things up * else * call processNextLink() to schecule a delay for the first link-group * * * NOTE: * dbScanLock is already held for prec before this function is called. * * We do NOT call processNextLink() if there is nothing to do, this prevents * us from calling dbProcess() recursively. * ******************************************************************************/ static long process(seqRecord *prec) { callbackSeq *pcb = (callbackSeq *) (prec->dpvt); linkDesc *plink; unsigned short lmask; int tmp; if(seqRecDebug > 10) printf("seqRecord: process(%s) pact = %d\n", prec->name, prec->pact); if (prec->pact) { /* In async completion phase */ asyncFinish(prec); return(0); } prec->pact = TRUE; /* Reset the PRIO in case it was changed */ callbackSetPriority(prec->prio,&pcb->callback); /* * We should not bother supporting seqSELM_All or seqSELM_Specified * they can both be supported by simply providing seqSELM_Mask. * build the proper mask using these other silly modes if necessary. */ if (prec->selm == seqSELM_All) { lmask = (unsigned short) SELN_BIT_MASK; } else { /* Fill in the SELN field */ if (prec->sell.type != CONSTANT) { dbGetLink(&(prec->sell), DBR_USHORT, &(prec->seln), 0,0); } if (prec->selm == seqSELM_Specified) { if(prec->seln>10) { /* Invalid selection number */ recGblSetSevr(prec,SOFT_ALARM,INVALID_ALARM); return(asyncFinish(prec)); } if (prec->seln == 0) return(asyncFinish(prec)); /* Nothing selected */ lmask = 1; lmask <<= prec->seln - 1; } else if (prec->selm == seqSELM_Mask) { lmask = (prec->seln) & SELN_BIT_MASK; } else { /* Invalid selection option */ recGblSetSevr(prec,SOFT_ALARM,INVALID_ALARM); return(asyncFinish(prec)); } } /* Figure out which links are going to be processed */ pcb->index = 0; plink = (linkDesc *)(&(prec->dly1)); tmp = 1; while (lmask) { if (seqRecDebug > 4) printf("seqRec-process Checking link %d - lnk %d dol %d\n", tmp, plink->lnk.type, plink->dol.type); if ((lmask & 1) && ((plink->lnk.type != CONSTANT)||(plink->dol.type != CONSTANT))) { if (seqRecDebug > 4) printf(" seqRec-process Adding link %d at index %d\n", tmp, pcb->index); pcb->plinks[pcb->index] = plink; pcb->index++; } lmask >>= 1; plink++; tmp++; } pcb->plinks[pcb->index] = NULL; /* mark the bottom of the list */ if (!pcb->index) { /* There was nothing to do, finish record processing here */ return(asyncFinish(prec)); } pcb->index = 0; /* Start doing the first forward link (We have at least one for sure) */ processNextLink(prec); return(0); }
static long process(boRecord *prec) { struct bodset *pdset = (struct bodset *)(prec->dset); long status=0; unsigned char pact=prec->pact; if( (pdset==NULL) || (pdset->write_bo==NULL) ) { prec->pact=TRUE; recGblRecordError(S_dev_missingSup,(void *)prec,"write_bo"); return(S_dev_missingSup); } if (!prec->pact) { if ((prec->dol.type != CONSTANT) && (prec->omsl == menuOmslclosed_loop)){ unsigned short val; prec->pact = TRUE; status=dbGetLink(&prec->dol,DBR_USHORT, &val,0,0); prec->pact = FALSE; if(status==0){ prec->val = val; prec->udf = FALSE; }else { recGblSetSevr(prec,LINK_ALARM,INVALID_ALARM); } } /* convert val to rval */ if ( prec->mask != 0 ) { if(prec->val==0) prec->rval = 0; else prec->rval = prec->mask; } else prec->rval = (epicsUInt32)prec->val; } /* check for alarms */ checkAlarms(prec); if (prec->nsev < INVALID_ALARM ) status=writeValue(prec); /* write the new value */ else { switch (prec->ivoa) { case (menuIvoaContinue_normally) : status=writeValue(prec); /* write the new value */ break; case (menuIvoaDon_t_drive_outputs) : break; case (menuIvoaSet_output_to_IVOV) : if(prec->pact == FALSE){ /* convert val to rval */ prec->val=prec->ivov; if ( prec->mask != 0 ) { if(prec->val==0) prec->rval = 0; else prec->rval = prec->mask; } else prec->rval = (epicsUInt32)prec->val; } status=writeValue(prec); /* write the new value */ break; default : status=-1; recGblRecordError(S_db_badField,(void *)prec, "bo:process Illegal IVOA field"); } } /* check if device support set pact */ if ( !pact && prec->pact ) return(0); prec->pact = TRUE; recGblGetTimeStamp(prec); if((prec->val==1) && (prec->high>0)){ myCallback *pcallback; pcallback = (myCallback *)(prec->rpvt); callbackSetPriority(prec->prio, &pcallback->callback); callbackRequestDelayed(&pcallback->callback,(double)prec->high); } /* check event list */ monitor(prec); /* process the forward scan link record */ recGblFwdLink(prec); prec->pact=FALSE; return(status); }