/* share/src/dev @(#)devSysmonInt.c 1.8 12/13/93 */ /***************************************************************** * * Author : Michael Hoffberg * Date: 12-93 * ***************************************************************** * COPYRIGHT NOTIFICATION ***************************************************************** * THE FOLLOWING IS A NOTICE OF COPYRIGHT, AVAILABILITY OF THE CODE, * AND DISCLAIMER WHICH MUST BE INCLUDED IN THE PROLOGUE OF THE CODE * AND IN ALL SOURCE LISTINGS OF THE CODE. * (C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO * Argonne National Laboratory (ANL), with facilities in the States of * Illinois and Idaho, is owned by the United States Government, and * operated by the University of Chicago under provision of a contract * with the Department of Energy. * Portions of this material resulted from work developed under a U.S. * Government contract and are subject to the following license: For * a period of five years from March 30, 1993, the Government is * granted for itself and others acting on its behalf a paid-up, * nonexclusive, irrevocable worldwide license in this computer * software to reproduce, prepare derivative works, and perform * publicly and display publicly. With the approval of DOE, this * period may be renewed for two additional five year periods. * Following the expiration of this period or periods, the Government * is granted for itself and others acting on its behalf, a paid-up, * nonexclusive, irrevocable worldwide license in this computer * software to reproduce, prepare derivative works, distribute copies * to the public, perform publicly and display publicly, and to permit * others to do so. ***************************************************************** * DISCLAIMER ***************************************************************** * NEITHER THE UNITED STATES GOVERNMENT NOR ANY AGENCY THEREOF, NOR * THE UNIVERSITY OF CHICAGO, NOR ANY OF THEIR EMPLOYEES OR OFFICERS, * MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY LEGAL * LIABILITY OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR * USEFULNESS OF ANY INFORMATION, APPARATUS, PRODUCT, OR PROCESS * DISCLOSED, OR REPRESENTS THAT ITS USE WOULD NOT INFRINGE PRIVATELY * OWNED RIGHTS. ***************************************************************** * LICENSING INQUIRIES MAY BE DIRECTED TO THE INDUSTRIAL TECHNOLOGY * DEVELOPMENT CENTER AT ARGONNE NATIONAL LABORATORY (708-252-2000). ***************************************************************** * Modification Log: * ----------------- * mgh 1/31/94 Started to add interrupt * ... * ... * * $Log$ * Revision 1.6 1995/01/06 16:55:04 winans * enabled irq services and rearranged the parm names and meanings. * * Revision 1.5 1994/12/07 15:11:13 winans * Fixed array index for temerature reading. * * Revision 1.4 1994/11/30 15:10:23 winans * Added IRQ mode stuff * * Revision 1.3 1994/11/17 21:11:58 winans * Major restructuring of init code. * * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define NUM_LINKS 1 /* max number of allowed sysmon cards */ #define STATIC int SysmonConfig(); STATIC long SysmonInit(); STATIC long SysmonReport(); STATIC long SysmonInitAiRec(), SysmonReadAi(); STATIC long SysmonInitBoRec(), SysmonInitBiRec(); STATIC long SysmonInitMbboRec(), SysmonInitMbbiRec(); STATIC long SysmonWriteBo(), SysmonReadBi(); STATIC long SysmonWriteMbbo(), SysmonReadMbbi(); static long SysmonGetIointInfoBi(); STATIC void SysmonIsr(); int devSysmonDebug = 0; /***** devSysmonDebug *****/ /** devSysmonDebug == 0 --- no debugging messages **/ /** devSysmonDebug >= 5 --- hardware initialization information **/ /** devSysmonDebug >= 10 -- record initialization information **/ /** devSysmonDebug >= 15 -- write commands **/ /** devSysmonDebug >= 20 -- read commands **/ typedef struct ParmTableStruct { char *parm_name; } ParmTableStruct; #define SYSMON_PARM_STATUS 0 #define SYSMON_PARM_DI 1 #define SYSMON_PARM_TEMP 2 #define SYSMON_PARM_BOOTWATCHDOG 3 #define SYSMON_PARM_DO 4 #define SYSMON_PARM_LED 5 #define SYSMON_PARM_RXWATCHDOG 6 #define SYSMON_PARM_RXTEMP 7 #define SYSMON_PARM_RXSTAT 8 #define SYSMON_PARM_RXRUN 9 #define SYSMON_PARM_RX12V 10 #define SYSMON_PARM_RX5V 11 #define SYSMON_PARM_RXFAIL 12 #define SYSMON_PARM_TXWATCHDOG 13 #define SYSMON_PARM_TXTEMP 14 #define SYSMON_PARM_TXSTAT 15 #define SYSMON_PARM_TXRUN 16 #define SYSMON_PARM_TX12V 17 #define SYSMON_PARM_TX5V 18 #define SYSMON_PARM_TXFAIL 19 static ParmTableStruct ParmTable[]= { {"StatusLink"}, {"Di"}, {"Temperature"}, {"BootWatchdog"}, {"Do"}, {"Led"}, {"RxWatchdog"}, {"RxTemp"}, {"RxStat"}, {"RxRun"}, {"Rx12v"}, {"Rx5v"}, {"RxFail"}, {"TxWatchdog"}, {"TxTemp"}, {"TxStat"}, {"TxRun"}, {"Tx12v"}, {"Tx5v"}, {"TxFail"} }; #define PARM_TABLE_SIZE (sizeof(ParmTable)/sizeof(ParmTable[0])) /*** SysMonStatusLink Rx, Tx ***/ /*** SysmonDio output, input *** 0-7=out, 8-15=in***/ /*** SysmonIntMask interrupt mask ***/ /*** SysmonTemperature temperature monitor ***/ /*** SysmonWatchdog watchdog & 4 status LEDs ***/ /*** SysmonVXIVector VXI interrupt vector ***/ /*** SysmonIntVector interrupt vector ***/ /*** SysmonIRQ1 IRQ 1 vector ***/ /*** SysmonIRQ2 IRQ 1 vector ***/ /*** SysmonIRQ3 IRQ 1 vector ***/ /*** SysmonIRQ4 IRQ 1 vector ***/ /*** SysmonIRQ5 IRQ 1 vector ***/ /*** SysmonIRQ6 IRQ 1 vector ***/ /*** SysmonIRQ7 IRQ 1 vector ***/ typedef struct SysmonStruct { char Pad[36]; /*** nF0 - nF17 36 bytes ***/ unsigned short SysmonStatusLink; /*** nF18 ***/ unsigned short SysmonDio; /*** nF19 ***/ unsigned short SysmonIntMask; /*** nF20 ***/ unsigned short SysmonTemperature; /*** nF21 ***/ unsigned short SysmonWatchdog; /*** nF22 ***/ unsigned short SysmonVXIVector; /*** nF23 ***/ unsigned short SysmonIntVector; /*** nF24 ***/ unsigned short SysmonIRQ1; /*** nF25 ***/ unsigned short SysmonIRQ2; /*** nF26 ***/ unsigned short SysmonIRQ3; /*** nF27 ***/ unsigned short SysmonIRQ4; /*** nF28 ***/ unsigned short SysmonIRQ5; /*** nF29 ***/ unsigned short SysmonIRQ6; /*** nF30 ***/ unsigned short SysmonIRQ7; /*** nF31 ***/ }SysmonStruct; /***************************************************************************** * * Per-record private structure hooked onto dpvt. * *****************************************************************************/ typedef struct PvtStruct { int index; /* Parameter/operation type */ volatile unsigned short *pReg; /* Pointer to actual register */ unsigned short mask; /* value mask derived from signal number */ } PvtStruct; /***************************************************************************** * * Per-card global variables. * *****************************************************************************/ struct ioCard { /* structure maintained for each card */ int CardValid; /* card exists */ unsigned long SysmonBaseA16; /* A16 card address */ volatile SysmonStruct *SysmonBase; /* Physical card address */ FAST_LOCK lock; /* semaphore */ IOSCANPVT ioscanpvt; /* Token for I/O intr scanned records */ int VMEintVector; /* IRQ vector used by sysmon */ int VMEintLevel; /* IRQ level */ int VXIintVector; /* Generated when C008 is written to (VXI silliness) */ int IrqInfo[2]; }; #define INITLEDS 0x01 static struct ioCard cards[NUM_LINKS]; /* card information structure */ struct dset_sysmon { long number; DEVSUPFUN report; /* used by dbior */ DEVSUPFUN init; /* called 1 time before & after all records */ DEVSUPFUN init_record; /* called 1 time for each record */ DEVSUPFUN get_ioint_info; /* used for COS processing */ DEVSUPFUN read_write; /* output command goes here */ }; typedef struct dset_sysmon DSET_SYSMON; DSET_SYSMON devAiSysmon={ 5, NULL, SysmonInit, SysmonInitAiRec, NULL, SysmonReadAi }; DSET_SYSMON devBoSysmon={ 5, NULL, SysmonInit, SysmonInitBoRec, NULL, SysmonWriteBo }; /* Create the dset for devBiSysmon */ DSET_SYSMON devBiSysmon={ 5, SysmonReport, SysmonInit, SysmonInitBiRec, SysmonGetIointInfoBi, SysmonReadBi }; /* Create the dset for devMbboSysmon */ DSET_SYSMON devMbboSysmon={ 5, NULL, SysmonInit, SysmonInitMbboRec, NULL, SysmonWriteMbbo }; /* Create the dset for devMbbiSysmon */ DSET_SYSMON devMbbiSysmon={ 5, NULL, SysmonInit, SysmonInitMbbiRec, NULL, SysmonReadMbbi }; STATIC long SysmonReport(void) { int j; for (j=0; j= NUM_LINKS)) { printf("ERROR: Invalid card number specified %d\n", Card); return(0); } cards[Card].CardValid = 0; cards[Card].VMEintVector = 0; cards[Card].VMEintLevel = 0; cards[Card].VXIintVector = 0; cards[Card].SysmonBaseA16 = 0; cards[Card].IrqInfo[0] = 0; cards[Card].IrqInfo[1] = 0; if ((VMEintVector < 64) || (VMEintVector > 255)) { printf("devSysmon: ERROR VME IRQ vector out of range\n"); return(0); } if (devSysmonDebug >= 5) printf("devSysmon: SysmonInit VME int vector = 0x%2.2X\n", VMEintVector); if ((VMEintLevel < 0) || (VMEintLevel > 7)) { printf("devSysmon: ERROR VME IRQ level out of range\n"); return(0); } if (devSysmonDebug >= 5) printf("devSysmon: SysmonInit VME int level = %d\n", VMEintLevel); if ((VXIintVector < 64) || (VXIintVector > 255)) { printf("devSysmon: ERROR VXI IRQ vector out of range\n"); return(0); } if (devSysmonDebug >= 5) printf("devSysmon: SysmonInit VXI int vector = 0x%2.2X\n", VXIintVector); if ((SysmonBaseA16 > 0xffff) || (SysmonBaseA16 & 0x003f)) { printf("devSysmon: ERROR Invalid address specified 0x4.4X\n", SysmonBaseA16); return(0); } if (devSysmonDebug >= 5) printf("devSysmon: SysmonInit VME (VXI) base address = %p\n", SysmonBaseA16); cards[Card].VMEintVector = VMEintVector; cards[Card].VMEintLevel = VMEintLevel; cards[Card].VXIintVector = VXIintVector; cards[Card].SysmonBaseA16 = SysmonBaseA16; cards[Card].IrqInfo[0] = VMEintVector; /*0x71*/ cards[Card].IrqInfo[1] = VXIintVector; /*0x72*/ cards[Card].CardValid = 1; return(0); } /************************************************** **************************************************/ STATIC void SysmonIsr(int Card) { if (devSysmonDebug >= 10) logMsg("In SysmonIsr\n"); scanIoRequest(cards[Card].ioscanpvt); cards[Card].SysmonBase->SysmonIntMask |= 0xff00; } /************************************************************************** * * Initialization of SYSMON Binary I/O Card * ***************************************************************************/ STATIC long SysmonInit(int flag) { int Card; unsigned short probeVal; static int init_flag = 0; if (init_flag != 0) return(OK); init_flag = 1; /* We end up here 1 time before all records are initialized */ for (Card=0; Card < NUM_LINKS; Card++) { if (cards[Card].CardValid != 0) { if (devSysmonDebug >= 5) logMsg("devSysmon: init link %d\n", Card); if (sysBusToLocalAdrs(VME_AM_SUP_SHORT_IO, (char *)cards[Card].SysmonBaseA16, (char **)&(cards[Card].SysmonBase)) == ERROR) { if (devSysmonDebug >= 5) logMsg("devSysmon: can not find short address space\n"); return(ERROR); /* BUG */ } probeVal = INITLEDS; if (devSysmonDebug >= 5) logMsg("devSysmon: init SysmonWatchdog 0x%X\n", (char *)&cards[Card].SysmonBase->SysmonWatchdog); if (vxMemProbe((char *)&cards[Card].SysmonBase->SysmonWatchdog, WRITE, sizeof(cards[Card].SysmonBase->SysmonWatchdog), (char *)&probeVal) != OK) { cards[Card].CardValid = 0; /* No card found */ if (devSysmonDebug >= 5) logMsg("devSysmon: init vxMemProbe FAILED\n"); } else { cards[Card].SysmonBase->SysmonIntMask = 0; FASTLOCKINIT(&(cards[Card].lock)); /* FASTUNLOCK(&(cards[Card].lock)); /* Init the board lock */ if (devSysmonDebug >= 5) logMsg("devSysmon: init address\n"); scanIoInit(&cards[Card].ioscanpvt); /* interrupt initialized */ if (devSysmonDebug >= 5) logMsg("devSysmon: init ScanIoInit \n"); if (devSysmonDebug >= 5) logMsg("devSysmon: init address of System Monitor %8.8x \n", cards[Card].SysmonBase); cards[Card].SysmonBase->SysmonIntVector = cards[Card].VMEintVector; if (devSysmonDebug >= 5) logMsg("devSysmon: init Interrupt vector loaded \n"); if(intConnect(INUM_TO_IVEC(cards[Card].VMEintVector),(FUNCPTR)SysmonIsr, Card)!=OK) { logMsg("devSysmon (init) intConnect failed \n"); return(ERROR); if (devSysmonDebug >= 5) logMsg("devSysmon: init intConnect\n"); } if (devSysmonDebug >= 5) logMsg("devSysmon: init vxMemProbe OK\n"); } sysIntEnable(cards[Card].VMEintLevel); } } return(OK); } /*************************************************************************** generic init record *************************************************************************/ static long generic_init_record(struct dbCommon *pr, DBLINK *link) { struct vmeio *pvmeio = (struct vmeio*)&(link->value); int j; PvtStruct *pvt; if (link->type != VME_IO) { recGblRecordError(S_dev_badBus,(void *)pr, "devSysmon (init_record) Illegal Bus Type"); return(S_dev_badBus); } /* make sure that signal is valid */ if ((pvmeio->signal > 7) || (pvmeio->signal < 0)) { pr->pact = 1; /* make sure we don't process this thing */ if (devSysmonDebug >= 10) logMsg("devSysmon: Illegal SIGNAL field ->%s<- \n", pr->name); recGblRecordError(S_dev_badSignal,(void *)pr, "devSysmon (init_record) Illegal SIGNAL field"); return(S_dev_badSignal); } /* makes sure that card is valid */ if ((pvmeio->card > NUM_LINKS) || (pvmeio->card < 0) || (!cards[pvmeio->card].CardValid)) { pr->pact = 1; /* make sure we don't process this thing */ if (devSysmonDebug >= 10) { logMsg("devSysmon: Illegal CARD field ->%s, %d<- \n", pr->name, pvmeio->card); if(!cards[pvmeio->card].CardValid) logMsg("devSysmon: Illegal CARD field card NOT VALID \n\n"); } recGblRecordError(S_dev_badCard,(void *)pr, "devSysmon (init_record) Illegal CARD field"); return(S_dev_badCard); } /* verifies that parm field is valid */ for (j = 0; (j < PARM_TABLE_SIZE) && strcmp(ParmTable[j].parm_name, pvmeio->parm); j++ ); if (j >= PARM_TABLE_SIZE) { if (devSysmonDebug >= 10) logMsg("devSysmon: Illegal parm field ->%s<- \n", pr->name); recGblRecordError(S_dev_badSignal,(void *)pr, "devSysmon (init_record) Illegal parm field"); return(S_dev_badSignal); } if (devSysmonDebug >= 10) logMsg("devSysmon: %s of record type %d - %s\n", pr->name, j, ParmTable[j].parm_name); pvt = (PvtStruct *) malloc(sizeof(PvtStruct)); pvt->index = j; pr->dpvt = pvt; return(0); } /*************************************************************************** * ***************************************************************************/ STATIC long SysmonInitAiRec(struct aiRecord *pRecord) { struct vmeio* pvmeio = (struct vmeio*)&(pRecord->inp.value); int status = 0; PvtStruct *pvt; status = generic_init_record((struct dbCommon *)pRecord, &pRecord->inp); if(status) { pRecord->dpvt = NULL; return(status); } pvt = (PvtStruct *)(pRecord->dpvt); if (pvt->index != SYSMON_PARM_TEMP) { pRecord->dpvt = NULL; if (devSysmonDebug >= 10) logMsg("devSysmon: Illegal parm field ->%s<- \n", pvmeio->parm); recGblRecordError(S_dev_badSignal,(void *)pRecord, "devSysmon (init_record) Illegal parm field"); return(S_dev_badSignal); } return(0); } /*************************************************************************** * ***************************************************************************/ STATIC long SysmonReadAi(struct aiRecord *pRecord) { struct vmeio *pvmeio = (struct vmeio*)&(pRecord->inp.value); unsigned short regVal; PvtStruct *pvt = (PvtStruct *)pRecord->dpvt; if (pvt == NULL) return(0); FASTLOCK(&cards[pvmeio->card].lock); regVal = cards[pvmeio->card].SysmonBase->SysmonTemperature & 0xff; FASTUNLOCK(&cards[pvmeio->card].lock); if (devSysmonDebug) printf("Sysmon AI temperature raw value %d\n", regVal); switch(regVal) { case 0xfe: pRecord->val = 20; break; case 0xfc: pRecord->val = 25; break; case 0xf8: pRecord->val = 30; break; case 0xf0: pRecord->val = 35; break; case 0xe0: pRecord->val = 40; break; case 0xc0: pRecord->val = 45; break; case 0x80: pRecord->val = 50; break; case 0x00: pRecord->val = 55; break; default: devGpibLib_setPvSevr(pRecord,MAJOR_ALARM,INVALID_ALARM); return(0); } pRecord->udf = FALSE; return(2); /* Don't do a conversion */ } /************************************************************************** * * BO Initialization (Called one time for each BO SYSMON card record) * **************************************************************************/ STATIC long SysmonInitBoRec(struct boRecord *pbo) { struct vmeio* pvmeio = (struct vmeio*)&(pbo->out.value); int status = 0; PvtStruct *pvt; status = generic_init_record((struct dbCommon *)pbo, &pbo->out); if(status) { pbo->dpvt = NULL; return(status); } pvt = (PvtStruct *)pbo->dpvt; switch (pvt->index) { case SYSMON_PARM_DO: pvt->mask = 1<signal; pvt->pReg = &(cards[pvmeio->card].SysmonBase->SysmonDio); break; case SYSMON_PARM_LED: if (pvmeio->signal > 3) { recGblRecordError(S_dev_badSignal,(void *)pbo, "devSysmon (init_record) Illegal signal value (0-3 for LED)"); return(S_dev_badSignal); } pvt->mask = 1<signal; pvt->pReg = &(cards[pvmeio->card].SysmonBase->SysmonWatchdog); break; case SYSMON_PARM_BOOTWATCHDOG: pvt->mask = 1<<7; pvt->pReg = &(cards[pvmeio->card].SysmonBase->SysmonWatchdog); break; #if 0 case SYSMON_PARM_DI: pvt->mask = 1<< (pvmeio->signal + 8); break; #endif default: pbo->dpvt = NULL; if (devSysmonDebug >= 10) logMsg("devSysmon: Illegal parm field ->%s<- \n", pvmeio->parm); recGblRecordError(S_dev_badSignal,(void *)pbo, "devSysmon (init_record) Illegal parm field"); return(S_dev_badSignal); } return (0); } /************************************************************************** * * BI Initialization (Called one time for each BI SYSMON card record) * **************************************************************************/ STATIC long SysmonInitBiRec(struct biRecord *pbi) { struct vmeio* pvmeio = (struct vmeio*)&(pbi->inp.value); PvtStruct *pvt; int status = 0; int signal; status = generic_init_record((struct dbCommon *)pbi, &pbi->inp); if(status) { pbi->dpvt = NULL; return(status); } pvt = (PvtStruct *)pbi->dpvt; switch (pvt->index) { case SYSMON_PARM_DO: pvt->mask = 1 << pvmeio->signal; pvt->pReg = &(cards[pvmeio->card].SysmonBase->SysmonDio); break; case SYSMON_PARM_DI: pvt->mask = 1<< (pvmeio->signal + 8); pvt->pReg = &(cards[pvmeio->card].SysmonBase->SysmonDio); break; case SYSMON_PARM_LED: if (pvmeio->signal > 3) { recGblRecordError(S_dev_badSignal,(void *)pbi, "devSysmon (init_record) Illegal signal value (0-3 for LED)"); return(S_dev_badSignal); } pvt->mask = 1<signal; pvt->pReg = &(cards[pvmeio->card].SysmonBase->SysmonWatchdog); break; case SYSMON_PARM_BOOTWATCHDOG: pvt->mask = 1<<7; pvt->pReg = &(cards[pvmeio->card].SysmonBase->SysmonWatchdog); break; case SYSMON_PARM_RXWATCHDOG: pvt->mask = 1<<0; pvt->pReg = &(cards[pvmeio->card].SysmonBase->SysmonStatusLink); break; case SYSMON_PARM_RXTEMP: pvt->mask = 1<<1; pvt->pReg = &(cards[pvmeio->card].SysmonBase->SysmonStatusLink); break; case SYSMON_PARM_RXSTAT: pvt->mask = 1<<2; pvt->pReg = &(cards[pvmeio->card].SysmonBase->SysmonStatusLink); break; case SYSMON_PARM_RXRUN: pvt->mask = 1<<3; pvt->pReg = &(cards[pvmeio->card].SysmonBase->SysmonStatusLink); break; case SYSMON_PARM_RX12V: pvt->mask = 1<<4; pvt->pReg = &(cards[pvmeio->card].SysmonBase->SysmonStatusLink); break; case SYSMON_PARM_RX5V: pvt->mask = 1<<5; pvt->pReg = &(cards[pvmeio->card].SysmonBase->SysmonStatusLink); break; case SYSMON_PARM_RXFAIL: pvt->mask = 1<<6; pvt->pReg = &(cards[pvmeio->card].SysmonBase->SysmonStatusLink); break; case SYSMON_PARM_TXWATCHDOG: pvt->mask = 1<<8; pvt->pReg = &(cards[pvmeio->card].SysmonBase->SysmonStatusLink); break; case SYSMON_PARM_TXTEMP: pvt->mask = 1<<9; pvt->pReg = &(cards[pvmeio->card].SysmonBase->SysmonStatusLink); break; case SYSMON_PARM_TXSTAT: pvt->mask = 1<<10; pvt->pReg = &(cards[pvmeio->card].SysmonBase->SysmonStatusLink); break; case SYSMON_PARM_TXRUN: pvt->mask = 1<<11; pvt->pReg = &(cards[pvmeio->card].SysmonBase->SysmonStatusLink); break; case SYSMON_PARM_TX12V: pvt->mask = 1<<12; pvt->pReg = &(cards[pvmeio->card].SysmonBase->SysmonStatusLink); break; case SYSMON_PARM_TX5V: pvt->mask = 1<<13; pvt->pReg = &(cards[pvmeio->card].SysmonBase->SysmonStatusLink); break; case SYSMON_PARM_TXFAIL: pvt->mask = 1<<14; pvt->pReg = &(cards[pvmeio->card].SysmonBase->SysmonStatusLink); break; default: pbi->dpvt = NULL; if (devSysmonDebug >= 10) logMsg("devSysmon: Illegal parm field ->%s<- \n", pvmeio->parm); recGblRecordError(S_dev_badSignal,(void *)pbi, "devSysmon (init_record) Illegal parm field"); return(S_dev_badSignal); } return (0); } #if 1 /* This looks completely insane JRW */ /************************************************************************** * * MBBO Initialization (Called one time for each MBBO SYSMON card record) * **************************************************************************/ STATIC long SysmonInitMbboRec(struct mbboRecord *pmbbo) { struct vmeio* pvmeio = (struct vmeio*)&(pmbbo->out.value); PvtStruct *pvt; int status = 0; status = generic_init_record((struct dbCommon *)pmbbo, &pmbbo->out); if(status) { pmbbo->dpvt = NULL; return(status); } pvt = (PvtStruct *)pmbbo->dpvt; if (pvt->index != SYSMON_PARM_TEMP) { pmbbo->dpvt = NULL; if (devSysmonDebug >= 10) logMsg("devSysmon: Illegal parm field ->%s<- \n", pvmeio->parm); recGblRecordError(S_dev_badSignal,(void *)pmbbo, "devSysmon (init_record) Illegal parm field"); return(S_dev_badSignal); } pmbbo->shft = pvmeio->signal; pmbbo->mask <<= pmbbo->shft; return(0); } #endif /************************************************************************** * * MBBI Initialization (Called one time for each MBBI SYSMON card record) * **************************************************************************/ STATIC long SysmonInitMbbiRec(struct mbbiRecord *pmbbi) { struct vmeio* pvmeio = (struct vmeio*)&(pmbbi->inp.value); PvtStruct *pvt; int status = 0; status = generic_init_record((struct dbCommon *)pmbbi, &pmbbi->inp); if(status) { pmbbi->dpvt = NULL; return(status); } pvt = (PvtStruct *)pmbbi->dpvt; if (pvt->index != SYSMON_PARM_TEMP) { pmbbi->dpvt = NULL; if (devSysmonDebug >= 10) logMsg("devSysmon: Illegal parm field ->%s<- \n", pvmeio->parm); recGblRecordError(S_dev_badSignal,(void *)pmbbi, "devSysmon (init_record) Illegal parm field"); return(S_dev_badSignal); } /* load temperature values up */ if (!strcmp(ParmTable[SYSMON_PARM_TEMP].parm_name, pvmeio->parm)) { if (devSysmonDebug >= 10) logMsg("devSysmon: mbbi record is Temperature\n"); pmbbi->nobt = 0x08; /* make sure 8 bits wide */ /* load up proper mask values */ pmbbi->zrvl = 0xff; pmbbi->onvl = 0xfe; pmbbi->twvl = 0xfc; pmbbi->thvl = 0xf8; pmbbi->frvl = 0xf0; pmbbi->fvvl = 0xe0; pmbbi->sxvl = 0xc0; pmbbi->svvl = 0x80; pmbbi->eivl = 0x10; pmbbi->nivl = 0x00; pmbbi->tevl = 0x55; pmbbi->elvl = 0x55; pmbbi->tvvl = 0x55; pmbbi->ttvl = 0x55; pmbbi->ftvl = 0x55; pmbbi->ffvl = 0x55; /* load up proper string values, if you don't like it, change the strings somewhere else */ strcpy(pmbbi->zrst,"Cal Error"); strcpy(pmbbi->onst,"20"); strcpy(pmbbi->twst,"25"); strcpy(pmbbi->thst,"30"); strcpy(pmbbi->frst,"35"); strcpy(pmbbi->fvst,"40"); strcpy(pmbbi->sxst,"45"); strcpy(pmbbi->svst,"50"); strcpy(pmbbi->eist,"Danger 55"); strcpy(pmbbi->nist,"Danger!"); strcpy(pmbbi->test,"Danger!!"); strcpy(pmbbi->elst,"Danger!!!"); strcpy(pmbbi->tvst,"Danger!!!!"); strcpy(pmbbi->ttst,"Danger!!!!!"); strcpy(pmbbi->ftst,"Danger!!!!!!"); strcpy(pmbbi->ffst,"AAAARRRGHH!!!"); } pmbbi->shft = pvmeio->signal; pmbbi->mask <<= pmbbi->shft; return(0); } /************************************************************************** * * Perform a write operation from a BO record * **************************************************************************/ STATIC long SysmonWriteBo(struct boRecord *pbo) { struct vmeio *pvmeio = (struct vmeio*)&(pbo->out.value); PvtStruct *pvt = (PvtStruct *)pbo->dpvt; if (pvt == NULL) return(0); FASTLOCK(&cards[pvmeio->card].lock); #if 0 switch (pvt->index) { case SYSMON_PARM_DO: case SYSMON_PARM_DI: if (pbo->val) cards[pvmeio->card].SysmonBase->SysmonDio |= pvt->mask; else cards[pvmeio->card].SysmonBase->SysmonDio &= ~pvt->mask; break; case SYSMON_PARM_WATCHDOG: if (pbo->val) cards[pvmeio->card].SysmonBase->SysmonWatchdog |= pvt->mask; else cards[pvmeio->card].SysmonBase->SysmonWatchdog &= ~pvt->mask; break; } #else if (pbo->val) *(pvt->pReg) |= pvt->mask; else *(pvt->pReg) &= ~pvt->mask; #endif FASTUNLOCK(&cards[pvmeio->card].lock); return(0); } /************************************************************************** * * Perform a read operation from a BI record * **************************************************************************/ STATIC long SysmonReadBi(struct biRecord *pbi) { struct vmeio *pvmeio = (struct vmeio*)&(pbi->inp.value); unsigned short regVal = 0; PvtStruct *pvt = (PvtStruct *)pbi->dpvt; if (pvt == NULL) return(0); regVal = *(pvt->pReg); if (devSysmonDebug) logMsg("read 0x%4.4X, masking with 0x%4.4X\n", regVal, pvt->mask); regVal &= pvt->mask; if(regVal) pbi->rval = 1; else pbi->rval = 0; /* Damn board's BI logic is bass-ackwards */ if (pvt->index == SYSMON_PARM_DI) pbi->rval = pbi->rval?0:1; return(0); } #if 1 /* This looks completely insane JRW */ /************************************************************************** * * Perform a write operation from a MBBO record * **************************************************************************/ STATIC long SysmonWriteMbbo(struct mbboRecord *pmbbo) { struct vmeio *pvmeio = (struct vmeio*)&(pmbbo->out.value); unsigned short regVal; PvtStruct *pvt = (PvtStruct *)pmbbo->dpvt; if (pvt == NULL) return(0); FASTLOCK(&cards[pvmeio->card].lock); /* BUG -- this looks broken, what about the shift? -- JRW */ regVal = cards[pvmeio->card].SysmonBase->SysmonTemperature; regVal = (regVal & ~pmbbo->mask) | (pmbbo->rval & pmbbo->mask); cards[pvmeio->card].SysmonBase->SysmonTemperature = regVal; FASTUNLOCK(&cards[pvmeio->card].lock); return(0); } #endif /************************************************************************** * * Perform a read operation from a MBBI record * **************************************************************************/ STATIC long SysmonReadMbbi(struct mbbiRecord *pmbbi) { struct vmeio *pvmeio = (struct vmeio*)&(pmbbi->inp.value); unsigned short regVal; PvtStruct *pvt = (PvtStruct *)pmbbi->dpvt; if (pvt == NULL) return(0); FASTLOCK(&cards[pvmeio->card].lock); regVal = cards[pvmeio->card].SysmonBase->SysmonTemperature; FASTUNLOCK(&cards[pvmeio->card].lock); /* BUG -- this looks broken, what about the shift? -- JRW */ pmbbi->rval=regVal & pmbbi->mask; pmbbi->udf = 0; return(0); } /***************************************************** record support interrupt routine * * cmd = 0 if being added * cmd = 1 if taken off the I/O Event scanned list * ****************************************************/ static long SysmonGetIointInfoBi( int cmd, struct biRecord *pr, IOSCANPVT *ppvt) { struct vmeio *pvmeio = (struct vmeio *)(&pr->inp.value); int intmask; if (pr->dpvt == NULL) return(0); if(pvmeio->card > NUM_LINKS) { recGblRecordError(S_dev_badCard,(void *)pr, "devSysmon (get_int_info) exceeded maximum supported cards"); return(S_dev_badCard); } *ppvt = cards[pvmeio->card].ioscanpvt; if (cmd == 0) { intmask = (((PvtStruct *)(pr->dpvt))->mask)>>8; if (devSysmonDebug) logMsg("SysmonGetIointInfoBi mask is %2.2X\n", intmask); cards[pvmeio->card].SysmonBase->SysmonIntMask |= intmask; } return(0); }