VirtualBox

Changeset 4236 in vbox


Ignore:
Timestamp:
Aug 20, 2007 8:56:32 AM (18 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
23734
Message:

Alexander Eichner: host serial device cleanup + added Windows host support

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/log.h

    r4071 r4236  
    135135    /** Host Parallel Driver group */
    136136    LOG_GROUP_DRV_HOST_PARALLEL,
     137    /** Host Serial Driver Group */
     138    LOG_GROUP_DRV_HOST_SERIAL,
    137139    /** The internal networking transport driver group. */
    138140    LOG_GROUP_DRV_INTNET,
     
    324326    "DRV_HOST_HDD", \
    325327    "DRV_HOST_PARALLEL", \
     328    "DRV_HOST_SERIAL", \
    326329    "DRV_INTNET",   \
    327330    "DRV_ISCSI",    \
  • trunk/src/VBox/Devices/Makefile.kmk

    r4144 r4236  
    442442Drivers_SOURCES.win   = \
    443443        Network/DrvTAPWin32.cpp \
    444         Audio/dsoundaudio.c
     444        Audio/dsoundaudio.c \
     445        Serial/DrvHostSerial.cpp
    445446
    446447
  • trunk/src/VBox/Devices/Serial/DrvHostSerial.cpp

    r4148 r4236  
    2828*   Header Files                                                               *
    2929*******************************************************************************/
    30 #define LOG_GROUP LOG_GROUP_DRV_CHAR
     30#define LOG_GROUP LOG_GROUP_DRV_HOST_SERIAL
    3131#include <VBox/pdm.h>
    3232#include <VBox/err.h>
     
    3737#include <iprt/stream.h>
    3838#include <iprt/semaphore.h>
     39#include <iprt/file.h>
     40#include <iprt/alloc.h>
    3941
    4042#ifdef RT_OS_LINUX
    41 #include <termios.h>
    42 #include <sys/types.h>
    43 #include <fcntl.h>
    44 #include <string.h>
    45 #include <unistd.h>
     43# include <termios.h>
     44# include <sys/types.h>
     45# include <fcntl.h>
     46# include <string.h>
     47# include <unistd.h>
     48#elif defined(RT_OS_WINDOWS)
     49# include <windows.h>
    4650#endif
    4751
     
    8084    char                        *pszDevicePath;
    8185    /** the device handle */
    82     int                         DeviceFile;
     86    RTFILE                      DeviceFile;
    8387
    8488    /** Internal send FIFO queue */
     
    150154{
    151155    PDRVHOSTSERIAL pData = PDMICHAR_2_DRVHOSTSERIAL(pInterface);
    152     struct termios termiosSetup;
     156#ifdef RT_OS_LINUX
     157    struct termios *termiosSetup;
    153158    int baud_rate;
     159#elif defined(RT_OS_WINDOWS)
     160    LPDCB comSetup;
     161#endif
    154162
    155163    LogFlow(("%s: Bps=%u chParity=%c cDataBits=%u cStopBits=%u\n", __FUNCTION__, Bps, chParity, cDataBits, cStopBits));
    156 
    157     memset(&termiosSetup, 0, sizeof(termiosSetup));
    158 
     164 
     165#ifdef RT_OS_LINUX
     166    termiosSetup = (struct termios *)RTMemTmpAllocZ(sizeof(struct termios));
     167 
    159168    /* Enable receiver */
    160     termiosSetup.c_cflag |= (CLOCAL | CREAD);
     169    termiosSetup->c_cflag |= (CLOCAL | CREAD);
    161170
    162171    switch (Bps) {
     
    234243    switch (cDataBits) {
    235244        case 5:
    236             termiosSetup.c_cflag |= CS5;
     245            termiosSetup->c_cflag |= CS5;
    237246            break;
    238247        case 6:
    239             termiosSetup.c_cflag |= CS6;
     248            termiosSetup->c_cflag |= CS6;
    240249            break;
    241250        case 7:
    242             termiosSetup.c_cflag |= CS7;
     251            termiosSetup->c_cflag |= CS7;
    243252            break;
    244253        case 8:
    245             termiosSetup.c_cflag |= CS8;
     254            termiosSetup->c_cflag |= CS8;
    246255            break;
    247256        default:
     
    260269
    261270    tcsetattr(pData->DeviceFile, TCSANOW, &termiosSetup);
     271    RTMemFree(termiosSetup);
     272#elif defined(RT_OS_WINDOWS)
     273    comSetup = (LPDCB)RTMemTmpAllocZ(sizeof(DCB));
     274
     275    comSetup->DCBlength = sizeof(DCB);
     276
     277    switch (Bps) {
     278        case 110:
     279            comSetup->BaudRate = CBR_110;
     280            break;
     281        case 300:
     282            comSetup->BaudRate = CBR_300;
     283            break;
     284        case 600:
     285            comSetup->BaudRate = CBR_600;
     286            break;
     287        case 1200:
     288            comSetup->BaudRate = CBR_1200;
     289            break;
     290        case 2400:
     291            comSetup->BaudRate = CBR_2400;
     292            break;
     293        case 4800:
     294            comSetup->BaudRate = CBR_4800;
     295            break;
     296        case 9600:
     297            comSetup->BaudRate = CBR_9600;
     298            break;
     299        case 14400:
     300            comSetup->BaudRate = CBR_14400;
     301            break;
     302        case 19200:
     303            comSetup->BaudRate = CBR_19200;
     304            break;
     305        case 38400:
     306            comSetup->BaudRate = CBR_38400;
     307            break;
     308        case 57600:
     309            comSetup->BaudRate = CBR_57600;
     310            break;
     311        case 115200:
     312            comSetup->BaudRate = CBR_115200;
     313            break;
     314        default:
     315            comSetup->BaudRate = CBR_9600;
     316    }
     317
     318    comSetup->fBinary = TRUE;
     319    comSetup->fOutxCtsFlow = FALSE;
     320    comSetup->fOutxDsrFlow = FALSE;
     321    comSetup->fDtrControl = DTR_CONTROL_DISABLE;
     322    comSetup->fDsrSensitivity = FALSE;
     323    comSetup->fTXContinueOnXoff = TRUE;
     324    comSetup->fOutX = FALSE;
     325    comSetup->fInX = FALSE;
     326    comSetup->fErrorChar = FALSE;
     327    comSetup->fNull = FALSE;
     328    comSetup->fRtsControl = RTS_CONTROL_DISABLE;
     329    comSetup->fAbortOnError = FALSE;
     330    comSetup->wReserved = 0;
     331    comSetup->XonLim = 5;
     332    comSetup->XoffLim = 5;
     333    comSetup->ByteSize = cDataBits;
     334
     335    switch (chParity) {
     336        case 'E':
     337            comSetup->Parity = EVENPARITY;
     338            break;
     339        case 'O':
     340            comSetup->Parity = ODDPARITY;
     341            break;
     342        case 'N':
     343            comSetup->Parity = NOPARITY;
     344            break;
     345        default:
     346            break;
     347    }
     348 
     349    switch (cStopBits) {
     350        case 1:
     351            comSetup->StopBits = ONESTOPBIT;
     352            break;
     353        case 2:
     354            comSetup->StopBits = TWOSTOPBITS;
     355            break;
     356        default:
     357            break;
     358    }
     359
     360    comSetup->XonChar = 0;
     361    comSetup->XoffChar = 0;
     362    comSetup->ErrorChar = 0;
     363    comSetup->EofChar = 0;
     364    comSetup->EvtChar = 0;
     365
     366    SetCommState((HANDLE)pData->DeviceFile, comSetup);
     367    RTMemFree(comSetup);
     368#endif /* RT_OS_WINDOWS */
    262369
    263370    return VINF_SUCCESS;
     
    292399                size_t cbProcessed = 1;
    293400
    294                 rc = write(pData->DeviceFile, &pData->aSendQueue[pData->iSendQueueTail], cbProcessed);
    295                 if (rc > 0)
     401                rc = RTFileWrite(pData->DeviceFile, &pData->aSendQueue[pData->iSendQueueTail], cbProcessed, NULL);
     402                if (VBOX_SUCCESS(rc))
    296403                {
    297404                    Assert(cbProcessed);
     
    299406                    pData->iSendQueueTail &= CHAR_MAX_SEND_QUEUE_MASK;
    300407                }
    301                 else if (rc < 0)
     408                else if (VBOX_FAILURE(rc))
    302409                {
    303410                    LogFlow(("Write failed with %Vrc; skipping\n", rc));
     
    329436    PDRVHOSTSERIAL pData = (PDRVHOSTSERIAL)pvUser;
    330437    char aBuffer[256], *pBuffer;
    331     size_t cbRemaining, cbProcessed;
     438    size_t cbRemaining, cbProcessed, cbRead;
    332439    int rc;
    333440
     
    338445        if (!cbRemaining)
    339446        {
    340             /* Get block of data from stream driver. */
     447            /* Get block of data from serial device. */
    341448            cbRemaining = sizeof(aBuffer);
    342             rc = read(pData->DeviceFile, aBuffer, cbRemaining);
    343             if (rc < 0)
     449            rc = RTFileRead(pData->DeviceFile, aBuffer, cbRemaining, &cbRead);
     450            if (VBOX_FAILURE(rc))
    344451            {
    345452                LogFlow(("Read failed with %Vrc\n", rc));
    346453                break;
    347454            } else {
    348                 cbRemaining = rc;
     455                cbRemaining = cbRead;
    349456            }
    350457            pBuffer = aBuffer;
     
    426533     * Open the device
    427534     */
    428     pData->DeviceFile = open(pData->pszDevicePath, O_RDWR | O_NONBLOCK);
    429     if (pData->DeviceFile < 0) {
    430 
    431     }
     535    rc = RTFileOpen(&pData->DeviceFile, pData->pszDevicePath, RTFILE_O_OPEN | RTFILE_O_READWRITE);
     536
     537    if (VBOX_FAILURE(rc)) {
     538        pData->DeviceFile = NIL_RTFILE;
     539        AssertMsgFailed(("Could not open host device %s, rc=%Vrc\n", pData->pszDevicePath, rc));
     540        switch (rc) {
     541            case VERR_ACCESS_DENIED:
     542                return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS,
     543#ifdef RT_OS_LINUX
     544                                           N_("Cannot open host device '%s' for read/write access. Check the permissions "
     545                                              "of that device ('/bin/ls -l %s'): Most probably you need to be member "
     546                                              "of the device group. Make sure that you logout/login after changing "
     547                                              "the group settings of the current user"),
     548#else
     549                                           N_("Cannot open host device '%s' for read/write access. Check the permissions "
     550                                              "of that device"),
     551#endif
     552                                           pData->pszDevicePath, pData->pszDevicePath);
     553           default:
     554                return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS,
     555                                           N_("Failed to open host device '%s'"),
     556                                           pData->pszDevicePath);
     557        }
     558    }
     559
     560    /* Set to non blocking I/O */
     561#ifdef RT_OS_LINUX
     562    fcntl(pData->DeviceFile, F_SETFL, O_NONBLOCK);
     563#elif defined(RT_OS_WINDOWS)
     564    /* Set the COMMTIMEOUTS to get non blocking I/O */
     565    COMMTIMEOUTS comTimeout;
     566
     567    comTimeout.ReadIntervalTimeout         = MAXDWORD;
     568    comTimeout.ReadTotalTimeoutMultiplier  = 0;
     569    comTimeout.ReadTotalTimeoutConstant    = 0;
     570    comTimeout.WriteTotalTimeoutMultiplier = 0;
     571    comTimeout.WriteTotalTimeoutConstant   = 0;
     572
     573    SetCommTimeouts((HANDLE)pData->DeviceFile, &comTimeout);
     574#endif
    432575
    433576    /*
     
    436579    pData->pDrvCharPort = (PPDMICHARPORT)pDrvIns->pUpBase->pfnQueryInterface(pDrvIns->pUpBase, PDMINTERFACE_CHAR_PORT);
    437580    if (!pData->pDrvCharPort)
    438         return PDMDrvHlpVMSetError(pDrvIns, VERR_PDM_MISSING_INTERFACE_ABOVE, RT_SRC_POS, N_("Char#%d has no char port interface above"), pDrvIns->iInstance);
     581        return PDMDrvHlpVMSetError(pDrvIns, VERR_PDM_MISSING_INTERFACE_ABOVE, RT_SRC_POS, N_("HostSerial#%d has no char port interface above"), pDrvIns->iInstance);
    439582
    440583    rc = RTThreadCreate(&pData->ReceiveThread, drvHostSerialReceiveLoop, (void *)pData, 0, RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "Char Receive");
    441584    if (VBOX_FAILURE(rc))
    442         return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("Char#%d cannot create receive thread"), pDrvIns->iInstance);
     585        return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("HostSerial#%d cannot create receive thread"), pDrvIns->iInstance);
    443586
    444587    rc = RTSemEventCreate(&pData->SendSem);
    445588    AssertRC(rc);
    446589
    447     rc = RTThreadCreate(&pData->SendThread, drvHostSerialSendLoop, (void *)pData, 0, RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "Char Send");
     590    rc = RTThreadCreate(&pData->SendThread, drvHostSerialSendLoop, (void *)pData, 0, RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "Serial Send");
    448591    if (VBOX_FAILURE(rc))
    449         return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("Char#%d cannot create send thread"), pDrvIns->iInstance);
    450 
    451 
    452     PDMDrvHlpSTAMRegisterF(pDrvIns, &pData->StatBytesWritten,    STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_BYTES, "Nr of bytes written",         "/Devices/Char%d/Written", pDrvIns->iInstance);
    453     PDMDrvHlpSTAMRegisterF(pDrvIns, &pData->StatBytesRead,       STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_BYTES, "Nr of bytes read",            "/Devices/Char%d/Read", pDrvIns->iInstance);
     592        return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("HostSerial#%d cannot create send thread"), pDrvIns->iInstance);
     593 
     594 
     595    PDMDrvHlpSTAMRegisterF(pDrvIns, &pData->StatBytesWritten,    STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_BYTES, "Nr of bytes written",         "/Devices/HostSerial%d/Written", pDrvIns->iInstance);
     596    PDMDrvHlpSTAMRegisterF(pDrvIns, &pData->StatBytesRead,       STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_BYTES, "Nr of bytes read",            "/Devices/HostSerial%d/Read", pDrvIns->iInstance);
    454597
    455598    return VINF_SUCCESS;
     
    476619        RTThreadWait(pData->ReceiveThread, 1000, NULL);
    477620        if (pData->ReceiveThread != NIL_RTTHREAD)
    478             LogRel(("Char%d: receive thread did not terminate\n", pDrvIns->iInstance));
     621            LogRel(("HostSerial%d: receive thread did not terminate\n", pDrvIns->iInstance));
    479622    }
    480623
     
    490633        RTThreadWait(pData->SendThread, 1000, NULL);
    491634        if (pData->SendThread != NIL_RTTHREAD)
    492             LogRel(("Char%d: send thread did not terminate\n", pDrvIns->iInstance));
     635            LogRel(("HostSerial%d: send thread did not terminate\n", pDrvIns->iInstance));
    493636    }
    494637}
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette