VirtualBox

source: vbox/trunk/src/VBox/HostDrivers/Support/freebsd/SUPDrv-freebsd.c@ 4225

最後變更 在這個檔案從4225是 4016,由 vboxsync 提交於 18 年 前

FreeBSD hacking.

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Id
檔案大小: 8.8 KB
 
1/* $Id: SUPDrv-freebsd.c 4016 2007-08-03 00:54:43Z vboxsync $ */
2/** @file
3 * VBoxDrv - FreeBSD specifics.
4 */
5
6/*
7 * Copyright (c) 2007 knut st. osmundsen <[email protected]>
8 *
9 * Permission is hereby granted, free of charge, to any person
10 * obtaining a copy of this software and associated documentation
11 * files (the "Software"), to deal in the Software without
12 * restriction, including without limitation the rights to use,
13 * copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following
16 * conditions:
17 *
18 * The above copyright notice and this permission notice shall be
19 * included in all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
23 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
25 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28 * OTHER DEALINGS IN THE SOFTWARE.
29 */
30
31
32/*******************************************************************************
33* Header Files *
34*******************************************************************************/
35/* Deal with conflicts first. */
36#include <sys/param.h>
37#undef PVM
38#include <sys/types.h>
39#include <sys/module.h>
40#include <sys/systm.h>
41#include <sys/errno.h>
42#include <sys/kernel.h>
43#include <sys/conf.h>
44#include <sys/uio.h>
45
46#include "SUPDRV.h"
47#include <VBox/version.h>
48#include <iprt/initterm.h>
49#include <iprt/string.h>
50#include <iprt/spinlock.h>
51#include <iprt/process.h>
52#include <iprt/assert.h>
53#include <iprt/log.h>
54
55
56/*******************************************************************************
57* Internal Functions *
58*******************************************************************************/
59static int VBoxDrvFreeBSDModuleEvent(struct module *pMod, int enmEventType, void *pvArg);
60static int VBoxDrvFreeBSDLoad(void);
61static int VBoxDrvFreeBSDUnload(void);
62static d_fdopen_t VBoxDrvFreeBSDOpen;
63static d_close_t VBoxDrvFreeBSDClose;
64static d_ioctl_t VBoxDrvFreeBSDIOCtl;
65static int VBoxDrvFreeBsdErr2Native(int rc);
66
67
68/*******************************************************************************
69* Global Variables *
70*******************************************************************************/
71/**
72 * Module info structure used by the kernel.
73 */
74static moduledata_t g_VBoxDrvFreeBSDModule =
75{
76 "vboxdrv",
77 VBoxDrvFreeBSDModuleEvent,
78 NULL
79};
80
81/** Declare the module as a pseudo device. */
82DECLARE_MODULE(vboxdrv, g_VBoxDrvFreeBSDModule, SI_SUB_PSEUDO, SI_ORDER_ANY);
83
84/**
85 * The /dev/vboxdrv character device entry points.
86 */
87static struct cdevsw g_VBoxDrvFreeBSDChrDevSW =
88{
89 .d_version = D_VERSION,
90 .d_flags = D_TRACKCLOSE,
91 .d_fdopen = VBoxDrvFreeBSDOpen,
92 .d_close = VBoxDrvFreeBSDClose,
93 .d_ioctl = VBoxDrvFreeBSDIOCtl,
94 .d_name = "vboxdrv"
95};
96
97/** The make_dev result. */
98static struct cdev *g_pVBoxDrvFreeBSDChrDev;
99
100/** The device extention. */
101static SUPDRVDEVEXT g_DevExt;
102
103/** Spinlock protecting g_apSessionHashTab. */
104static RTSPINLOCK g_Spinlock = NIL_RTSPINLOCK;
105/** Hash table */
106static PSUPDRVSESSION g_apSessionHashTab[19];
107/** Calculates the index into g_apSessionHashTab.*/
108#define SESSION_HASH(sfn) ((sfn) % RT_ELEMENTS(g_apSessionHashTab))
109
110
111
112
113/**
114 * Module event handler.
115 *
116 * @param pMod The module structure.
117 * @param enmEventType The event type (modeventtype_t).
118 * @param pvArg Module argument. NULL.
119 *
120 * @return 0 on success, errno.h status code on failure.
121 */
122static int VBoxDrvFreeBSDModuleEvent(struct module *pMod, int enmEventType, void *pvArg)
123{
124 int rc;
125 switch (enmEventType)
126 {
127 case MOD_LOAD:
128 rc = VBoxDrvFreeBSDLoad();
129 break;
130
131 case MOD_UNLOAD:
132 rc = VBoxDrvFreeBSDUnload();
133 break;
134
135 case MOD_SHUTDOWN:
136 case MOD_QUIESCE:
137 default:
138 return EOPNOTSUPP;
139 }
140
141 if (RT_SUCCESS(rc))
142 return 0;
143 return VBoxDrvFreeBsdErr2Native(rc);
144}
145
146
147static int VBoxDrvFreeBSDLoad(void)
148{
149 dprintf(("VBoxDrvFreeBSDLoad:\n"));
150
151 /*
152 * Initialize the runtime.
153 */
154 int rc = RTR0Init(0);
155 if (RT_SUCCESS(rc))
156 {
157 /*
158 * Initialize the device extension.
159 */
160 rc = supdrvInitDevExt(&g_DevExt);
161 if (RT_SUCCESS(rc))
162 {
163 /*
164 * Initialize the session hash table.
165 */
166 rc = RTSpinlockCreate(&g_Spinlock);
167 if (RT_SUCCESS(rc))
168 {
169 /*
170 * Create our device node.
171 */
172 /** @todo find a way to fix this 0666 permission issue. Perhaps by defining some vboxusers group with a fixed gid? */
173 g_pVBoxDrvFreeBSDChrDev = make_dev(&g_VBoxDrvFreeBSDChrDevSW,
174 0,
175 UID_ROOT,
176 GID_WHEEL,
177 0666,
178 "vboxdrv");
179 if (g_pVBoxDrvFreeBSDChrDev)
180 {
181 dprintf(("VBoxDrvFreeBSDLoad: returns successfully\n"));
182 return VINF_SUCCESS;
183 }
184
185 printf("vboxdrv: make_dev failed\n");
186 rc = SUPDRV_ERR_ALREADY_LOADED;
187 RTSpinlockDestroy(g_Spinlock);
188 g_Spinlock = NIL_RTSPINLOCK;
189 }
190 else
191 printf("vboxdrv: RTSpinlockCreate failed, rc=%d\n", rc);
192 supdrvDeleteDevExt(&g_DevExt);
193 }
194 else
195 printf("vboxdrv: supdrvInitDevExt failed, rc=%d\n", rc);
196 RTR0Term();
197 }
198 else
199 printf("vboxdrv: RTR0Init failed, rc=%d\n", rc);
200 return rc;
201}
202
203static int VBoxDrvFreeBSDUnload(void)
204{
205 int rc;
206 dprintf(("VBoxDrvFreeBSDUnload:\n"));
207
208 /** @todo verify that FreeBSD does reference counting. */
209
210 /*
211 * Reserve what we did in VBoxDrvFreeBSDInit.
212 */
213 if (g_pVBoxDrvFreeBSDChrDev)
214 {
215 destroy_dev(g_pVBoxDrvFreeBSDChrDev);
216 g_pVBoxDrvFreeBSDChrDev = NULL;
217 }
218
219 rc = supdrvDeleteDevExt(&g_DevExt);
220 AssertRC(rc);
221
222 rc = RTSpinlockDestroy(g_Spinlock);
223 AssertRC(rc);
224 g_Spinlock = NIL_RTSPINLOCK;
225
226 RTR0Term();
227
228 memset(&g_DevExt, 0, sizeof(g_DevExt));
229
230 dprintf(("VBoxDrvFreeBSDUnload: returns\n"));
231 return VINF_SUCCESS;
232}
233
234
235static int VBoxDrvFreeBSDOpen(struct cdev *dev, int oflags, struct thread *td, int fdidx)
236{
237 dprintf(("VBoxDrvFreeBSDOpen:\n"));
238 return EOPNOTSUPP;
239}
240
241
242static int VBoxDrvFreeBSDClose(struct cdev *dev, int fflag, int devtype, struct thread *td)
243{
244 dprintf(("VBoxDrvFreeBSDClose:\n"));
245 return EBADF;
246}
247
248
249static int VBoxDrvFreeBSDIOCtl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread *td)
250{
251 dprintf(("VBoxDrvFreeBSDIOCtl:\n"));
252 return EINVAL;
253}
254
255
256/**
257 * Converts an supdrv error code to a FreeBSD error code.
258 *
259 * @returns corresponding FreeBSD error code.
260 * @param rc supdrv error code (SUPDRV_ERR_* defines).
261 */
262static int VBoxDrvFreeBsdErr2Native(int rc)
263{
264 switch (rc)
265 {
266 case 0: return 0;
267 case SUPDRV_ERR_GENERAL_FAILURE: return EACCES;
268 case SUPDRV_ERR_INVALID_PARAM: return EINVAL;
269 case SUPDRV_ERR_INVALID_MAGIC: return EILSEQ;
270 case SUPDRV_ERR_INVALID_HANDLE: return ENXIO;
271 case SUPDRV_ERR_INVALID_POINTER: return EFAULT;
272 case SUPDRV_ERR_LOCK_FAILED: return ENOLCK;
273 case SUPDRV_ERR_ALREADY_LOADED: return EEXIST;
274 case SUPDRV_ERR_PERMISSION_DENIED: return EPERM;
275 case SUPDRV_ERR_VERSION_MISMATCH: return ENOSYS;
276 }
277
278 return EPERM;
279}
280
281
282void VBOXCALL supdrvOSObjInitCreator(PSUPDRVOBJ pObj, PSUPDRVSESSION pSession)
283{
284 NOREF(pObj);
285 NOREF(pSession);
286}
287
288
289bool VBOXCALL supdrvOSObjCanAccess(PSUPDRVOBJ pObj, PSUPDRVSESSION pSession, const char *pszObjName, int *prc)
290{
291 NOREF(pObj);
292 NOREF(pSession);
293 NOREF(pszObjName);
294 NOREF(prc);
295 return false;
296}
297
298
299SUPR0DECL(int) SUPR0Printf(const char *pszFormat, ...)
300{
301 va_list va;
302 char szMsg[256];
303 int cch;
304
305 va_start(va, pszFormat);
306 cch = RTStrPrintfV(szMsg, sizeof(szMsg), pszFormat, va);
307 va_end(va);
308
309 printf("%s", szMsg);
310
311 return cch;
312}
313
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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