1/*
2 * Copyright 1999, Be Incorporated.
3 * Copyright 2007, Haiku.
4 * Distributed under the terms of the MIT License.
5 *
6 * Authors:
7 *		Be Incorporated
8 *		Eric Petit <eric.petit@lapsus.org>
9 */
10
11#include "string.h"
12#include "unistd.h"
13#include "sys/types.h"
14#include "sys/stat.h"
15#include "fcntl.h"
16#include <sys/ioctl.h>
17#include <SupportDefs.h>
18
19#include "GlobalData.h"
20
21
22/* Initialization code shared between primary and cloned accelerants */
23static
24status_t InitCommon(int fd)
25{
26	status_t ret;
27
28	/* Memorize the file descriptor */
29	gFd = fd;
30
31	/* Contact driver and get a pointer to the registers and shared data */
32	if ((ret = ioctl(gFd, VMWARE_GET_PRIVATE_DATA, &gSharedArea,
33			sizeof(area_id))) != B_OK) {
34		TRACE("VMWARE_GET_PRIVATE_DATA failed (%"B_PRIx32"\n", ret);
35		return ret;
36	}
37
38	/* Clone the shared area for our use */
39	if ((gSharedArea = clone_area("VMware shared", (void **)&gSi,
40			B_ANY_ADDRESS, B_READ_AREA|B_WRITE_AREA, gSharedArea)) < 0) {
41		TRACE("could not clone shared area (%"B_PRId32")\n", gSharedArea);
42		return gSharedArea;
43	}
44
45	return B_OK;
46}
47
48
49static void
50UninitCommon()
51{
52	delete_area(gSharedArea);
53}
54
55
56status_t
57INIT_ACCELERANT(int fd)
58{
59	status_t ret;
60
61	TRACE("INIT_ACCELERANT (%d)\n", fd);
62
63	gAccelerantIsClone = 0;
64
65	/* Common initialization for the primary accelerant and clones */
66	if ((ret = InitCommon(fd)) == B_OK) {
67		/* Init semaphores */
68		INIT_BEN(gSi->engineLock);
69		INIT_BEN(gSi->fifoLock);
70	}
71
72	TRACE("INIT_ACCELERANT: %"B_PRIx32"\n", ret);
73	return ret;
74}
75
76
77ssize_t
78ACCELERANT_CLONE_INFO_SIZE()
79{
80	return B_PATH_NAME_LENGTH;
81}
82
83
84void
85GET_ACCELERANT_CLONE_INFO(void *data)
86{
87	TRACE("GET_ACCELERANT_CLONE_INFO (%d)\n", gFd);
88
89	// TODO: I have no idea why this doesn't work: gFd is 0 here !?!?
90	//ioctl(gFd, VMWARE_GET_DEVICE_NAME, data, B_PATH_NAME_LENGTH);
91	strlcpy(data, "graphics/vmware", B_PATH_NAME_LENGTH);
92
93}
94
95
96status_t
97CLONE_ACCELERANT(void *data)
98{
99	int fd;
100	char path[B_PATH_NAME_LENGTH];
101	status_t ret;
102
103	// create full device name
104	strcpy(path, "/dev/");
105	strlcat(path, (const char *)data, sizeof(path));
106
107	TRACE("CLONE_ACCELERANT: %s\n", (const char *)path);
108
109	fd = open(path, B_READ_WRITE);
110	if (fd < 0)
111		return fd;
112
113	gAccelerantIsClone = 1;
114
115	/* Common initialization for the primary accelerant and clones */
116	if ((ret = InitCommon(fd)) == B_OK) {
117		/* Init semaphores */
118		INIT_BEN(gSi->engineLock);
119		INIT_BEN(gSi->fifoLock);
120	}
121
122	TRACE("CLONE_ACCELERANT: %"B_PRIx32"\n", ret);
123	return ret;
124}
125
126
127void
128UNINIT_ACCELERANT()
129{
130	UninitCommon();
131	if (gAccelerantIsClone)
132		close(gFd);
133	else if (gUpdateThread > B_OK) {
134		status_t exitValue;
135		gUpdateThreadDie = 1;
136		wait_for_thread(gUpdateThread, &exitValue);
137	}
138	ioctl(gFd, VMWARE_FIFO_STOP, NULL, 0);
139}
140
141