SUPDrv-solaris.c revision 4424773d37044bcf5f6d85c04f6f2832b52c32fb
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/** @file
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * VBox host drivers - Ring-0 support drivers - Solaris host:
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Solaris driver C code
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/*
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Copyright (C) 2006-2007 innotek GmbH
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync *
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * available from http://www.virtualbox.org. This file is free software;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * you can redistribute it and/or modify it under the terms of the GNU
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * General Public License as published by the Free Software Foundation,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * distribution. VirtualBox OSE is distributed in the hope that it will
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * be useful, but WITHOUT ANY WARRANTY of any kind.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/*******************************************************************************
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync* Header Files *
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync*******************************************************************************/
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#include <sys/types.h>
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#include <sys/param.h>
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#include <sys/errno.h>
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#include <sys/uio.h>
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#include <sys/buf.h>
590bfe12ce22cd3716448fbb9f4dc51664bfe5e2vboxsync#include <sys/modctl.h>
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#include <sys/open.h>
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#include <sys/conf.h>
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#include <sys/cmn_err.h>
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#include <sys/stat.h>
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#include <sys/ddi.h>
590bfe12ce22cd3716448fbb9f4dc51664bfe5e2vboxsync#include <sys/sunddi.h>
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#include <sys/file.h>
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#undef u /* /usr/include/sys/user.h:249:1 is where this is defined to (curproc->p_user). very cool. */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#include "SUPDRV.h"
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#include <iprt/spinlock.h>
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#include <iprt/process.h>
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#include <iprt/thread.h>
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#include <iprt/initterm.h>
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#include <iprt/alloc.h>
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#include <iprt/string.h>
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
590bfe12ce22cd3716448fbb9f4dc51664bfe5e2vboxsync/*******************************************************************************
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync* Defined Constants And Macros *
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync*******************************************************************************/
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/** The module name. */
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync#define DEVICE_NAME "vboxdrv"
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync/** The module description as seen in 'modinfo'. */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#define DEVICE_DESC "VirtualBox Driver"
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/** Maximum number of driver instances. */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#define DEVICE_MAXINSTANCES 16
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/*******************************************************************************
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync* Internal Functions *
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync*******************************************************************************/
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncstatic int VBoxDrvSolarisOpen(dev_t *pDev, int fFlag, int fType, cred_t *pCred);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncstatic int VBoxDrvSolarisClose(dev_t Dev, int fFlag, int fType, cred_t *pCred);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncstatic int VBoxDrvSolarisRead(dev_t Dev, struct uio *pUio, cred_t *pCred);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncstatic int VBoxDrvSolarisWrite(dev_t Dev, struct uio *pUio, cred_t *pCred);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncstatic int VBoxDrvSolarisIOCtl (dev_t Dev, int Cmd, intptr_t pArgs, int mode, cred_t *pCred, int *pVal);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncstatic int VBoxDrvSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t Cmd);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncstatic int VBoxDrvSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t Cmd);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncstatic int VBoxSupDrvErr2SolarisErr(int rc);
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsyncstatic int VBoxDrvSolarisIOCtlSlow(PSUPDRVSESSION pSession, int Cmd, int Mode, intptr_t pArgs);
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/*******************************************************************************
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync* Global Variables *
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync*******************************************************************************/
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync/**
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * cb_ops: for drivers that support char/block entry points
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncstatic struct cb_ops g_VBoxDrvSolarisCbOps =
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync{
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync VBoxDrvSolarisOpen,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync VBoxDrvSolarisClose,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync nodev, /* b strategy */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync nodev, /* b dump */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync nodev, /* b print */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync VBoxDrvSolarisRead,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync VBoxDrvSolarisWrite,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync VBoxDrvSolarisIOCtl,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync nodev, /* c devmap */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync nodev, /* c mmap */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync nodev, /* c segmap */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync nochpoll, /* c poll */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync ddi_prop_op, /* property ops */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync NULL, /* streamtab */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync D_NEW | D_MP, /* compat. flag */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync CB_REV /* revision */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync};
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/**
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * dev_ops: for driver device operations
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncstatic struct dev_ops g_VBoxDrvSolarisDevOps =
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync{
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync DEVO_REV, /* driver build revision */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync 0, /* ref count */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync nulldev, /* get info */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync nulldev, /* identify */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync nulldev, /* probe */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync VBoxDrvSolarisAttach,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync VBoxDrvSolarisDetach,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync nodev, /* reset */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync &g_VBoxDrvSolarisCbOps,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync (struct bus_ops *)0,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync nodev /* power */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync};
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/**
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * modldrv: export driver specifics to the kernel
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncstatic struct modldrv g_VBoxDrvSolarisModule =
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync{
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync &mod_driverops, /* extern from kernel */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync DEVICE_DESC,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync &g_VBoxDrvSolarisDevOps
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync};
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/**
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * modlinkage: export install/remove/info to the kernel
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncstatic struct modlinkage g_VBoxDrvSolarisModLinkage =
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync{
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync MODREV_1, /* loadable module system revision */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync &g_VBoxDrvSolarisModule,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync NULL /* terminate array of linkage structures */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync};
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#ifndef USE_SESSION_HASH
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/**
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * State info for each open file handle.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsynctypedef struct
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync{
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /**< Pointer to the session data. */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync PSUPDRVSESSION pSession;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync} vbox_devstate_t;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#else
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/** State info. for each driver instance. */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsynctypedef struct
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync{
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync dev_info_t *pDip; /* Device handle */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync} vbox_devstate_t;
25747178cb66800d8386c20b8ffd87f78f24f4e5vboxsync#endif
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
25747178cb66800d8386c20b8ffd87f78f24f4e5vboxsync/** Opaque pointer to state */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncstatic void *g_pVBoxDrvSolarisState;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/** Device extention & session data association structure */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncstatic SUPDRVDEVEXT g_DevExt;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/* GCC C++ hack. */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncunsigned __gxx_personality_v0 = 0xcccccccc;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/** Hash table */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncstatic PSUPDRVSESSION g_apSessionHashTab[19];
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/** Spinlock protecting g_apSessionHashTab. */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncstatic RTSPINLOCK g_Spinlock = NIL_RTSPINLOCK;
25747178cb66800d8386c20b8ffd87f78f24f4e5vboxsync/** Calculates bucket index into g_apSessionHashTab.*/
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#define SESSION_HASH(sfn) ((sfn) % RT_ELEMENTS(g_apSessionHashTab))
25747178cb66800d8386c20b8ffd87f78f24f4e5vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/**
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Kernel entry points
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncint _init(void)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync{
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync cmn_err(CE_CONT, "VBoxDrvSolaris _init");
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync int rc = ddi_soft_state_init(&g_pVBoxDrvSolarisState, sizeof(vbox_devstate_t), 8);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (!rc)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync rc = mod_install(&g_VBoxDrvSolarisModLinkage);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (!rc)
25747178cb66800d8386c20b8ffd87f78f24f4e5vboxsync return 0; /* success */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
25747178cb66800d8386c20b8ffd87f78f24f4e5vboxsync ddi_soft_state_fini(&g_pVBoxDrvSolarisState);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync cmn_err(CE_CONT, "VBoxDrvSolaris _init failed with rc=%d", rc);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync return rc;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync}
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncint _fini(void)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync{
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync cmn_err(CE_CONT, "VBoxDrvSolaris _fini");
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync int e = mod_remove(&g_VBoxDrvSolarisModLinkage);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (e != 0)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync return e;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync ddi_soft_state_fini(&g_pVBoxDrvSolarisState);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync return e;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync}
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncint _info(struct modinfo *pModInfo)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync{
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync cmn_err(CE_CONT, "VBoxDrvSolaris _info");
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync int e = mod_info(&g_VBoxDrvSolarisModLinkage, pModInfo);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync cmn_err(CE_CONT, "VBoxDrvSolaris _info returns %d", e);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync return e;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync}
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/**
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Attach entry point, to attach a device to the system or resume it.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync *
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @param pDip The module structure instance.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @param enmCmd Attach type (ddi_attach_cmd_t)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync *
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @return corresponding solaris error code.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncstatic int VBoxDrvSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync{
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync cmn_err(CE_CONT, "VBoxDrvSolarisAttach");
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync switch (enmCmd)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync case DDI_ATTACH:
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync int rc;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync int instance = ddi_get_instance(pDip);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#ifdef USE_SESSION_HASH
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync vbox_devstate_t *pState;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (ddi_soft_state_zalloc(g_pVBoxDrvSolarisState, instance) != DDI_SUCCESS)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync cmn_err(CE_NOTE, "VBoxDrvSolarisAttach: state alloc failed");
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync return DDI_FAILURE;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync pState = ddi_get_soft_state(g_pVBoxDrvSolarisState, instance);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#endif
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /*
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Initialize IPRT R0 driver, which internally calls OS-specific r0 init.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync rc = RTR0Init(0);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (RT_SUCCESS(rc))
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /*
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Initialize the device extension
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync rc = supdrvInitDevExt(&g_DevExt);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (RT_SUCCESS(rc))
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /*
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Initialize the session hash table.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync memset(g_apSessionHashTab, 0, sizeof(g_apSessionHashTab));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync rc = RTSpinlockCreate(&g_Spinlock);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (RT_SUCCESS(rc))
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /*
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Register ourselves as a character device, pseudo-driver
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (ddi_create_minor_node(pDip, "0", S_IFCHR, instance, DDI_PSEUDO, 0) == DDI_SUCCESS)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#ifdef USE_SESSION_HASH
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync pState->pDip = pDip;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#endif
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync ddi_report_dev(pDip);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync return DDI_SUCCESS;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* Is this really necessary? */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync ddi_remove_minor_node(pDip, NULL);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync cmn_err(CE_NOTE,"VBoxDrvSolarisAttach: ddi_create_minor_node failed.");
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync RTSpinlockDestroy(g_Spinlock);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync g_Spinlock = NIL_RTSPINLOCK;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync else
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync cmn_err(CE_NOTE, "VBoxDrvSolarisAttach: RTSpinlockCreate failed");
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync supdrvDeleteDevExt(&g_DevExt);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync else
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync cmn_err(CE_NOTE, "VBoxDrvSolarisAttach: supdrvInitDevExt failed");
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync RTR0Term ();
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync else
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync cmn_err(CE_NOTE, "VBoxDrvSolarisAttach: failed to init R0Drv");
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync memset(&g_DevExt, 0, sizeof(g_DevExt));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync break;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync default:
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync return DDI_FAILURE;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync return DDI_FAILURE;
7b067f3f07310bff46d1d6a4ac94d8b9bb7ccccdvboxsync}
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/**
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Detach entry point, to detach a device to the system or suspend it.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync *
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @param pDip The module structure instance.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @param enmCmd Attach type (ddi_attach_cmd_t)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync *
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @return corresponding solaris error code.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncstatic int VBoxDrvSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync{
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync int rc = VINF_SUCCESS;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync cmn_err(CE_CONT, "VBoxDrvSolarisDetach");
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync switch (enmCmd)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync case DDI_DETACH:
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync int instance = ddi_get_instance(pDip);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#ifndef USE_SESSION_HASH
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync ddi_remove_minor_node(pDip, NULL);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#else
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync vbox_devstate_t *pState = ddi_get_soft_state(g_pVBoxDrvSolarisState, instance);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync ddi_remove_minor_node(pDip, NULL);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync ddi_soft_state_free(g_pVBoxDrvSolarisState, instance);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#endif
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync supdrvDeleteDevExt(&g_DevExt);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync rc = RTSpinlockDestroy(g_Spinlock);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync AssertRC(rc);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync g_Spinlock = NIL_RTSPINLOCK;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync RTR0Term();
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync memset(&g_DevExt, 0, sizeof(g_DevExt));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync cmn_err(CE_CONT, "VBoxDrvSolarisDetach: Clean Up Done.");
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync return DDI_SUCCESS;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync default:
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync return DDI_FAILURE;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync}
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/**
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * User context entry points
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncstatic int VBoxDrvSolarisOpen(dev_t *pDev, int fFlag, int fType, cred_t *pCred)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync{
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync int rc;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync PSUPDRVSESSION pSession;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync dprintf(("VBoxDrvSolarisOpen: pDev=%p:%#x\n", pDev, *pDev));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#ifndef USE_SESSION_HASH
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /*
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Locate a new device open instance.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync *
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * For each open call we'll allocate an item in the soft state of the device.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * The item index is stored in the dev_t. I hope this is ok...
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync vbox_devstate_t *pState = NULL;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync unsigned iOpenInstance;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync for (iOpenInstance = 0; iOpenInstance < 4096; iOpenInstance++)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if ( !ddi_get_soft_state(g_pVBoxDrvSolarisState, iOpenInstance) /* faster */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync && ddi_soft_state_zalloc(g_pVBoxDrvSolarisState, iOpenInstance) == DDI_SUCCESS)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync pState = ddi_get_soft_state(g_pVBoxDrvSolarisState, iOpenInstance);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync break;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (!pState)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync cmn_err(CE_NOTE,"VBoxDrvSolarisOpen: too many open instances.");
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync return ENXIO;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /*
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Create a new session.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync rc = supdrvCreateSession(&g_DevExt, &pSession);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (RT_SUCCESS(rc))
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync pState->pSession = pSession;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync *pDev = makedevice(getmajor(*pDev), iOpenInstance);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync dprintf(("VBoxDrvSolarisOpen: returns pDev=%#x pSession=%p pState=%p\n", *pDev, pSession, pState));
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync OSDBGPRINT(("VBoxDrvSolarisOpen: Dev=%#x pSession=%p pid=%d r0proc=%p thread=%p\n",
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync *pDev, pSession, RTProcSelf(), RTR0ProcHandleSelf(), RTThreadNativeSelf() ));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync return 0;
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync /* failed - clean up */
a39ea3668b7019c23a68936259545f9b71bce1aavboxsync ddi_soft_state_free(g_pVBoxDrvSolarisState, iOpenInstance);
fd492d285ed33c86dd76bc05d9d4f3e55bc0fb49vboxsync
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync#else
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /*
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Create a new session.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Sessions in Solaris driver are mostly useless. It's however needed
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * in VBoxDrvSolarisIOCtlSlow() while calling supdrvIOCtl()
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync rc = supdrvCreateSession(&g_DevExt, &pSession);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (RT_SUCCESS(rc))
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync unsigned iHash;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync pSession->Uid = crgetuid(pCred);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync pSession->Gid = crgetgid(pCred);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync pSession->Process = RTProcSelf();
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync pSession->R0Process = RTR0ProcHandleSelf();
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /*
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Insert it into the hash table.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync iHash = SESSION_HASH(pSession->Process);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync RTSpinlockAcquireNoInts(g_Spinlock, &Tmp);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync pSession->pNextHash = g_apSessionHashTab[iHash];
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync g_apSessionHashTab[iHash] = pSession;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync RTSpinlockReleaseNoInts(g_Spinlock, &Tmp);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync cmn_err(CE_NOTE,"VBoxDrvSolarisOpen success");
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync int instance;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync for (instance = 0; instance < DEVICE_MAXINSTANCES; instance++)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync vbox_devstate_t *pState = ddi_get_soft_state(g_pVBoxDrvSolarisState, instance);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (pState)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync break;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (instance >= DEVICE_MAXINSTANCES)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync cmn_err(CE_NOTE, "VBoxDrvSolarisOpen: All instances exhausted\n");
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync return ENXIO;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync *pDev = makedevice(getmajor(*pDev), instance);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync return VBoxSupDrvErr2SolarisErr(rc);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#endif
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync}
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncstatic int VBoxDrvSolarisClose(dev_t Dev, int flag, int otyp, cred_t *cred)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync{
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync dprintf(("VBoxDrvSolarisClose: Dev=%#x\n", Dev));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#ifndef USE_SESSION_HASH
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /*
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Get the session and free the soft state item.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync vbox_devstate_t *pState = ddi_get_soft_state(g_pVBoxDrvSolarisState, getminor(Dev));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (!pState)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync OSDBGPRINT(("VBoxDrvSolarisClose: no state data for %#x (%d)\n", Dev, getminor(Dev)));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync return DDI_SUCCESS;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync PSUPDRVSESSION pSession = pState->pSession;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync pState->pSession = NULL;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync ddi_soft_state_free(g_pVBoxDrvSolarisState, getminor(Dev));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (!pSession)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync OSDBGPRINT(("VBoxDrvSolarisClose: no session in state data for %#x (%d)\n", Dev, getminor(Dev)));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync return DDI_SUCCESS;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync OSDBGPRINT(("VBoxDrvSolarisClose: Dev=%#x pSession=%p pid=%d r0proc=%p thread=%p\n", Dev, pSession, RTProcSelf(), RTR0ProcHandleSelf(), RTThreadNativeSelf() ));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#else
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync const RTPROCESS Process = RTProcSelf();
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync const unsigned iHash = SESSION_HASH(Process);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync PSUPDRVSESSION pSession;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /*
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Remove from the hash table.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync RTSpinlockAcquireNoInts(g_Spinlock, &Tmp);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync pSession = g_apSessionHashTab[iHash];
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (pSession)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (pSession->Process == Process)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync g_apSessionHashTab[iHash] = pSession->pNextHash;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync pSession->pNextHash = NULL;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync else
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync PSUPDRVSESSION pPrev = pSession;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync pSession = pSession->pNextHash;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync while (pSession)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (pSession->Process == Process)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync pPrev->pNextHash = pSession->pNextHash;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync pSession->pNextHash = NULL;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync break;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* next */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync pPrev = pSession;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync pSession = pSession->pNextHash;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync RTSpinlockReleaseNoInts(g_Spinlock, &Tmp);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (!pSession)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync OSDBGPRINT(("VBoxDrvSolarisClose: WHAT?!? pSession == NULL! This must be a mistake... pid=%d (close)\n",
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync (int)Process));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync return DDI_FAILURE;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#endif
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /*
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Close the session.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync supdrvCloseSession(&g_DevExt, pSession);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync OSDBGPRINT(("VBoxDrvSolarisClose: returns\n"));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync return DDI_SUCCESS;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync}
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
fd492d285ed33c86dd76bc05d9d4f3e55bc0fb49vboxsyncstatic int VBoxDrvSolarisRead(dev_t Dev, struct uio *pUio, cred_t *pCred)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync{
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync cmn_err(CE_CONT, "VBoxDrvSolarisRead");
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync return DDI_SUCCESS;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync}
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncstatic int VBoxDrvSolarisWrite(dev_t Dev, struct uio *pUio, cred_t *pCred)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync{
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync cmn_err(CE_CONT, "VBoxDrvSolarisWrite");
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync return DDI_SUCCESS;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync}
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/**
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Driver ioctl, an alternate entry point for this character driver.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync *
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @param Dev Device number
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @param Cmd Operation identifier
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @param pArg Arguments from user to driver
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @param Mode Information bitfield (read/write, address space etc.)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @param pCred User credentials
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @param pVal Return value for calling process.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync *
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @return corresponding solaris error code.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncstatic int VBoxDrvSolarisIOCtl(dev_t Dev, int Cmd, intptr_t pArgs, int Mode, cred_t *pCred, int *pVal)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync{
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#ifndef USE_SESSION_HASH
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /*
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Get the session from the soft state item.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync vbox_devstate_t *pState = ddi_get_soft_state(g_pVBoxDrvSolarisState, getminor(Dev));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (!pState)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync OSDBGPRINT(("VBoxDrvSolarisIOCtl: no state data for %#x (%d)\n", Dev, getminor(Dev)));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync return EINVAL;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync PSUPDRVSESSION pSession = pState->pSession;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (!pSession)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync OSDBGPRINT(("VBoxDrvSolarisIOCtl: no session in state data for %#x (%d)\n", Dev, getminor(Dev)));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync return DDI_SUCCESS;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#else
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync const RTPROCESS Process = RTProcSelf();
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync const unsigned iHash = SESSION_HASH(Process);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync PSUPDRVSESSION pSession;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /*
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Find the session.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
25747178cb66800d8386c20b8ffd87f78f24f4e5vboxsync RTSpinlockAcquireNoInts(g_Spinlock, &Tmp);
25747178cb66800d8386c20b8ffd87f78f24f4e5vboxsync pSession = g_apSessionHashTab[iHash];
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (pSession && pSession->Process != Process)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
25747178cb66800d8386c20b8ffd87f78f24f4e5vboxsync do pSession = pSession->pNextHash;
25747178cb66800d8386c20b8ffd87f78f24f4e5vboxsync while (pSession && pSession->Process != Process);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync RTSpinlockReleaseNoInts(g_Spinlock, &Tmp);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (!pSession)
25747178cb66800d8386c20b8ffd87f78f24f4e5vboxsync {
25747178cb66800d8386c20b8ffd87f78f24f4e5vboxsync OSDBGPRINT(("VBoxSupDrvIOCtl: WHAT?!? pSession == NULL! This must be a mistake... pid=%d iCmd=%#x\n",
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync (int)Process, Cmd));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync return EINVAL;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#endif
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /*
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Deal with the two high-speed IOCtl that takes it's arguments from
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * the session and iCmd, and only returns a VBox status code.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if ( Cmd == SUP_IOCTL_FAST_DO_RAW_RUN
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync || Cmd == SUP_IOCTL_FAST_DO_HWACC_RUN
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync || Cmd == SUP_IOCTL_FAST_DO_NOP)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync *pVal = supdrvIOCtlFast(Cmd, &g_DevExt, pSession);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync return 0;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync return VBoxDrvSolarisIOCtlSlow(pSession, Cmd, Mode, pArgs);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync}
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/** @def IOCPARM_LEN
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Gets the length from the ioctl number.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * This is normally defined by sys/ioccom.h on BSD systems...
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#ifndef IOCPARM_LEN
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync# define IOCPARM_LEN(x) ( ((x) >> 16) & IOCPARM_MASK )
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#endif
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/**
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Worker for VBoxSupDrvIOCtl that takes the slow IOCtl functions.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync *
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @returns Solaris errno.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync *
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @param pSession The session.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @param Cmd The IOCtl command.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @param Mode Information bitfield (for specifying ownership of data)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @param iArg User space address of the request buffer.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncstatic int VBoxDrvSolarisIOCtlSlow(PSUPDRVSESSION pSession, int iCmd, int Mode, intptr_t iArg)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync{
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync int rc;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync uint32_t cbBuf = 0;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync SUPREQHDR Hdr;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync PSUPREQHDR pHdr;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /*
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Read the header.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (RT_UNLIKELY(IOCPARM_LEN(iCmd) != sizeof(Hdr)))
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync OSDBGPRINT(("VBoxDrvSolarisIOCtlSlow: iCmd=%#x len %d expected %d\n", iCmd, IOCPARM_LEN(iCmd), sizeof(Hdr)));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync return EINVAL;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync rc = ddi_copyin((void *)iArg, &Hdr, sizeof(Hdr), Mode);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (RT_UNLIKELY(rc))
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync OSDBGPRINT(("VBoxDrvSolarisIOCtlSlow: ddi_copyin(,%#lx,) failed; iCmd=%#x. rc=%d\n", iArg, iCmd, rc));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync return EFAULT;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (RT_UNLIKELY((Hdr.fFlags & SUPREQHDR_FLAGS_MAGIC_MASK) != SUPREQHDR_FLAGS_MAGIC))
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync OSDBGPRINT(("VBoxDrvSolarisIOCtlSlow: bad header magic %#x; iCmd=%#x\n", Hdr.fFlags & SUPREQHDR_FLAGS_MAGIC_MASK, iCmd));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync return EINVAL;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync cbBuf = RT_MAX(Hdr.cbIn, Hdr.cbOut);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (RT_UNLIKELY( Hdr.cbIn < sizeof(Hdr)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync || Hdr.cbOut < sizeof(Hdr)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync || cbBuf > _1M*16))
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync OSDBGPRINT(("VBoxDrvSolarisIOCtlSlow: max(%#x,%#x); iCmd=%#x\n", Hdr.cbIn, Hdr.cbOut, iCmd));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync return EINVAL;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /*
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Buffer the request.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync pHdr = RTMemTmpAlloc(cbBuf);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (RT_UNLIKELY(!pHdr))
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync OSDBGPRINT(("VBoxDrvSolarisIOCtlSlow: failed to allocate buffer of %d bytes for iCmd=%#x.\n", cbBuf, iCmd));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync return ENOMEM;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync rc = ddi_copyin((void *)iArg, pHdr, cbBuf, Mode);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (RT_UNLIKELY(rc))
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync dprintf(("VBoxDrvSolarisIOCtlSlow: copy_from_user(,%#lx, %#x) failed; iCmd=%#x. rc=%d\n", iArg, Hdr.cbIn, iCmd, rc));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync RTMemFree(pHdr);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync return EFAULT;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /*
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Process the IOCtl.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync rc = supdrvIOCtl(iCmd, &g_DevExt, pSession, pHdr);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /*
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Copy ioctl data and output buffer back to user space.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (RT_LIKELY(!rc))
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync uint32_t cbOut = pHdr->cbOut;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (RT_UNLIKELY(cbOut > cbBuf))
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync OSDBGPRINT(("VBoxDrvSolarisIOCtlSlow: too much output! %#x > %#x; iCmd=%#x!\n", cbOut, cbBuf, iCmd));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync cbOut = cbBuf;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync rc = ddi_copyout(pHdr, (void *)iArg, cbOut, Mode);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (RT_UNLIKELY(rc != 0))
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* this is really bad */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync OSDBGPRINT(("VBoxDrvSolarisIOCtlSlow: ddi_copyout(,%p,%d) failed. rc=%d\n", (void *)iArg, cbBuf, rc));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync rc = EFAULT;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync else
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync rc = EINVAL;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync RTMemTmpFree(pHdr);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync return rc;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync}
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/**
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Converts an supdrv error code to a solaris error code.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync *
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @returns corresponding solaris error code.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @param rc supdrv error code (SUPDRV_ERR_* defines).
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncstatic int VBoxSupDrvErr2SolarisErr(int rc)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync{
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync switch (rc)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync case 0: return 0;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync case SUPDRV_ERR_GENERAL_FAILURE: return EACCES;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync case SUPDRV_ERR_INVALID_PARAM: return EINVAL;
case SUPDRV_ERR_INVALID_MAGIC: return EILSEQ;
case SUPDRV_ERR_INVALID_HANDLE: return ENXIO;
case SUPDRV_ERR_INVALID_POINTER: return EFAULT;
case SUPDRV_ERR_LOCK_FAILED: return ENOLCK;
case SUPDRV_ERR_ALREADY_LOADED: return EEXIST;
case SUPDRV_ERR_PERMISSION_DENIED: return EPERM;
case SUPDRV_ERR_VERSION_MISMATCH: return ENOSYS;
}
return EPERM;
}
/**
* Initializes any OS specific object creator fields.
*/
void VBOXCALL supdrvOSObjInitCreator(PSUPDRVOBJ pObj, PSUPDRVSESSION pSession)
{
NOREF(pObj);
NOREF(pSession);
}
/**
* Checks if the session can access the object.
*
* @returns true if a decision has been made.
* @returns false if the default access policy should be applied.
*
* @param pObj The object in question.
* @param pSession The session wanting to access the object.
* @param pszObjName The object name, can be NULL.
* @param prc Where to store the result when returning true.
*/
bool VBOXCALL supdrvOSObjCanAccess(PSUPDRVOBJ pObj, PSUPDRVSESSION pSession, const char *pszObjName, int *prc)
{
NOREF(pObj);
NOREF(pSession);
NOREF(pszObjName);
NOREF(prc);
return false;
}
RTDECL(int) SUPR0Printf(const char *pszFormat, ...)
{
va_list args;
char szMsg[512];
va_start(args, pszFormat);
RTStrPrintfV(szMsg, sizeof(szMsg) - 1, pszFormat, args);
va_end(args);
szMsg[sizeof(szMsg) - 1] = '\0';
#if 1
uprintf("SUPR0Printf: %s", szMsg);
#endif
#if 1
cmn_err(CE_CONT, "VBoxDrv: %s", szMsg);
#endif
return 0;
}