2
* Copyright (c) 2007 Josef Cejka
3
* Copyright (c) 2009 Jiri Svoboda
4
* Copyright (c) 2010 Lenka Trochtova
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions
11
* - Redistributions of source code must retain the above copyright
12
* notice, this list of conditions and the following disclaimer.
13
* - Redistributions in binary form must reproduce the above copyright
14
* notice, this list of conditions and the following disclaimer in the
15
* documentation and/or other materials provided with the distribution.
16
* - The name of the author may not be used to endorse or promote products
17
* derived from this software without specific prior written permission.
19
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39
#include <ipc/services.h>
40
#include <ipc/devman.h>
43
#include <fibril_synch.h>
49
static int devman_phone_driver = -1;
50
static int devman_phone_client = -1;
52
static FIBRIL_MUTEX_INITIALIZE(devman_phone_mutex);
54
int devman_get_phone(devman_interface_t iface, unsigned int flags)
58
fibril_mutex_lock(&devman_phone_mutex);
59
if (devman_phone_driver >= 0) {
60
fibril_mutex_unlock(&devman_phone_mutex);
61
return devman_phone_driver;
64
if (flags & IPC_FLAG_BLOCKING)
65
devman_phone_driver = async_connect_me_to_blocking(
66
PHONE_NS, SERVICE_DEVMAN, DEVMAN_DRIVER, 0);
68
devman_phone_driver = async_connect_me_to(PHONE_NS,
69
SERVICE_DEVMAN, DEVMAN_DRIVER, 0);
71
fibril_mutex_unlock(&devman_phone_mutex);
72
return devman_phone_driver;
74
fibril_mutex_lock(&devman_phone_mutex);
75
if (devman_phone_client >= 0) {
76
fibril_mutex_unlock(&devman_phone_mutex);
77
return devman_phone_client;
80
if (flags & IPC_FLAG_BLOCKING) {
81
devman_phone_client = async_connect_me_to_blocking(
82
PHONE_NS, SERVICE_DEVMAN, DEVMAN_CLIENT, 0);
84
devman_phone_client = async_connect_me_to(PHONE_NS,
85
SERVICE_DEVMAN, DEVMAN_CLIENT, 0);
88
fibril_mutex_unlock(&devman_phone_mutex);
89
return devman_phone_client;
95
/** Register running driver with device manager. */
96
int devman_driver_register(const char *name, async_client_conn_t conn)
98
int phone = devman_get_phone(DEVMAN_DRIVER, IPC_FLAG_BLOCKING);
103
async_serialize_start();
106
aid_t req = async_send_2(phone, DEVMAN_DRIVER_REGISTER, 0, 0, &answer);
108
sysarg_t retval = async_data_write_start(phone, name, str_size(name));
110
async_wait_for(req, NULL);
111
async_serialize_end();
115
async_set_client_connection(conn);
117
async_connect_to_me(phone, 0, 0, 0, NULL);
118
async_wait_for(req, &retval);
120
async_serialize_end();
125
static int devman_send_match_id(int phone, match_id_t *match_id)
129
aid_t req = async_send_1(phone, DEVMAN_ADD_MATCH_ID, match_id->score,
131
int retval = async_data_write_start(phone, match_id->id,
132
str_size(match_id->id));
134
async_wait_for(req, NULL);
139
static int devman_send_match_ids(int phone, match_id_list_t *match_ids)
141
link_t *link = match_ids->ids.next;
142
match_id_t *match_id = NULL;
145
while (link != &match_ids->ids) {
146
match_id = list_get_instance(link, match_id_t, link);
147
ret = devman_send_match_id(phone, match_id);
158
/** Add function to a device.
160
* Request devman to add a new function to the specified device owned by
163
* @param name Name of the new function
164
* @param ftype Function type, fun_inner or fun_exposed
165
* @param match_ids Match IDs (should be empty for fun_exposed)
166
* @param devh Devman handle of the device
167
* @param funh Place to store handle of the new function
169
* @return EOK on success or negative error code.
171
int devman_add_function(const char *name, fun_type_t ftype,
172
match_id_list_t *match_ids, devman_handle_t devh, devman_handle_t *funh)
174
int phone = devman_get_phone(DEVMAN_DRIVER, IPC_FLAG_BLOCKING);
180
async_serialize_start();
182
int match_count = list_count(&match_ids->ids);
185
aid_t req = async_send_3(phone, DEVMAN_ADD_FUNCTION, (sysarg_t) ftype,
186
devh, match_count, &answer);
188
sysarg_t retval = async_data_write_start(phone, name, str_size(name));
190
async_wait_for(req, NULL);
191
async_serialize_end();
195
int match_ids_rc = devman_send_match_ids(phone, match_ids);
197
async_wait_for(req, &retval);
199
async_serialize_end();
201
/* Prefer the answer to DEVMAN_ADD_FUNCTION in case of errors. */
202
if ((match_ids_rc != EOK) && (retval == EOK)) {
203
retval = match_ids_rc;
207
fun_handle = (int) IPC_GET_ARG1(answer);
216
int devman_add_device_to_class(devman_handle_t devman_handle,
217
const char *class_name)
219
int phone = devman_get_phone(DEVMAN_DRIVER, IPC_FLAG_BLOCKING);
224
async_serialize_start();
226
aid_t req = async_send_1(phone, DEVMAN_ADD_DEVICE_TO_CLASS,
227
devman_handle, &answer);
229
sysarg_t retval = async_data_write_start(phone, class_name,
230
str_size(class_name));
232
async_wait_for(req, NULL);
233
async_serialize_end();
237
async_wait_for(req, &retval);
238
async_serialize_end();
243
void devman_hangup_phone(devman_interface_t iface)
247
if (devman_phone_driver >= 0) {
248
async_hangup(devman_phone_driver);
249
devman_phone_driver = -1;
253
if (devman_phone_client >= 0) {
254
async_hangup(devman_phone_client);
255
devman_phone_client = -1;
263
int devman_device_connect(devman_handle_t handle, unsigned int flags)
267
if (flags & IPC_FLAG_BLOCKING) {
268
phone = async_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAN,
269
DEVMAN_CONNECT_TO_DEVICE, handle);
271
phone = async_connect_me_to(PHONE_NS, SERVICE_DEVMAN,
272
DEVMAN_CONNECT_TO_DEVICE, handle);
278
int devman_parent_device_connect(devman_handle_t handle, unsigned int flags)
282
if (flags & IPC_FLAG_BLOCKING) {
283
phone = async_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAN,
284
DEVMAN_CONNECT_TO_PARENTS_DEVICE, handle);
286
phone = async_connect_me_to(PHONE_NS, SERVICE_DEVMAN,
287
DEVMAN_CONNECT_TO_PARENTS_DEVICE, handle);
293
int devman_device_get_handle(const char *pathname, devman_handle_t *handle,
296
int phone = devman_get_phone(DEVMAN_CLIENT, flags);
301
async_serialize_start();
304
aid_t req = async_send_2(phone, DEVMAN_DEVICE_GET_HANDLE, flags, 0,
307
sysarg_t retval = async_data_write_start(phone, pathname,
310
async_wait_for(req, NULL);
311
async_serialize_end();
315
async_wait_for(req, &retval);
317
async_serialize_end();
321
*handle = (devman_handle_t) -1;
326
*handle = (devman_handle_t) IPC_GET_ARG1(answer);
331
int devman_device_get_handle_by_class(const char *classname,
332
const char *devname, devman_handle_t *handle, unsigned int flags)
334
int phone = devman_get_phone(DEVMAN_CLIENT, flags);
339
async_serialize_start();
342
aid_t req = async_send_1(phone, DEVMAN_DEVICE_GET_HANDLE_BY_CLASS,
345
sysarg_t retval = async_data_write_start(phone, classname,
346
str_size(classname));
348
async_wait_for(req, NULL);
349
async_serialize_end();
352
retval = async_data_write_start(phone, devname,
355
async_wait_for(req, NULL);
356
async_serialize_end();
360
async_wait_for(req, &retval);
362
async_serialize_end();
366
*handle = (devman_handle_t) -1;
371
*handle = (devman_handle_t) IPC_GET_ARG1(answer);