DrvHostParallel.cpp revision cba6719bd64ec749967bbe931230452664109857
45e9809aff7304721fddb95654901b32195c9c7avboxsync * VirtualBox Host Parallel Port Driver.
45e9809aff7304721fddb95654901b32195c9c7avboxsync * Contributed by: Alexander Eichner
45e9809aff7304721fddb95654901b32195c9c7avboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
45e9809aff7304721fddb95654901b32195c9c7avboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
45e9809aff7304721fddb95654901b32195c9c7avboxsync * available from http://www.virtualbox.org. This file is free software;
45e9809aff7304721fddb95654901b32195c9c7avboxsync * you can redistribute it and/or modify it under the terms of the GNU
45e9809aff7304721fddb95654901b32195c9c7avboxsync * General Public License (GPL) as published by the Free Software
45e9809aff7304721fddb95654901b32195c9c7avboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
45e9809aff7304721fddb95654901b32195c9c7avboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
45e9809aff7304721fddb95654901b32195c9c7avboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
45e9809aff7304721fddb95654901b32195c9c7avboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
45e9809aff7304721fddb95654901b32195c9c7avboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
45e9809aff7304721fddb95654901b32195c9c7avboxsync * additional information or have any questions.
45e9809aff7304721fddb95654901b32195c9c7avboxsync/*******************************************************************************
45e9809aff7304721fddb95654901b32195c9c7avboxsync* Header Files *
45e9809aff7304721fddb95654901b32195c9c7avboxsync*******************************************************************************/
45e9809aff7304721fddb95654901b32195c9c7avboxsync/*******************************************************************************
45e9809aff7304721fddb95654901b32195c9c7avboxsync* Structures and Typedefs *
45e9809aff7304721fddb95654901b32195c9c7avboxsync*******************************************************************************/
45e9809aff7304721fddb95654901b32195c9c7avboxsync * Host parallel port driver instance data.
45e9809aff7304721fddb95654901b32195c9c7avboxsync /** Pointer to the driver instance structure. */
45e9809aff7304721fddb95654901b32195c9c7avboxsync /** Pointer to the char port interface of the driver/device above us. */
45e9809aff7304721fddb95654901b32195c9c7avboxsync /** Our host device interface. */
45e9809aff7304721fddb95654901b32195c9c7avboxsync /** Our host device port interface. */
45e9809aff7304721fddb95654901b32195c9c7avboxsync /** Device Path */
45e9809aff7304721fddb95654901b32195c9c7avboxsync /** Device Handle */
45e9809aff7304721fddb95654901b32195c9c7avboxsync /** Thread waiting for interrupts. */
45e9809aff7304721fddb95654901b32195c9c7avboxsync /** Wakeup pipe read end. */
45e9809aff7304721fddb95654901b32195c9c7avboxsync /** Wakeup pipe write end. */
45e9809aff7304721fddb95654901b32195c9c7avboxsync/** Converts a pointer to DRVHOSTPARALLEL::IHostDeviceConnector to a PDRHOSTPARALLEL. */
45e9809aff7304721fddb95654901b32195c9c7avboxsync#define PDMIHOSTPARALLELCONNECTOR_2_DRVHOSTPARALLEL(pInterface) ( (PDRVHOSTPARALLEL)((uintptr_t)pInterface - RT_OFFSETOF(DRVHOSTPARALLEL, IHostParallelConnector)) )
45e9809aff7304721fddb95654901b32195c9c7avboxsync/** Converts a pointer to DRVHOSTPARALLEL::IHostDevicePort to a PDRHOSTPARALLEL. */
45e9809aff7304721fddb95654901b32195c9c7avboxsync#define PDMIHOSTPARALLELPORT_2_DRVHOSTPARALLEL(pInterface) ( (PDRVHOSTPARALLEL)((uintptr_t)pInterface - RT_OFFSETOF(DRVHOSTPARALLEL, IHostParallelPort)) )
45e9809aff7304721fddb95654901b32195c9c7avboxsync/* -=-=-=-=- IBase -=-=-=-=- */
45e9809aff7304721fddb95654901b32195c9c7avboxsync * Queries an interface to the driver.
45e9809aff7304721fddb95654901b32195c9c7avboxsync * @returns Pointer to interface.
45e9809aff7304721fddb95654901b32195c9c7avboxsync * @returns NULL if the interface was not supported by the driver.
45e9809aff7304721fddb95654901b32195c9c7avboxsync * @param pInterface Pointer to this interface structure.
45e9809aff7304721fddb95654901b32195c9c7avboxsync * @param enmInterface The requested interface identification.
45e9809aff7304721fddb95654901b32195c9c7avboxsyncstatic DECLCALLBACK(void *) drvHostParallelQueryInterface(PPDMIBASE pInterface, PDMINTERFACE enmInterface)
45e9809aff7304721fddb95654901b32195c9c7avboxsync PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
45e9809aff7304721fddb95654901b32195c9c7avboxsync PDRVHOSTPARALLEL pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTPARALLEL);
45e9809aff7304721fddb95654901b32195c9c7avboxsync/* -=-=-=-=- IHostDeviceConnector -=-=-=-=- */
45e9809aff7304721fddb95654901b32195c9c7avboxsync/** @copydoc PDMICHAR::pfnWrite */
45e9809aff7304721fddb95654901b32195c9c7avboxsyncstatic DECLCALLBACK(int) drvHostParallelWrite(PPDMIHOSTPARALLELCONNECTOR pInterface, const void *pvBuf, size_t *cbWrite)
45e9809aff7304721fddb95654901b32195c9c7avboxsync PDRVHOSTPARALLEL pThis = PDMIHOSTPARALLELCONNECTOR_2_DRVHOSTPARALLEL(pInterface);
45e9809aff7304721fddb95654901b32195c9c7avboxsync const unsigned char *pBuffer = (const unsigned char *)pvBuf;
45e9809aff7304721fddb95654901b32195c9c7avboxsync LogFlow(("%s: pvBuf=%#p cbWrite=%d\n", __FUNCTION__, pvBuf, *cbWrite));
45e9809aff7304721fddb95654901b32195c9c7avboxsyncstatic DECLCALLBACK(int) drvHostParallelRead(PPDMIHOSTPARALLELCONNECTOR pInterface, void *pvBuf, size_t *cbRead)
45e9809aff7304721fddb95654901b32195c9c7avboxsync PDRVHOSTPARALLEL pThis = PDMIHOSTPARALLELCONNECTOR_2_DRVHOSTPARALLEL(pInterface);
45e9809aff7304721fddb95654901b32195c9c7avboxsync LogFlow(("%s: pvBuf=%#p cbRead=%d\n", __FUNCTION__, pvBuf, cbRead));
45e9809aff7304721fddb95654901b32195c9c7avboxsyncstatic DECLCALLBACK(int) drvHostParallelSetMode(PPDMIHOSTPARALLELCONNECTOR pInterface, PDMPARALLELPORTMODE enmMode)
45e9809aff7304721fddb95654901b32195c9c7avboxsync PDRVHOSTPARALLEL pThis = PDMIHOSTPARALLELCONNECTOR_2_DRVHOSTPARALLEL(pInterface);
45e9809aff7304721fddb95654901b32195c9c7avboxsync //ppdev_mode = IEEE1284_MODE_ECP;
45e9809aff7304721fddb95654901b32195c9c7avboxsyncstatic DECLCALLBACK(int) drvHostParallelWriteControl(PPDMIHOSTPARALLELCONNECTOR pInterface, uint8_t fReg)
45e9809aff7304721fddb95654901b32195c9c7avboxsync PDRVHOSTPARALLEL pThis = PDMIHOSTPARALLELCONNECTOR_2_DRVHOSTPARALLEL(pInterface);
45e9809aff7304721fddb95654901b32195c9c7avboxsyncstatic DECLCALLBACK(int) drvHostParallelReadControl(PPDMIHOSTPARALLELCONNECTOR pInterface, uint8_t *pfReg)
45e9809aff7304721fddb95654901b32195c9c7avboxsync PDRVHOSTPARALLEL pThis = PDMIHOSTPARALLELCONNECTOR_2_DRVHOSTPARALLEL(pInterface);
45e9809aff7304721fddb95654901b32195c9c7avboxsyncstatic DECLCALLBACK(int) drvHostParallelReadStatus(PPDMIHOSTPARALLELCONNECTOR pInterface, uint8_t *pfReg)
45e9809aff7304721fddb95654901b32195c9c7avboxsync PDRVHOSTPARALLEL pThis = PDMIHOSTPARALLELCONNECTOR_2_DRVHOSTPARALLEL(pInterface);
45e9809aff7304721fddb95654901b32195c9c7avboxsyncstatic DECLCALLBACK(int) drvHostParallelMonitorThread(PPDMDRVINS pDrvIns, PPDMTHREAD pThread)
45e9809aff7304721fddb95654901b32195c9c7avboxsync PDRVHOSTPARALLEL pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTPARALLEL);
45e9809aff7304721fddb95654901b32195c9c7avboxsync * We can wait for interrupts using poll on linux hosts.
45e9809aff7304721fddb95654901b32195c9c7avboxsync while (pThread->enmState == PDMTHREADSTATE_RUNNING)
45e9809aff7304721fddb95654901b32195c9c7avboxsync AssertMsgFailed(("poll failed with rc=%d\n", RTErrConvertFromErrno(errno)));
45e9809aff7304721fddb95654901b32195c9c7avboxsync if (aFDs[1].revents & (POLLHUP | POLLERR | POLLNVAL))
45e9809aff7304721fddb95654901b32195c9c7avboxsync /* notification to terminate -- drain the pipe */
return VINF_SUCCESS;
static DECLCALLBACK(int) drvHostParallelConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfgHandle, uint32_t fFlags)
return rc;
if (rc < 0)
if (rc < 0)
pThis->pDrvHostParallelPort = (PPDMIHOSTPARALLELPORT)pDrvIns->pUpBase->pfnQueryInterface(pDrvIns->pUpBase, PDMINTERFACE_HOST_PARALLEL_PORT);
return PDMDrvHlpVMSetError(pDrvIns, VERR_PDM_MISSING_INTERFACE_ABOVE, RT_SRC_POS, N_("Parallel#%d has no parallel port interface above"),
return rc;
rc = PDMDrvHlpPDMThreadCreate(pDrvIns, &pThis->pMonitorThread, pThis, drvHostParallelMonitorThread, drvHostParallelWakeupMonitorThread, 0,
return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("HostParallel#%d cannot create monitor thread"), pDrvIns->iInstance);
return VINF_SUCCESS;
sizeof(DRVHOSTPARALLEL),
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,