Changes for dynamic link modification
This commit is contained in:
@@ -5,6 +5,7 @@ include $(EPICS)/config/CONFIG_BASE
|
||||
INC += drvTS.h
|
||||
INC += drvSup.h
|
||||
INC += callback.h
|
||||
INC += dbLock.h
|
||||
INC += dbAccess.h
|
||||
INC += dbConvert.h
|
||||
INC += dbEvent.h
|
||||
|
||||
+6
-4
@@ -25,6 +25,7 @@ DBINSTALL += epics.db
|
||||
DBINSTALL += epicsLIBOBJS
|
||||
|
||||
SRCS.c = \
|
||||
../dbLock.c\
|
||||
../dbAccess.c\
|
||||
../dbBkpt.c\
|
||||
../dbConvert.c\
|
||||
@@ -40,12 +41,13 @@ SRCS.c = \
|
||||
../recGbl.c\
|
||||
../callback.c\
|
||||
../taskwd.c \
|
||||
../dbCaLink.c\
|
||||
../dbCaDblink.c\
|
||||
../dbCa.c\
|
||||
../dbcal.c\
|
||||
../devLib.c\
|
||||
../initHooks.c
|
||||
|
||||
LIBOBJS = \
|
||||
dbLock.o\
|
||||
dbAccess.o\
|
||||
dbBkpt.o\
|
||||
dbConvert.o\
|
||||
@@ -61,8 +63,8 @@ LIBOBJS = \
|
||||
recGbl.o\
|
||||
callback.o\
|
||||
taskwd.o\
|
||||
dbCaLink.o \
|
||||
dbCaDblink.o\
|
||||
dbCa.o \
|
||||
dbcal.o \
|
||||
devLib.o
|
||||
|
||||
PROD = initHooks.o
|
||||
|
||||
+5
-1
@@ -48,6 +48,7 @@
|
||||
#include <taskwd.h>
|
||||
#include <errMdef.h>
|
||||
#include <dbCommon.h>
|
||||
#include <dbLock.h>
|
||||
#include <task_params.h>
|
||||
|
||||
#define QUEUESIZE 1000
|
||||
@@ -129,9 +130,11 @@ void callbackRequest(CALLBACK *pcallback)
|
||||
}
|
||||
}
|
||||
|
||||
static char *priorityName[3] = {"Low","Medium","High"};
|
||||
static void start(int ind)
|
||||
{
|
||||
int priority;
|
||||
char taskName[20];
|
||||
|
||||
if((callbackSem[ind] = semBCreate(SEM_Q_FIFO,SEM_EMPTY))==NULL)
|
||||
errMessage(0,"semBcreate failed while starting a callback task\n");
|
||||
@@ -144,7 +147,8 @@ static void start(int ind)
|
||||
}
|
||||
if((callbackQ[ind] = rngCreate(sizeof(CALLBACK *) * QUEUESIZE)) == NULL)
|
||||
errMessage(0,"rngCreate failed while starting a callback task");
|
||||
callbackTaskId[ind] = taskSpawn(CALLBACK_NAME,priority,
|
||||
sprintf(taskName,"cb%s",priorityName[ind]);
|
||||
callbackTaskId[ind] = taskSpawn(taskName,priority,
|
||||
CALLBACK_OPT,CALLBACK_STACK,
|
||||
(FUNCPTR)callbackTask,ind,
|
||||
0,0,0,0,0,0,0,0,0);
|
||||
|
||||
+642
-775
File diff suppressed because it is too large
Load Diff
+48
-37
@@ -36,18 +36,22 @@
|
||||
* .06 02-02-94 mrk added definitions for dbPutNotify
|
||||
* .07 03-18-94 mcn added breakpoint codes, fast link protos
|
||||
*/
|
||||
|
||||
|
||||
#ifndef INCdbAccessh
|
||||
#define INCdbAccessh
|
||||
#include <dbDefs.h>
|
||||
#include <dbBase.h>
|
||||
#include <dbFldTypes.h>
|
||||
#include <link.h>
|
||||
#ifdef vxWorks
|
||||
#include <dbCommon.h>
|
||||
#endif
|
||||
#include <dbLock.h>
|
||||
#include <tsDefs.h>
|
||||
#include <callback.h>
|
||||
#include <ellLib.h>
|
||||
#include <caeventmask.h>
|
||||
|
||||
|
||||
typedef struct dbAddr{
|
||||
struct dbCommon *precord;/* address of record */
|
||||
void *pfield; /* address of field */
|
||||
@@ -251,68 +255,75 @@ struct dbr_alDouble {DBRalDouble};
|
||||
#define S_db_cntCont (M_dbAccess|65) /*Cannot resume dbContTask*/
|
||||
|
||||
/* Global Database Access Routines*/
|
||||
#define dbGetLink(PLNK,DBRTYPE,PBUFFER,OPTIONS,NREQUEST) \
|
||||
(((((PLNK)->type == CONSTANT)&&(!(NREQUEST))) ||\
|
||||
(! (((PLNK)->type == DB_LINK) || ((PLNK)->type == CA_LINK)) ))\
|
||||
? 0\
|
||||
: dbGetLinkValue((PLNK),(DBRTYPE), \
|
||||
(void *)(PBUFFER),(OPTIONS),(NREQUEST)))
|
||||
#define dbPutLink(PLNK,DBRTYPE,PBUFFER,NREQUEST) \
|
||||
((((PLNK)->type == CONSTANT) ||\
|
||||
(! (((PLNK)->type == DB_LINK) || ((PLNK)->type == CA_LINK)) ))\
|
||||
? 0\
|
||||
: dbPutLinkValue((PLNK),(DBRTYPE),(void *)(PBUFFER),(NREQUEST)))
|
||||
#ifdef __STDC__
|
||||
struct rset *dbGetRset(struct dbAddr *paddr);
|
||||
int dbIsValueField(struct dbFldDes *pdbFldDes);
|
||||
int dbGetFieldIndex(struct dbAddr *paddr);
|
||||
long dbCommonInit(struct dbCommon *precord, int pass);
|
||||
void dbScanLock(struct dbCommon *precord);
|
||||
void dbScanUnlock(struct dbCommon *precord);
|
||||
void dbScanLockInit(int nset);
|
||||
long dbScanPassive(struct dbCommon *pfrom,struct dbCommon *pto);
|
||||
long dbProcess(struct dbCommon *precord);
|
||||
long dbNameToAddr(char *pname,struct dbAddr *);
|
||||
long dbGetLink(struct db_link *,struct dbCommon *precord,short dbrType,
|
||||
long dbGetLinkValue(struct link *,short dbrType,
|
||||
void *pbuffer,long *options,long *nRequest);
|
||||
long dbGetField(struct dbAddr *,short dbrType,void *pbuffer,long *options,
|
||||
long *nRequest,void *pfl);
|
||||
long dbGet(struct dbAddr *,short dbrType,void *pbuffer,long *options,
|
||||
long *nRequest,void *pfl);
|
||||
long dbPutLinkValue(struct link *,short dbrType,void *pbuffer,long nRequest);
|
||||
long dbPutField(struct dbAddr *,short dbrType,void *pbuffer,long nRequest);
|
||||
long dbPut(struct dbAddr *,short dbrType,void *pbuffer,long nRequest);
|
||||
long dbPutNotify(PUTNOTIFY *pputnotify);
|
||||
/*dbNotifyAdd called by dbScanPassive and dbScanLink*/
|
||||
void dbNotifyAdd(struct dbCommon *pfrom,struct dbCommon *pto);
|
||||
void dbNotifyCancel(PUTNOTIFY *pputnotify);
|
||||
/*dbNotifyCompletion called by recGblFwdLink and dbProcess */
|
||||
void dbNotifyCompletion(struct dbCommon *precord); /*called only by recGblFwdLink*/
|
||||
long dbPut(struct dbAddr *,short dbrType,void *pbuffer,long nRequest);
|
||||
long dbGetField(struct dbAddr *,short dbrType,void *pbuffer,long *options,long *nRequest,void *pfl);
|
||||
long dbGet(struct dbAddr *,short dbrType,void *pbuffer,long *options,long *nRequest,void *pfl);
|
||||
long dbPutLink(struct db_link *,struct dbCommon *precord,short dbrType,
|
||||
void *pbuffer,long nRequest);
|
||||
/*dbNotifyCompletion called by recGblFwdLink */
|
||||
void dbNotifyCompletion(struct dbCommon *precord);
|
||||
long dbBufferSize(short dbrType,long options,long nRequest);
|
||||
long dbValueSize(short dbrType);
|
||||
|
||||
long dbCaAddInlink(struct link *plink,void *pdest_record,char *dest_fieldname);
|
||||
long dbCaAddOutlink(struct link *plink,void *psource_record,char *source_fieldname);
|
||||
long dbCaPutLink(struct link *plink,long *poptions,long *pnRequest);
|
||||
long dbCaGetLink(struct link *plink);
|
||||
void dbCaLinkInit(int pass);
|
||||
long dbFastLinkGet(struct link *plink, struct dbCommon *precord, void *pdest);
|
||||
long dbFastLinkPut(struct link *plink, struct dbCommon *precord, void *psource);
|
||||
long cvt_uninit(void *from, void *to, struct dbAddr *paddr);
|
||||
long cvt_dummy(void *from, void *to, struct dbAddr *paddr);
|
||||
void dbCaLinkInit(void);
|
||||
void dbCaAddLink(struct link *plink);
|
||||
void dbCaRemoveLink(struct link *plink);
|
||||
long dbCaGetLink(struct link *plink,short dbrType,void *pbuffer,
|
||||
unsigned short *psevr,long *nRequest);
|
||||
long dbCaPutLink(struct link *plink,short dbrType,void *pbuffer,long nRequest);
|
||||
|
||||
long dbScanLink(struct dbCommon *pfrom, struct dbCommon *pto);
|
||||
#else
|
||||
void dbScanLock();
|
||||
void dbScanUnlock();
|
||||
void dbScanLockInit();
|
||||
struct rset *dbGetRset();
|
||||
int dbIsValueField();
|
||||
int dbGetFieldIndex();
|
||||
long dbScanPassive();
|
||||
long dbProcess();
|
||||
long dbNameToAddr();
|
||||
long dbGetLink();
|
||||
long dbGetLinkValue();
|
||||
long dbGetField();
|
||||
long dbGet();
|
||||
long dbPutLinkValue();
|
||||
long dbPutField();
|
||||
long dbPut();
|
||||
long dbGetField();
|
||||
long dbPutLink();
|
||||
long dbPutNotify();
|
||||
void dbNotifyAdd();
|
||||
void dbNotifyCancel();
|
||||
void dbNotifyCompletion();
|
||||
long dbBufferSize();
|
||||
long dbValueSize();
|
||||
long dbCaAddInlink();
|
||||
long dbCaAddOutlink();
|
||||
long dbCaPutLink();
|
||||
void dbCaLinkInit();
|
||||
void dbCaAddLink();
|
||||
void dbCaRemoveLink();
|
||||
long dbCaGetLink();
|
||||
long dbFastLinkGet();
|
||||
long dbFastLinkPut();
|
||||
long cvt_uninit();
|
||||
long cvt_dummy();
|
||||
long dbCaPutLink();
|
||||
long dbScanLink();
|
||||
|
||||
#endif /*__STDC__*/
|
||||
|
||||
#endif /*INCdbAccessh*/
|
||||
|
||||
+11
-8
@@ -28,6 +28,9 @@
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* $Log$
|
||||
* Revision 1.6 1995/11/29 14:23:28 mrk
|
||||
* Changes for replacing default.dctsdr by all ascii files
|
||||
*
|
||||
* Revision 1.5 1995/02/23 21:45:03 mcn
|
||||
* Fixed locking error. OOPS.
|
||||
*
|
||||
@@ -76,6 +79,7 @@
|
||||
#include <dbAccess.h>
|
||||
#include <dbScan.h>
|
||||
#include <dbCommon.h>
|
||||
#include <dbLock.h>
|
||||
#include <dbFldTypes.h>
|
||||
#include <dbBkpt.h>
|
||||
#include <db_field_log.h>
|
||||
@@ -174,7 +178,7 @@ static SEM_ID bkpt_stack_sem;
|
||||
* lockset to be continued from differs from this
|
||||
* variable.
|
||||
*/
|
||||
static short last_lset = 0;
|
||||
static unsigned long last_lset = 0;
|
||||
|
||||
/*
|
||||
* FIND_LOCKSET() finds the stack entry
|
||||
@@ -185,7 +189,7 @@ static short last_lset = 0;
|
||||
#define FIND_LOCKSET(precord, pnode) \
|
||||
pnode = (struct LS_LIST *) lstFirst(&lset_stack); \
|
||||
while ((pnode) != NULL) { \
|
||||
if ((pnode)->l_num == (precord)->lset) break; \
|
||||
if (pnode->l_num == dbLockGetLockId(precord)) break; \
|
||||
pnode = (struct LS_LIST *) lstNext((NODE *)pnode); \
|
||||
} \
|
||||
|
||||
@@ -346,7 +350,7 @@ long dbb(char *record_name)
|
||||
|
||||
pnode->taskid = 0;
|
||||
pnode->step = 0;
|
||||
pnode->l_num = precord->lset;
|
||||
pnode->l_num = dbLockGetLockId(precord);
|
||||
lstAdd(&lset_stack, (NODE *)pnode);
|
||||
}
|
||||
|
||||
@@ -639,7 +643,7 @@ static void dbBkptCont(struct dbCommon *precord)
|
||||
/* remove execution semaphore */
|
||||
semDelete(pnode->ex_sem);
|
||||
|
||||
printf("\n BKPT> End debug of lockset %d\n-> ", pnode->l_num);
|
||||
printf("\n BKPT> End debug of lockset %lu\n-> ", pnode->l_num);
|
||||
|
||||
/* free list node */
|
||||
free(pnode);
|
||||
@@ -698,8 +702,7 @@ int dbBkpt(struct dbCommon *precord)
|
||||
}
|
||||
|
||||
/* Check disable flag */
|
||||
recGblGetFastLink(&precord->sdis, (void *) precord, &precord->disa);
|
||||
|
||||
dbGetLink(&(precord->sdis),DBR_SHORT,&(precord->disa),0,0);
|
||||
if (precord->disa == precord->disv) {
|
||||
/*
|
||||
* Do not process breakpoints if the record is disabled,
|
||||
@@ -917,7 +920,7 @@ long dbstat()
|
||||
while (pnode != NULL) {
|
||||
if (pnode->precord != NULL) {
|
||||
|
||||
printf("LSet: %5.5d Stopped at: %-28.28s #B: %5.5d T: 0x%7.7x\n",
|
||||
printf("LSet: %lu Stopped at: %-28.28s #B: %5.5d T: 0x%7.7x\n",
|
||||
pnode->l_num, pnode->precord->name, lstCount(&pnode->bp_list), pnode->taskid);
|
||||
|
||||
/* for each entrypoint detected, print out entrypoint statistics */
|
||||
@@ -932,7 +935,7 @@ long dbstat()
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("LSet: %5.5d #B: %5.5d T: 0x%7.7x\n",
|
||||
printf("LSet: %lu #B: %5.5d T: 0x%7.7x\n",
|
||||
pnode->l_num, lstCount(&pnode->bp_list), pnode->taskid);
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -32,6 +32,7 @@
|
||||
#ifndef INCdbBkptsh
|
||||
#define INCdbBkptsh 1
|
||||
|
||||
#include <lstLib.h>
|
||||
/* Needs to be put into dbTest.h ! */
|
||||
long dbpr(char *name, int level);
|
||||
|
||||
@@ -73,7 +74,7 @@ struct LS_LIST {
|
||||
SEM_ID ex_sem; /* semaphore for execution queue */
|
||||
int taskid; /* saved taskid for the task in stepping mode */
|
||||
int step; /* one if currently "stepping," else zero */
|
||||
short l_num; /* lockset number */
|
||||
unsigned long l_num; /* lockset number */
|
||||
};
|
||||
|
||||
/* Values for BKPT (breakpoint) field in record */
|
||||
|
||||
+439
@@ -0,0 +1,439 @@
|
||||
/* dbCa.c */
|
||||
/*****************************************************************
|
||||
COPYRIGHT NOTIFICATION
|
||||
*****************************************************************
|
||||
|
||||
(C) COPYRIGHT 1991 Regents of the University of California,
|
||||
and the University of Chicago Board of Governors.
|
||||
|
||||
This software was developed under a United States Government license
|
||||
described on the COPYRIGHT_Combined file included as part
|
||||
of this distribution.
|
||||
**********************************************************************/
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* Current Author: Bob Dalesio
|
||||
* Contributing Author: Marty Kraimer
|
||||
* Date: 26MAR96
|
||||
*
|
||||
* Complete replacement for dbCaDblink.c dbCaLink.c (Nicholas T. Karonis)
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 26MAR96 lrd rewritten for simplicity, robustness and flexibility
|
||||
****************************************************************/
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <taskLib.h>
|
||||
|
||||
#include "cadef.h"
|
||||
#include "caerr.h"
|
||||
#include "alarm.h"
|
||||
#include "db_access.h"
|
||||
#include "link.h"
|
||||
#include "task_params.h"
|
||||
#include "errMdef.h"
|
||||
#include "epicsPrint.h"
|
||||
#include "dbCommon.h"
|
||||
#include "dbCa.h"
|
||||
/*Following is because dbScan.h causes include for dbAccess.h*/
|
||||
void scanOnce(void *precord);
|
||||
|
||||
static ELLLIST caList; /* Work list for dbCaTask */
|
||||
static SEM_ID caListSem; /*Mutual exclusions semaphores for caList*/
|
||||
static SEM_ID caWakeupSem; /*wakeup semaphore for dbCaTask*/
|
||||
void dbCaTask(); /*The Channel Access Task*/
|
||||
|
||||
void dbCaLinkInit(void)
|
||||
{
|
||||
ellInit(&caList);
|
||||
caListSem = semBCreate(SEM_Q_PRIORITY,SEM_FULL);
|
||||
caWakeupSem = semBCreate(SEM_Q_PRIORITY,SEM_EMPTY);
|
||||
if(!caListSem || !caWakeupSem) {
|
||||
printf("dbCaLinkInit: semBCreate failed\n");
|
||||
return;
|
||||
}
|
||||
taskSpawn("dbCaLink", DB_CA_PRI, DB_CA_OPT,
|
||||
DB_CA_STACK, (FUNCPTR) dbCaTask,
|
||||
0,0,0,0,0,0,0,0,0,0);
|
||||
}
|
||||
|
||||
void dbCaAddLink( struct link *plink)
|
||||
{
|
||||
caLink *pca;
|
||||
|
||||
pca = (caLink*)dbCalloc(1,sizeof(caLink));
|
||||
pca->plink = plink;
|
||||
plink->type = CA_LINK;
|
||||
plink->value.pv_link.pvt = pca;
|
||||
if((pca->lock = semBCreate(SEM_Q_PRIORITY,SEM_FULL)) == NULL){
|
||||
printf("dbCaAddLink: semBCreate failed\n");
|
||||
taskSuspend(0);
|
||||
}
|
||||
semTake(caListSem,WAIT_FOREVER);
|
||||
pca->link_action = CA_CONNECT;
|
||||
ellAdd(&caList,&pca->node);
|
||||
semGive(caListSem);
|
||||
semGive(caWakeupSem);
|
||||
return;
|
||||
}
|
||||
|
||||
void dbCaRemoveLink( struct link *plink)
|
||||
{
|
||||
caLink *pca = (caLink *)plink->value.pv_link.pvt;
|
||||
|
||||
if(!pca) return;
|
||||
semTake(caListSem,WAIT_FOREVER);
|
||||
if(!pca->link_action){/*If not on work list add it*/
|
||||
ellAdd(&caList,&pca->node);
|
||||
}
|
||||
pca->link_action = CA_DELETE;
|
||||
plink->value.pv_link.pvt = 0;
|
||||
pca->plink = 0;
|
||||
semGive(caListSem);
|
||||
semGive(caWakeupSem);
|
||||
}
|
||||
|
||||
|
||||
long dbCaGetLink(struct link *plink,short dbrType, char *pdest,
|
||||
unsigned short *psevr,long *nelements)
|
||||
{
|
||||
caLink *pca = (caLink *)plink->value.pv_link.pvt;
|
||||
long status = 0;
|
||||
long (*pconvert)();
|
||||
STATUS semStatus;
|
||||
|
||||
if(!pca) {
|
||||
epicsPrintf("dbCaGetLink: record %s pv_link.pvt is NULL\n",
|
||||
plink->value.pv_link.precord);
|
||||
return(-1);
|
||||
}
|
||||
semStatus = semTake(pca->lock,WAIT_FOREVER);
|
||||
if(semStatus!=OK) {
|
||||
epicsPrintf("dbCaGetLink: semStatus!OK\n");
|
||||
taskSuspend(0);
|
||||
}
|
||||
if(ca_field_type(pca->chid) == TYPENOTCONN){
|
||||
pca->sevr = INVALID_ALARM;
|
||||
goto done;
|
||||
}
|
||||
if(!ca_read_access(pca->chid)) {
|
||||
pca->sevr = INVALID_ALARM;
|
||||
goto done;
|
||||
}
|
||||
if((pca->dbrType == DBR_ENUM)
|
||||
&& (dbDBRnewToDBRold[dbrType] == DBR_STRING)) {
|
||||
/*Must ask server for DBR_STRING*/
|
||||
if(!pca->pgetString) {
|
||||
pca->pgetString = dbCalloc(MAX_STRING_SIZE,sizeof(char));
|
||||
semGive(pca->lock);
|
||||
semTake(caListSem,WAIT_FOREVER);
|
||||
pca->link_action = CA_MONITOR_STRING;
|
||||
semGive(caListSem);
|
||||
semGive(caWakeupSem);
|
||||
semStatus = semTake(pca->lock,WAIT_FOREVER);
|
||||
if(semStatus!=OK) {
|
||||
epicsPrintf("dbCaGetLink: semStatus!OK\n");
|
||||
taskSuspend(0);
|
||||
}
|
||||
}
|
||||
if(!pca->gotInString) {
|
||||
pca->sevr = INVALID_ALARM;
|
||||
goto done;
|
||||
}
|
||||
if(nelements) *nelements = 1;
|
||||
pconvert=dbFastGetConvertRoutine[dbDBRoldToDBFnew[DBR_STRING]][dbrType];
|
||||
status = (*(pconvert))(pca->pgetString, pdest, 0);
|
||||
goto done;
|
||||
}
|
||||
if(!pca->gotInNative){
|
||||
pca->sevr = INVALID_ALARM;
|
||||
goto done;
|
||||
}
|
||||
if(!nelements || *nelements == 1){
|
||||
pconvert=
|
||||
dbFastGetConvertRoutine[dbDBRoldToDBFnew[pca->dbrType]][dbrType];
|
||||
status = (*(pconvert))(pca->pgetNative, pdest, 0);
|
||||
}else{
|
||||
unsigned long ntoget = *nelements;
|
||||
struct db_addr dbAddr;
|
||||
|
||||
if(ntoget > pca->nelements) ntoget = pca->nelements;
|
||||
*nelements = ntoget;
|
||||
pconvert = dbGetConvertRoutine[dbDBRoldToDBFnew[pca->dbrType]][dbrType];
|
||||
memset((void *)&dbAddr,0,sizeof(dbAddr));
|
||||
dbAddr.pfield = pca->pgetNative;
|
||||
/*Following will only be used for pca->dbrType == DBR_STRING*/
|
||||
dbAddr.field_size = MAX_STRING_SIZE;
|
||||
status = (*(pconvert))(&dbAddr,pdest,nelements,ntoget,0);
|
||||
}
|
||||
done:
|
||||
if(psevr) *psevr = pca->sevr;
|
||||
semGive(pca->lock);
|
||||
return(status);
|
||||
}
|
||||
|
||||
long dbCaPutLink(struct link *plink,short dbrType,
|
||||
void *psource,long nelements)
|
||||
{
|
||||
caLink *pca = (caLink *)plink->value.pv_link.pvt;
|
||||
long (*pconvert)();
|
||||
long status = 0;
|
||||
STATUS semStatus;
|
||||
short link_action;
|
||||
|
||||
if(!pca) {
|
||||
epicsPrintf("dbCaPutLink: record %s pv_link.pvt is NULL\n",
|
||||
plink->value.pv_link.precord);
|
||||
return(-1);
|
||||
}
|
||||
/* put the new value in */
|
||||
semStatus = semTake(pca->lock,WAIT_FOREVER);
|
||||
if(semStatus!=OK) {
|
||||
epicsPrintf("dbCaGetLink: semStatus!OK\n");
|
||||
taskSuspend(0);
|
||||
}
|
||||
if(ca_state(pca->chid) != cs_conn) {
|
||||
semGive(pca->lock);
|
||||
return(-1);
|
||||
}
|
||||
if((pca->dbrType == DBR_ENUM)
|
||||
&& (dbDBRnewToDBRold[dbrType] == DBR_STRING)) {
|
||||
/*Must send DBR_STRING*/
|
||||
if(!pca->pputString)
|
||||
pca->pputString = dbCalloc(MAX_STRING_SIZE,sizeof(char));
|
||||
pconvert=dbFastPutConvertRoutine[dbrType][dbDBRoldToDBFnew[DBR_STRING]];
|
||||
status = (*(pconvert))(psource,pca->pputString, 0);
|
||||
link_action = CA_WRITE_STRING;
|
||||
pca->gotOutString = TRUE;
|
||||
} else {
|
||||
if(nelements == 1){
|
||||
pconvert = dbFastPutConvertRoutine
|
||||
[dbrType][dbDBRoldToDBFnew[pca->dbrType]];
|
||||
status = (*(pconvert))(psource,pca->pputNative, 0);
|
||||
}else{
|
||||
struct db_addr dbAddr;
|
||||
pconvert = dbPutConvertRoutine
|
||||
[dbrType][dbDBRoldToDBFnew[pca->dbrType]];
|
||||
memset((void *)&dbAddr,0,sizeof(dbAddr));
|
||||
dbAddr.pfield = pca->pputNative;
|
||||
/*Following only used for DBF_STRING*/
|
||||
dbAddr.field_size = MAX_STRING_SIZE;
|
||||
status = (*(pconvert))(&dbAddr,psource,nelements,pca->nelements,0);
|
||||
}
|
||||
link_action = CA_WRITE_NATIVE;
|
||||
pca->gotOutNative = TRUE;
|
||||
}
|
||||
if(pca->newWrite) pca->nNoWrite++;
|
||||
pca->newWrite = TRUE;
|
||||
semGive(pca->lock);
|
||||
/* link it into the action list */
|
||||
semTake(caListSem,WAIT_FOREVER);
|
||||
if(!pca->link_action && ca_write_access(pca->chid)){
|
||||
pca->link_action = link_action;
|
||||
ellAdd(&caList,&pca->node);
|
||||
}
|
||||
semGive(caListSem);
|
||||
semGive(caWakeupSem);
|
||||
return(status);
|
||||
}
|
||||
|
||||
|
||||
static void caEventHandler(struct event_handler_args arg)
|
||||
{
|
||||
caLink *pca = (caLink *)arg.usr;
|
||||
struct link *plink;
|
||||
long size;
|
||||
|
||||
if(!pca) {
|
||||
epicsPrintf("caEventHandler why was arg.usr NULL\n");
|
||||
return;
|
||||
}
|
||||
plink = pca->plink;
|
||||
if(arg.status != ECA_NORMAL) {
|
||||
dbCommon *precord = 0;
|
||||
|
||||
if(plink) precord = (dbCommon *)plink->value.pv_link.precord;
|
||||
if(precord)
|
||||
epicsPrintf("dbCa: caEventHandler record %s error %s\n",
|
||||
precord->name,ca_message(arg.status));
|
||||
else
|
||||
epicsPrintf("dbCa: caEventHandler error %s\n",
|
||||
ca_message(arg.status));
|
||||
return;
|
||||
}
|
||||
if(!arg.dbr) {
|
||||
epicsPrintf("caEventHandler why was arg.dbr NULL\n");
|
||||
return;
|
||||
}
|
||||
semTake(pca->lock,WAIT_FOREVER);
|
||||
size = arg.count * dbr_value_size[arg.type];
|
||||
if((arg.type==DBR_STS_STRING)
|
||||
&& (ca_field_type(pca->chid)==DBR_ENUM)) {
|
||||
memcpy(pca->pgetString,dbr_value_ptr(arg.dbr,arg.type),size);
|
||||
pca->gotInString = TRUE;
|
||||
} else switch (arg.type){
|
||||
case DBR_STS_STRING:
|
||||
case DBR_STS_SHORT:
|
||||
case DBR_STS_FLOAT:
|
||||
case DBR_STS_ENUM:
|
||||
case DBR_STS_CHAR:
|
||||
case DBR_STS_LONG:
|
||||
case DBR_STS_DOUBLE:
|
||||
memcpy(pca->pgetNative,dbr_value_ptr(arg.dbr,arg.type),size);
|
||||
pca->gotInNative = TRUE;
|
||||
break;
|
||||
default:
|
||||
errMessage(-1,"dbCa: caEventHandler Logic Error\n");
|
||||
break;
|
||||
}
|
||||
pca->sevr=(unsigned short)((struct dbr_sts_double *)arg.dbr)->severity;
|
||||
plink = pca->plink;
|
||||
if(plink) {
|
||||
struct pv_link *ppv_link = &(plink->value.pv_link);
|
||||
dbCommon *precord = ppv_link->precord;
|
||||
|
||||
if(precord) {
|
||||
if((ppv_link->pvlMask&pvlOptCP)
|
||||
|| ((ppv_link->pvlMask&pvlOptCPP)&&(precord->scan==0)))
|
||||
scanOnce(ppv_link->precord);
|
||||
}
|
||||
}
|
||||
semGive(pca->lock);
|
||||
}
|
||||
|
||||
static void dbCaLinkConnectionHandler(struct connection_handler_args arg)
|
||||
{
|
||||
caLink *pca;
|
||||
int status;
|
||||
|
||||
pca = ca_puser(arg.chid);
|
||||
if(!pca) return;
|
||||
if(ca_state(arg.chid) != cs_conn){
|
||||
pca->nDisconnect++;
|
||||
return;
|
||||
}
|
||||
semTake(pca->lock,WAIT_FOREVER);
|
||||
if((pca->nelements != ca_element_count(arg.chid))
|
||||
|| (pca->dbrType != ca_field_type(arg.chid))){
|
||||
DBLINK *plink = pca->plink;
|
||||
|
||||
if(plink) plink->value.pv_link.getCvt = 0;
|
||||
free(pca->pgetNative);
|
||||
free(pca->pputNative);
|
||||
pca->pgetNative = NULL;
|
||||
pca->pputNative = NULL;
|
||||
pca->gotInNative = FALSE;
|
||||
pca->gotOutNative = FALSE;
|
||||
pca->gotInString = FALSE;
|
||||
}
|
||||
if(pca->pgetNative == NULL){
|
||||
short element_size;
|
||||
|
||||
pca->nelements = ca_element_count(arg.chid);
|
||||
pca->dbrType = ca_field_type(arg.chid);
|
||||
element_size = dbr_value_size[ca_field_type(arg.chid)];
|
||||
pca->pgetNative = dbCalloc(pca->nelements,element_size);
|
||||
pca->pputNative = dbCalloc(pca->nelements,element_size);
|
||||
status = ca_add_array_event(
|
||||
ca_field_type(arg.chid)+DBR_STS_STRING, ca_element_count(arg.chid),
|
||||
arg.chid, caEventHandler,pca,0.0,0.0,0.0,0);
|
||||
if(status!=ECA_NORMAL)
|
||||
epicsPrintf("dbCaTask ca_search_and_connect %s\n",
|
||||
ca_message(status));
|
||||
if(pca->pgetString) {
|
||||
status = ca_add_array_event(DBR_STS_STRING,1,
|
||||
arg.chid, caEventHandler,pca,0.0,0.0,0.0,0);
|
||||
if(status!=ECA_NORMAL)
|
||||
epicsPrintf("dbCaTask ca_search_and_connect %s\n",
|
||||
ca_message(status));
|
||||
}
|
||||
}
|
||||
semGive(pca->lock);
|
||||
semTake(caListSem,WAIT_FOREVER);
|
||||
if(pca->gotOutNative && !pca->link_action) {
|
||||
pca->link_action = CA_WRITE_NATIVE;
|
||||
ellAdd(&caList,&pca->node);
|
||||
}
|
||||
semGive(caListSem);
|
||||
}
|
||||
|
||||
void dbCaTask()
|
||||
{
|
||||
caLink *pca;
|
||||
short link_action;
|
||||
int status;
|
||||
|
||||
SEVCHK(ca_task_initialize(),NULL);
|
||||
/* channel access event loop */
|
||||
while (TRUE){
|
||||
semTake(caWakeupSem,WAIT_FOREVER);
|
||||
while(TRUE) { /* process all requests in caList*/
|
||||
semTake(caListSem,WAIT_FOREVER);
|
||||
if(pca = (caLink *)ellFirst(&caList)){/*Take off list head*/
|
||||
ellDelete(&caList,&pca->node);
|
||||
link_action = pca->link_action;
|
||||
pca->link_action = 0;
|
||||
semGive(caListSem); /*Give it back immediately*/
|
||||
switch(link_action) {
|
||||
case CA_CONNECT:
|
||||
status = ca_search_and_connect(
|
||||
pca->plink->value.pv_link.pvname,
|
||||
&(pca->chid),
|
||||
dbCaLinkConnectionHandler,(void *)pca);
|
||||
if(status!=ECA_NORMAL)
|
||||
epicsPrintf("dbCaTask ca_search_and_connect %s\n",
|
||||
ca_message(status));
|
||||
break;
|
||||
case CA_DELETE:
|
||||
if(pca->chid) ca_clear_channel(pca->chid);
|
||||
free(pca->pgetNative);
|
||||
free(pca->pputNative);
|
||||
free(pca->pgetString);
|
||||
free(pca->pputString);
|
||||
semDelete(pca->lock);
|
||||
free(pca);
|
||||
break;
|
||||
case CA_WRITE_NATIVE:
|
||||
if(ca_state(pca->chid) == cs_conn){
|
||||
status = ca_array_put(
|
||||
pca->dbrType,pca->nelements,
|
||||
pca->chid,pca->pputNative);
|
||||
if(status==ECA_NORMAL){
|
||||
pca->newWrite = FALSE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CA_WRITE_STRING:
|
||||
if(ca_state(pca->chid) == cs_conn){
|
||||
status = ca_array_put(
|
||||
DBR_STRING,1,
|
||||
pca->chid,pca->pputString);
|
||||
if(status==ECA_NORMAL) {
|
||||
pca->newWrite = FALSE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CA_MONITOR_STRING:
|
||||
if(ca_state(pca->chid) == cs_conn){
|
||||
status = ca_add_array_event(DBR_STS_STRING,1,
|
||||
pca->chid, caEventHandler,pca,0.0,0.0,0.0,0);
|
||||
if(status!=ECA_NORMAL)
|
||||
epicsPrintf("dbCaTask ca_add_array_event %s\n",
|
||||
ca_message(status));
|
||||
}
|
||||
break;
|
||||
}/*switch*/
|
||||
} else {
|
||||
semGive(caListSem);
|
||||
break; /*caList is empty*/
|
||||
}
|
||||
}
|
||||
SEVCHK(ca_flush_io(),0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/* dbCa.h.c */
|
||||
/*****************************************************************
|
||||
COPYRIGHT NOTIFICATION
|
||||
*****************************************************************
|
||||
|
||||
(C) COPYRIGHT 1991 Regents of the University of California,
|
||||
and the University of Chicago Board of Governors.
|
||||
|
||||
This software was developed under a United States Government license
|
||||
described on the COPYRIGHT_Combined file included as part
|
||||
of this distribution.
|
||||
**********************************************************************/
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* Current Author: Bob Dalesio
|
||||
* Contributing Author: Marty Kraimer
|
||||
* Date: 08APR96
|
||||
*
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 08APR96 mrk Made separate module for dbcal
|
||||
****************************************************************/
|
||||
|
||||
/* for input links */
|
||||
#define CA_CONNECT 1
|
||||
#define CA_DELETE 2
|
||||
#define CA_WRITE_NATIVE 3
|
||||
#define CA_WRITE_STRING 4
|
||||
#define CA_MONITOR_STRING 5
|
||||
typedef struct caLink
|
||||
{
|
||||
ELLNODE node;
|
||||
struct link *plink;
|
||||
chid chid;
|
||||
void *pgetNative;
|
||||
void *pputNative;
|
||||
char *pgetString;
|
||||
char *pputString;
|
||||
long nelements;
|
||||
SEM_ID lock;
|
||||
unsigned long nDisconnect;
|
||||
unsigned long nNoWrite;
|
||||
short dbrType;
|
||||
short link_action;
|
||||
unsigned short sevr;
|
||||
char gotInNative;
|
||||
char gotOutNative;
|
||||
char gotInString;
|
||||
char gotOutString;
|
||||
char newWrite;
|
||||
}caLink;
|
||||
@@ -1,757 +0,0 @@
|
||||
/* dbCaDblink.c */
|
||||
/* base/src/db $Id$ */
|
||||
/****************************************************************
|
||||
*
|
||||
* Author: Nicholas T. Karonis
|
||||
* Date: 01-01-92
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* This file exists because it is currently not possible to have a single .c
|
||||
* file that contains BOTH channel access calls AND calls to the NEW db
|
||||
* functions. This file calls a number of NEW db functions (dbNameToAddr(),
|
||||
* dbScanLock(), dbScanUnlock(), and dbPut()). If it were possible to mix
|
||||
* channel access calls and new db calls, the contents of this file should be
|
||||
* placed into dbCaLink.c as the all the externally visible functions in this
|
||||
* file are only called from functions in that file. Additionally, many of the
|
||||
* data structures found in this file would no longer be necessary.
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
/* needed for NULL */
|
||||
#include <vxWorks.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* needed for PVNAME_SZ and FLDNAME_SZ ... must be before dbAccess.h */
|
||||
#include <dbDefs.h>
|
||||
#include <recGbl.h>
|
||||
|
||||
/* needed for dbNameToAddr() */
|
||||
#include <dbAccess.h>
|
||||
|
||||
/* needed for struct dbCommon ... should be removed when */
|
||||
/* MAXSEVERITY_FROM_PDBADDR moved to another header file */
|
||||
#include <dbCommon.h>
|
||||
|
||||
/* needed for (db_field_log *) NULL parm passed to dbGet() */
|
||||
#include <db_field_log.h>
|
||||
|
||||
#include <errMdef.h>
|
||||
#include <calink.h>
|
||||
|
||||
/* needed for recGblSetSevr() macro */
|
||||
#include <recSup.h>
|
||||
|
||||
/* these should be in dbFldTypes.h where */
|
||||
/* the valid DBF and DBR types are defined */
|
||||
|
||||
#define INVALID_DBR -1
|
||||
#define INVALID_DBF -1
|
||||
|
||||
/* this macro was defined by list of DBF and DBR types */
|
||||
/* found in dbFldTypes.h and belongs in that header file. */
|
||||
|
||||
#define DBF_TO_DBR(DBF) \
|
||||
((DBF) == DBF_STRING ? DBR_STRING : \
|
||||
((DBF) == DBF_CHAR ? DBR_CHAR : \
|
||||
((DBF) == DBF_UCHAR ? DBR_UCHAR : \
|
||||
((DBF) == DBF_SHORT ? DBR_SHORT : \
|
||||
((DBF) == DBF_USHORT ? DBR_USHORT : \
|
||||
((DBF) == DBF_LONG ? DBR_LONG : \
|
||||
((DBF) == DBF_ULONG ? DBR_ULONG : \
|
||||
((DBF) == DBF_FLOAT ? DBR_FLOAT : \
|
||||
((DBF) == DBF_DOUBLE ? DBR_DOUBLE : \
|
||||
((DBF) == DBF_ENUM ? DBR_ENUM : \
|
||||
((DBF) == DBF_MENU ? DBR_ENUM : \
|
||||
((DBF) == DBF_DEVICE ? DBR_ENUM : \
|
||||
INVALID_DBF ))))))))))))
|
||||
|
||||
/* this macro should be in recSup.h */
|
||||
/* to hide the fact that the precord */
|
||||
/* field needs to be accessed from a */
|
||||
/* dbaddr to set a new severity. */
|
||||
#define MAXSEVERITY_FROM_PDBADDR(PDBADDR, NEWSTATUS, NEWSEVERITY) \
|
||||
recGblSetSevr((struct dbCommon *) (PDBADDR)->precord, \
|
||||
(NEWSTATUS), (NEWSEVERITY));
|
||||
|
||||
/* START definitions from db_access.c */
|
||||
|
||||
#define oldDBF_STRING 0
|
||||
#define oldDBF_INT 1
|
||||
#define oldDBF_SHORT 1
|
||||
#define oldDBF_FLOAT 2
|
||||
#define oldDBF_ENUM 3
|
||||
#define oldDBF_CHAR 4
|
||||
#define oldDBF_LONG 5
|
||||
#define oldDBF_DOUBLE 6
|
||||
|
||||
/* data request buffer types */
|
||||
#define oldDBR_STRING oldDBF_STRING
|
||||
#define oldDBR_INT oldDBF_INT
|
||||
#define oldDBR_SHORT oldDBF_INT
|
||||
#define oldDBR_FLOAT oldDBF_FLOAT
|
||||
#define oldDBR_ENUM oldDBF_ENUM
|
||||
#define oldDBR_CHAR oldDBF_CHAR
|
||||
#define oldDBR_LONG oldDBF_LONG
|
||||
#define oldDBR_DOUBLE oldDBF_DOUBLE
|
||||
#define oldDBR_STS_STRING 7
|
||||
#define oldDBR_STS_INT 8
|
||||
#define oldDBR_STS_SHORT 8
|
||||
#define oldDBR_STS_FLOAT 9
|
||||
#define oldDBR_STS_ENUM 10
|
||||
#define oldDBR_STS_CHAR 11
|
||||
#define oldDBR_STS_LONG 12
|
||||
#define oldDBR_STS_DOUBLE 13
|
||||
#define oldDBR_TIME_STRING 14
|
||||
#define oldDBR_TIME_INT 15
|
||||
#define oldDBR_TIME_SHORT 15
|
||||
#define oldDBR_TIME_FLOAT 16
|
||||
#define oldDBR_TIME_ENUM 17
|
||||
#define oldDBR_TIME_CHAR 18
|
||||
#define oldDBR_TIME_LONG 19
|
||||
#define oldDBR_TIME_DOUBLE 20
|
||||
#define oldDBR_GR_STRING 21
|
||||
#define oldDBR_GR_INT 22
|
||||
#define oldDBR_GR_SHORT 22
|
||||
#define oldDBR_GR_FLOAT 23
|
||||
#define oldDBR_GR_ENUM 24
|
||||
#define oldDBR_GR_CHAR 25
|
||||
#define oldDBR_GR_LONG 26
|
||||
#define oldDBR_GR_DOUBLE 27
|
||||
#define oldDBR_CTRL_STRING 28
|
||||
#define oldDBR_CTRL_INT 29
|
||||
#define oldDBR_CTRL_SHORT 29
|
||||
#define oldDBR_CTRL_FLOAT 30
|
||||
#define oldDBR_CTRL_ENUM 31
|
||||
#define oldDBR_CTRL_CHAR 32
|
||||
#define oldDBR_CTRL_LONG 33
|
||||
#define oldDBR_CTRL_DOUBLE 34
|
||||
|
||||
/* END definitions from db_access.c */
|
||||
|
||||
/**************************************/
|
||||
/* */
|
||||
/* Externally Visible Local Functions */
|
||||
/* */
|
||||
/**************************************/
|
||||
|
||||
long dbCaCopyPvar(); /* called from dbCaLink.c */
|
||||
long dbCaDbPut(); /* called from dbCaLink.c */
|
||||
long dbCaMaximizeSeverity(); /* called from dbCaLink.c */
|
||||
long dbCaNameToAddr(); /* called from dbCaLink.c */
|
||||
|
||||
/* conversion routines */
|
||||
|
||||
short dbCaNewDbfToNewDbr(); /* called from dbCaLink.c */
|
||||
/* these two go away when channel access learns new db technology */
|
||||
short dbCaNewDbrToOldDbr(); /* called from dbCaLink.c */
|
||||
short dbCaOldDbrToNewDbr(); /* called from dbCaLink.c */
|
||||
short dbCaOldDbrToOldDbrSts(); /* called from dbCaLink.c */
|
||||
|
||||
/* these should be moved to db access */
|
||||
char *dbCaRecnameFromDbCommon(); /* called from dbCaLink.c */
|
||||
short dbCaDbfFromDbAddr(); /* called from dbCaLink.c */
|
||||
long dbCaNelementsFromDbAddr(); /* called from dbCaLink.c */
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* EXTERNALLY VISIBLE FUNCTIONS
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* Input:
|
||||
*
|
||||
* Output:
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* Logic:
|
||||
*
|
||||
* Notes:
|
||||
* Typically this routine is called from a place that has no
|
||||
* knowledge about struct dbAddr, therefore pdbaddr comes in as
|
||||
* a void *.
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
short dbCaDbfFromDbAddr(pdbaddr)
|
||||
void *pdbaddr;
|
||||
{
|
||||
|
||||
short rc;
|
||||
|
||||
if (pdbaddr)
|
||||
rc = ((struct dbAddr *) pdbaddr)->field_type;
|
||||
else
|
||||
rc = (short) INVALID_DBF;
|
||||
|
||||
return rc;
|
||||
|
||||
} /* end dbCaDbfFromDbAddr() */
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* long dbCaNameToAddr(pvarname)
|
||||
* char *pvarname;
|
||||
*
|
||||
* Description:
|
||||
* During record initialization a record was found to have an input link
|
||||
* whose source is in a different physical database (on another IOC). This
|
||||
* function registers that input link as remote.
|
||||
*
|
||||
* Input:
|
||||
* char *pvarname name of destination pvar for input link
|
||||
*
|
||||
* Output: None.
|
||||
*
|
||||
* Returns:
|
||||
* any rc from dbNameToAddr()
|
||||
* S_dbCa_nullarg - received a NULL pointer in one of the args
|
||||
* S_dbCa_failedmalloc - could not dynamically allocate memory
|
||||
*
|
||||
* Notes:
|
||||
* The name of the destination pvar for this input link serves as
|
||||
* the primary key when relating the the Input List in this file
|
||||
* to the Input List in dbCaLink.c as each input link has exactly one source
|
||||
* (i.e., name of destination of input link --FD--> input link).
|
||||
*
|
||||
* This function is called by dbCaAddInlink() in dbCaLink.c.
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
long dbCaNameToAddr(pvarname, ppdbaddr)
|
||||
char *pvarname;
|
||||
void **ppdbaddr;
|
||||
{
|
||||
|
||||
char errmsg[100];
|
||||
long rc;
|
||||
|
||||
if (pvarname)
|
||||
{
|
||||
if (ppdbaddr)
|
||||
{
|
||||
if (*ppdbaddr = (void *) calloc
|
||||
((unsigned) 1, (unsigned) sizeof (struct dbAddr)))
|
||||
{
|
||||
rc = dbNameToAddr(pvarname, (struct dbAddr *) *ppdbaddr);
|
||||
|
||||
if (!RTN_SUCCESS(rc))
|
||||
free(*ppdbaddr);
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = S_dbCa_failedmalloc;
|
||||
sprintf(errmsg,
|
||||
"ERROR: dbCaNameToAddr() could not calloc dbAddr for dpvar >%s<",
|
||||
pvarname);
|
||||
errMessage(S_dbCa_failedmalloc, errmsg);
|
||||
} /* endif */
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = S_dbCa_nullarg;
|
||||
errMessage(S_dbCa_nullarg,
|
||||
"ERROR: dbCaNameToAddr() got NULL ppdest_dbaddr");
|
||||
} /* endif */
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = S_dbCa_nullarg;
|
||||
errMessage(S_dbCa_nullarg,
|
||||
"ERROR: dbCaNameToAddr() got NULL pvarname");
|
||||
} /* endif */
|
||||
|
||||
return rc;
|
||||
|
||||
} /* end dbCaNameToAddr() */
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* Description:
|
||||
* A record is being processed that has an output link that refers to a
|
||||
* process variable on another physical database (another IOC). This function
|
||||
* copies the value from the source pvar into the temporary store of the output
|
||||
* node.
|
||||
*
|
||||
* Input:
|
||||
*
|
||||
* Output: None.
|
||||
*
|
||||
* Returns:
|
||||
* any rc from dbGet()
|
||||
* S_dbCa_nullarg - received a NULL pointer in one of the args
|
||||
*
|
||||
* Notes:
|
||||
* The source pvar name is used as the primary key to index the Output List
|
||||
* in this file.
|
||||
* The two arguments poptions and pnrequest are passed because this function
|
||||
* uses dbGet() to transfer the data from the record to the temporary store
|
||||
* in the Output List.
|
||||
* This function is called by dbCaPutLink() in dbCaLink.c.
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
long dbCaCopyPvar(psource_dbaddr, dest_old_dbr_type, pval,
|
||||
poptions, pnrequest)
|
||||
void *psource_dbaddr;
|
||||
short dest_old_dbr_type;
|
||||
void *pval;
|
||||
long *poptions;
|
||||
long *pnrequest;
|
||||
{
|
||||
|
||||
long rc;
|
||||
|
||||
if (psource_dbaddr)
|
||||
{
|
||||
if (pval)
|
||||
{
|
||||
if (poptions)
|
||||
{
|
||||
if (pnrequest)
|
||||
rc = dbGet((struct dbAddr *) psource_dbaddr,
|
||||
dest_old_dbr_type, (caddr_t) pval,
|
||||
poptions, pnrequest, (db_field_log *) NULL);
|
||||
else
|
||||
{
|
||||
rc = S_dbCa_nullarg;
|
||||
errMessage(S_dbCa_nullarg,
|
||||
"ERROR: dbCaCopyPvar() got NULL pnrequest");
|
||||
} /* endif */
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = S_dbCa_nullarg;
|
||||
errMessage(S_dbCa_nullarg,
|
||||
"ERROR: dbCaCopyPvar() got NULL poptions");
|
||||
} /* endif */
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = S_dbCa_nullarg;
|
||||
errMessage(S_dbCa_nullarg, "ERROR: dbCaCopyPvar() got NULL pval");
|
||||
} /* endif */
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = S_dbCa_nullarg;
|
||||
errMessage(S_dbCa_nullarg,
|
||||
"ERROR: dbCaCopyPvar() got NULL psource_dbaddr");
|
||||
} /* endif */
|
||||
|
||||
return rc;
|
||||
|
||||
} /* end dbCaCopyPvar() */
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* long dbCaMaximizeSeverity(dest_pvarname, new_severity, new_status)
|
||||
* char dest_pvarname;
|
||||
* unsigned short new_severity;
|
||||
* unsigned short new_status;
|
||||
*
|
||||
* Description:
|
||||
* A record is being processed that has an input link that refers to a
|
||||
* process variable on another physical database (another IOC) and the input
|
||||
* link is MS. The severity of the source record is appropriately propogated
|
||||
* to the destination record.
|
||||
*
|
||||
* Input:
|
||||
* char dest_pvarname destination pvar name
|
||||
* unsigned short new_severity new alarm severity
|
||||
* unsigned short new_status new alarm status
|
||||
*
|
||||
* Output: None.
|
||||
*
|
||||
* Returns:
|
||||
* 0 - Success
|
||||
* S_dbCa_foundnull - found a NULL pointer where one should not be
|
||||
* S_dbCa_nullarg - encountered a NULL pointer in one of the input args
|
||||
*
|
||||
* Notes:
|
||||
* The dest pvar name is used as the primary key to index the Input List
|
||||
* in this file.
|
||||
* This function is called by dbCaGetLink() in dbCaLink.c.
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
long dbCaMaximizeSeverity(pdest_dbaddr, new_severity, new_status)
|
||||
void *pdest_dbaddr;
|
||||
unsigned short new_severity;
|
||||
unsigned short new_status;
|
||||
{
|
||||
|
||||
long rc;
|
||||
|
||||
if (pdest_dbaddr)
|
||||
{
|
||||
rc = 0L;
|
||||
|
||||
MAXSEVERITY_FROM_PDBADDR ((struct dbAddr *) pdest_dbaddr,
|
||||
new_status, new_severity)
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = S_dbCa_nullarg;
|
||||
errMessage(S_dbCa_nullarg,
|
||||
"ERROR:dbCaMaximizeSeverity() got NULL pdest_dbaddr");
|
||||
} /* endif */
|
||||
|
||||
return rc;
|
||||
|
||||
} /* end dbCaMaximizeSeverity() */
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* Description:
|
||||
* A record is being processed that has an input link that refers to a
|
||||
* process variable on another physical database (another IOC). This function
|
||||
* copies the value in the temporary store of the input node into the
|
||||
* destination.
|
||||
*
|
||||
* Input:
|
||||
*
|
||||
* Output: None.
|
||||
*
|
||||
* Returns:
|
||||
* any rc from dbPut()
|
||||
* S_dbCa_nullarg - encountered a NULL pointer in one of the input args
|
||||
*
|
||||
* Notes:
|
||||
* The source pvar name is used as the primary key to index the Input List
|
||||
* in this file.
|
||||
* This function is called by dbCaGetLink() in dbCaLink.c.
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
long dbCaDbPut(pdest_dbaddr, dest_revised_new_dbr_type, pval, nelements)
|
||||
void *pdest_dbaddr;
|
||||
short dest_revised_new_dbr_type;
|
||||
void *pval;
|
||||
long nelements;
|
||||
{
|
||||
|
||||
long rc;
|
||||
|
||||
if (pdest_dbaddr)
|
||||
{
|
||||
if (nelements > 0L)
|
||||
{
|
||||
/* printf("dbCaDbPut(): writing to >%s< link revised new dbr type %d nelements %ld\n", (((struct dbAddr *) pdest_dbaddr)->precord)->name, dest_revised_new_dbr_type, nelements); */
|
||||
if (pval)
|
||||
/* this stuff is copied from dbPutField() without */
|
||||
/* honoring the ascii definition process passive */
|
||||
/* for writing to this field within the record. */
|
||||
/* */
|
||||
/* since this function is called during record */
|
||||
/* processing, it is assumed that the record has */
|
||||
/* been successfully locked. */
|
||||
|
||||
rc = dbPut((struct dbAddr *) pdest_dbaddr,
|
||||
dest_revised_new_dbr_type, (caddr_t) pval, nelements);
|
||||
else
|
||||
{
|
||||
rc = S_dbCa_nullarg;
|
||||
errMessage(S_dbCa_nullarg, "ERROR: dbCaDbPut() got NULL pval");
|
||||
} /* endif */
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = S_dbCa_nullarg;
|
||||
errMessage(S_dbCa_nullarg,
|
||||
"ERROR: dbCaDbPut() got non-positive nelements");
|
||||
} /* endif */
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = S_dbCa_nullarg;
|
||||
errMessage(S_dbCa_nullarg, "ERROR: dbCaDbPut() got NULL ppdest_dbaddr");
|
||||
} /* endif */
|
||||
|
||||
return rc;
|
||||
|
||||
} /* end dbCaDbPut() */
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* Input:
|
||||
*
|
||||
* Output:
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* Logic:
|
||||
*
|
||||
* Notes:
|
||||
* Typically this routine is called from a place that has no
|
||||
* knowledge about struct dbAddr, therefore pdbaddr comes in as
|
||||
* a void *.
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
long dbCaNelementsFromDbAddr(pdbaddr)
|
||||
void *pdbaddr;
|
||||
{
|
||||
|
||||
long rc;
|
||||
|
||||
if (pdbaddr)
|
||||
rc = ((struct dbAddr *) pdbaddr)->no_elements;
|
||||
else
|
||||
rc = -1L;
|
||||
|
||||
return rc;
|
||||
|
||||
} /* end dbCaNelementsFromDbAddr() */
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* short dbCaNewDbfToNewDbr(new_dbf_type)
|
||||
* short new_dbf_type;
|
||||
*
|
||||
* Description:
|
||||
* This function converts DBF_XXX -> DBR_XXX both using new db technology.
|
||||
*
|
||||
* Input:
|
||||
* short new_dbf_type DBF type to be converted.
|
||||
*
|
||||
* Output: None.
|
||||
*
|
||||
* Returns:
|
||||
* -1 - conversion failed
|
||||
* new DBR type
|
||||
*
|
||||
* Notes:
|
||||
* It is assumed that -1 is an invalid new DBR type and that DBF_INT and
|
||||
* DBF_SHORT are defined to be the same thing.
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
short dbCaNewDbfToNewDbr(new_dbf_type)
|
||||
short new_dbf_type;
|
||||
{
|
||||
|
||||
return ((short) DBF_TO_DBR(new_dbf_type));
|
||||
|
||||
} /* end dbCaNewDbfToNewDbr() */
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* short dbCaNewDbrToOldDbr(new_dbr_type)
|
||||
* short new_dbr_type;
|
||||
*
|
||||
* Description:
|
||||
* This function converts new DBR_XXX types old DBR_XXX types.
|
||||
*
|
||||
* Input:
|
||||
* short new_dbr_type new DBR type to be converted
|
||||
*
|
||||
* Output: None.
|
||||
*
|
||||
* Returns:
|
||||
* -1 - conversion failed
|
||||
* old DBR type
|
||||
*
|
||||
* Notes:
|
||||
* It is assumed that -1 is an invalid old DBR type and that DBR_INT and
|
||||
* DBR_SHORT are defined to be the same thing.
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
short dbCaNewDbrToOldDbr(new_dbr_type)
|
||||
short new_dbr_type;
|
||||
{
|
||||
|
||||
short old_dbr_type;
|
||||
|
||||
switch (new_dbr_type)
|
||||
{
|
||||
case DBR_STRING: old_dbr_type = oldDBR_STRING; break;
|
||||
case DBR_CHAR: old_dbr_type = oldDBR_CHAR; break;
|
||||
/* case DBR_UCHAR: old_dbr_type = oldDBR_CHAR; break; */
|
||||
case DBR_UCHAR: old_dbr_type = oldDBR_SHORT; break;
|
||||
case DBR_SHORT: old_dbr_type = oldDBR_SHORT; break;
|
||||
/* case DBR_USHORT: old_dbr_type = oldDBR_ENUM; break; */
|
||||
case DBR_USHORT: old_dbr_type = oldDBR_LONG; break;
|
||||
case DBR_LONG: old_dbr_type = oldDBR_LONG; break;
|
||||
case DBR_ULONG: old_dbr_type = oldDBR_LONG; break;
|
||||
case DBR_FLOAT: old_dbr_type = oldDBR_FLOAT; break;
|
||||
case DBR_DOUBLE: old_dbr_type = oldDBR_DOUBLE; break;
|
||||
case DBR_ENUM: old_dbr_type = oldDBR_ENUM; break;
|
||||
|
||||
/* Unrecognizable ... don't know what to do for now */
|
||||
default: old_dbr_type = -1; break;
|
||||
} /* end switch() */
|
||||
|
||||
return old_dbr_type;
|
||||
|
||||
} /* end dbCaNewDbrToOldDbr() */
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* short dbCaOldDbrToNewDbr(new_dbr_type)
|
||||
* short new_dbr_type;
|
||||
*
|
||||
* Description:
|
||||
* This function converts old DBR_XXX types new DBR_XXX types.
|
||||
*
|
||||
* Input:
|
||||
* short old_dbr_type old DBR type to be converted
|
||||
*
|
||||
* Output: None.
|
||||
*
|
||||
* Returns:
|
||||
* -1 - conversion failed
|
||||
* new DBR type
|
||||
*
|
||||
* Notes:
|
||||
* It is assumed that -1 is an invalid new DBR type and that oldDBR_INT and
|
||||
* oldDBR_SHORT are defined to be the same thing.
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
short dbCaOldDbrToNewDbr(old_dbr_type)
|
||||
short old_dbr_type;
|
||||
{
|
||||
|
||||
short new_dbr_type;
|
||||
|
||||
switch (old_dbr_type)
|
||||
{
|
||||
|
||||
case oldDBR_STRING: new_dbr_type = DBR_STRING; break;
|
||||
/* case oldDBR_INT: */
|
||||
case oldDBR_SHORT: new_dbr_type = DBR_SHORT; break;
|
||||
case oldDBR_FLOAT: new_dbr_type = DBR_FLOAT; break;
|
||||
case oldDBR_ENUM: new_dbr_type = DBR_ENUM; break;
|
||||
case oldDBR_CHAR: new_dbr_type = DBR_UCHAR; break;
|
||||
case oldDBR_LONG: new_dbr_type = DBR_LONG; break;
|
||||
case oldDBR_DOUBLE: new_dbr_type = DBR_DOUBLE; break;
|
||||
|
||||
/* Unrecognizable ... don't know what to do for now */
|
||||
default: new_dbr_type = -1; break;
|
||||
} /* end switch() */
|
||||
|
||||
return new_dbr_type;
|
||||
|
||||
} /* end dbCaOldDbrToNewDbr() */
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* short dbCaOldDbrToOldDbrSts(old_dbr_type)
|
||||
* short old_dbr_type;
|
||||
*
|
||||
* Description:
|
||||
* This function converts old DBR_XXX types to old DBR_STS_XXX types.
|
||||
*
|
||||
* Input:
|
||||
* short old_dbr_type old DBR type to be converted
|
||||
*
|
||||
* Output: None.
|
||||
*
|
||||
* Returns:
|
||||
* -1 - conversion failed
|
||||
* old DBR_STS type
|
||||
*
|
||||
* Logic:
|
||||
* convert
|
||||
*
|
||||
* Notes:
|
||||
* It is assumed that -1 is an invalid old DBR_STS type and that oldDBR_INT
|
||||
* and oldDBR_SHORT are defined to be the same thing.
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
short dbCaOldDbrToOldDbrSts(old_dbr_type)
|
||||
short old_dbr_type;
|
||||
{
|
||||
|
||||
short old_dbr_sts_type;
|
||||
|
||||
switch (old_dbr_type)
|
||||
{
|
||||
|
||||
case oldDBR_STRING: old_dbr_sts_type = oldDBR_STS_STRING; break;
|
||||
/* case oldDBR_INT: */
|
||||
case oldDBR_SHORT: old_dbr_sts_type = oldDBR_STS_SHORT; break;
|
||||
case oldDBR_FLOAT: old_dbr_sts_type = oldDBR_STS_FLOAT; break;
|
||||
case oldDBR_ENUM: old_dbr_sts_type = oldDBR_STS_ENUM; break;
|
||||
case oldDBR_CHAR: old_dbr_sts_type = oldDBR_STS_CHAR; break;
|
||||
case oldDBR_LONG: old_dbr_sts_type = oldDBR_STS_LONG; break;
|
||||
case oldDBR_DOUBLE: old_dbr_sts_type = oldDBR_STS_DOUBLE; break;
|
||||
|
||||
/* Unrecognizable ... don't know what to do for now */
|
||||
default: old_dbr_sts_type = -1; break;
|
||||
} /* end switch() */
|
||||
|
||||
return old_dbr_sts_type;
|
||||
|
||||
} /* end dbCaOldDbrToOldDbrSts() */
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* Input:
|
||||
*
|
||||
* Output:
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* Logic:
|
||||
*
|
||||
* Notes:
|
||||
* Typically this routine is called from a place that has no
|
||||
* knowledge about struct dbCommon, therefore precord comes in as
|
||||
* a void *.
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
char *dbCaRecnameFromDbCommon(precord)
|
||||
void *precord;
|
||||
{
|
||||
|
||||
char *rc;
|
||||
|
||||
if (precord)
|
||||
rc = ((struct dbCommon *) precord)->name;
|
||||
else
|
||||
rc = (char *) NULL;
|
||||
|
||||
return rc;
|
||||
|
||||
} /* end dbCaRecnameFromDbCommon() */
|
||||
-2366
File diff suppressed because it is too large
Load Diff
+14
-9
@@ -46,13 +46,11 @@
|
||||
field(TSEL,DBF_INLINK) {
|
||||
prompt("Time Stamp Link")
|
||||
promptgroup(GUI_SCAN)
|
||||
special(SPC_NOMOD)
|
||||
interest(1)
|
||||
}
|
||||
field(DTYP,DBF_DEVICE) {
|
||||
prompt("Device Type")
|
||||
promptgroup(GUI_LINKS)
|
||||
special(SPC_NOMOD)
|
||||
interest(1)
|
||||
}
|
||||
field(DISV,DBF_SHORT) {
|
||||
@@ -66,7 +64,6 @@
|
||||
field(SDIS,DBF_INLINK) {
|
||||
prompt("Scanning Disable")
|
||||
promptgroup(GUI_SCAN)
|
||||
special(SPC_NOMOD)
|
||||
interest(1)
|
||||
}
|
||||
field(MLOK,DBF_NOACCESS) {
|
||||
@@ -134,11 +131,6 @@
|
||||
interest(1)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(LSET,DBF_SHORT) {
|
||||
prompt("Lock Set")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
}
|
||||
field(LCNT,DBF_UCHAR) {
|
||||
prompt("Lock Count")
|
||||
special(SPC_NOMOD)
|
||||
@@ -208,6 +200,20 @@
|
||||
size(4)
|
||||
extra("void *dpvt")
|
||||
}
|
||||
field(RDES,DBF_NOACCESS) {
|
||||
prompt("Address of dbRecDes")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
size(4)
|
||||
extra("void *rdes")
|
||||
}
|
||||
field(LSET,DBF_NOACCESS) {
|
||||
prompt("Lock Set")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
size(4)
|
||||
extra("void *lset")
|
||||
}
|
||||
field(PRIO,DBF_MENU) {
|
||||
prompt("Scheduling Priority")
|
||||
promptgroup(GUI_SCAN)
|
||||
@@ -241,6 +247,5 @@
|
||||
field(FLNK,DBF_FWDLINK) {
|
||||
prompt("Forward Process Link")
|
||||
promptgroup(GUI_LINKS)
|
||||
special(SPC_NOMOD)
|
||||
interest(1)
|
||||
}
|
||||
|
||||
+32
-42
@@ -1502,22 +1502,17 @@ static long getFloatString(
|
||||
{
|
||||
char *pbuffer = (char *)pto;
|
||||
float *psrc=(float *)(paddr->pfield);
|
||||
long status;
|
||||
int precision;
|
||||
long status = 0;
|
||||
int precision = 0;
|
||||
struct rset *prset;
|
||||
|
||||
if((prset=dbGetRset(paddr)) && (prset->get_precision))
|
||||
status = (*prset->get_precision)(paddr,&precision);
|
||||
else
|
||||
status=S_db_precision;
|
||||
if(status) {
|
||||
recGblRecSupError(status,paddr,"dbGet","get_precision");
|
||||
return(status);
|
||||
}
|
||||
|
||||
if(nRequest==1 && offset==0) {
|
||||
cvtFloatToString(*psrc,pbuffer,precision);
|
||||
return(0);
|
||||
return(status);
|
||||
}
|
||||
psrc += offset;
|
||||
while (nRequest) {
|
||||
@@ -1529,7 +1524,7 @@ static long getFloatString(
|
||||
psrc++;
|
||||
nRequest--;
|
||||
}
|
||||
return(0);
|
||||
return(status);
|
||||
}
|
||||
|
||||
static long getFloatChar(
|
||||
@@ -1711,22 +1706,17 @@ static long getDoubleString(
|
||||
{
|
||||
char *pbuffer = (char *)pto;
|
||||
double *psrc=(double *)(paddr->pfield);
|
||||
long status;
|
||||
int precision;
|
||||
long status = 0;
|
||||
int precision = 0;
|
||||
struct rset *prset;
|
||||
|
||||
if((prset=dbGetRset(paddr)) && (prset->get_precision))
|
||||
status = (*prset->get_precision)(paddr,&precision);
|
||||
else
|
||||
status=S_db_precision;
|
||||
if(status) {
|
||||
recGblRecSupError(status,paddr,"dbGet","get_precision");
|
||||
return(status);
|
||||
}
|
||||
|
||||
if(nRequest==1 && offset==0) {
|
||||
cvtDoubleToString(*psrc,pbuffer,precision);
|
||||
return(0);
|
||||
return(status);
|
||||
}
|
||||
psrc += offset;
|
||||
while (nRequest) {
|
||||
@@ -1738,7 +1728,7 @@ static long getDoubleString(
|
||||
psrc++;
|
||||
nRequest--;
|
||||
}
|
||||
return(0);
|
||||
return(status);
|
||||
}
|
||||
|
||||
static long getDoubleChar(
|
||||
@@ -2105,7 +2095,7 @@ static long getMenuString(DBADDR *paddr, void *pto,
|
||||
{
|
||||
char *pbuffer = (char *)pto;
|
||||
dbFldDes *pdbFldDes = (dbFldDes *)paddr->pfldDes;
|
||||
dbMenu *pdbMenu = (dbMenu *)pdbFldDes->ftPvt;
|
||||
dbMenu *pdbMenu;
|
||||
char **papChoiceValue;
|
||||
char *pchoice;
|
||||
unsigned short choice_ind= *((unsigned short*)paddr->pfield);
|
||||
@@ -2114,7 +2104,9 @@ static long getMenuString(DBADDR *paddr, void *pto,
|
||||
recGblDbaddrError(S_db_onlyOne,paddr,"dbGet(getMenuString)");
|
||||
return(S_db_onlyOne);
|
||||
}
|
||||
if( !pdbMenu || choice_ind>=pdbMenu->nChoice
|
||||
if(!pdbFldDes
|
||||
|| !(pdbMenu = (dbMenu *)pdbFldDes->ftPvt)
|
||||
|| (choice_ind>=pdbMenu->nChoice)
|
||||
|| !(papChoiceValue = pdbMenu->papChoiceValue)
|
||||
|| !(pchoice=papChoiceValue[choice_ind])) {
|
||||
recGblDbaddrError(S_db_badChoice,paddr,"dbGet(getMenuString)");
|
||||
@@ -2129,7 +2121,7 @@ static long getDeviceString(DBADDR *paddr, void *pto,
|
||||
{
|
||||
char *pbuffer = (char *)pto;
|
||||
dbFldDes *pdbFldDes = (dbFldDes *)paddr->pfldDes;
|
||||
dbDeviceMenu *pdbDeviceMenu = (dbDeviceMenu *)pdbFldDes->ftPvt;
|
||||
dbDeviceMenu *pdbDeviceMenu;
|
||||
char **papChoice;
|
||||
char *pchoice;
|
||||
unsigned short choice_ind= *((unsigned short*)paddr->pfield);
|
||||
@@ -2138,7 +2130,9 @@ static long getDeviceString(DBADDR *paddr, void *pto,
|
||||
recGblDbaddrError(S_db_onlyOne,paddr,"dbGet(getDeviceString)");
|
||||
return(S_db_onlyOne);
|
||||
}
|
||||
if( !pdbDeviceMenu || choice_ind>=pdbDeviceMenu->nChoice
|
||||
if(!pdbFldDes
|
||||
|| !(pdbDeviceMenu = (dbDeviceMenu *)pdbFldDes->ftPvt)
|
||||
|| (choice_ind>=pdbDeviceMenu->nChoice )
|
||||
|| !(papChoice = pdbDeviceMenu->papChoice)
|
||||
|| !(pchoice=papChoice[choice_ind])) {
|
||||
recGblDbaddrError(S_db_badChoice,paddr,"dbGet(getDeviceString)");
|
||||
@@ -2465,7 +2459,7 @@ static long putStringEnum(
|
||||
if(status == S_db_noRSET) {
|
||||
recGblRecSupError(status,paddr,"dbPutField","put_enum_str");
|
||||
} else {
|
||||
recGblDbaddrError(status,paddr,"dbPut(putStringEnum)");
|
||||
recGblRecordError(status,(void *)paddr->precord,pbuffer);
|
||||
}
|
||||
return(status);
|
||||
}
|
||||
@@ -2475,7 +2469,7 @@ static long putStringMenu(
|
||||
{
|
||||
char *pbuffer = (char *)pfrom;
|
||||
dbFldDes *pdbFldDes = (dbFldDes *)paddr->pfldDes;
|
||||
dbMenu *pdbMenu = (dbMenu *)pdbFldDes->ftPvt;
|
||||
dbMenu *pdbMenu;
|
||||
char **papChoiceValue;
|
||||
char *pchoice;
|
||||
unsigned short *pfield= (unsigned short*)(paddr->pfield);
|
||||
@@ -2486,7 +2480,9 @@ static long putStringMenu(
|
||||
recGblDbaddrError(S_db_onlyOne,paddr,"dbPut(putStringMenu)");
|
||||
return(S_db_onlyOne);
|
||||
}
|
||||
if( pdbMenu && (papChoiceValue = pdbMenu->papChoiceValue)) {
|
||||
if(pdbFldDes
|
||||
&& (pdbMenu = (dbMenu *)pdbFldDes->ftPvt)
|
||||
&& (papChoiceValue = pdbMenu->papChoiceValue)) {
|
||||
nChoice = pdbMenu->nChoice;
|
||||
for(ind=0; ind<nChoice; ind++) {
|
||||
if(!(pchoice=papChoiceValue[ind])) continue;
|
||||
@@ -2521,7 +2517,9 @@ static long putStringDevice(
|
||||
recGblDbaddrError(S_db_onlyOne,paddr,"dbPut(putStringDevice)");
|
||||
return(S_db_onlyOne);
|
||||
}
|
||||
if( pdbDeviceMenu && (papChoice = pdbDeviceMenu->papChoice)) {
|
||||
if(pdbFldDes
|
||||
&& (pdbDeviceMenu = (dbDeviceMenu *)pdbFldDes->ftPvt)
|
||||
&& (papChoice = pdbDeviceMenu->papChoice)) {
|
||||
nChoice = pdbDeviceMenu->nChoice;
|
||||
for(ind=0; ind<nChoice; ind++) {
|
||||
if(!(pchoice=papChoice[ind])) continue;
|
||||
@@ -3721,8 +3719,8 @@ static long putFloatString(
|
||||
{
|
||||
float *pbuffer = (float *)pfrom;
|
||||
char *pdest=(char *)(paddr->pfield);
|
||||
long status;
|
||||
int precision;
|
||||
long status = 0;
|
||||
int precision = 0;
|
||||
struct rset *prset;
|
||||
short size=paddr->field_size;
|
||||
|
||||
@@ -3730,14 +3728,10 @@ static long putFloatString(
|
||||
status = (*prset->get_precision)(paddr,&precision);
|
||||
else
|
||||
status=S_db_precision;
|
||||
if(status) {
|
||||
recGblRecSupError(status,paddr,"dbPutField","get_precision");
|
||||
return(status);
|
||||
}
|
||||
|
||||
if(nRequest==1 && offset==0) {
|
||||
cvtFloatToString(*pbuffer,pdest,precision);
|
||||
return(0);
|
||||
return(status);
|
||||
}
|
||||
pdest += (size*offset);
|
||||
while (nRequest) {
|
||||
@@ -3749,7 +3743,7 @@ static long putFloatString(
|
||||
pdest += size;
|
||||
nRequest--;
|
||||
}
|
||||
return(0);
|
||||
return(status);
|
||||
}
|
||||
|
||||
static long putFloatChar(
|
||||
@@ -3931,8 +3925,8 @@ static long putDoubleString(
|
||||
{
|
||||
double *pbuffer = (double *)pfrom;
|
||||
char *pdest=(char *)(paddr->pfield);
|
||||
long status;
|
||||
int precision;
|
||||
long status = 0;
|
||||
int precision = 0;
|
||||
struct rset *prset;
|
||||
short size=paddr->field_size;
|
||||
|
||||
@@ -3940,14 +3934,10 @@ static long putDoubleString(
|
||||
status = (*prset->get_precision)(paddr,&precision);
|
||||
else
|
||||
status=S_db_precision;
|
||||
if(status) {
|
||||
recGblRecSupError(status,paddr,"dbPutField","get_precision");
|
||||
return(status);
|
||||
}
|
||||
|
||||
if(nRequest==1 && offset==0) {
|
||||
cvtDoubleToString(*pbuffer,pdest,precision);
|
||||
return(0);
|
||||
return(status);
|
||||
}
|
||||
pdest += (size*offset);
|
||||
while (nRequest) {
|
||||
@@ -3959,7 +3949,7 @@ static long putDoubleString(
|
||||
pdest += size;
|
||||
nRequest--;
|
||||
}
|
||||
return(0);
|
||||
return(status);
|
||||
}
|
||||
|
||||
static long putDoubleChar(
|
||||
|
||||
+2
-1
@@ -29,7 +29,8 @@
|
||||
* .01 13OCT95 mrk Created header file as part of extracting convert from
|
||||
* dbLink
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <dbFldTypes.h>
|
||||
extern long (*dbGetConvertRoutine[DBF_DEVICE+1][DBR_ENUM+1])
|
||||
(DBADDR *paddr, void *pbuffer,long nRequest, long no_elements, long offset);
|
||||
|
||||
+30
-58
@@ -85,41 +85,21 @@ extern struct dbBase *pdbbase;
|
||||
* will have this conversion.
|
||||
*/
|
||||
|
||||
/* Uninitialized Conversion */
|
||||
long cvt_uninit(
|
||||
void *from,
|
||||
void *to,
|
||||
struct dbAddr *paddr)
|
||||
{
|
||||
recGblDbaddrError(-1,paddr,"cvt_uninit: uninitialized link");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Dummy Conversion
|
||||
* In the case of an unsupported conversion, run this
|
||||
* dummy function instead to avoid a bus error.
|
||||
*/
|
||||
long cvt_dummy(
|
||||
void *from,
|
||||
void *to,
|
||||
struct dbAddr *paddr)
|
||||
{ return(-1); }
|
||||
|
||||
/* Convert String to String */
|
||||
static long cvt_st_st(
|
||||
char *from,
|
||||
char *to,
|
||||
struct dbAddr *paddr)
|
||||
{
|
||||
char size = paddr->field_size;
|
||||
|
||||
if (size >= MAX_STRING_SIZE)
|
||||
size = MAX_STRING_SIZE - 1;
|
||||
char size;
|
||||
|
||||
if(paddr && paddr->field_size<MAX_STRING_SIZE) {
|
||||
size = paddr->field_size - 1;
|
||||
} else {
|
||||
size = MAX_STRING_SIZE - 1;
|
||||
}
|
||||
strncpy(to, from, size);
|
||||
*(to+size) = '\000';
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -257,10 +237,10 @@ static long cvt_st_e(
|
||||
unsigned short *to,
|
||||
struct dbAddr *paddr)
|
||||
{
|
||||
struct rset *prset;
|
||||
struct rset *prset = 0;
|
||||
long status;
|
||||
|
||||
prset = dbGetRset(paddr);
|
||||
if(paddr) prset = dbGetRset(paddr);
|
||||
|
||||
if (prset && prset->put_enum_str)
|
||||
return (*prset->put_enum_str)(paddr, from);
|
||||
@@ -760,24 +740,17 @@ static long cvt_f_st(
|
||||
char *to,
|
||||
struct dbAddr *paddr)
|
||||
{
|
||||
struct rset *prset;
|
||||
struct rset *prset = 0;
|
||||
long status = 0;
|
||||
long precision = 2;
|
||||
long precision = 0;
|
||||
|
||||
prset = dbGetRset(paddr);
|
||||
if(paddr) prset = dbGetRset(paddr);
|
||||
|
||||
if (prset && prset->get_precision)
|
||||
(*prset->get_precision)(paddr, &precision);
|
||||
status = (*prset->get_precision)(paddr, &precision);
|
||||
else
|
||||
status = S_db_precision;
|
||||
|
||||
if (status) {
|
||||
recGblRecSupError(status, paddr, "dbGetField", "get_precision");
|
||||
return(status);
|
||||
}
|
||||
|
||||
cvtFloatToString(*from, to, precision);
|
||||
|
||||
return(status);
|
||||
}
|
||||
|
||||
@@ -850,24 +823,17 @@ static long cvt_d_st(
|
||||
char *to,
|
||||
struct dbAddr *paddr)
|
||||
{
|
||||
struct rset *prset;
|
||||
struct rset *prset = 0;
|
||||
long status = 0;
|
||||
long precision = 2;
|
||||
long precision = 0;
|
||||
|
||||
prset = dbGetRset(paddr);
|
||||
if(paddr) prset = dbGetRset(paddr);
|
||||
|
||||
if (prset && prset->get_precision)
|
||||
(*prset->get_precision)(paddr, &precision);
|
||||
status = (*prset->get_precision)(paddr, &precision);
|
||||
else
|
||||
status = S_db_precision;
|
||||
|
||||
if (status) {
|
||||
recGblRecSupError(status, paddr, "dbGetField", "get_precision");
|
||||
return(status);
|
||||
}
|
||||
|
||||
cvtDoubleToString(*from, to, precision);
|
||||
|
||||
return(status);
|
||||
}
|
||||
|
||||
@@ -1005,10 +971,10 @@ static long cvt_e_st_get(
|
||||
char *to,
|
||||
struct dbAddr *paddr)
|
||||
{
|
||||
struct rset *prset;
|
||||
struct rset *prset = 0;
|
||||
long status;
|
||||
|
||||
prset = dbGetRset(paddr);
|
||||
if(paddr) prset = dbGetRset(paddr);
|
||||
|
||||
if (prset && prset->get_enum_str)
|
||||
return (*prset->get_enum_str)(paddr, to);
|
||||
@@ -1032,12 +998,15 @@ static long cvt_menu_st(
|
||||
char *to,
|
||||
struct dbAddr *paddr)
|
||||
{
|
||||
dbFldDes *pdbFldDes = (dbFldDes *)paddr->pfldDes;
|
||||
dbMenu *pdbMenu = (dbMenu *)pdbFldDes->ftPvt;
|
||||
dbFldDes *pdbFldDes;
|
||||
dbMenu *pdbMenu;
|
||||
char **papChoiceValue;
|
||||
char *pchoice;
|
||||
|
||||
if( !pdbMenu || *from>=pdbMenu->nChoice
|
||||
if(! paddr
|
||||
|| !(pdbFldDes = (dbFldDes *)paddr->pfldDes)
|
||||
|| !(pdbMenu = (dbMenu *)pdbFldDes->ftPvt)
|
||||
|| *from>=pdbMenu->nChoice
|
||||
|| !(papChoiceValue = pdbMenu->papChoiceValue)
|
||||
|| !(pchoice=papChoiceValue[*from])) {
|
||||
recGblDbaddrError(S_db_badChoice,paddr,"dbFastLinkConv(cvt_menu_st)");
|
||||
@@ -1054,12 +1023,15 @@ static long cvt_device_st(
|
||||
char *to,
|
||||
struct dbAddr *paddr)
|
||||
{
|
||||
dbFldDes *pdbFldDes = (dbFldDes *)paddr->pfldDes;
|
||||
dbDeviceMenu *pdbDeviceMenu = (dbDeviceMenu *)pdbFldDes->ftPvt;
|
||||
dbFldDes *pdbFldDes;
|
||||
dbDeviceMenu *pdbDeviceMenu;
|
||||
char **papChoice;
|
||||
char *pchoice;
|
||||
|
||||
if( !pdbDeviceMenu || *from>=pdbDeviceMenu->nChoice
|
||||
if(!paddr
|
||||
|| !(pdbFldDes = (dbFldDes *)paddr->pfldDes)
|
||||
|| !(pdbDeviceMenu = (dbDeviceMenu *)pdbFldDes->ftPvt)
|
||||
|| *from>=pdbDeviceMenu->nChoice
|
||||
|| !(papChoice= pdbDeviceMenu->papChoice)
|
||||
|| !(pchoice=papChoice[*from])) {
|
||||
recGblDbaddrError(S_db_badChoice,paddr,"dbFastLinkConv(cvt_device_st)");
|
||||
|
||||
+495
@@ -0,0 +1,495 @@
|
||||
/* dbLock.c */
|
||||
/* Author: Marty Kraimer Date: 12MAR96 */
|
||||
/*****************************************************************
|
||||
COPYRIGHT NOTIFICATION
|
||||
*****************************************************************
|
||||
|
||||
(C) COPYRIGHT 1991 Regents of the University of California,
|
||||
and the University of Chicago Board of Governors.
|
||||
|
||||
This software was developed under a United States Government license
|
||||
described on the COPYRIGHT_Combined file included as part
|
||||
of this distribution.
|
||||
**********************************************************************/
|
||||
|
||||
/* Modification Log:
|
||||
* -----------------
|
||||
* .01 12MAR96 mrk Initial Implementation
|
||||
*/
|
||||
|
||||
/************** DISCUSSION OF DYNAMIC LINK MODIFICATION **********************
|
||||
|
||||
Since the purpose of lock sets is to prevent multiple tasks from simultaneously
|
||||
accessing records in set, dynamically changing lock sets presents a problem.
|
||||
|
||||
Four problems arise:
|
||||
|
||||
1) Two tasks simultaneoulsy trying to change lock sets
|
||||
2) Another task has successfully issued a dbScanLock and currently owns it.
|
||||
3) A task is waiting for dbScanLock.
|
||||
4) While lock set is being changed, a task issues a dbScanLock.
|
||||
|
||||
Solution:
|
||||
|
||||
A routine attempting to modify a link must do the following:
|
||||
|
||||
Call dbLockSetGblLock before modifying any link and dbLockSetGblUnlock after.
|
||||
Call dbLockSetRecordLock for any record referenced during change.
|
||||
Call dbLockSetSplit before changing any link that is originally a DB_LINK
|
||||
Call dbLockSetMerge if changed link becomes a DB_LINK.
|
||||
|
||||
Discussion:
|
||||
|
||||
|
||||
Each problem above is solved as follows:
|
||||
1) dbLockGlobal solves this problem.
|
||||
2) dbLockSetRecordLock solves this problem.
|
||||
3) After changing lock sets original semId id deleted.
|
||||
This makes all tasks in semTake for that semaphore fail.
|
||||
The code in dbScanLock makes task recover.
|
||||
4) The global variable changingLockSets and code in
|
||||
dbScanLock and semFlush in dbLockSetGblUnlock solves
|
||||
this problem.
|
||||
|
||||
Note that all other tasks are prevented from processing records between
|
||||
dbLockSetGblLock and dbLockSetGblUnlock.
|
||||
|
||||
dblls may crash if executed while lock sets are being modified.
|
||||
It is NOT a good idea to make it more robust by issuing dbLockSetGblLock
|
||||
since this will delay all other tasks.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <lstLib.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <semLib.h>
|
||||
#include <tickLib.h>
|
||||
#include <sysLib.h>
|
||||
#include <taskLib.h>
|
||||
|
||||
#include <dbDefs.h>
|
||||
#include <dbBase.h>
|
||||
#include <ellLib.h>
|
||||
#include <dbAccess.h>
|
||||
#include <dbStaticLib.h>
|
||||
#include <dbConvert.h>
|
||||
#include <dbCommon.h>
|
||||
#include <dbLock.h>
|
||||
#include <epicsPrint.h>
|
||||
#include <dbFldTypes.h>
|
||||
#include <errMdef.h>
|
||||
|
||||
#define STATIC static
|
||||
|
||||
STATIC int lockListInitialized = FALSE;
|
||||
|
||||
STATIC ELLLIST lockList;
|
||||
STATIC SEM_ID globalLockSemId;
|
||||
STATIC SEM_ID globalWaitSemid;
|
||||
STATIC unsigned long id = 0;
|
||||
STATIC int changingLockSets = FALSE;
|
||||
|
||||
typedef struct lockSet {
|
||||
ELLNODE node;
|
||||
ELLLIST recordList;
|
||||
SEM_ID semId;
|
||||
ULONG start_time;
|
||||
int task_id;
|
||||
dbCommon *precord;
|
||||
unsigned long id;
|
||||
} lockSet;
|
||||
|
||||
typedef struct lockRecord {
|
||||
ELLNODE node;
|
||||
lockSet *plockSet;
|
||||
dbCommon *precord;
|
||||
} lockRecord;
|
||||
|
||||
/*private routines */
|
||||
STATIC void initLockList(void)
|
||||
{
|
||||
ellInit(&lockList);
|
||||
if((globalLockSemId = semBCreate(SEM_Q_FIFO,SEM_FULL))==0) {
|
||||
errMessage(0,"allocLockNode called semBCreate\n");
|
||||
exit(-1);
|
||||
}
|
||||
if((globalWaitSemid = semBCreate(SEM_Q_FIFO,SEM_EMPTY))==0) {
|
||||
errMessage(0,"allocLockNode called semBCreate\n");
|
||||
exit(-1);
|
||||
}
|
||||
lockListInitialized = TRUE;
|
||||
}
|
||||
|
||||
STATIC lockSet * allocLock(lockRecord *plockRecord)
|
||||
{
|
||||
lockSet *plockSet;
|
||||
|
||||
if(!lockListInitialized) initLockList();
|
||||
plockSet = dbCalloc(1,sizeof(lockSet));
|
||||
ellInit(&plockSet->recordList);
|
||||
plockRecord->plockSet = plockSet;
|
||||
id++;
|
||||
plockSet->id = id;
|
||||
ellAdd(&plockSet->recordList,&plockRecord->node);
|
||||
ellAdd(&lockList,&plockSet->node);
|
||||
if((plockSet->semId = semBCreate(SEM_Q_FIFO,SEM_FULL))==0) {
|
||||
errMessage(0,"allocLockNode called semBCreate\n");
|
||||
exit(-1);
|
||||
}
|
||||
return(plockSet);
|
||||
}
|
||||
|
||||
/*Add new lockRecord to lockSet list*/
|
||||
STATIC void lockAddRecord(lockSet *plockSet,lockRecord *pnew)
|
||||
{
|
||||
pnew->plockSet = plockSet;
|
||||
ellAdd(&plockSet->recordList,&pnew->node);
|
||||
}
|
||||
|
||||
void dbLockSetGblLock(void)
|
||||
{
|
||||
STATUS status;
|
||||
|
||||
if(!lockListInitialized) initLockList();
|
||||
status = semTake(globalLockSemId,WAIT_FOREVER);
|
||||
if(status!=OK) {
|
||||
epicsPrintf("dbLockSetGblLock failure\n");
|
||||
taskSuspend(0);
|
||||
}
|
||||
changingLockSets = TRUE;
|
||||
}
|
||||
|
||||
void dbLockSetGblUnlock(void)
|
||||
{
|
||||
taskLock();
|
||||
changingLockSets = FALSE;
|
||||
semFlush(globalWaitSemid);
|
||||
taskUnlock();
|
||||
semGive(globalLockSemId);
|
||||
return;
|
||||
}
|
||||
|
||||
void dbLockSetRecordLock(dbCommon *precord)
|
||||
{
|
||||
lockRecord *plockRecord = (lockRecord *)precord->lset;
|
||||
lockSet *plockSet;
|
||||
STATUS status;
|
||||
|
||||
/*Make sure that dbLockSetGblLock was called*/
|
||||
if(!changingLockSets) {
|
||||
epicsPrintf("dbLockSetRecordLock called before dbLockSetGblLock\n");
|
||||
taskSuspend(0);
|
||||
}
|
||||
/*Must make sure that no other task has lock*/
|
||||
if(!plockRecord) return;
|
||||
plockSet = plockRecord->plockSet;
|
||||
if(!plockSet) return;
|
||||
if(plockSet->task_id==taskIdSelf()) return;
|
||||
/*Wait for up to 1 minute*/
|
||||
status = semTake(plockRecord->plockSet->semId,sysClkRateGet()*60);
|
||||
if(status==OK) {
|
||||
plockSet->start_time = tickGet();
|
||||
plockSet->task_id = taskIdSelf();
|
||||
plockSet->precord = (void *)precord;
|
||||
/*give it back in case it will not be changed*/
|
||||
semGive(plockRecord->plockSet->semId);
|
||||
return;
|
||||
}
|
||||
/*Should never reach this point*/
|
||||
epicsPrintf("dbLockSetRecordLock timeout caller 0x%x owner 0x%x",
|
||||
taskIdSelf(),plockSet->task_id);
|
||||
epicsPrintf(" record %s\n",precord->name);
|
||||
return;
|
||||
}
|
||||
|
||||
void dbScanLock(dbCommon *precord)
|
||||
{
|
||||
lockRecord *plockRecord = (lockRecord *)precord->lset;
|
||||
lockSet *plockSet;
|
||||
STATUS status;
|
||||
|
||||
while(TRUE) {
|
||||
if(changingLockSets) {
|
||||
semTake(globalWaitSemid,WAIT_FOREVER);
|
||||
continue;
|
||||
}
|
||||
status = semTake(plockRecord->plockSet->semId,WAIT_FOREVER);
|
||||
/*semTake fails if semDelete was called while active*/
|
||||
if(status==OK) break;
|
||||
}
|
||||
plockSet = plockRecord->plockSet;
|
||||
plockSet->start_time = tickGet();
|
||||
plockSet->task_id = taskIdSelf();
|
||||
plockSet->precord = (void *)precord;
|
||||
return;
|
||||
}
|
||||
|
||||
void dbScanUnlock(dbCommon *precord)
|
||||
{
|
||||
lockRecord *plockRecord = (lockRecord *)precord->lset;
|
||||
|
||||
if(!plockRecord || !plockRecord->plockSet) {
|
||||
epicsPrintf("dbScanUnlock plockRecord or plockRecord->plockSet NULL\n");
|
||||
return;
|
||||
}
|
||||
semGive(plockRecord->plockSet->semId);
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned long dbLockGetLockId(dbCommon *precord)
|
||||
{
|
||||
lockRecord *plockRecord = (lockRecord *)precord->lset;
|
||||
lockSet *plockSet;
|
||||
|
||||
if(!plockRecord) return(0);
|
||||
plockSet = plockRecord->plockSet;
|
||||
if(!plockSet) return(0);
|
||||
return(plockSet->id);
|
||||
}
|
||||
|
||||
void dbLockInitRecords(dbBase *pdbbase)
|
||||
{
|
||||
int link;
|
||||
dbRecDes *pdbRecDes;
|
||||
dbFldDes *pdbFldDes;
|
||||
dbRecordNode *pdbRecordNode;
|
||||
dbCommon *precord;
|
||||
DBLINK *plink;
|
||||
int nrecords=0;
|
||||
lockRecord *plockRecord;
|
||||
|
||||
/*Allocate and initialize a lockRecord for each record instance*/
|
||||
for(pdbRecDes = (dbRecDes *)ellFirst(&pdbbase->recDesList); pdbRecDes;
|
||||
pdbRecDes = (dbRecDes *)ellNext(&pdbRecDes->node)) {
|
||||
nrecords += ellCount(&pdbRecDes->recList);
|
||||
}
|
||||
/*Allocate all of them at once */
|
||||
plockRecord = dbCalloc(nrecords,sizeof(lockRecord));
|
||||
for(pdbRecDes = (dbRecDes *)ellFirst(&pdbbase->recDesList); pdbRecDes;
|
||||
pdbRecDes = (dbRecDes *)ellNext(&pdbRecDes->node)) {
|
||||
for (pdbRecordNode=(dbRecordNode *)ellFirst(&pdbRecDes->recList);
|
||||
pdbRecordNode;
|
||||
pdbRecordNode = (dbRecordNode *)ellNext(&pdbRecordNode->node)) {
|
||||
precord = pdbRecordNode->precord;
|
||||
plockRecord->precord = precord;
|
||||
precord->lset = plockRecord;
|
||||
plockRecord++;
|
||||
}
|
||||
}
|
||||
for(pdbRecDes = (dbRecDes *)ellFirst(&pdbbase->recDesList); pdbRecDes;
|
||||
pdbRecDes = (dbRecDes *)ellNext(&pdbRecDes->node)) {
|
||||
for (pdbRecordNode=(dbRecordNode *)ellFirst(&pdbRecDes->recList);
|
||||
pdbRecordNode;
|
||||
pdbRecordNode = (dbRecordNode *)ellNext(&pdbRecordNode->node)) {
|
||||
precord = pdbRecordNode->precord;
|
||||
if(!(precord->name[0])) continue;
|
||||
for(link=0; link<pdbRecDes->no_links; link++) {
|
||||
DBADDR *pdbAddr;
|
||||
|
||||
pdbFldDes = pdbRecDes->papFldDes[pdbRecDes->link_ind[link]];
|
||||
plink = (DBLINK *)((char *)precord + pdbFldDes->offset);
|
||||
if(plink->type != DB_LINK) continue;
|
||||
pdbAddr = (DBADDR *)(plink->value.pv_link.pvt);
|
||||
/* The current record is in a different lockset -IF-
|
||||
* 1. Input link
|
||||
* 2. Not Process Passive
|
||||
* 3. Not Maximize Severity
|
||||
* 4. Not An Array Operation - single element only
|
||||
*/
|
||||
if (pdbFldDes->field_type==DBF_INLINK
|
||||
&& !(plink->value.pv_link.pvlMask&pvlOptPP)
|
||||
&& !(plink->value.pv_link.pvlMask&pvlOptMS)
|
||||
&& pdbAddr->no_elements<=1) continue;
|
||||
dbLockSetMerge(precord,pdbAddr->precord);
|
||||
}
|
||||
plockRecord = (lockRecord *)precord->lset;
|
||||
if(!plockRecord->plockSet) allocLock(plockRecord);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dbLockSetMerge(dbCommon *pfirst,dbCommon *psecond)
|
||||
{
|
||||
lockRecord *p1lockRecord = (lockRecord *)pfirst->lset;
|
||||
lockRecord *p2lockRecord = (lockRecord *)psecond->lset;
|
||||
lockSet *p1lockSet;
|
||||
lockSet *p2lockSet;
|
||||
|
||||
p1lockSet = p1lockRecord->plockSet;
|
||||
p2lockSet = p2lockRecord->plockSet;
|
||||
if(!p1lockSet) {
|
||||
if(p2lockSet) {
|
||||
lockAddRecord(p2lockSet,p1lockRecord);
|
||||
return;
|
||||
}
|
||||
p1lockSet = allocLock(p1lockRecord);
|
||||
}
|
||||
if(p1lockSet == p2lockSet) return;
|
||||
if(!p2lockSet) {
|
||||
lockAddRecord(p1lockSet,p2lockRecord);
|
||||
return;
|
||||
}
|
||||
/*Move entire second list to first*/
|
||||
p2lockRecord = (lockRecord *)ellFirst(&p2lockSet->recordList);
|
||||
while(p2lockRecord) {
|
||||
p2lockRecord->plockSet = p1lockSet;
|
||||
p2lockRecord = (lockRecord *)ellNext(&p2lockRecord->node);
|
||||
}
|
||||
ellConcat(&p1lockSet->recordList,&p2lockSet->recordList);
|
||||
if(semDelete(p2lockSet->semId)!=OK) {
|
||||
errMessage(0,"dbLockSetMerge calling semDelete");
|
||||
taskSuspend(0);
|
||||
}
|
||||
ellDelete(&lockList,&p2lockSet->node);
|
||||
free((void *)p2lockSet);
|
||||
return;
|
||||
}
|
||||
|
||||
void dbLockSetSplit(dbCommon *psource)
|
||||
{
|
||||
lockSet *plockSet;
|
||||
lockRecord *plockRecord;
|
||||
dbCommon *precord;
|
||||
int link;
|
||||
dbRecDes *pdbRecDes;
|
||||
dbFldDes *pdbFldDes;
|
||||
DBLINK *plink;
|
||||
int nrecordsInSet,i;
|
||||
dbCommon **paprecord;
|
||||
|
||||
plockRecord = (lockRecord *)psource->lset;
|
||||
if(!plockRecord) {
|
||||
errMessage(-1,"dbLockSetSplit called before lockRecord allocated");
|
||||
return;
|
||||
}
|
||||
plockSet = plockRecord->plockSet;
|
||||
if(!plockSet) {
|
||||
errMessage(-1,"dbLockSetSplit called without lockSet allocated");
|
||||
return;
|
||||
}
|
||||
/*First remove all records from lock set*/
|
||||
nrecordsInSet = ellCount(&plockSet->recordList);
|
||||
paprecord = dbCalloc(nrecordsInSet,sizeof(dbCommon *));
|
||||
for(plockRecord = (lockRecord *)ellFirst(&plockSet->recordList), i=0;
|
||||
plockRecord;
|
||||
plockRecord = (lockRecord *)ellNext(&plockRecord->node), i++) {
|
||||
paprecord[i] = plockRecord->precord;
|
||||
plockRecord->plockSet = 0;
|
||||
}
|
||||
/*Now recompute lock sets */
|
||||
for(i=0; i<nrecordsInSet; i++) {
|
||||
precord = paprecord[i];
|
||||
plockRecord = (lockRecord *)precord->lset;
|
||||
if(!(precord->name[0])) continue;
|
||||
pdbRecDes = (dbRecDes *)precord->rdes;
|
||||
for(link=0; link<pdbRecDes->no_links; link++) {
|
||||
DBADDR *pdbAddr;
|
||||
|
||||
pdbFldDes = pdbRecDes->papFldDes[pdbRecDes->link_ind[link]];
|
||||
plink = (DBLINK *)((char *)precord + pdbFldDes->offset);
|
||||
if(plink->type != DB_LINK) continue;
|
||||
|
||||
pdbAddr = (DBADDR *)(plink->value.pv_link.pvt);
|
||||
if (pdbFldDes->field_type==DBF_INLINK
|
||||
&& !(plink->value.pv_link.pvlMask&pvlOptPP)
|
||||
&& !(plink->value.pv_link.pvlMask&pvlOptMS)
|
||||
&& pdbAddr->no_elements<=1) continue;
|
||||
dbLockSetMerge(precord,pdbAddr->precord);
|
||||
}
|
||||
if(!plockRecord->plockSet) allocLock(plockRecord);
|
||||
}
|
||||
if(semDelete(plockSet->semId)!=OK) {
|
||||
errMessage(0,"dbLockSetSplit calling semDelete");
|
||||
taskSuspend(0);
|
||||
}
|
||||
ellDelete(&lockList,&plockSet->node);
|
||||
free((void *)plockSet);
|
||||
free((void *)paprecord);
|
||||
}
|
||||
|
||||
extern struct dbBase *pdbbase;
|
||||
long dblls(char *recordname,int level)
|
||||
{
|
||||
int link;
|
||||
DBENTRY dbentry;
|
||||
DBENTRY *pdbentry=&dbentry;
|
||||
long status;
|
||||
dbCommon *precord;
|
||||
lockSet *plockSet;
|
||||
lockRecord *plockRecord;
|
||||
dbRecDes *pdbRecDes;
|
||||
dbFldDes *pdbFldDes;
|
||||
DBLINK *plink;
|
||||
|
||||
if(recordname) {
|
||||
dbInitEntry(pdbbase,pdbentry);
|
||||
status = dbFindRecord(pdbentry,recordname);
|
||||
if(status) {
|
||||
printf("Record not found\n");
|
||||
dbFinishEntry(pdbentry);
|
||||
return(0);
|
||||
}
|
||||
precord = pdbentry->precnode->precord;
|
||||
dbFinishEntry(pdbentry);
|
||||
plockRecord = (lockRecord *)precord->lset;
|
||||
if(!plockRecord) return(0);
|
||||
plockSet = plockRecord->plockSet;
|
||||
} else {
|
||||
plockSet = (lockSet *)ellFirst(&lockList);
|
||||
}
|
||||
for( ; plockSet; plockSet = (lockSet *)ellNext(&plockSet->node)) {
|
||||
double lockSeconds;
|
||||
|
||||
printf("Lock Set %lu %d members",
|
||||
plockSet->id,ellCount(&plockSet->recordList));
|
||||
if(semTake(plockSet->semId,NO_WAIT)==OK) {
|
||||
semGive(plockSet->semId);
|
||||
printf(" Not Locked\n");
|
||||
} else {
|
||||
lockSeconds = plockSet->start_time;
|
||||
lockSeconds = (tickGet() - lockSeconds) / sysClkRateGet();
|
||||
printf(" Locked %f seconds", lockSeconds);
|
||||
printf(" task 0x%x",plockSet->task_id);
|
||||
if(! plockSet->precord || !plockSet->precord->name)
|
||||
printf(" NULL record or record name\n");
|
||||
else
|
||||
printf(" record %s\n",plockSet->precord->name);
|
||||
}
|
||||
if(level==0) {
|
||||
if(recordname) break;
|
||||
continue;
|
||||
}
|
||||
for(plockRecord = (lockRecord *)ellFirst(&plockSet->recordList);
|
||||
plockRecord; plockRecord = (lockRecord *)ellNext(&plockRecord->node)) {
|
||||
precord = plockRecord->precord;
|
||||
pdbRecDes = (dbRecDes *)precord->rdes;
|
||||
printf("%s\n",precord->name);
|
||||
if(level<=1) continue;
|
||||
for(link=0; (link<pdbRecDes->no_links) ; link++) {
|
||||
DBADDR *pdbAddr;
|
||||
|
||||
pdbFldDes = pdbRecDes->papFldDes[pdbRecDes->link_ind[link]];
|
||||
plink = (DBLINK *)((char *)precord + pdbFldDes->offset);
|
||||
if(plink->type != DB_LINK) continue;
|
||||
pdbAddr = (DBADDR *)(plink->value.pv_link.pvt);
|
||||
printf("\t%s",pdbFldDes->name);
|
||||
if(pdbFldDes->field_type==DBF_INLINK) {
|
||||
printf("\t INLINK");
|
||||
} else if(pdbFldDes->field_type==DBF_OUTLINK) {
|
||||
printf("\tOUTLINK");
|
||||
} else if(pdbFldDes->field_type==DBF_FWDLINK) {
|
||||
printf("\tFWDLINK");
|
||||
}
|
||||
printf(" %s %s",
|
||||
((plink->value.pv_link.pvlMask&pvlOptPP)?" PP":"NPP"),
|
||||
((plink->value.pv_link.pvlMask&pvlOptMS)?" MS":"NMS"));
|
||||
printf(" %s\n",pdbAddr->precord->name);
|
||||
}
|
||||
}
|
||||
if(recordname) break;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/* dbLock.h */
|
||||
/* Author: Marty Kraimer Date: 12MAR96 */
|
||||
/*****************************************************************
|
||||
COPYRIGHT NOTIFICATION
|
||||
*****************************************************************
|
||||
|
||||
(C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO
|
||||
|
||||
This software was developed under a United States Government license
|
||||
described on the COPYRIGHT_UniversityOfChicago file included as part
|
||||
of this distribution.
|
||||
**********************************************************************/
|
||||
|
||||
/* Modification Log:
|
||||
* -----------------
|
||||
* .01 12MAR96 mrk Initial Implementation
|
||||
*/
|
||||
#ifndef INCdbLockh
|
||||
#define INCdbLockh
|
||||
void dbScanLock(struct dbCommon *precord);
|
||||
void dbScanUnlock(struct dbCommon *precord);
|
||||
unsigned long dbLockGetLockId(struct dbCommon *precord);
|
||||
|
||||
void dbLockInitRecords(dbBase *pdbbase);
|
||||
void dbLockSetMerge(struct dbCommon *pfirst,struct dbCommon *psecond);
|
||||
void dbLockSetSplit(struct dbCommon *psource);
|
||||
/*The following are for code that modifies lock sets*/
|
||||
void dbLockSetGblLock(void);
|
||||
void dbLockSetGblUnlock(void);
|
||||
void dbLockSetRecordLock(struct dbCommon *precord);
|
||||
|
||||
long dblls(char *recordname,int level); /*list all records in same lock set*/
|
||||
/* If recordname NULL then all records*/
|
||||
/* level = (0,1,2) (lock set state, + recordname, +DB links) */
|
||||
|
||||
#endif /*INCdbLockh*/
|
||||
+13
-4
@@ -63,6 +63,7 @@
|
||||
#include <callback.h>
|
||||
#include <dbBase.h>
|
||||
#include <dbCommon.h>
|
||||
#include <dbLock.h>
|
||||
#include <devSup.h>
|
||||
#include <recGbl.h>
|
||||
#include <task_params.h>
|
||||
@@ -72,7 +73,7 @@
|
||||
extern struct dbBase *pdbbase;
|
||||
|
||||
/* SCAN ONCE */
|
||||
#define ONCE_QUEUE_SIZE 256
|
||||
int onceQueueSize = 256;
|
||||
static SEM_ID onceSem;
|
||||
static RING_ID onceQ;
|
||||
static int onceTaskId;
|
||||
@@ -426,9 +427,15 @@ static void onceTask(void)
|
||||
}
|
||||
}
|
||||
|
||||
int scanOnceSetQueueSize(int size)
|
||||
{
|
||||
onceQueueSize = size;
|
||||
return(0);
|
||||
}
|
||||
|
||||
static void initOnce(void)
|
||||
{
|
||||
if((onceQ = rngCreate(sizeof(void *) * ONCE_QUEUE_SIZE))==NULL){
|
||||
if((onceQ = rngCreate(sizeof(void *) * onceQueueSize))==NULL){
|
||||
errMessage(0,"dbScan: initOnce failed");
|
||||
exit(1);
|
||||
}
|
||||
@@ -485,10 +492,12 @@ static void initPeriodic()
|
||||
|
||||
static void spawnPeriodic(int ind)
|
||||
{
|
||||
struct scan_list *psl;
|
||||
struct scan_list *psl;
|
||||
char taskName[20];
|
||||
|
||||
psl = papPeriodic[ind];
|
||||
periodicTaskId[ind] = taskSpawn(PERIODSCAN_NAME,PERIODSCAN_PRI-ind,
|
||||
sprintf(taskName,"scan%d",psl->ticks);
|
||||
periodicTaskId[ind] = taskSpawn(taskName,PERIODSCAN_PRI-ind,
|
||||
PERIODSCAN_OPT,PERIODSCAN_STACK,
|
||||
(FUNCPTR )periodicTask,(int)psl,
|
||||
0,0,0,0,0,0,0,0,0);
|
||||
|
||||
@@ -50,6 +50,7 @@ void post_event(int event);
|
||||
void scanAdd(struct dbCommon *);
|
||||
void scanDelete(struct dbCommon *);
|
||||
void scanOnce(void *precord);
|
||||
int scanOnceSetQueueSize(int size);
|
||||
int scanppl(void); /*print periodic lists*/
|
||||
int scanpel(void); /*print event lists*/
|
||||
int scanpiol(void); /*print io_event list*/
|
||||
|
||||
+33
-204
@@ -57,8 +57,6 @@ long dbtgf(char *pname); /*test get field*/
|
||||
long dbtpf(char *pname,char *pvalue); /*test put field*/
|
||||
long dbior(char *pdrvName,int type); /*I/O report */
|
||||
int dbhcr(void); /*Hardware Configuration Report*/
|
||||
long dblls(int lockset); /*list lock sets*/
|
||||
int dbllsdblinks(int lset); /*List dblinks for each record in lock set*/
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <stdlib.h>
|
||||
@@ -72,6 +70,7 @@ int dbllsdblinks(int lset); /*List dblinks for each record in lock set*/
|
||||
#include <dbAccess.h>
|
||||
#include <dbBase.h>
|
||||
#include <dbCommon.h>
|
||||
#include <dbLock.h>
|
||||
#include <recSup.h>
|
||||
#include <devSup.h>
|
||||
#include <drvSup.h>
|
||||
@@ -110,8 +109,8 @@ static void dbpr_init_msg(TAB_BUFFER *pMsgBuff,int tab_size);
|
||||
static void dbpr_insert_msg(TAB_BUFFER *pMsgBuff,int len,int tab_size);
|
||||
static void dbpr_msg_flush(TAB_BUFFER *pMsgBuff,int tab_size);
|
||||
static void dbprReportLink(
|
||||
TAB_BUFFER *pMsgBuff,char *pfield_name,struct link *plink,
|
||||
short field_type,int tab_size);
|
||||
TAB_BUFFER *pMsgBuff,char *precord_name, char *pfield_name,
|
||||
struct link *plink, short field_type,int tab_size);
|
||||
static void dbprReportMenu(
|
||||
TAB_BUFFER *pMsgBuff,struct dbCommon *precord,dbFldDes *pdbFldDes,
|
||||
unsigned short choice_value,int tab_size);
|
||||
@@ -693,37 +692,6 @@ int dbhcr(void)
|
||||
return(0);
|
||||
}
|
||||
|
||||
long dblls(int lockset)
|
||||
{
|
||||
DBENTRY dbentry;
|
||||
DBENTRY *pdbentry=&dbentry;
|
||||
long status;
|
||||
struct dbCommon *precord;
|
||||
|
||||
dbInitEntry(pdbbase,pdbentry);
|
||||
status = dbFirstRecdes(pdbentry);
|
||||
printf(" lset lcnt disv disa pact\n");
|
||||
while(!status) {
|
||||
status = dbFirstRecord(pdbentry);
|
||||
while(!status) {
|
||||
precord = pdbentry->precnode->precord;
|
||||
if(lockset==0 || lockset==precord->lset) {
|
||||
printf("%5.5d %5.5d %5.5d %5.5d %5.5d %s\n",
|
||||
precord->lset,
|
||||
precord->lcnt,
|
||||
precord->disv,
|
||||
precord->disa,
|
||||
precord->pact,
|
||||
precord->name);
|
||||
}
|
||||
status = dbNextRecord(pdbentry);
|
||||
}
|
||||
status = dbNextRecdes(pdbentry);
|
||||
}
|
||||
dbFinishEntry(pdbentry);
|
||||
return(0);
|
||||
}
|
||||
|
||||
static char *dbf[DBF_NTYPES]={
|
||||
"STRING","CHAR","UCHAR","SHORT","USHORT","LONG","ULONG",
|
||||
"FLOAT","DOUBLE","ENUM","MENU","DEVICE",
|
||||
@@ -1150,18 +1118,11 @@ static int dbpr_report(
|
||||
*(unsigned short *)pfield, tab_size);
|
||||
break;
|
||||
case DBF_INLINK:
|
||||
dbprReportLink(pMsgBuff, pfield_name,
|
||||
(struct link *) pfield, pdbFldDes->field_type, tab_size);
|
||||
break;
|
||||
case DBF_OUTLINK:
|
||||
dbprReportLink(pMsgBuff, pfield_name,
|
||||
(struct link *) pfield, pdbFldDes->field_type, tab_size);
|
||||
break;
|
||||
case DBF_FWDLINK:
|
||||
dbprReportLink(pMsgBuff, pfield_name,
|
||||
dbprReportLink(pMsgBuff, paddr->precord->name,pfield_name,
|
||||
(struct link *) pfield, pdbFldDes->field_type, tab_size);
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
sprintf(pmsg, "%s: dbpr: Unknown field_type", pfield_name);
|
||||
dbpr_msgOut(pMsgBuff, tab_size);
|
||||
@@ -1269,129 +1230,39 @@ static void dbpr_msg_flush(TAB_BUFFER *pMsgBuff,int tab_size)
|
||||
}
|
||||
|
||||
static void dbprReportLink(
|
||||
TAB_BUFFER *pMsgBuff,char *pfield_name,struct link *plink,
|
||||
short field_type,int tab_size)
|
||||
TAB_BUFFER *pMsgBuff,char *precordname,char *pfield_name,
|
||||
struct link *plink, short field_type,int tab_size)
|
||||
{
|
||||
char *pmsg = pMsgBuff->message;
|
||||
switch(plink->type) {
|
||||
case CONSTANT:
|
||||
sprintf(pmsg,"%4s: %s", pfield_name, plink->value.constantStr);
|
||||
dbpr_msgOut(pMsgBuff,tab_size);
|
||||
break;
|
||||
case PV_LINK:
|
||||
if(field_type != DBF_FWDLINK) {
|
||||
sprintf(pmsg,"%4s: PV_LINK pp=%1d ms=%1d %s",
|
||||
pfield_name,
|
||||
plink->value.pv_link.process_passive,
|
||||
plink->value.pv_link.maximize_sevr,
|
||||
plink->value.pv_link.pvname);
|
||||
} else {
|
||||
sprintf(pmsg,"%4s: PV_LINK %s",
|
||||
pfield_name,
|
||||
plink->value.pv_link.pvname);
|
||||
}
|
||||
dbpr_msgOut(pMsgBuff,tab_size);
|
||||
break;
|
||||
case VME_IO:
|
||||
sprintf(pmsg,"%4s: VME card=%2d signal=%2d parm=%s",
|
||||
pfield_name,
|
||||
plink->value.vmeio.card,plink->value.vmeio.signal,
|
||||
plink->value.vmeio.parm);
|
||||
dbpr_msgOut(pMsgBuff,tab_size);
|
||||
break;
|
||||
case VXI_IO:
|
||||
if(plink->value.vxiio.flag==0)
|
||||
{
|
||||
sprintf(pmsg,"%4s: VXI frame=%2d slot=%2d signal=%2d parm=%s",
|
||||
pfield_name,
|
||||
plink->value.vxiio.frame,
|
||||
plink->value.vxiio.slot,
|
||||
plink->value.vxiio.signal,
|
||||
plink->value.vxiio.parm);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(pmsg,"%4s: VXI la=%2d signal=%2d parm=%s",
|
||||
pfield_name,
|
||||
plink->value.vxiio.la,
|
||||
plink->value.vxiio.signal,
|
||||
plink->value.vxiio.parm);
|
||||
}
|
||||
dbpr_msgOut(pMsgBuff,tab_size);
|
||||
break;
|
||||
case CAMAC_IO:
|
||||
sprintf(pmsg,"%4s: CAMAC b=%2d c=%2d n=%2d a=%2d f=%2d parm=%s",
|
||||
pfield_name,
|
||||
plink->value.camacio.b,plink->value.camacio.c,
|
||||
plink->value.camacio.n,plink->value.camacio.a,
|
||||
plink->value.camacio.f,plink->value.camacio.parm);
|
||||
dbpr_msgOut(pMsgBuff,tab_size);
|
||||
break;
|
||||
case AB_IO:
|
||||
sprintf(pmsg,"%4s: ABIO link=%2d adaptor=%2d card=%2d signal=%2d parm=%s",
|
||||
pfield_name,
|
||||
plink->value.abio.link,plink->value.abio.adapter,
|
||||
plink->value.abio.card,plink->value.abio.signal,
|
||||
plink->value.abio.parm);
|
||||
dbpr_msgOut(pMsgBuff,tab_size);
|
||||
break;
|
||||
case GPIB_IO:
|
||||
sprintf(pmsg,"%4s: GPIB link=%2d addr=%2d parm=%s",
|
||||
pfield_name,
|
||||
plink->value.gpibio.link, plink->value.gpibio.addr,
|
||||
&plink->value.gpibio.parm[0]);
|
||||
dbpr_msgOut(pMsgBuff,tab_size);
|
||||
break;
|
||||
case BITBUS_IO:
|
||||
sprintf(pmsg,"%4s: BITBUS link=%2d node=%2d port=%2d signal=%2d parm=%s",
|
||||
pfield_name,
|
||||
plink->value.bitbusio.link,plink->value.bitbusio.node,
|
||||
plink->value.bitbusio.port,plink->value.bitbusio.signal,
|
||||
&plink->value.bitbusio.parm[0]);
|
||||
dbpr_msgOut(pMsgBuff,tab_size);
|
||||
break;
|
||||
case BBGPIB_IO:
|
||||
sprintf(pmsg,"%4s: BBGPIBIO link=%2d bbaddr=%2d gpibio=%2d parm=%s",
|
||||
pfield_name,
|
||||
plink->value.bbgpibio.link,plink->value.bbgpibio.bbaddr,
|
||||
plink->value.bbgpibio.gpibaddr,
|
||||
&plink->value.bbgpibio.parm[0]);
|
||||
dbpr_msgOut(pMsgBuff,tab_size);
|
||||
break;
|
||||
case INST_IO:
|
||||
sprintf(pmsg,"%4s: INSTIO parm=%s",
|
||||
pfield_name,
|
||||
&plink->value.instio.string[0]);
|
||||
dbpr_msgOut(pMsgBuff,tab_size);
|
||||
break;
|
||||
case DB_LINK:
|
||||
if(field_type != DBF_FWDLINK) {
|
||||
DBADDR *paddr = (DBADDR *)plink->value.db_link.pdbAddr;
|
||||
char *pmsg = pMsgBuff->message;
|
||||
DBENTRY dbEntry;
|
||||
DBENTRY *pdbEntry;
|
||||
long status;
|
||||
char *pvalue;
|
||||
|
||||
sprintf(pmsg,"%4s: DB_LINK pp=%1d ms=%1d %s",
|
||||
pfield_name,
|
||||
plink->value.db_link.process_passive,
|
||||
plink->value.db_link.maximize_sevr,
|
||||
paddr->precord->name);
|
||||
}else{
|
||||
sprintf(pmsg,"%4s: DB_LINK %.32s",
|
||||
pfield_name,
|
||||
((struct dbCommon *)(
|
||||
((DBADDR *)plink->value.db_link.pdbAddr)
|
||||
->precord))->name);
|
||||
pdbEntry = &dbEntry;
|
||||
dbInitEntry(pdbbase,pdbEntry);
|
||||
status = dbFindRecord(pdbEntry,precordname);
|
||||
if(!status) status = dbFindField(pdbEntry,pfield_name);
|
||||
if(status) {
|
||||
sprintf(pmsg,"%4s: dbGetString Failed", pfield_name);
|
||||
} else {
|
||||
int ind;
|
||||
|
||||
for(ind=0; ind<LINK_NTYPES; ind++) {
|
||||
if(pamaplinkType[ind].value == plink->type) break;
|
||||
}
|
||||
if(ind>=LINK_NTYPES) {
|
||||
sprintf(pmsg,"%4s: Illegal Link Type", pfield_name);
|
||||
} else {
|
||||
pvalue = dbGetString(pdbEntry);
|
||||
sprintf(pmsg,"%4s:%s %s",
|
||||
pfield_name,
|
||||
pamaplinkType[ind].strvalue,
|
||||
pvalue);
|
||||
}
|
||||
dbpr_msgOut(pMsgBuff,tab_size);
|
||||
break;
|
||||
case CA_LINK:
|
||||
sprintf(pmsg,"%4s: CA_LINK",pfield_name);
|
||||
dbpr_msgOut(pMsgBuff,tab_size);
|
||||
break;
|
||||
default:
|
||||
sprintf(pmsg,"%4s: dbprReportLink: Illegal link.type",
|
||||
pfield_name);
|
||||
dbpr_msgOut(pMsgBuff,tab_size);
|
||||
break;
|
||||
}
|
||||
dbpr_msgOut(pMsgBuff,tab_size);
|
||||
dbFinishEntry(&dbEntry);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1478,45 +1349,3 @@ char *record_name;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int dbllsdblinks(int lset)
|
||||
{
|
||||
int link;
|
||||
dbRecDes *pdbRecDes;
|
||||
dbFldDes *pdbFldDes;
|
||||
dbRecordNode *pdbRecordNode;
|
||||
dbCommon *precord;
|
||||
DBLINK *plink;
|
||||
|
||||
for(pdbRecDes = (dbRecDes *)ellFirst(&pdbbase->recDesList); pdbRecDes;
|
||||
pdbRecDes = (dbRecDes *)ellNext(&pdbRecDes->node)) {
|
||||
for (pdbRecordNode=(dbRecordNode *)ellFirst(&pdbRecDes->recList);
|
||||
pdbRecordNode;
|
||||
pdbRecordNode = (dbRecordNode *)ellNext(&pdbRecordNode->node)) {
|
||||
precord = pdbRecordNode->precord;
|
||||
if(!(precord->name[0])) continue;
|
||||
if(precord->lset != lset) continue;
|
||||
printf("%s\n",precord->name);
|
||||
for(link=0; (link<pdbRecDes->no_links) ; link++) {
|
||||
DBADDR *pdbAddr;
|
||||
|
||||
pdbFldDes = pdbRecDes->papFldDes[pdbRecDes->link_ind[link]];
|
||||
plink = (DBLINK *)((char *)precord + pdbFldDes->offset);
|
||||
if(plink->type != DB_LINK) continue;
|
||||
pdbAddr = (DBADDR *)(plink->value.db_link.pdbAddr);
|
||||
if(pdbFldDes->field_type==DBF_INLINK) {
|
||||
printf("\t INLINK");
|
||||
} else if(pdbFldDes->field_type==DBF_OUTLINK) {
|
||||
printf("\tOUTLINK");
|
||||
} else if(pdbFldDes->field_type==DBF_FWDLINK) {
|
||||
printf("\tFWDLINK");
|
||||
}
|
||||
printf(" %s %s",
|
||||
((plink->value.db_link.process_passive)?" PP":"NPP"),
|
||||
((plink->value.db_link.maximize_sevr)?" MS":"NMS"));
|
||||
printf(" %s\n",pdbAddr->precord->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
+4
-3
@@ -116,6 +116,9 @@
|
||||
#define oldDBR_PUT_ACKT oldDBR_CTRL_DOUBLE + 1
|
||||
#define oldDBR_PUT_ACKS oldDBR_PUT_ACKT + 1
|
||||
#define oldDBR_STSACK_STRING oldDBR_PUT_ACKS + 1
|
||||
|
||||
/*Following is defined in db_access.h*/
|
||||
extern unsigned short dbDBRnewToDBRold[DBR_ENUM+1];
|
||||
|
||||
|
||||
/* function declarations */
|
||||
@@ -572,8 +575,6 @@ void fill(pbuffer,size,fillchar)
|
||||
/*
|
||||
* DB_NAME_TO_ADDR
|
||||
*/
|
||||
static short mapNewToOld[]={0,4,4,1,5,5,6,2,6,3};
|
||||
|
||||
short db_name_to_addr(pname,paddr)
|
||||
char *pname;
|
||||
struct dbAddr *paddr;
|
||||
@@ -588,7 +589,7 @@ short db_name_to_addr(pname,paddr)
|
||||
recGblDbaddrError(S_db_badDbrtype,paddr,"db_name_to_addr error");
|
||||
return(-2);
|
||||
}
|
||||
paddr->dbr_field_type = mapNewToOld[ftype];
|
||||
paddr->dbr_field_type = dbDBRnewToDBRold[ftype];
|
||||
return(0);
|
||||
}
|
||||
else
|
||||
|
||||
+49
-1
@@ -237,6 +237,54 @@ READONLY int epicsTypeToDBR_XXXX [lastEpicsType+1] = {
|
||||
epicsShareExtern READONLY int epicsTypeToDBR_XXXX [lastEpicsType+1];
|
||||
#endif
|
||||
|
||||
/*Definitions that allow old database access to use new conversion routines*/
|
||||
#define newDBF_DEVICE 11
|
||||
#define newDBR_ENUM 9
|
||||
#ifdef __STDC__
|
||||
void *dbCalloc(size_t nobj,size_t size);
|
||||
void *dbMalloc(size_t size);
|
||||
extern long (*dbGetConvertRoutine[newDBF_DEVICE+1][newDBR_ENUM+1])
|
||||
(struct db_addr *paddr, void *pbuffer,long nRequest,
|
||||
long no_elements, long offset);
|
||||
extern long (*dbPutConvertRoutine[newDBR_ENUM+1][newDBF_DEVICE+1])
|
||||
(struct db_addr *paddr, void *pbuffer,long nRequest,
|
||||
long no_elements, long offset);
|
||||
extern long (*dbFastGetConvertRoutine[newDBF_DEVICE+1][newDBR_ENUM+1])();
|
||||
extern long (*dbFastPutConvertRoutine[newDBR_ENUM+1][newDBF_DEVICE+1])();
|
||||
#else
|
||||
extern long (*dbGetConvertRoutine[newDBF_DEVICE+1][newDBR_ENUM+1]) ();
|
||||
extern long (*dbPutConvertRoutine[newDBR_ENUM+1][newDBF_DEVICE+1]) ();
|
||||
extern long (*dbFastGetConvertRoutine[newDBF_DEVICE+1][newDBR_ENUM+1])();
|
||||
extern long (*dbFastPutConvertRoutine[newDBR_ENUM+1][newDBF_DEVICE+1])();
|
||||
#endif /*__STDC__*/
|
||||
|
||||
/*Conversion between old and new DBR types*/
|
||||
extern unsigned short dbDBRoldToDBFnew[DBR_DOUBLE+1];
|
||||
extern unsigned short dbDBRnewToDBRold[newDBR_ENUM+1];
|
||||
#ifdef DB_TEXT_GLBLSOURCE
|
||||
unsigned short dbDBRoldToDBFnew[DBR_DOUBLE+1] = {
|
||||
0, /*DBR_STRING to DBF_STRING*/
|
||||
3, /*DBR_INT to DBF_SHORT*/
|
||||
7, /*DBR_FLOAT to DBF_FLOAT*/
|
||||
9, /*DBR_ENUM to DBF_ENUM*/
|
||||
1, /*DBR_CHAR to DBF_CHAR*/
|
||||
5, /*DBR_LONG to DBF_LONG*/
|
||||
8 /*DBR_DOUBLE to DBF_DOUBLE*/
|
||||
};
|
||||
unsigned short dbDBRnewToDBRold[newDBR_ENUM+1] = {
|
||||
0, /*DBR_STRING to DBR_STRING*/
|
||||
4, /*DBR_CHAR to DBR_CHAR*/
|
||||
4, /*DBR_UCHAR to DBR_CHAR*/
|
||||
1, /*DBR_SHORT to DBR_SHORT*/
|
||||
5, /*DBR_USHORT to DBR_LONG*/
|
||||
5, /*DBR_LONG to DBR_LONG*/
|
||||
6, /*DBR_ULONG to DBR_DOUBLE*/
|
||||
2, /*DBR_FLOAT to DBR_FLOAT*/
|
||||
6, /*DBR_DOUBLE to DBR_DOUBLE*/
|
||||
3, /*DBR_ENUM to DBR_ENUM*/
|
||||
};
|
||||
#endif /*DB_TEXT_GLBLSOURCE*/
|
||||
|
||||
/*
|
||||
* The DBR_XXXX types are indicies into this array
|
||||
*/
|
||||
@@ -290,7 +338,7 @@ epicsShareExtern READONLY epicsType DBR_XXXXToEpicsType [LAST_BUFFER_TYPE+1];
|
||||
#define EP_SCAN 0x01
|
||||
#define EP_INIT 0x02
|
||||
#define EP_CALC 0x03
|
||||
|
||||
|
||||
/* values returned for each field type
|
||||
* DBR_STRING returns a NULL terminated string
|
||||
* DBR_SHORT returns an unsigned short
|
||||
|
||||
+1
-1
@@ -39,7 +39,7 @@ struct db_addr{
|
||||
void *asPvt; /*Access Security Private */
|
||||
short pad1; /*not used by old */
|
||||
short no_elements; /* number of elements in arrays of data */
|
||||
short pad2; /* not used by old */
|
||||
short new_field_type; /* field type for new database access*/
|
||||
short field_size; /* size of the field being accessed */
|
||||
/* from database for values of waveforms */
|
||||
short special; /* special processing */
|
||||
|
||||
+125
@@ -0,0 +1,125 @@
|
||||
/* dbcal.c */
|
||||
/*****************************************************************
|
||||
COPYRIGHT NOTIFICATION
|
||||
*****************************************************************
|
||||
|
||||
(C) COPYRIGHT 1991 Regents of the University of California,
|
||||
and the University of Chicago Board of Governors.
|
||||
|
||||
This software was developed under a United States Government license
|
||||
described on the COPYRIGHT_Combined file included as part
|
||||
of this distribution.
|
||||
**********************************************************************/
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* Current Author: Marty Kraimer
|
||||
* Date: 10APR96
|
||||
*
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 10APR96 mrk list db to CA links
|
||||
****************************************************************/
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <taskLib.h>
|
||||
|
||||
#include "dbStaticLib.h"
|
||||
#include "link.h"
|
||||
/*definitions needed because of old vs new database access*/
|
||||
#undef DBR_SHORT
|
||||
#undef DBR_PUT_ACKT
|
||||
#undef DBR_PUT_ACKS
|
||||
#undef VALID_DB_REQ
|
||||
#undef INVALID_DB_REQ
|
||||
/*end of conflicting definitions*/
|
||||
#include "cadef.h"
|
||||
#include "epicsPrint.h"
|
||||
#include "dbCommon.h"
|
||||
#include "dbCa.h"
|
||||
extern struct dbBase *pdbbase;
|
||||
|
||||
long dbcal(char *precordname,int level)
|
||||
{
|
||||
DBENTRY dbentry;
|
||||
DBENTRY *pdbentry=&dbentry;
|
||||
long status;
|
||||
dbCommon *precord;
|
||||
dbRecDes *pdbRecDes;
|
||||
dbFldDes *pdbFldDes;
|
||||
DBLINK *plink;
|
||||
int ncalinks=0;
|
||||
int nconnected=0;
|
||||
int noReadAccess=0;
|
||||
int noWriteAccess=0;
|
||||
unsigned long nDisconnect=0;
|
||||
unsigned long nNoWrite=0;
|
||||
caLink *pca;
|
||||
int j;
|
||||
|
||||
|
||||
dbInitEntry(pdbbase,pdbentry);
|
||||
status = dbFirstRecdes(pdbentry);
|
||||
while(!status) {
|
||||
status = dbFirstRecord(pdbentry);
|
||||
while(!status) {
|
||||
if(!precordname
|
||||
|| (strcmp(precordname,dbGetRecordName(pdbentry)) ==0)) {
|
||||
pdbRecDes = pdbentry->precdes;
|
||||
precord = (dbCommon *)pdbentry->precnode->precord;
|
||||
for(j=0; j<pdbRecDes->no_links; j++) {
|
||||
pdbFldDes = pdbRecDes->papFldDes[pdbRecDes->link_ind[j]];
|
||||
plink = (DBLINK *)((char *)precord + pdbFldDes->offset);
|
||||
if (plink->type == CA_LINK) {
|
||||
ncalinks++;
|
||||
pca = (caLink *)plink->value.pv_link.pvt;
|
||||
if(pca && (ca_field_type(pca->chid) != TYPENOTCONN)) {
|
||||
nconnected++;
|
||||
nDisconnect += pca->nDisconnect;
|
||||
nNoWrite += pca->nNoWrite;
|
||||
if(!ca_read_access(pca->chid)) noReadAccess++;
|
||||
if(!ca_write_access(pca->chid)) noWriteAccess++;
|
||||
if(level>1) {
|
||||
printf(" connected");
|
||||
printf("%s",ca_host_name(pca->chid));
|
||||
if(!ca_read_access(pca->chid))
|
||||
printf(" no_read_access");
|
||||
if(!ca_write_access(pca->chid))
|
||||
printf(" no_write_access");
|
||||
printf(" %s.%s %s",
|
||||
precord->name,
|
||||
pdbFldDes->name,
|
||||
plink->value.pv_link.pvname);
|
||||
printf(" nDisconnect %lu nNoWrite %lu\n",
|
||||
pca->nDisconnect,pca->nNoWrite);
|
||||
}
|
||||
} else {
|
||||
if(level>0) {
|
||||
printf("not_connected %s.%s",
|
||||
precord->name,pdbFldDes->name);
|
||||
printf(" nDisconnect %lu nNoWrite %lu\n",
|
||||
pca->nDisconnect,pca->nNoWrite);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(precordname) goto done;
|
||||
}
|
||||
status = dbNextRecord(pdbentry);
|
||||
}
|
||||
status = dbNextRecdes(pdbentry);
|
||||
}
|
||||
done:
|
||||
printf("ncalinks %d",ncalinks);
|
||||
printf(" not connected %d",(ncalinks - nconnected));
|
||||
printf(" no_read_access %d",noReadAccess);
|
||||
printf(" no_write_access %d\n",noWriteAccess);
|
||||
printf(" nDisconnect %lu nNoWrite %lu\n",nDisconnect,nNoWrite);
|
||||
dbFinishEntry(pdbentry);
|
||||
return(0);
|
||||
}
|
||||
@@ -73,8 +73,6 @@ int callNumber;
|
||||
break;
|
||||
case INITHOOKafterInitDatabase :
|
||||
break;
|
||||
case INITHOOKafterCaLinkInit2 :
|
||||
break;
|
||||
case INITHOOKafterFinishDevSup :
|
||||
break;
|
||||
case INITHOOKafterScanInit :
|
||||
|
||||
+5
-6
@@ -45,11 +45,10 @@
|
||||
#define INITHOOKafterInitDevSup 7
|
||||
#define INITHOOKafterTS_init 8
|
||||
#define INITHOOKafterInitDatabase 9
|
||||
#define INITHOOKafterCaLinkInit2 10
|
||||
#define INITHOOKafterFinishDevSup 11
|
||||
#define INITHOOKafterScanInit 12
|
||||
#define INITHOOKafterInterruptAccept 13
|
||||
#define INITHOOKafterInitialProcess 14
|
||||
#define INITHOOKatEnd 15
|
||||
#define INITHOOKafterFinishDevSup 10
|
||||
#define INITHOOKafterScanInit 11
|
||||
#define INITHOOKafterInterruptAccept 12
|
||||
#define INITHOOKafterInitialProcess 13
|
||||
#define INITHOOKatEnd 14
|
||||
|
||||
#endif /*INCinitHooksh*/
|
||||
|
||||
+28
-247
@@ -79,12 +79,13 @@
|
||||
#include <ellLib.h>
|
||||
#include <fast_lock.h>
|
||||
#include <dbDefs.h>
|
||||
#include <dbBase.h>
|
||||
#include <dbAccess.h>
|
||||
#include <dbScan.h>
|
||||
#include <taskwd.h>
|
||||
#include <callback.h>
|
||||
#include <dbCommon.h>
|
||||
#include <dbBase.h>
|
||||
#include <dbLock.h>
|
||||
#include <dbFldTypes.h>
|
||||
#include <devSup.h>
|
||||
#include <drvSup.h>
|
||||
@@ -115,9 +116,6 @@ LOCAL long initRecSup(void);
|
||||
LOCAL long initDevSup(void);
|
||||
LOCAL long finishDevSup(void);
|
||||
LOCAL long initDatabase(void);
|
||||
LOCAL void createLockSets(void);
|
||||
LOCAL void createLockSetsExtraPass(int *anyChange);
|
||||
LOCAL short makeSameSet(struct dbAddr *paddr,short set,int *anyChange);
|
||||
LOCAL long initialProcess(void);
|
||||
LOCAL long getResources(char *fname);
|
||||
LOCAL int getResourceToken(FILE *fp, char *pToken, unsigned maxToken);
|
||||
@@ -142,7 +140,7 @@ int iocInit(char * pResourceFilename)
|
||||
}
|
||||
|
||||
if (!pdbbase) {
|
||||
logMsg("iocInit aborting because No database loaded by dbReadDatabase\n",
|
||||
logMsg("iocInit aborting because No database\n",
|
||||
0,0,0,0,0,0);
|
||||
return(-1);
|
||||
}
|
||||
@@ -182,8 +180,8 @@ int iocInit(char * pResourceFilename)
|
||||
(void)taskDelay(sysClkRateGet()/10);
|
||||
if (pinitHooks) (*pinitHooks)(INITHOOKafterCallbackInit);
|
||||
|
||||
/* Initialize Channel Access Link mechanism. Pass #1 */
|
||||
dbCaLinkInit((int) 1);
|
||||
/* Initialize Channel Access Link mechanism. */
|
||||
dbCaLinkInit();
|
||||
if (pinitHooks) (*pinitHooks)(INITHOOKafterCaLinkInit1);
|
||||
|
||||
if (initDrvSup() != 0)
|
||||
@@ -207,12 +205,9 @@ int iocInit(char * pResourceFilename)
|
||||
if (initDatabase() != 0)
|
||||
logMsg("iocInit: Database Failed during Initialization\n",0,0,0,0,0,0);
|
||||
|
||||
createLockSets();
|
||||
dbLockInitRecords(pdbbase);
|
||||
if (pinitHooks) (*pinitHooks)(INITHOOKafterInitDatabase);
|
||||
|
||||
dbCaLinkInit((int) 2);
|
||||
if (pinitHooks) (*pinitHooks)(INITHOOKafterCaLinkInit2);
|
||||
|
||||
if (finishDevSup() != 0)
|
||||
logMsg("iocInit: Device Support Failed during Finalization\n",
|
||||
0,0,0,0,0,0);
|
||||
@@ -428,6 +423,7 @@ LOCAL long initDatabase(void)
|
||||
precord = pdbRecordNode->precord;
|
||||
if(!(precord->name[0])) continue;
|
||||
precord->rset = prset;
|
||||
precord->rdes = pdbRecDes;
|
||||
FASTLOCKINIT(&precord->mlok);
|
||||
ellInit(&(precord->mlis));
|
||||
|
||||
@@ -438,8 +434,6 @@ LOCAL long initDatabase(void)
|
||||
pdevSup = (devSup *)ellNth(&pdbRecDes->devList,precord->dtyp+1);
|
||||
pdset = (pdevSup ? pdevSup->pdset : 0);
|
||||
precord->dset = pdset;
|
||||
/* Initialize dbCommon - First pass (pass=0) */
|
||||
rtnval = dbCommonInit(precord,0);
|
||||
if(!prset->init_record) continue;
|
||||
rtnval = (*prset->init_record)(precord,0);
|
||||
if (status==0) status = rtnval;
|
||||
@@ -457,50 +451,29 @@ LOCAL long initDatabase(void)
|
||||
pdbRecordNode = (dbRecordNode *)ellNext(&pdbRecordNode->node)) {
|
||||
precord = pdbRecordNode->precord;
|
||||
if(!(precord->name[0])) continue;
|
||||
/*
|
||||
* Convert all PV_LINKs to DB_LINKs or CA_LINKs
|
||||
* Figures out what type of link to use. A
|
||||
* database link local to the IOC, or a channel
|
||||
* access link across the network.
|
||||
*/
|
||||
/* Convert all PV_LINKs to DB_LINKs or CA_LINKs */
|
||||
/* For all the links in the record type... */
|
||||
for(j=0; j<pdbRecDes->no_links; j++) {
|
||||
pdbFldDes = pdbRecDes->papFldDes[pdbRecDes->link_ind[j]];
|
||||
plink = (DBLINK *)((char *)precord + pdbFldDes->offset);
|
||||
if (plink->type == PV_LINK) {
|
||||
/*
|
||||
* Lookup record name in database
|
||||
* If a record is _not_ local to the IOC, it is a
|
||||
* channel access link, otherwise it is a
|
||||
* database link.
|
||||
*/
|
||||
if(dbNameToAddr(plink->value.pv_link.pvname,&dbaddr) == 0) {
|
||||
if(!(plink->value.pv_link.pvlMask&(pvlOptCA|pvlOptCP|pvlOptCPP))
|
||||
&& (dbNameToAddr(plink->value.pv_link.pvname,&dbaddr)==0)) {
|
||||
DBADDR *pdbAddr;
|
||||
|
||||
plink->type = DB_LINK;
|
||||
pdbAddr = dbCalloc(1,sizeof(struct dbAddr));
|
||||
*pdbAddr = dbaddr; /*structure copy*/;
|
||||
plink->value.db_link.pdbAddr = pdbAddr;
|
||||
/*Initialize conversion to "uninitialized" conversion */
|
||||
plink->value.db_link.conversion = cvt_uninit;
|
||||
} else {
|
||||
/*
|
||||
* Not a local process variable ... assuming a CA_LINK
|
||||
* Only supporting Non Process Passive links,
|
||||
* Input Maximize Severity/No Maximize Severity(MS/NMS)
|
||||
* , and output NMS
|
||||
* links ... The following code checks for this.
|
||||
*/
|
||||
if (errVerbose &&
|
||||
(plink->value.db_link.process_passive
|
||||
|| (pdbFldDes->field_type == DBF_OUTLINK
|
||||
&& plink->value.db_link.maximize_sevr))) {
|
||||
status = S_db_badField;
|
||||
errPrintf(status,__FILE__,__LINE__,"%s.%s %s",
|
||||
precord->name,pdbFldDes->name,
|
||||
" PP and/or MS illegal");
|
||||
status = 0;
|
||||
}
|
||||
plink->value.pv_link.pvt = pdbAddr;
|
||||
} else {/*It is a CA link*/
|
||||
char *pperiod;
|
||||
|
||||
dbCaAddLink(plink);
|
||||
if(pdbFldDes->field_type==DBF_FWDLINK) {
|
||||
pperiod = strrchr(plink->value.pv_link.pvname,'.');
|
||||
if(pperiod && strstr(pperiod,"PROC"))
|
||||
plink->value.pv_link.pvlMask |= pvlOptFWD;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -518,8 +491,6 @@ LOCAL long initDatabase(void)
|
||||
/* Find pointer to record instance */
|
||||
precord = pdbRecordNode->precord;
|
||||
if(!(precord->name[0])) continue;
|
||||
rtnval = dbCommonInit(precord,1);
|
||||
if (status==0) status = rtnval;
|
||||
precord->rset = prset;
|
||||
if(!prset->init_record) continue;
|
||||
rtnval = (*prset->init_record)(precord,1);
|
||||
@@ -529,199 +500,6 @@ LOCAL long initDatabase(void)
|
||||
return(status);
|
||||
}
|
||||
|
||||
LOCAL void createLockSets(void)
|
||||
{
|
||||
int link;
|
||||
dbRecDes *pdbRecDes;
|
||||
dbFldDes *pdbFldDes;
|
||||
dbRecordNode *pdbRecordNode;
|
||||
dbCommon *precord;
|
||||
DBLINK *plink;
|
||||
short nset,maxnset,newset;
|
||||
int again;
|
||||
int anyChange;
|
||||
|
||||
nset = 0;
|
||||
for(pdbRecDes = (dbRecDes *)ellFirst(&pdbbase->recDesList); pdbRecDes;
|
||||
pdbRecDes = (dbRecDes *)ellNext(&pdbRecDes->node)) {
|
||||
for (pdbRecordNode=(dbRecordNode *)ellFirst(&pdbRecDes->recList);
|
||||
pdbRecordNode;
|
||||
pdbRecordNode = (dbRecordNode *)ellNext(&pdbRecordNode->node)) {
|
||||
precord = pdbRecordNode->precord;
|
||||
if(!(precord->name[0])) continue;
|
||||
if(precord->lset) continue; /*already in a lock set*/
|
||||
/*
|
||||
* At First, assume record is in a different lockset
|
||||
* We shall see later if this assumption is incorrect.
|
||||
*/
|
||||
precord->lset = maxnset = ++nset;
|
||||
/*
|
||||
* Use the process active flag to eliminate traversing
|
||||
* cycles in the database "graph"
|
||||
*/
|
||||
precord->pact = TRUE; again = TRUE;
|
||||
while(again) {
|
||||
again = FALSE;
|
||||
for(link=0; (link<pdbRecDes->no_links&&!again) ; link++) {
|
||||
DBADDR *pdbAddr;
|
||||
|
||||
pdbFldDes = pdbRecDes->papFldDes[pdbRecDes->link_ind[link]];
|
||||
plink = (DBLINK *)((char *)precord + pdbFldDes->offset);
|
||||
if(plink->type != DB_LINK) continue;
|
||||
|
||||
pdbAddr = (DBADDR *)(plink->value.db_link.pdbAddr);
|
||||
|
||||
/* The current record is in a different lockset -IF-
|
||||
* 1. Input link
|
||||
* 2. Not Process Passive
|
||||
* 3. Not Maximize Severity
|
||||
* 4. Not An Array Operation - single element only
|
||||
*/
|
||||
if (pdbFldDes->field_type==DBF_INLINK
|
||||
&& ( !(plink->value.db_link.process_passive)
|
||||
&& !(plink->value.db_link.maximize_sevr))
|
||||
&& pdbAddr->no_elements<=1) continue;
|
||||
|
||||
/*
|
||||
* Combine the lock sets of the current record with the
|
||||
* remote record pointed to by the link. (recursively)
|
||||
*/
|
||||
newset = makeSameSet(pdbAddr,precord->lset,&anyChange);
|
||||
|
||||
/*
|
||||
* Perform an iteration of the while-loop again
|
||||
* if we find that the record pointed to by
|
||||
* the link has its lockset set earlier. If
|
||||
* it has, set the current record's lockset to
|
||||
* that of the link's endpoint.
|
||||
*/
|
||||
if (newset!=precord->lset) {
|
||||
if(precord->lset==maxnset && maxnset==nset) nset--;
|
||||
precord->lset = newset;
|
||||
again = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
precord->pact = FALSE;
|
||||
}
|
||||
}
|
||||
anyChange = TRUE;
|
||||
while(anyChange) {
|
||||
anyChange = FALSE;
|
||||
createLockSetsExtraPass(&anyChange);
|
||||
}
|
||||
dbScanLockInit(nset);
|
||||
}
|
||||
|
||||
LOCAL void createLockSetsExtraPass(int *anyChange)
|
||||
{
|
||||
int link;
|
||||
dbRecDes *pdbRecDes;
|
||||
dbFldDes *pdbFldDes;
|
||||
dbRecordNode *pdbRecordNode;
|
||||
dbCommon *precord;
|
||||
DBLINK *plink;
|
||||
int again;
|
||||
|
||||
for(pdbRecDes = (dbRecDes *)ellFirst(&pdbbase->recDesList); pdbRecDes;
|
||||
pdbRecDes = (dbRecDes *)ellNext(&pdbRecDes->node)) {
|
||||
for (pdbRecordNode=(dbRecordNode *)ellFirst(&pdbRecDes->recList);
|
||||
pdbRecordNode;
|
||||
pdbRecordNode = (dbRecordNode *)ellNext(&pdbRecordNode->node)) {
|
||||
precord = pdbRecordNode->precord;
|
||||
if(!(precord->name[0])) continue;
|
||||
/*Prevent cycles in database graph*/
|
||||
precord->pact = TRUE; again = TRUE;
|
||||
while(again) {
|
||||
short newset;
|
||||
|
||||
again = FALSE;
|
||||
for(link=0; (link<pdbRecDes->no_links&&!again) ; link++) {
|
||||
DBADDR *pdbAddr;
|
||||
|
||||
pdbFldDes = pdbRecDes->papFldDes[pdbRecDes->link_ind[link]];
|
||||
plink = (DBLINK *)((char *)precord + pdbFldDes->offset);
|
||||
if(plink->type != DB_LINK) continue;
|
||||
pdbAddr = (DBADDR *)(plink->value.db_link.pdbAddr);
|
||||
if(pdbFldDes->field_type==DBF_INLINK
|
||||
&& ( !(plink->value.db_link.process_passive)
|
||||
&& !(plink->value.db_link.maximize_sevr))
|
||||
&& pdbAddr->no_elements<=1) continue;
|
||||
|
||||
newset = makeSameSet(pdbAddr,precord->lset,anyChange);
|
||||
if (newset!=precord->lset) {
|
||||
precord->lset = newset;
|
||||
*anyChange = TRUE;
|
||||
again = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
precord->pact = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LOCAL short makeSameSet(struct dbAddr *paddr, short lset,int *anyChange)
|
||||
{
|
||||
dbCommon *precord = paddr->precord;
|
||||
short link;
|
||||
dbRecDes *pdbRecDes;
|
||||
dbFldDes *pdbFldDes;
|
||||
DBLINK *plink;
|
||||
int again;
|
||||
|
||||
/*Prevent cycles in database graph*/
|
||||
if(precord->pact) return(((precord->lset<lset) ? precord->lset : lset));
|
||||
|
||||
/*
|
||||
* If the lock set of the link's endpoint is already set
|
||||
* to the lockset we are setting it to, return...
|
||||
*/
|
||||
if(lset == precord->lset) return(lset);
|
||||
|
||||
/*
|
||||
* If the record has an uninitialized lock set field,
|
||||
* we set it here.
|
||||
*/
|
||||
if(precord->lset == 0) precord->lset = lset;
|
||||
|
||||
/*
|
||||
* If the record is already in a lockset determined earlier,
|
||||
* return that lock set.
|
||||
*/
|
||||
if(precord->lset < lset) return(precord->lset);
|
||||
/* set pact to prevent cycles */
|
||||
precord->lset = lset; precord->pact = TRUE; again = TRUE;
|
||||
while(again) {
|
||||
again = FALSE;
|
||||
pdbRecDes = ((dbFldDes *)paddr->pfldDes)->pdbRecDes;
|
||||
for(link=0; link<pdbRecDes->no_links; link++) {
|
||||
DBADDR *pdbAddr;
|
||||
short newset;
|
||||
|
||||
pdbFldDes = pdbRecDes->papFldDes[pdbRecDes->link_ind[link]];
|
||||
plink = (DBLINK *)((char *)precord + pdbFldDes->offset);
|
||||
if(plink->type != DB_LINK) continue;
|
||||
pdbAddr = (DBADDR *)(plink->value.db_link.pdbAddr);
|
||||
if( pdbFldDes->field_type==DBF_INLINK
|
||||
&& ( !(plink->value.db_link.process_passive)
|
||||
&& !(plink->value.db_link.maximize_sevr) )
|
||||
&& pdbAddr->no_elements<=1) continue;
|
||||
newset = makeSameSet(pdbAddr,precord->lset,anyChange);
|
||||
if(newset != precord->lset) {
|
||||
precord->lset = newset;
|
||||
again = TRUE;
|
||||
*anyChange = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
precord->pact = FALSE;
|
||||
return(precord->lset);
|
||||
}
|
||||
|
||||
/*
|
||||
* Process database records at initialization if
|
||||
* their pini (process at init) field is set.
|
||||
@@ -745,7 +523,15 @@ LOCAL long initialProcess(void)
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int dbLoadDatabase(char *filename,char *path)
|
||||
{
|
||||
return(dbReadDatabase(&pdbbase,filename,path));
|
||||
}
|
||||
|
||||
/*Remaining code supplied by Bob Zieman*/
|
||||
#define MAX 256
|
||||
#define SAME 0
|
||||
|
||||
@@ -1098,8 +884,3 @@ LOCAL int getResourceTokenInternal(FILE *fp, char *pToken, unsigned maxToken)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dbLoadDatabase(char *filename,char *path)
|
||||
{
|
||||
return(dbReadDatabase(&pdbbase,filename,path));
|
||||
}
|
||||
|
||||
+23
-209
@@ -111,27 +111,32 @@ void recGblRecSupError(long status,struct dbAddr *paddr,char *pcaller_name,
|
||||
{
|
||||
char buffer[200];
|
||||
struct dbCommon *precord;
|
||||
dbFldDes *pdbFldDes=(dbFldDes *)(paddr->pfldDes);
|
||||
dbRecDes *pdbRecDes = pdbFldDes->pdbRecDes;
|
||||
dbFldDes *pdbFldDes = 0;
|
||||
dbRecDes *pdbRecDes = 0;
|
||||
|
||||
if(paddr) pdbFldDes=(dbFldDes *)(paddr->pfldDes);
|
||||
if(pdbFldDes) pdbRecDes = pdbFldDes->pdbRecDes;
|
||||
buffer[0]=0;
|
||||
strcat(buffer,"Record Support Routine (");
|
||||
if(psupport_name)
|
||||
strcat(buffer,psupport_name);
|
||||
else
|
||||
strcat(buffer,"Unknown");
|
||||
strcat(buffer,") not available.\nRecord Type is ");
|
||||
strcat(buffer,pdbRecDes->name);
|
||||
if(paddr) { /* print process variable name */
|
||||
strcat(buffer,") not available.\n");
|
||||
if(pdbRecDes) {
|
||||
strcat(buffer,"Record Type is ");
|
||||
strcat(buffer,pdbRecDes->name);
|
||||
if(paddr) { /* print process variable name */
|
||||
precord=(struct dbCommon *)(paddr->precord);
|
||||
strcat(buffer,", PV is ");
|
||||
strcat(buffer,precord->name);
|
||||
strcat(buffer,".");
|
||||
strcat(buffer,pdbFldDes->name);
|
||||
strcat(buffer," ");
|
||||
strcat(buffer,"\n");
|
||||
}
|
||||
}
|
||||
if(pcaller_name) {
|
||||
strcat(buffer,"\nerror detected in routine: ");
|
||||
strcat(buffer,"error detected in routine: ");
|
||||
strcat(buffer,pcaller_name);
|
||||
}
|
||||
errMessage(status,buffer);
|
||||
@@ -164,7 +169,7 @@ void recGblGetPrec(struct dbAddr *paddr,long *precision)
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void recGblGetGraphicDouble(struct dbAddr *paddr,struct dbr_grDouble *pgd)
|
||||
{
|
||||
dbFldDes *pdbFldDes=(dbFldDes *)(paddr->pfldDes);
|
||||
@@ -174,7 +179,7 @@ void recGblGetGraphicDouble(struct dbAddr *paddr,struct dbr_grDouble *pgd)
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void recGblGetAlarmDouble(struct dbAddr *paddr,struct dbr_alDouble *pad)
|
||||
{
|
||||
pad->upper_alarm_limit = 0;
|
||||
@@ -184,7 +189,7 @@ void recGblGetAlarmDouble(struct dbAddr *paddr,struct dbr_alDouble *pad)
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void recGblGetControlDouble(struct dbAddr *paddr,struct dbr_ctrlDouble *pcd)
|
||||
{
|
||||
dbFldDes *pdbFldDes=(dbFldDes *)(paddr->pfldDes);
|
||||
@@ -246,70 +251,6 @@ int recGblInitConstantLink(struct link *plink,short dbftype,void *pdest)
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
long recGblGetLinkValue(struct link *plink,void *pdbc,short dbrType,
|
||||
void *pdest,long *poptions,long *pnRequest)
|
||||
{
|
||||
struct dbCommon *precord = pdbc;
|
||||
long status=0;
|
||||
unsigned char pact;
|
||||
|
||||
pact = precord->pact;
|
||||
precord->pact = TRUE;
|
||||
switch (plink->type){
|
||||
case(CONSTANT):
|
||||
*pnRequest = 0;
|
||||
break;
|
||||
case(DB_LINK):
|
||||
status=dbGetLink(&(plink->value.db_link),
|
||||
precord,dbrType,pdest,poptions,pnRequest);
|
||||
if(status)
|
||||
recGblSetSevr(precord,LINK_ALARM,INVALID_ALARM);
|
||||
break;
|
||||
case(CA_LINK):
|
||||
status=dbCaGetLink(plink);
|
||||
if(status)
|
||||
recGblSetSevr(precord,LINK_ALARM,INVALID_ALARM);
|
||||
break;
|
||||
default:
|
||||
status=-1;
|
||||
recGblSetSevr(precord,SOFT_ALARM,INVALID_ALARM);
|
||||
}
|
||||
precord->pact = pact;
|
||||
return(status);
|
||||
}
|
||||
|
||||
long recGblPutLinkValue(struct link *plink,void *pdbc,short dbrType,
|
||||
void *psource,long *pnRequest)
|
||||
{
|
||||
struct dbCommon *precord = pdbc;
|
||||
long options=0;
|
||||
long status=0;
|
||||
unsigned char pact;
|
||||
|
||||
pact = precord->pact;
|
||||
precord->pact = TRUE;
|
||||
switch (plink->type){
|
||||
case(CONSTANT):
|
||||
break;
|
||||
case(DB_LINK):
|
||||
status=dbPutLink(&(plink->value.db_link),
|
||||
precord,dbrType,psource,*pnRequest);
|
||||
if(status)
|
||||
recGblSetSevr(precord,LINK_ALARM,INVALID_ALARM);
|
||||
break;
|
||||
case(CA_LINK):
|
||||
status = dbCaPutLink(plink, &options, pnRequest);
|
||||
if(status)
|
||||
recGblSetSevr(precord,LINK_ALARM,INVALID_ALARM);
|
||||
break;
|
||||
default:
|
||||
status=-1;
|
||||
recGblSetSevr(precord,SOFT_ALARM,INVALID_ALARM);
|
||||
}
|
||||
precord->pact = pact;
|
||||
return(status);
|
||||
}
|
||||
|
||||
unsigned short recGblResetAlarms(void *precord)
|
||||
{
|
||||
struct dbCommon *pdbc = precord;
|
||||
@@ -342,10 +283,15 @@ unsigned short recGblResetAlarms(void *precord)
|
||||
void recGblFwdLink(void *precord)
|
||||
{
|
||||
struct dbCommon *pdbc = precord;
|
||||
static short fwdLinkValue = 1;
|
||||
|
||||
if(pdbc->flnk.type==DB_LINK ) {
|
||||
struct dbAddr *paddr = pdbc->flnk.value.db_link.pdbAddr;
|
||||
struct dbAddr *paddr = pdbc->flnk.value.pv_link.pvt;
|
||||
dbScanPassive(precord,paddr->precord);
|
||||
} else
|
||||
if((pdbc->flnk.type==CA_LINK)
|
||||
&& (pdbc->flnk.value.pv_link.pvlMask & pvlOptFWD)) {
|
||||
dbCaPutLink(&pdbc->flnk,DBR_SHORT,&fwdLinkValue,1);
|
||||
}
|
||||
/*Handle dbPutFieldNotify record completions*/
|
||||
if(pdbc->ppn) dbNotifyCompletion(pdbc);
|
||||
@@ -358,18 +304,14 @@ void recGblFwdLink(void *precord)
|
||||
pdbc->putf = FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void recGblGetTimeStamp(void* prec)
|
||||
{
|
||||
struct dbCommon* pr = (struct dbCommon*)prec;
|
||||
long nRequest=1;
|
||||
long options=0;
|
||||
|
||||
if(pr->tsel.type!=CONSTANT)
|
||||
{
|
||||
recGblGetLinkValue(&(pr->tsel),(void*)pr,
|
||||
DBR_SHORT,&(pr->tse),&options,&nRequest);
|
||||
|
||||
dbGetLink(&(pr->tsel), DBR_SHORT,&(pr->tse),0,0);
|
||||
TSgetTimeStamp((int)pr->tse,(struct timespec*)&pr->time);
|
||||
}
|
||||
else
|
||||
@@ -420,131 +362,3 @@ static void getMaxRangeValues(field_type,pupper_limit,plower_limit)
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Fast link initialization routines */
|
||||
|
||||
/*
|
||||
* String if bad database request type chosen
|
||||
*/
|
||||
static char *bad_in_req_type = "recGblInitFastInLink: Bad database request type";
|
||||
static char *bad_out_req_type = "recGblInitFastInLink: Bad database request type";
|
||||
|
||||
/*
|
||||
* Initialize fast input links.
|
||||
*/
|
||||
long recGblInitFastInLink(
|
||||
struct link *plink,
|
||||
void *precord,
|
||||
short dbrType,
|
||||
char *fld_name)
|
||||
{
|
||||
long status = 0;
|
||||
struct db_link *pdb_link = &(plink->value.db_link);
|
||||
struct dbAddr *pdb_addr = (struct dbAddr *) (pdb_link->pdbAddr);
|
||||
long (*cvt_func)();
|
||||
|
||||
/*
|
||||
* Check for CA_LINK
|
||||
*/
|
||||
if (plink->type == PV_LINK) {
|
||||
status = dbCaAddInlink(plink, (struct dbCommon *) precord, fld_name);
|
||||
return(status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return if not database link (A constant link, for example)
|
||||
*/
|
||||
if (plink->type != DB_LINK)
|
||||
return(0);
|
||||
|
||||
/*
|
||||
* Check for legal conversion range...
|
||||
*/
|
||||
if ((pdb_addr->field_type < DBF_STRING) ||
|
||||
(pdb_addr->field_type > DBF_DEVICE) ||
|
||||
( dbrType < DBR_STRING) ||
|
||||
( dbrType > DBR_ENUM)) {
|
||||
|
||||
pdb_link->conversion = cvt_dummy;
|
||||
recGblDbaddrError(S_db_badDbrtype, pdb_addr, bad_in_req_type);
|
||||
return(S_db_badDbrtype);
|
||||
}
|
||||
|
||||
/*
|
||||
* Lookup conversion function
|
||||
*/
|
||||
cvt_func = dbFastGetConvertRoutine[pdb_addr->field_type][dbrType];
|
||||
|
||||
if (cvt_func == NULL) {
|
||||
pdb_link->conversion = cvt_dummy;
|
||||
recGblDbaddrError(S_db_badDbrtype, pdb_addr, bad_in_req_type);
|
||||
return(S_db_badDbrtype);
|
||||
}
|
||||
|
||||
/*
|
||||
* Put function it into conversion field (Run Time Link)
|
||||
*/
|
||||
pdb_link->conversion = cvt_func;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize fast output links.
|
||||
*/
|
||||
long recGblInitFastOutLink(
|
||||
struct link *plink,
|
||||
void *precord,
|
||||
short dbrType,
|
||||
char *fld_name)
|
||||
{
|
||||
long status = 0;
|
||||
struct db_link *pdb_link = &(plink->value.db_link);
|
||||
struct dbAddr *pdb_addr = (struct dbAddr *) (pdb_link->pdbAddr);
|
||||
long (*cvt_func)();
|
||||
|
||||
/*
|
||||
* Check for CA_LINK
|
||||
*/
|
||||
if (plink->type == PV_LINK) {
|
||||
status = dbCaAddOutlink(plink, (struct dbCommon *) precord, fld_name);
|
||||
return(status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return if not database link (A constant link, for example)
|
||||
*/
|
||||
if (plink->type != DB_LINK)
|
||||
return(0);
|
||||
|
||||
/*
|
||||
* Check for legal conversion range...
|
||||
*/
|
||||
if ((pdb_addr->field_type < DBF_STRING) ||
|
||||
(pdb_addr->field_type > DBF_DEVICE) ||
|
||||
( dbrType < DBR_STRING) ||
|
||||
( dbrType > DBR_ENUM)) {
|
||||
|
||||
pdb_link->conversion = cvt_dummy;
|
||||
recGblDbaddrError(S_db_badDbrtype, pdb_addr, bad_out_req_type);
|
||||
return(S_db_badDbrtype);
|
||||
}
|
||||
/*
|
||||
* Lookup conversion function
|
||||
*/
|
||||
cvt_func = dbFastPutConvertRoutine[dbrType][pdb_addr->field_type];
|
||||
|
||||
if (cvt_func == NULL) {
|
||||
pdb_link->conversion = cvt_dummy;
|
||||
recGblDbaddrError(S_db_badDbrtype, pdb_addr, bad_out_req_type);
|
||||
return(S_db_badDbrtype);
|
||||
}
|
||||
|
||||
/*
|
||||
* Put function it into conversion field (Run Time Link)
|
||||
*/
|
||||
pdb_link->conversion = cvt_func;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
+2
-24
@@ -50,7 +50,7 @@
|
||||
#include <alarm.h>
|
||||
#endif
|
||||
#include <dbFldTypes.h>
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* The following must match definitions in global menu definitions
|
||||
*************************************************************************/
|
||||
@@ -62,22 +62,6 @@
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
#define recGblGetFastLink(PLNK,PREC,PVAL) \
|
||||
\
|
||||
((((PLNK)->type == CONSTANT) ||\
|
||||
(! (((PLNK)->type == DB_LINK) || ((PLNK)->type == CA_LINK)) ))\
|
||||
? 0\
|
||||
: dbFastLinkGet((PLNK),(struct dbCommon *)(PREC),(PVAL)))
|
||||
|
||||
|
||||
#define recGblPutFastLink(PLNK,PREC,PVAL) \
|
||||
\
|
||||
((((PLNK)->type == CONSTANT) ||\
|
||||
(! (((PLNK)->type == DB_LINK) || ((PLNK)->type == CA_LINK)) ))\
|
||||
? 0\
|
||||
: dbFastLinkPut((PLNK),(struct dbCommon *)(PREC),(PVAL)))
|
||||
|
||||
|
||||
#define recGblSetSevr(PREC,NSTA,NSEV) \
|
||||
(\
|
||||
((PREC)->nsev<(NSEV))\
|
||||
@@ -85,7 +69,7 @@
|
||||
: FALSE\
|
||||
)
|
||||
|
||||
|
||||
|
||||
/* Global Record Support Routines*/
|
||||
void recGblDbaddrError(long status, struct dbAddr *paddr, char *pcaller_name);
|
||||
void recGblRecordError(long status, void *precord, char *pcaller_name);
|
||||
@@ -95,13 +79,7 @@ void recGblGetControlDouble(struct dbAddr *paddr, struct dbr_ctrlDouble *pcd);
|
||||
void recGblGetAlarmDouble(struct dbAddr *paddr, struct dbr_alDouble *pad);
|
||||
void recGblGetPrec(struct dbAddr *paddr, long *pprecision);
|
||||
int recGblInitConstantLink(struct link *plink,short dbftype,void *pdest);
|
||||
long recGblGetLinkValue(struct link *plink,void *precord,
|
||||
short dbrType,void *pdest,long *poptions,long *pnRequest);
|
||||
long recGblPutLinkValue(struct link *plink,void *precord,
|
||||
short dbrType,void *pdest,long *pnRequest);
|
||||
unsigned short recGblResetAlarms(void *precord);
|
||||
void recGblFwdLink(void *precord);
|
||||
void recGblGetTimeStamp(void *precord);
|
||||
long recGblInitFastInLink(struct link *plink, void *precord, short dbrType, char *fld_name);
|
||||
long recGblInitFastOutLink(struct link *plink, void *precord, short dbrType, char *fld_name);
|
||||
#endif /*INCrecGblh*/
|
||||
|
||||
+9
-14
@@ -51,8 +51,14 @@
|
||||
* to 60 sec
|
||||
* .17 03-18-94 mcn added entries for breakpoint tasks
|
||||
* $Log$
|
||||
* Revision 1.1 1996/01/25 21:13:29 mrk
|
||||
* moved includes; .ascii=> .db; path changes
|
||||
*
|
||||
* Revision 1.27 1995/11/29 19:27:59 jhill
|
||||
* added $Log$
|
||||
* added Revision 1.1 1996/01/25 21:13:29 mrk
|
||||
* added moved includes; .ascii=> .db; path changes
|
||||
* added
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -65,14 +71,12 @@
|
||||
/* Task Names */
|
||||
#define IOEVENTSCAN_NAME "scanIo"
|
||||
#define EVENTSCAN_NAME "scanEvent"
|
||||
#define CALLBACK_NAME "callback"
|
||||
#define SCANONCE_NAME "scanOnce"
|
||||
#define SMCMD_NAME "smCommand"
|
||||
#define SMRESP_NAME "smResponse"
|
||||
#define ABDONE_NAME "abDone"
|
||||
#define ABSCAN_NAME "abScan"
|
||||
#define ABCOS_NAME "abBiCosScanner"
|
||||
#define PERIODSCAN_NAME "scanPeriod"
|
||||
#define MOMENTARY_NAME "momentary"
|
||||
#define WFDONE_NAME "wfDone"
|
||||
#define SEQUENCER_NAME "sequencer"
|
||||
@@ -95,9 +99,6 @@
|
||||
#define BBTXLINK_NAME "bbTx"
|
||||
#define BBRXLINK_NAME "bbRx"
|
||||
#define BBWDTASK_NAME "bbwd"
|
||||
#define DB_CA_INPUT_NAME "dbCaInput"
|
||||
#define DB_CA_OUTPUT_NAME "dbCaOutput"
|
||||
#define DB_CA_PROC_ASYNCH_EV_TASK_NAME "process_asynch_events_task"
|
||||
#define EPICSPRINT_NAME "epicsPrint"
|
||||
#define LOG_RESTART_NAME "logRestart"
|
||||
|
||||
@@ -126,9 +127,7 @@
|
||||
#define PERIODSCAN_PRI 59 /* Periodic Scanners - Slowest rate */
|
||||
#define SEQUENCER_PRI 70
|
||||
#define XY240_PRI 111 /* xy 240 dio scanner */
|
||||
#define DB_CA_INPUT_PRI 100
|
||||
#define DB_CA_OUTPUT_PRI 100
|
||||
#define DB_CA_PROC_ASYNCH_EV_TASK_PRI 100
|
||||
#define DB_CA_PRI 100
|
||||
#define SCANNER_PRI 150
|
||||
#define REQ_SRVR_PRI 181 /* Channel Access TCP request server*/
|
||||
#define CA_CLIENT_PRI 180 /* Channel Access clients */
|
||||
@@ -182,9 +181,7 @@
|
||||
#define BBTXLINK_OPT VX_FP_TASK|VX_STDIO
|
||||
#define BBRXLINK_OPT VX_FP_TASK|VX_STDIO
|
||||
#define BBWDTASK_OPT VX_FP_TASK|VX_STDIO
|
||||
#define DB_CA_INPUT_OPT (VX_FP_TASK | VX_STDIO)
|
||||
#define DB_CA_OUTPUT_OPT (VX_FP_TASK | VX_STDIO)
|
||||
#define DB_CA_PROC_ASYNCH_EV_TASK_OPT (VX_FP_TASK | VX_STDIO)
|
||||
#define DB_CA_OPT (VX_FP_TASK | VX_STDIO)
|
||||
#define XY_240_OPT (0) /* none */
|
||||
#define LOG_RESTART_OPT (VX_FP_TASK)
|
||||
|
||||
@@ -221,9 +218,7 @@
|
||||
#define BBRXLINK_STACK 5000
|
||||
#define BBTXLINK_STACK 5000
|
||||
#define BBWDTASK_STACK 5000
|
||||
#define DB_CA_INPUT_STACK 20000
|
||||
#define DB_CA_OUTPUT_STACK 20000
|
||||
#define DB_CA_PROC_ASYNCH_EV_TASK_STACK 20000
|
||||
#define DB_CA_STACK 10000
|
||||
#define XY_240_STACK 4096
|
||||
#define LOG_RESTART_STACK 0x1000
|
||||
|
||||
|
||||
@@ -125,7 +125,7 @@ typedef struct dbRecDes {
|
||||
char **papsortFldName;/* ptr to array of ptr to fld names*/
|
||||
short *sortFldInd; /* addr of array of ind in papFldDes*/
|
||||
dbFldDes *pvalFldDes; /*pointer dbFldDes for VAL field*/
|
||||
short indvalFlddes; /*ind in apFldDes*/
|
||||
short indvalFlddes; /*ind in papFldDes*/
|
||||
dbFldDes **papFldDes; /* ptr to array of ptr to fldDes*/
|
||||
/*The following are only available on run time system*/
|
||||
struct rset *prset;
|
||||
|
||||
@@ -238,7 +238,7 @@ static int db_yyinput(char *buf, int max_size)
|
||||
pinputFileNow = (inputFile *)ellLast(&inputFileList);
|
||||
if(!pinputFileNow) return(0);
|
||||
}
|
||||
if(dbDebug) fprintf(stderr,"%s",my_buffer);
|
||||
if(dbStaticDebug) fprintf(stderr,"%s",my_buffer);
|
||||
pinputFileNow->line_num++;
|
||||
my_buffer_ptr = &my_buffer[0];
|
||||
}
|
||||
|
||||
+228
-190
@@ -18,7 +18,7 @@ of this distribution.
|
||||
* .02 09-10-93 mrk dbIsDefault always returns FALSE for DEVCHOICE
|
||||
* .03 02-23-94 mrk dbPutString to DEV_CHOICE. Ok if no INP or OUT
|
||||
*/
|
||||
|
||||
|
||||
#ifdef vxWorks
|
||||
#include <vxWorks.h>
|
||||
#include <taskLib.h>
|
||||
@@ -50,12 +50,12 @@ of this distribution.
|
||||
#include <guigroup.h>
|
||||
#include <special.h>
|
||||
|
||||
int dbDebug = 0;
|
||||
int dbStaticDebug = 0;
|
||||
#define messagesize 100
|
||||
#define RPCL_LEN 184
|
||||
long postfix(char *pinfix, char *ppostfix,short *perror);
|
||||
|
||||
static char *ppstring[2]={"NPP","PP"};
|
||||
static char *ppstring[5]={"NPP","PP","CA","CP","CPP"};
|
||||
static char *msstring[2]={"NMS","MS"};
|
||||
|
||||
static int mapDBFtoDCT[DBF_NOACCESS+1] = {
|
||||
@@ -78,10 +78,6 @@ struct form {
|
||||
|
||||
static char *promptCONSTANT[] = {
|
||||
"Constant:"};
|
||||
static char *promptPV_LINK[] = {
|
||||
" PV Name:",
|
||||
" Process Passive?",
|
||||
" Maximize Severity?"};
|
||||
static char *promptVME_IO[] = {
|
||||
" card:",
|
||||
"signal:",
|
||||
@@ -129,10 +125,87 @@ static char *promptVXI_IO[] = {
|
||||
" Signal:",
|
||||
" parm:"};
|
||||
|
||||
static char **promptAddr[VXI_IO+1];
|
||||
static int formlines[VXI_IO+1];
|
||||
/*Each DBF link type is separate case*/
|
||||
#define FWD_LINK VXI_IO+1
|
||||
#define IN_LINK FWD_LINK+1
|
||||
#define OUTLINK IN_LINK+1
|
||||
static char *promptFWD_LINK[] = {
|
||||
" PV Name:"};
|
||||
static char *promptIN_LINK[] = {
|
||||
" PV Name:",
|
||||
"NPP PP CA CP CPP:"
|
||||
" NMS or MS:"};
|
||||
static char *promptOUT_LINK[] = {
|
||||
" PV Name:",
|
||||
"NPP PP CA:"
|
||||
"NMS or MS:"};
|
||||
static char **promptAddr[OUTLINK+1];
|
||||
static int formlines[OUTLINK+1];
|
||||
|
||||
/* internal routines*/
|
||||
/*checkDevChoice initializes INP or OUT field*/
|
||||
static char *pNullString = "";
|
||||
static long checkDevChoice(DBENTRY *pdbentry, long link_type)
|
||||
{
|
||||
dbFldDes *savepflddes = pdbentry->pflddes;
|
||||
void *savepfield = pdbentry->pfield;
|
||||
short saveindfield = pdbentry->indfield;
|
||||
dbFldDes *pflddes;
|
||||
DBLINK *plink;
|
||||
long status=0;
|
||||
|
||||
status = dbFindField(pdbentry,"INP");
|
||||
if(status) status = dbFindField(pdbentry,"OUT");
|
||||
if(!status) {
|
||||
pflddes = pdbentry->pflddes;
|
||||
plink = (DBLINK *)(pdbentry->pfield);
|
||||
if(plink->type == link_type) goto clean_up;
|
||||
if(link_type==CONSTANT && plink->type==PV_LINK)goto clean_up;
|
||||
if(link_type!=CONSTANT && plink->type==PV_LINK) {
|
||||
status = S_dbLib_badField;
|
||||
goto clean_up;
|
||||
}
|
||||
plink->type = link_type;
|
||||
if(plink->type==CONSTANT) free((void *)plink->value.constantStr);
|
||||
memset((char *)plink,0,sizeof(struct link));
|
||||
switch(plink->type) {
|
||||
case VME_IO: plink->value.vmeio.parm = pNullString; break;
|
||||
case CAMAC_IO: plink->value.camacio.parm = pNullString; break;
|
||||
case AB_IO: plink->value.abio.parm = pNullString; break;
|
||||
case GPIB_IO: plink->value.gpibio.parm = pNullString; break;
|
||||
case BITBUS_IO: plink->value.bitbusio.parm = pNullString; break;
|
||||
case INST_IO: plink->value.instio.string = pNullString; break;
|
||||
case BBGPIB_IO: plink->value.bbgpibio.parm = pNullString; break;
|
||||
case VXI_IO: plink->value.vxiio.parm = pNullString; break;
|
||||
}
|
||||
} else {
|
||||
if(link_type==CONSTANT) status = 0;
|
||||
else status = S_dbLib_badField;
|
||||
}
|
||||
clean_up:
|
||||
pdbentry->pflddes = savepflddes;
|
||||
pdbentry->pfield = savepfield;
|
||||
pdbentry->indfield = saveindfield;
|
||||
return(status);
|
||||
}
|
||||
|
||||
static long putParmString(char **pparm,char *pstring)
|
||||
{
|
||||
size_t size;
|
||||
|
||||
size = strlen(pstring) + 1;
|
||||
if(size>=MAX_STRING_SIZE) return(S_dbLib_badLink);
|
||||
if(*pparm && (*pparm != pNullString)) free((void *)(*pparm));
|
||||
*pparm = dbCalloc(size, sizeof(char *));
|
||||
strcpy(*pparm,pstring);
|
||||
return(0);
|
||||
}
|
||||
|
||||
void dbFreeParmString(char **pparm)
|
||||
{
|
||||
if(*pparm && (*pparm != pNullString)) free((void *)(*pparm));
|
||||
}
|
||||
|
||||
static void dbFreePath(DBBASE *pdbbase) {
|
||||
ELLLIST *ppathList;
|
||||
dbPathNode *pdbPathNode;
|
||||
@@ -157,12 +230,11 @@ static void initForms(void)
|
||||
|
||||
if(!firstTime) return;
|
||||
firstTime = FALSE;
|
||||
for(i=0; i<=VXI_IO; i++) {
|
||||
for(i=0; i<=OUTLINK; i++) {
|
||||
promptAddr[i] = NULL;
|
||||
formlines[i] = 0;
|
||||
}
|
||||
promptAddr[CONSTANT] = promptCONSTANT; formlines[CONSTANT] = 1;
|
||||
promptAddr[PV_LINK] = promptPV_LINK; formlines[PV_LINK] = 4;
|
||||
promptAddr[VME_IO] = promptVME_IO; formlines[VME_IO] = 3;
|
||||
promptAddr[CAMAC_IO] = promptCAMAC_IO; formlines[CAMAC_IO] = 6;
|
||||
promptAddr[RF_IO] = promptRF_IO; formlines[RF_IO] = 4;
|
||||
@@ -172,6 +244,9 @@ static void initForms(void)
|
||||
promptAddr[INST_IO] = promptINST_IO; formlines[INST_IO] = 1;
|
||||
promptAddr[BBGPIB_IO]= promptBBGPIB_IO;formlines[BBGPIB_IO]= 4;
|
||||
promptAddr[VXI_IO] = promptVXI_IO; formlines[VXI_IO] = 6;
|
||||
promptAddr[FWD_LINK] = promptFWD_LINK; formlines[FWD_LINK] = 1;
|
||||
promptAddr[IN_LINK] = promptIN_LINK; formlines[IN_LINK] = 3;
|
||||
promptAddr[OUTLINK] = promptOUT_LINK; formlines[OUTLINK] = 3;
|
||||
}
|
||||
|
||||
static void entryErrMessage(DBENTRY *pdbentry,long status,char *mess)
|
||||
@@ -219,6 +294,36 @@ static char *getpMessage(DBENTRY *pdbentry)
|
||||
return(pdbentry->message);
|
||||
}
|
||||
|
||||
static long putPvLink(DBENTRY *pdbentry,short pvlMask,char *pvname)
|
||||
{
|
||||
dbFldDes *pflddes;
|
||||
DBLINK *plink;
|
||||
char *pname;
|
||||
|
||||
dbGetFieldAddress(pdbentry);
|
||||
pflddes = pdbentry->pflddes;
|
||||
if(!pflddes) return(-1);
|
||||
plink = (DBLINK *)pdbentry->pfield;
|
||||
if(!plink) return(-1);
|
||||
switch (pflddes->field_type) {
|
||||
case DBF_INLINK:
|
||||
case DBF_OUTLINK:
|
||||
case DBF_FWDLINK:
|
||||
if(plink->type != PV_LINK) return(S_dbLib_badLink);
|
||||
pname = plink->value.pv_link.pvname;
|
||||
if(pname) free((void *)pname);
|
||||
pname = dbCalloc(strlen(pvname)+1,sizeof(char));
|
||||
plink->value.pv_link.pvname = pname;
|
||||
strcpy(pname,pvname);
|
||||
plink->value.pv_link.pvlMask = pvlMask;
|
||||
return(0);
|
||||
default:
|
||||
errPrintf(-1,__FILE__, __LINE__,"Logic Error\n");
|
||||
}
|
||||
return(S_dbLib_badLink);
|
||||
}
|
||||
|
||||
/*Public only for dbStaticRun*/
|
||||
void dbInitDeviceMenu(DBENTRY *pdbentry)
|
||||
{
|
||||
dbRecDes *precdes = pdbentry->precdes;
|
||||
@@ -273,7 +378,7 @@ void *dbMalloc(size_t size)
|
||||
#endif
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
||||
dbBase *dbAllocBase(void)
|
||||
{
|
||||
dbBase *pdbbase;
|
||||
@@ -288,7 +393,7 @@ dbBase *dbAllocBase(void)
|
||||
initForms();
|
||||
return (pdbbase);
|
||||
}
|
||||
|
||||
|
||||
void dbFreeBase(dbBase *pdbbase)
|
||||
{
|
||||
dbMenu *pdbMenu;
|
||||
@@ -657,7 +762,9 @@ long dbWriteRecDesFP(DBBASE *pdbbase,FILE *fp,char *recdesName)
|
||||
}
|
||||
}
|
||||
if(pdbFldDes->special) {
|
||||
for(j=0; j<SPC_NTYPES; j++) {
|
||||
if(pdbFldDes->special >= SPC_NTYPES) {
|
||||
fprintf(fp,"\t\tspecial(%d)\n",pdbFldDes->special);
|
||||
} else for(j=0; j<SPC_NTYPES; j++) {
|
||||
if(pamapspcType[j].value == pdbFldDes->special) {
|
||||
fprintf(fp,"\t\tspecial(%s)\n",
|
||||
pamapspcType[j].strvalue);
|
||||
@@ -854,14 +961,20 @@ int dbGetNRecdes(DBENTRY *pdbentry)
|
||||
long dbCreateRecord(DBENTRY *pdbentry,char *precordName)
|
||||
{
|
||||
dbRecDes *precdes = pdbentry->precdes;
|
||||
dbFldDes *pdbFldDes;
|
||||
PVDENTRY *ppvd;
|
||||
ELLLIST *preclist = NULL;
|
||||
dbRecordNode *precnode = NULL;
|
||||
dbRecordNode *pNewRecNode = NULL;
|
||||
long status;
|
||||
devSup *pdevSup;
|
||||
|
||||
if((int)strlen(precordName)>PVNAME_SZ) return(S_dbLib_nameLength);
|
||||
if(!precdes) return(S_dbLib_recdesNotFound);
|
||||
/*Get size of NAME field*/
|
||||
pdbFldDes = precdes->papFldDes[0];
|
||||
if(!pdbFldDes || (strcmp(pdbFldDes->name,"NAME")!=0))
|
||||
return(S_dbLib_nameLength);
|
||||
if((int)strlen(precordName)>=pdbFldDes->size) return(S_dbLib_nameLength);
|
||||
/* clear callers entry */
|
||||
zeroDbentry(pdbentry);
|
||||
if(!dbFindRecord(pdbentry,precordName)) return (S_dbLib_recExists);
|
||||
@@ -885,7 +998,11 @@ long dbCreateRecord(DBENTRY *pdbentry,char *precordName)
|
||||
pdbentry->precnode = pNewRecNode;
|
||||
ppvd = dbPvdAdd(pdbentry->pdbbase,precdes,pNewRecNode);
|
||||
if(!ppvd) {errMessage(-1,"Logic Err: Could not add to PVD");return(-1);}
|
||||
return (0);
|
||||
/*If any device support exists let checkDevChoice give default for INP/OUT*/
|
||||
pdevSup = (devSup *)ellFirst(&precdes->devList);
|
||||
if(!pdevSup) return(0);
|
||||
status = checkDevChoice(pdbentry,pdevSup->link_type);
|
||||
return (status);
|
||||
}
|
||||
|
||||
long dbDeleteRecord(DBENTRY *pdbentry)
|
||||
@@ -981,6 +1098,7 @@ long dbRenameRecord(DBENTRY *pdbentry,char *newName)
|
||||
{
|
||||
dbBase *pdbbase = pdbentry->pdbbase;
|
||||
dbRecDes *precdes = pdbentry->precdes;
|
||||
dbFldDes *pdbFldDes;
|
||||
dbRecordNode *precnode = pdbentry->precnode;
|
||||
PVDENTRY *ppvd;
|
||||
ELLLIST *preclist;
|
||||
@@ -988,7 +1106,12 @@ long dbRenameRecord(DBENTRY *pdbentry,char *newName)
|
||||
long status;
|
||||
DBENTRY dbentry;
|
||||
|
||||
if((int)strlen(newName)>PVNAME_SZ) return(S_dbLib_nameLength);
|
||||
if(!precdes) return(S_dbLib_recdesNotFound);
|
||||
/*Get size of NAME field*/
|
||||
pdbFldDes = precdes->papFldDes[0];
|
||||
if(!pdbFldDes || (strcmp(pdbFldDes->name,"NAME")!=0))
|
||||
return(S_dbLib_nameLength);
|
||||
if((int)strlen(newName)>=pdbFldDes->size) return(S_dbLib_nameLength);
|
||||
if(!precnode) return(S_dbLib_recNotFound);
|
||||
dbInitEntry(pdbentry->pdbbase,&dbentry);
|
||||
status = dbFindRecord(&dbentry,newName);
|
||||
@@ -1229,17 +1352,23 @@ char *dbGetString(DBENTRY *pdbentry)
|
||||
}
|
||||
break;
|
||||
case PV_LINK:
|
||||
if(plink->value.pv_link.process_passive<0
|
||||
||plink->value.pv_link.process_passive>1)
|
||||
plink->value.pv_link.process_passive=0;
|
||||
if(plink->value.pv_link.maximize_sevr<0
|
||||
||plink->value.pv_link.maximize_sevr>1)
|
||||
plink->value.pv_link.maximize_sevr=0;
|
||||
case CA_LINK:
|
||||
case DB_LINK: {
|
||||
int ppind;
|
||||
short pvlMask;
|
||||
|
||||
pvlMask = plink->value.pv_link.pvlMask;
|
||||
if(pvlMask&pvlOptPP) ppind=1;
|
||||
else if(pvlMask&pvlOptCA) ppind=2;
|
||||
else if(pvlMask&pvlOptCP) ppind=3;
|
||||
else if(pvlMask&pvlOptCPP) ppind=4;
|
||||
else ppind=0;
|
||||
sprintf(message,"%s %s %s",
|
||||
plink->value.pv_link.pvname,
|
||||
ppstring[plink->value.pv_link.process_passive],
|
||||
msstring[plink->value.pv_link.maximize_sevr]);
|
||||
ppstring[ppind],
|
||||
msstring[pvlMask&pvlOptMS]);
|
||||
break;
|
||||
}
|
||||
case VME_IO:
|
||||
sprintf(message,"#C%d S%d @%s",
|
||||
plink->value.vmeio.card,plink->value.vmeio.signal,
|
||||
@@ -1307,6 +1436,8 @@ char *dbGetString(DBENTRY *pdbentry)
|
||||
strcpy(message,"0");
|
||||
break;
|
||||
case PV_LINK:
|
||||
case CA_LINK:
|
||||
case DB_LINK:
|
||||
sprintf(message,"%s",
|
||||
plink->value.pv_link.pvname);
|
||||
break;
|
||||
@@ -1321,41 +1452,6 @@ char *dbGetString(DBENTRY *pdbentry)
|
||||
return (message);
|
||||
}
|
||||
|
||||
/* utility routines used by dbPutString */
|
||||
static long checkDevChoice(DBENTRY *pdbentry, long link_type)
|
||||
{
|
||||
dbFldDes *savepflddes = pdbentry->pflddes;
|
||||
void *savepfield = pdbentry->pfield;
|
||||
short saveindfield = pdbentry->indfield;
|
||||
dbFldDes *pflddes;
|
||||
DBLINK *plink;
|
||||
long status=0;
|
||||
|
||||
status = dbFindField(pdbentry,"INP");
|
||||
if(status) status = dbFindField(pdbentry,"OUT");
|
||||
if(!status) {
|
||||
pflddes = pdbentry->pflddes;
|
||||
plink = (DBLINK *)(pdbentry->pfield);
|
||||
if(plink->type == link_type) goto clean_up;
|
||||
if(link_type==CONSTANT && plink->type==PV_LINK)goto clean_up;
|
||||
if(link_type!=CONSTANT && plink->type==PV_LINK) {
|
||||
status = S_dbLib_badField;
|
||||
goto clean_up;
|
||||
}
|
||||
if(plink->type==CONSTANT) free((void *)plink->value.constantStr);
|
||||
memset((char *)plink,0,sizeof(struct link));
|
||||
plink->type = link_type;
|
||||
} else {
|
||||
if(link_type==CONSTANT) status = 0;
|
||||
else status = S_dbLib_badField;
|
||||
}
|
||||
clean_up:
|
||||
pdbentry->pflddes = savepflddes;
|
||||
pdbentry->pfield = savepfield;
|
||||
pdbentry->indfield = saveindfield;
|
||||
return(status);
|
||||
}
|
||||
|
||||
long dbPutString(DBENTRY *pdbentry,char *pstring)
|
||||
{
|
||||
dbFldDes *pflddes = pdbentry->pflddes;
|
||||
@@ -1457,8 +1553,8 @@ long dbPutString(DBENTRY *pdbentry,char *pstring)
|
||||
switch(plink->type) {
|
||||
case CONSTANT:
|
||||
case PV_LINK: {
|
||||
int pp=0;
|
||||
int ms=0;
|
||||
short ppOpt = 0;
|
||||
short msOpt = 0;
|
||||
char *end;
|
||||
double tempval;
|
||||
|
||||
@@ -1481,13 +1577,18 @@ long dbPutString(DBENTRY *pdbentry,char *pstring)
|
||||
if(plink->type==CONSTANT) dbCvtLinkToPvlink(pdbentry);
|
||||
end = strchr(pstr,' ');
|
||||
if(end) {
|
||||
if(strstr(end," PP")) pp = TRUE;
|
||||
if(strstr(end,".PP")) pp = TRUE;
|
||||
if(strstr(end," MS")) ms = TRUE;
|
||||
if(strstr(end,".MS")) ms = TRUE;
|
||||
if(strstr(end,"NPP")) ppOpt = 0;
|
||||
else if(strstr(end,"PP")) ppOpt = pvlOptPP;
|
||||
else if(strstr(end,"CA")) ppOpt = pvlOptCA;
|
||||
else if(strstr(end,"CP")) ppOpt = pvlOptCP;
|
||||
else if(strstr(end,"CPP")) ppOpt = pvlOptCPP;
|
||||
else ppOpt = 0;
|
||||
if(strstr(end,"NMS")) msOpt = 0;
|
||||
else if(strstr(end,"MS")) msOpt = pvlOptMS;
|
||||
else msOpt = 0;
|
||||
*end = 0;
|
||||
}
|
||||
status = dbPutPvlink(pdbentry,pp,ms,pstr);
|
||||
status = putPvLink(pdbentry,ppOpt|msOpt,pstr);
|
||||
return(0);
|
||||
}
|
||||
case VME_IO: {
|
||||
@@ -1501,11 +1602,7 @@ long dbPutString(DBENTRY *pdbentry,char *pstring)
|
||||
if(!(end = strchr(pstr,'S'))) return (S_dbLib_badField);
|
||||
pstr = end + 1;
|
||||
sscanf(pstr,"%hd",&plink->value.vmeio.signal);
|
||||
plink->value.vmeio.parm[0] = 0;
|
||||
if(end = strchr(pstr,'@')) {
|
||||
pstr = end + 1;
|
||||
strcpy(&plink->value.vmeio.parm[0],pstr);
|
||||
}
|
||||
status = putParmString(&plink->value.vmeio.parm,pstr);
|
||||
}
|
||||
break;
|
||||
case CAMAC_IO: {
|
||||
@@ -1534,11 +1631,7 @@ long dbPutString(DBENTRY *pdbentry,char *pstring)
|
||||
pstr = end + 1;
|
||||
sscanf(pstr,"%hd",&plink->value.camacio.f);
|
||||
}
|
||||
plink->value.camacio.parm[0] = 0;
|
||||
if(end = strchr(pstr,'@')) {
|
||||
pstr = end + 1;
|
||||
strcpy(&plink->value.camacio.parm[0],pstr);
|
||||
}
|
||||
status = putParmString(&plink->value.camacio.parm,pstr);
|
||||
}
|
||||
break;
|
||||
case RF_IO: {
|
||||
@@ -1577,11 +1670,7 @@ long dbPutString(DBENTRY *pdbentry,char *pstring)
|
||||
if(!(end = strchr(pstr,'S'))) return (S_dbLib_badField);
|
||||
pstr = end + 1;
|
||||
sscanf(pstr,"%hd",&plink->value.abio.signal);
|
||||
plink->value.abio.parm[0] = 0;
|
||||
if(end = strchr(pstr,'@')) {
|
||||
pstr = end + 1;
|
||||
strcpy(&plink->value.abio.parm[0],pstr);
|
||||
}
|
||||
status = putParmString(&plink->value.abio.parm,pstr);
|
||||
}
|
||||
break;
|
||||
case GPIB_IO: {
|
||||
@@ -1595,11 +1684,7 @@ long dbPutString(DBENTRY *pdbentry,char *pstring)
|
||||
if(!(end = strchr(pstr,'A'))) return (S_dbLib_badField);
|
||||
pstr = end + 1;
|
||||
sscanf(pstr,"%hd",&plink->value.gpibio.addr);
|
||||
plink->value.gpibio.parm[0] = 0;
|
||||
if(end = strchr(pstr,'@')) {
|
||||
pstr = end + 1;
|
||||
strcpy(&plink->value.gpibio.parm[0],pstr);
|
||||
}
|
||||
status = putParmString(&plink->value.gpibio.parm,pstr);
|
||||
}
|
||||
break;
|
||||
case BITBUS_IO: {
|
||||
@@ -1627,11 +1712,7 @@ long dbPutString(DBENTRY *pdbentry,char *pstring)
|
||||
pstr = end + 1;
|
||||
sscanf(pstr,"%hd",&tmp_val);
|
||||
plink->value.bitbusio.signal=(unsigned char)tmp_val;
|
||||
plink->value.bitbusio.parm[0] = 0;
|
||||
if(end = strchr(pstr,'@')) {
|
||||
pstr = end + 1;
|
||||
strcpy(&plink->value.bitbusio.parm[0],pstr);
|
||||
}
|
||||
status = putParmString(&plink->value.bitbusio.parm,pstr);
|
||||
}
|
||||
break;
|
||||
case BBGPIB_IO: {
|
||||
@@ -1655,11 +1736,7 @@ long dbPutString(DBENTRY *pdbentry,char *pstring)
|
||||
pstr = end + 1;
|
||||
sscanf(pstr,"%hd",&tmp_val);
|
||||
plink->value.bbgpibio.gpibaddr=tmp_val;
|
||||
plink->value.bbgpibio.parm[0] = 0;
|
||||
if(end = strchr(pstr,'@')) {
|
||||
pstr = end + 1;
|
||||
strcpy(&plink->value.bbgpibio.parm[0],pstr);
|
||||
}
|
||||
status = putParmString(&plink->value.bbgpibio.parm,pstr);
|
||||
}
|
||||
break;
|
||||
case VXI_IO: {
|
||||
@@ -1688,21 +1765,11 @@ long dbPutString(DBENTRY *pdbentry,char *pstring)
|
||||
} else {
|
||||
plink->value.vxiio.signal = 0;
|
||||
}
|
||||
plink->value.vxiio.parm[0] = 0;
|
||||
if(end = strchr(pstr,'@')) {
|
||||
pstr = end + 1;
|
||||
strcpy(&plink->value.vxiio.parm[0],pstr);
|
||||
}
|
||||
status = putParmString(&plink->value.vxiio.parm,pstr);
|
||||
}
|
||||
break;
|
||||
case INST_IO: {
|
||||
char *end;
|
||||
|
||||
plink->value.instio.string[0] = 0;
|
||||
if(end = strchr(pstr,'@')) {
|
||||
pstr = end + 1;
|
||||
strcpy(&plink->value.instio.string[0],pstr);
|
||||
}
|
||||
status = putParmString(&plink->value.instio.string,pstr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1892,7 +1959,7 @@ char *dbGetRange(DBENTRY *pdbentry)
|
||||
strcpy(message,"Not a valid field type");
|
||||
return (message);
|
||||
}
|
||||
|
||||
|
||||
brkTable *dbFindBrkTable(dbBase *pdbbase,char *name)
|
||||
{
|
||||
GPHENTRY *pgph;
|
||||
@@ -2076,6 +2143,7 @@ char **dbGetFormPrompt(DBENTRY *pdbentry)
|
||||
char **dbGetFormValue(DBENTRY *pdbentry)
|
||||
{
|
||||
struct form *pform = pdbentry->formpvt;
|
||||
dbFldDes *pflddes = pdbentry->pflddes;
|
||||
DBLINK *plink;
|
||||
char **value;
|
||||
|
||||
@@ -2091,12 +2159,27 @@ char **dbGetFormValue(DBENTRY *pdbentry)
|
||||
*value = 0;
|
||||
}
|
||||
break;
|
||||
case PV_LINK:
|
||||
case PV_LINK: {
|
||||
short pvlMask = plink->value.pv_link.pvlMask;
|
||||
|
||||
strcpy(*value,plink->value.pv_link.pvname);
|
||||
value++;
|
||||
strcpy(*value, (plink->value.pv_link.process_passive ? "Yes" : "No"));
|
||||
value++;
|
||||
strcpy(*value, (plink->value.pv_link.maximize_sevr ? "Yes" : "No"));
|
||||
switch(pflddes->field_type) {
|
||||
case DBF_INLINK:
|
||||
case DBF_OUTLINK:
|
||||
if(pvlMask&pvlOptPP) strcpy(*value,"PP");
|
||||
else if(pvlMask&pvlOptCA) strcpy(*value,"CA");
|
||||
else if(pvlMask&pvlOptCP) strcpy(*value,"CP");
|
||||
else if(pvlMask&pvlOptCPP) strcpy(*value,"CPP");
|
||||
else strcpy(*value,"NPP");
|
||||
value++;
|
||||
if(pvlMask&pvlOptMS) strcpy(*value,"MS");
|
||||
else strcpy(*value,"NMS");
|
||||
value++;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case VME_IO:
|
||||
cvtShortToString(plink->value.vmeio.card,*value);
|
||||
@@ -2204,6 +2287,7 @@ long dbPutForm(DBENTRY *pdbentry,char **value)
|
||||
long lvalue;
|
||||
double dvalue;
|
||||
char *endp;
|
||||
long status = 0;
|
||||
|
||||
if(!pform) return(S_dbLib_badLink);
|
||||
plink = pform->plink;
|
||||
@@ -2226,17 +2310,28 @@ long dbPutForm(DBENTRY *pdbentry,char **value)
|
||||
strcpy(plink->value.constantStr,*value);
|
||||
break;
|
||||
case PV_LINK: {
|
||||
int pp=0;
|
||||
int ms=0;
|
||||
short ppOpt = 0;
|
||||
short msOpt = 0;
|
||||
char *pstr;
|
||||
|
||||
pstr = *value;
|
||||
**verify = 0;
|
||||
value++; verify++;
|
||||
pp = ((strchr(*value,'Y') || strchr(*value,'y') ? TRUE : FALSE));
|
||||
**verify = 0; /*Initialize verify to NULL*/
|
||||
if(!(*value)) ppOpt = 0;
|
||||
else if(strstr(*value,"NPP")) ppOpt = 0;
|
||||
else if(strstr(*value,"PP")) ppOpt = pvlOptPP;
|
||||
else if(strstr(*value,"CA")) ppOpt = pvlOptCA;
|
||||
else if(strstr(*value,"CP")) ppOpt = pvlOptCP;
|
||||
else if(strstr(*value,"CPP")) ppOpt = pvlOptCPP;
|
||||
else strcpy(*verify,"Illegal. Chose a value");
|
||||
value++; verify++;
|
||||
ms = ((strchr(*value,'Y') || strchr(*value,'y') ? TRUE : FALSE));
|
||||
dbPutPvlink(pdbentry,pp,ms,pstr);
|
||||
**verify = 0; /*Initialize verify to NULL*/
|
||||
if(!(*value)) msOpt = 0;
|
||||
else if(strstr(*value,"NMS")) msOpt = 0;
|
||||
else if(strstr(*value,"MS")) msOpt = pvlOptMS;
|
||||
else strcpy(*verify,"Illegal. Chose a value");
|
||||
putPvLink(pdbentry,ppOpt|msOpt,pstr);
|
||||
}
|
||||
break;
|
||||
case VME_IO:
|
||||
@@ -2254,7 +2349,7 @@ long dbPutForm(DBENTRY *pdbentry,char **value)
|
||||
strcpy(*verify,"Illegal. Must be number");
|
||||
}
|
||||
value++; verify++;
|
||||
strncpy(plink->value.vmeio.parm,*value,VME_PARAM_SZ-1);
|
||||
status = putParmString(&plink->value.vmeio.parm,*value);
|
||||
break;
|
||||
case CAMAC_IO:
|
||||
lvalue = strtol(*value,&endp,0);
|
||||
@@ -2292,7 +2387,7 @@ long dbPutForm(DBENTRY *pdbentry,char **value)
|
||||
strcpy(*verify,"Illegal. Must be number");
|
||||
}
|
||||
value++; verify++;
|
||||
strncpy(plink->value.camacio.parm,*value,CAMAC_PARAM_SZ-1);
|
||||
status = putParmString(&plink->value.camacio.parm,*value);
|
||||
break;
|
||||
case RF_IO:
|
||||
lvalue = strtol(*value,&endp,0);
|
||||
@@ -2352,7 +2447,7 @@ long dbPutForm(DBENTRY *pdbentry,char **value)
|
||||
strcpy(*verify,"Illegal. Must be number");
|
||||
}
|
||||
value++; verify++;
|
||||
strncpy(plink->value.abio.parm,*value,AB_PARAM_SZ-1);
|
||||
status = putParmString(&plink->value.abio.parm,*value);
|
||||
break;
|
||||
case GPIB_IO:
|
||||
lvalue = strtol(*value,&endp,0);
|
||||
@@ -2369,7 +2464,7 @@ long dbPutForm(DBENTRY *pdbentry,char **value)
|
||||
strcpy(*verify,"Illegal. Must be number");
|
||||
}
|
||||
value++; verify++;
|
||||
strncpy(plink->value.gpibio.parm,*value,LINK_PARAM_SZ-1);
|
||||
status = putParmString(&plink->value.gpibio.parm,*value);
|
||||
**verify = 0;
|
||||
break;
|
||||
case BITBUS_IO:
|
||||
@@ -2401,11 +2496,11 @@ long dbPutForm(DBENTRY *pdbentry,char **value)
|
||||
strcpy(*verify,"Illegal. Must be number");
|
||||
}
|
||||
value++; verify++;
|
||||
strncpy(plink->value.bitbusio.parm,*value,LINK_PARAM_SZ-1);
|
||||
status = putParmString(&plink->value.bitbusio.parm,*value);
|
||||
**verify = 0;
|
||||
break;
|
||||
case INST_IO:
|
||||
strncpy(plink->value.instio.string,*value,INSTIO_FLD_SZ-1);
|
||||
status = putParmString(&plink->value.instio.string,*value);
|
||||
**verify = 0;
|
||||
break;
|
||||
case BBGPIB_IO:
|
||||
@@ -2430,7 +2525,7 @@ long dbPutForm(DBENTRY *pdbentry,char **value)
|
||||
strcpy(*verify,"Illegal. Must be number");
|
||||
}
|
||||
value++; verify++;
|
||||
strncpy(plink->value.bbgpibio.parm,*value,LINK_PARAM_SZ-1);
|
||||
status = putParmString(&plink->value.bbgpibio.parm,*value);
|
||||
**verify = 0;
|
||||
break;
|
||||
case VXI_IO:
|
||||
@@ -2465,13 +2560,13 @@ long dbPutForm(DBENTRY *pdbentry,char **value)
|
||||
strcpy(*verify,"Illegal. Must be number");
|
||||
}
|
||||
value++; verify++;
|
||||
strncpy(plink->value.vxiio.parm,*value,VXI_PARAM_SZ-1);
|
||||
status = putParmString(&plink->value.vxiio.parm,*value);
|
||||
**verify = 0;
|
||||
break;
|
||||
default :
|
||||
return(S_dbLib_badLink);
|
||||
}
|
||||
return(0);
|
||||
return(status);
|
||||
}
|
||||
|
||||
char **dbVerifyForm(DBENTRY *pdbentry,char **value)
|
||||
@@ -2517,7 +2612,7 @@ long dbGetLinkField(DBENTRY *pdbentry,int index)
|
||||
dbGetFieldAddress(pdbentry);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
int dbGetLinkType(DBENTRY *pdbentry)
|
||||
{
|
||||
dbFldDes *pflddes;
|
||||
@@ -2567,6 +2662,7 @@ long dbCvtLinkToConstant(DBENTRY *pdbentry)
|
||||
if(plink->type == CONSTANT) return(0);
|
||||
if(plink->type != PV_LINK) return(S_dbLib_badLink);
|
||||
free((void *)plink->value.pv_link.pvname);
|
||||
plink->value.pv_link.pvname = 0;
|
||||
plink->type = CONSTANT;
|
||||
if(pflddes->initial) {
|
||||
plink->value.constantStr =
|
||||
@@ -2588,6 +2684,7 @@ long dbCvtLinkToPvlink(DBENTRY *pdbentry)
|
||||
dbGetFieldAddress(pdbentry);
|
||||
pflddes = pdbentry->pflddes;
|
||||
if(!pflddes) return(-1);
|
||||
if(!pdbentry->precnode || !pdbentry->precnode->precord) return(-1);
|
||||
plink = (DBLINK *)pdbentry->pfield;
|
||||
if(!plink) return(-1);
|
||||
switch (pflddes->field_type) {
|
||||
@@ -2598,9 +2695,9 @@ long dbCvtLinkToPvlink(DBENTRY *pdbentry)
|
||||
if(plink->type != CONSTANT) return(S_dbLib_badLink);
|
||||
free(plink->value.constantStr);
|
||||
plink->type = PV_LINK;
|
||||
plink->value.pv_link.process_passive = 0;
|
||||
plink->value.pv_link.maximize_sevr = 0;
|
||||
plink->value.pv_link.pvlMask = 0;
|
||||
plink->value.pv_link.pvname = 0;
|
||||
plink->value.pv_link.precord = pdbentry->precnode->precord;
|
||||
return(0);
|
||||
default:
|
||||
errPrintf(-1,__FILE__, __LINE__,"Logic Error\n");
|
||||
@@ -2608,65 +2705,6 @@ long dbCvtLinkToPvlink(DBENTRY *pdbentry)
|
||||
return(S_dbLib_badLink);
|
||||
}
|
||||
|
||||
long dbPutPvlink(DBENTRY *pdbentry,int pp,int ms,char *pvname)
|
||||
{
|
||||
dbFldDes *pflddes;
|
||||
DBLINK *plink;
|
||||
char *pname;
|
||||
|
||||
dbGetFieldAddress(pdbentry);
|
||||
pflddes = pdbentry->pflddes;
|
||||
if(!pflddes) return(-1);
|
||||
plink = (DBLINK *)pdbentry->pfield;
|
||||
if(!plink) return(-1);
|
||||
switch (pflddes->field_type) {
|
||||
case DBF_INLINK:
|
||||
case DBF_OUTLINK:
|
||||
case DBF_FWDLINK:
|
||||
if(plink->type != PV_LINK) return(S_dbLib_badLink);
|
||||
pname = plink->value.pv_link.pvname;
|
||||
if(pname) free((void **)pname);
|
||||
pname = dbCalloc(strlen(pvname)+1,sizeof(char));
|
||||
plink->value.pv_link.pvname = pname;
|
||||
strcpy(pname,pvname);
|
||||
plink->value.pv_link.process_passive = pp;
|
||||
plink->value.pv_link.maximize_sevr = ms;
|
||||
return(0);
|
||||
default:
|
||||
errPrintf(-1,__FILE__, __LINE__,"Logic Error\n");
|
||||
}
|
||||
return(S_dbLib_badLink);
|
||||
}
|
||||
|
||||
long dbGetPvlink(DBENTRY *pdbentry,int *pp,int *ms,char *pvname)
|
||||
{
|
||||
dbFldDes *pflddes;
|
||||
DBLINK *plink;
|
||||
|
||||
dbGetFieldAddress(pdbentry);
|
||||
pflddes = pdbentry->pflddes;
|
||||
if(!pflddes) return(-1);
|
||||
plink = (DBLINK *)pdbentry->pfield;
|
||||
if(!plink) return(-1);
|
||||
switch (pflddes->field_type) {
|
||||
case DBF_INLINK:
|
||||
case DBF_OUTLINK:
|
||||
case DBF_FWDLINK:
|
||||
if(plink->type != PV_LINK) return(S_dbLib_badLink);
|
||||
if(plink->value.pv_link.pvname) {
|
||||
strcpy(pvname,plink->value.pv_link.pvname);
|
||||
} else {
|
||||
strcpy(pvname,"0");
|
||||
}
|
||||
*pp = plink->value.pv_link.process_passive;
|
||||
*ms = plink->value.pv_link.maximize_sevr;
|
||||
return(0);
|
||||
default:
|
||||
errPrintf(-1,__FILE__, __LINE__,"Logic Error\n");
|
||||
return(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void dbDumpPath(DBBASE *pdbbase)
|
||||
{
|
||||
ELLLIST *ppathList;
|
||||
|
||||
@@ -162,8 +162,6 @@ long dbGetLinkField(DBENTRY *pdbentry,int index);
|
||||
int dbGetLinkType(DBENTRY *pdbentry);
|
||||
long dbCvtLinkToConstant(DBENTRY *pdbentry);
|
||||
long dbCvtLinkToPvlink(DBENTRY *pdbentry);
|
||||
long dbPutPvlink(DBENTRY *pdbentry,int pp,int ms,char *pvname);
|
||||
long dbGetPvlink(DBENTRY *pdbentry,int *pp,int *ms,char *pvname);
|
||||
|
||||
/*dump routines*/
|
||||
void dbDumpPath(DBBASE *pdbbase);
|
||||
@@ -183,7 +181,7 @@ void dbReportDeviceConfig(DBBASE *pdbbase,FILE *report);
|
||||
void *dbCalloc(size_t nobj,size_t size);
|
||||
void *dbMalloc(size_t size);
|
||||
|
||||
extern int dbDebug;
|
||||
extern int dbStaticDebug;
|
||||
|
||||
#define S_dbLib_recdesNotFound (M_dbLib| 1) /*Record Type does not exist*/
|
||||
#define S_dbLib_recExists (M_dbLib| 3) /*Record Already exists*/
|
||||
|
||||
@@ -31,31 +31,31 @@ of this distribution.
|
||||
|
||||
long dbAllocRecord(DBENTRY *pdbentry,char *precordName)
|
||||
{
|
||||
dbRecDes *precdes = pdbentry->precdes;
|
||||
dbRecDes *pdbRecDes = pdbentry->precdes;
|
||||
dbRecordNode *precnode = pdbentry->precnode;
|
||||
dbFldDes *pflddes;
|
||||
void **papField;
|
||||
int i;
|
||||
char *pstr;
|
||||
|
||||
if(!precdes) return(S_dbLib_recdesNotFound);
|
||||
if(!pdbRecDes) return(S_dbLib_recdesNotFound);
|
||||
if(!precnode) return(S_dbLib_recNotFound);
|
||||
precnode->precord = dbCalloc(precdes->no_fields,sizeof(void *));
|
||||
precnode->precord = dbCalloc(pdbRecDes->no_fields,sizeof(void *));
|
||||
papField = (void **)precnode->precord;
|
||||
for(i=0; i<precdes->no_fields; i++) {
|
||||
pflddes = precdes->papFldDes[i];
|
||||
for(i=0; i<pdbRecDes->no_fields; i++) {
|
||||
pflddes = pdbRecDes->papFldDes[i];
|
||||
if(!pflddes) continue;
|
||||
switch(pflddes->field_type) {
|
||||
case DBF_STRING:
|
||||
if(pflddes->size <= 0) {
|
||||
fprintf(stderr,"size=0 for %s.%s\n",precdes->name,pflddes->name);
|
||||
fprintf(stderr,"size=0 for %s.%s\n",pdbRecDes->name,pflddes->name);
|
||||
pflddes->size = 1;
|
||||
}
|
||||
papField[i] = dbCalloc(pflddes->size,sizeof(char));
|
||||
if(pflddes->initial) {
|
||||
if(strlen(pflddes->initial) >= pflddes->size) {
|
||||
if(strlen(pflddes->initial) >= (unsigned)(pflddes->size)) {
|
||||
fprintf(stderr,"initial size > size for %s.%s\n",
|
||||
precdes->name,pflddes->name);
|
||||
pdbRecDes->name,pflddes->name);
|
||||
} else {
|
||||
strcpy((char *)papField[i],pflddes->initial);
|
||||
}
|
||||
@@ -107,44 +107,52 @@ long dbAllocRecord(DBENTRY *pdbentry,char *precordName)
|
||||
|
||||
long dbFreeRecord(DBENTRY *pdbentry)
|
||||
{
|
||||
dbRecDes *precdes = pdbentry->precdes;
|
||||
dbRecDes *pdbRecDes = pdbentry->precdes;
|
||||
dbRecordNode *precnode = pdbentry->precnode;
|
||||
dbFldDes *pflddes = pdbentry->pflddes;
|
||||
void **pap;
|
||||
int i,field_type;
|
||||
|
||||
if(!precdes) return(S_dbLib_recdesNotFound);
|
||||
if(!pdbRecDes) return(S_dbLib_recdesNotFound);
|
||||
if(!precnode) return(S_dbLib_recNotFound);
|
||||
if(!precnode->precord) return(S_dbLib_recNotFound);
|
||||
pap = (void **)precnode->precord;
|
||||
precnode->precord = NULL;
|
||||
for(i=0; i<precdes->no_fields; i++) {
|
||||
pflddes = precdes->papFldDes[i];
|
||||
for(i=0; i<pdbRecDes->no_fields; i++) {
|
||||
pflddes = pdbRecDes->papFldDes[i];
|
||||
field_type = pflddes->field_type;
|
||||
if(field_type==DBF_INLINK
|
||||
|| field_type==DBF_OUTLINK
|
||||
|| field_type==DBF_FWDLINK) {
|
||||
struct link *plink = (struct link *)pap[i];
|
||||
|
||||
if(plink->type== CONSTANT)
|
||||
free((void *)plink->value.constantStr);
|
||||
if(plink->type==PV_LINK)
|
||||
free((void *)plink->value.pv_link.pvname);
|
||||
switch(plink->type) {
|
||||
case CONSTANT: free((void *)plink->value.constantStr); break;
|
||||
case PV_LINK: free((void *)plink->value.pv_link.pvname); break;
|
||||
case VME_IO: dbFreeParmString(&plink->value.vmeio.parm); break;
|
||||
case CAMAC_IO: dbFreeParmString(&plink->value.camacio.parm); break;
|
||||
case AB_IO: dbFreeParmString(&plink->value.abio.parm); break;
|
||||
case GPIB_IO: dbFreeParmString(&plink->value.gpibio.parm); break;
|
||||
case BITBUS_IO: dbFreeParmString(&plink->value.bitbusio.parm);break;
|
||||
case INST_IO: dbFreeParmString(&plink->value.instio.string); break;
|
||||
case BBGPIB_IO: dbFreeParmString(&plink->value.bbgpibio.parm);break;
|
||||
case VXI_IO: dbFreeParmString(&plink->value.vxiio.parm); break;
|
||||
}
|
||||
}
|
||||
free(pap[i]);
|
||||
}
|
||||
free((void *)pap);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
long dbGetFieldAddress(DBENTRY *pdbentry)
|
||||
{
|
||||
dbRecDes *precdes = pdbentry->precdes;
|
||||
dbRecDes *pdbRecDes = pdbentry->precdes;
|
||||
dbRecordNode *precnode = pdbentry->precnode;
|
||||
dbFldDes *pflddes = pdbentry->pflddes;
|
||||
void **pap;
|
||||
|
||||
if(!precdes) return(S_dbLib_recdesNotFound);
|
||||
if(!pdbRecDes) return(S_dbLib_recdesNotFound);
|
||||
if(!precnode) return(S_dbLib_recNotFound);
|
||||
if(!pflddes) return(S_dbLib_flddesNotFound);
|
||||
if(!precnode->precord) return(0);
|
||||
@@ -155,11 +163,11 @@ long dbGetFieldAddress(DBENTRY *pdbentry)
|
||||
|
||||
char *dbRecordName(DBENTRY *pdbentry)
|
||||
{
|
||||
dbRecDes *precdes = pdbentry->precdes;
|
||||
dbRecDes *pdbRecDes = pdbentry->precdes;
|
||||
dbRecordNode *precnode = pdbentry->precnode;
|
||||
void **pap;
|
||||
|
||||
if(!precdes) return(0);
|
||||
if(!pdbRecDes) return(0);
|
||||
if(!precnode) return(0);
|
||||
if(!precnode->precord) return(0);
|
||||
pap = (void **)precnode->precord;
|
||||
@@ -190,8 +198,7 @@ int dbIsDefaultValue(DBENTRY *pdbentry)
|
||||
if(!pfield) return(TRUE);
|
||||
if(!pflddes->initial) return(FALSE);
|
||||
return(strcmp((char *)pfield,(char *)pflddes->initial)==0);
|
||||
case DBF_MENU:
|
||||
case DBF_DEVICE: {
|
||||
case DBF_MENU: {
|
||||
unsigned short val,ival;
|
||||
|
||||
if(!pfield) return(FALSE);
|
||||
@@ -200,6 +207,18 @@ int dbIsDefaultValue(DBENTRY *pdbentry)
|
||||
sscanf(pflddes->initial,"%hu",&ival);
|
||||
return((val==ival)?TRUE:FALSE);
|
||||
}
|
||||
case DBF_DEVICE: {
|
||||
dbRecDes *pdbRecDes = pdbentry->precdes;
|
||||
devSup *pdevSup;
|
||||
|
||||
if(!pdbRecDes) {
|
||||
epicsPrintf("dbIsDefaultValue: pdbRecDes is NULL??\n");
|
||||
return(FALSE);
|
||||
}
|
||||
pdevSup = (devSup *)ellFirst(&pdbRecDes->devList);
|
||||
if(!pdevSup) return(TRUE);
|
||||
return(FALSE);
|
||||
}
|
||||
case DBF_INLINK:
|
||||
case DBF_OUTLINK:
|
||||
case DBF_FWDLINK: {
|
||||
@@ -243,7 +262,7 @@ long dbPutStringNum(DBENTRY *pdbentry,char *pstring)
|
||||
if(!precnode->precord) return(S_dbLib_recNotFound);
|
||||
if(!pflddes) return(S_dbLib_flddesNotFound);
|
||||
if(pfield) {
|
||||
if(strlen(pfield) < strlen(pstring)) {
|
||||
if((unsigned)strlen(pfield) < (unsigned)strlen(pstring)) {
|
||||
free((void *)pfield);
|
||||
pfield = NULL;
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
|
||||
/*Following are not intended for client code */
|
||||
void dbInitDeviceMenu(DBENTRY *pdbentry);
|
||||
void dbFreeParmString(char **pparm);
|
||||
|
||||
/*The following routines have different versions for run-time no-run-time*/
|
||||
long dbAllocRecord(DBENTRY *pdbentry,char *precordName);
|
||||
@@ -61,7 +62,7 @@ typedef struct{
|
||||
dbRecordNode *precnode;
|
||||
}PVDENTRY;
|
||||
int dbPvdTableSize(int size);
|
||||
extern int dbDebug;
|
||||
extern int dbStaticDebug;
|
||||
void dbPvdInitPvt(DBBASE *pdbbase);
|
||||
PVDENTRY *dbPvdFind(DBBASE *pdbbase,char *name,int lenname);
|
||||
PVDENTRY *dbPvdAdd(DBBASE *pdbbase,dbRecDes *precdes,dbRecordNode *precnode);
|
||||
|
||||
+45
-25
@@ -152,23 +152,23 @@ static void doubleToString(double value,char *preturn)
|
||||
|
||||
long dbAllocRecord(DBENTRY *pdbentry,char *precordName)
|
||||
{
|
||||
dbRecDes *precdes = pdbentry->precdes;
|
||||
dbRecDes *pdbRecDes = pdbentry->precdes;
|
||||
dbRecordNode *precnode = pdbentry->precnode;
|
||||
dbFldDes *pflddes;
|
||||
int i;
|
||||
char *precord;
|
||||
char *pfield;
|
||||
|
||||
if(!precdes) return(S_dbLib_recdesNotFound);
|
||||
if(!pdbRecDes) return(S_dbLib_recdesNotFound);
|
||||
if(!precnode) return(S_dbLib_recNotFound);
|
||||
precnode->precord = dbCalloc(1,precdes->rec_size);
|
||||
precnode->precord = dbCalloc(1,pdbRecDes->rec_size);
|
||||
precord = (char *)precnode->precord;
|
||||
if(precdes->rec_size == 0) {
|
||||
if(pdbRecDes->rec_size == 0) {
|
||||
epicsPrintf("dbAllocRecord(%s) record_size =0\n",
|
||||
precdes->name);
|
||||
pdbRecDes->name);
|
||||
return(S_dbLib_noRecSup);
|
||||
}
|
||||
pflddes = precdes->papFldDes[0];
|
||||
pflddes = pdbRecDes->papFldDes[0];
|
||||
if(!pflddes) {
|
||||
epicsPrintf("dbAllocRecord pflddes for NAME not found\n");
|
||||
return(S_dbLib_flddesNotFound);
|
||||
@@ -179,9 +179,9 @@ long dbAllocRecord(DBENTRY *pdbentry,char *precordName)
|
||||
}
|
||||
pfield = precord + pflddes->offset;
|
||||
strcpy(pfield,precordName);
|
||||
for(i=1; i<precdes->no_fields; i++) {
|
||||
for(i=1; i<pdbRecDes->no_fields; i++) {
|
||||
|
||||
pflddes = precdes->papFldDes[i];
|
||||
pflddes = pdbRecDes->papFldDes[i];
|
||||
if(!pflddes) continue;
|
||||
pfield = precord + pflddes->offset;
|
||||
pdbentry->pfield = (void *)pfield;
|
||||
@@ -192,7 +192,7 @@ long dbAllocRecord(DBENTRY *pdbentry,char *precordName)
|
||||
if(pflddes->initial) {
|
||||
if(strlen(pflddes->initial) >= pflddes->size) {
|
||||
epicsPrintf("initial size > size for %s.%s\n",
|
||||
precdes->name,pflddes->name);
|
||||
pdbRecDes->name,pflddes->name);
|
||||
} else {
|
||||
strcpy(pfield,pflddes->initial);
|
||||
}
|
||||
@@ -207,8 +207,6 @@ long dbAllocRecord(DBENTRY *pdbentry,char *precordName)
|
||||
case DBF_FLOAT:
|
||||
case DBF_DOUBLE:
|
||||
case DBF_ENUM:
|
||||
case DBF_DEVICE:
|
||||
if(!pflddes->ftPvt) dbInitDeviceMenu(pdbentry);
|
||||
case DBF_MENU:
|
||||
if(pflddes->initial) {
|
||||
long status;
|
||||
@@ -216,9 +214,12 @@ long dbAllocRecord(DBENTRY *pdbentry,char *precordName)
|
||||
status = dbPutStringNum(pdbentry,pflddes->initial);
|
||||
if(status)
|
||||
epicsPrintf("Error initializing %s.%s initial %s\n",
|
||||
precdes->name,pflddes->name,pflddes->initial);
|
||||
pdbRecDes->name,pflddes->name,pflddes->initial);
|
||||
}
|
||||
break;
|
||||
case DBF_DEVICE:
|
||||
if(!pflddes->ftPvt) dbInitDeviceMenu(pdbentry);
|
||||
break;
|
||||
case DBF_INLINK:
|
||||
case DBF_OUTLINK:
|
||||
case DBF_FWDLINK: {
|
||||
@@ -242,10 +243,10 @@ long dbAllocRecord(DBENTRY *pdbentry,char *precordName)
|
||||
|
||||
long dbFreeRecord(DBENTRY *pdbentry)
|
||||
{
|
||||
dbRecDes *precdes = pdbentry->precdes;
|
||||
dbRecDes *pdbRecDes = pdbentry->precdes;
|
||||
dbRecordNode *precnode = pdbentry->precnode;
|
||||
|
||||
if(!precdes) return(S_dbLib_recdesNotFound);
|
||||
if(!pdbRecDes) return(S_dbLib_recdesNotFound);
|
||||
if(!precnode) return(S_dbLib_recNotFound);
|
||||
if(!precnode->precord) return(S_dbLib_recNotFound);
|
||||
free(precnode->precord);
|
||||
@@ -255,11 +256,11 @@ long dbFreeRecord(DBENTRY *pdbentry)
|
||||
|
||||
long dbGetFieldAddress(DBENTRY *pdbentry)
|
||||
{
|
||||
dbRecDes *precdes = pdbentry->precdes;
|
||||
dbRecDes *pdbRecDes = pdbentry->precdes;
|
||||
dbRecordNode *precnode = pdbentry->precnode;
|
||||
dbFldDes *pflddes = pdbentry->pflddes;
|
||||
|
||||
if(!precdes) return(S_dbLib_recdesNotFound);
|
||||
if(!pdbRecDes) return(S_dbLib_recdesNotFound);
|
||||
if(!precnode) return(S_dbLib_recNotFound);
|
||||
if(!pflddes) return(S_dbLib_flddesNotFound);
|
||||
if(!precnode->precord) return(0);
|
||||
@@ -269,16 +270,16 @@ long dbGetFieldAddress(DBENTRY *pdbentry)
|
||||
|
||||
char *dbRecordName(DBENTRY *pdbentry)
|
||||
{
|
||||
dbRecDes *precdes = pdbentry->precdes;
|
||||
dbRecDes *pdbRecDes = pdbentry->precdes;
|
||||
dbRecordNode *precnode = pdbentry->precnode;
|
||||
dbFldDes *pflddes;
|
||||
char *precord;
|
||||
|
||||
if(!precdes) return(0);
|
||||
if(!pdbRecDes) return(0);
|
||||
if(!precnode) return(0);
|
||||
if(!precnode->precord) return(0);
|
||||
precord = (char *)precnode->precord;
|
||||
pflddes = precdes->papFldDes[0];
|
||||
pflddes = pdbRecDes->papFldDes[0];
|
||||
if(!pflddes) return(NULL);
|
||||
return(precord + pflddes->offset);
|
||||
}
|
||||
@@ -377,8 +378,7 @@ int dbIsDefaultValue(DBENTRY *pdbentry)
|
||||
return((field==0.0));
|
||||
}
|
||||
case DBF_ENUM:
|
||||
case DBF_MENU:
|
||||
case DBF_DEVICE: {
|
||||
case DBF_MENU: {
|
||||
unsigned short field = *(unsigned short *)pfield;
|
||||
unsigned long ltemp;
|
||||
|
||||
@@ -388,10 +388,30 @@ int dbIsDefaultValue(DBENTRY *pdbentry)
|
||||
}
|
||||
return((field==0));
|
||||
}
|
||||
case DBF_DEVICE: {
|
||||
dbRecDes *pdbRecDes = pdbentry->precdes;
|
||||
devSup *pdevSup;
|
||||
|
||||
if(!pdbRecDes) {
|
||||
epicsPrintf("dbIsDefaultValue: pdbRecDes is NULL??\n");
|
||||
return(FALSE);
|
||||
}
|
||||
pdevSup = (devSup *)ellFirst(&pdbRecDes->devList);
|
||||
if(!pdevSup) return(TRUE);
|
||||
return(FALSE);
|
||||
}
|
||||
case DBF_INLINK:
|
||||
case DBF_OUTLINK:
|
||||
case DBF_FWDLINK:
|
||||
return(TRUE); /*Dont know what to do with this!!*/
|
||||
case DBF_FWDLINK: {
|
||||
struct link *plink = (struct link *)pfield;
|
||||
|
||||
if(!plink) return(FALSE);
|
||||
if(plink->type!=CONSTANT) return(FALSE);
|
||||
if(plink->value.constantStr == 0) return(TRUE);
|
||||
if(strcmp(plink->value.constantStr,pflddes->initial)==0)
|
||||
return(TRUE);
|
||||
return(FALSE);
|
||||
}
|
||||
default:
|
||||
return(TRUE);
|
||||
}
|
||||
@@ -583,8 +603,8 @@ void dbGetRecordtypeSizeOffset(dbRecDes *pdbRecDes)
|
||||
(void *)&sizeOffset, &type);
|
||||
if (vxstatus != OK) {
|
||||
status = S_rec_noSizeOffset;
|
||||
errPrintf(status,__FILE__,__LINE__,"%s",pdbRecDes->name);
|
||||
return;
|
||||
errPrintf(status,__FILE__,__LINE__,"%s",name);
|
||||
exit(1);
|
||||
}
|
||||
sizeOffset(pdbRecDes);
|
||||
}
|
||||
|
||||
+19
-19
@@ -37,31 +37,31 @@ database_item: include
|
||||
|
||||
include: tokenINCLUDE tokenSTRING
|
||||
{
|
||||
if(dbDebug>2) printf("include : %s\n",$2);
|
||||
if(dbStaticDebug>2) printf("include : %s\n",$2);
|
||||
dbIncludeNew($2);
|
||||
};
|
||||
|
||||
path: tokenPATH tokenSTRING
|
||||
{
|
||||
if(dbDebug>2) printf("path : %s\n",$2);
|
||||
if(dbStaticDebug>2) printf("path : %s\n",$2);
|
||||
dbPathCmd($2);
|
||||
};
|
||||
|
||||
addpath: tokenADDPATH tokenSTRING
|
||||
{
|
||||
if(dbDebug>2) printf("addpath : %s\n",$2);
|
||||
if(dbStaticDebug>2) printf("addpath : %s\n",$2);
|
||||
dbAddPathCmd($2);
|
||||
};
|
||||
|
||||
menu_head: '(' tokenSTRING ')'
|
||||
{
|
||||
if(dbDebug>2) printf("menu_head %s\n",$2);
|
||||
if(dbStaticDebug>2) printf("menu_head %s\n",$2);
|
||||
dbMenuHead($2);
|
||||
};
|
||||
|
||||
menu_body: '{' choice_list '}'
|
||||
{
|
||||
if(dbDebug>2) printf("menu_body\n");
|
||||
if(dbStaticDebug>2) printf("menu_body\n");
|
||||
dbMenuBody();
|
||||
}
|
||||
| include ;
|
||||
@@ -70,19 +70,19 @@ choice_list: choice_list choice | choice;
|
||||
|
||||
choice: tokenCHOICE '(' tokenSTRING ',' tokenSTRING ')'
|
||||
{
|
||||
if(dbDebug>2) printf("choice %s %s\n",$3,$5);
|
||||
if(dbStaticDebug>2) printf("choice %s %s\n",$3,$5);
|
||||
dbMenuChoice($3,$5);
|
||||
} ;
|
||||
|
||||
recordtype_head: '(' tokenSTRING ')'
|
||||
{
|
||||
if(dbDebug>2) printf("recordtype_head %s\n",$2);
|
||||
if(dbStaticDebug>2) printf("recordtype_head %s\n",$2);
|
||||
dbRecordtypeHead($2);
|
||||
};
|
||||
|
||||
recordtype_body: '{' recordtype_field_list '}'
|
||||
{
|
||||
if(dbDebug>2) printf("recordtype_body\n");
|
||||
if(dbStaticDebug>2) printf("recordtype_body\n");
|
||||
dbRecordtypeBody();
|
||||
};
|
||||
|
||||
@@ -94,7 +94,7 @@ recordtype_field: tokenFIELD recordtype_field_head recordtype_field_body
|
||||
|
||||
recordtype_field_head: '(' tokenSTRING ',' tokenSTRING ')'
|
||||
{
|
||||
if(dbDebug>2) printf("recordtype_field_head %s %s\n",$2,$4);
|
||||
if(dbStaticDebug>2) printf("recordtype_field_head %s %s\n",$2,$4);
|
||||
dbRecordtypeFieldHead($2,$4);
|
||||
};
|
||||
|
||||
@@ -105,14 +105,14 @@ recordtype_field_item_list: recordtype_field_item_list recordtype_field_item
|
||||
|
||||
recordtype_field_item: tokenSTRING '(' tokenSTRING ')'
|
||||
{
|
||||
if(dbDebug>2) printf("recordtype_field_item %s %s\n",$1,$3);
|
||||
if(dbStaticDebug>2) printf("recordtype_field_item %s %s\n",$1,$3);
|
||||
dbRecordtypeFieldItem($1,$3);
|
||||
}
|
||||
| tokenMENU '(' tokenSTRING ')'
|
||||
{
|
||||
char *pmenu;
|
||||
|
||||
if(dbDebug>2) printf("recordtype_field_item %s (%s)\n",menuString,$3);
|
||||
if(dbStaticDebug>2) printf("recordtype_field_item %s (%s)\n",menuString,$3);
|
||||
pmenu = (char *)malloc(strlen(menuString)+1);
|
||||
strcpy(pmenu,menuString);
|
||||
dbRecordtypeFieldItem(pmenu,$3);
|
||||
@@ -122,26 +122,26 @@ recordtype_field_item: tokenSTRING '(' tokenSTRING ')'
|
||||
device: tokenDEVICE '('
|
||||
tokenSTRING ',' tokenSTRING ',' tokenSTRING ',' tokenSTRING ')'
|
||||
{
|
||||
if(dbDebug>2) printf("device %s %s %s %s\n",$3,$5,$7,$9);
|
||||
if(dbStaticDebug>2) printf("device %s %s %s %s\n",$3,$5,$7,$9);
|
||||
dbDevice($3,$5,$7,$9);
|
||||
};
|
||||
|
||||
|
||||
driver: tokenDRIVER '(' tokenSTRING ')'
|
||||
{
|
||||
if(dbDebug>2) printf("driver %s\n",$3);
|
||||
if(dbStaticDebug>2) printf("driver %s\n",$3);
|
||||
dbDriver($3);
|
||||
};
|
||||
|
||||
break_head: '(' tokenSTRING ')'
|
||||
{
|
||||
if(dbDebug>2) printf("break_head %s\n",$2);
|
||||
if(dbStaticDebug>2) printf("break_head %s\n",$2);
|
||||
dbBreakHead($2);
|
||||
};
|
||||
|
||||
break_body : '{' break_list '}'
|
||||
{
|
||||
if(dbDebug>2) printf("break_body\n");
|
||||
if(dbStaticDebug>2) printf("break_body\n");
|
||||
dbBreakBody();
|
||||
};
|
||||
|
||||
@@ -151,20 +151,20 @@ break_list: break_list ',' break_item
|
||||
|
||||
break_item: tokenSTRING
|
||||
{
|
||||
if(dbDebug>2) printf("break_item tokenSTRING %s\n",$1);
|
||||
if(dbStaticDebug>2) printf("break_item tokenSTRING %s\n",$1);
|
||||
dbBreakItem($1);
|
||||
};
|
||||
|
||||
|
||||
record_head: '(' tokenSTRING ',' tokenSTRING ')'
|
||||
{
|
||||
if(dbDebug>2) printf("record_head %s %s\n",$2,$4);
|
||||
if(dbStaticDebug>2) printf("record_head %s %s\n",$2,$4);
|
||||
dbRecordHead($2,$4);
|
||||
};
|
||||
|
||||
record_body: '{' record_field_list '}'
|
||||
{
|
||||
if(dbDebug>2) printf("record_body\n");
|
||||
if(dbStaticDebug>2) printf("record_body\n");
|
||||
dbRecordBody();
|
||||
};
|
||||
|
||||
@@ -173,7 +173,7 @@ record_field_list: record_field_list record_field
|
||||
|
||||
record_field: tokenFIELD '(' tokenSTRING ',' tokenSTRING ')'
|
||||
{
|
||||
if(dbDebug>2) printf("record_field %s %s\n",$3,$5);
|
||||
if(dbStaticDebug>2) printf("record_field %s %s\n",$3,$5);
|
||||
dbRecordField($3,$5);
|
||||
}
|
||||
| include ;
|
||||
|
||||
+29
-37
@@ -34,13 +34,15 @@
|
||||
* .03 9-9-92 frl added vxi link type
|
||||
* .04 12-13-93 mcn added conversion pointer for fast links
|
||||
* .05 1-10-95 jt added rf_io structure
|
||||
* .06 01-10-96 lrd added ca_link structure fields
|
||||
*/
|
||||
|
||||
#include <dbDefs.h>
|
||||
|
||||
#ifndef INClinkh
|
||||
#define INClinkh 1
|
||||
|
||||
/* link types */
|
||||
#ifndef INClinkLT
|
||||
#define INClinkLT
|
||||
#define CONSTANT 0
|
||||
#define PV_LINK 1
|
||||
#define VME_IO 2
|
||||
@@ -80,39 +82,32 @@ maplinkType pamaplinkType[LINK_NTYPES] = {
|
||||
};
|
||||
#endif /*LINK_GBLSOURCE*/
|
||||
|
||||
#endif /*INClinkLT*/
|
||||
|
||||
#ifndef INClinkh
|
||||
#define INClinkh 1
|
||||
#define INSTIO_FLD_SZ 36 /* field size for instio */
|
||||
#define LINK_PARAM_SZ 32
|
||||
#define VME_PARAM_SZ 32
|
||||
#define AB_PARAM_SZ 28
|
||||
#define CAMAC_PARAM_SZ 26
|
||||
#define VXI_PARAM_SZ 26
|
||||
#define VXIDYNAMIC 0
|
||||
#define VXISTATIC 1
|
||||
|
||||
/* structure of a link to a process variable*/
|
||||
/* structure of a PV_LINK DB_LINK and a CA_LINK */
|
||||
/*Options defined by pvlMask */
|
||||
#define pvlOptMS 0x1 /*Maximize Severity*/
|
||||
#define pvlOptPP 0x2 /*Process Passive*/
|
||||
#define pvlOptCA 0x4 /*Always make it a CA link*/
|
||||
#define pvlOptCP 0x8 /*CA + process on monitor*/
|
||||
#define pvlOptCPP 0x10 /*CA + process passive record on monitor*/
|
||||
#define pvlOptFWD 0x20 /*Generate ca_put for forward link*/
|
||||
typedef long (*LINKCVT)();
|
||||
struct pv_link {
|
||||
short process_passive; /* should in/out passive link be processed*/
|
||||
short maximize_sevr; /* maximize sevr of link. stat=LINK_ALARM*/
|
||||
char *pvname;
|
||||
};
|
||||
|
||||
/* structure of a link to a database link */
|
||||
struct db_link {
|
||||
short process_passive; /* should in/out passive link be processed */
|
||||
short maximize_sevr; /* maximize sevr of link. stat=LINK_ALARM */
|
||||
void *pdbAddr; /* pointer to database address structure */
|
||||
long (*conversion)(); /* conversion routine for fast links */
|
||||
char *pvname; /*pvname to link to*/
|
||||
void *precord; /*Address of record containing link*/
|
||||
void *pvt; /*CA or DB private*/
|
||||
LINKCVT getCvt; /*input conversion function*/
|
||||
short pvlMask; /*Options mask*/
|
||||
short lastGetdbrType; /*last dbrType for DB or CA get*/
|
||||
};
|
||||
|
||||
/* structure of a VME io channel */
|
||||
struct vmeio {
|
||||
short card;
|
||||
short signal;
|
||||
char parm[VME_PARAM_SZ];
|
||||
char *parm;
|
||||
};
|
||||
|
||||
/* structure of a CAMAC io channel */
|
||||
@@ -122,7 +117,7 @@ struct camacio {
|
||||
short n;
|
||||
short a;
|
||||
short f;
|
||||
char parm[CAMAC_PARAM_SZ];
|
||||
char *parm;
|
||||
};
|
||||
|
||||
/* structure of a RF io channel */
|
||||
@@ -141,14 +136,14 @@ struct abio {
|
||||
short adapter;
|
||||
short card;
|
||||
short signal;
|
||||
char parm[AB_PARAM_SZ];
|
||||
char *parm;
|
||||
};
|
||||
|
||||
/* structure of a gpib io channel */
|
||||
struct gpibio {
|
||||
short link;
|
||||
short addr; /* device address */
|
||||
char parm[LINK_PARAM_SZ];
|
||||
char *parm;
|
||||
};
|
||||
|
||||
/* structure of a bitbus io channel */
|
||||
@@ -157,7 +152,7 @@ struct bitbusio {
|
||||
unsigned char node;
|
||||
unsigned char port;
|
||||
unsigned char signal;
|
||||
char parm[LINK_PARAM_SZ];
|
||||
char *parm;
|
||||
};
|
||||
|
||||
/* structure of a bitbus to gpib io channel */
|
||||
@@ -166,12 +161,12 @@ struct bbgpibio {
|
||||
unsigned char bbaddr;
|
||||
unsigned char gpibaddr;
|
||||
unsigned char pad;
|
||||
char parm[LINK_PARAM_SZ];
|
||||
char *parm;
|
||||
};
|
||||
|
||||
/* structure of an instrument io link */
|
||||
struct instio {
|
||||
char string[INSTIO_FLD_SZ]; /* the cat of location.
|
||||
char *string; /* the cat of location.
|
||||
signal.parameter */
|
||||
};
|
||||
|
||||
@@ -182,7 +177,7 @@ struct vxiio{
|
||||
short slot;
|
||||
short la; /* logical address if flag =1 */
|
||||
short signal;
|
||||
char parm[VXI_PARAM_SZ];
|
||||
char *parm;
|
||||
};
|
||||
|
||||
/* union of possible address structures */
|
||||
@@ -195,18 +190,15 @@ union value{
|
||||
struct abio abio; /* allen-bradley io point */
|
||||
struct gpibio gpibio;
|
||||
struct bitbusio bitbusio;
|
||||
struct db_link db_link; /* Data base link */
|
||||
void *ca_link; /* Channel Access link */
|
||||
struct instio instio; /* instrument io link */
|
||||
struct bbgpibio bbgpibio; /* bitbus to gpib io link */
|
||||
struct vxiio vxiio; /* vxi io */
|
||||
};
|
||||
|
||||
struct link{
|
||||
long type;
|
||||
long pad;
|
||||
union value value;
|
||||
short type;
|
||||
};
|
||||
|
||||
typedef struct link DBLINK;
|
||||
#endif
|
||||
#endif /*INClinkh*/
|
||||
|
||||
Reference in New Issue
Block a user