VirtualBox

source: vbox/trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-solaris.c@ 6032

Last change on this file since 6032 was 6032, checked in by vboxsync, 17 years ago

Moved the MMIO mapping code myself. (probably doesn't compile now)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 23.7 KB
Line 
1/* $Id: VBoxGuest-solaris.c 6032 2007-12-10 07:35:42Z vboxsync $ */
2/** @file
3 * VirtualBox Guest Additions Driver for Solaris.
4 */
5
6/*
7 * Copyright (C) 2007 innotek GmbH
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 as published by the Free Software Foundation,
13 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
14 * distribution. VirtualBox OSE is distributed in the hope that it will
15 * be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*******************************************************************************
20* Header Files *
21*******************************************************************************/
22#include "the-solaris-kernel.h" /** @todo r=bird: no need to do like linux here, solaris is stable. */
23#include "VBoxGuestInternal.h"
24
25#include <VBox/log.h>
26#include <VBox/VBoxGuest.h>
27#include <iprt/asm.h>
28#include <iprt/assert.h>
29#include <iprt/initterm.h>
30#include <iprt/process.h>
31
32
33/*******************************************************************************
34* Defined Constants And Macros *
35*******************************************************************************/
36/** The module name. */
37#define DEVICE_NAME "vboxadd"
38/** The module description as seen in 'modinfo'. */
39#define DEVICE_DESC "VirtualBox Guest Additions Driver"
40/** @name R0 Log helpers.
41 * @{ */
42#define VBA_LOGCONT(...) cmn_err(CE_CONT, "vboxadd: " __VA_ARGS__);
43#define VBA_LOGNOTE(...) cmn_err(CE_NOTE, "vboxadd: " __VA_ARGS__);
44/** @} */
45
46
47/*******************************************************************************
48* Internal Functions *
49*******************************************************************************/
50static int VBoxAddSolarisOpen(dev_t *pDev, int fFlag, int fType, cred_t *pCred);
51static int VBoxAddSolarisClose(dev_t Dev, int fFlag, int fType, cred_t *pCred);
52static int VBoxAddSolarisRead(dev_t Dev, struct uio *pUio, cred_t *pCred);
53static int VBoxAddSolarisWrite(dev_t Dev, struct uio *pUio, cred_t *pCred);
54static int VBoxAddSolarisIOCtl(dev_t Dev, int Cmd, intptr_t pArgs, int mode, cred_t *pCred, int *pVal);
55
56static int VBoxAddSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd);
57static int VBoxAddSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd);
58
59static int VBoxGuestSolarisAddIRQ(dev_info_t *pDip, void *pvState);
60static void VBoxGuestSolarisRemoveIRQ(dev_info_t *pDip, void *pvState);
61static uint_t VBoxGuestSolarisISR(caddr_t Arg);
62
63DECLVBGL(int) VBoxGuestSolarisServiceCall(void *pvState, unsigned iCmd, void *pvData, size_t cbData, size_t *pcbDataReturned);
64DECLVBGL(void *) VBoxGuestSolarisServiceOpen(uint32_t *pu32Version);
65DECLVBGL(void) VBoxGuestSolarisServiceClose(void *pvState);
66
67
68/*******************************************************************************
69* Global Variables *
70*******************************************************************************/
71/**
72 * cb_ops: for drivers that support char/block entry points
73 */
74static struct cb_ops g_VBoxAddSolarisCbOps =
75{
76 VBoxAddSolarisOpen,
77 VBoxAddSolarisClose,
78 nodev, /* b strategy */
79 nodev, /* b dump */
80 nodev, /* b print */
81 VBoxAddSolarisRead,
82 VBoxAddSolarisWrite,
83 VBoxAddSolarisIOCtl,
84 nodev, /* c devmap */
85 nodev, /* c mmap */
86 nodev, /* c segmap */
87 nochpoll, /* c poll */
88 ddi_prop_op, /* property ops */
89 NULL, /* streamtab */
90 D_NEW | D_MP, /* compat. flag */
91 CB_REV /* revision */
92};
93
94/**
95 * dev_ops: for driver device operations
96 */
97static struct dev_ops g_VBoxAddSolarisDevOps =
98{
99 DEVO_REV, /* driver build revision */
100 0, /* ref count */
101 nulldev, /* get info */
102 nulldev, /* identify */
103 nulldev, /* probe */
104 VBoxAddSolarisAttach,
105 VBoxAddSolarisDetach,
106 nodev, /* reset */
107 &g_VBoxAddSolarisCbOps,
108 (struct bus_ops *)0,
109 nodev /* power */
110};
111
112/**
113 * modldrv: export driver specifics to the kernel
114 */
115static struct modldrv g_VBoxAddSolarisModule =
116{
117 &mod_driverops, /* extern from kernel */
118 DEVICE_DESC,
119 &g_VBoxAddSolarisDevOps
120};
121
122/**
123 * modlinkage: export install/remove/info to the kernel
124 */
125static struct modlinkage g_VBoxAddSolarisModLinkage =
126{
127 MODREV_1, /* loadable module system revision */
128 &g_VBoxAddSolarisModule,
129 NULL /* terminate array of linkage structures */
130};
131
132/**
133 * State info for each open file handle.
134 */
135typedef struct
136{
137 /** PCI handle of VMMDev. */
138 ddi_acc_handle_t PciHandle;
139 /** Interrupt block cookie. */
140 ddi_iblock_cookie_t BlockCookie;
141 /** Driver Mutex. */
142 kmutex_t Mtx;
143 /** IO Port. */
144 uint16_t uIOPortBase;
145 /** Physical address of the MMIO region.*/
146 uint32_t uPhysMMIOBase;
147 /** Size of the MMIO region. */
148 off_t cbMMIO;
149 /** Kernel session. */
150 PVBOXGUESTSESSION pKernelSession;
151 /** VMMDev Version. */
152 uint32_t u32Version;
153} VBoxAddDevState;
154
155/** Device handle (we support only one instance). */
156static dev_info_t *g_pDip;
157
158/** Opaque pointer to state */
159static void *g_pVBoxAddSolarisState;
160
161/** Device extention & session data association structure. */
162static VBOXGUESTDEVEXT g_DevExt;
163/** Spinlock protecting g_apSessionHashTab. */
164static RTSPINLOCK g_Spinlock = NIL_RTSPINLOCK;
165/** Hash table */
166static PVBOXGUESTSESSION g_apSessionHashTab[19];
167/** Calculates the index into g_apSessionHashTab.*/
168#define SESSION_HASH(sfn) ((sfn) % RT_ELEMENTS(g_apSessionHashTab))
169
170/** GCC C++ hack. */
171unsigned __gxx_personality_v0 = 0xdecea5ed;
172
173/**
174 * Kernel entry points
175 */
176int _init(void)
177{
178 int rc;
179
180 VBA_LOGCONT("_init\n");
181 rc = ddi_soft_state_init(&g_pVBoxAddSolarisState, sizeof(VBoxAddDevState), 1);
182 if (!rc)
183 {
184 rc = mod_install(&g_VBoxAddSolarisModLinkage);
185 if (rc)
186 ddi_soft_state_fini(&g_pVBoxAddSolarisState);
187 }
188 return rc;
189}
190
191
192int _fini(void)
193{
194 int rc;
195
196 VBA_LOGCONT("_fini\n");
197 rc = mod_remove(&g_VBoxAddSolarisModLinkage);
198 if (!rc)
199 ddi_soft_state_fini(&g_pVBoxAddSolarisState);
200 return rc;
201}
202
203
204int _info(struct modinfo *pModInfo)
205{
206 VBA_LOGCONT("_info\n");
207 return mod_info(&g_VBoxAddSolarisModLinkage, pModInfo);
208}
209
210
211/**
212 * Attach entry point, to attach a device to the system or resume it.
213 *
214 * @param pDip The module structure instance.
215 * @param enmCmd Attach type (ddi_attach_cmd_t)
216 *
217 * @return corresponding solaris error code.
218 */
219static int VBoxAddSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd)
220{
221 VBA_LOGCONT("VBoxAddSolarisAttach\n");
222 switch (enmCmd)
223 {
224 case DDI_ATTACH:
225 {
226 int rc;
227 int instance;
228 VBoxAddDevState *pState;
229
230 instance = ddi_get_instance(pDip);
231 rc = ddi_soft_state_zalloc(g_pVBoxAddSolarisState, instance);
232 if (rc != DDI_SUCCESS)
233 {
234 VBA_LOGNOTE("ddi_soft_state_zalloc failed.\n");
235 return DDI_FAILURE;
236 }
237
238 pState = ddi_get_soft_state(g_pVBoxAddSolarisState, instance);
239 if (!pState)
240 {
241 ddi_soft_state_free(g_pVBoxAddSolarisState, instance);
242 VBA_LOGNOTE("ddi_get_soft_state for instance %d failed\n", instance);
243 return DDI_FAILURE;
244 }
245
246 /*
247 * Initialize IPRT R0 driver, which internally calls OS-specific r0 init.
248 */
249 rc = RTR0Init(0);
250 if (RT_FAILURE(rc))
251 {
252 VBA_LOGNOTE("RTR0Init failed.\n");
253 return DDI_FAILURE;
254 }
255
256 /*
257 * Initialize the session hash table.
258 */
259 rc = RTSpinlockCreate(&g_Spinlock);
260 if (RT_SUCCESS(rc))
261 {
262 /*
263 * Enable resources for PCI access.
264 */
265 rc = pci_config_setup(pDip, &pState->PciHandle);
266 if (rc == DDI_SUCCESS)
267 {
268 /*
269 * Check vendor and device ID.
270 */
271 uint16_t uVendorID = pci_config_get16(pState->PciHandle, PCI_CONF_VENID);
272 uint16_t uDeviceID = pci_config_get16(pState->PciHandle, PCI_CONF_DEVID);
273 if ( uVendorID == VMMDEV_VENDORID
274 && uDeviceID == VMMDEV_DEVICEID)
275 {
276 /*
277 * Verify PCI class of the device (a bit paranoid).
278 */
279 uint8_t uClass = pci_config_get8(pState->PciHandle, PCI_CONF_BASCLASS);
280 uint8_t uSubClass = pci_config_get8(pState->PciHandle, PCI_CONF_SUBCLASS);
281 if ( uClass == PCI_CLASS_PERIPH
282 && uSubClass == PCI_PERIPH_OTHER)
283 {
284 /*
285 * Get register sizes 0 (IO Port) and 1 (MMIO).
286 */
287 off_t cbIOSize;
288 if ( ddi_dev_regsize(pDip, 0, &cbIOSize) == DDI_SUCCESS
289 && ddi_dev_regsize(pDip, 1, &pState->cbMMIO) == DDI_SUCCESS)
290 {
291 /*
292 * Map the register address space.
293 */
294 caddr_t baseAddr;
295 ddi_device_acc_attr_t deviceAttr;
296 deviceAttr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
297 deviceAttr.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC;
298 deviceAttr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
299 deviceAttr.devacc_attr_access = DDI_DEFAULT_ACC;
300 rc = ddi_regs_map_setup(pDip, 0, &baseAddr, 0, cbIOSize, &deviceAttr, &pState->PciHandle);
301 if (rc == DDI_SUCCESS)
302 {
303 pState->uIOPortBase = (uintptr_t)baseAddr;
304 rc = ddi_regs_map_setup(pDip, 1, &baseAddr, 0, pState->cbMMIO, &deviceAttr, &pState->PciHandle);
305 if (rc == DDI_SUCCESS)
306 {
307 /*
308 * Add IRQ of VMMDev.
309 */
310 pState->uPhysMMIOBase = (uint32_t)baseAddr;
311 rc = VBoxGuestSolarisAddIRQ(pDip, pState);
312 if (rc == DDI_SUCCESS)
313 {
314 /*
315 * Create kernel session.
316 */
317 /** @todo this should be done *each* time the device is opened by a client kernel module. */
318 rc = VBoxGuestCreateKernelSession(&g_DevExt, &pState->pKernelSession);
319 pState->u32Version = VMMDEV_VERSION;
320 if (RT_SUCCESS(rc))
321 {
322 /*
323 * Call the common device extension initializer.
324 */
325 rc = VBoxGuestInitDevExt(&g_DevExt, pState->uIOPortBase, NULL, 0, OSTypeSolaris);
326 if (RT_SUCCESS(rc))
327 {
328 rc = ddi_create_minor_node(pDip, DEVICE_NAME, S_IFCHR, instance, DDI_PSEUDO, 0);
329 if (rc == DDI_SUCCESS)
330 {
331 g_pDip = pDip;
332 ddi_set_driver_private(pDip, pState);
333 pci_config_teardown(&pState->PciHandle);
334 ddi_report_dev(pDip);
335 return DDI_SUCCESS;
336 }
337
338 VBA_LOGNOTE("ddi_create_minor_node failed.\n");
339 }
340 else
341 VBA_LOGNOTE("VBoxGuestInitDevExt failed.\n");
342 }
343 else
344 VBA_LOGNOTE("VBoxGuestCreateKernelSession failed.\n");
345 VBoxGuestSolarisRemoveIRQ(pDip, pState);
346 }
347 else
348 VBA_LOGNOTE("VBoxGuestSolarisAddIRQ failed.\n");
349 }
350 else
351 VBA_LOGNOTE("ddi_regs_map_setup for MMIO region failed.\n");
352 ddi_regs_map_free(&pState->PciHandle);
353 }
354 else
355 VBA_LOGNOTE("ddi_regs_map_setup for IOport failed.\n");
356 }
357 else
358 VBA_LOGNOTE("ddi_dev_regsize failed.\n");
359 }
360 else
361 VBA_LOGNOTE("PCI class/sub-class does not match.\n");
362 }
363 else
364 VBA_LOGNOTE("PCI vendorID, deviceID does not match.\n");
365 pci_config_teardown(&pState->PciHandle);
366 }
367 else
368 VBA_LOGNOTE("pci_config_setup failed.\n");
369 RTSpinlockDestroy(g_Spinlock);
370 g_Spinlock = NIL_RTSPINLOCK;
371 }
372 else
373 VBA_LOGNOTE("RTSpinlockCreate failed.\n");
374
375 RTR0Term();
376 return DDI_FAILURE;
377 }
378
379 case DDI_RESUME:
380 {
381 /** @todo implement resume for guest driver. */
382 return DDI_SUCCESS;
383 }
384
385 default:
386 return DDI_FAILURE;
387 }
388}
389
390
391/**
392 * Detach entry point, to detach a device to the system or suspend it.
393 *
394 * @param pDip The module structure instance.
395 * @param enmCmd Attach type (ddi_attach_cmd_t)
396 *
397 * @return corresponding solaris error code.
398 */
399static int VBoxAddSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd)
400{
401 VBA_LOGCONT("VBoxAddSolarisDetach\n");
402 switch (enmCmd)
403 {
404 case DDI_DETACH:
405 {
406 int rc;
407 int instance = ddi_get_instance(pDip);
408 VBoxAddDevState *pState = ddi_get_soft_state(pDip, instance);
409
410 VBoxGuestSolarisRemoveIRQ(pDip, pState);
411 ddi_regs_map_free(&pState->PciHandle);
412 ddi_remove_minor_node(pDip, NULL);
413 ddi_soft_state_free(g_pVBoxAddSolarisState, instance);
414
415 rc = RTSpinlockDestroy(g_Spinlock);
416 AssertRC(rc);
417 g_Spinlock = NIL_RTSPINLOCK;
418
419 RTR0Term();
420 return DDI_SUCCESS;
421 }
422
423 case DDI_SUSPEND:
424 {
425 /** @todo implement suspend for guest driver. */
426 return DDI_SUCCESS;
427 }
428
429 default:
430 return DDI_FAILURE;
431 }
432}
433
434
435/**
436 * User context entry points
437 */
438static int VBoxAddSolarisOpen(dev_t *pDev, int fFlag, int fType, cred_t *pCred)
439{
440 int rc;
441 PVBOXGUESTSESSION pSession;
442
443 VBA_LOGCONT("VBoxAddSolarisOpen\n");
444
445 /*
446 * Create a new session.
447 */
448 rc = VBoxGuestCreateUserSession(&g_DevExt, &pSession);
449 if (RT_SUCCESS(rc))
450 {
451 /*
452 * Insert it into the hash table.
453 */
454 unsigned iHash = SESSION_HASH(pSession->Process);
455 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
456 RTSpinlockAcquireNoInts(g_Spinlock, &Tmp);
457 pSession->pNextHash = g_apSessionHashTab[iHash];
458 g_apSessionHashTab[iHash] = pSession;
459 RTSpinlockReleaseNoInts(g_Spinlock, &Tmp);
460
461 Log(("VBoxAddSolarisOpen: g_DevExt=%p pSession=%p rc=%d pid=%d\n", &g_DevExt, pSession, rc, (int)RTProcSelf()));
462 return 0;
463 }
464 LogRel(("VBoxAddSolarisOpen: VBoxGuestCreateUserSession failed. rc=%d\n", rc));
465 return rc;
466}
467
468
469static int VBoxAddSolarisClose(dev_t Dev, int flag, int fType, cred_t *pCred)
470{
471 VBA_LOGCONT("VBoxAddSolarisClose pid=%d=%d\n", (int)RTProcSelf());
472
473 /*
474 * Remove from the hash table.
475 */
476 PVBOXGUESTSESSION pSession;
477 const RTPROCESS Process = RTProcSelf();
478 const unsigned iHash = SESSION_HASH(Process);
479 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
480 RTSpinlockAcquireNoInts(g_Spinlock, &Tmp);
481
482 pSession = g_apSessionHashTab[iHash];
483 if (pSession)
484 {
485 if (pSession->Process == Process)
486 {
487 g_apSessionHashTab[iHash] = pSession->pNextHash;
488 pSession->pNextHash = NULL;
489 }
490 else
491 {
492 PVBOXGUESTSESSION pPrev = pSession;
493 pSession = pSession->pNextHash;
494 while (pSession)
495 {
496 if (pSession->Process == Process)
497 {
498 pPrev->pNextHash = pSession->pNextHash;
499 pSession->pNextHash = NULL;
500 break;
501 }
502
503 /* next */
504 pPrev = pSession;
505 pSession = pSession->pNextHash;
506 }
507 }
508 }
509 RTSpinlockReleaseNoInts(g_Spinlock, &Tmp);
510 if (!pSession)
511 {
512 Log(("VBoxGuestIoctl: WHUT?!? pSession == NULL! This must be a mistake... pid=%d", (int)Process));
513 return VERR_INVALID_PARAMETER;
514 }
515
516 /*
517 * Close the session.
518 */
519 VBoxGuestCloseSession(&g_DevExt, pSession);
520 return 0;
521}
522
523
524static int VBoxAddSolarisRead(dev_t Dev, struct uio *pUio, cred_t *pCred)
525{
526 VBA_LOGCONT("VBoxAddSolarisRead\n");
527 return DDI_SUCCESS;
528}
529
530
531static int VBoxAddSolarisWrite(dev_t Dev, struct uio *pUio, cred_t *pCred)
532{
533 VBA_LOGCONT("VBoxAddSolarisWrite\n");
534 return DDI_SUCCESS;
535}
536
537
538/**
539 * Driver ioctl, an alternate entry point for this character driver.
540 *
541 * @param Dev Device number
542 * @param Cmd Operation identifier
543 * @param pArg Arguments from user to driver
544 * @param Mode Information bitfield (read/write, address space etc.)
545 * @param pCred User credentials
546 * @param pVal Return value for calling process.
547 *
548 * @return corresponding solaris error code.
549 */
550static int VBoxAddSolarisIOCtl(dev_t Dev, int Cmd, intptr_t pArgs, int Mode, cred_t *pCred, int *pVal)
551{
552 VBA_LOGCONT("VBoxAddSolarisIOCtl\n");
553 return DDI_SUCCESS;
554}
555
556
557/**
558 * Sets IRQ for VMMDev.
559 *
560 * @returns Solaris error code.
561 * @param pDip Pointer to the device info structure.
562 * @param pvState Pointer to the state info structure.
563 */
564static int VBoxGuestSolarisAddIRQ(dev_info_t *pDip, void *pvState)
565{
566 int rc;
567 VBoxAddDevState *pState = (VBoxAddDevState *)pvState;
568 VBA_LOGCONT("VBoxGuestSolarisAddIRQ\n");
569
570 /*
571 * These calls are supposedly deprecated. But Sun seems to use them all over
572 * the place. Anyway, once this works we will switch to the highly elaborate
573 * and non-obsolete way of setting up IRQs.
574 */
575 rc = ddi_get_iblock_cookie(pDip, 0, &pState->BlockCookie);
576 if (rc == DDI_SUCCESS)
577 {
578 mutex_init(&pState->Mtx, "VBoxGuest Driver Mutex", MUTEX_DRIVER, (void *)pState->BlockCookie);
579 rc = ddi_add_intr(pDip, 0, &pState->BlockCookie, NULL, VBoxGuestSolarisISR, (caddr_t)pState);
580 if (rc != DDI_SUCCESS)
581 VBA_LOGNOTE("ddi_add_intr failed. Cannot set IRQ for VMMDev.\n");
582 }
583 else
584 VBA_LOGNOTE("ddi_get_iblock_cookie failed. Cannot set IRQ for VMMDev.\n");
585 return rc;
586}
587
588
589/**
590 * Removes IRQ for VMMDev.
591 *
592 * @param pDip Pointer to the device info structure.
593 * @param pvState Opaque pointer to the state info structure.
594 */
595static void VBoxGuestSolarisRemoveIRQ(dev_info_t *pDip, void *pvState)
596{
597 VBA_LOGCONT("VBoxGuestSolarisRemoveIRQ\n");
598
599 VBoxAddDevState *pState = (VBoxAddDevState *)pvState;
600 ddi_remove_intr(pDip, 0, pState->BlockCookie);
601 mutex_destroy(&pState->Mtx);
602}
603
604
605/**
606 * Interrupt Service Routine for VMMDev.
607 *
608 * @returns DDI_INTR_CLAIMED if it's our interrupt, DDI_INTR_UNCLAIMED if it isn't.
609 */
610static uint_t VBoxGuestSolarisISR(caddr_t Arg)
611{
612 VBA_LOGCONT("VBoxGuestSolarisISR\n");
613
614 VBoxAddDevState *pState = (VBoxAddDevState *)Arg;
615 mutex_enter(&pState->Mtx);
616 bool fOurIRQ = VBoxGuestCommonISR(&g_DevExt);
617 mutex_exit(&pState->Mtx);
618
619 return fOurIRQ ? DDI_INTR_CLAIMED : DDI_INTR_CLAIMED;
620}
621
622
623/**
624 * VBoxGuest Common ioctl wrapper from VBoxGuestLib.
625 *
626 * @returns VBox error code.
627 * @param pvState Opaque pointer to the state info structure.
628 * @param iCmd Requested function.
629 * @param pvData IO data buffer.
630 * @param cbData Size of the data buffer.
631 * @param pcbDataReturned Where to store the amount of returned data.
632 */
633DECLVBGL(int) VBoxGuestSolarisServiceCall(void *pvState, unsigned iCmd, void *pvData, size_t cbData, size_t *pcbDataReturned)
634{
635 VBA_LOGCONT("VBoxGuestSolarisServiceCall\n");
636
637 VBoxAddDevState *pState = (VBoxAddDevState *)pvState;
638 AssertPtrReturn(pState, VERR_INVALID_POINTER);
639 AssertPtrReturn(pState->pKernelSession, VERR_INVALID_POINTER);
640 AssertMsgReturn(pState->pKernelSession->pDevExt == &g_DevExt,
641 ("SC: %p != %p\n", pState->pKernelSession->pDevExt, &g_DevExt), VERR_INVALID_HANDLE);
642
643 return VBoxGuestCommonIOCtl(iCmd, &g_DevExt, pState->pKernelSession, pvData, cbData, pcbDataReturned);
644}
645
646
647/**
648 * Solaris Guest service open.
649 *
650 * @returns Opaque pointer to driver state info structure.
651 * @param pu32Version Where to store VMMDev version.
652 */
653DECLVBGL(void *) VBoxGuestSolarisServiceOpen(uint32_t *pu32Version)
654{
655 VBA_LOGCONT("VBoxGuestSolarisServiceOpen\n");
656
657 /** @todo See the comment where pKernelSession is initialized.
658 * This is the same call as VBoxGuestOS2IDCConnect */
659 VBoxAddDevState *pState = ddi_get_driver_private(g_pDip);
660 AssertPtrReturn(pState, NULL);
661
662 if (pState)
663 {
664 *pu32Version = VMMDEV_VERSION;
665 return pState;
666 }
667 return NULL;
668}
669
670
671/**
672 * Solaris Guest service close.
673 *
674 * @param pvState Opaque pointer to the state info structure.
675 */
676DECLVBGL(void) VBoxGuestSolarisServiceClose(void *pvState)
677{
678 /** @todo Must close the session created above.
679 * This is the same call as VBoxGuestOS2IDCService / case VBOXGUEST_IOCTL_OS2_IDC_DISCONNECT. */
680 VBA_LOGCONT("VBoxGuestSolarisServiceClosel\n");
681 NOREF(pvState);
682}
683
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