VBoxGuestIDC-unix.c.h revision b53ae39cd277866a2b502bcd33548af30d430b64
de4157257515400c2c25373591135f110227b68cvboxsync/* $Rev$ */
de4157257515400c2c25373591135f110227b68cvboxsync/** @file
de4157257515400c2c25373591135f110227b68cvboxsync * VBoxGuest - Inter Driver Communication, unix implementation.
de4157257515400c2c25373591135f110227b68cvboxsync *
de4157257515400c2c25373591135f110227b68cvboxsync * This file is included by the platform specific source file.
de4157257515400c2c25373591135f110227b68cvboxsync */
e64031e20c39650a7bc902a3e1aba613b9415deevboxsync
de4157257515400c2c25373591135f110227b68cvboxsync/*
b263fac6f6e7fa933c7bfb2a45d598fe8e458c09vboxsync * Copyright (C) 2006-2009 Oracle Corporation
b263fac6f6e7fa933c7bfb2a45d598fe8e458c09vboxsync *
b263fac6f6e7fa933c7bfb2a45d598fe8e458c09vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
b263fac6f6e7fa933c7bfb2a45d598fe8e458c09vboxsync * available from http://www.virtualbox.org. This file is free software;
b263fac6f6e7fa933c7bfb2a45d598fe8e458c09vboxsync * you can redistribute it and/or modify it under the terms of the GNU
b263fac6f6e7fa933c7bfb2a45d598fe8e458c09vboxsync * General Public License (GPL) as published by the Free Software
b263fac6f6e7fa933c7bfb2a45d598fe8e458c09vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
de4157257515400c2c25373591135f110227b68cvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
de4157257515400c2c25373591135f110227b68cvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
de4157257515400c2c25373591135f110227b68cvboxsync * Some lines of code to disable the local APIC on x86_64 machines taken
de4157257515400c2c25373591135f110227b68cvboxsync * from a Mandriva patch by Gwenole Beauchesne <gbeauchesne@mandriva.com>.
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync */
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync/** @todo Use some header that we have in common with VBoxGuestLib.h... */
de4157257515400c2c25373591135f110227b68cvboxsyncDECLVBGL(void *) VBoxGuestIDCOpen(uint32_t *pu32Version);
de4157257515400c2c25373591135f110227b68cvboxsyncDECLVBGL(int) VBoxGuestIDCClose(void *pvSession);
de4157257515400c2c25373591135f110227b68cvboxsyncDECLVBGL(int) VBoxGuestIDCCall(void *pvSession, unsigned iCmd, void *pvData, size_t cbData, size_t *pcbDataReturned);
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync/**
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync * Open a new IDC connection.
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync *
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync * @returns Opaque pointer to session object.
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync * @param pu32Version Where to store VMMDev version.
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync */
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsyncDECLVBGL(void *) VBoxGuestIDCOpen(uint32_t *pu32Version)
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync{
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync PVBOXGUESTSESSION pSession;
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync int rc;
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync LogFlow(("VBoxGuestIDCOpen: Version=%#x\n", pu32Version ? *pu32Version : 0));
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync AssertPtrReturn(pu32Version, NULL);
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync#ifdef RT_OS_SOLARIS
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync mutex_enter(&g_LdiMtx);
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync if (!g_LdiHandle)
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync {
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync ldi_ident_t DevIdent = ldi_ident_from_anon();
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync rc = ldi_open_by_name(VBOXGUEST_DEVICE_NAME, FREAD, kcred, &g_LdiHandle, DevIdent);
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync ldi_ident_release(DevIdent);
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync if (rc)
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync {
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync LogRel(("VBoxGuestIDCOpen: ldi_open_by_name failed. rc=%d\n", rc));
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync mutex_exit(&g_LdiMtx);
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync return NULL;
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync }
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync }
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync ++g_cLdiOpens;
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync mutex_exit(&g_LdiMtx);
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync#endif
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync rc = VBoxGuestCreateKernelSession(&g_DevExt, &pSession);
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync if (RT_SUCCESS(rc))
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync {
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync *pu32Version = VMMDEV_VERSION;
de4157257515400c2c25373591135f110227b68cvboxsync return pSession;
de4157257515400c2c25373591135f110227b68cvboxsync }
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync#ifdef RT_OS_SOLARIS
de4157257515400c2c25373591135f110227b68cvboxsync mutex_enter(&g_LdiMtx);
de4157257515400c2c25373591135f110227b68cvboxsync if (g_cLdiOpens > 0)
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync --g_cLdiOpens;
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync if ( g_cLdiOpens == 0
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync && g_LdiHandle)
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync {
de4157257515400c2c25373591135f110227b68cvboxsync ldi_close(g_LdiHandle, FREAD, kcred);
de4157257515400c2c25373591135f110227b68cvboxsync g_LdiHandle = NULL;
de4157257515400c2c25373591135f110227b68cvboxsync }
de4157257515400c2c25373591135f110227b68cvboxsync mutex_exit(&g_LdiMtx);
de4157257515400c2c25373591135f110227b68cvboxsync#endif
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync LogRel(("VBoxGuestIDCOpen: VBoxGuestCreateKernelSession failed. rc=%d\n", rc));
de4157257515400c2c25373591135f110227b68cvboxsync return NULL;
de4157257515400c2c25373591135f110227b68cvboxsync}
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync/**
de4157257515400c2c25373591135f110227b68cvboxsync * Close an IDC connection.
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync *
de4157257515400c2c25373591135f110227b68cvboxsync * @returns VBox error code.
de4157257515400c2c25373591135f110227b68cvboxsync * @param pvState Opaque pointer to the session object.
de4157257515400c2c25373591135f110227b68cvboxsync */
de4157257515400c2c25373591135f110227b68cvboxsyncDECLVBGL(int) VBoxGuestIDCClose(void *pvSession)
de4157257515400c2c25373591135f110227b68cvboxsync{
de4157257515400c2c25373591135f110227b68cvboxsync PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)pvSession;
de4157257515400c2c25373591135f110227b68cvboxsync LogFlow(("VBoxGuestIDCClose:\n"));
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync AssertPtrReturn(pSession, VERR_INVALID_POINTER);
de4157257515400c2c25373591135f110227b68cvboxsync VBoxGuestCloseSession(&g_DevExt, pSession);
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync#ifdef RT_OS_SOLARIS
de4157257515400c2c25373591135f110227b68cvboxsync mutex_enter(&g_LdiMtx);
de4157257515400c2c25373591135f110227b68cvboxsync if (g_cLdiOpens > 0)
de4157257515400c2c25373591135f110227b68cvboxsync --g_cLdiOpens;
de4157257515400c2c25373591135f110227b68cvboxsync if ( g_cLdiOpens == 0
de4157257515400c2c25373591135f110227b68cvboxsync && g_LdiHandle)
de4157257515400c2c25373591135f110227b68cvboxsync {
de4157257515400c2c25373591135f110227b68cvboxsync ldi_close(g_LdiHandle, FREAD, kcred);
de4157257515400c2c25373591135f110227b68cvboxsync g_LdiHandle = NULL;
de4157257515400c2c25373591135f110227b68cvboxsync }
de4157257515400c2c25373591135f110227b68cvboxsync mutex_exit(&g_LdiMtx);
de4157257515400c2c25373591135f110227b68cvboxsync#endif
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync return VINF_SUCCESS;
de4157257515400c2c25373591135f110227b68cvboxsync}
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync/**
de4157257515400c2c25373591135f110227b68cvboxsync * Perform an IDC call.
de4157257515400c2c25373591135f110227b68cvboxsync *
de4157257515400c2c25373591135f110227b68cvboxsync * @returns VBox error code.
de4157257515400c2c25373591135f110227b68cvboxsync * @param pvSession Opaque pointer to the session.
de4157257515400c2c25373591135f110227b68cvboxsync * @param iCmd Requested function.
de4157257515400c2c25373591135f110227b68cvboxsync * @param pvData IO data buffer.
de4157257515400c2c25373591135f110227b68cvboxsync * @param cbData Size of the data buffer.
de4157257515400c2c25373591135f110227b68cvboxsync * @param pcbDataReturned Where to store the amount of returned data.
de4157257515400c2c25373591135f110227b68cvboxsync */
de4157257515400c2c25373591135f110227b68cvboxsyncDECLVBGL(int) VBoxGuestIDCCall(void *pvSession, unsigned iCmd, void *pvData, size_t cbData, size_t *pcbDataReturned)
de4157257515400c2c25373591135f110227b68cvboxsync{
de4157257515400c2c25373591135f110227b68cvboxsync PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)pvSession;
de4157257515400c2c25373591135f110227b68cvboxsync LogFlow(("VBoxGuestIDCCall: %pvSession=%p Cmd=%u pvData=%p cbData=%d\n", pvSession, iCmd, pvData, cbData));
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync AssertPtrReturn(pSession, VERR_INVALID_POINTER);
de4157257515400c2c25373591135f110227b68cvboxsync AssertMsgReturn(pSession->pDevExt == &g_DevExt,
de4157257515400c2c25373591135f110227b68cvboxsync ("SC: %p != %p\n", pSession->pDevExt, &g_DevExt), VERR_INVALID_HANDLE);
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync return VBoxGuestCommonIOCtl(iCmd, &g_DevExt, pSession, pvData, cbData, pcbDataReturned);
de4157257515400c2c25373591135f110227b68cvboxsync}
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync