VirtualBox

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

Last change on this file since 2676 was 1890, checked in by vboxsync, 17 years ago

Attempt to fix ALSA on Linux kernels <= 2.6.17: use mmap not memalign for allocating pages. Use madvise or mprotect to separater VM area structs inside the kernel. Most SUP* functions work on cPages now (not cBytes anymore). The free functions take a cPages parameter which is used for munmap on Linux.

File size: 7.7 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 InnoTek Systemberatung GmbH
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 as published by the Free Software Foundation,
14 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
15 * distribution. VirtualBox OSE is distributed in the hope that it will
16 * be useful, but WITHOUT ANY WARRANTY of any kind.
17 *
18 * If you received this file as part of a commercial VirtualBox
19 * distribution, then only the terms of your commercial VirtualBox
20 * license agreement apply instead of the previous paragraph.
21 */
22
23
24/*******************************************************************************
25* Header Files *
26*******************************************************************************/
27#define LOG_GROUP LOG_GROUP_SUP
28#include <VBox/types.h>
29#include <VBox/sup.h>
30#include <VBox/param.h>
31#include <VBox/err.h>
32#include <VBox/log.h>
33#include <iprt/path.h>
34#include <iprt/assert.h>
35#include <iprt/err.h>
36#include <iprt/string.h>
37#include "SUPLibInternal.h"
38#include "SUPDRVIOC.h"
39
40#include <sys/fcntl.h>
41#include <sys/ioctl.h>
42#include <errno.h>
43#include <unistd.h>
44#include <stdlib.h>
45#include <mach/mach_port.h>
46#include <IOKit/IOKitLib.h>
47
48
49/*******************************************************************************
50* Defined Constants And Macros *
51*******************************************************************************/
52/** BSD Device name. */
53#define DEVICE_NAME "/dev/vboxdrv"
54/** The IOClass key of the service (see SUPDrv-darwin.cpp / Info.plist). */
55#define IOCLASS_NAME "org_virtualbox_SupDrv"
56
57
58/*******************************************************************************
59* Global Variables *
60*******************************************************************************/
61/** Handle to the open device. */
62static int g_hDevice = -1;
63/** The IOMasterPort. */
64static mach_port_t g_MasterPort = 0;
65/** The current service connection. */
66static io_connect_t g_Connection = NULL;
67
68
69int suplibOsInit(size_t cbReserve)
70{
71 /*
72 * Check if already initialized.
73 */
74 if (g_hDevice >= 0)
75 return VINF_SUCCESS;
76
77 /*
78 * Open the IOKit client first - The first step is finding the service.
79 */
80 mach_port_t MasterPort;
81 kern_return_t kr = IOMasterPort(MACH_PORT_NULL, &MasterPort);
82 if (kr != kIOReturnSuccess)
83 {
84 LogRel(("IOMasterPort -> %d\n", kr));
85 return VERR_GENERAL_FAILURE;
86 }
87
88 CFDictionaryRef ClassToMatch = IOServiceMatching(IOCLASS_NAME);
89 if (!ClassToMatch)
90 {
91 LogRel(("IOServiceMatching(\"%s\") failed.\n", IOCLASS_NAME));
92 return VERR_GENERAL_FAILURE;
93 }
94
95 /* Create an io_iterator_t for all instances of our drivers class that exist in the IORegistry. */
96 io_iterator_t Iterator;
97 kr = IOServiceGetMatchingServices(g_MasterPort, ClassToMatch, &Iterator);
98 if (kr != kIOReturnSuccess)
99 {
100 LogRel(("IOServiceGetMatchingServices returned %d\n", kr));
101 return VERR_GENERAL_FAILURE;
102 }
103
104 /* Get the first item in the iterator and release it. */
105 io_service_t ServiceObject = IOIteratorNext(Iterator);
106 IOObjectRelease(Iterator);
107 if (!ServiceObject)
108 {
109 LogRel(("Couldn't find any matches.\n"));
110 return VERR_GENERAL_FAILURE;
111 }
112
113 /*
114 * Open the service.
115 * This will cause the user client class in SUPDrv-darwin.cpp to be instantiated.
116 */
117 kr = IOServiceOpen(ServiceObject, mach_task_self(), 0, &g_Connection);
118 IOObjectRelease(ServiceObject);
119 if (kr != kIOReturnSuccess)
120 {
121 LogRel(("IOServiceOpen returned %d\n", kr));
122 return VERR_GENERAL_FAILURE;
123 }
124
125 /*
126 * Now, try open the BSD device.
127 */
128 g_hDevice = open(DEVICE_NAME, O_RDWR, 0);
129 if (g_hDevice < 0)
130 {
131 int rc = errno;
132 LogRel(("Failed to open \"%s\", errno=%d\n", rc));
133 kr = IOServiceClose(g_Connection);
134 if (kr != kIOReturnSuccess)
135 LogRel(("Warning: IOServiceClose(%p) returned %d\n", g_Connection, kr));
136 return RTErrConvertFromErrno(rc);
137 }
138
139 /*
140 * We're done.
141 */
142 NOREF(cbReserve);
143 return VINF_SUCCESS;
144}
145
146
147int suplibOsTerm(void)
148{
149 /*
150 * Check if we're initited at all.
151 */
152 if (g_hDevice >= 0)
153 {
154 if (close(g_hDevice))
155 AssertFailed();
156 g_hDevice = -1;
157 }
158
159 /*
160 * Close the connection to the IOService and destroy the connection handle.
161 */
162 if (g_Connection)
163 {
164 kern_return_t kr = IOServiceClose(g_Connection);
165 if (kr != kIOReturnSuccess)
166 {
167 LogRel(("Warning: IOServiceClose(%p) returned %d\n", g_Connection, kr));
168 AssertFailed();
169 }
170 g_Connection = NULL;
171 }
172
173 return VINF_SUCCESS;
174}
175
176
177/**
178 * Installs anything required by the support library.
179 *
180 * @returns 0 on success.
181 * @returns error code on failure.
182 */
183int suplibOsInstall(void)
184{
185// int rc = mknod(DEVICE_NAME, S_IFCHR, );
186
187 return VERR_NOT_IMPLEMENTED;
188}
189
190
191/**
192 * Installs anything required by the support library.
193 *
194 * @returns 0 on success.
195 * @returns error code on failure.
196 */
197int suplibOsUninstall(void)
198{
199// int rc = unlink(DEVICE_NAME);
200
201 return VERR_NOT_IMPLEMENTED;
202}
203
204
205/**
206 * Send a I/O Control request to the device.
207 *
208 * @returns 0 on success.
209 * @returns VBOX error code on failure.
210 * @param uFunction IO Control function.
211 * @param pvIn Input data buffer.
212 * @param cbIn Size of input data.
213 * @param pvOut Output data buffer.
214 * @param cbOut Size of output data.
215 */
216int suplibOsIOCtl(unsigned uFunction, void *pvIn, size_t cbIn, void *pvOut, size_t cbOut)
217{
218 AssertMsg(g_hDevice != -1, ("SUPLIB not initiated successfully!\n"));
219 /*
220 * Issue device iocontrol.
221 */
222 SUPDRVIOCTLDATA Args;
223 Args.pvIn = pvIn;
224 Args.cbIn = cbIn;
225 Args.pvOut = pvOut;
226 Args.cbOut = cbOut;
227
228 if (ioctl(g_hDevice, uFunction, &Args) >= 0)
229 return 0;
230 /* This is the reverse operation of the one found in SUPDrv-linux.c */
231 switch (errno)
232 {
233 case EACCES: return VERR_GENERAL_FAILURE;
234 case EINVAL: return VERR_INVALID_PARAMETER;
235 case ENOSYS: return VERR_INVALID_MAGIC;
236 case ENXIO: return VERR_INVALID_HANDLE;
237 case EFAULT: return VERR_INVALID_POINTER;
238 case ENOLCK: return VERR_LOCK_FAILED;
239 case EEXIST: return VERR_ALREADY_LOADED;
240 }
241
242 return RTErrConvertFromErrno(errno);
243}
244
245#ifdef VBOX_WITHOUT_IDT_PATCHING
246int suplibOSIOCtlFast(unsigned uFunction)
247{
248 int rc = ioctl(g_hDevice, uFunction, NULL);
249 if (rc == -1)
250 rc = errno;
251 return rc;
252}
253#endif
254
255
256/**
257 * Allocate a number of zero-filled pages in user space.
258 *
259 * @returns VBox status code.
260 * @param cPages Number of pages to allocate.
261 * @param ppvPages Where to return the base pointer.
262 */
263int suplibOsPageAlloc(size_t cPages, void **ppvPages)
264{
265 *ppvPages = valloc(cPages << PAGE_SHIFT);
266 if (*ppvPages)
267 {
268 memset(*ppvPages, 0, cPages << PAGE_SHIFT);
269 return VINF_SUCCESS;
270 }
271 return RTErrConvertFromErrno(errno);
272}
273
274
275/**
276 * Frees pages allocated by suplibOsPageAlloc().
277 *
278 * @returns VBox status code.
279 * @param pvPages Pointer to pages.
280 */
281int suplibOsPageFree(void *pvPages, size_t /* cPages */)
282{
283 free(pvPages);
284 return VINF_SUCCESS;
285}
286
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use