VirtualBox

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

Last change on this file since 93115 was 93115, checked in by vboxsync, 2 years ago

scm --update-copyright-year

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

© 2023 Oracle
ContactPrivacy policyTerms of Use