SUPDrv-solaris.c revision 43bb4d90097ef9a9d7fc597315d0869427609694
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync/* $Id$ */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync/** @file
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * VBoxDrv - The VirtualBox Support Driver - Solaris specifics.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync/*
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync *
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * available from http://www.virtualbox.org. This file is free software;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * you can redistribute it and/or modify it under the terms of the GNU
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * General Public License (GPL) as published by the Free Software
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync *
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * The contents of this file may alternatively be used under the terms
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * of the Common Development and Distribution License Version 1.0
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * VirtualBox OSE distribution, in which case the provisions of the
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * CDDL are applicable instead of those of the GPL.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync *
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * You may elect to license modified versions of this file under the
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * terms and conditions of either the GPL or the CDDL or both.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync *
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * additional information or have any questions.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync */
c8bcebedf264bc1287bcce50bdf66d08e28a88dcvboxsync
5debbbcc37114f1dbecaecfc66c81ea2fbda6140vboxsync/*******************************************************************************
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync* Header Files *
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync*******************************************************************************/
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync#define LOG_GROUP LOG_GROUP_SUP_DRV
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync#include <sys/types.h>
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync#include <sys/param.h>
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync#include <sys/errno.h>
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync#include <sys/uio.h>
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync#include <sys/buf.h>
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync#include <sys/modctl.h>
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync#include <sys/open.h>
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync#include <sys/conf.h>
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync#include <sys/cmn_err.h>
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync#include <sys/stat.h>
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync#include <sys/ddi.h>
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync#include <sys/sunddi.h>
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync#include <sys/file.h>
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync#include <sys/priv_names.h>
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync#undef u /* /usr/include/sys/user.h:249:1 is where this is defined to (curproc->p_user). very cool. */
d44cb80e1d772854c10ef9ae03daba8dcf61d389vboxsync
d44cb80e1d772854c10ef9ae03daba8dcf61d389vboxsync#include "../SUPDrvInternal.h"
d44cb80e1d772854c10ef9ae03daba8dcf61d389vboxsync#include <VBox/log.h>
d44cb80e1d772854c10ef9ae03daba8dcf61d389vboxsync#include <VBox/version.h>
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync#include <iprt/semaphore.h>
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync#include <iprt/spinlock.h>
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync#include <iprt/mp.h>
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync#include <iprt/process.h>
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync#include <iprt/thread.h>
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync#include <iprt/initterm.h>
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync#include <iprt/alloc.h>
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync#include <iprt/string.h>
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync#include <iprt/err.h>
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync/*******************************************************************************
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync* Defined Constants And Macros *
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync*******************************************************************************/
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync/** @todo this quoting macros probably should be moved to a common place.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * The indirection is for expanding macros passed to the first macro. */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync#define VBOXSOLQUOTE2(x) #x
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync#define VBOXSOLQUOTE(x) VBOXSOLQUOTE2(x)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync/** The module name. */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync#define DEVICE_NAME "vboxdrv"
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync/** The module description as seen in 'modinfo'. */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync#define DEVICE_DESC "VirtualBox HostDrv"
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync/** Maximum number of driver instances. */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync#define DEVICE_MAXINSTANCES 16
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync/*******************************************************************************
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync* Internal Functions *
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync*******************************************************************************/
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncstatic int VBoxDrvSolarisOpen(dev_t *pDev, int fFlag, int fType, cred_t *pCred);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncstatic int VBoxDrvSolarisClose(dev_t Dev, int fFlag, int fType, cred_t *pCred);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncstatic int VBoxDrvSolarisRead(dev_t Dev, struct uio *pUio, cred_t *pCred);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncstatic int VBoxDrvSolarisWrite(dev_t Dev, struct uio *pUio, cred_t *pCred);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncstatic int VBoxDrvSolarisIOCtl(dev_t Dev, int Cmd, intptr_t pArgs, int mode, cred_t *pCred, int *pVal);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncstatic int VBoxDrvSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t Cmd);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncstatic int VBoxDrvSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t Cmd);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncstatic int VBoxSupDrvErr2SolarisErr(int rc);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncstatic int VBoxDrvSolarisIOCtlSlow(PSUPDRVSESSION pSession, int Cmd, int Mode, intptr_t pArgs);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync/*******************************************************************************
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync* Global Variables *
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync*******************************************************************************/
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync/**
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * cb_ops: for drivers that support char/block entry points
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncstatic struct cb_ops g_VBoxDrvSolarisCbOps =
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync{
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync VBoxDrvSolarisOpen,
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync VBoxDrvSolarisClose,
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync nodev, /* b strategy */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync nodev, /* b dump */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync nodev, /* b print */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync VBoxDrvSolarisRead,
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync VBoxDrvSolarisWrite,
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync VBoxDrvSolarisIOCtl,
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync nodev, /* c devmap */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync nodev, /* c mmap */
e7e60b177e688900656c04404c5123f1dfa1d02cvboxsync nodev, /* c segmap */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync nochpoll, /* c poll */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync ddi_prop_op, /* property ops */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync NULL, /* streamtab */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync D_NEW | D_MP, /* compat. flag */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync CB_REV /* revision */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync};
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync/**
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * dev_ops: for driver device operations
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync */
ada022f71e6728d4f2b15e643d35aa94992656c7vboxsyncstatic struct dev_ops g_VBoxDrvSolarisDevOps =
bf4de0c2965291e927412f708c6c27eeeb5825d4vboxsync{
bf4de0c2965291e927412f708c6c27eeeb5825d4vboxsync DEVO_REV, /* driver build revision */
bf4de0c2965291e927412f708c6c27eeeb5825d4vboxsync 0, /* ref count */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync nulldev, /* get info */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync nulldev, /* identify */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync nulldev, /* probe */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync VBoxDrvSolarisAttach,
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync VBoxDrvSolarisDetach,
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync nodev, /* reset */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync &g_VBoxDrvSolarisCbOps,
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync (struct bus_ops *)0,
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync nodev /* power */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync};
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync/**
bf4de0c2965291e927412f708c6c27eeeb5825d4vboxsync * modldrv: export driver specifics to the kernel
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncstatic struct modldrv g_VBoxDrvSolarisModule =
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync{
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync &mod_driverops, /* extern from kernel */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync DEVICE_DESC " " VBOX_VERSION_STRING "r" VBOXSOLQUOTE(VBOX_SVN_REV),
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync &g_VBoxDrvSolarisDevOps
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync};
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync/**
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * modlinkage: export install/remove/info to the kernel
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncstatic struct modlinkage g_VBoxDrvSolarisModLinkage =
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync{
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync MODREV_1, /* loadable module system revision */
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync &g_VBoxDrvSolarisModule,
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync NULL /* terminate array of linkage structures */
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync};
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync#ifndef USE_SESSION_HASH
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync/**
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * State info for each open file handle.
e7e60b177e688900656c04404c5123f1dfa1d02cvboxsync */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsynctypedef struct
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync{
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /**< Pointer to the session data. */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync PSUPDRVSESSION pSession;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync} vbox_devstate_t;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync#else
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync/** State info. for each driver instance. */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsynctypedef struct
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync{
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync dev_info_t *pDip; /* Device handle */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync} vbox_devstate_t;
bf4de0c2965291e927412f708c6c27eeeb5825d4vboxsync#endif
bf4de0c2965291e927412f708c6c27eeeb5825d4vboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync/** Opaque pointer to list of state */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncstatic void *g_pVBoxDrvSolarisState;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync/** Device extention & session data association structure */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncstatic SUPDRVDEVEXT g_DevExt;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync/** Hash table */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncstatic PSUPDRVSESSION g_apSessionHashTab[19];
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync/** Spinlock protecting g_apSessionHashTab. */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncstatic RTSPINLOCK g_Spinlock = NIL_RTSPINLOCK;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync/** Calculates bucket index into g_apSessionHashTab.*/
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync#define SESSION_HASH(sfn) ((sfn) % RT_ELEMENTS(g_apSessionHashTab))
bf4de0c2965291e927412f708c6c27eeeb5825d4vboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync/**
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * Kernel entry points
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncint _init(void)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync{
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync LogFlow((DEVICE_NAME ":_init\n"));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /*
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync * Prevent module autounloading.
9f9eff04f209bd905529ee3b76076e55568db917vboxsync */
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync modctl_t *pModCtl = mod_getctl(&g_VBoxDrvSolarisModLinkage);
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync if (pModCtl)
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync pModCtl->mod_loadflags |= MOD_NOAUTOUNLOAD;
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync else
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync LogRel((DEVICE_NAME ":failed to disable autounloading!\n"));
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync /*
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync * Initialize IPRT R0 driver, which internally calls OS-specific r0 init.
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync */
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync int rc = RTR0Init(0);
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync if (RT_SUCCESS(rc))
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync {
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync /*
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync * Initialize the device extension
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync */
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync rc = supdrvInitDevExt(&g_DevExt);
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync if (RT_SUCCESS(rc))
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync {
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync /*
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync * Initialize the session hash table.
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync */
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync memset(g_apSessionHashTab, 0, sizeof(g_apSessionHashTab));
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync rc = RTSpinlockCreate(&g_Spinlock);
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync if (RT_SUCCESS(rc))
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync {
9f9eff04f209bd905529ee3b76076e55568db917vboxsync int rc = ddi_soft_state_init(&g_pVBoxDrvSolarisState, sizeof(vbox_devstate_t), 8);
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync if (!rc)
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync {
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync rc = mod_install(&g_VBoxDrvSolarisModLinkage);
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync if (!rc)
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync return rc; /* success */
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync ddi_soft_state_fini(&g_pVBoxDrvSolarisState);
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync LogRel((DEVICE_NAME ":mod_install failed! rc=%d\n", rc));
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync }
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync else
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync LogRel((DEVICE_NAME ":failed to initialize soft state.\n"));
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync RTSpinlockDestroy(g_Spinlock);
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync g_Spinlock = NIL_RTSPINLOCK;
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync }
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync else
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync LogRel((DEVICE_NAME ":VBoxDrvSolarisAttach: RTSpinlockCreate failed\n"));
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync supdrvDeleteDevExt(&g_DevExt);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync else
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync LogRel((DEVICE_NAME ":VBoxDrvSolarisAttach: supdrvInitDevExt failed\n"));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync RTR0Term();
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync else
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync LogRel((DEVICE_NAME ":VBoxDrvSolarisAttach: failed to init R0Drv\n"));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync memset(&g_DevExt, 0, sizeof(g_DevExt));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync return RTErrConvertToErrno(rc);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync}
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsyncint _fini(void)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync{
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync LogFlow((DEVICE_NAME ":_fini\n"));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /*
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync * Undo the work we did at start (in the reverse order).
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync int rc = mod_remove(&g_VBoxDrvSolarisModLinkage);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (rc != 0)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync return rc;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync supdrvDeleteDevExt(&g_DevExt);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync rc = RTSpinlockDestroy(g_Spinlock);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync AssertRC(rc);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync g_Spinlock = NIL_RTSPINLOCK;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync RTR0Term();
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync memset(&g_DevExt, 0, sizeof(g_DevExt));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync ddi_soft_state_fini(&g_pVBoxDrvSolarisState);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync return 0;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync}
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
bf4de0c2965291e927412f708c6c27eeeb5825d4vboxsyncint _info(struct modinfo *pModInfo)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync{
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync LogFlow((DEVICE_NAME ":_info\n"));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync int e = mod_info(&g_VBoxDrvSolarisModLinkage, pModInfo);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync return e;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync}
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync/**
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * Attach entry point, to attach a device to the system or resume it.
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync *
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * @param pDip The module structure instance.
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * @param enmCmd Operation type (attach/resume).
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync *
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * @return corresponding solaris error code.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncstatic int VBoxDrvSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd)
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync{
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync LogFlow((DEVICE_NAME ":VBoxDrvSolarisAttach\n"));
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync switch (enmCmd)
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync {
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync case DDI_ATTACH:
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync {
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync int rc;
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync int instance = ddi_get_instance(pDip);
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync#ifdef USE_SESSION_HASH
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync vbox_devstate_t *pState;
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync if (ddi_soft_state_zalloc(g_pVBoxDrvSolarisState, instance) != DDI_SUCCESS)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync LogRel((DEVICE_NAME ":VBoxDrvSolarisAttach: state alloc failed\n"));
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync return DDI_FAILURE;
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync }
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync pState = ddi_get_soft_state(g_pVBoxDrvSolarisState, instance);
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync#endif
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync /*
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * Register ourselves as a character device, pseudo-driver
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync */
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync#ifdef VBOX_WITH_HARDENING
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync rc = ddi_create_priv_minor_node(pDip, DEVICE_NAME, S_IFCHR, instance, DDI_PSEUDO,
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync 0, NULL, NULL, 0600);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync#else
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync rc = ddi_create_priv_minor_node(pDip, DEVICE_NAME, S_IFCHR, instance, DDI_PSEUDO,
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync 0, "none", "none", 0666);
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync#endif
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync if (rc == DDI_SUCCESS)
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync {
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync#ifdef USE_SESSION_HASH
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync pState->pDip = pDip;
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync#endif
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync ddi_report_dev(pDip);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync return DDI_SUCCESS;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync return DDI_FAILURE;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync case DDI_RESUME:
e7e60b177e688900656c04404c5123f1dfa1d02cvboxsync {
243041cd7eae9f34b08e7340533b2a88218ee57evboxsync RTSemFastMutexRequest(g_DevExt.mtxGip);
e7e60b177e688900656c04404c5123f1dfa1d02cvboxsync if (g_DevExt.pGipTimer)
e7e60b177e688900656c04404c5123f1dfa1d02cvboxsync RTTimerStart(g_DevExt.pGipTimer, 0);
e7e60b177e688900656c04404c5123f1dfa1d02cvboxsync
e7e60b177e688900656c04404c5123f1dfa1d02cvboxsync RTSemFastMutexRelease(g_DevExt.mtxGip);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync return DDI_SUCCESS;
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync }
243041cd7eae9f34b08e7340533b2a88218ee57evboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync default:
243041cd7eae9f34b08e7340533b2a88218ee57evboxsync return DDI_FAILURE;
243041cd7eae9f34b08e7340533b2a88218ee57evboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync return DDI_FAILURE;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync}
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
243041cd7eae9f34b08e7340533b2a88218ee57evboxsync/**
243041cd7eae9f34b08e7340533b2a88218ee57evboxsync * Detach entry point, to detach a device to the system or suspend it.
243041cd7eae9f34b08e7340533b2a88218ee57evboxsync *
243041cd7eae9f34b08e7340533b2a88218ee57evboxsync * @param pDip The module structure instance.
e7e60b177e688900656c04404c5123f1dfa1d02cvboxsync * @param enmCmd Operation type (detach/suspend).
243041cd7eae9f34b08e7340533b2a88218ee57evboxsync *
e61cd03db2217b7ec7467065af02d7ea7549149evboxsync * @return corresponding solaris error code.
243041cd7eae9f34b08e7340533b2a88218ee57evboxsync */
243041cd7eae9f34b08e7340533b2a88218ee57evboxsyncstatic int VBoxDrvSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd)
e61cd03db2217b7ec7467065af02d7ea7549149evboxsync{
243041cd7eae9f34b08e7340533b2a88218ee57evboxsync int rc = VINF_SUCCESS;
243041cd7eae9f34b08e7340533b2a88218ee57evboxsync
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync LogFlow((DEVICE_NAME ":VBoxDrvSolarisDetach\n"));
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync switch (enmCmd)
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync {
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync case DDI_DETACH:
243041cd7eae9f34b08e7340533b2a88218ee57evboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync int instance = ddi_get_instance(pDip);
243041cd7eae9f34b08e7340533b2a88218ee57evboxsync#ifndef USE_SESSION_HASH
243041cd7eae9f34b08e7340533b2a88218ee57evboxsync ddi_remove_minor_node(pDip, NULL);
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync#else
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync vbox_devstate_t *pState = ddi_get_soft_state(g_pVBoxDrvSolarisState, instance);
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync ddi_remove_minor_node(pDip, NULL);
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync ddi_soft_state_free(g_pVBoxDrvSolarisState, instance);
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync#endif
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync return DDI_SUCCESS;
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync }
e61cd03db2217b7ec7467065af02d7ea7549149evboxsync
243041cd7eae9f34b08e7340533b2a88218ee57evboxsync case DDI_SUSPEND:
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync RTSemFastMutexRequest(g_DevExt.mtxGip);
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync if (g_DevExt.pGipTimer && g_DevExt.cGipUsers > 0)
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync RTTimerStop(g_DevExt.pGipTimer);
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync RTSemFastMutexRelease(g_DevExt.mtxGip);
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync return DDI_SUCCESS;
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync }
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync default:
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync return DDI_FAILURE;
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync }
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync}
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync
243041cd7eae9f34b08e7340533b2a88218ee57evboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync/**
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * User context entry points
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncstatic int VBoxDrvSolarisOpen(dev_t *pDev, int fFlag, int fType, cred_t *pCred)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync{
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync int rc;
243041cd7eae9f34b08e7340533b2a88218ee57evboxsync PSUPDRVSESSION pSession;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync LogFlow((DEVICE_NAME ":VBoxDrvSolarisOpen: pDev=%p:%#x\n", pDev, *pDev));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync#ifndef USE_SESSION_HASH
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /*
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * Locate a new device open instance.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync *
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * For each open call we'll allocate an item in the soft state of the device.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * The item index is stored in the dev_t. I hope this is ok...
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync vbox_devstate_t *pState = NULL;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync unsigned iOpenInstance;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync for (iOpenInstance = 0; iOpenInstance < 4096; iOpenInstance++)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if ( !ddi_get_soft_state(g_pVBoxDrvSolarisState, iOpenInstance) /* faster */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync && ddi_soft_state_zalloc(g_pVBoxDrvSolarisState, iOpenInstance) == DDI_SUCCESS)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync pState = ddi_get_soft_state(g_pVBoxDrvSolarisState, iOpenInstance);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync break;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync if (!pState)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync LogRel((DEVICE_NAME ":VBoxDrvSolarisOpen: too many open instances.\n"));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync return ENXIO;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /*
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * Create a new session.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync rc = supdrvCreateSession(&g_DevExt, true /* fUser */, &pSession);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (RT_SUCCESS(rc))
bf4de0c2965291e927412f708c6c27eeeb5825d4vboxsync {
bf4de0c2965291e927412f708c6c27eeeb5825d4vboxsync pSession->Uid = crgetruid(pCred);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync pSession->Gid = crgetrgid(pCred);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
bf4de0c2965291e927412f708c6c27eeeb5825d4vboxsync pState->pSession = pSession;
bf4de0c2965291e927412f708c6c27eeeb5825d4vboxsync *pDev = makedevice(getmajor(*pDev), iOpenInstance);
bf4de0c2965291e927412f708c6c27eeeb5825d4vboxsync LogFlow((DEVICE_NAME ":VBoxDrvSolarisOpen: Dev=%#x pSession=%p pid=%d r0proc=%p thread=%p\n",
bf4de0c2965291e927412f708c6c27eeeb5825d4vboxsync *pDev, pSession, RTProcSelf(), RTR0ProcHandleSelf(), RTThreadNativeSelf() ));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync return 0;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
bf4de0c2965291e927412f708c6c27eeeb5825d4vboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* failed - clean up */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync ddi_soft_state_free(g_pVBoxDrvSolarisState, iOpenInstance);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
bf4de0c2965291e927412f708c6c27eeeb5825d4vboxsync#else
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /*
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * Create a new session.
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync * Sessions in Solaris driver are mostly useless. It's however needed
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync * in VBoxDrvSolarisIOCtlSlow() while calling supdrvIOCtl()
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync */
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync rc = supdrvCreateSession(&g_DevExt, true /* fUser */, &pSession);
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync if (RT_SUCCESS(rc))
0c436e66dac8edc81d43b54cd878ed239a63574bvboxsync {
0c436e66dac8edc81d43b54cd878ed239a63574bvboxsync RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync unsigned iHash;
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync pSession->Uid = crgetruid(pCred);
0c436e66dac8edc81d43b54cd878ed239a63574bvboxsync pSession->Gid = crgetrgid(pCred);
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync /*
0c436e66dac8edc81d43b54cd878ed239a63574bvboxsync * Insert it into the hash table.
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync */
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync iHash = SESSION_HASH(pSession->Process);
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync RTSpinlockAcquireNoInts(g_Spinlock, &Tmp);
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync pSession->pNextHash = g_apSessionHashTab[iHash];
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync g_apSessionHashTab[iHash] = pSession;
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync RTSpinlockReleaseNoInts(g_Spinlock, &Tmp);
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync LogFlow((DEVICE_NAME ":VBoxDrvSolarisOpen success\n"));
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync }
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync int instance;
0c436e66dac8edc81d43b54cd878ed239a63574bvboxsync for (instance = 0; instance < DEVICE_MAXINSTANCES; instance++)
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync {
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync vbox_devstate_t *pState = ddi_get_soft_state(g_pVBoxDrvSolarisState, instance);
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync if (pState)
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync break;
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync }
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync if (instance >= DEVICE_MAXINSTANCES)
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync {
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync LogRel((DEVICE_NAME ":VBoxDrvSolarisOpen: All instances exhausted\n"));
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync return ENXIO;
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync }
bf4de0c2965291e927412f708c6c27eeeb5825d4vboxsync
bf4de0c2965291e927412f708c6c27eeeb5825d4vboxsync *pDev = makedevice(getmajor(*pDev), instance);
0c436e66dac8edc81d43b54cd878ed239a63574bvboxsync
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync return VBoxSupDrvErr2SolarisErr(rc);
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync#endif
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync}
bf4de0c2965291e927412f708c6c27eeeb5825d4vboxsync
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsyncstatic int VBoxDrvSolarisClose(dev_t Dev, int flag, int otyp, cred_t *cred)
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync{
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync LogFlow((DEVICE_NAME ":VBoxDrvSolarisClose: Dev=%#x\n", Dev));
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync#ifndef USE_SESSION_HASH
0c436e66dac8edc81d43b54cd878ed239a63574bvboxsync /*
0c436e66dac8edc81d43b54cd878ed239a63574bvboxsync * Get the session and free the soft state item.
0c436e66dac8edc81d43b54cd878ed239a63574bvboxsync */
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync vbox_devstate_t *pState = ddi_get_soft_state(g_pVBoxDrvSolarisState, getminor(Dev));
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync if (!pState)
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync {
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync LogRel((DEVICE_NAME ":VBoxDrvSolarisClose: no state data for %#x (%d)\n", Dev, getminor(Dev)));
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync return EFAULT;
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync }
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync PSUPDRVSESSION pSession = pState->pSession;
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync pState->pSession = NULL;
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync ddi_soft_state_free(g_pVBoxDrvSolarisState, getminor(Dev));
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync if (!pSession)
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync {
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync LogRel((DEVICE_NAME ":VBoxDrvSolarisClose: no session in state data for %#x (%d)\n", Dev, getminor(Dev)));
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync return EFAULT;
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync }
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync LogFlow((DEVICE_NAME ":VBoxDrvSolarisClose: Dev=%#x pSession=%p pid=%d r0proc=%p thread=%p\n",
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync Dev, pSession, RTProcSelf(), RTR0ProcHandleSelf(), RTThreadNativeSelf() ));
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync#else
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync const RTPROCESS Process = RTProcSelf();
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync const unsigned iHash = SESSION_HASH(Process);
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync PSUPDRVSESSION pSession;
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync /*
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync * Remove from the hash table.
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync */
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync RTSpinlockAcquireNoInts(g_Spinlock, &Tmp);
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync pSession = g_apSessionHashTab[iHash];
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync if (pSession)
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync {
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync if (pSession->Process == Process)
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync {
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync g_apSessionHashTab[iHash] = pSession->pNextHash;
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync pSession->pNextHash = NULL;
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync }
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync else
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync {
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync PSUPDRVSESSION pPrev = pSession;
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync pSession = pSession->pNextHash;
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync while (pSession)
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync {
9ee72227058430bcead5831131741b5dc1601f00vboxsync if (pSession->Process == Process)
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync {
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync pPrev->pNextHash = pSession->pNextHash;
9ee72227058430bcead5831131741b5dc1601f00vboxsync pSession->pNextHash = NULL;
9ee72227058430bcead5831131741b5dc1601f00vboxsync break;
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync }
9ee72227058430bcead5831131741b5dc1601f00vboxsync
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync /* next */
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync pPrev = pSession;
7c930c3ee58f55e1a2cebfa2ad3ae918569a8f44vboxsync pSession = pSession->pNextHash;
9ee72227058430bcead5831131741b5dc1601f00vboxsync }
7c930c3ee58f55e1a2cebfa2ad3ae918569a8f44vboxsync }
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync }
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync RTSpinlockReleaseNoInts(g_Spinlock, &Tmp);
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync if (!pSession)
bf4de0c2965291e927412f708c6c27eeeb5825d4vboxsync {
bf4de0c2965291e927412f708c6c27eeeb5825d4vboxsync LogRel((DEVICE_NAME ":VBoxDrvSolarisClose: WHAT?!? pSession == NULL! This must be a mistake... pid=%d (close)\n",
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync (int)Process));
9ee72227058430bcead5831131741b5dc1601f00vboxsync return EFAULT;
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync }
7c930c3ee58f55e1a2cebfa2ad3ae918569a8f44vboxsync#endif
9ee72227058430bcead5831131741b5dc1601f00vboxsync
bf4de0c2965291e927412f708c6c27eeeb5825d4vboxsync /*
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * Close the session.
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync */
bf4de0c2965291e927412f708c6c27eeeb5825d4vboxsync supdrvCloseSession(&g_DevExt, pSession);
bf4de0c2965291e927412f708c6c27eeeb5825d4vboxsync return 0;
bf4de0c2965291e927412f708c6c27eeeb5825d4vboxsync}
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync
bf4de0c2965291e927412f708c6c27eeeb5825d4vboxsync
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsyncstatic int VBoxDrvSolarisRead(dev_t Dev, struct uio *pUio, cred_t *pCred)
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync{
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync LogFlow((DEVICE_NAME ":VBoxDrvSolarisRead"));
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync return 0;
7c930c3ee58f55e1a2cebfa2ad3ae918569a8f44vboxsync}
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsyncstatic int VBoxDrvSolarisWrite(dev_t Dev, struct uio *pUio, cred_t *pCred)
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync{
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync LogFlow((DEVICE_NAME ":VBoxDrvSolarisWrite"));
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync return 0;
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync}
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync/**
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync * Driver ioctl, an alternate entry point for this character driver.
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync *
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * @param Dev Device number
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * @param Cmd Operation identifier
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * @param pArg Arguments from user to driver
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * @param Mode Information bitfield (read/write, address space etc.)
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * @param pCred User credentials
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync * @param pVal Return value for calling process.
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync *
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * @return corresponding solaris error code.
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync */
70142706c9117b6c1befe7a5be768d25c699ead5vboxsyncstatic int VBoxDrvSolarisIOCtl(dev_t Dev, int Cmd, intptr_t pArgs, int Mode, cred_t *pCred, int *pVal)
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync{
d44cb80e1d772854c10ef9ae03daba8dcf61d389vboxsync#ifndef USE_SESSION_HASH
d44cb80e1d772854c10ef9ae03daba8dcf61d389vboxsync /*
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * Get the session from the soft state item.
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync */
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync vbox_devstate_t *pState = ddi_get_soft_state(g_pVBoxDrvSolarisState, getminor(Dev));
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync if (!pState)
7c930c3ee58f55e1a2cebfa2ad3ae918569a8f44vboxsync {
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync LogRel((DEVICE_NAME ":VBoxDrvSolarisIOCtl: no state data for %#x (%d)\n", Dev, getminor(Dev)));
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync return EINVAL;
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync }
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync PSUPDRVSESSION pSession = pState->pSession;
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync if (!pSession)
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync {
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync LogRel((DEVICE_NAME ":VBoxDrvSolarisIOCtl: no session in state data for %#x (%d)\n", Dev, getminor(Dev)));
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync return DDI_SUCCESS;
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync }
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync#else
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync const RTPROCESS Process = RTProcSelf();
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync const unsigned iHash = SESSION_HASH(Process);
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync PSUPDRVSESSION pSession;
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync /*
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync * Find the session.
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync */
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync RTSpinlockAcquireNoInts(g_Spinlock, &Tmp);
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync pSession = g_apSessionHashTab[iHash];
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync if (pSession && pSession->Process != Process)
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync {
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync do pSession = pSession->pNextHash;
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync while (pSession && pSession->Process != Process);
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync }
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync RTSpinlockReleaseNoInts(g_Spinlock, &Tmp);
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync if (!pSession)
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync {
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync LogRel((DEVICE_NAME ":VBoxSupDrvIOCtl: WHAT?!? pSession == NULL! This must be a mistake... pid=%d iCmd=%#x\n",
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync (int)Process, Cmd));
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync return EINVAL;
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync }
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync#endif
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync /*
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync * Deal with the two high-speed IOCtl that takes it's arguments from
9ee72227058430bcead5831131741b5dc1601f00vboxsync * the session and iCmd, and only returns a VBox status code.
9ee72227058430bcead5831131741b5dc1601f00vboxsync */
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync if ( Cmd == SUP_IOCTL_FAST_DO_RAW_RUN
9ee72227058430bcead5831131741b5dc1601f00vboxsync || Cmd == SUP_IOCTL_FAST_DO_HWACC_RUN
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync || Cmd == SUP_IOCTL_FAST_DO_NOP)
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync {
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync *pVal = supdrvIOCtlFast(Cmd, pArgs, &g_DevExt, pSession);
d44cb80e1d772854c10ef9ae03daba8dcf61d389vboxsync return 0;
d44cb80e1d772854c10ef9ae03daba8dcf61d389vboxsync }
d44cb80e1d772854c10ef9ae03daba8dcf61d389vboxsync
d44cb80e1d772854c10ef9ae03daba8dcf61d389vboxsync return VBoxDrvSolarisIOCtlSlow(pSession, Cmd, Mode, pArgs);
d44cb80e1d772854c10ef9ae03daba8dcf61d389vboxsync}
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync/** @def IOCPARM_LEN
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * Gets the length from the ioctl number.
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * This is normally defined by sys/ioccom.h on BSD systems...
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync */
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync#ifndef IOCPARM_LEN
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync# define IOCPARM_LEN(x) ( ((x) >> 16) & IOCPARM_MASK )
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync#endif
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync/**
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * Worker for VBoxSupDrvIOCtl that takes the slow IOCtl functions.
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync *
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * @returns Solaris errno.
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync *
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * @param pSession The session.
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * @param Cmd The IOCtl command.
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * @param Mode Information bitfield (for specifying ownership of data)
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * @param iArg User space address of the request buffer.
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync */
70142706c9117b6c1befe7a5be768d25c699ead5vboxsyncstatic int VBoxDrvSolarisIOCtlSlow(PSUPDRVSESSION pSession, int iCmd, int Mode, intptr_t iArg)
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync{
d44cb80e1d772854c10ef9ae03daba8dcf61d389vboxsync int rc;
d44cb80e1d772854c10ef9ae03daba8dcf61d389vboxsync uint32_t cbBuf = 0;
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync union
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync {
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync SUPREQHDR Hdr;
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync uint8_t abBuf[64];
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync } StackBuf;
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync PSUPREQHDR pHdr;
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync
d44cb80e1d772854c10ef9ae03daba8dcf61d389vboxsync /*
d44cb80e1d772854c10ef9ae03daba8dcf61d389vboxsync * Read the header.
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync */
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync if (RT_UNLIKELY(IOCPARM_LEN(iCmd) != sizeof(StackBuf.Hdr)))
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync {
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync LogRel((DEVICE_NAME ":VBoxDrvSolarisIOCtlSlow: iCmd=%#x len %d expected %d\n", iCmd, IOCPARM_LEN(iCmd), sizeof(StackBuf.Hdr)));
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync return EINVAL;
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync }
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync rc = ddi_copyin((void *)iArg, &StackBuf.Hdr, sizeof(StackBuf.Hdr), Mode);
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync if (RT_UNLIKELY(rc))
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync {
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync LogRel((DEVICE_NAME ":VBoxDrvSolarisIOCtlSlow: ddi_copyin(,%#lx,) failed; iCmd=%#x. rc=%d\n", iArg, iCmd, rc));
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync return EFAULT;
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync }
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync if (RT_UNLIKELY((StackBuf.Hdr.fFlags & SUPREQHDR_FLAGS_MAGIC_MASK) != SUPREQHDR_FLAGS_MAGIC))
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync {
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync LogRel((DEVICE_NAME ":VBoxDrvSolarisIOCtlSlow: bad header magic %#x; iCmd=%#x\n", StackBuf.Hdr.fFlags & SUPREQHDR_FLAGS_MAGIC_MASK, iCmd));
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync return EINVAL;
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync }
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync cbBuf = RT_MAX(StackBuf.Hdr.cbIn, StackBuf.Hdr.cbOut);
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync if (RT_UNLIKELY( StackBuf.Hdr.cbIn < sizeof(StackBuf.Hdr)
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync || StackBuf.Hdr.cbOut < sizeof(StackBuf.Hdr)
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync || cbBuf > _1M*16))
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync {
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync LogRel((DEVICE_NAME ":VBoxDrvSolarisIOCtlSlow: max(%#x,%#x); iCmd=%#x\n", StackBuf.Hdr.cbIn, StackBuf.Hdr.cbOut, iCmd));
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync return EINVAL;
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync }
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync /*
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync * Buffer the request.
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync */
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync if (cbBuf <= sizeof(StackBuf))
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync pHdr = &StackBuf.Hdr;
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync else
33d90ac36a3ebf89e46a50252fe9542602a6b2bevboxsync {
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync pHdr = RTMemTmpAlloc(cbBuf);
33d90ac36a3ebf89e46a50252fe9542602a6b2bevboxsync if (RT_UNLIKELY(!pHdr))
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync {
33d90ac36a3ebf89e46a50252fe9542602a6b2bevboxsync LogRel((DEVICE_NAME ":VBoxDrvSolarisIOCtlSlow: failed to allocate buffer of %d bytes for iCmd=%#x.\n", cbBuf, iCmd));
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync return ENOMEM;
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync }
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync }
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync rc = ddi_copyin((void *)iArg, pHdr, cbBuf, Mode);
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync if (RT_UNLIKELY(rc))
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync {
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync LogRel((DEVICE_NAME ":VBoxDrvSolarisIOCtlSlow: copy_from_user(,%#lx, %#x) failed; iCmd=%#x. rc=%d\n", iArg, cbBuf, iCmd, rc));
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync if (pHdr != &StackBuf.Hdr)
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync RTMemFree(pHdr);
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync return EFAULT;
33d90ac36a3ebf89e46a50252fe9542602a6b2bevboxsync }
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync /*
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * Process the IOCtl.
33d90ac36a3ebf89e46a50252fe9542602a6b2bevboxsync */
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync rc = supdrvIOCtl(iCmd, &g_DevExt, pSession, pHdr);
9ee72227058430bcead5831131741b5dc1601f00vboxsync
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync /*
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync * Copy ioctl data and output buffer back to user space.
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync */
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync if (RT_LIKELY(!rc))
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync {
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync uint32_t cbOut = pHdr->cbOut;
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync if (RT_UNLIKELY(cbOut > cbBuf))
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync {
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync LogRel((DEVICE_NAME ":VBoxDrvSolarisIOCtlSlow: too much output! %#x > %#x; iCmd=%#x!\n", cbOut, cbBuf, iCmd));
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync cbOut = cbBuf;
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync }
33d90ac36a3ebf89e46a50252fe9542602a6b2bevboxsync rc = ddi_copyout(pHdr, (void *)iArg, cbOut, Mode);
33d90ac36a3ebf89e46a50252fe9542602a6b2bevboxsync if (RT_UNLIKELY(rc != 0))
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync {
33d90ac36a3ebf89e46a50252fe9542602a6b2bevboxsync /* this is really bad */
33d90ac36a3ebf89e46a50252fe9542602a6b2bevboxsync LogRel((DEVICE_NAME ":VBoxDrvSolarisIOCtlSlow: ddi_copyout(,%p,%d) failed. rc=%d\n", (void *)iArg, cbBuf, rc));
33d90ac36a3ebf89e46a50252fe9542602a6b2bevboxsync rc = EFAULT;
33d90ac36a3ebf89e46a50252fe9542602a6b2bevboxsync }
33d90ac36a3ebf89e46a50252fe9542602a6b2bevboxsync }
33d90ac36a3ebf89e46a50252fe9542602a6b2bevboxsync else
33d90ac36a3ebf89e46a50252fe9542602a6b2bevboxsync rc = EINVAL;
33d90ac36a3ebf89e46a50252fe9542602a6b2bevboxsync
33d90ac36a3ebf89e46a50252fe9542602a6b2bevboxsync if (pHdr != &StackBuf.Hdr)
33d90ac36a3ebf89e46a50252fe9542602a6b2bevboxsync RTMemTmpFree(pHdr);
33d90ac36a3ebf89e46a50252fe9542602a6b2bevboxsync return rc;
33d90ac36a3ebf89e46a50252fe9542602a6b2bevboxsync}
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync/**
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * The SUPDRV IDC entry point.
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync *
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * @returns VBox status code, see supdrvIDC.
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * @param iReq The request code.
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * @param pReq The request.
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync */
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsyncint VBOXCALL SUPDrvSolarisIDC(uint32_t uReq, PSUPDRVIDCREQHDR pReq)
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync{
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync PSUPDRVSESSION pSession;
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync /*
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * Some quick validations.
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync */
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync if (RT_UNLIKELY(!VALID_PTR(pReq)))
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync return VERR_INVALID_POINTER;
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync pSession = pReq->pSession;
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync if (pSession)
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync {
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync if (RT_UNLIKELY(!VALID_PTR(pSession)))
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync return VERR_INVALID_PARAMETER;
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync if (RT_UNLIKELY(pSession->pDevExt != &g_DevExt))
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync return VERR_INVALID_PARAMETER;
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync }
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync else if (RT_UNLIKELY(uReq != SUPDRV_IDC_REQ_CONNECT))
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync return VERR_INVALID_PARAMETER;
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync /*
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * Do the job.
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync */
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync return supdrvIDC(uReq, &g_DevExt, pSession, pReq);
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync}
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync/**
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * Converts an supdrv error code to a solaris error code.
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync *
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * @returns corresponding solaris error code.
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * @param rc supdrv error code (SUPDRV_ERR_* defines).
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync */
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsyncstatic int VBoxSupDrvErr2SolarisErr(int rc)
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync{
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync switch (rc)
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync {
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync case 0: return 0;
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync case SUPDRV_ERR_GENERAL_FAILURE: return EACCES;
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync case SUPDRV_ERR_INVALID_PARAM: return EINVAL;
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync case SUPDRV_ERR_INVALID_MAGIC: return EILSEQ;
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync case SUPDRV_ERR_INVALID_HANDLE: return ENXIO;
76b4af0cf9fc1811afa84c646645382467a5350bvboxsync case SUPDRV_ERR_INVALID_POINTER: return EFAULT;
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync case SUPDRV_ERR_LOCK_FAILED: return ENOLCK;
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync case SUPDRV_ERR_ALREADY_LOADED: return EEXIST;
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync case SUPDRV_ERR_PERMISSION_DENIED: return EPERM;
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync case SUPDRV_ERR_VERSION_MISMATCH: return ENOSYS;
bf4de0c2965291e927412f708c6c27eeeb5825d4vboxsync }
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync return EPERM;
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync}
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync
32ad75b4af91dad97e4f6c0b1d9f2fd63d173f19vboxsync
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync/**
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * Initializes any OS specific object creator fields.
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync */
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsyncvoid VBOXCALL supdrvOSObjInitCreator(PSUPDRVOBJ pObj, PSUPDRVSESSION pSession)
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync{
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync NOREF(pObj);
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync NOREF(pSession);
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync}
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync/**
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * Checks if the session can access the object.
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync *
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * @returns true if a decision has been made.
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * @returns false if the default access policy should be applied.
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync *
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * @param pObj The object in question.
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * @param pSession The session wanting to access the object.
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * @param pszObjName The object name, can be NULL.
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * @param prc Where to store the result when returning true.
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync */
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsyncbool VBOXCALL supdrvOSObjCanAccess(PSUPDRVOBJ pObj, PSUPDRVSESSION pSession, const char *pszObjName, int *prc)
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync{
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync NOREF(pObj);
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync NOREF(pSession);
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync NOREF(pszObjName);
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync NOREF(prc);
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync return false;
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync}
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsyncbool VBOXCALL supdrvOSGetForcedAsyncTscMode(PSUPDRVDEVEXT pDevExt)
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync{
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync return false;
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync}
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsyncRTDECL(int) SUPR0Printf(const char *pszFormat, ...)
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync{
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync va_list args;
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync char szMsg[512];
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync va_start(args, pszFormat);
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync RTStrPrintfV(szMsg, sizeof(szMsg) - 1, pszFormat, args);
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync va_end(args);
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync szMsg[sizeof(szMsg) - 1] = '\0';
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync cmn_err(CE_CONT, "%s", szMsg);
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync return 0;
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync}
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync