VBoxPci.c revision 36e44a1ca13ffd4e286f0cd7e7d730c697e2fbeb
/* $Id $ */
/** @file
* VBoxPci - PCI card passthrough support (Host), Common Code.
*/
/*
* Copyright (C) 2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
/** @page pg_rawpci VBoxPci - host PCI support
*
* This is a kernel module that works as host proxy between guest and
* PCI hardware.
*
*/
#define LOG_GROUP LOG_GROUP_DEV_PCI_RAW
#include <iprt/spinlock.h>
#include "VBoxPciInternal.h"
#define DEVPORT_2_VBOXRAWPCIINS(pPort) \
/**
* Implements the SUPDRV component factor interface query method.
*
* @returns Pointer to an interface. NULL if not supported.
*
* @param pSupDrvFactory Pointer to the component factory registration structure.
* @param pSession The session - unused.
* @param pszInterfaceUuid The factory interface id.
*/
static DECLCALLBACK(void *) vboxPciQueryFactoryInterface(PCSUPDRVFACTORY pSupDrvFactory, PSUPDRVSESSION pSession, const char *pszInterfaceUuid)
{
PVBOXRAWPCIGLOBALS pGlobals = (PVBOXRAWPCIGLOBALS)((uint8_t *)pSupDrvFactory - RT_OFFSETOF(VBOXRAWPCIGLOBALS, SupDrvFactory));
/*
* Convert the UUID strings and compare them.
*/
if (RT_SUCCESS(rc))
{
{
return &pGlobals->RawPciFactory;
}
}
else
return NULL;
}
{
return rc;
}
{
}
{
return rc;
}
{
}
{
return rc;
}
{
}
{
{
return pCur;
}
return NULL;
}
{
else
{
{
{
break;
}
}
}
}
{
{
}
{
}
}
/**
* @copydoc RAWPCIDEVPORT:: pfnInit
*/
{
int rc;
return rc;
}
/**
* @copydoc RAWPCIDEVPORT:: pfnDeinit
*/
{
int rc;
/* Bit racy, better check under lock. */
{
}
return rc;
}
/**
* @copydoc RAWPCIDEVPORT:: pfnDestroy
*/
{
int rc;
if (rc == VINF_SUCCESS)
{
{
}
{
}
}
return rc;
}
/**
* @copydoc RAWPCIDEVPORT:: pfnGetRegionInfo
*/
bool *pfPresent,
{
int rc;
return rc;
}
/**
* @copydoc RAWPCIDEVPORT:: pfnMapRegion
*/
{
int rc;
return rc;
}
/**
* @copydoc RAWPCIDEVPORT:: pfnUnapRegion
*/
{
int rc;
return rc;
}
/**
* @copydoc RAWPCIDEVPORT:: pfnPciCfgRead
*/
{
int rc;
return rc;
}
/**
* @copydoc RAWPCIDEVPORT:: pfnPciCfgWrite
*/
DECLHIDDEN(int) vboxPciDevPciCfgWrite(PRAWPCIDEVPORT pPort, uint32_t Register, PCIRAWMEMLOC *pValue)
{
int rc;
return rc;
}
DECLHIDDEN(int) vboxPciDevRegisterIrqHandler(PRAWPCIDEVPORT pPort, PFNRAWPCIISR pfnHandler, void* pIrqContext, int32_t *piHostIrq)
{
int rc;
if (RT_FAILURE(rc))
{
*piHostIrq = -1;
}
else
return rc;
}
{
int rc;
if (RT_SUCCESS(rc))
{
}
return rc;
}
{
int rc;
return rc;
}
/**
* Creates a new instance.
*
* @returns VBox status code.
* @param pGlobals The globals.
* @param pszName The instance name.
* @param ppDevPort Where to store the pointer to our port interface.
*/
{
int rc;
if (!pNew)
return VERR_NO_MEMORY;
if (RT_SUCCESS(rc))
{
if (RT_SUCCESS(rc))
{
if (RT_SUCCESS(rc))
{
}
else
{
}
return rc;
}
}
return rc;
}
/**
* @copydoc RAWPCIFACTORY::pfnCreateAndConnect
*/
{
PVBOXRAWPCIGLOBALS pGlobals = (PVBOXRAWPCIGLOBALS)((uint8_t *)pFactory - RT_OFFSETOF(VBOXRAWPCIGLOBALS, RawPciFactory));
int rc;
/* First search if there's no existing instance with same host device
* address - if so - we cannot continue.
*/
{
goto unlock;
}
return rc;
}
/**
* @copydoc RAWPCIFACTORY::pfnRelease
*/
{
PVBOXRAWPCIGLOBALS pGlobals = (PVBOXRAWPCIGLOBALS)((uint8_t *)pFactory - RT_OFFSETOF(VBOXRAWPCIGLOBALS, RawPciFactory));
}
/**
* @copydoc RAWPCIFACTORY::pfnInitVm
*/
{
int rc;
if (!pThis)
return VERR_NO_MEMORY;
if (RT_SUCCESS(rc))
{
if (RT_SUCCESS(rc))
{
return VINF_SUCCESS;
}
}
return rc;
}
/**
* @copydoc RAWPCIFACTORY::pfnDeinitVm
*/
{
if (pPciData->pDriverData)
{
{
}
}
}
{
&& pGlobals->cFactoryRefs <= 0;
return fRc;
}
{
int rc;
/*
* Establish a connection to SUPDRV and register our component factory.
*/
rc = SUPR0IdcOpen(&pGlobals->SupDrvIDC, 0 /* iReqVersion = default */, 0 /* iMinVersion = default */, NULL, NULL, NULL);
if (RT_SUCCESS(rc))
{
if (RT_SUCCESS(rc))
{
return rc;
}
/* bail out. */
}
return rc;
}
/**
* Try to close the IDC connection to SUPDRV if established.
*
* @returns VBox status code.
* @retval VINF_SUCCESS on success.
* @retval VERR_WRONG_ORDER if we're busy.
*
* @param pGlobals Pointer to the globals.
*/
{
int rc;
/*
* Check before trying to deregister the factory.
*/
if (!vboxPciCanUnload(pGlobals))
return VERR_WRONG_ORDER;
rc = VINF_SUCCESS;
else
{
/*
* Disconnect from SUPDRV.
*/
}
return rc;
}
/**
* Initializes the globals.
*
* @returns VBox status code.
* @param pGlobals Pointer to the globals.
*/
{
/*
* Initialize the common portions of the structure.
*/
if (RT_SUCCESS(rc))
{
}
return rc;
}
/**
* Deletes the globals.
*
*
* @param pGlobals Pointer to the globals.
*/
{
/*
* Release resources.
*/
{
}
}
{
/*
* Initialize the common portions of the structure.
*/
if (RT_SUCCESS(rc))
{
if (RT_SUCCESS(rc))
return rc;
/* bail out. */
}
return rc;
}
{
if (RT_SUCCESS(rc))
}