VirtualBox

source: vbox/trunk/src/VBox/Additions/common/VBoxGuest/VBoxDev-haiku.c@ 62484

Last change on this file since 62484 was 58113, checked in by vboxsync, 9 years ago

VBoxGuest: Vbgd -> VGDrv, cleanups - will probably not build cleanly everywhere. :)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.0 KB
Line 
1/* $Id: VBoxDev-haiku.c 58113 2015-10-08 10:13:54Z vboxsync $ */
2/** @file
3 * VBoxGuest kernel driver, Haiku Guest Additions, implementation.
4 */
5
6/*
7 * Copyright (C) 2012-2015 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18/*
19 * This code is based on:
20 *
21 * VirtualBox Guest Additions for Haiku.
22 * Copyright (c) 2011 Mike Smith <mike@scgtrp.net>
23 * François Revol <revol@free.fr>
24 *
25 * Permission is hereby granted, free of charge, to any person
26 * obtaining a copy of this software and associated documentation
27 * files (the "Software"), to deal in the Software without
28 * restriction, including without limitation the rights to use,
29 * copy, modify, merge, publish, distribute, sublicense, and/or sell
30 * copies of the Software, and to permit persons to whom the
31 * Software is furnished to do so, subject to the following
32 * conditions:
33 *
34 * The above copyright notice and this permission notice shall be
35 * included in all copies or substantial portions of the Software.
36 *
37 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
38 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
39 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
40 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
41 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
42 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
43 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
44 * OTHER DEALINGS IN THE SOFTWARE.
45 */
46
47
48/*********************************************************************************************************************************
49* Header Files *
50*********************************************************************************************************************************/
51#include <sys/param.h>
52#include <sys/types.h>
53#include <sys/uio.h>
54#include <OS.h>
55#include <Drivers.h>
56#include <KernelExport.h>
57#include <PCI.h>
58
59#include "VBoxGuest-haiku.h"
60#include "VBoxGuestInternal.h"
61#include <VBox/log.h>
62#include <iprt/assert.h>
63#include <iprt/initterm.h>
64#include <iprt/process.h>
65#include <iprt/mem.h>
66#include <iprt/asm.h>
67
68#define DRIVER_NAME "vboxdev"
69#define DEVICE_NAME "misc/vboxguest"
70#define MODULE_NAME "generic/vboxguest"
71
72
73/*********************************************************************************************************************************
74* Global Variables *
75*********************************************************************************************************************************/
76int32 api_version = B_CUR_DRIVER_API_VERSION;
77
78
79/**
80 * Driver open hook.
81 *
82 * @param name The name of the device as returned by publish_devices.
83 * @param flags Open flags.
84 * @param cookie Where to store the session pointer.
85 *
86 * @return Haiku status code.
87 */
88static status_t vgdrvHaikuOpen(const char *name, uint32 flags, void **cookie)
89{
90 int rc;
91 PVBOXGUESTSESSION pSession;
92
93 LogFlow((DRIVER_NAME ":vgdrvHaikuOpen\n"));
94
95 /*
96 * Create a new session.
97 */
98 rc = VGDrvCommonCreateUserSession(&g_DevExt, &pSession);
99 if (RT_SUCCESS(rc))
100 {
101 Log((DRIVER_NAME ":vgdrvHaikuOpen success: g_DevExt=%p pSession=%p rc=%d pid=%d\n",&g_DevExt, pSession, rc,(int)RTProcSelf()));
102 ASMAtomicIncU32(&cUsers);
103 *cookie = pSession;
104 return B_OK;
105 }
106
107 LogRel((DRIVER_NAME ":vgdrvHaikuOpen: failed. rc=%d\n", rc));
108 return RTErrConvertToErrno(rc);
109}
110
111
112/**
113 * Driver close hook.
114 * @param cookie The session.
115 *
116 * @return Haiku status code.
117 */
118static status_t vgdrvHaikuClose(void *cookie)
119{
120 PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)cookie;
121 Log(("vgdrvHaikuClose: pSession=%p\n", pSession));
122
123 /** @todo r=ramshankar: should we really be using the session spinlock here? */
124 RTSpinlockAcquire(g_DevExt.SessionSpinlock);
125
126 /* @todo we don't know if it belongs to this session!! */
127 if (sState.selectSync)
128 {
129 //dprintf(DRIVER_NAME "close: unblocking select %p %x\n", sState.selectSync, sState.selectEvent);
130 notify_select_event(sState.selectSync, sState.selectEvent);
131 sState.selectEvent = (uint8_t)0;
132 sState.selectRef = (uint32_t)0;
133 sState.selectSync = (void *)NULL;
134 }
135
136 RTSpinlockRelease(g_DevExt.SessionSpinlock);
137 return B_OK;
138}
139
140
141/**
142 * Driver free hook.
143 * @param cookie The session.
144 *
145 * @return Haiku status code.
146 */
147static status_t vgdrvHaikuFree(void *cookie)
148{
149 PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)cookie;
150 Log(("vgdrvHaikuFree: pSession=%p\n", pSession));
151
152 /*
153 * Close the session if it's still hanging on to the device...
154 */
155 if (VALID_PTR(pSession))
156 {
157 VGDrvCommonCloseSession(&g_DevExt, pSession);
158 ASMAtomicDecU32(&cUsers);
159 }
160 else
161 Log(("vgdrvHaikuFree: si_drv1=%p!\n", pSession));
162 return B_OK;
163}
164
165
166/**
167 * Driver IOCtl entry.
168 * @param cookie The session.
169 * @param op The operation to perform.
170 * @param data The data associated with the operation.
171 * @param len Size of the data in bytes.
172 *
173 * @return Haiku status code.
174 */
175static status_t vgdrvHaikuIOCtl(void *cookie, uint32 op, void *data, size_t len)
176{
177 PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)cookie;
178 int rc;
179 Log(("vgdrvHaikuIOCtl: cookie=%p op=0x%08x data=%p len=%lu)\n", cookie, op, data, len));
180
181 /*
182 * Validate the input.
183 */
184 if (RT_UNLIKELY(!VALID_PTR(pSession)))
185 return EINVAL;
186
187 /*
188 * Validate the request wrapper.
189 */
190#if 0
191 if (IOCPARM_LEN(ulCmd) != sizeof(VBGLBIGREQ))
192 {
193 Log((DRIVER_NAME ": vgdrvHaikuIOCtl: bad request %lu size=%lu expected=%d\n", ulCmd, IOCPARM_LEN(ulCmd),
194 sizeof(VBGLBIGREQ)));
195 return ENOTTY;
196 }
197#endif
198
199 if (RT_UNLIKELY(len > _1M * 16))
200 {
201 dprintf(DRIVER_NAME ": vgdrvHaikuIOCtl: bad size %#x; pArg=%p Cmd=%lu.\n", (unsigned)len, data, op);
202 return EINVAL;
203 }
204
205 /*
206 * Read the request.
207 */
208 void *pvBuf = NULL;
209 if (RT_LIKELY(len > 0))
210 {
211 pvBuf = RTMemTmpAlloc(len);
212 if (RT_UNLIKELY(!pvBuf))
213 {
214 LogRel((DRIVER_NAME ":vgdrvHaikuIOCtl: RTMemTmpAlloc failed to alloc %d bytes.\n", len));
215 return ENOMEM;
216 }
217
218 /** @todo r=ramshankar: replace with RTR0MemUserCopyFrom() */
219 rc = user_memcpy(pvBuf, data, len);
220 if (RT_UNLIKELY(rc < 0))
221 {
222 RTMemTmpFree(pvBuf);
223 LogRel((DRIVER_NAME ":vgdrvHaikuIOCtl: user_memcpy failed; pvBuf=%p data=%p op=%d. rc=%d\n", pvBuf, data, op, rc));
224 return EFAULT;
225 }
226 if (RT_UNLIKELY(!VALID_PTR(pvBuf)))
227 {
228 RTMemTmpFree(pvBuf);
229 LogRel((DRIVER_NAME ":vgdrvHaikuIOCtl: pvBuf invalid pointer %p\n", pvBuf));
230 return EINVAL;
231 }
232 }
233 Log(("vgdrvHaikuIOCtl: pSession=%p pid=%d.\n", pSession,(int)RTProcSelf()));
234
235 /*
236 * Process the IOCtl.
237 */
238 size_t cbDataReturned;
239 rc = VGDrvCommonIoCtl(op, &g_DevExt, pSession, pvBuf, len, &cbDataReturned);
240 if (RT_SUCCESS(rc))
241 {
242 rc = 0;
243 if (RT_UNLIKELY(cbDataReturned > len))
244 {
245 Log(("vgdrvHaikuIOCtl: too much output data %d expected %d\n", cbDataReturned, len));
246 cbDataReturned = len;
247 }
248 if (cbDataReturned > 0)
249 {
250 rc = user_memcpy(data, pvBuf, cbDataReturned);
251 if (RT_UNLIKELY(rc < 0))
252 {
253 Log(("vgdrvHaikuIOCtl: user_memcpy failed; pvBuf=%p pArg=%p Cmd=%lu. rc=%d\n", pvBuf, data, op, rc));
254 rc = EFAULT;
255 }
256 }
257 }
258 else
259 {
260 Log(("vgdrvHaikuIOCtl: VGDrvCommonIoCtl failed. rc=%d\n", rc));
261 rc = EFAULT;
262 }
263 RTMemTmpFree(pvBuf);
264 return rc;
265}
266
267
268/**
269 * Driver select hook.
270 *
271 * @param cookie The session.
272 * @param event The event.
273 * @param ref ???
274 * @param sync ???
275 *
276 * @return Haiku status code.
277 */
278static status_t vgdrvHaikuSelect(void *cookie, uint8 event, uint32 ref, selectsync *sync)
279{
280 PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)cookie;
281 status_t err = B_OK;
282
283 switch (event)
284 {
285 case B_SELECT_READ:
286 break;
287 default:
288 return EINVAL;
289 }
290
291 RTSpinlockAcquire(g_DevExt.SessionSpinlock);
292
293 uint32_t u32CurSeq = ASMAtomicUoReadU32(&g_DevExt.u32MousePosChangedSeq);
294 if (pSession->u32MousePosChangedSeq != u32CurSeq)
295 {
296 pSession->u32MousePosChangedSeq = u32CurSeq;
297 notify_select_event(sync, event);
298 }
299 else if (sState.selectSync == NULL)
300 {
301 sState.selectEvent = (uint8_t)event;
302 sState.selectRef = (uint32_t)ref;
303 sState.selectSync = (void *)sync;
304 }
305 else
306 err = B_WOULD_BLOCK;
307
308 RTSpinlockRelease(g_DevExt.SessionSpinlock);
309
310 return err;
311}
312
313
314/**
315 * Driver deselect hook.
316 * @param cookie The session.
317 * @param event The event.
318 * @param sync ???
319 *
320 * @return Haiku status code.
321 */
322static status_t vgdrvHaikuDeselect(void *cookie, uint8 event, selectsync *sync)
323{
324 PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)cookie;
325 status_t err = B_OK;
326 //dprintf(DRIVER_NAME "deselect(,%d,%p)\n", event, sync);
327
328 RTSpinlockAcquire(g_DevExt.SessionSpinlock);
329
330 if (sState.selectSync == sync)
331 {
332 //dprintf(DRIVER_NAME "deselect: dropping: %p %x\n", sState.selectSync, sState.selectEvent);
333 sState.selectEvent = (uint8_t)0;
334 sState.selectRef = (uint32_t)0;
335 sState.selectSync = NULL;
336 }
337 else
338 err = B_OK;
339
340 RTSpinlockRelease(g_DevExt.SessionSpinlock);
341 return err;
342}
343
344
345/**
346 * Driver write hook.
347 * @param cookie The session.
348 * @param position The offset.
349 * @param data Pointer to the data.
350 * @param numBytes Where to store the number of bytes written.
351 *
352 * @return Haiku status code.
353 */
354static status_t vgdrvHaikuWrite(void *cookie, off_t position, const void *data, size_t *numBytes)
355{
356 *numBytes = 0;
357 return B_OK;
358}
359
360
361/**
362 * Driver read hook.
363 * @param cookie The session.
364 * @param position The offset.
365 * @param data Pointer to the data.
366 * @param numBytes Where to store the number of bytes read.
367 *
368 * @return Haiku status code.
369 */
370static status_t vgdrvHaikuRead(void *cookie, off_t position, void *data, size_t *numBytes)
371{
372 PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)cookie;
373
374 if (*numBytes == 0)
375 return B_OK;
376
377 uint32_t u32CurSeq = ASMAtomicUoReadU32(&g_DevExt.u32MousePosChangedSeq);
378 if (pSession->u32MousePosChangedSeq != u32CurSeq)
379 {
380 pSession->u32MousePosChangedSeq = u32CurSeq;
381 *numBytes = 1;
382 return B_OK;
383 }
384
385 *numBytes = 0;
386 return B_OK;
387}
388
389
390
391status_t init_hardware()
392{
393 return get_module(MODULE_NAME, (module_info **)&g_VBoxGuest);
394}
395
396status_t init_driver()
397{
398 return B_OK;
399}
400
401device_hooks *find_device(const char *name)
402{
403 static device_hooks s_vgdrvHaikuDeviceHooks =
404 {
405 vgdrvHaikuOpen,
406 vgdrvHaikuClose,
407 vgdrvHaikuFree,
408 vgdrvHaikuIOCtl,
409 vgdrvHaikuRead,
410 vgdrvHaikuWrite,
411 vgdrvHaikuSelect,
412 vgdrvHaikuDeselect,
413 };
414 return &s_vgdrvHaikuDeviceHooks;
415}
416
417const char **publish_devices()
418{
419 static const char *s_papszDevices[] = { DEVICE_NAME, NULL };
420 return s_papszDevices;
421}
422
423void uninit_driver()
424{
425 put_module(MODULE_NAME);
426}
427
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