Changes in uspace/lib/drv/generic/driver.c [2a770a35:45059d6b] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/drv/generic/driver.c
r2a770a35 r45059d6b 47 47 #include <stdlib.h> 48 48 #include <str.h> 49 #include <str_error.h> 49 50 #include <ctype.h> 50 51 #include <errno.h> … … 138 139 find_interrupt_context_by_id(interrupt_context_list_t *list, int id) 139 140 { 141 interrupt_context_t *ctx; 142 140 143 fibril_mutex_lock(&list->mutex); 141 144 142 link_t *link = list->contexts.next; 143 interrupt_context_t *ctx; 144 145 while (link != &list->contexts) { 145 list_foreach(list->contexts, link) { 146 146 ctx = list_get_instance(link, interrupt_context_t, link); 147 147 if (ctx->id == id) { … … 149 149 return ctx; 150 150 } 151 link = link->next;152 151 } 153 152 … … 159 158 find_interrupt_context(interrupt_context_list_t *list, ddf_dev_t *dev, int irq) 160 159 { 160 interrupt_context_t *ctx; 161 161 162 fibril_mutex_lock(&list->mutex); 162 163 163 link_t *link = list->contexts.next; 164 interrupt_context_t *ctx; 165 166 while (link != &list->contexts) { 164 list_foreach(list->contexts, link) { 167 165 ctx = list_get_instance(link, interrupt_context_t, link); 168 166 if (ctx->irq == irq && ctx->dev == dev) { … … 170 168 return ctx; 171 169 } 172 link = link->next;173 170 } 174 171 … … 230 227 } 231 228 232 static ddf_fun_t *driver_get_function(li nk_t *functions, devman_handle_t handle)229 static ddf_fun_t *driver_get_function(list_t *functions, devman_handle_t handle) 233 230 { 234 231 ddf_fun_t *fun = NULL; 235 232 236 233 fibril_mutex_lock(&functions_mutex); 237 link_t *link = functions->next; 238 239 while (link != functions) { 234 235 list_foreach(*functions, link) { 240 236 fun = list_get_instance(link, ddf_fun_t, link); 241 237 if (fun->handle == handle) { … … 243 239 return fun; 244 240 } 245 246 link = link->next;247 241 } 248 242 … … 273 267 274 268 res = driver->driver_ops->add_device(dev); 275 if (res == EOK) { 276 printf("%s: new device with handle=%" PRIun " was added.\n", 277 driver->name, dev_handle); 278 } else { 279 printf("%s: failed to add a new device with handle = %" PRIun ".\n", 280 driver->name, dev_handle); 269 if (res != EOK) 281 270 delete_device(dev); 282 }283 271 284 272 async_answer_0(iid, res); … … 290 278 async_answer_0(iid, EOK); 291 279 292 bool cont = true; 293 while (cont) { 280 while (true) { 294 281 ipc_call_t call; 295 282 ipc_callid_t callid = async_get_call(&call); 296 283 284 if (!IPC_GET_IMETHOD(call)) 285 break; 286 297 287 switch (IPC_GET_IMETHOD(call)) { 298 case IPC_M_PHONE_HUNGUP:299 cont = false;300 continue;301 288 case DRIVER_ADD_DEVICE: 302 289 driver_add_device(callid, &call); … … 308 295 } 309 296 310 /** 311 * Generic client connection handler both for applications and drivers.312 * 313 * @param drv True for driver client, false for other clients314 * (applications, services etc.).297 /** Generic client connection handler both for applications and drivers. 298 * 299 * @param drv True for driver client, false for other clients 300 * (applications, services, etc.). 301 * 315 302 */ 316 303 static void driver_connection_gen(ipc_callid_t iid, ipc_call_t *icall, bool drv) … … 322 309 devman_handle_t handle = IPC_GET_ARG2(*icall); 323 310 ddf_fun_t *fun = driver_get_function(&functions, handle); 324 311 325 312 if (fun == NULL) { 326 313 printf("%s: driver_connection_gen error - no function with handle" … … 330 317 } 331 318 319 if (fun->conn_handler != NULL) { 320 /* Driver has a custom connection handler. */ 321 (*fun->conn_handler)(iid, icall, (void *)fun); 322 return; 323 } 332 324 333 325 /* … … 345 337 return; 346 338 347 while ( 1) {339 while (true) { 348 340 ipc_callid_t callid; 349 341 ipc_call_t call; 350 342 callid = async_get_call(&call); 351 343 sysarg_t method = IPC_GET_IMETHOD(call); 352 int iface_idx; 353 354 switch (method) { 355 case IPC_M_PHONE_HUNGUP: 344 345 if (!method) { 356 346 /* Close device function */ 357 347 if (fun->ops != NULL && fun->ops->close != NULL) … … 359 349 async_answer_0(callid, EOK); 360 350 return; 361 default: 362 /* convert ipc interface id to interface index */ 363 364 iface_idx = DEV_IFACE_IDX(method); 365 366 if (!is_valid_iface_idx(iface_idx)) { 367 remote_handler_t *default_handler = 368 function_get_default_handler(fun); 369 if (default_handler != NULL) { 370 (*default_handler)(fun, callid, &call); 371 break; 372 } 373 374 /* 375 * Function has no such interface and 376 * default handler is not provided. 377 */ 378 printf("%s: driver_connection_gen error - " 379 "invalid interface id %d.", 380 driver->name, iface_idx); 381 async_answer_0(callid, ENOTSUP); 382 break; 383 } 384 385 /* calling one of the function's interfaces */ 386 387 /* Get the interface ops structure. */ 388 void *ops = function_get_ops(fun, iface_idx); 389 if (ops == NULL) { 390 printf("%s: driver_connection_gen error - ", 391 driver->name); 392 printf("Function with handle %" PRIun " has no interface " 393 "with id %d.\n", handle, iface_idx); 394 async_answer_0(callid, ENOTSUP); 395 break; 351 } 352 353 /* Convert ipc interface id to interface index */ 354 355 int iface_idx = DEV_IFACE_IDX(method); 356 357 if (!is_valid_iface_idx(iface_idx)) { 358 remote_handler_t *default_handler = 359 function_get_default_handler(fun); 360 if (default_handler != NULL) { 361 (*default_handler)(fun, callid, &call); 362 continue; 396 363 } 397 364 398 365 /* 399 * Get the corresponding interface for remote request400 * handling ("remote interface").366 * Function has no such interface and 367 * default handler is not provided. 401 368 */ 402 remote_iface_t *rem_iface = get_remote_iface(iface_idx); 403 assert(rem_iface != NULL); 404 405 /* get the method of the remote interface */ 406 sysarg_t iface_method_idx = IPC_GET_ARG1(call); 407 remote_iface_func_ptr_t iface_method_ptr = 408 get_remote_method(rem_iface, iface_method_idx); 409 if (iface_method_ptr == NULL) { 410 // the interface has not such method 411 printf("%s: driver_connection_gen error - " 412 "invalid interface method.", driver->name); 413 async_answer_0(callid, ENOTSUP); 414 break; 415 } 416 417 /* 418 * Call the remote interface's method, which will 419 * receive parameters from the remote client and it will 420 * pass it to the corresponding local interface method 421 * associated with the function by its driver. 422 */ 423 (*iface_method_ptr)(fun, ops, callid, &call); 424 break; 369 printf("%s: driver_connection_gen error - " 370 "invalid interface id %d.", 371 driver->name, iface_idx); 372 async_answer_0(callid, ENOTSUP); 373 continue; 425 374 } 375 376 /* Calling one of the function's interfaces */ 377 378 /* Get the interface ops structure. */ 379 void *ops = function_get_ops(fun, iface_idx); 380 if (ops == NULL) { 381 printf("%s: driver_connection_gen error - ", driver->name); 382 printf("Function with handle %" PRIun " has no interface " 383 "with id %d.\n", handle, iface_idx); 384 async_answer_0(callid, ENOTSUP); 385 continue; 386 } 387 388 /* 389 * Get the corresponding interface for remote request 390 * handling ("remote interface"). 391 */ 392 remote_iface_t *rem_iface = get_remote_iface(iface_idx); 393 assert(rem_iface != NULL); 394 395 /* get the method of the remote interface */ 396 sysarg_t iface_method_idx = IPC_GET_ARG1(call); 397 remote_iface_func_ptr_t iface_method_ptr = 398 get_remote_method(rem_iface, iface_method_idx); 399 if (iface_method_ptr == NULL) { 400 /* The interface has not such method */ 401 printf("%s: driver_connection_gen error - " 402 "invalid interface method.", driver->name); 403 async_answer_0(callid, ENOTSUP); 404 continue; 405 } 406 407 /* 408 * Call the remote interface's method, which will 409 * receive parameters from the remote client and it will 410 * pass it to the corresponding local interface method 411 * associated with the function by its driver. 412 */ 413 (*iface_method_ptr)(fun, ops, callid, &call); 426 414 } 427 415 } … … 438 426 439 427 /** Function for handling connections to device driver. */ 440 static void driver_connection(ipc_callid_t iid, ipc_call_t *icall) 441 { 428 static void driver_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg) 429 { 430 sysarg_t conn_type; 431 432 if (iid == 0) { 433 /* Callback connection from devman */ 434 /* XXX Use separate handler for this type of connection */ 435 conn_type = DRIVER_DEVMAN; 436 } else { 437 conn_type = IPC_GET_ARG1(*icall); 438 } 439 442 440 /* Select interface */ 443 switch ( (sysarg_t) (IPC_GET_ARG1(*icall))) {441 switch (conn_type) { 444 442 case DRIVER_DEVMAN: 445 443 /* Handle request from device manager */ … … 594 592 int ddf_fun_bind(ddf_fun_t *fun) 595 593 { 594 assert(fun->bound == false); 596 595 assert(fun->name != NULL); 597 596 … … 610 609 } 611 610 611 /** Unbind a function node. 612 * 613 * Unbind the specified function from the system. This effectively makes 614 * the function invisible to the system. 615 * 616 * @param fun Function to bind 617 * @return EOK on success or negative error code 618 */ 619 int ddf_fun_unbind(ddf_fun_t *fun) 620 { 621 int res; 622 623 assert(fun->bound == true); 624 625 add_to_functions_list(fun); 626 res = devman_remove_function(fun->handle); 627 if (res != EOK) 628 return res; 629 630 remove_from_functions_list(fun); 631 632 fun->bound = false; 633 return EOK; 634 } 635 612 636 /** Add single match ID to inner function. 613 637 * … … 632 656 return ENOMEM; 633 657 634 match_id->id = match_id_str;658 match_id->id = str_dup(match_id_str); 635 659 match_id->score = 90; 636 660 … … 647 671 } 648 672 649 /** Add exposed function to c lass.673 /** Add exposed function to category. 650 674 * 651 675 * Must only be called when the function is bound. 652 676 */ 653 int ddf_fun_add_to_c lass(ddf_fun_t *fun, const char *class_name)677 int ddf_fun_add_to_category(ddf_fun_t *fun, const char *cat_name) 654 678 { 655 679 assert(fun->bound == true); 656 680 assert(fun->ftype == fun_exposed); 657 681 658 return devman_add_device_to_c lass(fun->handle, class_name);682 return devman_add_device_to_category(fun->handle, cat_name); 659 683 } 660 684 661 685 int ddf_driver_main(driver_t *drv) 662 686 { 687 int rc; 688 663 689 /* 664 690 * Remember the driver structure - driver_ops will be called by generic … … 674 700 675 701 /* 676 * Register driver by device manager with generic handler for incoming677 * connections.702 * Register driver with device manager using generic handler for 703 * incoming connections. 678 704 */ 679 devman_driver_register(driver->name, driver_connection); 680 705 rc = devman_driver_register(driver->name, driver_connection); 706 if (rc != EOK) { 707 printf("Error: Failed to register driver with device manager " 708 "(%s).\n", (rc == EEXISTS) ? "driver already started" : 709 str_error(rc)); 710 711 return 1; 712 } 713 714 /* Return success from the task since server has started. */ 715 rc = task_retval(0); 716 if (rc != EOK) 717 return 1; 718 681 719 async_manager(); 682 720
Note:
See TracChangeset
for help on using the changeset viewer.