VirtualBox

Changeset 4236

Show
Ignore:
Timestamp:
08/20/07 10:56:32 (1 year ago)
Author:
vboxsync
Message:

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

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • 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} 

© 2008 Sun Microsystems, Inc.
ContactPrivacy policy