VirtualBox

儲存庫 vbox 的更動 62620


忽略:
時間撮記:
2016-7-28 下午02:38:36 (8 年 以前)
作者:
vboxsync
訊息:

DrvHostParallel: Ring-0 needs to check whether ports are configured before using them. Use a buffer to do data reads and writes so we'll spend less time context switching between user and kernel mode.

檔案:
修改 1 筆資料

圖例:

未更動
新增
刪除
  • trunk/src/VBox/Devices/Parallel/DrvHostParallel.cpp

    r62619 r62620  
    117117    /** Control register.  */
    118118    RTIOPORT                    PortDirectControl;
    119     /** Data read result buffer. */
    120     uint8_t                     bReadIn;
    121119    /** Control read result buffer. */
    122120    uint8_t                     bReadInControl;
    123121    /** Status read result buffer. */
    124122    uint8_t                     bReadInStatus;
     123    /** Data buffer for reads and writes. */
     124    uint8_t                     abDataBuf[32];
    125125#endif /* VBOX_WITH_WIN_PARPORT_SUP */
    126126} DRVHOSTPARALLEL, *PDRVHOSTPARALLEL;
     
    136136    /** Perform R0 initialization. */
    137137    DRVHOSTPARALLELR0OP_INITR0STUFF,
    138     /** Read data. */
     138    /** Read data into the data buffer (abDataBuf). */
    139139    DRVHOSTPARALLELR0OP_READ,
    140140    /** Read status register. */
     
    142142    /** Read control register. */
    143143    DRVHOSTPARALLELR0OP_READCONTROL,
    144     /** Write data. */
     144    /** Write data from the data buffer (abDataBuf). */
    145145    DRVHOSTPARALLELR0OP_WRITE,
    146146    /** Write control register. */
     
    170170 *
    171171 * @returns VBox status code.
    172  * @param   pDrvIns    Driver instance.
    173  * @param   u64Arg     Data to be written to data register.
    174  *
    175  */
    176 static int drvR0HostParallelReqWrite(PPDMDRVINS pDrvIns, uint64_t u64Arg)
    177 {
    178     PDRVHOSTPARALLEL pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTPARALLEL);
    179     LogFlowFunc(("write to data port=%#x val=%#x\n", pThis->PortDirectData, u64Arg));
    180     ASMOutU8(pThis->PortDirectData, (uint8_t)(u64Arg));
     172 * @param   pThis       Pointer to the instance data.
     173 * @param   u64Arg      The number of bytes to write (from abDataBuf).
     174 */
     175static int drvR0HostParallelReqWrite(PDRVHOSTPARALLEL pThis, uint64_t u64Arg)
     176{
     177    LogFlowFunc(("write %#RX64 bytes to data (%#x)\n", u64Arg, pThis->PortDirectData));
     178
     179    AssertReturn(u64Arg > 0 && u64Arg <= sizeof(pThis->abDataBuf), VERR_OUT_OF_RANGE);
     180    uint8_t const *pbSrc = pThis->abDataBuf;
     181    while (u64Arg-- > 0)
     182    {
     183        ASMOutU8(pThis->PortDirectData, *pbSrc);
     184        pbSrc++;
     185    }
     186
    181187    return VINF_SUCCESS;
    182188}
     
    186192 *
    187193 * @returns VBox status code.
    188  * @param   pDrvIns     Driver instance.
     194 * @param   pThis       Pointer to the instance data.
    189195 * @param   u64Arg      Data to be written to control register.
    190196 */
    191 static int drvR0HostParallelReqWriteControl(PPDMDRVINS pDrvIns, uint64_t u64Arg)
    192 {
    193     PDRVHOSTPARALLEL pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTPARALLEL);
     197static int drvR0HostParallelReqWriteControl(PDRVHOSTPARALLEL pThis, uint64_t u64Arg)
     198{
    194199    LogFlowFunc(("write to ctrl port=%#x val=%#x\n", pThis->PortDirectControl, u64Arg));
    195200    ASMOutU8(pThis->PortDirectControl, (uint8_t)(u64Arg));
     
    201206 *
    202207 * @returns VBox status code.
    203  * @param   pDrvIns    Driver instance.
    204  */
    205 static int drvR0HostParallelReqRead(PPDMDRVINS pDrvIns)
    206 {
    207     PDRVHOSTPARALLEL pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTPARALLEL);
    208     uint8_t u8Data = ASMInU8(pThis->PortDirectData);
    209     LogFlowFunc(("read from data port=%#x val=%#x\n", pThis->PortDirectData, u8Data));
    210     pThis->bReadIn = u8Data;
     208 * @param   pThis       Pointer to the instance data.
     209 * @param   u64Arg      The number of bytes to read into abDataBuf.
     210 */
     211static int drvR0HostParallelReqRead(PDRVHOSTPARALLEL pThis, uint64_t u64Arg)
     212{
     213    LogFlowFunc(("read %#RX64 bytes to data (%#x)\n", u64Arg, pThis->PortDirectData));
     214
     215    AssertReturn(u64Arg > 0 && u64Arg <= sizeof(pThis->abDataBuf), VERR_OUT_OF_RANGE);
     216    uint8_t *pbDst = pThis->abDataBuf;
     217    while (u64Arg-- > 0)
     218        *pbDst++ = ASMInU8(pThis->PortDirectData);
     219
    211220    return VINF_SUCCESS;
    212221}
     
    216225 *
    217226 * @returns VBox status code.
    218  * @param   pDrvIns    Driver instance.
    219  */
    220 static int drvR0HostParallelReqReadControl(PPDMDRVINS pDrvIns)
    221 {
    222     PDRVHOSTPARALLEL pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTPARALLEL);
     227 * @param   pThis       Pointer to the instance data.
     228 */
     229static int drvR0HostParallelReqReadControl(PDRVHOSTPARALLEL pThis)
     230{
    223231    uint8_t u8Data = ASMInU8(pThis->PortDirectControl);
    224232    LogFlowFunc(("read from ctrl port=%#x val=%#x\n", pThis->PortDirectControl, u8Data));
     
    231239 *
    232240 * @returns VBox status code.
    233  * @param   pDrvIns    Driver instance.
    234  */
    235 static int drvR0HostParallelReqReadStatus(PPDMDRVINS pDrvIns)
    236 {
    237     PDRVHOSTPARALLEL pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTPARALLEL);
     241 * @param   pThis       Pointer to the instance data.
     242 */
     243static int drvR0HostParallelReqReadStatus(PDRVHOSTPARALLEL pThis)
     244{
    238245    uint8_t u8Data = ASMInU8(pThis->PortDirectStatus);
    239246    LogFlowFunc(("read from status port=%#x val=%#x\n", pThis->PortDirectStatus, u8Data));
     
    247254 *
    248255 * @returns VBox status code.
    249  * @param   pDrvIns    Driver instance.
    250  * @param   u64Arg     Mode.
    251  */
    252 static int drvR0HostParallelReqSetPortDir(PPDMDRVINS pDrvIns, uint64_t u64Arg)
    253 {
    254     PDRVHOSTPARALLEL pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTPARALLEL);
    255 
     256 * @param   pThis       Pointer to the instance data.
     257 * @param   u64Arg      Mode.
     258 */
     259static int drvR0HostParallelReqSetPortDir(PDRVHOSTPARALLEL pThis, uint64_t u64Arg)
     260{
    256261    uint8_t bCtl = ASMInU8(pThis->PortDirectControl);
    257262    if (u64Arg)
     
    269274PDMBOTHCBDECL(int) drvR0HostParallelReqHandler(PPDMDRVINS pDrvIns, uint32_t uOperation, uint64_t u64Arg)
    270275{
     276    PDRVHOSTPARALLEL pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTPARALLEL);
    271277    int rc;
    272 
    273278    LogFlowFuncEnter();
    274     switch ((DRVHOSTPARALLELR0OP)uOperation)
    275     {
    276         case DRVHOSTPARALLELR0OP_READ:
    277             rc = drvR0HostParallelReqRead(pDrvIns);
    278             break;
    279         case DRVHOSTPARALLELR0OP_READSTATUS:
    280             rc = drvR0HostParallelReqReadStatus(pDrvIns);
    281             break;
    282         case DRVHOSTPARALLELR0OP_READCONTROL:
    283             rc = drvR0HostParallelReqReadControl(pDrvIns);
    284             break;
    285         case DRVHOSTPARALLELR0OP_WRITE:
    286             rc = drvR0HostParallelReqWrite(pDrvIns, u64Arg);
    287             break;
    288         case DRVHOSTPARALLELR0OP_WRITECONTROL:
    289             rc = drvR0HostParallelReqWriteControl(pDrvIns, u64Arg);
    290             break;
    291         case DRVHOSTPARALLELR0OP_SETPORTDIRECTION:
    292             rc = drvR0HostParallelReqSetPortDir(pDrvIns, u64Arg);
    293             break;
    294         default:        /* not supported */
    295             rc = VERR_NOT_SUPPORTED;
    296     }
    297     LogFlowFuncLeave();
     279
     280    if (pThis->PortDirectData != 0)
     281    {
     282        switch ((DRVHOSTPARALLELR0OP)uOperation)
     283        {
     284            case DRVHOSTPARALLELR0OP_READ:
     285                rc = drvR0HostParallelReqRead(pThis, u64Arg);
     286                break;
     287            case DRVHOSTPARALLELR0OP_READSTATUS:
     288                rc = drvR0HostParallelReqReadStatus(pThis);
     289                break;
     290            case DRVHOSTPARALLELR0OP_READCONTROL:
     291                rc = drvR0HostParallelReqReadControl(pThis);
     292                break;
     293            case DRVHOSTPARALLELR0OP_WRITE:
     294                rc = drvR0HostParallelReqWrite(pThis, u64Arg);
     295                break;
     296            case DRVHOSTPARALLELR0OP_WRITECONTROL:
     297                rc = drvR0HostParallelReqWriteControl(pThis, u64Arg);
     298                break;
     299            case DRVHOSTPARALLELR0OP_SETPORTDIRECTION:
     300                rc = drvR0HostParallelReqSetPortDir(pThis, u64Arg);
     301                break;
     302            default:
     303                rc = VERR_INVALID_FUNCTION;
     304                break;
     305        }
     306    }
     307    else
     308        rc = VERR_WRONG_ORDER;
     309
     310    LogFlowFuncLeaveRC(rc);
    298311    return rc;
    299312}
     
    576589 * @interface_method_impl{PDMIHOSTPARALLELCONNECTOR,pfnWrite}
    577590 */
    578 static DECLCALLBACK(int) drvHostParallelWrite(PPDMIHOSTPARALLELCONNECTOR pInterface, const void *pvBuf, size_t cbWrite, PDMPARALLELPORTMODE enmMode)
     591static DECLCALLBACK(int) drvHostParallelWrite(PPDMIHOSTPARALLELCONNECTOR pInterface, const void *pvBuf, size_t cbWrite,
     592                                              PDMPARALLELPORTMODE enmMode)
    579593{
    580594    PPDMDRVINS          pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
     
    602616    if (RT_UNLIKELY(rcLnx < 0))
    603617        rc = RTErrConvertFromErrno(errno);
     618
    604619# else /* VBOX_WITH_WIN_PARPORT_SUP */
    605620    if (pThis->PortDirectData != 0)
    606621    {
    607         for (size_t i = 0; i < cbWrite; i++)
     622        while (cbWrite > 0)
    608623        {
    609             uint64_t u64Data = (uint8_t) *((uint8_t *)(pvBuf) + i);
    610             LogFlowFunc(("calling R0 to write to parallel port, data=%#x\n", u64Data));
    611             rc = PDMDrvHlpCallR0(pThis->CTX_SUFF(pDrvIns), DRVHOSTPARALLELR0OP_WRITE, u64Data);
     624            size_t cbToWrite = RT_MIN(cbWrite, sizeof(pThis->abDataBuf));
     625            LogFlowFunc(("Calling R0 to write %#zu bytes of data\n", cbToWrite));
     626            memcpy(pThis->abDataBuf, pvBuf, cbToWrite);
     627            rc = PDMDrvHlpCallR0(pThis->CTX_SUFF(pDrvIns), DRVHOSTPARALLELR0OP_WRITE, cbToWrite);
    612628            AssertRC(rc);
     629            pvBuf = (uint8_t const *)pvBuf + cbToWrite;
     630            cbWrite -= cbToWrite;
    613631        }
    614632    }
     
    620638 * @interface_method_impl{PDMIHOSTPARALLELCONNECTOR,pfnRead}
    621639 */
    622 static DECLCALLBACK(int) drvHostParallelRead(PPDMIHOSTPARALLELCONNECTOR pInterface, void *pvBuf, size_t cbRead, PDMPARALLELPORTMODE enmMode)
     640static DECLCALLBACK(int) drvHostParallelRead(PPDMIHOSTPARALLELCONNECTOR pInterface, void *pvBuf, size_t cbRead,
     641                                             PDMPARALLELPORTMODE enmMode)
    623642{
    624643    PDRVHOSTPARALLEL    pThis   = RT_FROM_MEMBER(pInterface, DRVHOSTPARALLEL, CTX_SUFF(IHostParallelConnector));
     
    645664    if (RT_UNLIKELY(rcLnx < 0))
    646665        rc = RTErrConvertFromErrno(errno);
     666
    647667# else  /* VBOX_WITH_WIN_PARPORT_SUP */
    648668    if (pThis->PortDirectData != 0)
    649669    {
    650         uint8_t *pabBuf = (uint8_t *)pvBuf;
    651         memset(pabBuf, 0, cbRead);
    652         for (size_t i = 0; i < cbRead; i++)
     670        while (cbRead > 0)
    653671        {
    654             LogFlowFunc(("calling R0 to read from parallel port\n"));
    655             int rc = PDMDrvHlpCallR0(pThis->CTX_SUFF(pDrvIns), DRVHOSTPARALLELR0OP_READ, 0);
     672            size_t cbToRead = RT_MIN(cbRead, sizeof(pThis->abDataBuf));
     673            LogFlowFunc(("Calling R0 to read %#zu bytes of data\n", cbToRead));
     674            memset(pThis->abDataBuf, 0, cbToRead);
     675            rc = PDMDrvHlpCallR0(pThis->CTX_SUFF(pDrvIns), DRVHOSTPARALLELR0OP_READ, cbToRead);
    656676            AssertRC(rc);
    657             pabBuf[i] = (uint8_t)pThis->bReadIn;
     677            memcpy(pvBuf, pThis->abDataBuf, cbToRead);
     678            pvBuf   = (uint8_t *)pvBuf + cbToRead;
     679            cbRead -= cbToRead;
    658680        }
    659681    }
注意: 瀏覽 TracChangeset 來幫助您使用更動檢視器

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