diff --git a/src/AsynDriverInterface.cc b/src/AsynDriverInterface.cc index 0268ece7..5d5490eb 100644 --- a/src/AsynDriverInterface.cc +++ b/src/AsynDriverInterface.cc @@ -171,6 +171,7 @@ class AsynDriverInterface : StreamBusInterface epicsTimerQueueActive* timerQueue; epicsTimer* timer; #endif + asynStatus previousAsynStatus; AsynDriverInterface(Client* client); ~AsynDriverInterface(); @@ -229,6 +230,7 @@ class AsynDriverInterface : StreamBusInterface timer->cancel(); #endif } + void reportAsynStatus(asynStatus status, const char *name); // asynUser callback functions friend void handleRequest(asynUser*); @@ -262,6 +264,7 @@ AsynDriverInterface(Client* client) : StreamBusInterface(client) eventMask = 0; receivedEvent = 0; peeksize = 1; + previousAsynStatus = asynSuccess; debug ("AsynDriverInterface(%s) createAsynUser\n", client->name()); pasynUser = pasynManager->createAsynUser(handleRequest, handleTimeout); @@ -490,6 +493,19 @@ connectToBus(const char* portname, int addr) return true; } +void AsynDriverInterface:: +reportAsynStatus(asynStatus status, const char *name) +{ + if (previousAsynStatus != status) { + previousAsynStatus = status; + if (status == asynSuccess) { + error("%s %s: status returned to normal\n", clientName(), name); + } else { + error("%s %s: %s\n", clientName(), name, pasynUser->errorMessage); + } + } +} + // interface function: we want exclusive access to the device // lockTimeout_ms=0 means "block here" (used in @init) bool AsynDriverInterface:: @@ -503,16 +519,11 @@ lockRequest(unsigned long lockTimeout_ms) ioAction = Lock; status = pasynManager->queueRequest(pasynUser, priority(), lockTimeout); - if (status != asynSuccess) - { - error("%s lockRequest: pasynManager->queueRequest() failed: %s\n", - clientName(), pasynUser->errorMessage); - return false; - } + reportAsynStatus(status, "lockRequest: pasynManager->queueRequest"); + return (status == asynSuccess); // continues with: // handleRequest() -> lockHandler() -> lockCallback() // or handleTimeout() -> lockCallback(StreamIoTimeout) - return true; } bool AsynDriverInterface:: @@ -562,22 +573,12 @@ connectToAsynPort() clientName(), connected ? "already" : "not yet"); if (!connected) { - printf ("%s: AsynDriverInterface::connectToAsynPort: " - "pasynCommon->connect(%p, %p)\n", - clientName(), pvtCommon, pasynUser); status = pasynCommon->connect(pvtCommon, pasynUser); - printf ("%s: AsynDriverInterface::connectToAsynPort: " - "pasynCommon->connect(%p, %p) = %s\n", - clientName(), pvtCommon, pasynUser, asynStatusStr[status]); debug("AsynDriverInterface::connectToAsynPort(%s): " "status=%s\n", clientName(), asynStatusStr[status]); - if (status != asynSuccess) - { - error("%s connectToAsynPort: pasynCommon->connect() failed: %s\n", - clientName(), pasynUser->errorMessage); - return false; - } + reportAsynStatus(status, "connectToAsynPort: pasynCommon->connect"); + return (status == asynSuccess); } // We probably should set REN=1 prior to sending but this // seems to hang up the device every other time. @@ -644,16 +645,11 @@ writeRequest(const void* output, size_t size, ioAction = Write; status = pasynManager->queueRequest(pasynUser, priority(), writeTimeout); - if (status != asynSuccess) - { - error("%s writeRequest: pasynManager->queueRequest() failed: %s\n", - clientName(), pasynUser->errorMessage); - return false; - } + reportAsynStatus(status, "writeRequest: pasynManager->queueRequest"); + return (status == asynSuccess); // continues with: // handleRequest() -> writeHandler() -> lockCallback() // or handleTimeout() -> writeCallback(StreamIoTimeout) - return true; } // now, we can write (called by asynManager) @@ -667,25 +663,28 @@ writeHandler() pasynUser->timeout = 0; if (!pasynGpib) - // discard any early input, but forward it to potential async records - // thus do not use pasynOctet->flush() - // unfortunately we cannot do this with GPIB because addressing a device as talker - // when it has nothing to say is an error. Also timeout=0 does not help here (would need - // a change in asynGPIB), thus use flush() for GPIB. - do { - char buffer [256]; - size_t received = 0; - int eomReason = 0; - debug("AsynDriverInterface::writeHandler(%s): reading old input\n", - clientName()); - status = pasynOctet->read(pvtOctet, pasynUser, - buffer, sizeof(buffer), &received, &eomReason); - if (status == asynError || received == 0) break; + { + // discard any early input, but forward it to potential async records + // thus do not use pasynOctet->flush() + // unfortunately we cannot do this with GPIB because addressing a device as talker + // when it has nothing to say is an error. Also timeout=0 does not help here + // (would need a change in asynGPIB), thus use flush() for GPIB. + do { + char buffer [256]; + size_t received = 0; + int eomReason = 0; + debug("AsynDriverInterface::writeHandler(%s): reading old input\n", + clientName()); + status = pasynOctet->read(pvtOctet, pasynUser, + buffer, sizeof(buffer), &received, &eomReason); + if (status == asynError || received == 0) break; #ifndef NO_TEMPORARY - if (received) debug("AsynDriverInterface::writeHandler(%s): flushing %ld bytes: \"%s\"\n", - clientName(), (long)received, StreamBuffer(buffer, received).expand()()); + if (received) debug("AsynDriverInterface::writeHandler(%s): " + "flushing %ld bytes: \"%s\"\n", + clientName(), (long)received, StreamBuffer(buffer, received).expand()()); #endif - } while (status == asynSuccess); + } while (status == asynSuccess); + } else { debug("AsynDriverInterface::writeHandler(%s): flushing old input\n", @@ -754,11 +753,9 @@ writeHandler() { status = pasynManager->queueRequest(pasynUser, priority(), lockTimeout); + reportAsynStatus(status, "writeHandler: pasynManager->queueRequest"); if (status != asynSuccess) { - error("%s writeHandler: " - "pasynManager->queueRequest() failed: %s\n", - clientName(), pasynUser->errorMessage); writeCallback(StreamIoFault); } // continues with: @@ -838,6 +835,10 @@ readRequest(unsigned long replyTimeout_ms, unsigned long readTimeout_ms, clientName(), priority(), queueTimeout, asynStatusStr[status], async? "true" : "false", status!=asynSuccess ? pasynUser->errorMessage : ""); + if (!async) + { + reportAsynStatus(status, "readRequest: pasynManager->queueRequest"); + } if (status != asynSuccess) { // Not queued for some reason (e.g. disconnected / already queued) @@ -847,8 +848,6 @@ readRequest(unsigned long replyTimeout_ms, unsigned long readTimeout_ms, startTimer(replyTimeout); return true; } - error("%s readRequest: pasynManager->queueRequest() failed: %s\n", - clientName(), pasynUser->errorMessage); return false; } // continues with: @@ -1408,16 +1407,11 @@ connectRequest(unsigned long connecttimeout_ms) clientName()); status = pasynManager->queueRequest(pasynUser, asynQueuePriorityConnect, queueTimeout); - if (status != asynSuccess) - { - error("%s connectRequest: pasynManager->queueRequest() failed: %s\n", - clientName(), pasynUser->errorMessage); - return false; - } + reportAsynStatus(status, "connectRequest: pasynManager->queueRequest"); + return (status == asynSuccess); // continues with: // handleRequest() -> connectHandler() -> connectCallback() // or handleTimeout() -> connectCallback(StreamIoTimeout) - return true; } void AsynDriverInterface:: @@ -1436,15 +1430,10 @@ disconnectRequest() clientName()); status = pasynManager->queueRequest(pasynUser, asynQueuePriorityConnect, 0.0); - if (status != asynSuccess) - { - error("%s disconnectRequest: pasynManager->queueRequest() failed: %s\n", - clientName(), pasynUser->errorMessage); - return false; - } + reportAsynStatus(status, "disconnectRequest: pasynManager->queueRequest"); + return (status == asynSuccess); // continues with: // handleRequest() -> disconnectHandler() - return true; } void AsynDriverInterface::