VBoxGuest-solaris.c revision cdead8438143d4d6168ddae6cb4b7ba609ac3cdb
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync * VirtualBox Guest Additions Driver for Solaris.
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * Copyright (C) 2007 Sun Microsystems, Inc.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * available from http://www.virtualbox.org. This file is free software;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * you can redistribute it and/or modify it under the terms of the GNU
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * General Public License (GPL) as published by the Free Software
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * additional information or have any questions.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*******************************************************************************
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync* Header Files *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync*******************************************************************************/
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#undef u /* /usr/include/sys/user.h:249:1 is where this is defined to (curproc->p_user). very cool. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*******************************************************************************
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync* Defined Constants And Macros *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync*******************************************************************************/
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** The module name. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** The module description as seen in 'modinfo'. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*******************************************************************************
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync* Internal Functions *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync*******************************************************************************/
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int VBoxGuestSolarisOpen(dev_t *pDev, int fFlag, int fType, cred_t *pCred);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int VBoxGuestSolarisClose(dev_t Dev, int fFlag, int fType, cred_t *pCred);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int VBoxGuestSolarisRead(dev_t Dev, struct uio *pUio, cred_t *pCred);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int VBoxGuestSolarisWrite(dev_t Dev, struct uio *pUio, cred_t *pCred);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int VBoxGuestSolarisIOCtl(dev_t Dev, int Cmd, intptr_t pArg, int Mode, cred_t *pCred, int *pVal);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int VBoxGuestSolarisPoll(dev_t Dev, short fEvents, int fAnyYet, short *pReqEvents, struct pollhead **ppPollHead);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int VBoxGuestSolarisGetInfo(dev_info_t *pDip, ddi_info_cmd_t enmCmd, void *pArg, void **ppResult);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int VBoxGuestSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int VBoxGuestSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int VBoxGuestSolarisAddIRQ(dev_info_t *pDip);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic void VBoxGuestSolarisRemoveIRQ(dev_info_t *pDip);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*******************************************************************************
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync* Structures and Typedefs *
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync*******************************************************************************/
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync * cb_ops: for drivers that support char/block entry points
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * dev_ops: for driver device operations
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync 0, /* ref count */
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync (struct bus_ops *)0,
05406988cc320ac1b0971de976b6cf0c986044a9vboxsync * modldrv: export driver specifics to the kernel
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync DEVICE_DESC " " VBOX_VERSION_STRING "r" RT_XSTR(VBOX_SVN_REV),
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync * modlinkage: export install/remove/info to the kernel
05406988cc320ac1b0971de976b6cf0c986044a9vboxsyncstatic struct modlinkage g_VBoxGuestSolarisModLinkage =
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * State info for each open file handle.
3d5f0ee34d7d75f349347d02f25c5abae9b197aavboxsynctypedef struct
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** Pointer to the session handle. */
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync /** The process reference for posting signals */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*******************************************************************************
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync* Global Variables *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync*******************************************************************************/
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** Device handle (we support only one instance). */
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync/** Opaque pointer to file-descriptor states */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** Device extention & session data association structure. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** IO port handle. */
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync/** MMIO handle. */
23de3d76e5d27015e334e6ff763ab08de5969363vboxsync/** IO Port. */
23de3d76e5d27015e334e6ff763ab08de5969363vboxsync/** Address of the MMIO region.*/
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** Size of the MMIO region. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** VMMDev Version. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** Pointer to the interrupt handle vector */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** Number of actually allocated interrupt handles */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** The pollhead structure */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** The IRQ Mutex */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Kernel entry points
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Prevent module autounloading.
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync modctl_t *pModCtl = mod_getctl(&g_VBoxGuestSolarisModLinkage);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel((DEVICE_NAME ":failed to disable autounloading!\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES;
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync int rc = RTLogCreate(&pRelLogger, 0 /* fFlags */, "all",
61e80138f3c5ea5213990bde94a973c8e64d1dadvboxsync "VBOX_RELEASE_LOG", RT_ELEMENTS(s_apszGroups), s_apszGroups,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = ddi_soft_state_init(&g_pVBoxGuestSolarisState, sizeof(vboxguest_state_t), 1);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int rc = mod_remove(&g_VBoxGuestSolarisModLinkage);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return mod_info(&g_VBoxGuestSolarisModLinkage, pModInfo);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Attach entry point, to attach a device to the system or resume it.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pDip The module structure instance.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param enmCmd Attach type (ddi_attach_cmd_t)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @return corresponding solaris error code.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int VBoxGuestSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel((DEVICE_NAME "::Attach: Only one instance supported.\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Initialize IPRT R0 driver, which internally calls OS-specific r0 init.
090f6abdd6282f48527b83162b8b441425f05e36vboxsync * Enable resources for PCI access.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Map the register address space.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync deviceAttr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
090f6abdd6282f48527b83162b8b441425f05e36vboxsync deviceAttr.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC;
090f6abdd6282f48527b83162b8b441425f05e36vboxsync deviceAttr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
090f6abdd6282f48527b83162b8b441425f05e36vboxsync rc = ddi_regs_map_setup(pDip, 1, &baseAddr, 0, 0, &deviceAttr, &g_PciIOHandle);
090f6abdd6282f48527b83162b8b441425f05e36vboxsync * Read size of the MMIO region.
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync rc = ddi_regs_map_setup(pDip, 2, &g_pMMIOBase, 0, g_cbMMIO, &deviceAttr,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Add IRQ of VMMDev.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Call the common device extension initializer.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = VBoxGuestInitDevExt(&g_DevExt, g_uIOPortBase, g_pMMIOBase,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = ddi_create_minor_node(pDip, DEVICE_NAME, S_IFCHR, instance, DDI_PSEUDO, 0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel((DEVICE_NAME "::Attach: ddi_create_minor_node failed.\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel((DEVICE_NAME "::Attach: VBoxGuestInitDevExt failed.\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel((DEVICE_NAME "::Attach: VBoxGuestSolarisAddIRQ failed.\n"));
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync LogRel((DEVICE_NAME "::Attach: ddi_regs_map_setup for MMIO region failed.\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel((DEVICE_NAME "::Attach: ddi_dev_regsize for MMIO region failed.\n"));
0ebb1ef53864eb9cc97580f722288c9b29bc5d03vboxsync LogRel((DEVICE_NAME "::Attach: ddi_regs_map_setup for IOport failed.\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel((DEVICE_NAME "::Attach: pci_config_setup failed rc=%d.\n", rc));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** @todo implement resume for guest driver. */
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync * Detach entry point, to detach a device to the system or suspend it.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pDip The module structure instance.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param enmCmd Attach type (ddi_attach_cmd_t)
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync * @return corresponding solaris error code.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int VBoxGuestSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd)
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync /** @todo implement suspend for guest driver. */
7e960d3a0a8a3a84d7aba2cca45d72b1c31cc97bvboxsync * Info entry point, called by solaris kernel for obtaining driver info.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pDip The module structure instance (do not use).
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param enmCmd Information request type.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pvArg Type specific argument.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param ppvResult Where to store the requested info.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @return corresponding solaris error code.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int VBoxGuestSolarisGetInfo(dev_info_t *pDip, ddi_info_cmd_t enmCmd, void *pvArg, void **ppvResult)
7e960d3a0a8a3a84d7aba2cca45d72b1c31cc97bvboxsync *ppvResult = (void *)(uintptr_t)ddi_get_instance(g_pDip);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * User context entry points
323b78bf4831666c95416edf3b6e54657a769e5dvboxsyncstatic int VBoxGuestSolarisOpen(dev_t *pDev, int fFlag, int fType, cred_t *pCred)
13d75a5db336ccb682d7ab28b397a4f0b8982ea3vboxsync * Verify we are being opened as a character device.
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync for (iOpenInstance = 0; iOpenInstance < 4096; iOpenInstance++)
bee1a7d4b183cab9654f247b3ea8cf680842bed5vboxsync if ( !ddi_get_soft_state(g_pVBoxGuestSolarisState, iOpenInstance) /* faster */
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync && ddi_soft_state_zalloc(g_pVBoxGuestSolarisState, iOpenInstance) == DDI_SUCCESS)
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync pState = ddi_get_soft_state(g_pVBoxGuestSolarisState, iOpenInstance);
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync Log((DEVICE_NAME "::Open: too many open instances."));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Create a new session.
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync rc = VBoxGuestCreateUserSession(&g_DevExt, &pSession);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *pDev = makedevice(getmajor(*pDev), iOpenInstance);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log((DEVICE_NAME "::Open: pSession=%p pState=%p pid=%d\n", pSession, pState, (int)RTProcSelf()));
13d75a5db336ccb682d7ab28b397a4f0b8982ea3vboxsync /* Failed, clean up. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ddi_soft_state_free(g_pVBoxGuestSolarisState, iOpenInstance);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel((DEVICE_NAME "::Open: VBoxGuestCreateUserSession failed. rc=%d\n", rc));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int VBoxGuestSolarisClose(dev_t Dev, int flag, int fType, cred_t *pCred)
d45f7f7fe0c28b500b45b2dc88d7a04f4c0be6b8vboxsync LogFlow((DEVICE_NAME "::Close pid=%d\n", (int)RTProcSelf()));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxguest_state_t *pState = ddi_get_soft_state(g_pVBoxGuestSolarisState, getminor(Dev));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log((DEVICE_NAME "::Close: failed to get pState.\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log((DEVICE_NAME "::Close: pSession=%p pState=%p\n", pSession, pState));
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync ddi_soft_state_free(g_pVBoxGuestSolarisState, getminor(Dev));
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync Log((DEVICE_NAME "::Close: failed to get pSession.\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Close the session.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int VBoxGuestSolarisRead(dev_t Dev, struct uio *pUio, cred_t *pCred)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxguest_state_t *pState = ddi_get_soft_state(g_pVBoxGuestSolarisState, getminor(Dev));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log((DEVICE_NAME "::Close: failed to get pState.\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync uint32_t u32CurSeq = ASMAtomicUoReadU32(&g_DevExt.u32MousePosChangedSeq);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int VBoxGuestSolarisWrite(dev_t Dev, struct uio *pUio, cred_t *pCred)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** @def IOCPARM_LEN
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Gets the length from the ioctl number.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * This is normally defined by sys/ioccom.h on BSD systems...
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# define IOCPARM_LEN(Code) (((Code) >> 16) & IOCPARM_MASK)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Driver ioctl, an alternate entry point for this character driver.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param Dev Device number
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param Cmd Operation identifier
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pArg Arguments from user to driver
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync * @param Mode Information bitfield (read/write, address space etc.)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pCred User credentials
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pVal Return value for calling process.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @return corresponding solaris error code.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int VBoxGuestSolarisIOCtl(dev_t Dev, int Cmd, intptr_t pArg, int Mode, cred_t *pCred, int *pVal)
0ebb1ef53864eb9cc97580f722288c9b29bc5d03vboxsync * Get the session from the soft state item.
0ebb1ef53864eb9cc97580f722288c9b29bc5d03vboxsync vboxguest_state_t *pState = ddi_get_soft_state(g_pVBoxGuestSolarisState, getminor(Dev));
a44cdd0b29504e3de7b8aa87f839ad62b6e66f51vboxsync LogRel((DEVICE_NAME "::IOCtl: no state data for %d\n", getminor(Dev)));
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync LogRel((DEVICE_NAME "::IOCtl: no session data for %d\n", getminor(Dev)));
332ccb6ac6feb4b50ec24d63ff029119164182ffvboxsync * Read and validate the request wrapper.
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync LogRel((DEVICE_NAME "::IOCtl: bad request %#x size=%d expected=%d\n", Cmd, IOCPARM_LEN(Cmd), sizeof(ReqWrap)));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int rc = ddi_copyin((void *)pArg, &ReqWrap, sizeof(ReqWrap), Mode);
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync LogRel((DEVICE_NAME "::IOCtl: ddi_copyin failed to read header pArg=%p Cmd=%d. rc=%d.\n", pArg, Cmd, rc));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel((DEVICE_NAME "::IOCtl: bad magic %#x; pArg=%p Cmd=%d.\n", ReqWrap.u32Magic, pArg, Cmd));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel((DEVICE_NAME "::IOCtl: bad size %#x; pArg=%p Cmd=%d.\n", ReqWrap.cbData, pArg, Cmd));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Read the request.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel((DEVICE_NAME "::IOCtl: RTMemTmpAlloc failed to alloc %d bytes.\n", ReqWrap.cbData));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = ddi_copyin((void *)(uintptr_t)ReqWrap.pvDataR3, pvBuf, ReqWrap.cbData, Mode);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel((DEVICE_NAME "::IOCtl: ddi_copyin failed; pvBuf=%p pArg=%p Cmd=%d. rc=%d\n", pvBuf, pArg, Cmd, rc));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel((DEVICE_NAME "::IOCtl: pvBuf invalid pointer %p\n", pvBuf));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log((DEVICE_NAME "::IOCtl: pSession=%p pid=%d.\n", pSession, (int)RTProcSelf()));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Process the IOCtl.
13d75a5db336ccb682d7ab28b397a4f0b8982ea3vboxsync rc = VBoxGuestCommonIOCtl(Cmd, &g_DevExt, pSession, pvBuf, ReqWrap.cbData, &cbDataReturned);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel((DEVICE_NAME "::IOCtl: too much output data %d expected %d\n", cbDataReturned, ReqWrap.cbData));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = ddi_copyout(pvBuf, (void *)(uintptr_t)ReqWrap.pvDataR3, cbDataReturned, Mode);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel((DEVICE_NAME "::IOCtl: ddi_copyout failed; pvBuf=%p pArg=%p cbDataReturned=%u Cmd=%d. rc=%d\n",
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel((DEVICE_NAME "::IOCtl: VBoxGuestCommonIOCtl failed. rc=%d\n", rc));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int VBoxGuestSolarisPoll(dev_t Dev, short fEvents, int fAnyYet, short *pReqEvents, struct pollhead **ppPollHead)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow((DEVICE_NAME "::Poll: fEvents=%d fAnyYet=%d\n", fEvents, fAnyYet));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxguest_state_t *pState = ddi_get_soft_state(g_pVBoxGuestSolarisState, getminor(Dev));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)pState->pSession;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync uint32_t u32CurSeq = ASMAtomicUoReadU32(&g_DevExt.u32MousePosChangedSeq);
13d75a5db336ccb682d7ab28b397a4f0b8982ea3vboxsync Log((DEVICE_NAME "::Poll: no state data for %d\n", getminor(Dev)));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Sets IRQ for VMMDev.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @returns Solaris error code.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pDip Pointer to the device info structure.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow((DEVICE_NAME "::AddIRQ: pDip=%p\n", pDip));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int rc = ddi_intr_get_supported_types(pDip, &IntrType);
e11fe099decbb0f65cfcc7e2939fa00bacefbb1cvboxsync /* We won't need to bother about MSIs. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = ddi_intr_get_nintrs(pDip, IntrType, &IntrCount);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = ddi_intr_get_navail(pDip, IntrType, &IntrAvail);
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync /* Allocated kernel memory for the interrupt handles. The allocation size is stored internally. */
9f16100a870e25701da9bc9819e15c0f9fb3870evboxsync g_pIntr = RTMemAlloc(IntrCount * sizeof(ddi_intr_handle_t));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = ddi_intr_alloc(pDip, g_pIntr, IntrType, 0, IntrCount, &IntrAllocated, DDI_INTR_ALLOC_NORMAL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Initialize the mutex. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mutex_init(&g_IrqMtx, NULL, MUTEX_DRIVER, DDI_INTR_PRI(uIntrPriority));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Assign interrupt handler functions and enable interrupts. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync for (int i = 0; i < IntrAllocated; i++)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = ddi_intr_add_handler(g_pIntr[i], (ddi_intr_handler_t *)VBoxGuestSolarisISR,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Changing local IntrAllocated to hold so-far allocated handles for freeing. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Remove any assigned handlers */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel((DEVICE_NAME ":failed to assign IRQs allocated=%d\n", IntrAllocated));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync for (int x = 0; x < IntrAllocated; x++)
e11fe099decbb0f65cfcc7e2939fa00bacefbb1cvboxsync LogRel((DEVICE_NAME "::AddIRQ: failed to get priority of interrupt. rc=%d\n", rc));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Remove allocated IRQs, too bad we can free only one handle at a time. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync for (int k = 0; k < g_cIntrAllocated; k++)
ab0130d1627b2b214952b929de71b89e4ba41eb1vboxsync LogRel((DEVICE_NAME "::AddIRQ: failed to allocated IRQs. count=%d\n", IntrCount));
9f16100a870e25701da9bc9819e15c0f9fb3870evboxsync LogRel((DEVICE_NAME "::AddIRQ: failed to allocated IRQs. count=%d\n", IntrCount));
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync LogRel((DEVICE_NAME "::AddIRQ: failed to get or insufficient available IRQs. rc=%d IntrAvail=%d\n", rc, IntrAvail));
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync LogRel((DEVICE_NAME "::AddIRQ: failed to get or insufficient number of IRQs. rc=%d IntrCount=%d\n", rc, IntrCount));
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync LogRel((DEVICE_NAME "::AddIRQ: invalid irq type. IntrType=%#x\n", IntrType));
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync LogRel((DEVICE_NAME "::AddIRQ: failed to get supported interrupt types\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Removes IRQ for VMMDev.
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync * @param pDip Pointer to the device info structure.
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsyncstatic void VBoxGuestSolarisRemoveIRQ(dev_info_t *pDip)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync for (int i = 0; i < g_cIntrAllocated; i++)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Interrupt Service Routine for VMMDev.
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync * @param Arg Private data (unused, will be NULL).
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync * @returns DDI_INTR_CLAIMED if it's our interrupt, DDI_INTR_UNCLAIMED if it isn't.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return fOurIRQ ? DDI_INTR_CLAIMED : DDI_INTR_UNCLAIMED;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncvoid VBoxGuestNativeISRMousePollEvent(PVBOXGUESTDEVEXT pDevExt)
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync LogFlow((DEVICE_NAME "::NativeISRMousePollEvent:\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Wake up poll waiters.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/* Common code that depend on g_DevExt. */