VirtualBox

source: vbox/trunk/src/VBox/Devices/Network/DrvDedicatedNic.cpp@ 34244

Last change on this file since 34244 was 31094, checked in by vboxsync, 14 years ago

typo

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 17.7 KB
Line 
1/* $Id: DrvDedicatedNic.cpp 31094 2010-07-26 08:14:34Z vboxsync $ */
2/** @file
3 * DrvDedicatedNic - Experimental network driver for using a dedicated (V)NIC.
4 */
5
6/*
7 * Copyright (C) 2010 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18/*******************************************************************************
19* Header Files *
20*******************************************************************************/
21#define LOG_GROUP LOG_GROUP_DEFAULT
22#include <VBox/log.h>
23#include <VBox/pdmcritsect.h>
24#include <VBox/pdmdrv.h>
25#include <VBox/pdmnetifs.h>
26#include <VBox/pdmnetinline.h>
27#include <VBox/intnet.h>
28#include <VBox/intnetinline.h>
29
30#include <iprt/asm.h>
31#include <iprt/assert.h>
32#include <iprt/mem.h>
33#include <iprt/path.h>
34#include <iprt/string.h>
35#include <iprt/thread.h>
36#include <iprt/uuid.h>
37
38#include "../Builtins.h"
39
40
41/*******************************************************************************
42* Structures and Typedefs *
43*******************************************************************************/
44/**
45 * Instance data for the dedicated (V)NIC driver.
46 *
47 * @implements PDMINETWORKUP
48 */
49typedef struct DRVDEDICATEDNIC
50{
51 /** The network interface. */
52 PDMINETWORKUP INetworkUpR3;
53 /** The network interface. */
54 R3PTRTYPE(PPDMINETWORKDOWN) pIAboveNet;
55 /** The network config interface.
56 * Can (in theory at least) be NULL. */
57 R3PTRTYPE(PPDMINETWORKCONFIG) pIAboveConfigR3;
58 /** Pointer to the driver instance. */
59 PPDMDRVINSR3 pDrvInsR3;
60 /** Ring-3 base interface for the ring-0 context. */
61 PDMIBASER0 IBaseR0;
62 /** Ring-3 base interface for the raw-mode context. */
63 PDMIBASERC IBaseRC;
64 RTR3PTR R3PtrAlignment;
65
66
67 /** The network interface for the ring-0 context. */
68 PDMINETWORKUPR0 INetworkUpR0;
69 /** Pointer to the driver instance. */
70 PPDMDRVINSR0 pDrvInsR0;
71 RTR0PTR R0PtrAlignment;
72
73 /** The interface we're talking to. */
74 R0PTRTYPE(PINTNETTRUNKIFPORT) pIfPortR0;
75 /** Set if the link is up, clear if its down. */
76 bool fLinkDown;
77 /** Set if the current transmit operation is done the XMIT thread. If clear,
78 * we assume its an EMT. */
79 bool fXmitOnXmitThread;
80 /** The name of the interface that we're connected to. */
81 char szIfName[128 + 8 - 2];
82
83 /** Critical section serializing transmission. */
84 PDMCRITSECT XmitLock;
85 /** The transmit scatter gather buffer (ring-3 -> ring-0). */
86 PDMSCATTERGATHER XmitSg;
87 /** The transmit GSO context (when applicable). */
88 PDMNETWORKGSO XmitGso;
89 /** The transmit buffer (ring-3 -> ring-0). */
90 uint8_t abXmitBuf[_64K];
91
92 /** The receive scatter gather buffer. */
93 PDMSCATTERGATHER RecvSg;
94 /** The receive buffer (ring-0 -> ring-3). */
95 uint8_t abRecvBuf[_64K];
96
97} DRVDEDICATEDNIC;
98/** Pointer to the instance data for the dedicated (V)NIC driver. */
99typedef DRVDEDICATEDNIC *PDRVDEDICATEDNIC;
100
101/**
102 * Ring-0 operations.
103 */
104typedef enum DRVDEDICATEDNICR0OP
105{
106 /** Invalid zero value.. */
107 DRVDEDICATEDNICR0OP_INVALID = 0,
108 /** Initialize the connection to the NIC. */
109 DRVDEDICATEDNICR0OP_INIT,
110 /** Terminate the connection to the NIC. */
111 DRVDEDICATEDNICR0OP_TERM,
112 /** Suspend the operation. */
113 DRVDEDICATEDNICR0OP_SUSPEND,
114 /** Resume the operation. */
115 DRVDEDICATEDNICR0OP_RESUME,
116 /** Wait for and do receive work.
117 * We do this in ring-0 instead of ring-3 to save 1-2 buffer copies and
118 * unnecessary context switching. */
119 DRVDEDICATEDNICR0OP_RECV,
120 /** Wait for and do transmit work.
121 * We do this in ring-0 instead of ring-3 to save 1-2 buffer copies and
122 * unnecessary context switching. */
123 DRVDEDICATEDNICR0OP_SEND,
124 /** Changes the promiscuousness of the interface (guest point of view). */
125 DRVDEDICATEDNICR0OP_PROMISC,
126 /** End of the valid operations. */
127 DRVDEDICATEDNICR0OP_END,
128 /** The usual 32-bit hack. */
129 DRVDEDICATEDNICR0OP_32BIT_HACK = 0x7fffffff
130} DRVDEDICATEDNICR0OP;
131
132
133
134#ifdef IN_RING0
135
136/**
137 * @interface_method_impl{FNPDMDRVREQHANDLERR0}
138 */
139PDMBOTHCBDECL(int) drvR0DedicatedNicReqHandler(PPDMDRVINS pDrvIns, uint32_t uOperation, uint64_t u64Arg)
140{
141 switch ((DRVDEDICATEDNICR0OP)uOperation)
142 {
143 case DRVDEDICATEDNICR0OP_INIT:
144 return VERR_NOT_IMPLEMENTED;//drvR0DedicatedNicReqInit(pDrvIns, u64Arg);
145
146 case DRVDEDICATEDNICR0OP_TERM:
147 return VERR_NOT_IMPLEMENTED;//drvR0DedicatedNicReqTerm(pDrvIns);
148
149 case DRVDEDICATEDNICR0OP_SUSPEND:
150 return VERR_NOT_IMPLEMENTED;//drvR0DedicatedNicReqSuspend(pDrvIns);
151
152 case DRVDEDICATEDNICR0OP_RESUME:
153 return VERR_NOT_IMPLEMENTED;//drvR0DedicatedNicReqResume(pDrvIns);
154
155 case DRVDEDICATEDNICR0OP_RECV:
156 return VERR_NOT_IMPLEMENTED;//drvR0DedicatedNicReqRecv(pDrvIns);
157
158 case DRVDEDICATEDNICR0OP_SEND:
159 return VERR_NOT_IMPLEMENTED;//drvR0DedicatedNicReqSend(pDrvIns);
160
161 case DRVDEDICATEDNICR0OP_PROMISC:
162 return VERR_NOT_IMPLEMENTED;//drvR0DedicatedNicReqPromisc(pDrvIns, !!u64Arg);
163
164 case DRVDEDICATEDNICR0OP_END:
165 default:
166 return VERR_INVALID_FUNCTION;
167 }
168 return VINF_SUCCESS;
169}
170
171#endif /* IN_RING0 */
172
173
174
175/* -=-=-=-=- PDMINETWORKUP -=-=-=-=- */
176
177/**
178 * @interface_method_impl{PDMINETWORKUP,pfnBeginXmit}
179 */
180PDMBOTHCBDECL(int) drvDedicatedNicUp_BeginXmit(PPDMINETWORKUP pInterface, bool fOnWorkerThread)
181{
182 PDRVDEDICATEDNIC pThis = RT_FROM_MEMBER(pInterface, DRVDEDICATEDNIC, CTX_SUFF(INetworkUp));
183 int rc = PDMCritSectTryEnter(&pThis->XmitLock);
184 if (RT_SUCCESS(rc))
185 ASMAtomicUoWriteBool(&pThis->fXmitOnXmitThread, fOnWorkerThread);
186 return rc;
187}
188
189
190/**
191 * @interface_method_impl{PDMINETWORKUP,pfnAllocBuf}
192 */
193PDMBOTHCBDECL(int) drvDedicatedNicUp_AllocBuf(PPDMINETWORKUP pInterface, size_t cbMin,
194 PCPDMNETWORKGSO pGso, PPPDMSCATTERGATHER ppSgBuf)
195{
196 PDRVDEDICATEDNIC pThis = RT_FROM_MEMBER(pInterface, DRVDEDICATEDNIC, CTX_SUFF(INetworkUp));
197 Assert(PDMCritSectIsOwner(&pThis->XmitLock));
198
199 /*
200 * If the net is down, we can return immediately.
201 */
202 if (pThis->fLinkDown)
203 return VERR_NET_DOWN;
204
205#ifdef IN_RING0
206 /** @todo Ask the driver for a buffer, atomically if we're called on EMT. */
207 return VERR_TRY_AGAIN;
208
209#else /* IN_RING3 */
210 /*
211 * Are we busy or is the request too big?
212 */
213 if (RT_UNLIKELY((pThis->XmitSg.fFlags & PDMSCATTERGATHER_FLAGS_MAGIC_MASK) == PDMSCATTERGATHER_FLAGS_MAGIC))
214 return VERR_TRY_AGAIN;
215 if (cbMin > sizeof(pThis->abXmitBuf))
216 return VERR_NO_MEMORY;
217
218 /*
219 * Initialize the S/G buffer and return.
220 */
221 pThis->XmitSg.fFlags = PDMSCATTERGATHER_FLAGS_MAGIC | PDMSCATTERGATHER_FLAGS_OWNER_1;
222 pThis->XmitSg.cbUsed = 0;
223 pThis->XmitSg.cbAvailable = sizeof(pThis->abXmitBuf);
224 pThis->XmitSg.pvAllocator = NULL;
225 if (!pGso)
226 {
227 pThis->XmitSg.pvUser = NULL;
228 pThis->XmitGso.u8Type = PDMNETWORKGSOTYPE_INVALID;
229 }
230 else
231 {
232 pThis->XmitSg.pvUser = &pThis->XmitGso;
233 pThis->XmitGso = *pGso;
234 }
235 pThis->XmitSg.cSegs = 1;
236 pThis->XmitSg.aSegs[0].cbSeg = pThis->XmitSg.cbAvailable;
237 pThis->XmitSg.aSegs[0].pvSeg = &pThis->abXmitBuf[0];
238
239# if 0 /* poison */
240 memset(pThis->XmitSg.aSegs[0].pvSeg, 'F', pThis->XmitSg.aSegs[0].cbSeg);
241# endif
242
243 *ppSgBuf = &pThis->XmitSg;
244 return VINF_SUCCESS;
245#endif /* IN_RING3 */
246}
247
248
249/**
250 * @interface_method_impl{PDMINETWORKUP,pfnFreeBuf}
251 */
252PDMBOTHCBDECL(int) drvDedicatedNicUp_FreeBuf(PPDMINETWORKUP pInterface, PPDMSCATTERGATHER pSgBuf)
253{
254 PDRVDEDICATEDNIC pThis = RT_FROM_MEMBER(pInterface, DRVDEDICATEDNIC, CTX_SUFF(INetworkUp));
255 Assert(pSgBuf->fFlags == (PDMSCATTERGATHER_FLAGS_MAGIC | PDMSCATTERGATHER_FLAGS_OWNER_1));
256 Assert(pSgBuf->cbUsed <= pSgBuf->cbAvailable);
257 Assert(PDMCritSectIsOwner(&pThis->XmitLock));
258
259 if (pSgBuf)
260 {
261#ifdef IN_RING0
262 // ...
263#else
264 Assert(pSgBuf == &pThis->XmitSg);
265 Assert((pSgBuf->fFlags & PDMSCATTERGATHER_FLAGS_MAGIC_MASK) == PDMSCATTERGATHER_FLAGS_MAGIC);
266 pSgBuf->fFlags = 0;
267#endif
268 }
269
270 return VINF_SUCCESS;
271}
272
273
274/**
275 * @interface_method_impl{PDMINETWORKUP,pfnSendBuf}
276 */
277PDMBOTHCBDECL(int) drvDedicatedNicUp_SendBuf(PPDMINETWORKUP pInterface, PPDMSCATTERGATHER pSgBuf, bool fOnWorkerThread)
278{
279 PDRVDEDICATEDNIC pThis = RT_FROM_MEMBER(pInterface, DRVDEDICATEDNIC, CTX_SUFF(INetworkUp));
280 STAM_PROFILE_START(&pThis->StatTransmit, a);
281
282 AssertPtr(pSgBuf);
283 Assert(pSgBuf->fFlags == (PDMSCATTERGATHER_FLAGS_MAGIC | PDMSCATTERGATHER_FLAGS_OWNER_1));
284 Assert(pSgBuf->cbUsed <= pSgBuf->cbAvailable);
285#ifdef IN_RING0
286 Assert(pSgBuf == &pThis->XmitSg);
287#endif
288 Assert(PDMCritSectIsOwner(&pThis->XmitLock));
289
290#ifdef IN_RING0
291 /*
292 * Tell the driver to send the packet.
293 */
294
295 return VERR_INTERNAL_ERROR_4;
296
297#else /* IN_RING3 */
298 /*
299 * Call ring-0 to start the transfer.
300 */
301 int rc = PDMDrvHlpCallR0(pThis->pDrvInsR3, DRVDEDICATEDNICR0OP_SEND, pSgBuf->cbUsed);
302 if (RT_FAILURE(rc) && rc != VERR_NET_DOWN)
303 rc = VERR_NET_NO_BUFFER_SPACE;
304 pSgBuf->fFlags = 0;
305 return rc;
306#endif /* IN_RING3 */
307}
308
309
310/**
311 * @interface_method_impl{PDMINETWORKUP,pfnEndXmit}
312 */
313PDMBOTHCBDECL(void) drvDedicatedNicUp_EndXmit(PPDMINETWORKUP pInterface)
314{
315 PDRVDEDICATEDNIC pThis = RT_FROM_MEMBER(pInterface, DRVDEDICATEDNIC, CTX_SUFF(INetworkUp));
316 ASMAtomicUoWriteBool(&pThis->fXmitOnXmitThread, false);
317 PDMCritSectLeave(&pThis->XmitLock);
318}
319
320
321/**
322 * @interface_method_impl{PDMINETWORKUP,pfnSetPromiscuousMode}
323 */
324PDMBOTHCBDECL(void) drvDedicatedNicUp_SetPromiscuousMode(PPDMINETWORKUP pInterface, bool fPromiscuous)
325{
326 PDRVDEDICATEDNIC pThis = RT_FROM_MEMBER(pInterface, DRVDEDICATEDNIC, CTX_SUFF(INetworkUp));
327 /** @todo enable/disable promiscuous mode (should be easy) */
328}
329
330#ifdef IN_RING3
331
332/**
333 * @interface_method_impl{PDMINETWORKUP,pfnNotifyLinkChanged}
334 */
335static DECLCALLBACK(void) drvR3DedicatedNicUp_NotifyLinkChanged(PPDMINETWORKUP pInterface, PDMNETWORKLINKSTATE enmLinkState)
336{
337 PDRVDEDICATEDNIC pThis = RT_FROM_MEMBER(pInterface, DRVDEDICATEDNIC, CTX_SUFF(INetworkUp));
338 bool fLinkDown;
339 switch (enmLinkState)
340 {
341 case PDMNETWORKLINKSTATE_DOWN:
342 case PDMNETWORKLINKSTATE_DOWN_RESUME:
343 fLinkDown = true;
344 break;
345 default:
346 AssertMsgFailed(("enmLinkState=%d\n", enmLinkState));
347 case PDMNETWORKLINKSTATE_UP:
348 fLinkDown = false;
349 break;
350 }
351 LogFlow(("drvR3DedicatedNicUp_NotifyLinkChanged: enmLinkState=%d %d->%d\n", enmLinkState, pThis->fLinkDown, fLinkDown));
352 ASMAtomicWriteBool(&pThis->fLinkDown, fLinkDown);
353}
354
355
356/* -=-=-=-=- PDMIBASER0 -=-=-=-=- */
357
358/**
359 * @interface_method_impl{PDMIBASER0,pfnQueryInterface}
360 */
361static DECLCALLBACK(RTR0PTR) drvR3DedicatedNicIBaseR0_QueryInterface(PPDMIBASER0 pInterface, const char *pszIID)
362{
363 PDRVDEDICATEDNIC pThis = RT_FROM_MEMBER(pInterface, DRVDEDICATEDNIC, IBaseR0);
364 PDMIBASER0_RETURN_INTERFACE(pThis->pDrvInsR3, pszIID, PDMINETWORKUP, &pThis->INetworkUpR0);
365 return NIL_RTR0PTR;
366}
367
368
369/* -=-=-=-=- PDMIBASE -=-=-=-=- */
370
371/**
372 * @interface_method_impl{PDMIBASE,pfnQueryInterface}
373 */
374static DECLCALLBACK(void *) drvR3DedicatedNicIBase_QueryInterface(PPDMIBASE pInterface, const char *pszIID)
375{
376 PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
377 PDRVDEDICATEDNIC pThis = PDMINS_2_DATA(pDrvIns, PDRVDEDICATEDNIC);
378
379 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
380 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASER0, &pThis->IBaseR0);
381 PDMIBASE_RETURN_INTERFACE(pszIID, PDMINETWORKUP, &pThis->INetworkUpR3);
382 return NULL;
383}
384
385
386/* -=-=-=-=- PDMDRVREG -=-=-=-=- */
387
388/**
389 * @interface_method_impl{PDMDRVREG,pfnPowerOff}
390 */
391static DECLCALLBACK(void) drvR3DedicatedNicPowerOff(PPDMDRVINS pDrvIns)
392{
393 LogFlow(("drvR3DedicatedNicPowerOff\n"));
394 PDRVDEDICATEDNIC pThis = PDMINS_2_DATA(pDrvIns, PDRVDEDICATEDNIC);
395
396 int rc = PDMDrvHlpCallR0(pDrvIns, DRVDEDICATEDNICR0OP_SUSPEND, 0);
397 AssertRC(rc);
398}
399
400
401/**
402 * @interface_method_impl{PDMDRVREG,pfnResume}
403 */
404static DECLCALLBACK(void) drvR3DedicatedNicResume(PPDMDRVINS pDrvIns)
405{
406 LogFlow(("drvR3DedicatedNicPowerResume\n"));
407 PDRVDEDICATEDNIC pThis = PDMINS_2_DATA(pDrvIns, PDRVDEDICATEDNIC);
408
409 int rc = PDMDrvHlpCallR0(pDrvIns, DRVDEDICATEDNICR0OP_RESUME, 0);
410 AssertRC(rc);
411}
412
413
414/**
415 * @interface_method_impl{PDMDRVREG,pfnSuspend}
416 */
417static DECLCALLBACK(void) drvR3DedicatedNicSuspend(PPDMDRVINS pDrvIns)
418{
419 LogFlow(("drvR3DedicatedNicPowerSuspend\n"));
420 PDRVDEDICATEDNIC pThis = PDMINS_2_DATA(pDrvIns, PDRVDEDICATEDNIC);
421
422 int rc = PDMDrvHlpCallR0(pDrvIns, DRVDEDICATEDNICR0OP_SUSPEND, 0);
423 AssertRC(rc);
424}
425
426
427/**
428 * @interface_method_impl{PDMDRVREG,pfnPowerOn}
429 */
430static DECLCALLBACK(void) drvR3DedicatedNicPowerOn(PPDMDRVINS pDrvIns)
431{
432 LogFlow(("drvR3DedicatedNicPowerOn\n"));
433 PDRVDEDICATEDNIC pThis = PDMINS_2_DATA(pDrvIns, PDRVDEDICATEDNIC);
434
435 int rc = PDMDrvHlpCallR0(pDrvIns, DRVDEDICATEDNICR0OP_RESUME, 0);
436 AssertRC(rc);
437}
438
439
440/**
441 * @interface_method_impl{PDMDRVREG,pfnDestruct}
442 */
443static DECLCALLBACK(void) drvR3DedicatedNicDestruct(PPDMDRVINS pDrvIns)
444{
445 LogFlow(("drvR3DedicatedNicDestruct\n"));
446 PDRVDEDICATEDNIC pThis = PDMINS_2_DATA(pDrvIns, PDRVDEDICATEDNIC);
447 PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
448
449 if (pThis->pIfPortR0)
450 {
451 int rc = PDMDrvHlpCallR0(pDrvIns, DRVDEDICATEDNICR0OP_TERM, 0);
452 AssertRC(rc);;
453 }
454}
455
456
457/**
458 * @interface_method_impl{PDMDRVREG,pfnConstruct}
459 */
460static DECLCALLBACK(int) drvR3DedicatedNicConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
461{
462 PDRVDEDICATEDNIC pThis = PDMINS_2_DATA(pDrvIns, PDRVDEDICATEDNIC);
463 bool f;
464 PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
465
466 /*
467 * Init the static parts.
468 */
469 pThis->pDrvInsR3 = pDrvIns;
470 pThis->pDrvInsR0 = PDMDRVINS_2_R0PTR(pDrvIns);
471#if 0
472 pThis->hRecvThread = NIL_RTTHREAD;
473 pThis->hRecvEvt = NIL_RTSEMEVENT;
474 pThis->pXmitThread = NULL;
475 pThis->hXmitEvt = NIL_SUPSEMEVENT;
476 pThis->pSupDrvSession = PDMDrvHlpGetSupDrvSession(pDrvIns);
477 pThis->hSgCache = NIL_RTMEMCACHE;
478 pThis->enmRecvState = RECVSTATE_SUSPENDED;
479 pThis->fActivateEarlyDeactivateLate = false;
480 /* IBase* */
481 pDrvIns->IBase.pfnQueryInterface = drvR3DedicatedNicIBase_QueryInterface;
482 pThis->IBaseR0.pfnQueryInterface = drvR3DedicatedNicIBaseR0_QueryInterface;
483 pThis->IBaseRC.pfnQueryInterface = drvR3DedicatedNicIBaseRC_QueryInterface;
484 /* INetworkUp */
485 pThis->INetworkUpR3.pfnBeginXmit = drvDedicatedNic_BeginXmit;
486 pThis->INetworkUpR3.pfnAllocBuf = drvDedicatedNic_AllocBuf;
487 pThis->INetworkUpR3.pfnFreeBuf = drvDedicatedNic_FreeBuf;
488 pThis->INetworkUpR3.pfnSendBuf = drvDedicatedNic_SendBuf;
489 pThis->INetworkUpR3.pfnEndXmit = drvDedicatedNic_EndXmit;
490 pThis->INetworkUpR3.pfnSetPromiscuousMode = drvDedicatedNic_SetPromiscuousMode;
491 pThis->INetworkUpR3.pfnNotifyLinkChanged = drvR3DedicatedNicUp_NotifyLinkChanged;
492#endif
493
494 /** @todo
495 * Need to create a generic way of calling into the ring-0 side of the driver so
496 * we can initialize the thing as well as send and receive. Hmm ... the
497 * sending could be done more efficiently from a ring-0 kernel thread actually
498 * (saves context switching and 1-2 copy operations). Ditto for receive, except
499 * we need to tie the thread to the process or we cannot access the guest ram so
500 * easily.
501 */
502
503 return VERR_NOT_IMPLEMENTED;
504}
505
506
507
508/**
509 * Internal networking transport driver registration record.
510 */
511const PDMDRVREG g_DrvDedicatedNic =
512{
513 /* u32Version */
514 PDM_DRVREG_VERSION,
515 /* szName */
516 "DedicatedNic",
517 /* szRCMod */
518 "",
519 /* szR0Mod */
520 "VBoxDDR0.r0",
521 /* pszDescription */
522 "Dedicated (V)NIC Driver",
523 /* fFlags */
524 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DRVREG_FLAGS_R0,
525 /* fClass. */
526 PDM_DRVREG_CLASS_NETWORK,
527 /* cMaxInstances */
528 ~0,
529 /* cbInstance */
530 sizeof(DRVDEDICATEDNIC),
531 /* pfnConstruct */
532 drvR3DedicatedNicConstruct,
533 /* pfnDestruct */
534 drvR3DedicatedNicDestruct,
535 /* pfnRelocate */
536 NULL,
537 /* pfnIOCtl */
538 NULL,
539 /* pfnPowerOn */
540 drvR3DedicatedNicPowerOn,
541 /* pfnReset */
542 NULL,
543 /* pfnSuspend */
544 drvR3DedicatedNicSuspend,
545 /* pfnResume */
546 drvR3DedicatedNicResume,
547 /* pfnAttach */
548 NULL,
549 /* pfnDetach */
550 NULL,
551 /* pfnPowerOff */
552 drvR3DedicatedNicPowerOff,
553 /* pfnSoftReset */
554 NULL,
555 /* u32EndVersion */
556 PDM_DRVREG_VERSION
557};
558
559#endif /* IN_RING3 */
560
Note: See TracBrowser for help on using the repository browser.

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