Changeset 35946 in vbox
- Timestamp:
- Feb 11, 2011 5:58:30 PM (14 years ago)
- Location:
- trunk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/rawpci.h
r35920 r35946 189 189 } PCIRAWR0OPERATION; 190 190 191 /** Forward declarations. */ 192 typedef struct RAWPCIFACTORY *PRAWPCIFACTORY; 193 typedef 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 */ 201 typedef 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 */ 234 typedef 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 191 272 RT_C_DECLS_END 192 273 -
trunk/src/VBox/HostDrivers/VBoxPci/VBoxPci.c
r35920 r35946 18 18 /** @page pg_rawpci VBoxPci - host PCI support 19 19 * 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 21 21 * PCI hardware. 22 22 * 23 23 */ 24 24 25 #define LOG_GROUP LOG_GROUP_PCI_RAW 26 #include "VBoxPciInternal.h" 27 25 #define LOG_GROUP LOG_GROUP_DEV_PCI_RAW 28 26 #include <VBox/log.h> 29 27 #include <VBox/err.h> 28 #include <VBox/sup.h> 29 #include <VBox/version.h> 30 30 31 #include <iprt/string.h> 31 32 #include <VBox/sup.h>33 32 #include <iprt/assert.h> 34 33 #include <iprt/spinlock.h> 35 34 #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 */ 50 static 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 */ 76 DECLHIDDEN(void) vboxPciDevRetain(PRAWPCIDEVPORT pThis) 77 { 78 } 79 80 /** 81 * @copydoc RAWPCIDEVPORT:: pfnRelease 82 */ 83 DECLHIDDEN(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 */ 96 static 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 */ 131 static 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 */ 154 static 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 166 static 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 177 static 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 */ 213 DECLHIDDEN(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 */ 248 DECLHIDDEN(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 */ 273 DECLHIDDEN(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 288 int 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 308 void 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 24 24 #include <iprt/assert.h> 25 25 26 27 RT_C_DECLS_BEGIN 28 29 /* Forward declaration. */ 30 typedef struct VBOXRAWPCIGLOBALS *PVBOXRAWPCIGLOBALS; 31 typedef 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 */ 42 typedef 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 */ 66 typedef 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 87 DECLHIDDEN(int) vboxPciInit(PVBOXRAWPCIGLOBALS pGlobals); 88 DECLHIDDEN(void) vboxPciShutdown(PVBOXRAWPCIGLOBALS pGlobals); 89 90 RT_C_DECLS_END 91 26 92 #endif 27
Note:
See TracChangeset
for help on using the changeset viewer.