Esempio n. 1
0
asynStatus sendCmd(asynUser *pasynUser, myData *pPvt, char* cmd )
{
    char buffer[BUFFER_SIZE];
    int nread, nwrite, eomReason;
    asynStatus status;

        buffer[0] = 0;

        status = pasynOctetSyncIO->writeRead( pasynUser,
                                          cmd, strlen(cmd),
                                          buffer, BUFFER_SIZE,
                                          pPvt->readTimeout,
                                          &nwrite, &nread, &eomReason );
        switch (status) {
        case asynTimeout:
            asynPrint(pasynUser, ASYN_TRACE_ERROR,
                      "testPmacAsynIPPort: TIMEOUT\n");
            /* no break - fall throught to asynSuccess */
            
        case asynSuccess:
             asynPrintIO(pasynUser,ASYN_TRACEIO_DEVICE,cmd,strlen(cmd),
                 "testPmacAsynIPPort: %s write %d:\n",pPvt->portName,strlen(cmd));
             asynPrintIO(pasynUser,ASYN_TRACEIO_DEVICE,buffer,nread,
                 "testPmacAsynIPPort: %s read %d:\n",pPvt->portName,nread);
            break;

        default:
            asynPrint(pasynUser, ASYN_TRACE_ERROR,
                      "testPmacAsynIPPort: writeRead error on: %s: write %d: %s, status=%d error=%s\n", 
                      pPvt->portName, strlen(cmd), cmd, status, pasynUser->errorMessage);
            break;
        }
        return status;
}
static int readCvtio(gpibDpvt *pgpibDpvt,int P1, int P2, char **P3)
{
    stringinRecord *precord = (stringinRecord*)pgpibDpvt->precord;
    asynUser *pasynUser = pgpibDpvt->pasynUser;
    gpibCmd *pgpibCmd = gpibCmdGet(pgpibDpvt);
    asynOctet *pasynOctet = pgpibDpvt->pasynOctet;
    void *asynOctetPvt = pgpibDpvt->asynOctetPvt;
    asynStatus status;
    size_t nchars = 0, lenmsg = 0;
    pgpibDpvt->msgInputLen = 0;

    assert(pgpibCmd->cmd);
    lenmsg = strlen(pgpibCmd->cmd);
    status  = pasynOctet->write(asynOctetPvt,pasynUser,
        pgpibCmd->cmd,lenmsg,&nchars);
    if(nchars==lenmsg) {
        asynPrintIO(pasynUser,ASYN_TRACEIO_DEVICE,pgpibCmd->cmd,nchars,
                                            "%s readCvtio\n",precord->name);
    } else {
        asynPrint(pasynUser,ASYN_TRACE_ERROR,
            "%s write status \"%s\" requested %d but sent %d bytes\n",
                precord->name,pasynUser->errorMessage,lenmsg,nchars);
            return -1;
    }
    if(!pgpibDpvt->msg) {
        asynPrint(pasynUser,ASYN_TRACE_ERROR,
            "%s pgpibDpvt->msg is null\n",precord->name);
        nchars = 0; return -1;
    } else {
        status = pasynOctet->read(asynOctetPvt,pasynUser,
            pgpibDpvt->msg,pgpibCmd->msgLen,&nchars,0);
    }
    asynPrint(pasynUser,ASYN_TRACE_FLOW,"%s readCvtio nchars %d\n",
        precord->name,nchars);
    if(nchars > 0) {
        asynPrintIO(pasynUser,ASYN_TRACEIO_DEVICE,pgpibDpvt->msg,nchars,
            "%s readCvtio\n",precord->name);
    } else {
        asynPrint(pasynUser,ASYN_TRACE_ERROR,
            "%s read status \"%s\" nin %d\n",
            precord->name, pasynUser->errorMessage,nchars);
        pgpibDpvt->msgInputLen = 0;
        return -1;
    }
    pgpibDpvt->msgInputLen = nchars;
    if(nchars<pgpibCmd->msgLen) pgpibDpvt->msg[nchars] = 0;
    readString(pgpibDpvt,P1,P2,P3);
    return 0;
}
Esempio n. 3
0
static asynStatus gpibPortGetEos(void *pdrvPvt,asynUser *pasynUser,
    char *eos, int eossize, int *eoslen)
{
    niport *pniport = (niport *)pdrvPvt;
    int        addr = 0;
    asynStatus status;

    status = pasynManager->getAddr(pasynUser,&addr);
    if(status!=asynSuccess) return status;
    if(eossize<1) {
        asynPrint(pasynUser,ASYN_TRACE_ERROR,
            "%s addr %d gpibPortGetEos eossize %d too small\n",
            pniport->portName,addr,eossize);
        *eoslen = 0;
        return asynError;
    }
    if(pniport->eos==-1) {
        *eoslen = 0;
    } else {
        eos[0] = (unsigned int)pniport->eos;
        *eoslen = 1;
    }
    asynPrintIO(pasynUser, ASYN_TRACE_FLOW, eos, *eoslen,
        "%s addr %d gpibPortGetEos eoslen %d\n",pniport->portName,addr,eoslen);
    return asynSuccess;
}
Esempio n. 4
0
static asynStatus gpibPortWrite(void *pdrvPvt,asynUser *pasynUser,
    const char *data,int numchars,int *nbytesTransfered)
{
    niport *pniport = (niport *)pdrvPvt;
    int        actual = 0;
    double     timeout = pasynUser->timeout;
    int        addr = 0;
    asynStatus status;

    status = pasynManager->getAddr(pasynUser,&addr);
    if(status!=asynSuccess) return status;
    asynPrint(pasynUser,ASYN_TRACE_FLOW,"%s addr %d gpibPortWrite nchar %d\n",
        pniport->portName,addr,numchars);
    pniport->errorMessage[0] = 0;
    status = writeGpib(pniport,data,numchars,&actual,addr,timeout);
    if(status!=asynSuccess) {
        epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
            "%s writeGpib failed %s",pniport->portName,pniport->errorMessage);
    } else if(actual!=numchars) {
        epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
            "%s requested %d but sent %d bytes",pniport->portName,numchars,actual);
        status = asynError;
    }
    asynPrintIO(pasynUser,ASYN_TRACEIO_DRIVER,
        data,actual,"%s addr %d gpibPortWrite\n",pniport->portName,addr);
    *nbytesTransfered = actual;
    return status;
}
Esempio n. 5
0
static asynStatus readIt(asynUser *pasynUser,
                   char *buffer, size_t buffer_len, 
                   double timeout,
                   size_t *nbytesTransfered,int *eomReason)
{
    asynStatus status, unlockStatus;
    ioPvt      *pioPvt = (ioPvt *)pasynUser->userPvt;

    pasynUser->timeout = timeout;
    status = pasynManager->queueLockPort(pasynUser);
    if(status!=asynSuccess) {
        return status;
    }
    status = pioPvt->pasynOctet->read(
        pioPvt->octetPvt,pasynUser,buffer,buffer_len,nbytesTransfered,eomReason);
    if(status==asynSuccess) {
         asynPrintIO(pasynUser, ASYN_TRACEIO_DEVICE,
             buffer,*nbytesTransfered,"asynOctetSyncIO read:\n");
    }
    unlockStatus = pasynManager->queueUnlockPort(pasynUser);
    if (unlockStatus != asynSuccess) {
        return unlockStatus;
    }
    return status;
}
Esempio n. 6
0
/*
 * asynOctet methods
 */
static asynStatus
writeIt(void *drvPvt, asynUser *pasynUser, const char *data,
        size_t numchars,size_t *nbytesTransfered)
{
    usbController_t *usb = (usbController_t *)drvPvt;
    double          cmdstr[3];
    unsigned char   cmd[3];

    assert(usb);
    asynPrint(pasynUser, ASYN_TRACE_FLOW,
              "%s write.\n", usb->usbDeviceName);
    asynPrintIO(pasynUser, ASYN_TRACEIO_DRIVER, data, numchars,
                "%s write %d\n", usb->usbDeviceName, numchars);
    if (usb->dev == NULL) {
        epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                      "%s disconnected:", usb->usbDeviceName);
        return asynError;
    }
    if (sscanf(data, "%lf %lf %lf", &cmdstr[0], &cmdstr[1], &cmdstr[2])!=3) return asynError;
    cmd[0] = cmdstr[0];
    cmd[1] = cmdstr[1];
    cmd[2] = cmdstr[2];
    if (numchars!=3) numchars = 3;
    *nbytesTransfered = 0;
    *nbytesTransfered = libusb_control_transfer(usb->handle, 0x40, 6, 0x100, 0,
                                                cmd, (uint16_t)numchars, 0);
    if (*nbytesTransfered>=numchars)
        return asynSuccess;
    else
        return asynError;
    return asynSuccess;
}
static int writeCvtio(gpibDpvt *pgpibDpvt,int P1, int P2, char **P3)
{
    stringoutRecord *precord = (stringoutRecord*)pgpibDpvt->precord;
    asynUser *pasynUser = pgpibDpvt->pasynUser;
    asynOctet *pasynOctet = pgpibDpvt->pasynOctet;
    void *asynOctetPvt = pgpibDpvt->asynOctetPvt;
    asynStatus status;
    size_t nsent = 0, lenmsg = 0;
    pgpibDpvt->msgInputLen = 0;

    lenmsg = writeString(pgpibDpvt,P1,P2,P3);
    if(lenmsg <= 0) return -1;
    status  = pasynOctet->write(asynOctetPvt,pasynUser,
        pgpibDpvt->msg,lenmsg,&nsent);
    if(nsent==lenmsg) {
        asynPrintIO(pasynUser,ASYN_TRACEIO_DEVICE,pgpibDpvt->msg,lenmsg,
                                            "%s writeCvtio\n",precord->name);
    } else {
        asynPrint(pasynUser,ASYN_TRACE_ERROR,
            "%s write status \"%s\" requested %d but sent %d bytes\n",
                precord->name,pasynUser->errorMessage,lenmsg,nsent);
            return -1;
    }
    return 0;
}
Esempio n. 8
0
static asynStatus writeIt(asynUser *pasynUser,const char *message,size_t nbytes)
{
    devPvt     *pdevPvt = (devPvt *)pasynUser->userPvt;
    dbCommon   *precord = pdevPvt->precord;
    asynOctet  *poctet = pdevPvt->poctet;
    void       *octetPvt = pdevPvt->octetPvt;
    asynStatus status;
    size_t     nbytesTransfered;

    status = poctet->write(octetPvt,pasynUser,message,nbytes,&nbytesTransfered);
    if(status!=asynSuccess) {
        asynPrint(pasynUser,ASYN_TRACE_ERROR,
            "%s devTestBlock: writeIt failed %s\n",
            precord->name,pasynUser->errorMessage);
        recGblSetSevr(precord, WRITE_ALARM, INVALID_ALARM);
        return status;
    }
    if(nbytes != nbytesTransfered) {
        asynPrint(pasynUser,ASYN_TRACE_ERROR,
            "%s devTestBlock: writeIt requested %lu but sent %lu bytes\n",
            precord->name,(unsigned long)nbytes,(unsigned long)nbytesTransfered);
        recGblSetSevr(precord, WRITE_ALARM, MINOR_ALARM);
        return asynError;
    }
    asynPrintIO(pasynUser,ASYN_TRACEIO_DEVICE,message,nbytes,
       "%s devTestBlock: writeIt\n",precord->name);
    return status;
}
Esempio n. 9
0
static asynStatus gpibPortAddressedCmd(void *pdrvPvt,asynUser *pasynUser,
    const char *data, int length)
{
    niport *pniport = (niport *)pdrvPvt;
    double     timeout = pasynUser->timeout;
    int        addr = 0;
    int        actual;
    asynStatus status;
    char cmdbuf[2] = {IBUNT,IBUNL};

    status = pasynManager->getAddr(pasynUser,&addr);
    if(status!=asynSuccess) return status;
    asynPrint(pasynUser,ASYN_TRACE_FLOW,
       "%s addr %d gpibPortAddressedCmd nchar %d\n",
        pniport->portName,addr,length);
    pniport->errorMessage[0] = 0;
    status = writeAddr(pniport,0,addr,timeout,transferStateIdle);
    if(status==asynSuccess) {
        status=writeCmd(pniport,data,length,timeout,transferStateIdle);
    }
    if(status!=asynSuccess) {
        epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
            "%s writeGpib failed %s",pniport->portName,pniport->errorMessage);
    }
    actual = length - pniport->bytesRemainingCmd;
    asynPrintIO(pasynUser,ASYN_TRACEIO_DRIVER,
        data,actual,"%s gpibPortAddressedCmd\n",pniport->portName);
    if(status!=asynSuccess) return status;
    writeCmd(pniport,cmdbuf,2,timeout,transferStateIdle);
    return status;
}
Esempio n. 10
0
static asynStatus writeRead(asynUser *pasynUser, 
                        const char *write_buffer, size_t write_buffer_len,
                        char *read_buffer, size_t read_buffer_len,
                        double timeout,
                        size_t *nbytesOut, size_t *nbytesIn,int *eomReason)
{
    asynStatus status, unlockStatus;
    ioPvt      *pioPvt = (ioPvt *)pasynUser->userPvt;

    pasynUser->timeout = timeout;
    status = pasynManager->queueLockPort(pasynUser);
    if(status!=asynSuccess) {
        return status;
    }
    status = pioPvt->pasynOctet->flush(pioPvt->octetPvt,pasynUser);
    if(status!=asynSuccess) {
        goto bad;
    }
    status = pioPvt->pasynOctet->write(
        pioPvt->octetPvt,pasynUser,write_buffer,write_buffer_len,nbytesOut);
    if(status!=asynSuccess) {
        goto bad;
    } else {
         asynPrintIO(pasynUser, ASYN_TRACEIO_DEVICE,
             write_buffer,*nbytesOut,"asynOctetSyncIO wrote:\n");
    }
    status = pioPvt->pasynOctet->read(
        pioPvt->octetPvt,pasynUser,read_buffer,read_buffer_len,nbytesIn,eomReason);
    if(status!=asynSuccess) {
        goto bad;
    } else {
         asynPrintIO(pasynUser, ASYN_TRACEIO_DEVICE,
             read_buffer,*nbytesIn,"asynOctetSyncIO read:\n");
    }
    bad:
    unlockStatus = pasynManager->queueUnlockPort(pasynUser);
    if (unlockStatus != asynSuccess) {
        return unlockStatus;
    }
    return status;
}
Esempio n. 11
0
static asynStatus
readIt(void *ppvt, asynUser *pasynUser,
    char *data, size_t maxchars, size_t *nbytesTransfered, int *eomReason)
{
    interposePvt *pinterposePvt = (interposePvt *)ppvt;
    int eom;
    size_t nRead, nCheck;
    char *iac;
    char *base = data;
    int unstuffed = 0;
    asynStatus status;
    
    status = pinterposePvt->pasynOctetDrv->read(pinterposePvt->drvPvt,
                                    pasynUser, data, maxchars, &nRead, &eom);
    if (status != asynSuccess)
        return status;
    nCheck = nRead;
    while ((iac = memchr(data, C_IAC, nCheck)) != NULL) {
        int c;
        unstuffed = 1;
        eom &= ~ASYN_EOM_CNT;
        if (iac == data + nCheck - 1) {
            c = nextChar(pinterposePvt, pasynUser);
            iac--;
        }
        else {
            c = *(iac + 1) & 0xFF;
            nRead--;
        }
        if (c != C_IAC) {
            epicsSnprintf(pasynUser->errorMessage,
                          pasynUser->errorMessageSize, "Missing IAC");
            return asynError;
        }
        nCheck -= (iac - data) + 2;
        data = iac + 1;
        if (nCheck == 0)
            break;
        memmove(data, data + 1, nCheck);
    }
    if (unstuffed)
        asynPrintIO(pasynUser, ASYN_TRACEIO_FILTER, base, nRead,
                                "nRead %d after IAC unstuffing", (int)nRead);
    if (nRead == maxchars)
        eom |= ASYN_EOM_CNT;
    *nbytesTransfered = nRead;
    if (eomReason) *eomReason = eom;
    return asynSuccess;
}
Esempio n. 12
0
static asynStatus gpibPortUniversalCmd(void *pdrvPvt, asynUser *pasynUser, int cmd)
{
    niport *pniport = (niport *)pdrvPvt;
    double     timeout = pasynUser->timeout;
    asynStatus status;
    char   buffer[1];

    asynPrint(pasynUser,ASYN_TRACE_FLOW,"%s gpibPortUniversalCmd %2.2x\n",
        pniport->portName,cmd);
    pniport->errorMessage[0] = 0;
    buffer[0] = cmd;
    status = writeCmd(pniport,buffer,1,timeout,transferStateIdle);
    if(status!=asynSuccess) {
        epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
            "%s writeGpib failed %s",pniport->portName,pniport->errorMessage);
    }
    asynPrintIO(pasynUser,ASYN_TRACEIO_DRIVER,
        buffer,1,"%s gpibPortUniversalCmd\n",pniport->portName);
    return status;
}
Esempio n. 13
0
static asynStatus readIt(asynUser *pasynUser,char *message,
        size_t maxBytes, size_t *nBytesRead)
{
    devPvt     *pdevPvt = (devPvt *)pasynUser->userPvt;
    dbCommon   *precord = pdevPvt->precord;
    asynOctet  *poctet = pdevPvt->poctet;
    void       *octetPvt = pdevPvt->octetPvt;
    asynStatus status;
    int        eomReason;

    status = poctet->read(octetPvt,pasynUser,message,maxBytes,
        nBytesRead,&eomReason);
    if(status!=asynSuccess) {
        asynPrint(pasynUser,ASYN_TRACE_ERROR,
            "%s devTestBlock: readIt failed %s\n",
            precord->name,pasynUser->errorMessage);
        recGblSetSevr(precord, READ_ALARM, INVALID_ALARM);
        return status;
    }
    asynPrintIO(pasynUser,ASYN_TRACEIO_DEVICE,message,*nBytesRead,
       "%s devTestBlock: readIt eomReason %d\n",precord->name,eomReason);
    return status;
}
Esempio n. 14
0
static asynStatus gpibPortRead(void *pdrvPvt,asynUser *pasynUser,
    char *data,int maxchars,int *nbytesTransfered,int *eomReason)
{
    niport *pniport = (niport *)pdrvPvt;
    int        actual = 0;
    double     timeout = pasynUser->timeout;
    int        addr = 0;
    asynStatus status;

    status = pasynManager->getAddr(pasynUser,&addr);
    if(status!=asynSuccess) return status;
    asynPrint(pasynUser,ASYN_TRACE_FLOW,"%s addr %d gpibPortRead\n",
        pniport->portName,addr);
    pniport->errorMessage[0] = 0;
    status = readGpib(pniport,data,maxchars,&actual,addr,timeout,eomReason);
    if(status!=asynSuccess) {
        epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
            "%s readGpib failed %s",pniport->portName,pniport->errorMessage);
    }
    asynPrintIO(pasynUser,ASYN_TRACEIO_DRIVER,
        data,actual,"%s addr %d gpibPortRead\n",pniport->portName,addr);
    *nbytesTransfered = actual;
    return status;
}
Esempio n. 15
0
/*
 * Read from the serial line
 */
static asynStatus readIt(void *drvPvt, asynUser *pasynUser,
    char *data, size_t maxchars,size_t *nbytesTransfered,int *gotEom)
{
    ttyController_t *tty = (ttyController_t *)drvPvt;
    int thisRead;
    int nRead = 0;
    int timerStarted = 0;
    asynStatus status = asynSuccess;

    assert(tty);
    asynPrint(pasynUser, ASYN_TRACE_FLOW,
               "%s read.\n", tty->serialDeviceName);
    if (tty->fd < 0) {
        epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                                "%s disconnected:", tty->serialDeviceName);
        return asynError;
    }
    if (maxchars <= 0) {
        epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
            "%s maxchars %d Why <=0?",tty->serialDeviceName,(int)maxchars);
        return asynError;
    }
    if (tty->readTimeout != pasynUser->timeout) {
#ifndef vxWorks
        /*
         * Must set flags if we're transitioning
         * between blocking and non-blocking.
         */
        if ((pasynUser->timeout == 0) || (tty->readTimeout == 0)) {
            int newFlags = (pasynUser->timeout == 0) ? O_NONBLOCK : 0;
            if (fcntl(tty->fd, F_SETFL, newFlags) < 0) {
                epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                            "Can't set %s file flags: %s",
                                    tty->serialDeviceName, strerror(errno));
                closeConnection(pasynUser,tty);
                return asynError;
            }
        }
        /*
         * Set TERMIOS timeout
         */
        if (pasynUser->timeout > 0) {
            int t = (pasynUser->timeout * 10) + 1;
            if (t > 255)
                t = 255;
            tty->termios.c_cc[VMIN] = 0;
            tty->termios.c_cc[VTIME] = t;
        }
        else if (pasynUser->timeout == 0) {
            tty->termios.c_cc[VMIN] = 0;
            tty->termios.c_cc[VTIME] = 0;
        }
        else {
            tty->termios.c_cc[VMIN] = 1;
            tty->termios.c_cc[VTIME] = 0;
        }
            
        if (tcsetattr(tty->fd, TCSANOW, &tty->termios) < 0) {
            epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                              "Can't set \"%s\" c_cc[VTIME]: %s",
                                       tty->serialDeviceName, strerror(errno));
            closeConnection(pasynUser,tty);
            return asynError;
        }
#endif
        tty->readTimeout = pasynUser->timeout;
    }
    tty->timeoutFlag = 0;
    if (gotEom) *gotEom = 0;
    for (;;) {
#ifdef vxWorks
        /*
         * vxWorks has neither poll() nor termios but does have the
         * ability to cancel an operation in progress.  If the read
         * timeout is zero we have to check for characters explicitly
         * since we don't want to start a timer with 0 delay.
         */
        if (tty->readTimeout == 0) {
            int nready;
            ioctl(tty->fd, FIONREAD, (int)&nready);
            if (nready == 0) {
                tty->timeoutFlag = 1;
                break;
            }
        }
#endif
        if (!timerStarted && (tty->readTimeout > 0)) {
            epicsTimerStartDelay(tty->timer, tty->readTimeout);
            timerStarted = 1;
        }
        thisRead = read(tty->fd, data, maxchars);
        if (thisRead > 0) {
            asynPrintIO(pasynUser, ASYN_TRACEIO_DRIVER, data, thisRead,
                       "%s read %d\n", tty->serialDeviceName, thisRead);
            nRead = thisRead;
            tty->nRead += thisRead;
            break;
        }
        else {
            if ((thisRead < 0) && (errno != EWOULDBLOCK)
                               && (errno != EINTR)
                               && (errno != EAGAIN)) {
                epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                                "%s read error: %s",
                                        tty->serialDeviceName, strerror(errno));
                closeConnection(pasynUser,tty);
                status = asynError;
                break;
            }
            if (tty->readTimeout == 0)
                tty->timeoutFlag = 1;
        }
        if (tty->timeoutFlag)
            break;
    }
    if (timerStarted) epicsTimerCancel(tty->timer);
    if (tty->timeoutFlag && (status == asynSuccess))
        status = asynTimeout;
    *nbytesTransfered = nRead;
    /* If there is room add a null byte */
    if (nRead < maxchars)
        data[nRead] = 0;
    else if (gotEom)
        *gotEom = ASYN_EOM_CNT;
    asynPrint(pasynUser, ASYN_TRACE_FLOW, "%s read %lu, return %d\n",
                            tty->serialDeviceName, (unsigned long)*nbytesTransfered, status);
    return status;
}
Esempio n. 16
0
/*
 * Write to the serial line
 */
static asynStatus writeIt(void *drvPvt, asynUser *pasynUser,
    const char *data, size_t numchars,size_t *nbytesTransfered)
{
    ttyController_t *tty = (ttyController_t *)drvPvt;
    int thisWrite;
    int nleft = numchars;
    int timerStarted = 0;
    asynStatus status = asynSuccess;

    assert(tty);
    asynPrint(pasynUser, ASYN_TRACE_FLOW,
                            "%s write.\n", tty->serialDeviceName);
    asynPrintIO(pasynUser, ASYN_TRACEIO_DRIVER, data, numchars,
                            "%s write %lu\n", tty->serialDeviceName, (unsigned long)numchars);
    if (tty->fd < 0) {
        epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                                "%s disconnected:", tty->serialDeviceName);
        return asynError;
    }
    if (numchars == 0) {
        *nbytesTransfered = 0;
        return asynSuccess;
    }
    if (tty->writeTimeout != pasynUser->timeout) {
#ifndef vxWorks
        /*
         * Must set flags if we're transitioning
         * between blocking and non-blocking.
         */
        if ((pasynUser->timeout == 0) || (tty->writeTimeout == 0)) {
            int newFlags = (pasynUser->timeout == 0) ? O_NONBLOCK : 0;
            if (fcntl(tty->fd, F_SETFL, newFlags) < 0) {
                epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                            "Can't set %s file flags: %s",
                                    tty->serialDeviceName, strerror(errno));
                closeConnection(pasynUser,tty);
                return asynError;
            }
        }
#endif
        tty->writeTimeout = pasynUser->timeout;
    }
    tty->timeoutFlag = 0;
    nleft = numchars;
#ifdef vxWorks
    if (tty->writeTimeout >= 0)
#else
    if (tty->writeTimeout > 0)
#endif
        {
        epicsTimerStartDelay(tty->timer, tty->writeTimeout);
        timerStarted = 1;
        }
    for (;;) {
        thisWrite = write(tty->fd, (char *)data, nleft);
        if (thisWrite > 0) {
            tty->nWritten += thisWrite;
            nleft -= thisWrite;
            if (nleft == 0)
                break;
            data += thisWrite;
        }
        if (tty->timeoutFlag || (tty->writeTimeout == 0)) {
            status = asynTimeout;
            break;
        }
        if ((thisWrite < 0) && (errno != EWOULDBLOCK)
                            && (errno != EINTR)
                            && (errno != EAGAIN)) {
            epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                                "%s write error: %s",
                                        tty->serialDeviceName, strerror(errno));
            closeConnection(pasynUser,tty);
            status = asynError;
            break;
        }
    }
    if (timerStarted) epicsTimerCancel(tty->timer);
    *nbytesTransfered = numchars - nleft;
    asynPrint(pasynUser, ASYN_TRACE_FLOW, "wrote %lu to %s, return %s\n",
                                            (unsigned long)*nbytesTransfered,
                                            tty->serialDeviceName,
                                            pasynManager->strStatus(status));
    return status;
}
Esempio n. 17
0
/** This thread is woken up by an interrupt or a request to read status
  * It loops calling readFIFO until acquiring_ goes to false.
  * readFIFO only reads a limited amount of FIFO data at once in order
  * to avoid blocking the device support threads. */
void drvSIS3801::readFIFOThread()
{
  int count;
  int signal;
  int chan;
  int nChans;
  int status;
  int i;
  bool acquiring;  // We have a separate flag because we need to continue processing one last
                   // time even if acquiring_ goes to false because acquisition was manually stopped
  epicsUInt32 scalerPresets[SIS38XX_MAX_SIGNALS];
  epicsUInt32 *pOut=NULL;
  epicsTimeStamp t1, t2;
  static const char* functionName="readFIFOThread";

  while(true)
  {
    epicsEventWait(readFIFOEventId_);
    // We got an event, which can come from acquisition starting, or FIFO full interrupt
    asynPrint(pasynUserSelf, ASYN_TRACE_FLOW,
              "%s:%s: got readFIFOEvent, eventType=%d, interrupt status=0x%8.8x\n",
              driverName, functionName, eventType_, registers_->csr_reg & 0xFFF00000);
    lock();
    acquiring = acquiring_;
    unlock();
    while (acquiring) {
      lock();
      for (i=0; i<maxSignals_; i++) 
        getIntegerParam(i, scalerPresets_, (int *)&scalerPresets[i]);
      getIntegerParam(mcaNumChannels_, &nChans);
      asynPrint(pasynUserSelf, ASYN_TRACE_FLOW,
                "%s:%s: scaler presets[0]=%d, scalerData[0]=%d\n",
                driverName, functionName, scalerPresets[0], scalerData_[0]);
      signal = nextSignal_;
      chan = nextChan_;
      count = 0;
      // This block of code can be slow and does not require the asynPortDriver lock because we are not
      // accessing object data that could change.  
      // It does require the FIFO lock so no one resets the FIFO while it executes
      epicsMutexLock(fifoLockId_);
      unlock();
      epicsTimeGetCurrent(&t1);

      /* Read out FIFO. It would be more efficient not to check the empty
       * flag on each transfer, using the almost empty flag.  But this has gotten
       * too complex, and is unlikely to save time on new boards with lots of
       * memory.
       */
      if (acquireMode_== ACQUIRE_MODE_MCS) {
        // Copy the data from the FIFO to the mcsBuffer
        pOut = mcsData_ + signal*maxChans_ + chan;
        asynPrint(pasynUserSelf, ASYN_TRACE_FLOW,
                  "%s:%s: pOut=%p, signal=%d, chan=%d\n",
                  driverName, functionName, pOut, signal, chan);
        while (((registers_->csr_reg & STATUS_M_FIFO_FLAG_EMPTY)==0) && (chan < nChans) && acquiring_) {
          *pOut = registers_->fifo_reg;
          signal++;
          count++;
          if (signal >= maxSignals_) {
            signal = 0;
            chan++;
            pOut = mcsData_ + chan;
          } else {
            pOut += maxChans_;
          }
        }
      } else if (acquireMode_ == ACQUIRE_MODE_SCALER) {
        while ((registers_->csr_reg & STATUS_M_FIFO_FLAG_EMPTY)==0 && acquiring_) {
          scalerData_[signal] += registers_->fifo_reg;
          signal++;
          count++;
          if (signal >= maxSignals_) {
            for (i=0; i<maxSignals_; i++) {
              if ((scalerPresets[i] != 0) && 
                  (scalerData_[i] >= scalerPresets[i]))
                acquiring = false;
            }
            asynPrintIO(pasynUserSelf, ASYN_TRACEIO_DRIVER, 
                      (const char*)scalerData_, maxSignals_*sizeof(epicsUInt32), 
                      "%s:%s:\n",
                      driverName, functionName);
            if (!acquiring) break;
            signal = 0;
          }
        }
      }
      epicsTimeGetCurrent(&t2);

      asynPrint(pasynUserSelf, ASYN_TRACE_FLOW, 
                "%s:%s: read FIFO (%d) in %fs, acquiring=%d\n",
                driverName, functionName, count, epicsTimeDiffInSeconds(&t2, &t1), acquiring_);
      // Release the FIFO lock, we are done accessing the FIFO
      epicsMutexUnlock(fifoLockId_);
      
      // Take the lock since we are now changing object data
      lock();
      nextChan_ = chan;
      nextSignal_ = signal;
      if (acquireMode_ == ACQUIRE_MODE_MCS) {
        asynPrint(pasynUserSelf, ASYN_TRACE_FLOW,
                  "%s:%s: pOut=%p,signal=%d, chan=%d\n",
                  driverName, functionName, pOut, signal, chan);
        checkMCSDone();
      } else if (acquireMode_ == ACQUIRE_MODE_SCALER) {
        if (!acquiring) acquiring_ = false;
        if (!acquiring_) {
          asynPrint(pasynUserSelf, ASYN_TRACE_FLOW,
                    "%s:%s: scaler done, doing callbacks\n",
                    driverName, functionName);
          stopScaler();
          setIntegerParam(scalerDone_, 1);
          callParamCallbacks();
        }
      }
      /* Reenable interrupts in case we were woken up by an interrupt for FIFO almost full */
      enableInterrupts();
      acquiring = acquiring_;
      // Release the lock
      unlock();
      // If we are still acquiring then sleep for a short time, but wake up if there is an interrupt
      if (acquiring) {
        status = epicsEventWaitWithTimeout(readFIFOEventId_, epicsThreadSleepQuantum());
        if (status == epicsEventWaitOK) 
          asynPrint(pasynUserSelf, ASYN_TRACE_FLOW,
                    "%s:%s: got interrupt in epicsEventWaitWithTimeout, eventType=%d\n",
                    driverName, functionName, eventType_);
      }
    }  
  }
}
/*
 * Read from the serial line
 */
static asynStatus readIt(void *drvPvt, asynUser *pasynUser,
    char *data, size_t maxchars,size_t *nbytesTransfered,int *gotEom)
{
    ttyController_t *tty = (ttyController_t *)drvPvt;
    int thisRead;
    int nRead = 0;
    int timerStarted = 0;
    COMMTIMEOUTS ctimeout;
    BOOL ret;
    DWORD error;
    asynStatus status = asynSuccess;

    assert(tty);
    asynPrint(pasynUser, ASYN_TRACE_FLOW,
               "%s read.\n", tty->serialDeviceName);
    if (tty->commHandle == INVALID_HANDLE_VALUE) {
        epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                                "%s disconnected:", tty->serialDeviceName);
        return asynError;
    }
    if (maxchars <= 0) {
        epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
            "%s maxchars %d Why <=0?",tty->serialDeviceName,(int)maxchars);
        return asynError;
    }
    if (tty->readTimeout != pasynUser->timeout) {
        if (pasynUser->timeout >= 0) {
            ctimeout.ReadIntervalTimeout          = (int)(pasynUser->timeout*1000.); 
            ctimeout.ReadTotalTimeoutMultiplier   = 1; 
            ctimeout.ReadTotalTimeoutConstant     = (int)(pasynUser->timeout*1000.); 
            ctimeout.WriteTotalTimeoutMultiplier  = 1; 
            ctimeout.WriteTotalTimeoutConstant    = (int)(pasynUser->timeout*1000.); 

            ret = SetCommTimeouts(tty->commHandle, &ctimeout);
            if (ret == 0) {
                error = GetLastError();
                epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                              "Can't set \"%s\" timeout: %f, error=%d",
                              tty->serialDeviceName, pasynUser->timeout, error);
                return asynError;
            }
            tty->readTimeout = pasynUser->timeout;
        }
    }
    tty->timeoutFlag = 0;
    if (gotEom) *gotEom = 0;
    for (;;) {
        if (!timerStarted && (tty->readTimeout > 0)) {
            epicsTimerStartDelay(tty->timer, tty->readTimeout);
            timerStarted = 1;
        }
        ret = ReadFile(
                        tty->commHandle,  // handle of file to read
                        data,             // pointer to buffer that receives data
                        1,                // number of bytes to read
                        &thisRead,        // pointer to number of bytes read
                        NULL              // pointer to structure for data
                        );
        if (ret == 0) {
            error = GetLastError();
            epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                          "%s read error: %d",
                          tty->serialDeviceName, error);
            status = asynError;
            break;
        }
        if (thisRead > 0) {
            asynPrintIO(pasynUser, ASYN_TRACEIO_DRIVER, data, thisRead,
                       "%s read %d\n", tty->serialDeviceName, thisRead);
            nRead = thisRead;
            tty->nRead += thisRead;
            break;
        }
        if (tty->timeoutFlag)
            break;
        if (tty->readTimeout == 0) /* Timeout of 0 means return immediately */
            break;
    }
    if (timerStarted) epicsTimerCancel(tty->timer);
    if (tty->timeoutFlag && (status == asynSuccess))
        status = asynTimeout;
    *nbytesTransfered = nRead;
    /* If there is room add a null byte */
    if (nRead < (int)maxchars)
        data[nRead] = 0;
    else if (gotEom)
        *gotEom = ASYN_EOM_CNT;
    asynPrint(pasynUser, ASYN_TRACE_FLOW, "%s read %d, return %d\n",
                            tty->serialDeviceName, *nbytesTransfered, status);
    return status;
}
/*
 * Write to the serial line
 */
static asynStatus writeIt(void *drvPvt, asynUser *pasynUser,
    const char *data, size_t numchars,size_t *nbytesTransfered)
{
    ttyController_t *tty = (ttyController_t *)drvPvt;
    int thisWrite;
    int nleft = (int)numchars;
    int timerStarted = 0;
    BOOL ret;
    DWORD error;
    asynStatus status = asynSuccess;

    assert(tty);
    asynPrint(pasynUser, ASYN_TRACE_FLOW,
                            "%s write.\n", tty->serialDeviceName);
    asynPrintIO(pasynUser, ASYN_TRACEIO_DRIVER, data, numchars,
                            "%s write %d\n", tty->serialDeviceName, numchars);
    if (tty->commHandle == INVALID_HANDLE_VALUE) {
        epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                                "%s disconnected:", tty->serialDeviceName);
        return asynError;
    }
    if (numchars == 0) {
        *nbytesTransfered = 0;
        return asynSuccess;
    }
    if (tty->writeTimeout != pasynUser->timeout) {
        tty->writeTimeout = pasynUser->timeout;
    }
    tty->timeoutFlag = 0;
    nleft = (int)numchars;
    if (tty->writeTimeout > 0)
        {
        epicsTimerStartDelay(tty->timer, tty->writeTimeout);
        timerStarted = 1;
        }
    for (;;) {
        ret = WriteFile(tty->commHandle,     // handle to file to write to
                        data,     // pointer to data to write to file
                        nleft,     // number of bytes to write
                        &thisWrite, // pointer to number of bytes written
                        NULL     // pointer to structure for overlapped I/O
                        );
        if (ret == 0) {
            error = GetLastError();
            epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                                "%s write error: %d",
                                        tty->serialDeviceName, error);
            closeConnection(pasynUser,tty);
            status = asynError;
            break;
        }
        tty->nWritten += thisWrite;
        nleft -= thisWrite;
        if (nleft == 0)
            break;
        data += thisWrite;
        if (tty->timeoutFlag || (tty->writeTimeout == 0)) {
            status = asynTimeout;
            break;
        }
    }
    if (timerStarted) epicsTimerCancel(tty->timer);
    *nbytesTransfered = numchars - nleft;
    asynPrint(pasynUser, ASYN_TRACE_FLOW, "wrote %lu to %s, return %s\n",
                                            (unsigned long)*nbytesTransfered,
                                            tty->serialDeviceName,
                                            pasynManager->strStatus(status));
    return status;
}
Esempio n. 20
0
/*
 * Read from the TCP port
 */
static asynStatus readIt(void *drvPvt, asynUser *pasynUser,
                         char *data, size_t maxchars,size_t *nbytesTransfered,int *gotEom)
{
    ttyController_t *tty = (ttyController_t *)drvPvt;
    int thisRead;
    int readPollmsec;
    int reason = 0;
    epicsTimeStamp startTime;
    epicsTimeStamp endTime;
    asynStatus status = asynSuccess;

    assert(tty);
    asynPrint(pasynUser, ASYN_TRACE_FLOW,
              "%s read.\n", tty->IPDeviceName);
    if (tty->fd == INVALID_SOCKET) {
        if (tty->flags & FLAG_CONNECT_PER_TRANSACTION) {
            if ((status = connectIt(drvPvt, pasynUser)) != asynSuccess)
                return status;
        }
        else {
            epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                          "%s disconnected:", tty->IPDeviceName);
            return asynError;
        }
    }
    if (maxchars <= 0) {
        epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                      "%s maxchars %d. Why <=0?",tty->IPDeviceName,(int)maxchars);
        return asynError;
    }
    readPollmsec = (int) (pasynUser->timeout * 1000.0);
    if (readPollmsec == 0) readPollmsec = 1;
    if (readPollmsec < 0) readPollmsec = -1;
#ifdef USE_SOCKTIMEOUT
    {
        struct timeval tv;
        tv.tv_sec = readPollmsec / 1000;
        tv.tv_usec = (readPollmsec % 1000) * 1000;
        if (setsockopt(tty->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof tv) < 0) {
            epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                          "Can't set %s socket receive timeout: %s",
                          tty->IPDeviceName, strerror(SOCKERRNO));
            status = asynError;
        }
    }
#endif
    if (gotEom) *gotEom = 0;
#ifdef USE_POLL
    {
        struct pollfd pollfd;
        pollfd.fd = tty->fd;
        pollfd.events = POLLIN;
        epicsTimeGetCurrent(&startTime);
        while (poll(&pollfd, 1, readPollmsec) < 0) {
            if (errno != EINTR) {
                epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                              "Poll() failed: %s", strerror(errno));
                return asynError;
            }
            epicsTimeGetCurrent(&endTime);
            if (epicsTimeDiffInSeconds(&endTime, &startTime)*1000. > readPollmsec) break;
        }
    }
#endif
    if (tty->socketType == SOCK_DGRAM) {
        /* We use recvfrom() for SOCK_DRAM so we can print the source address with ASYN_TRACEIO_DRIVER */
        osiSockAddr oa;
        unsigned int addrlen = sizeof(oa.ia);
        thisRead = recvfrom(tty->fd, data, (int)maxchars, 0, &oa.sa, &addrlen);
        if (thisRead > 0) {
            if (pasynTrace->getTraceMask(pasynUser) & ASYN_TRACEIO_DRIVER) {
                char inetBuff[32];
                ipAddrToDottedIP(&oa.ia, inetBuff, sizeof(inetBuff));
                asynPrintIO(pasynUser, ASYN_TRACEIO_DRIVER, data, thisRead,
                            "%s (from %s) read %d\n",
                            tty->IPDeviceName, inetBuff, thisRead);
            }
            tty->nRead += (unsigned long)thisRead;
        }
    } else {
        thisRead = recv(tty->fd, data, (int)maxchars, 0);
        if (thisRead > 0) {
            asynPrintIO(pasynUser, ASYN_TRACEIO_DRIVER, data, thisRead,
                        "%s read %d\n", tty->IPDeviceName, thisRead);
            tty->nRead += (unsigned long)thisRead;
        }
    }
    if (thisRead < 0) {
        int should_close = (tty->userFlags & USERFLAG_CLOSE_ON_READ_TIMEOUT) ||
                           ((SOCKERRNO != SOCK_EWOULDBLOCK) && (SOCKERRNO != SOCK_EINTR));
        if (should_close) {
            epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                          "%s read error: %s",
                          tty->IPDeviceName, strerror(SOCKERRNO));
            closeConnection(pasynUser,tty,"Read error");
            status = asynError;
        } else {
            epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                          "%s timeout: %s",
                          tty->IPDeviceName, strerror(SOCKERRNO));
            status = asynTimeout;
        }
    }
    /* If recv() returns 0 on a SOCK_STREAM (TCP) socket, the connection has closed */
    if ((thisRead == 0) && (tty->socketType == SOCK_STREAM)) {
        epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                      "%s connection closed",
                      tty->IPDeviceName);
        closeConnection(pasynUser,tty,"Read from broken connection");
        reason |= ASYN_EOM_END;
    }
    if (thisRead < 0)
        thisRead = 0;
    *nbytesTransfered = thisRead;
    /* If there is room add a null byte */
    if (thisRead < (int) maxchars)
        data[thisRead] = 0;
    else
        reason |= ASYN_EOM_CNT;
    if (gotEom) *gotEom = reason;
    return status;
}
Esempio n. 21
0
/*
 * Write to the TCP port
 */
static asynStatus writeIt(void *drvPvt, asynUser *pasynUser,
                          const char *data, size_t numchars,size_t *nbytesTransfered)
{
    ttyController_t *tty = (ttyController_t *)drvPvt;
    int thisWrite;
    asynStatus status = asynSuccess;
    int writePollmsec;
    int epicsTimeStatus;
    epicsTimeStamp startTime;
    epicsTimeStamp endTime;
    int haveStartTime;

    assert(tty);
    asynPrint(pasynUser, ASYN_TRACE_FLOW,
              "%s write.\n", tty->IPDeviceName);
    asynPrintIO(pasynUser, ASYN_TRACEIO_DRIVER, data, numchars,
                "%s write %lu\n", tty->IPDeviceName, (unsigned long)numchars);
    *nbytesTransfered = 0;
    if (tty->fd == INVALID_SOCKET) {
        if (tty->flags & FLAG_CONNECT_PER_TRANSACTION) {
            if ((status = connectIt(drvPvt, pasynUser)) != asynSuccess)
                return status;
        }
        else {
            epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                          "%s disconnected:", tty->IPDeviceName);
            return asynError;
        }
    }
    if (numchars == 0)
        return asynSuccess;
    writePollmsec = (int) (pasynUser->timeout * 1000.0);
    if (writePollmsec == 0) writePollmsec = 1;
    if (writePollmsec < 0) writePollmsec = -1;
#ifdef USE_SOCKTIMEOUT
    {
        struct timeval tv;
        tv.tv_sec = writePollmsec / 1000;
        tv.tv_usec = (writePollmsec % 1000) * 1000;
        if (setsockopt(tty->fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof tv) < 0) {
            epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                          "Can't set %s socket send timeout: %s",
                          tty->IPDeviceName, strerror(SOCKERRNO));
            return asynError;
        }
    }
#endif
    haveStartTime = 0;
    for (;;) {
#ifdef USE_POLL
        struct pollfd pollfd;
        pollfd.fd = tty->fd;
        pollfd.events = POLLOUT;
        epicsTimeGetCurrent(&startTime);
        while (poll(&pollfd, 1, writePollmsec) < 0) {
            if (errno != EINTR) {
                epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                              "Poll() failed: %s", strerror(errno));
                return asynError;
            }
            epicsTimeGetCurrent(&endTime);
            if (epicsTimeDiffInSeconds(&endTime, &startTime)*1000 > writePollmsec) break;
        }
#endif
        for (;;) {
            if (tty->socketType == SOCK_DGRAM) {
                thisWrite = sendto(tty->fd, (char *)data, (int)numchars, 0, &tty->farAddr.oa.sa, (int)tty->farAddrSize);
            } else {
                thisWrite = send(tty->fd, (char *)data, (int)numchars, 0);
            }
            if (thisWrite >= 0) break;
            if (SOCKERRNO == SOCK_EWOULDBLOCK || SOCKERRNO == SOCK_EINTR) {
                if (!haveStartTime) {
                    epicsTimeStatus = epicsTimeGetCurrent(&startTime);
                    assert(epicsTimeStatus == epicsTimeOK);
                    haveStartTime = 1;
                } else if (pasynUser->timeout >= 0) {
                    epicsTimeStatus = epicsTimeGetCurrent(&endTime);
                    assert(epicsTimeStatus == epicsTimeOK);
                    if (epicsTimeDiffInSeconds(&endTime, &startTime) >
                            pasynUser->timeout) {
                        thisWrite = 0;
                        break;
                    }
                }
                epicsThreadSleep(SEND_RETRY_DELAY);
            } else break;
        }
        if (thisWrite > 0) {
            tty->nWritten += (unsigned long)thisWrite;
            *nbytesTransfered += thisWrite;
            numchars -= thisWrite;
            if (numchars == 0)
                break;
            data += thisWrite;
        }
        else if (thisWrite == 0) {
            status = asynTimeout;
            break;
        }
        else {
            epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize,
                          "%s write error: %s", tty->IPDeviceName,
                          strerror(SOCKERRNO));
            closeConnection(pasynUser,tty,"Write error");
            status = asynError;
            break;
        }
    }
    asynPrint(pasynUser, ASYN_TRACE_FLOW,
              "wrote %lu to %s, return %s.\n", (unsigned long)*nbytesTransfered,
              tty->IPDeviceName,
              pasynManager->strStatus(status));
    return status;
}