VirtualBox

source: vbox/trunk/src/VBox/HostDrivers/Support/darwin/SUPLib-darwin.cpp@ 10256

Last change on this file since 10256 was 10256, checked in by vboxsync, 16 years ago

SUPDRVIOC.h -> (../)SUPDrvIOC.h

File size: 7.2 KB
Line 
1/** @file
2 *
3 * VBox host drivers - Ring-0 support drivers - Darwin host:
4 * Darwin implementations for support library
5 */
6
7/*
8 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 *
18 * The contents of this file may alternatively be used under the terms
19 * of the Common Development and Distribution License Version 1.0
20 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
21 * VirtualBox OSE distribution, in which case the provisions of the
22 * CDDL are applicable instead of those of the GPL.
23 *
24 * You may elect to license modified versions of this file under the
25 * terms and conditions of either the GPL or the CDDL or both.
26 *
27 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
28 * Clara, CA 95054 USA or visit http://www.sun.com if you need
29 * additional information or have any questions.
30 */
31
32
33/*******************************************************************************
34* Header Files *
35*******************************************************************************/
36#define LOG_GROUP LOG_GROUP_SUP
37#include <VBox/types.h>
38#include <VBox/sup.h>
39#include <VBox/param.h>
40#include <VBox/err.h>
41#include <VBox/log.h>
42#include <iprt/path.h>
43#include <iprt/assert.h>
44#include <iprt/err.h>
45#include <iprt/string.h>
46#include "../SUPLibInternal.h"
47#include "../SUPDrvIOC.h"
48
49#include <sys/fcntl.h>
50#include <sys/ioctl.h>
51#include <errno.h>
52#include <unistd.h>
53#include <stdlib.h>
54#include <mach/mach_port.h>
55#include <IOKit/IOKitLib.h>
56
57
58/*******************************************************************************
59* Defined Constants And Macros *
60*******************************************************************************/
61/** BSD Device name. */
62#define DEVICE_NAME "/dev/vboxdrv"
63/** The IOClass key of the service (see SUPDrv-darwin.cpp / Info.plist). */
64#define IOCLASS_NAME "org_virtualbox_SupDrv"
65
66
67/*******************************************************************************
68* Global Variables *
69*******************************************************************************/
70/** Handle to the open device. */
71static int g_hDevice = -1;
72/** The IOMasterPort. */
73static mach_port_t g_MasterPort = 0;
74/** The current service connection. */
75static io_connect_t g_Connection = NULL;
76
77
78int suplibOsInit(size_t cbReserve)
79{
80 /*
81 * Check if already initialized.
82 */
83 if (g_hDevice >= 0)
84 return VINF_SUCCESS;
85
86 /*
87 * Open the IOKit client first - The first step is finding the service.
88 */
89 mach_port_t MasterPort;
90 kern_return_t kr = IOMasterPort(MACH_PORT_NULL, &MasterPort);
91 if (kr != kIOReturnSuccess)
92 {
93 LogRel(("IOMasterPort -> %d\n", kr));
94 return VERR_GENERAL_FAILURE;
95 }
96
97 CFDictionaryRef ClassToMatch = IOServiceMatching(IOCLASS_NAME);
98 if (!ClassToMatch)
99 {
100 LogRel(("IOServiceMatching(\"%s\") failed.\n", IOCLASS_NAME));
101 return VERR_GENERAL_FAILURE;
102 }
103
104 /* Create an io_iterator_t for all instances of our drivers class that exist in the IORegistry. */
105 io_iterator_t Iterator;
106 kr = IOServiceGetMatchingServices(g_MasterPort, ClassToMatch, &Iterator);
107 if (kr != kIOReturnSuccess)
108 {
109 LogRel(("IOServiceGetMatchingServices returned %d\n", kr));
110 return VERR_GENERAL_FAILURE;
111 }
112
113 /* Get the first item in the iterator and release it. */
114 io_service_t ServiceObject = IOIteratorNext(Iterator);
115 IOObjectRelease(Iterator);
116 if (!ServiceObject)
117 {
118 LogRel(("SUP: Couldn't find any matches. The kernel module is probably not loaded.\n"));
119 return VERR_VM_DRIVER_NOT_INSTALLED;
120 }
121
122 /*
123 * Open the service.
124 * This will cause the user client class in SUPDrv-darwin.cpp to be instantiated.
125 */
126 kr = IOServiceOpen(ServiceObject, mach_task_self(), 0, &g_Connection);
127 IOObjectRelease(ServiceObject);
128 if (kr != kIOReturnSuccess)
129 {
130 LogRel(("SUP: IOServiceOpen returned %d. Driver open failed.\n", kr));
131 return VERR_VM_DRIVER_OPEN_ERROR;
132 }
133
134 /*
135 * Now, try open the BSD device.
136 */
137 g_hDevice = open(DEVICE_NAME, O_RDWR, 0);
138 if (g_hDevice < 0)
139 {
140 int rc;
141 switch (errno)
142 {
143 case ENODEV: rc = VERR_VM_DRIVER_LOAD_ERROR; break;
144 case EPERM:
145 case EACCES: rc = VERR_VM_DRIVER_NOT_ACCESSIBLE; break;
146 case ENOENT: rc = VERR_VM_DRIVER_NOT_INSTALLED; break;
147 default: rc = VERR_VM_DRIVER_OPEN_ERROR; break;
148 }
149 LogRel(("SUP: Failed to open \"%s\", errno=%d, rc=%Vrc\n", DEVICE_NAME, errno, rc));
150
151 kr = IOServiceClose(g_Connection);
152 if (kr != kIOReturnSuccess)
153 LogRel(("Warning: IOServiceClose(%p) returned %d\n", g_Connection, kr));
154 return rc;
155 }
156
157 /*
158 * Mark the file handle close on exec.
159 */
160 if (fcntl(g_hDevice, F_SETFD, FD_CLOEXEC) != 0)
161 {
162 int rc = errno;
163 LogRel(("suplibOSInit: setting FD_CLOEXEC failed, errno=%d\n", rc));
164 close(g_hDevice);
165 g_hDevice = -1;
166 return RTErrConvertFromErrno(rc);
167 }
168
169 /*
170 * We're done.
171 */
172 NOREF(cbReserve);
173 return VINF_SUCCESS;
174}
175
176
177int suplibOsTerm(void)
178{
179 /*
180 * Check if we're initited at all.
181 */
182 if (g_hDevice >= 0)
183 {
184 if (close(g_hDevice))
185 AssertFailed();
186 g_hDevice = -1;
187 }
188
189 /*
190 * Close the connection to the IOService and destroy the connection handle.
191 */
192 if (g_Connection)
193 {
194 kern_return_t kr = IOServiceClose(g_Connection);
195 if (kr != kIOReturnSuccess)
196 {
197 LogRel(("Warning: IOServiceClose(%p) returned %d\n", g_Connection, kr));
198 AssertFailed();
199 }
200 g_Connection = NULL;
201 }
202
203 return VINF_SUCCESS;
204}
205
206
207int suplibOsInstall(void)
208{
209 return VERR_NOT_IMPLEMENTED;
210}
211
212
213int suplibOsUninstall(void)
214{
215 return VERR_NOT_IMPLEMENTED;
216}
217
218
219int suplibOsIOCtl(uintptr_t uFunction, void *pvReq, size_t cbReq)
220{
221 AssertMsg(g_hDevice != -1, ("SUPLIB not initiated successfully!\n"));
222
223 if (RT_LIKELY(ioctl(g_hDevice, uFunction, pvReq) >= 0))
224 return VINF_SUCCESS;
225 return RTErrConvertFromErrno(errno);
226}
227
228
229int suplibOsIOCtlFast(uintptr_t uFunction)
230{
231 int rc = ioctl(g_hDevice, uFunction, NULL);
232 if (rc == -1)
233 rc = errno;
234 return rc;
235}
236
237
238int suplibOsPageAlloc(size_t cPages, void **ppvPages)
239{
240 *ppvPages = valloc(cPages << PAGE_SHIFT);
241 if (*ppvPages)
242 {
243 memset(*ppvPages, 0, cPages << PAGE_SHIFT);
244 return VINF_SUCCESS;
245 }
246 return RTErrConvertFromErrno(errno);
247}
248
249
250int suplibOsPageFree(void *pvPages, size_t /* cPages */)
251{
252 free(pvPages);
253 return VINF_SUCCESS;
254}
255
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette