VirtualBox

Ticket #812: DrvHostSerial.diff

File DrvHostSerial.diff, 4.7 KB (added by Lawrence Rust, 16 years ago)

Linux TIOCMIWAIT workaround

  • .cpp

    old new  
    6161#  ifndef TIOCM_LOOP
    6262#   define TIOCM_LOOP 0x8000
    6363#  endif
    64 
    65 #define LINUX_CMIWAIT_BUG 1 /* 2.6.24 TIOCMIWAIT workaround */
    6664# endif /* linux */
    6765
    6866#elif defined(RT_OS_WINDOWS)
     
    123121    RTFILE                      WakeupPipeR;
    124122    /** The write end of the control pipe */
    125123    RTFILE                      WakeupPipeW;
    126 # if !defined RT_OS_LINUX || LINUX_CMIWAIT_BUG
     124# ifndef RT_OS_LINUX
    127125    /** The current line status.
    128126     * Used by the polling version of drvHostSerialMonitorThread.  */
    129127    int                         fStatusLines;
     
    945943{
    946944    PDRVHOSTSERIAL pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTSERIAL);
    947945    int rc = VINF_SUCCESS;
    948     unsigned const uStatusLinesToCheck = TIOCM_CAR | TIOCM_RNG | TIOCM_DSR | TIOCM_CTS;
     946    unsigned uStatusLinesToCheck = 0;
    949947
    950     if ( PDMTHREADSTATE_INITIALIZING == pThread->enmState)
     948    uStatusLinesToCheck = TIOCM_CAR | TIOCM_RNG | TIOCM_LE | TIOCM_CTS;
     949
     950    if (pThread->enmState == PDMTHREADSTATE_INITIALIZING)
    951951        return VINF_SUCCESS;
    952     do
     952
     953    while (pThread->enmState == PDMTHREADSTATE_RUNNING)
    953954    {
    954955        uint32_t newStatusLine = 0;
    955956        unsigned int statusLines;
    956957
    957         if ( 0 > (rc = ioctl( pThis->DeviceFile, TIOCMGET, &statusLines)))
     958# ifdef RT_OS_LINUX
     959        /*
     960         * Wait for status line change.
     961         */
     962        rc = ioctl(pThis->DeviceFile, TIOCMIWAIT, &uStatusLinesToCheck);
     963        if (pThread->enmState != PDMTHREADSTATE_RUNNING)
     964            break;
     965        if (rc < 0)
    958966        {
     967ioctl_error:
    959968            PDMDrvHlpVMSetRuntimeError( pDrvIns, false, "DrvHostSerialFail",
    960969                N_("Ioctl failed for serial host device '%s' (%Rrc). The device will not work properly"),
    961                 pThis->pszDevicePath, RTErrConvertFromErrno(errno)
    962             );
     970                                       pThis->pszDevicePath, RTErrConvertFromErrno(errno));
    963971            break;
    964972        }
     973
     974        rc = ioctl(pThis->DeviceFile, TIOCMGET, &statusLines);
     975        if (rc < 0)
     976            goto ioctl_error;
     977# else  /* !RT_OS_LINUX */
     978        /*
     979         * Poll for the status line change.
     980         */
     981        rc = ioctl(pThis->DeviceFile, TIOCMGET, &statusLines);
     982        if (rc < 0)
     983        {
     984            PDMDrvHlpVMSetRuntimeError(pDrvIns, false, "DrvHostSerialFail",
     985                                       N_("Ioctl failed for serial host device '%s' (%Rrc). The device will not work properly"),
     986                                       pThis->pszDevicePath, RTErrConvertFromErrno(errno));
     987            break;
     988        }
     989        if (!((statusLines ^ pThis->fStatusLines) & uStatusLinesToCheck))
     990        {
     991            PDMR3ThreadSleep(pThread, 500); /* 0.5 sec */
     992            continue;
     993        }
     994        pThis->fStatusLines = statusLines;
     995# endif /* !RT_OS_LINUX */
     996
    965997        if ( statusLines & TIOCM_CAR)
    966998            newStatusLine |= PDM_ICHAR_STATUS_LINES_DCD;
    967999        if ( statusLines & TIOCM_RNG)
     
    9701002            newStatusLine |= PDM_ICHAR_STATUS_LINES_DSR;
    9711003        if ( statusLines & TIOCM_CTS)
    9721004            newStatusLine |= PDM_ICHAR_STATUS_LINES_CTS;
    973         pThis->pDrvCharPort->pfnNotifyStatusLinesChanged( pThis->pDrvCharPort, newStatusLine);
    974 
    975         if ( PDMTHREADSTATE_RUNNING != pThread->enmState)
    976             break;
    977 # if defined RT_OS_LINUX && !LINUX_CMIWAIT_BUG
    978         /* BUGBUG: In Linux 2.6.24 and earlier the 8250 driver doesn't report modem status
    979          * changes unless there has been data I/O. */
    980 
    981         /* Wait for status line change. */
    982         ioctl( pThis->DeviceFile, TIOCMIWAIT, uStatusLinesToCheck);
    983         Log(("HostSerial#%d: MonitorThread modem status changed.\n", pDrvIns->iInstance));
    984 # else
    985         /* Poll for status line change. */
    986         if (!((statusLines ^ pThis->fStatusLines) & uStatusLinesToCheck))
    987             PDMR3ThreadSleep( pThread, 500); /* 0.5 sec */
    988         pThis->fStatusLines = statusLines;
    989 # endif
     1005        rc = pThis->pDrvCharPort->pfnNotifyStatusLinesChanged(pThis->pDrvCharPort, newStatusLine);
    9901006    }
    991     while ( PDMTHREADSTATE_RUNNING == pThread->enmState);
    9921007
    993     return rc;
     1008    return VINF_SUCCESS;
    9941009}
    9951010
    9961011/**
     
    13251340
    13261341#if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN)
    13271342    /* Linux & darwin needs a separate thread which monitors the status lines. */
    1328 # if !defined RT_OS_LINUX || LINUX_CMIWAIT_BUG
     1343# ifndef RT_OS_LINUX
    13291344    ioctl(pThis->DeviceFile, TIOCMGET, &pThis->fStatusLines);
    13301345# endif
    13311346    rc = PDMDrvHlpPDMThreadCreate(pDrvIns, &pThis->pMonitorThread, pThis, drvHostSerialMonitorThread, drvHostSerialWakeupMonitorThread, 0, RTTHREADTYPE_IO, "SerMon");

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy