Changes in uspace/lib/c/generic/devman.c [1a5b252:e72fb34] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/devman.c
r1a5b252 re72fb34 1 1 /* 2 2 * Copyright (c) 2007 Josef Cejka 3 * Copyright (c) 20 11Jiri Svoboda3 * Copyright (c) 2009 Jiri Svoboda 4 4 * Copyright (c) 2010 Lenka Trochtova 5 5 * All rights reserved. … … 35 35 */ 36 36 37 #include <adt/list.h>38 37 #include <str.h> 38 #include <stdio.h> 39 39 #include <ipc/services.h> 40 #include <ns.h>41 40 #include <ipc/devman.h> 42 41 #include <devman.h> 42 #include <async.h> 43 43 #include <fibril_synch.h> 44 #include <async.h>45 44 #include <errno.h> 46 45 #include <malloc.h> 47 46 #include <bool.h> 48 49 static FIBRIL_MUTEX_INITIALIZE(devman_driver_block_mutex); 50 static FIBRIL_MUTEX_INITIALIZE(devman_client_block_mutex); 51 52 static FIBRIL_MUTEX_INITIALIZE(devman_driver_mutex); 53 static FIBRIL_MUTEX_INITIALIZE(devman_client_mutex); 54 55 static async_sess_t *devman_driver_block_sess = NULL; 56 static async_sess_t *devman_client_block_sess = NULL; 57 58 static async_sess_t *devman_driver_sess = NULL; 59 static async_sess_t *devman_client_sess = NULL; 60 61 static void clone_session(fibril_mutex_t *mtx, async_sess_t *src, 62 async_sess_t **dst) 63 { 64 fibril_mutex_lock(mtx); 65 66 if ((*dst == NULL) && (src != NULL)) 67 *dst = src; 68 69 fibril_mutex_unlock(mtx); 70 } 71 72 /** Start an async exchange on the devman session (blocking). 73 * 74 * @param iface Device manager interface to choose 75 * 76 * @return New exchange. 77 * 78 */ 79 async_exch_t *devman_exchange_begin_blocking(devman_interface_t iface) 47 #include <adt/list.h> 48 49 static int devman_phone_driver = -1; 50 static int devman_phone_client = -1; 51 52 static FIBRIL_MUTEX_INITIALIZE(devman_phone_mutex); 53 54 int devman_get_phone(devman_interface_t iface, unsigned int flags) 80 55 { 81 56 switch (iface) { 82 57 case DEVMAN_DRIVER: 83 fibril_mutex_lock(&devman_driver_block_mutex); 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; 62 } 84 63 85 while (devman_driver_block_sess == NULL) { 86 clone_session(&devman_driver_mutex, devman_driver_sess, 87 &devman_driver_block_sess); 88 89 if (devman_driver_block_sess == NULL) 90 devman_driver_block_sess = 91 service_connect_blocking(EXCHANGE_PARALLEL, 92 SERVICE_DEVMAN, DEVMAN_DRIVER, 0); 93 } 64 if (flags & IPC_FLAG_BLOCKING) 65 devman_phone_driver = async_connect_me_to_blocking( 66 PHONE_NS, SERVICE_DEVMAN, DEVMAN_DRIVER, 0); 67 else 68 devman_phone_driver = async_connect_me_to(PHONE_NS, 69 SERVICE_DEVMAN, DEVMAN_DRIVER, 0); 94 70 95 fibril_mutex_unlock(&devman_driver_block_mutex); 71 fibril_mutex_unlock(&devman_phone_mutex); 72 return devman_phone_driver; 73 case DEVMAN_CLIENT: 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; 78 } 96 79 97 clone_session(&devman_driver_mutex, devman_driver_block_sess, 98 &devman_driver_sess); 80 if (flags & IPC_FLAG_BLOCKING) { 81 devman_phone_client = async_connect_me_to_blocking( 82 PHONE_NS, SERVICE_DEVMAN, DEVMAN_CLIENT, 0); 83 } else { 84 devman_phone_client = async_connect_me_to(PHONE_NS, 85 SERVICE_DEVMAN, DEVMAN_CLIENT, 0); 86 } 99 87 100 return async_exchange_begin(devman_driver_block_sess); 101 case DEVMAN_CLIENT: 102 fibril_mutex_lock(&devman_client_block_mutex); 103 104 while (devman_client_block_sess == NULL) { 105 clone_session(&devman_client_mutex, devman_client_sess, 106 &devman_client_block_sess); 107 108 if (devman_client_block_sess == NULL) 109 devman_client_block_sess = 110 service_connect_blocking(EXCHANGE_SERIALIZE, 111 SERVICE_DEVMAN, DEVMAN_CLIENT, 0); 112 } 113 114 fibril_mutex_unlock(&devman_client_block_mutex); 115 116 clone_session(&devman_client_mutex, devman_client_block_sess, 117 &devman_client_sess); 118 119 return async_exchange_begin(devman_client_block_sess); 88 fibril_mutex_unlock(&devman_phone_mutex); 89 return devman_phone_client; 120 90 default: 121 return NULL; 122 } 123 } 124 125 /** Start an async exchange on the devman session. 126 * 127 * @param iface Device manager interface to choose 128 * 129 * @return New exchange. 130 * 131 */ 132 async_exch_t *devman_exchange_begin(devman_interface_t iface) 91 return -1; 92 } 93 } 94 95 /** Register running driver with device manager. */ 96 int devman_driver_register(const char *name, async_client_conn_t conn) 97 { 98 int phone = devman_get_phone(DEVMAN_DRIVER, IPC_FLAG_BLOCKING); 99 100 if (phone < 0) 101 return phone; 102 103 async_serialize_start(); 104 105 ipc_call_t answer; 106 aid_t req = async_send_2(phone, DEVMAN_DRIVER_REGISTER, 0, 0, &answer); 107 108 sysarg_t retval = async_data_write_start(phone, name, str_size(name)); 109 if (retval != EOK) { 110 async_wait_for(req, NULL); 111 async_serialize_end(); 112 return -1; 113 } 114 115 async_set_client_connection(conn); 116 117 async_connect_to_me(phone, 0, 0, 0, NULL); 118 async_wait_for(req, &retval); 119 120 async_serialize_end(); 121 122 return retval; 123 } 124 125 static int devman_send_match_id(int phone, match_id_t *match_id) 126 { 127 ipc_call_t answer; 128 129 aid_t req = async_send_1(phone, DEVMAN_ADD_MATCH_ID, match_id->score, 130 &answer); 131 int retval = async_data_write_start(phone, match_id->id, 132 str_size(match_id->id)); 133 134 async_wait_for(req, NULL); 135 return retval; 136 } 137 138 139 static int devman_send_match_ids(int phone, match_id_list_t *match_ids) 140 { 141 link_t *link = match_ids->ids.next; 142 match_id_t *match_id = NULL; 143 int ret = EOK; 144 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); 148 if (ret != EOK) { 149 return ret; 150 } 151 152 link = link->next; 153 } 154 155 return ret; 156 } 157 158 /** Add function to a device. 159 * 160 * Request devman to add a new function to the specified device owned by 161 * this driver task. 162 * 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 168 * 169 * @return EOK on success or negative error code. 170 */ 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) 173 { 174 int phone = devman_get_phone(DEVMAN_DRIVER, IPC_FLAG_BLOCKING); 175 int fun_handle; 176 177 if (phone < 0) 178 return phone; 179 180 async_serialize_start(); 181 182 int match_count = list_count(&match_ids->ids); 183 ipc_call_t answer; 184 185 aid_t req = async_send_3(phone, DEVMAN_ADD_FUNCTION, (sysarg_t) ftype, 186 devh, match_count, &answer); 187 188 sysarg_t retval = async_data_write_start(phone, name, str_size(name)); 189 if (retval != EOK) { 190 async_wait_for(req, NULL); 191 async_serialize_end(); 192 return retval; 193 } 194 195 int match_ids_rc = devman_send_match_ids(phone, match_ids); 196 197 async_wait_for(req, &retval); 198 199 async_serialize_end(); 200 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; 204 } 205 206 if (retval == EOK) 207 fun_handle = (int) IPC_GET_ARG1(answer); 208 else 209 fun_handle = -1; 210 211 *funh = fun_handle; 212 213 return retval; 214 } 215 216 int devman_add_device_to_class(devman_handle_t devman_handle, 217 const char *class_name) 218 { 219 int phone = devman_get_phone(DEVMAN_DRIVER, IPC_FLAG_BLOCKING); 220 221 if (phone < 0) 222 return phone; 223 224 async_serialize_start(); 225 ipc_call_t answer; 226 aid_t req = async_send_1(phone, DEVMAN_ADD_DEVICE_TO_CLASS, 227 devman_handle, &answer); 228 229 sysarg_t retval = async_data_write_start(phone, class_name, 230 str_size(class_name)); 231 if (retval != EOK) { 232 async_wait_for(req, NULL); 233 async_serialize_end(); 234 return retval; 235 } 236 237 async_wait_for(req, &retval); 238 async_serialize_end(); 239 240 return retval; 241 } 242 243 void devman_hangup_phone(devman_interface_t iface) 133 244 { 134 245 switch (iface) { 135 246 case DEVMAN_DRIVER: 136 fibril_mutex_lock(&devman_driver_mutex); 137 138 if (devman_driver_sess == NULL) 139 devman_driver_sess = 140 service_connect(EXCHANGE_PARALLEL, SERVICE_DEVMAN, 141 DEVMAN_DRIVER, 0); 142 143 fibril_mutex_unlock(&devman_driver_mutex); 144 145 if (devman_driver_sess == NULL) 146 return NULL; 147 148 return async_exchange_begin(devman_driver_sess); 247 if (devman_phone_driver >= 0) { 248 async_hangup(devman_phone_driver); 249 devman_phone_driver = -1; 250 } 251 break; 149 252 case DEVMAN_CLIENT: 150 fibril_mutex_lock(&devman_client_mutex); 151 152 if (devman_client_sess == NULL) 153 devman_client_sess = 154 service_connect(EXCHANGE_SERIALIZE, SERVICE_DEVMAN, 155 DEVMAN_CLIENT, 0); 156 157 fibril_mutex_unlock(&devman_client_mutex); 158 159 if (devman_client_sess == NULL) 160 return NULL; 161 162 return async_exchange_begin(devman_client_sess); 253 if (devman_phone_client >= 0) { 254 async_hangup(devman_phone_client); 255 devman_phone_client = -1; 256 } 257 break; 163 258 default: 164 return NULL; 165 } 166 } 167 168 /** Finish an async exchange on the devman session. 169 * 170 * @param exch Exchange to be finished. 171 * 172 */ 173 void devman_exchange_end(async_exch_t *exch) 174 { 175 async_exchange_end(exch); 176 } 177 178 /** Register running driver with device manager. */ 179 int devman_driver_register(const char *name, async_client_conn_t conn) 180 { 181 async_exch_t *exch = devman_exchange_begin_blocking(DEVMAN_DRIVER); 182 183 ipc_call_t answer; 184 aid_t req = async_send_2(exch, DEVMAN_DRIVER_REGISTER, 0, 0, &answer); 185 sysarg_t retval = async_data_write_start(exch, name, str_size(name)); 186 187 devman_exchange_end(exch); 188 189 if (retval != EOK) { 190 async_wait_for(req, NULL); 191 return retval; 192 } 193 194 async_set_client_connection(conn); 195 196 exch = devman_exchange_begin(DEVMAN_DRIVER); 197 async_connect_to_me(exch, 0, 0, 0, conn, NULL); 198 devman_exchange_end(exch); 199 200 async_wait_for(req, &retval); 201 return retval; 202 } 203 204 /** Add function to a device. 205 * 206 * Request devman to add a new function to the specified device owned by 207 * this driver task. 208 * 209 * @param name Name of the new function 210 * @param ftype Function type, fun_inner or fun_exposed 211 * @param match_ids Match IDs (should be empty for fun_exposed) 212 * @param devh Devman handle of the device 213 * @param funh Place to store handle of the new function 214 * 215 * @return EOK on success or negative error code. 216 * 217 */ 218 int devman_add_function(const char *name, fun_type_t ftype, 219 match_id_list_t *match_ids, devman_handle_t devh, devman_handle_t *funh) 220 { 221 int match_count = list_count(&match_ids->ids); 222 async_exch_t *exch = devman_exchange_begin_blocking(DEVMAN_DRIVER); 223 224 ipc_call_t answer; 225 aid_t req = async_send_3(exch, DEVMAN_ADD_FUNCTION, (sysarg_t) ftype, 226 devh, match_count, &answer); 227 sysarg_t retval = async_data_write_start(exch, name, str_size(name)); 228 if (retval != EOK) { 229 devman_exchange_end(exch); 230 async_wait_for(req, NULL); 231 return retval; 232 } 233 234 match_id_t *match_id = NULL; 235 236 list_foreach(match_ids->ids, link) { 237 match_id = list_get_instance(link, match_id_t, link); 238 239 ipc_call_t answer2; 240 aid_t req2 = async_send_1(exch, DEVMAN_ADD_MATCH_ID, 241 match_id->score, &answer2); 242 retval = async_data_write_start(exch, match_id->id, 243 str_size(match_id->id)); 244 if (retval != EOK) { 245 devman_exchange_end(exch); 246 async_wait_for(req2, NULL); 247 async_wait_for(req, NULL); 248 return retval; 249 } 250 251 async_wait_for(req2, &retval); 252 if (retval != EOK) { 253 devman_exchange_end(exch); 254 async_wait_for(req, NULL); 255 return retval; 256 } 257 } 258 259 devman_exchange_end(exch); 260 261 async_wait_for(req, &retval); 262 if (retval == EOK) { 263 if (funh != NULL) 264 *funh = (int) IPC_GET_ARG1(answer); 259 break; 260 } 261 } 262 263 int devman_device_connect(devman_handle_t handle, unsigned int flags) 264 { 265 int phone; 266 267 if (flags & IPC_FLAG_BLOCKING) { 268 phone = async_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAN, 269 DEVMAN_CONNECT_TO_DEVICE, handle); 265 270 } else { 266 if (funh != NULL) 267 *funh = -1; 268 } 269 270 return retval; 271 } 272 273 int devman_add_device_to_category(devman_handle_t devman_handle, 274 const char *cat_name) 275 { 276 async_exch_t *exch = devman_exchange_begin_blocking(DEVMAN_DRIVER); 277 278 ipc_call_t answer; 279 aid_t req = async_send_1(exch, DEVMAN_ADD_DEVICE_TO_CATEGORY, 280 devman_handle, &answer); 281 sysarg_t retval = async_data_write_start(exch, cat_name, 282 str_size(cat_name)); 283 284 devman_exchange_end(exch); 285 286 if (retval != EOK) { 287 async_wait_for(req, NULL); 288 return retval; 289 } 290 291 async_wait_for(req, &retval); 292 return retval; 293 } 294 295 async_sess_t *devman_device_connect(exch_mgmt_t mgmt, devman_handle_t handle, 271 phone = async_connect_me_to(PHONE_NS, SERVICE_DEVMAN, 272 DEVMAN_CONNECT_TO_DEVICE, handle); 273 } 274 275 return phone; 276 } 277 278 int devman_parent_device_connect(devman_handle_t handle, unsigned int flags) 279 { 280 int phone; 281 282 if (flags & IPC_FLAG_BLOCKING) { 283 phone = async_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAN, 284 DEVMAN_CONNECT_TO_PARENTS_DEVICE, handle); 285 } else { 286 phone = async_connect_me_to(PHONE_NS, SERVICE_DEVMAN, 287 DEVMAN_CONNECT_TO_PARENTS_DEVICE, handle); 288 } 289 290 return phone; 291 } 292 293 int devman_device_get_handle(const char *pathname, devman_handle_t *handle, 296 294 unsigned int flags) 297 295 { 298 async_sess_t *sess; 299 300 if (flags & IPC_FLAG_BLOCKING) 301 sess = service_connect_blocking(mgmt, SERVICE_DEVMAN, 302 DEVMAN_CONNECT_TO_DEVICE, handle); 303 else 304 sess = service_connect(mgmt, SERVICE_DEVMAN, 305 DEVMAN_CONNECT_TO_DEVICE, handle); 306 307 return sess; 308 } 309 310 /** Remove function from device. 311 * 312 * Request devman to remove function owned by this driver task. 313 * @param funh Devman handle of the function 314 * 315 * @return EOK on success or negative error code. 316 */ 317 int devman_remove_function(devman_handle_t funh) 318 { 319 async_exch_t *exch; 320 sysarg_t retval; 321 322 exch = devman_exchange_begin_blocking(DEVMAN_DRIVER); 323 retval = async_req_1_0(exch, DEVMAN_REMOVE_FUNCTION, (sysarg_t) funh); 324 devman_exchange_end(exch); 325 326 return (int) retval; 327 } 328 329 int devman_drv_fun_online(devman_handle_t funh) 330 { 331 async_exch_t *exch = devman_exchange_begin(DEVMAN_DRIVER); 332 if (exch == NULL) 333 return ENOMEM; 334 335 sysarg_t retval = async_req_1_0(exch, DEVMAN_DRV_FUN_ONLINE, funh); 336 337 devman_exchange_end(exch); 338 return (int) retval; 339 } 340 341 int devman_drv_fun_offline(devman_handle_t funh) 342 { 343 async_exch_t *exch = devman_exchange_begin(DEVMAN_DRIVER); 344 if (exch == NULL) 345 return ENOMEM; 346 347 sysarg_t retval = async_req_1_0(exch, DEVMAN_DRV_FUN_OFFLINE, funh); 348 349 devman_exchange_end(exch); 350 return (int) retval; 351 } 352 353 async_sess_t *devman_parent_device_connect(exch_mgmt_t mgmt, 354 devman_handle_t handle, unsigned int flags) 355 { 356 async_sess_t *sess; 357 358 if (flags & IPC_FLAG_BLOCKING) 359 sess = service_connect_blocking(mgmt, SERVICE_DEVMAN, 360 DEVMAN_CONNECT_TO_PARENTS_DEVICE, handle); 361 else 362 sess = service_connect(mgmt, SERVICE_DEVMAN, 363 DEVMAN_CONNECT_TO_PARENTS_DEVICE, handle); 364 365 return sess; 366 } 367 368 int devman_fun_get_handle(const char *pathname, devman_handle_t *handle, 369 unsigned int flags) 370 { 371 async_exch_t *exch; 372 373 if (flags & IPC_FLAG_BLOCKING) 374 exch = devman_exchange_begin_blocking(DEVMAN_CLIENT); 375 else { 376 exch = devman_exchange_begin(DEVMAN_CLIENT); 377 if (exch == NULL) 378 return ENOMEM; 379 } 380 381 ipc_call_t answer; 382 aid_t req = async_send_2(exch, DEVMAN_DEVICE_GET_HANDLE, flags, 0, 296 int phone = devman_get_phone(DEVMAN_CLIENT, flags); 297 298 if (phone < 0) 299 return phone; 300 301 async_serialize_start(); 302 303 ipc_call_t answer; 304 aid_t req = async_send_2(phone, DEVMAN_DEVICE_GET_HANDLE, flags, 0, 383 305 &answer); 384 sysarg_t retval = async_data_write_start(exch, pathname, 306 307 sysarg_t retval = async_data_write_start(phone, pathname, 385 308 str_size(pathname)); 386 387 devman_exchange_end(exch);388 389 if (retval != EOK) {390 async_wait_for(req, NULL);391 return retval;392 }393 394 async_ wait_for(req, &retval);309 if (retval != EOK) { 310 async_wait_for(req, NULL); 311 async_serialize_end(); 312 return retval; 313 } 314 315 async_wait_for(req, &retval); 316 317 async_serialize_end(); 395 318 396 319 if (retval != EOK) { 397 320 if (handle != NULL) 398 321 *handle = (devman_handle_t) -1; 399 400 322 return retval; 401 323 } … … 407 329 } 408 330 409 static int devman_get_str_internal(sysarg_t method, sysarg_t arg1, char *buf, 410 size_t buf_size) 411 { 412 async_exch_t *exch; 413 ipc_call_t dreply; 414 size_t act_size; 415 sysarg_t dretval; 416 417 exch = devman_exchange_begin_blocking(LOC_PORT_CONSUMER); 418 419 ipc_call_t answer; 420 aid_t req = async_send_1(exch, method, arg1, &answer); 421 aid_t dreq = async_data_read(exch, buf, buf_size - 1, &dreply); 422 async_wait_for(dreq, &dretval); 423 424 devman_exchange_end(exch); 425 426 if (dretval != EOK) { 427 async_wait_for(req, NULL); 428 return dretval; 429 } 430 431 sysarg_t retval; 432 async_wait_for(req, &retval); 433 434 if (retval != EOK) 435 return retval; 436 437 act_size = IPC_GET_ARG2(dreply); 438 assert(act_size <= buf_size - 1); 439 buf[act_size] = '\0'; 440 441 return EOK; 442 } 443 444 int devman_fun_get_path(devman_handle_t handle, char *buf, size_t buf_size) 445 { 446 return devman_get_str_internal(DEVMAN_FUN_GET_PATH, handle, buf, 447 buf_size); 448 } 449 450 int devman_fun_get_name(devman_handle_t handle, char *buf, size_t buf_size) 451 { 452 return devman_get_str_internal(DEVMAN_FUN_GET_NAME, handle, buf, 453 buf_size); 454 } 455 456 int devman_fun_online(devman_handle_t funh) 457 { 458 async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT); 459 if (exch == NULL) 460 return ENOMEM; 461 462 sysarg_t retval = async_req_1_0(exch, DEVMAN_FUN_ONLINE, funh); 463 464 devman_exchange_end(exch); 465 return (int) retval; 466 } 467 468 int devman_fun_offline(devman_handle_t funh) 469 { 470 async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT); 471 if (exch == NULL) 472 return ENOMEM; 473 474 sysarg_t retval = async_req_1_0(exch, DEVMAN_FUN_OFFLINE, funh); 475 476 devman_exchange_end(exch); 477 return (int) retval; 478 } 479 480 static int devman_get_handles_once(sysarg_t method, sysarg_t arg1, 481 devman_handle_t *handle_buf, size_t buf_size, size_t *act_size) 482 { 483 async_exch_t *exch = devman_exchange_begin_blocking(DEVMAN_CLIENT); 484 485 ipc_call_t answer; 486 aid_t req = async_send_1(exch, method, arg1, &answer); 487 int rc = async_data_read_start(exch, handle_buf, buf_size); 488 489 devman_exchange_end(exch); 490 491 if (rc != EOK) { 492 async_wait_for(req, NULL); 493 return rc; 494 } 495 496 sysarg_t retval; 497 async_wait_for(req, &retval); 498 499 if (retval != EOK) { 500 return retval; 501 } 502 503 *act_size = IPC_GET_ARG1(answer); 504 return EOK; 505 } 506 507 /** Get list of handles. 508 * 509 * Returns an allocated array of handles. 510 * 511 * @param method IPC method 512 * @param arg1 IPC argument 1 513 * @param data Place to store pointer to array of handles 514 * @param count Place to store number of handles 515 * @return EOK on success or negative error code 516 */ 517 static int devman_get_handles_internal(sysarg_t method, sysarg_t arg1, 518 devman_handle_t **data, size_t *count) 519 { 520 devman_handle_t *handles; 521 size_t act_size; 522 size_t alloc_size; 523 int rc; 524 525 *data = NULL; 526 act_size = 0; /* silence warning */ 527 528 rc = devman_get_handles_once(method, arg1, NULL, 0, 529 &act_size); 530 if (rc != EOK) 531 return rc; 532 533 alloc_size = act_size; 534 handles = malloc(alloc_size); 535 if (handles == NULL) 536 return ENOMEM; 537 538 while (true) { 539 rc = devman_get_handles_once(method, arg1, handles, alloc_size, 540 &act_size); 541 if (rc != EOK) 542 return rc; 543 544 if (act_size <= alloc_size) 545 break; 546 547 alloc_size *= 2; 548 free(handles); 549 550 handles = malloc(alloc_size); 551 if (handles == NULL) 552 return ENOMEM; 553 } 554 555 *count = act_size / sizeof(devman_handle_t); 556 *data = handles; 557 return EOK; 558 } 559 560 int devman_fun_get_child(devman_handle_t funh, devman_handle_t *devh) 561 { 562 async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT); 563 if (exch == NULL) 564 return ENOMEM; 565 566 sysarg_t retval = async_req_1_1(exch, DEVMAN_FUN_GET_CHILD, 567 funh, devh); 568 569 devman_exchange_end(exch); 570 return (int) retval; 571 } 572 573 int devman_dev_get_functions(devman_handle_t devh, devman_handle_t **funcs, 574 size_t *count) 575 { 576 return devman_get_handles_internal(DEVMAN_DEV_GET_FUNCTIONS, 577 devh, funcs, count); 578 } 579 580 int devman_fun_sid_to_handle(service_id_t sid, devman_handle_t *handle) 581 { 582 async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT); 583 if (exch == NULL) 584 return ENOMEM; 585 586 sysarg_t retval = async_req_1_1(exch, DEVMAN_FUN_SID_TO_HANDLE, 587 sid, handle); 588 589 devman_exchange_end(exch); 590 return (int) retval; 591 } 331 int devman_device_get_handle_by_class(const char *classname, 332 const char *devname, devman_handle_t *handle, unsigned int flags) 333 { 334 int phone = devman_get_phone(DEVMAN_CLIENT, flags); 335 336 if (phone < 0) 337 return phone; 338 339 async_serialize_start(); 340 341 ipc_call_t answer; 342 aid_t req = async_send_1(phone, DEVMAN_DEVICE_GET_HANDLE_BY_CLASS, 343 flags, &answer); 344 345 sysarg_t retval = async_data_write_start(phone, classname, 346 str_size(classname)); 347 if (retval != EOK) { 348 async_wait_for(req, NULL); 349 async_serialize_end(); 350 return retval; 351 } 352 retval = async_data_write_start(phone, devname, 353 str_size(devname)); 354 if (retval != EOK) { 355 async_wait_for(req, NULL); 356 async_serialize_end(); 357 return retval; 358 } 359 360 async_wait_for(req, &retval); 361 362 async_serialize_end(); 363 364 if (retval != EOK) { 365 if (handle != NULL) 366 *handle = (devman_handle_t) -1; 367 return retval; 368 } 369 370 if (handle != NULL) 371 *handle = (devman_handle_t) IPC_GET_ARG1(answer); 372 373 return retval; 374 } 375 592 376 593 377 /** @}
Note:
See TracChangeset
for help on using the changeset viewer.