diff --git a/src/drv/drvEpvxi.c b/src/drv/drvEpvxi.c index fb6277236..103089ad2 100644 --- a/src/drv/drvEpvxi.c +++ b/src/drv/drvEpvxi.c @@ -1,5 +1,7 @@ /* - * share/src/drv $Id$ + * drvEpvxi.c + * + * share/src/drv/$Id$ * Routines for the VXI device support and resource management. * * @@ -58,6 +60,12 @@ * has already been registered * .19 joh 09-03-92 Use the correct routine in NIVXI * for CPU030 trigger routing + * .20 joh 09-30-92 split epvxiOpen() into epvxiOpen() and + * epvxiDeviceVerify() + * .21 joh 10-30-92 NI CPU030 trigger routing was failing + * due to no entry for the 030 in the resman + * tables - it cant see itself in A16. + * A work around was installed. * * To do * ----- @@ -2463,38 +2471,74 @@ unsigned long driverConfigSize, void (*pio_report_func)() ) { - VXICSR *pcsr; VXIDI *pvxidi; void *pconfig; -#ifdef V5_vxWorks - UINT16 device_status; -#else - unsigned short device_status; -#endif - int status; + int status; - if(la > NELEMENTS(epvxiLibDeviceList)){ - return VXI_BAD_LA; - } if(vxiDriverID == UNINITIALIZED_DRIVER_ID){ return VXI_NOT_OWNER; } + status = epvxiDeviceVerify(la); + if(status<0){ + return status; + } + pvxidi = epvxiLibDeviceList[la]; - if(pvxidi){ - if(pvxidi->driverID == vxiDriverID){ - return VXI_DEVICE_OPEN; - } - else if(pvxidi->driverID != NO_DRIVER_ATTACHED_ID){ - return VXI_NOT_OWNER; - } + if(pvxidi->driverID == vxiDriverID){ + return VXI_DEVICE_OPEN; + } + else if(pvxidi->driverID != NO_DRIVER_ATTACHED_ID){ + return VXI_NOT_OWNER; + } + + if(driverConfigSize){ + pconfig = (void *)calloc(1,driverConfigSize); + if(!pconfig){ + return VXI_NO_MEMORY; + } + pvxidi->pDriverConfig = pconfig; } else{ + pvxidi->pDriverConfig = NULL; + } + + pvxidi->pio_report_func = pio_report_func; + + pvxidi->driverID = vxiDriverID; + + return VXI_SUCCESS; +} + + +/* + * + * epvxiDeviceVerify() + * + * + */ +int epvxiDeviceVerify(unsigned la) +{ + int status; + VXICSR *pcsr; + VXIDI *pvxidi; +# ifdef V5_vxWorks + UINT16 device_status; +# else + unsigned short device_status; +# endif + + if(la > NELEMENTS(epvxiLibDeviceList)){ + return VXI_BAD_LA; + } + + pvxidi = epvxiLibDeviceList[la]; + if(!pvxidi){ return VXI_UKN_DEVICE; } - + /* * verify that the device exists * and check the self test in memory @@ -2513,21 +2557,6 @@ void (*pio_report_func)() return VXI_SELF_TEST_FAILED; } - if(driverConfigSize){ - pconfig = (void *)calloc(1,driverConfigSize); - if(!pconfig){ - return VXI_NO_MEMORY; - } - pvxidi->pDriverConfig = pconfig; - } - else{ - pvxidi->pDriverConfig = NULL; - } - - pvxidi->pio_report_func = pio_report_func; - - pvxidi->driverID = vxiDriverID; - return VXI_SUCCESS; } @@ -2668,22 +2697,6 @@ unsigned io_map /* bits 0-5 correspond to trig 0-5 */ int status; int i; - plac = epvxiLibDeviceList[la]; - if(plac){ - if(!plac->st_passed){ - return VXI_SELF_TEST_FAILED; - } - } - else{ - return VXI_NO_DEVICE; - } - - mask = (1<st_passed){ + return VXI_SELF_TEST_FAILED; + } + } + else{ + return VXI_NO_DEVICE; + } + + mask = (1<st_passed){ - return VXI_SELF_TEST_FAILED; - } - } - else{ - return VXI_NO_DEVICE; - } - - mask = (1<st_passed){ + return VXI_SELF_TEST_FAILED; + } + } + else{ + return VXI_NO_DEVICE; + } + + mask = (1<pMsgConfig)) + /* * local functions */ @@ -132,15 +135,15 @@ int vxiMsgOpen( unsigned la ); -int vxiMsgSignalSetup( +void vxiMsgSignalSetup( void ); -int vxiCPU030MsgSignalSetup( +void vxiCPU030MsgSignalSetup( void ); -int vxiHP1404MsgSignalSetup( +void vxiHP1404MsgSignalSetup( void ); @@ -291,13 +294,11 @@ unsigned long cmd logMsg("cmd to be sent %4x (la=%d)\n", cmd, la); # endif - pvximdi = epvxiPConfig(la, vxiMsgLibDriverId, VXIMDI *); - if(!pvximdi){ + while(!(pvximdi = epvxiPMsgConfig(la))){ status = vxiMsgOpen(la); if(status != VXI_SUCCESS){ return status; } - pvximdi = (VXIMDI *) epvxiLibDeviceList[la]->pDriverConfig; } pcsr = VXIBASE(la); @@ -306,7 +307,7 @@ unsigned long cmd /* * RULE C.3.3 - * A commander shall not send any command requiring a servant to + * A commander shall not send any command requiring a servant to * place data in in its data registers until the commander has read * (from the data registers) all data generated by previous commands * (and the read ready bit is set to zero). @@ -361,13 +362,11 @@ unsigned long *presp VXIMDI *pvximdi; int status; - pvximdi = epvxiPConfig(la, vxiMsgLibDriverId, VXIMDI *); - if(!pvximdi){ + while(!(pvximdi = epvxiPMsgConfig(la))){ status = vxiMsgOpen(la); if(status != VXI_SUCCESS){ return status; } - pvximdi = (VXIMDI *) epvxiLibDeviceList[la]->pDriverConfig; } pcsr = VXIBASE(la); @@ -443,13 +442,11 @@ unsigned long option VXIMDI *pvximdi; int status; - pvximdi = epvxiPConfig(la, vxiMsgLibDriverId, VXIMDI *); - if(!pvximdi){ + while(!(pvximdi = epvxiPMsgConfig(la))){ status = vxiMsgOpen(la); if(status != VXI_SUCCESS){ return status; } - pvximdi = (VXIMDI *) epvxiLibDeviceList[la]->pDriverConfig; } /* @@ -488,6 +485,8 @@ unsigned long option #ifdef FASTHANDSHAKE +@@@@ needs to tell them if their buffer is full + and the EOM bit wasnt se @@@@ /* * epvxiReadFastHandshake() * @@ -516,13 +515,11 @@ int epvxiReadFastHandshake( int status; int i; - pvximdi = epvxiPConfig(la, vxiMsgLibDriverId, VXIMDI *); - if(!pvximdi){ + while(!(pvximdi = epvxiPMsgConfig(la))){ status = vxiMsgOpen(la); if(status != VXI_SUCCESS){ return status; } - pvximdi = (VXIMDI *) epvxiLibDeviceList[la]->pDriverConfig; } pcsr = VXIBASE(la); @@ -629,23 +626,31 @@ int epvxiReadSlowHandshake( struct vxi_csr *pcsr; short resp; int status; + int function_status; int i; - pvximdi = epvxiPConfig(la, vxiMsgLibDriverId, VXIMDI *); - if(!pvximdi){ + while(!(pvximdi = epvxiPMsgConfig(la))){ status = vxiMsgOpen(la); if(status != VXI_SUCCESS){ return status; } - pvximdi = (VXIMDI *) epvxiLibDeviceList[la]->pDriverConfig; } pcsr = VXIBASE(la); - FASTLOCK(&pvximdi->lck); /* * always leave room to write a NULL termination */ + if(count<1){ + return VXI_BUFFER_FULL; + } + + FASTLOCK(&pvximdi->lck); + + /* + * always leave room to write a NULL termination + */ + function_status = VXI_BUFFER_FULL; for(i=0; i<(count-1); i++){ /* @@ -660,11 +665,13 @@ int epvxiReadSlowHandshake( VXIWRITEREADYMASK|VXIDORMASK, FALSE); if(status<0){ - *pread_count = i; if(pcsr->dir.r.dd.msg.response&VXIREADREADYMASK){ - status = VXI_UNREAD_DATA; + function_status = VXI_UNREAD_DATA; } - goto exit; + else{ + function_status = status; + } + break; } pcsr->dir.w.dd.msg.dlow = MBC_BR; @@ -678,8 +685,8 @@ int epvxiReadSlowHandshake( VXIREADREADYMASK, FALSE); if(status<0){ - *pread_count = i; - goto exit; + function_status = status; + break; } resp = pcsr->dir.r.dd.msg.dlow; @@ -687,29 +694,29 @@ int epvxiReadSlowHandshake( *pbuf = resp; pbuf++; if(resp & MBC_END){ - int cnt; - cnt = i+1; - *pread_count= cnt; + /* + * so the read count will be correct below + */ + i++; + function_status = VXI_SUCCESS; break; } } - - status = VXI_SUCCESS; - -exit: FASTUNLOCK(&pvximdi->lck); - if(status == VXI_PROTOCOL_ERROR){ - return fetch_protocol_error(la); - } + *pread_count = i; /* * append the NULL */ *pbuf = NULL; - return status; + if(function_status == VXI_PROTOCOL_ERROR){ + return fetch_protocol_error(la); + } + + return function_status; } @@ -734,13 +741,11 @@ unsigned long option int status; char *pstr; - pvximdi = epvxiPConfig(la, vxiMsgLibDriverId, VXIMDI *); - if(!pvximdi){ + while(!(pvximdi = epvxiPMsgConfig(la))){ status = vxiMsgOpen(la); if(status != VXI_SUCCESS){ return status; } - pvximdi = (VXIMDI *) epvxiLibDeviceList[la]->pDriverConfig; } pcsr = VXIBASE(la); @@ -813,13 +818,11 @@ unsigned long timeout VXIMDI *pvximdi; int status; - pvximdi = epvxiPConfig(la, vxiMsgLibDriverId, VXIMDI *); - if(!pvximdi){ + while(!(pvximdi = epvxiPMsgConfig(la))){ status = vxiMsgOpen(la); if(status != VXI_SUCCESS){ return status; } - pvximdi = (VXIMDI *) epvxiLibDeviceList[la]->pDriverConfig; } /* @@ -850,16 +853,13 @@ int enable; VXIMDI *pvximdi; int status; - pvximdi = epvxiPConfig(la, vxiMsgLibDriverId, VXIMDI *); - if(!pvximdi){ + while(!(pvximdi = epvxiPMsgConfig(la))){ status = vxiMsgOpen(la); if(status != VXI_SUCCESS){ return status; } - pvximdi = (VXIMDI *) epvxiLibDeviceList[la]->pDriverConfig; } - pvximdi->trace = enable?TRUE:FALSE; return VXI_SUCCESS; @@ -880,7 +880,7 @@ unsigned la int status; VXIMDI *pvximdi; - pvximdi = epvxiPConfig(la, vxiMsgLibDriverId, VXIMDI *); + pvximdi = epvxiPMsgConfig(la); if(!pvximdi){ return VXI_NOT_OPEN; } @@ -890,11 +890,6 @@ unsigned la logMsg( "%s: vxiMsgClose(): bad sem id\n", __FILE__); } - status = epvxiClose(la, vxiMsgLibDriverId); - if(status<0){ - logMsg( "%s: vxiMsgClose(): close failed\n", - __FILE__); - } FASTLOCKFREE(&pvximdi->lck); return VXI_SUCCESS; } @@ -912,6 +907,7 @@ int vxiMsgOpen( ) { int status; + VXIDI *pvxidi; VXIMDI *pvximdi; unsigned long resp; unsigned long read_proto_resp; @@ -920,42 +916,40 @@ int vxiMsgOpen( int signalSync = FALSE; int intSync = FALSE; - if(vxiMsgLibDriverId==UNINITIALIZED_DRIVER_ID){ - vxiMsgLibDriverId = epvxiUniqueDriverID(); + + /* + * return quickly if we have been here before + */ + pvxidi = epvxiLibDeviceList[la]; + if(pvxidi->pMsgConfig){ + return VXI_SUCCESS; } - - status = epvxiOpen( - la, - vxiMsgLibDriverId, - (unsigned long)sizeof(*pvximdi), - NULL); + + status = epvxiDeviceVerify(la); if(status<0){ return status; } - pvximdi = epvxiPConfig(la, vxiMsgLibDriverId, VXIMDI *); - if(!pvximdi){ - abort(0); - } - - if(!vxiMsgSignalInit){ - vxiMsgSignalSetup(); - } - pcsr = VXIBASE(la); - if(VXICLASS(pcsr) != VXI_MESSAGE_DEVICE){ - epvxiClose(la, vxiMsgLibDriverId); return VXI_NOT_MSG_DEVICE; } + pvximdi = (VXIMDI *) calloc(1, sizeof(*pvximdi)); + if(!pvximdi){ + return VXI_NO_MEMORY; + } + + pvxidi->pMsgConfig = (void *) pvximdi; + + vxiMsgSignalSetup(); + # ifdef V5_vxWorks pvximdi->syncSem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY); # else pvximdi->syncSem = semCreate(); # endif if(!pvximdi->syncSem){ - epvxiClose(la, vxiMsgLibDriverId); return VXI_NO_MEMORY; } @@ -1007,6 +1001,7 @@ logMsg("mb device has response gen\n"); /* * try to setup interrupt synchronization first + * (this works even if we dont have a signal register) */ if(VXIMBINT(pcsr)){ cmd = MBC_ASYNC_MODE_CONTROL | @@ -1021,7 +1016,7 @@ logMsg("mb device has response gen\n"); } /* - * hopefully signal hardware is available if we get to here + * hopefully a signal register is available if we get to here */ if(VXIVMEBM(pcsr) && !intSync && msgCommanderLA>=0){ cmd = MBC_ASYNC_MODE_CONTROL | @@ -1083,25 +1078,29 @@ logMsg("synchronized msg based device is ready!\n"); * */ LOCAL -int vxiMsgSignalSetup( +void vxiMsgSignalSetup( void ) { - int status; + int status; + static char vxiMsgSignalInit; + + if(vxiMsgSignalInit){ + return; + } vxiMsgSignalInit = TRUE; - status = vxiHP1404MsgSignalSetup(); - if(status>=0){ - return OK; + vxiHP1404MsgSignalSetup(); + + if(msgCommanderLA<0){ + vxiCPU030MsgSignalSetup(); } - status = vxiCPU030MsgSignalSetup(); - if(status>=0){ - return OK; + if(msgCommanderLA<0){ + logMsg( "%s: Unable to locate determine the commander's LA\n", + __FILE__); } - - return ERROR; } @@ -1112,33 +1111,29 @@ int vxiMsgSignalSetup( * */ LOCAL -int vxiCPU030MsgSignalSetup( +void vxiCPU030MsgSignalSetup( void ) { int niMsgLA; int status; - if(pnivxi_func[(unsigned)e_GetMyLA]){ - niMsgLA = (*pnivxi_func[(unsigned)e_GetMyLA])(); - } - else{ - return ERROR; - } - if( !pnivxi_func[(unsigned)e_EnableSignalInt] || !pnivxi_func[(unsigned)e_SetSignalHandler] || - !pnivxi_func[(unsigned)e_RouteSignal]){ - return ERROR; + !pnivxi_func[(unsigned)e_RouteSignal] || + !pnivxi_func[(unsigned)e_GetMyLA]){ + return; } + niMsgLA = (*pnivxi_func[(unsigned)e_GetMyLA])(); + # define ANY_DEVICE (-1) # define MSG_RESP_ENABLE (0x3f) status = (*pnivxi_func[(unsigned)e_RouteSignal])( ANY_DEVICE, - MSG_RESP_ENABLE); + ~0); /* enable every thing */ if(status<0){ - return ERROR; + return; } # define UKN_DEVICE (-2) @@ -1146,18 +1141,17 @@ int vxiCPU030MsgSignalSetup( UKN_DEVICE, signalHandler); if(status<0){ - return ERROR; + return; } status = (*pnivxi_func[(unsigned)e_EnableSignalInt])(); if(status){ - return ERROR; + return; } -logMsg("vxiCPU030MsgSignalSetup() done\n"); msgCommanderLA = niMsgLA; - return OK; + return; } @@ -1168,7 +1162,7 @@ logMsg("vxiCPU030MsgSignalSetup() done\n"); * */ LOCAL -int vxiHP1404MsgSignalSetup( +void vxiHP1404MsgSignalSetup( void ) { @@ -1182,27 +1176,27 @@ int vxiHP1404MsgSignalSetup( dsp.model = VXI_HP_MODEL_E1404_MSG; status = epvxiLookupLA(&dsp, set_la, (void *)&hpMsgLA); if(status<0){ - return ERROR; + return; } if(hpMsgLA<0){ - return ERROR; + return; } dsp.flags = VXI_DSP_make | VXI_DSP_slot; dsp.make = VXI_MAKE_HP; dsp.slot = epvxiLibDeviceList[hpMsgLA]->slot; status = epvxiLookupLA(&dsp, set_la, (void *)&hpRegLA); if(status<0){ - return ERROR; + return; } if(hpRegLA<0){ - return ERROR; + return; } msgCommanderLA = hpMsgLA; hpE1404SignalConnect(hpRegLA, signalHandler); - return OK; + return; } @@ -1315,13 +1309,11 @@ int vxiMsgSync( int pollcnt = 100; - pvximdi = epvxiPConfig(la, vxiMsgLibDriverId, VXIMDI *); - if(!pvximdi){ + while(!(pvximdi = epvxiPMsgConfig(la))){ status = vxiMsgOpen(la); if(status != VXI_SUCCESS){ return status; } - pvximdi = (VXIMDI *) epvxiLibDeviceList[la]->pDriverConfig; } pcsr = VXIBASE(la); @@ -1407,7 +1399,7 @@ int fetch_protocol_error( unsigned short resp; int status; - pvximdi = epvxiPConfig(la, vxiMsgLibDriverId, VXIMDI *); + pvximdi = epvxiPMsgConfig(la); if(!pvximdi){ return VXI_ERR_FETCH_FAIL; } @@ -1477,7 +1469,7 @@ void vxiMsgInt( /* * verify that this device is open for business */ - pvximdi = epvxiPConfig(la, vxiMsgLibDriverId, VXIMDI *); + pvximdi = epvxiPMsgConfig(la); if(pvximdi){ /* @@ -1492,7 +1484,7 @@ void vxiMsgInt( } } else{ - logMsg( "%s: vxiMsgInt(): msg int to ukn dev\n", + logMsg( "%s: vxiMsgInt(): msg int to ukn or closed dev\n", __FILE__); } }