1 /* VBOX driver interface - synchronous version - by D.C. van Moolenbroek */
3 #include <minix/drivers.h>
4 #include <minix/vboxtype.h>
5 #include <minix/vboxif.h>
6 #include <minix/vbox.h>
10 static endpoint_t vbox_endpt
= NONE
;
14 /* Initialize the library, by resolving the VBOX driver endpoint.
18 if ((r
= ds_retrieve_label_endpt("vbox", &vbox_endpt
)) != OK
) {
19 printf("libvbox: unable to obtain VBOX endpoint (%d)\n", r
);
27 vbox_conn_t
vbox_open(char *name
)
29 /* Open a VirtualBox HGCM connection.
36 if (vbox_endpt
== NONE
)
39 len
= strlen(name
) + 1;
40 grant
= cpf_grant_direct(vbox_endpt
, (vir_bytes
) name
, len
, CPF_READ
);
41 if (!GRANT_VALID(grant
))
44 memset(&m
, 0, sizeof(m
));
50 r
= sendrec(vbox_endpt
, &m
);
63 int vbox_close(vbox_conn_t conn
)
65 /* Close a VirtualBox HGCM connection.
70 if (vbox_endpt
== NONE
)
73 memset(&m
, 0, sizeof(m
));
74 m
.m_type
= VBOX_CLOSE
;
78 r
= sendrec(vbox_endpt
, &m
);
89 int vbox_call(vbox_conn_t conn
, u32_t function
, vbox_param_t
*param
, int count
,
92 /* Call a VirtualBox HGCM function. The caller must set up all buffer grants.
94 cp_grant_id_t grant
= GRANT_INVALID
;
98 if (vbox_endpt
== NONE
) {
99 vbox_put(param
, count
);
104 /* Check whether all parameters are initialized correctly. */
105 for (i
= 0; i
< count
; i
++) {
106 switch (param
[i
].type
) {
113 vbox_put(param
, count
);
120 grant
= cpf_grant_direct(vbox_endpt
, (vir_bytes
) param
,
121 sizeof(param
[0]) * count
, CPF_READ
| CPF_WRITE
);
122 if (!GRANT_VALID(grant
)) {
123 vbox_put(param
, count
);
129 memset(&m
, 0, sizeof(m
));
130 m
.m_type
= VBOX_CALL
;
132 m
.VBOX_GRANT
= grant
;
133 m
.VBOX_COUNT
= count
;
135 m
.VBOX_FUNCTION
= function
;
137 r
= sendrec(vbox_endpt
, &m
);
139 if (GRANT_VALID(grant
))
142 vbox_put(param
, count
);
153 return m
.VBOX_RESULT
;
156 void vbox_set_u32(vbox_param_t
*param
, u32_t value
)
158 /* Set the given parameter to a 32-bit value.
161 param
->type
= VBOX_TYPE_U32
;
165 void vbox_set_u64(vbox_param_t
*param
, u64_t value
)
167 /* Set the given parameter to a 32-bit value.
170 param
->type
= VBOX_TYPE_U64
;
174 void vbox_set_ptr(vbox_param_t
*param
, void *ptr
, size_t size
,
177 /* Set the given parameter to a grant for the given local pointer.
179 cp_grant_id_t grant
= GRANT_INVALID
;
183 if (dir
& VBOX_DIR_IN
) flags
|= CPF_WRITE
;
184 if (dir
& VBOX_DIR_OUT
) flags
|= CPF_READ
;
187 grant
= cpf_grant_direct(vbox_endpt
, (vir_bytes
) ptr
, size
, flags
);
188 if (!GRANT_VALID(grant
)) {
189 param
->type
= VBOX_TYPE_INVALID
;
195 param
->type
= VBOX_TYPE_PTR
;
196 param
->ptr
.grant
= grant
;
198 param
->ptr
.size
= size
;
199 param
->ptr
.dir
= dir
;
202 void vbox_set_grant(vbox_param_t
*param
, endpoint_t endpt
, cp_grant_id_t grant
,
203 size_t off
, size_t size
, unsigned int dir
)
205 /* Set the given parameter to an indirect grant for the given grant.
207 cp_grant_id_t indir_grant
;
209 /* Unfortunately, the current implementation of indirect grants does not
210 * support making smaller subgrants out of larger original grants. Therefore,
211 * we are forced to grant more access than we would like.
213 indir_grant
= cpf_grant_indirect(vbox_endpt
, endpt
, grant
);
214 if (!GRANT_VALID(indir_grant
)) {
215 param
->type
= VBOX_TYPE_INVALID
;
220 param
->type
= VBOX_TYPE_PTR
;
221 param
->ptr
.grant
= indir_grant
;
222 param
->ptr
.off
= off
;
223 param
->ptr
.size
= size
;
224 param
->ptr
.dir
= dir
;
227 void vbox_put(vbox_param_t
*param
, int count
)
229 /* Free all resources used for the given parameters.
233 if (param
->type
== VBOX_TYPE_PTR
&& GRANT_VALID(param
->ptr
.grant
))
234 cpf_revoke(param
->ptr
.grant
);
240 u32_t
vbox_get_u32(vbox_param_t
*param
)
242 /* Retrieve the 32-bit value from the given parameter.
245 assert(param
->type
== VBOX_TYPE_U32
);
249 u64_t
vbox_get_u64(vbox_param_t
*param
)
251 /* Retrieve the 64-bit value from the given parameter.
254 assert(param
->type
== VBOX_TYPE_U64
);