diff --git a/src/ioc/db/Makefile b/src/ioc/db/Makefile index 83cd2ce4a..1b83eeaf9 100644 --- a/src/ioc/db/Makefile +++ b/src/ioc/db/Makefile @@ -14,12 +14,13 @@ SRC_DIRS += $(IOCDIR)/db INC += callback.h INC += dbAccess.h INC += dbAccessDefs.h -INC += dbCa.h INC += dbAddr.h INC += dbBkpt.h +INC += dbCa.h INC += dbChannel.h INC += dbConvert.h INC += dbConvertFast.h +INC += dbDbLink.h INC += dbExtractArray.h INC += dbEvent.h INC += dbLink.h @@ -65,6 +66,7 @@ dbCore_SRCS += dbAccess.c dbCore_SRCS += dbBkpt.c dbCore_SRCS += dbChannel.c dbCore_SRCS += dbConvert.c +dbCore_SRCS += dbDbLink.c dbCore_SRCS += dbFastLinkConv.c dbCore_SRCS += dbExtractArray.c dbCore_SRCS += dbLink.c diff --git a/src/ioc/db/dbDbLink.c b/src/ioc/db/dbDbLink.c new file mode 100644 index 000000000..ab106f77d --- /dev/null +++ b/src/ioc/db/dbDbLink.c @@ -0,0 +1,344 @@ +/*************************************************************************\ +* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne +* National Laboratory. +* Copyright (c) 2002 The Regents of the University of California, as +* Operator of Los Alamos National Laboratory. +* EPICS BASE is distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. +\*************************************************************************/ +/* dbDbLink.c + * + * Original Authors: Bob Dalesio, Marty Kraimer + * Current Author: Andrew Johnson + */ + +#include +#include +#include +#include +#include + +#include "alarm.h" +#include "cantProceed.h" +#include "cvtFast.h" +#include "dbDefs.h" +#include "ellLib.h" +#include "epicsTime.h" +#include "errlog.h" + +#include "caeventmask.h" + +#define epicsExportSharedSymbols +#include "dbAccessDefs.h" +#include "dbAddr.h" +#include "dbBase.h" +#include "dbBkpt.h" +#include "dbCommon.h" +#include "dbConvertFast.h" +#include "dbConvert.h" +#include "db_field_log.h" +#include "dbFldTypes.h" +#include "dbLink.h" +#include "dbLockPvt.h" +#include "dbNotify.h" +#include "dbScan.h" +#include "dbStaticLib.h" +#include "devSup.h" +#include "link.h" +#include "recGbl.h" +#include "recSup.h" +#include "special.h" + +/***************************** Database Links *****************************/ + +/* Forward definition */ +static lset dbDb_lset; + +long dbDbInitLink(struct link *plink, short dbfType) +{ + DBADDR dbaddr; + long status; + DBADDR *pdbAddr; + + status = dbNameToAddr(plink->value.pv_link.pvname, &dbaddr); + if (status) + return status; + + plink->lset = &dbDb_lset; + plink->type = DB_LINK; + pdbAddr = dbCalloc(1, sizeof(struct dbAddr)); + *pdbAddr = dbaddr; /* structure copy */ + plink->value.pv_link.pvt = pdbAddr; + ellAdd(&dbaddr.precord->bklnk, &plink->value.pv_link.backlinknode); + /* merging into the same lockset is deferred to the caller. + * cf. initPVLinks() + */ + dbLockSetMerge(NULL, plink->precord, dbaddr.precord); + assert(plink->precord->lset->plockSet == dbaddr.precord->lset->plockSet); + return 0; +} + +void dbDbAddLink(dbLocker *locker, struct link *plink, short dbfType, DBADDR *ptarget) +{ + plink->lset = &dbDb_lset; + plink->type = DB_LINK; + plink->value.pv_link.pvt = ptarget; + ellAdd(&ptarget->precord->bklnk, &plink->value.pv_link.backlinknode); + + /* target record is already locked in dbPutFieldLink() */ + dbLockSetMerge(locker, plink->precord, ptarget->precord); +} + +static void dbDbRemoveLink(dbLocker *locker, struct link *plink) +{ + DBADDR *pdbAddr = (DBADDR *) plink->value.pv_link.pvt; + plink->value.pv_link.pvt = 0; + plink->value.pv_link.getCvt = 0; + plink->value.pv_link.pvlMask = 0; + plink->value.pv_link.lastGetdbrType = 0; + plink->type = PV_LINK; + plink->lset = NULL; + ellDelete(&pdbAddr->precord->bklnk, &plink->value.pv_link.backlinknode); + dbLockSetSplit(locker, plink->precord, pdbAddr->precord); + free(pdbAddr); +} + +static int dbDbIsConnected(const struct link *plink) +{ + return TRUE; +} + +static int dbDbGetDBFtype(const struct link *plink) +{ + DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt; + + return paddr->field_type; +} + +static long dbDbGetElements(const struct link *plink, long *nelements) +{ + DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt; + + *nelements = paddr->no_elements; + return 0; +} + +static long dbDbGetValue(struct link *plink, short dbrType, void *pbuffer, + epicsEnum16 *pstat, epicsEnum16 *psevr, long *pnRequest) +{ + struct pv_link *ppv_link = &plink->value.pv_link; + DBADDR *paddr = ppv_link->pvt; + dbCommon *precord = plink->precord; + long status; + + /* scan passive records if link is process passive */ + if (ppv_link->pvlMask & pvlOptPP) { + unsigned char pact = precord->pact; + + precord->pact = TRUE; + status = dbScanPassive(precord, paddr->precord); + precord->pact = pact; + if (status) + return status; + } + *pstat = paddr->precord->stat; + *psevr = paddr->precord->sevr; + + if (ppv_link->getCvt && ppv_link->lastGetdbrType == dbrType) { + status = ppv_link->getCvt(paddr->pfield, pbuffer, paddr); + } else { + unsigned short dbfType = paddr->field_type; + + if (dbrType < 0 || dbrType > DBR_ENUM || dbfType > DBF_DEVICE) + return S_db_badDbrtype; + + if (paddr->no_elements == 1 && (!pnRequest || *pnRequest == 1) + && paddr->special != SPC_ATTRIBUTE) { + ppv_link->getCvt = dbFastGetConvertRoutine[dbfType][dbrType]; + status = ppv_link->getCvt(paddr->pfield, pbuffer, paddr); + } else { + ppv_link->getCvt = NULL; + status = dbGet(paddr, dbrType, pbuffer, NULL, pnRequest, NULL); + } + ppv_link->lastGetdbrType = dbrType; + } + return status; +} + +static long dbDbGetControlLimits(const struct link *plink, double *low, + double *high) +{ + DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt; + struct buffer { + DBRctrlDouble + double value; + } buffer; + long options = DBR_CTRL_DOUBLE; + long number_elements = 0; + long status = dbGet(paddr, DBR_DOUBLE, &buffer, &options, &number_elements, + NULL); + + if (status) + return status; + + *low = buffer.lower_ctrl_limit; + *high = buffer.upper_ctrl_limit; + return 0; +} + +static long dbDbGetGraphicLimits(const struct link *plink, double *low, + double *high) +{ + DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt; + struct buffer { + DBRgrDouble + double value; + } buffer; + long options = DBR_GR_DOUBLE; + long number_elements = 0; + long status = dbGet(paddr, DBR_DOUBLE, &buffer, &options, &number_elements, + NULL); + + if (status) + return status; + + *low = buffer.lower_disp_limit; + *high = buffer.upper_disp_limit; + return 0; +} + +static long dbDbGetAlarmLimits(const struct link *plink, double *lolo, + double *low, double *high, double *hihi) +{ + DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt; + struct buffer { + DBRalDouble + double value; + } buffer; + long options = DBR_AL_DOUBLE; + long number_elements = 0; + long status = dbGet(paddr, DBR_DOUBLE, &buffer, &options, &number_elements, + 0); + + if (status) + return status; + + *lolo = buffer.lower_alarm_limit; + *low = buffer.lower_warning_limit; + *high = buffer.upper_warning_limit; + *hihi = buffer.upper_alarm_limit; + return 0; +} + +static long dbDbGetPrecision(const struct link *plink, short *precision) +{ + DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt; + struct buffer { + DBRprecision + double value; + } buffer; + long options = DBR_PRECISION; + long number_elements = 0; + long status = dbGet(paddr, DBR_DOUBLE, &buffer, &options, &number_elements, + 0); + + if (status) + return status; + + *precision = (short) buffer.precision.dp; + return 0; +} + +static long dbDbGetUnits(const struct link *plink, char *units, int unitsSize) +{ + DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt; + struct buffer { + DBRunits + double value; + } buffer; + long options = DBR_UNITS; + long number_elements = 0; + long status = dbGet(paddr, DBR_DOUBLE, &buffer, &options, &number_elements, + 0); + + if (status) + return status; + + strncpy(units, buffer.units, unitsSize); + return 0; +} + +static long dbDbGetAlarm(const struct link *plink, epicsEnum16 *status, + epicsEnum16 *severity) +{ + DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt; + + if (status) + *status = paddr->precord->stat; + if (severity) + *severity = paddr->precord->sevr; + return 0; +} + +static long dbDbGetTimeStamp(const struct link *plink, epicsTimeStamp *pstamp) +{ + DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt; + + *pstamp = paddr->precord->time; + return 0; +} + +static long dbDbPutValue(struct link *plink, short dbrType, + const void *pbuffer, long nRequest) +{ + struct pv_link *ppv_link = &plink->value.pv_link; + struct dbCommon *psrce = plink->precord; + DBADDR *paddr = (DBADDR *) ppv_link->pvt; + dbCommon *pdest = paddr->precord; + long status = dbPut(paddr, dbrType, pbuffer, nRequest); + + recGblInheritSevr(ppv_link->pvlMask & pvlOptMsMode, pdest, psrce->nsta, + psrce->nsev); + if (status) + return status; + + if (paddr->pfield == (void *) &pdest->proc || + (ppv_link->pvlMask & pvlOptPP && pdest->scan == 0)) { + /* if dbPutField caused asyn record to process */ + /* ask for reprocessing*/ + if (pdest->putf) { + pdest->rpro = TRUE; + } else { /* process dest record with source's PACT true */ + unsigned char pact; + + if (psrce && psrce->ppn) + dbNotifyAdd(psrce, pdest); + pact = psrce->pact; + psrce->pact = TRUE; + status = dbProcess(pdest); + psrce->pact = pact; + } + } + return status; +} + +static void dbDbScanFwdLink(struct link *plink) +{ + dbCommon *precord = plink->precord; + dbAddr *paddr = (dbAddr *) plink->value.pv_link.pvt; + + dbScanPassive(precord, paddr->precord); +} + +static lset dbDb_lset = { + dbDbRemoveLink, + dbDbIsConnected, + dbDbGetDBFtype, dbDbGetElements, + dbDbGetValue, + dbDbGetControlLimits, dbDbGetGraphicLimits, dbDbGetAlarmLimits, + dbDbGetPrecision, dbDbGetUnits, + dbDbGetAlarm, dbDbGetTimeStamp, + dbDbPutValue, + dbDbScanFwdLink +}; + diff --git a/src/ioc/db/dbDbLink.h b/src/ioc/db/dbDbLink.h new file mode 100644 index 000000000..c36772004 --- /dev/null +++ b/src/ioc/db/dbDbLink.h @@ -0,0 +1,35 @@ +/*************************************************************************\ +* Copyright (c) 2016 UChicago Argonne LLC, as Operator of Argonne +* National Laboratory. +* Copyright (c) 2002 The Regents of the University of California, as +* Operator of Los Alamos National Laboratory. +* EPICS BASE is distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. +\*************************************************************************/ +/* dbDbLink.h + * + * Created on: April 3rd, 2016 + * Author: Andrew Johnson + */ + +#ifndef INC_dbDbLink_H +#define INC_dbDbLink_H + +#include "shareLib.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct link; +struct dbLocker; + +epicsShareFunc long dbDbInitLink(struct link *plink, short dbfType); +epicsShareFunc void dbDbAddLink(struct dbLocker *locker, struct link *plink, + short dbfType, DBADDR *ptarget); + +#ifdef __cplusplus +} +#endif + +#endif /* INC_dbDbLink_H */ diff --git a/src/ioc/db/dbLink.c b/src/ioc/db/dbLink.c index a224eac0f..5faa437bb 100644 --- a/src/ioc/db/dbLink.c +++ b/src/ioc/db/dbLink.c @@ -39,6 +39,7 @@ #include "dbCommon.h" #include "dbConvertFast.h" #include "dbConvert.h" +#include "dbDbLink.h" #include "dbEvent.h" #include "db_field_log.h" #include "dbFldTypes.h" @@ -56,25 +57,6 @@ #include "recSup.h" #include "special.h" -static void inherit_severity(const struct pv_link *ppv_link, dbCommon *pdest, - epicsEnum16 stat, epicsEnum16 sevr) -{ - switch (ppv_link->pvlMask & pvlOptMsMode) { - case pvlOptNMS: - break; - case pvlOptMSI: - if (sevr < INVALID_ALARM) - break; - /* Fall through */ - case pvlOptMS: - recGblSetSevr(pdest, LINK_ALARM, sevr); - break; - case pvlOptMSS: - recGblSetSevr(pdest, stat, sevr); - break; - } -} - /* How to identify links in error messages */ static const char * link_field_name(const struct link *plink) { @@ -150,298 +132,6 @@ static lset dbConst_lset = { NULL }; -/***************************** Database Links *****************************/ - -/* Forward definition */ -static lset dbDb_lset; - -static long dbDbInitLink(struct link *plink, short dbfType) -{ - DBADDR dbaddr; - long status; - DBADDR *pdbAddr; - - status = dbNameToAddr(plink->value.pv_link.pvname, &dbaddr); - if (status) - return status; - - plink->lset = &dbDb_lset; - plink->type = DB_LINK; - pdbAddr = dbCalloc(1, sizeof(struct dbAddr)); - *pdbAddr = dbaddr; /* structure copy */ - plink->value.pv_link.pvt = pdbAddr; - ellAdd(&dbaddr.precord->bklnk, &plink->value.pv_link.backlinknode); - /* merging into the same lockset is deferred to the caller. - * cf. initPVLinks() - */ - dbLockSetMerge(NULL, plink->precord, dbaddr.precord); - assert(plink->precord->lset->plockSet == dbaddr.precord->lset->plockSet); - return 0; -} - -static void dbDbAddLink(dbLocker *locker, struct link *plink, short dbfType, DBADDR *ptarget) -{ - plink->lset = &dbDb_lset; - plink->type = DB_LINK; - plink->value.pv_link.pvt = ptarget; - ellAdd(&ptarget->precord->bklnk, &plink->value.pv_link.backlinknode); - - /* target record is already locked in dbPutFieldLink() */ - dbLockSetMerge(locker, plink->precord, ptarget->precord); -} - -static void dbDbRemoveLink(dbLocker *locker, struct link *plink) -{ - DBADDR *pdbAddr = (DBADDR *) plink->value.pv_link.pvt; - plink->value.pv_link.pvt = 0; - plink->value.pv_link.getCvt = 0; - plink->value.pv_link.pvlMask = 0; - plink->value.pv_link.lastGetdbrType = 0; - plink->type = PV_LINK; - plink->lset = NULL; - ellDelete(&pdbAddr->precord->bklnk, &plink->value.pv_link.backlinknode); - dbLockSetSplit(locker, plink->precord, pdbAddr->precord); - free(pdbAddr); -} - -static int dbDbIsConnected(const struct link *plink) -{ - return TRUE; -} - -static int dbDbGetDBFtype(const struct link *plink) -{ - DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt; - - return paddr->field_type; -} - -static long dbDbGetElements(const struct link *plink, long *nelements) -{ - DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt; - - *nelements = paddr->no_elements; - return 0; -} - -static long dbDbGetValue(struct link *plink, short dbrType, void *pbuffer, - epicsEnum16 *pstat, epicsEnum16 *psevr, long *pnRequest) -{ - struct pv_link *ppv_link = &plink->value.pv_link; - DBADDR *paddr = ppv_link->pvt; - dbCommon *precord = plink->precord; - long status; - - /* scan passive records if link is process passive */ - if (ppv_link->pvlMask & pvlOptPP) { - unsigned char pact = precord->pact; - - precord->pact = TRUE; - status = dbScanPassive(precord, paddr->precord); - precord->pact = pact; - if (status) - return status; - } - *pstat = paddr->precord->stat; - *psevr = paddr->precord->sevr; - - if (ppv_link->getCvt && ppv_link->lastGetdbrType == dbrType) { - status = ppv_link->getCvt(paddr->pfield, pbuffer, paddr); - } else { - unsigned short dbfType = paddr->field_type; - - if (dbrType < 0 || dbrType > DBR_ENUM || dbfType > DBF_DEVICE) - return S_db_badDbrtype; - - if (paddr->no_elements == 1 && (!pnRequest || *pnRequest == 1) - && paddr->special != SPC_ATTRIBUTE) { - ppv_link->getCvt = dbFastGetConvertRoutine[dbfType][dbrType]; - status = ppv_link->getCvt(paddr->pfield, pbuffer, paddr); - } else { - ppv_link->getCvt = NULL; - status = dbGet(paddr, dbrType, pbuffer, NULL, pnRequest, NULL); - } - ppv_link->lastGetdbrType = dbrType; - } - return status; -} - -static long dbDbGetControlLimits(const struct link *plink, double *low, - double *high) -{ - DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt; - struct buffer { - DBRctrlDouble - double value; - } buffer; - long options = DBR_CTRL_DOUBLE; - long number_elements = 0; - long status = dbGet(paddr, DBR_DOUBLE, &buffer, &options, &number_elements, - NULL); - - if (status) - return status; - - *low = buffer.lower_ctrl_limit; - *high = buffer.upper_ctrl_limit; - return 0; -} - -static long dbDbGetGraphicLimits(const struct link *plink, double *low, - double *high) -{ - DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt; - struct buffer { - DBRgrDouble - double value; - } buffer; - long options = DBR_GR_DOUBLE; - long number_elements = 0; - long status = dbGet(paddr, DBR_DOUBLE, &buffer, &options, &number_elements, - NULL); - - if (status) - return status; - - *low = buffer.lower_disp_limit; - *high = buffer.upper_disp_limit; - return 0; -} - -static long dbDbGetAlarmLimits(const struct link *plink, double *lolo, - double *low, double *high, double *hihi) -{ - DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt; - struct buffer { - DBRalDouble - double value; - } buffer; - long options = DBR_AL_DOUBLE; - long number_elements = 0; - long status = dbGet(paddr, DBR_DOUBLE, &buffer, &options, &number_elements, - 0); - - if (status) - return status; - - *lolo = buffer.lower_alarm_limit; - *low = buffer.lower_warning_limit; - *high = buffer.upper_warning_limit; - *hihi = buffer.upper_alarm_limit; - return 0; -} - -static long dbDbGetPrecision(const struct link *plink, short *precision) -{ - DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt; - struct buffer { - DBRprecision - double value; - } buffer; - long options = DBR_PRECISION; - long number_elements = 0; - long status = dbGet(paddr, DBR_DOUBLE, &buffer, &options, &number_elements, - 0); - - if (status) - return status; - - *precision = (short) buffer.precision.dp; - return 0; -} - -static long dbDbGetUnits(const struct link *plink, char *units, int unitsSize) -{ - DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt; - struct buffer { - DBRunits - double value; - } buffer; - long options = DBR_UNITS; - long number_elements = 0; - long status = dbGet(paddr, DBR_DOUBLE, &buffer, &options, &number_elements, - 0); - - if (status) - return status; - - strncpy(units, buffer.units, unitsSize); - return 0; -} - -static long dbDbGetAlarm(const struct link *plink, epicsEnum16 *status, - epicsEnum16 *severity) -{ - DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt; - - if (status) - *status = paddr->precord->stat; - if (severity) - *severity = paddr->precord->sevr; - return 0; -} - -static long dbDbGetTimeStamp(const struct link *plink, epicsTimeStamp *pstamp) -{ - DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt; - - *pstamp = paddr->precord->time; - return 0; -} - -static long dbDbPutValue(struct link *plink, short dbrType, - const void *pbuffer, long nRequest) -{ - struct pv_link *ppv_link = &plink->value.pv_link; - struct dbCommon *psrce = plink->precord; - DBADDR *paddr = (DBADDR *) ppv_link->pvt; - dbCommon *pdest = paddr->precord; - long status = dbPut(paddr, dbrType, pbuffer, nRequest); - - inherit_severity(ppv_link, pdest, psrce->nsta, psrce->nsev); - if (status) - return status; - - if (paddr->pfield == (void *) &pdest->proc || - (ppv_link->pvlMask & pvlOptPP && pdest->scan == 0)) { - /* if dbPutField caused asyn record to process */ - /* ask for reprocessing*/ - if (pdest->putf) { - pdest->rpro = TRUE; - } else { /* process dest record with source's PACT true */ - unsigned char pact; - - if (psrce && psrce->ppn) - dbNotifyAdd(psrce, pdest); - pact = psrce->pact; - psrce->pact = TRUE; - status = dbProcess(pdest); - psrce->pact = pact; - } - } - return status; -} - -static void dbDbScanFwdLink(struct link *plink) -{ - dbCommon *precord = plink->precord; - dbAddr *paddr = (dbAddr *) plink->value.pv_link.pvt; - - dbScanPassive(precord, paddr->precord); -} - -static lset dbDb_lset = { - dbDbRemoveLink, - dbDbIsConnected, - dbDbGetDBFtype, dbDbGetElements, - dbDbGetValue, - dbDbGetControlLimits, dbDbGetGraphicLimits, dbDbGetAlarmLimits, - dbDbGetPrecision, dbDbGetUnits, - dbDbGetAlarm, dbDbGetTimeStamp, - dbDbPutValue, - dbDbScanFwdLink -}; - /***************************** Generic Link API *****************************/ void dbInitLink(struct link *plink, short dbfType) @@ -587,7 +277,8 @@ long dbGetLink(struct link *plink, short dbrType, void *pbuffer, if (status) { recGblSetSevr(precord, LINK_ALARM, INVALID_ALARM); } else { - inherit_severity(&plink->value.pv_link, precord, stat, sevr); + recGblInheritSevr(plink->value.pv_link.pvlMask & pvlOptMsMode, precord, + stat, sevr); } return status; } diff --git a/src/ioc/db/recGbl.c b/src/ioc/db/recGbl.c index 7b7affd97..7ed1293f9 100644 --- a/src/ioc/db/recGbl.c +++ b/src/ioc/db/recGbl.c @@ -17,6 +17,7 @@ #include #include +#include "alarm.h" #include "dbDefs.h" #include "epicsMath.h" #include "epicsPrint.h" @@ -214,7 +215,27 @@ int recGblSetSevr(void *precord, epicsEnum16 new_stat, epicsEnum16 new_sevr) } return FALSE; } - + +void recGblInheritSevr(int msMode, void *precord, epicsEnum16 stat, + epicsEnum16 sevr) +{ + switch (msMode) { + case pvlOptNMS: + break; + case pvlOptMSI: + if (sevr < INVALID_ALARM) + break; + /* Fall through */ + case pvlOptMS: + recGblSetSevr(precord, LINK_ALARM, sevr); + break; + case pvlOptMSS: + recGblSetSevr(precord, stat, sevr); + break; + } +} + + void recGblFwdLink(void *precord) { dbCommon *pdbc = precord; diff --git a/src/ioc/db/recGbl.h b/src/ioc/db/recGbl.h index e81749a54..8eb589450 100644 --- a/src/ioc/db/recGbl.h +++ b/src/ioc/db/recGbl.h @@ -59,6 +59,8 @@ epicsShareFunc int recGblInitConstantLink(struct link *plink, epicsShareFunc unsigned short recGblResetAlarms(void *precord); epicsShareFunc int recGblSetSevr(void *precord, epicsEnum16 new_stat, epicsEnum16 new_sevr); +epicsShareFunc void recGblInheritSevr(int msMode, void *precord, epicsEnum16 stat, + epicsEnum16 sevr); epicsShareFunc void recGblFwdLink(void *precord); epicsShareFunc void recGblGetTimeStamp(void *precord); epicsShareFunc void recGblTSELwasModified(struct link *plink);