VirtualBox

Changeset 35946 in vbox


Ignore:
Timestamp:
Feb 11, 2011 5:58:30 PM (14 years ago)
Author:
vboxsync
Message:

VMM, host drivers: IDC work for PCI

Location:
trunk
Files:
3 edited

Legend:

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

    r35920 r35946  
    189189} PCIRAWR0OPERATION;
    190190
     191/** Forward declarations. */
     192typedef struct RAWPCIFACTORY *PRAWPCIFACTORY;
     193typedef struct RAWPCIDEVPORT *PRAWPCIDEVPORT;
     194
     195/**
     196 * This is the port on the device interface, i.e. the driver side which the
     197 * host device is connected to.
     198 *
     199 * This is only used for the in-kernel PCI device connections.
     200 */
     201typedef struct RAWPCIDEVPORT
     202{
     203    /** Structure version number. (RAWPCIDEVPORT_VERSION) */
     204    uint32_t u32Version;
     205
     206    /**
     207     * Retain the object.
     208     *
     209     * It will normally be called while owning the internal semaphore.
     210     *
     211     * @param   pPort     Pointer to this structure.
     212     */
     213    DECLR0CALLBACKMEMBER(void, pfnRetain,(PRAWPCIDEVPORT pPort));
     214
     215    /**
     216     * Releases the object.
     217     *
     218     * This must be called for every pfnRetain call.
     219     *
     220     *
     221     * @param   pPort     Pointer to this structure.
     222     */
     223    DECLR0CALLBACKMEMBER(void, pfnRelease,(PRAWPCIDEVPORT pPort));
     224   
     225    /** Structure version number. (RAWPCIDEVPORT_VERSION) */
     226    uint32_t u32VersionEnd;
     227} RAWPCIDEVPORT;
     228/** Version number for the RAWPCIDEVPORT::u32Version and RAWPCIIFPORT::u32VersionEnd fields. */
     229#define RAWPCIDEVPORT_VERSION   UINT32_C(0xAFBDCC01)
     230
     231/**
     232 * The component factory interface for create a raw PCI interfaces.
     233 */
     234typedef struct RAWPCIFACTORY
     235{
     236    /**
     237     * Release this factory.
     238     *
     239     * SUPR0ComponentQueryFactory (SUPDRVFACTORY::pfnQueryFactoryInterface to be precise)
     240     * will retain a reference to the factory and the caller has to call this method to
     241     * release it once the pfnCreateAndConnect call(s) has been done.
     242     *
     243     * @param   pIfFactory          Pointer to this structure.
     244     */
     245    DECLR0CALLBACKMEMBER(void, pfnRelease,(PRAWPCIFACTORY pFactory));
     246
     247    /**
     248     * Create an instance for the specfied host PCI card and connects it
     249     * to the driver.
     250     *
     251     *
     252     * @returns VBox status code.
     253     *
     254     * @param   pIfFactory          Pointer to this structure.
     255     * @param   u32HostAddress      Address of PCI device on the host.
     256     * @param   fFlags              Creation flags.
     257     * @param   ppDevPort           Where to store the pointer to the device port
     258     *                              on success.
     259     *
     260     */
     261    DECLR0CALLBACKMEMBER(int, pfnCreateAndConnect,(PRAWPCIFACTORY       pFactory,
     262                                                   uint32_t             u32HostAddress,
     263                                                   uint32_t             fFlags,
     264                                                   PRAWPCIDEVPORT       *ppDevPort));
     265
     266
     267} RAWPCIFACTORY;
     268
     269
     270#define RAWPCIFACTORY_UUID_STR "c0268f49-e1e4-402b-b7e0-eb8d09659a9b"
     271
    191272RT_C_DECLS_END
    192273
  • trunk/src/VBox/HostDrivers/VBoxPci/VBoxPci.c

    r35920 r35946  
    1818/** @page pg_rawpci     VBoxPci - host PCI support
    1919 *
    20  * This is a kernel module that works as host proxy between guest and 
     20 * This is a kernel module that works as host proxy between guest and
    2121 * PCI hardware.
    2222 *
    2323 */
    2424
    25 #define LOG_GROUP LOG_GROUP_PCI_RAW
    26 #include "VBoxPciInternal.h"
    27 
     25#define LOG_GROUP LOG_GROUP_DEV_PCI_RAW
    2826#include <VBox/log.h>
    2927#include <VBox/err.h>
     28#include <VBox/sup.h>
     29#include <VBox/version.h>
     30
    3031#include <iprt/string.h>
    31 
    32 #include <VBox/sup.h>
    3332#include <iprt/assert.h>
    3433#include <iprt/spinlock.h>
    3534#include <iprt/uuid.h>
    36 #include <VBox/version.h>
    37 
     35#include <iprt/asm.h>
     36#include <iprt/mem.h>
     37
     38#include "VBoxPciInternal.h"
     39
     40
     41/**
     42 * Implements the SUPDRV component factor interface query method.
     43 *
     44 * @returns Pointer to an interface. NULL if not supported.
     45 *
     46 * @param   pSupDrvFactory      Pointer to the component factory registration structure.
     47 * @param   pSession            The session - unused.
     48 * @param   pszInterfaceUuid    The factory interface id.
     49 */
     50static DECLCALLBACK(void *) vboxPciQueryFactoryInterface(PCSUPDRVFACTORY pSupDrvFactory, PSUPDRVSESSION pSession, const char *pszInterfaceUuid)
     51{
     52    PVBOXRAWPCIGLOBALS pGlobals = (PVBOXRAWPCIGLOBALS)((uint8_t *)pSupDrvFactory - RT_OFFSETOF(VBOXRAWPCIGLOBALS, SupDrvFactory));
     53
     54    /*
     55     * Convert the UUID strings and compare them.
     56     */
     57    RTUUID UuidReq;
     58    int rc = RTUuidFromStr(&UuidReq, pszInterfaceUuid);
     59    if (RT_SUCCESS(rc))
     60    {
     61        if (!RTUuidCompareStr(&UuidReq, RAWPCIFACTORY_UUID_STR))
     62        {
     63            ASMAtomicIncS32(&pGlobals->cFactoryRefs);
     64            return &pGlobals->RawPciFactory;
     65        }
     66    }
     67    else
     68        Log(("VBoxRawPci: rc=%Rrc, uuid=%s\n", rc, pszInterfaceUuid));
     69
     70    return NULL;
     71}
     72
     73/**
     74 * @copydoc RAWPCIDEVPORT:: pfnRetain
     75 */
     76DECLHIDDEN(void) vboxPciDevRetain(PRAWPCIDEVPORT pThis)
     77{
     78}
     79
     80/**
     81 * @copydoc RAWPCIDEVPORT:: pfnRelease
     82 */
     83DECLHIDDEN(void) vboxPciDevRelease(PRAWPCIDEVPORT pThis)
     84{
     85}
     86
     87
     88/**
     89 * Creates a new instance.
     90 *
     91 * @returns VBox status code.
     92 * @param   pGlobals            The globals.
     93 * @param   pszName             The instance name.
     94 * @param   ppDevPort           Where to store the pointer to our port interface.
     95 */
     96static int vboxPciNewInstance(PVBOXRAWPCIGLOBALS pGlobals,
     97                              uint32_t           u32HostAddress,
     98                              uint32_t           fFlags,
     99                              PRAWPCIDEVPORT     *ppDevPort)
     100{
     101    int             rc;
     102    PVBOXRAWPCIINS  pNew = (PVBOXRAWPCIINS)RTMemAllocZ(sizeof(*pNew));
     103    if (!pNew)
     104        return VERR_NO_MEMORY;
     105
     106    pNew->pGlobals                      = pGlobals;
     107    pNew->hSpinlock                     = NIL_RTSPINLOCK;
     108    pNew->cRefs                         = 1;   
     109    pNew->pNext                         = NULL;
     110    pNew->HostPciAddress                = u32HostAddress;
     111
     112    pNew->DevPort.u32Version            = RAWPCIDEVPORT_VERSION;
     113    pNew->DevPort.pfnRetain             = vboxPciDevRetain;
     114    pNew->DevPort.pfnRelease            = vboxPciDevRelease;
     115    pNew->DevPort.u32VersionEnd         = RAWPCIDEVPORT_VERSION;
     116   
     117    rc = RTSpinlockCreate(&pNew->hSpinlock);
     118    if (RT_SUCCESS(rc))
     119    {
     120        *ppDevPort = &pNew->DevPort;
     121        return rc;
     122    }
     123
     124    return rc;
     125}
     126
     127
     128/**
     129 * @copydoc RAWPCIFACTORY::pfnCreateAndConnect
     130 */
     131static DECLCALLBACK(int) vboxPciFactoryCreateAndConnect(PRAWPCIFACTORY       pFactory,
     132                                                        uint32_t             u32HostAddress,
     133                                                        uint32_t             fFlags,
     134                                                        PRAWPCIDEVPORT       *ppDevPort)
     135{
     136    PVBOXRAWPCIGLOBALS pGlobals = (PVBOXRAWPCIGLOBALS)((uint8_t *)pFactory - RT_OFFSETOF(VBOXRAWPCIGLOBALS, RawPciFactory));
     137    int rc;
     138
     139    LogFlow(("vboxPciFactoryCreateAndConnect: PCI=%x fFlags=%#x\n", u32HostAddress, fFlags));
     140    Assert(pGlobals->cFactoryRefs > 0);
     141    rc = RTSemFastMutexRequest(pGlobals->hFastMtx);
     142    AssertRCReturn(rc, rc);
     143
     144    rc = vboxPciNewInstance(pGlobals, u32HostAddress, fFlags, ppDevPort);
     145
     146    RTSemFastMutexRelease(pGlobals->hFastMtx);
     147
     148    return rc;
     149}
     150
     151/**
     152 * @copydoc RAWPCIFACTORY::pfnRelease
     153 */
     154static DECLCALLBACK(void) vboxPciFactoryRelease(PRAWPCIFACTORY pFactory)
     155{
     156    PVBOXRAWPCIGLOBALS pGlobals = (PVBOXRAWPCIGLOBALS)((uint8_t *)pFactory - RT_OFFSETOF(VBOXRAWPCIGLOBALS, RawPciFactory));
     157
     158    int32_t cRefs = ASMAtomicDecS32(&pGlobals->cFactoryRefs);
     159    Assert(cRefs >= 0); NOREF(cRefs);
     160    LogFlow(("vboxPciFactoryRelease: cRefs=%d (new)\n", cRefs));
     161}
     162
     163
     164
     165
     166static DECLHIDDEN(bool) vboxPciCanUnload(PVBOXRAWPCIGLOBALS pGlobals)
     167{
     168    int rc = RTSemFastMutexRequest(pGlobals->hFastMtx);
     169    bool fRc = !pGlobals->pInstanceHead
     170            && pGlobals->cFactoryRefs <= 0;
     171    RTSemFastMutexRelease(pGlobals->hFastMtx);
     172    AssertRC(rc);
     173    return fRc;
     174}
     175
     176
     177static DECLHIDDEN(int) vboxPciInitIdc(PVBOXRAWPCIGLOBALS pGlobals)
     178{
     179    int rc;
     180    Assert(!pGlobals->fIDCOpen);
     181
     182    /*
     183     * Establish a connection to SUPDRV and register our component factory.
     184     */
     185    rc = SUPR0IdcOpen(&pGlobals->SupDrvIDC, 0 /* iReqVersion = default */, 0 /* iMinVersion = default */, NULL, NULL, NULL);
     186    if (RT_SUCCESS(rc))
     187    {
     188        rc = SUPR0IdcComponentRegisterFactory(&pGlobals->SupDrvIDC, &pGlobals->SupDrvFactory);
     189        if (RT_SUCCESS(rc))
     190        {
     191            pGlobals->fIDCOpen = true;
     192            Log(("VBoxRawPci: pSession=%p\n", SUPR0IdcGetSession(&pGlobals->SupDrvIDC)));
     193            return rc;
     194        }
     195
     196        /* bail out. */
     197        LogRel(("VBoxRawPci: Failed to register component factory, rc=%Rrc\n", rc));
     198        SUPR0IdcClose(&pGlobals->SupDrvIDC);
     199    }
     200
     201    return rc;
     202}
     203
     204/**
     205 * Try to close the IDC connection to SUPDRV if established.
     206 *
     207 * @returns VBox status code.
     208 * @retval  VINF_SUCCESS on success.
     209 * @retval  VERR_WRONG_ORDER if we're busy.
     210 *
     211 * @param   pGlobals        Pointer to the globals.
     212 */
     213DECLHIDDEN(int) vboxPciDeleteIdc(PVBOXRAWPCIGLOBALS pGlobals)
     214{
     215    int rc;
     216
     217    Assert(pGlobals->hFastMtx != NIL_RTSEMFASTMUTEX);
     218
     219    /*
     220     * Check before trying to deregister the factory.
     221     */
     222    if (!vboxPciCanUnload(pGlobals))
     223        return VERR_WRONG_ORDER;
     224
     225    if (!pGlobals->fIDCOpen)
     226        rc = VINF_SUCCESS;
     227    else
     228    {
     229        /*
     230         * Disconnect from SUPDRV.
     231         */
     232        rc = SUPR0IdcComponentDeregisterFactory(&pGlobals->SupDrvIDC, &pGlobals->SupDrvFactory);
     233        AssertRC(rc);
     234        SUPR0IdcClose(&pGlobals->SupDrvIDC);
     235        pGlobals->fIDCOpen = false;
     236    }
     237
     238    return rc;
     239}
     240
     241
     242/**
     243 * Initializes the globals.
     244 *
     245 * @returns VBox status code.
     246 * @param   pGlobals        Pointer to the globals.
     247 */
     248DECLHIDDEN(int) vboxPciInitGlobals(PVBOXRAWPCIGLOBALS pGlobals)
     249{
     250    /*
     251     * Initialize the common portions of the structure.
     252     */
     253    int rc = RTSemFastMutexCreate(&pGlobals->hFastMtx);
     254    if (RT_SUCCESS(rc))
     255    {
     256        pGlobals->pInstanceHead = NULL;
     257        pGlobals->RawPciFactory.pfnRelease = vboxPciFactoryRelease;
     258        pGlobals->RawPciFactory.pfnCreateAndConnect = vboxPciFactoryCreateAndConnect;
     259        memcpy(pGlobals->SupDrvFactory.szName, "VBoxRawPci", sizeof("VBoxRawPci"));
     260        pGlobals->SupDrvFactory.pfnQueryFactoryInterface = vboxPciQueryFactoryInterface;
     261        pGlobals->fIDCOpen = false;
     262    }
     263    return rc;
     264}
     265
     266
     267/**
     268 * Deletes the globals.
     269 *
     270 *
     271 * @param   pGlobals        Pointer to the globals.
     272 */
     273DECLHIDDEN(void) vboxPciDeleteGlobals(PVBOXRAWPCIGLOBALS pGlobals)
     274{
     275    Assert(!pGlobals->fIDCOpen);
     276
     277    /*
     278     * Release resources.
     279     */
     280    if (pGlobals->hFastMtx)
     281    {
     282        RTSemFastMutexDestroy(pGlobals->hFastMtx);
     283        pGlobals->hFastMtx = NIL_RTSEMFASTMUTEX;
     284    }
     285}
     286
     287
     288int  vboxPciInit(PVBOXRAWPCIGLOBALS pGlobals)
     289{
     290
     291    /*
     292     * Initialize the common portions of the structure.
     293     */
     294    int rc = vboxPciInitGlobals(pGlobals);
     295    if (RT_SUCCESS(rc))
     296    {     
     297        rc = vboxPciInitIdc(pGlobals);
     298        if (RT_SUCCESS(rc))
     299            return rc;
     300
     301        /* bail out. */
     302        vboxPciDeleteGlobals(pGlobals);
     303    }
     304
     305    return rc;
     306}
     307
     308void vboxPciShutdown(PVBOXRAWPCIGLOBALS pGlobals)
     309{
     310    int rc = vboxPciDeleteIdc(pGlobals);
     311   
     312    if (RT_SUCCESS(rc))
     313        vboxPciDeleteGlobals(pGlobals);
     314}
  • trunk/src/VBox/HostDrivers/VBoxPci/VBoxPciInternal.h

    r35920 r35946  
    2424#include <iprt/assert.h>
    2525
     26
     27RT_C_DECLS_BEGIN
     28
     29/* Forward declaration. */
     30typedef struct VBOXRAWPCIGLOBALS *PVBOXRAWPCIGLOBALS;
     31typedef struct VBOXRAWPCIINS     *PVBOXRAWPCIINS;
     32
     33/**
     34 * The per-instance data of the VBox raw PCI interface.
     35 *
     36 * This is data associated with a host PCI card which
     37 * the filter driver has been or may be attached to. When possible it is
     38 * attached dynamically, but this may not be possible on all OSes so we have
     39 * to be flexible about things.
     40 *
     41 */
     42typedef struct VBOXRAWPCIINS
     43{
     44    /** Pointer to the globals. */
     45    PVBOXRAWPCIGLOBALS pGlobals;
     46    /** The spinlock protecting the state variables and host interface handle. */
     47    RTSPINLOCK         hSpinlock;
     48    /** Pointer to the next device in the list. */
     49    PVBOXRAWPCIINS     pNext;
     50    /** Reference count. */
     51    uint32_t volatile cRefs;
     52
     53    /* Host PCI address of this device. */
     54    uint32_t           HostPciAddress;
     55
     56    /** Port, given to the outside world. */
     57    RAWPCIDEVPORT      DevPort;
     58} VBOXRAWPCIINS;
     59
     60/**
     61 * The global data of the VBox PCI driver.
     62 *
     63 * This contains the bit required for communicating with support driver, VBoxDrv
     64 * (start out as SupDrv).
     65 */
     66typedef struct VBOXRAWPCIGLOBALS
     67{
     68    /** Mutex protecting the list of instances and state changes. */
     69    RTSEMFASTMUTEX hFastMtx;
     70
     71    /** Pointer to a list of instance data. */
     72    PVBOXRAWPCIINS pInstanceHead;
     73
     74    /** The raw PCI interface factory. */
     75    RAWPCIFACTORY RawPciFactory;
     76    /** The SUPDRV component factory registration. */
     77    SUPDRVFACTORY SupDrvFactory;
     78    /** The number of current factory references. */
     79    int32_t volatile cFactoryRefs;
     80    /** Whether the IDC connection is open or not.
     81     * This is only for cleaning up correctly after the separate IDC init on Windows. */
     82    bool fIDCOpen;
     83    /** The SUPDRV IDC handle (opaque struct). */
     84    SUPDRVIDCHANDLE SupDrvIDC;
     85} VBOXRAWPCIGLOBALS;
     86
     87DECLHIDDEN(int)  vboxPciInit(PVBOXRAWPCIGLOBALS pGlobals);
     88DECLHIDDEN(void) vboxPciShutdown(PVBOXRAWPCIGLOBALS pGlobals);
     89
     90RT_C_DECLS_END
     91
    2692#endif
    27 
Note: See TracChangeset for help on using the changeset viewer.

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