Rev 4540 | Rev 4591 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 4540 | Rev 4570 | ||
|---|---|---|---|
| Line 43... | Line 43... | ||
| 43 | #include <bool.h> |
43 | #include <bool.h> |
| 44 | #include <fibril_sync.h> |
44 | #include <fibril_sync.h> |
| 45 | #include <stdlib.h> |
45 | #include <stdlib.h> |
| 46 | #include <string.h> |
46 | #include <string.h> |
| 47 | #include <ipc/devmap.h> |
47 | #include <ipc/devmap.h> |
| 48 | #include <assert.h> |
- | |
| 49 | 48 | ||
| 50 | #define NAME "devmap" |
49 | #define NAME "devmap" |
| 51 | 50 | ||
| 52 | /** Representation of device driver. |
51 | /** Representation of device driver. |
| 53 | * |
52 | * |
| Line 82... | Line 81... | ||
| 82 | char *name; |
81 | char *name; |
| 83 | /** Device driver handling this device */ |
82 | /** Device driver handling this device */ |
| 84 | devmap_driver_t *driver; |
83 | devmap_driver_t *driver; |
| 85 | } devmap_device_t; |
84 | } devmap_device_t; |
| 86 | 85 | ||
| 87 | /** Pending lookup structure. */ |
- | |
| 88 | typedef struct { |
- | |
| 89 | link_t link; |
- | |
| 90 | char *name; /**< Device name */ |
- | |
| 91 | ipc_callid_t callid; /**< Call ID waiting for the lookup */ |
- | |
| 92 | } pending_req_t; |
- | |
| 93 | - | ||
| 94 | LIST_INITIALIZE(devices_list); |
86 | LIST_INITIALIZE(devices_list); |
| 95 | LIST_INITIALIZE(drivers_list); |
87 | LIST_INITIALIZE(drivers_list); |
| 96 | LIST_INITIALIZE(pending_req); |
- | |
| 97 | - | ||
| 98 | static bool pending_new_dev = false; |
- | |
| 99 | static FIBRIL_CONDVAR_INITIALIZE(pending_cv); |
- | |
| 100 | 88 | ||
| 101 | /* Locking order: |
89 | /* Locking order: |
| 102 | * drivers_list_mutex |
90 | * drivers_list_mutex |
| 103 | * devices_list_mutex |
91 | * devices_list_mutex |
| 104 | * (devmap_driver_t *)->devices_mutex |
92 | * (devmap_driver_t *)->devices_mutex |
| 105 | * create_handle_mutex |
93 | * create_handle_mutex |
| 106 | **/ |
94 | **/ |
| 107 | 95 | ||
| 108 | static FIBRIL_MUTEX_INITIALIZE(devices_list_mutex); |
96 | static FIBRIL_MUTEX_INITIALIZE(devices_list_mutex); |
| - | 97 | static FIBRIL_CONDVAR_INITIALIZE(devices_list_cv); |
|
| 109 | static FIBRIL_MUTEX_INITIALIZE(drivers_list_mutex); |
98 | static FIBRIL_MUTEX_INITIALIZE(drivers_list_mutex); |
| 110 | static FIBRIL_MUTEX_INITIALIZE(create_handle_mutex); |
99 | static FIBRIL_MUTEX_INITIALIZE(create_handle_mutex); |
| 111 | 100 | ||
| 112 | static dev_handle_t last_handle = 0; |
101 | static dev_handle_t last_handle = 0; |
| 113 | 102 | ||
| Line 342... | Line 331... | ||
| 342 | free(driver); |
331 | free(driver); |
| 343 | 332 | ||
| 344 | return EOK; |
333 | return EOK; |
| 345 | } |
334 | } |
| 346 | 335 | ||
| 347 | - | ||
| 348 | /** Process pending lookup requests */ |
- | |
| 349 | static void process_pending_lookup(void) |
- | |
| 350 | { |
- | |
| 351 | link_t *cur; |
- | |
| 352 | - | ||
| 353 | loop: |
- | |
| 354 | fibril_mutex_lock(&devices_list_mutex); |
- | |
| 355 | while (!pending_new_dev) |
- | |
| 356 | fibril_condvar_wait(&pending_cv, &devices_list_mutex); |
- | |
| 357 | rescan: |
- | |
| 358 | for (cur = pending_req.next; cur != &pending_req; cur = cur->next) { |
- | |
| 359 | pending_req_t *pr = list_get_instance(cur, pending_req_t, link); |
- | |
| 360 | - | ||
| 361 | const devmap_device_t *dev = devmap_device_find_name(pr->name); |
- | |
| 362 | if (!dev) |
- | |
| 363 | continue; |
- | |
| 364 | - | ||
| 365 | ipc_answer_1(pr->callid, EOK, dev->handle); |
- | |
| 366 | - | ||
| 367 | free(pr->name); |
- | |
| 368 | list_remove(cur); |
- | |
| 369 | free(pr); |
- | |
| 370 | - | ||
| 371 | goto rescan; |
- | |
| 372 | } |
- | |
| 373 | pending_new_dev = false; |
- | |
| 374 | fibril_mutex_unlock(&devices_list_mutex); |
- | |
| 375 | goto loop; |
- | |
| 376 | } |
- | |
| 377 | - | ||
| 378 | - | ||
| 379 | /** Register instance of device |
336 | /** Register instance of device |
| 380 | * |
337 | * |
| 381 | */ |
338 | */ |
| 382 | static void devmap_device_register(ipc_callid_t iid, ipc_call_t *icall, |
339 | static void devmap_device_register(ipc_callid_t iid, ipc_call_t *icall, |
| 383 | devmap_driver_t *driver) |
340 | devmap_driver_t *driver) |
| Line 450... | Line 407... | ||
| 450 | fibril_mutex_lock(&device->driver->devices_mutex); |
407 | fibril_mutex_lock(&device->driver->devices_mutex); |
| 451 | 408 | ||
| 452 | list_append(&device->driver_devices, &device->driver->devices); |
409 | list_append(&device->driver_devices, &device->driver->devices); |
| 453 | 410 | ||
| 454 | fibril_mutex_unlock(&device->driver->devices_mutex); |
411 | fibril_mutex_unlock(&device->driver->devices_mutex); |
| 455 | pending_new_dev = true; |
- | |
| 456 | fibril_condvar_signal(&pending_cv); |
412 | fibril_condvar_broadcast(&devices_list_cv); |
| 457 | fibril_mutex_unlock(&devices_list_mutex); |
413 | fibril_mutex_unlock(&devices_list_mutex); |
| 458 | 414 | ||
| 459 | ipc_answer_1(iid, EOK, device->handle); |
415 | ipc_answer_1(iid, EOK, device->handle); |
| 460 | } |
416 | } |
| 461 | 417 | ||
| Line 538... | Line 494... | ||
| 538 | return; |
494 | return; |
| 539 | } |
495 | } |
| 540 | name[size] = '\0'; |
496 | name[size] = '\0'; |
| 541 | 497 | ||
| 542 | fibril_mutex_lock(&devices_list_mutex); |
498 | fibril_mutex_lock(&devices_list_mutex); |
| - | 499 | const devmap_device_t *dev; |
|
| - | 500 | recheck: |
|
| 543 | 501 | ||
| 544 | /* |
502 | /* |
| 545 | * Find device name in linked list of known devices. |
503 | * Find device name in the list of known devices. |
| 546 | */ |
504 | */ |
| 547 | const devmap_device_t *dev = devmap_device_find_name(name); |
505 | dev = devmap_device_find_name(name); |
| 548 | 506 | ||
| 549 | /* |
507 | /* |
| 550 | * Device was not found. |
508 | * Device was not found. |
| 551 | */ |
509 | */ |
| 552 | if (dev == NULL) { |
510 | if (dev == NULL) { |
| 553 | if (IPC_GET_ARG1(*icall) & IPC_FLAG_BLOCKING) { |
511 | if (IPC_GET_ARG1(*icall) & IPC_FLAG_BLOCKING) { |
| 554 | /* Blocking lookup, add to pending list */ |
512 | /* Blocking lookup */ |
| 555 | pending_req_t *pr = (pending_req_t *) malloc(sizeof(pending_req_t)); |
- | |
| 556 | if (!pr) { |
- | |
| 557 | fibril_mutex_unlock(&devices_list_mutex); |
513 | fibril_condvar_wait(&devices_list_cv, |
| 558 | ipc_answer_0(iid, ENOMEM); |
- | |
| 559 | free(name); |
- | |
| 560 | return; |
- | |
| 561 | } |
- | |
| 562 | - | ||
| 563 | pr->name = name; |
- | |
| 564 | pr->callid = iid; |
- | |
| 565 | list_append(&pr->link, &pending_req); |
- | |
| 566 | fibril_mutex_unlock(&devices_list_mutex); |
514 | &devices_list_mutex); |
| 567 | return; |
515 | goto recheck; |
| 568 | } |
516 | } |
| 569 | 517 | ||
| 570 | ipc_answer_0(iid, ENOENT); |
518 | ipc_answer_0(iid, ENOENT); |
| 571 | free(name); |
519 | free(name); |
| 572 | fibril_mutex_unlock(&devices_list_mutex); |
520 | fibril_mutex_unlock(&devices_list_mutex); |
| Line 834... | Line 782... | ||
| 834 | } |
782 | } |
| 835 | 783 | ||
| 836 | /* Set a handler of incomming connections */ |
784 | /* Set a handler of incomming connections */ |
| 837 | async_set_client_connection(devmap_connection); |
785 | async_set_client_connection(devmap_connection); |
| 838 | 786 | ||
| 839 | /* Create a fibril for handling pending device lookups */ |
- | |
| 840 | fid_t fid = fibril_create(process_pending_lookup, NULL); |
- | |
| 841 | assert(fid); |
- | |
| 842 | fibril_add_ready(fid); |
- | |
| 843 | - | ||
| 844 | /* Register device mapper at naming service */ |
787 | /* Register device mapper at naming service */ |
| 845 | ipcarg_t phonead; |
788 | ipcarg_t phonead; |
| 846 | if (ipc_connect_to_me(PHONE_NS, SERVICE_DEVMAP, 0, 0, &phonead) != 0) |
789 | if (ipc_connect_to_me(PHONE_NS, SERVICE_DEVMAP, 0, 0, &phonead) != 0) |
| 847 | return -1; |
790 | return -1; |
| 848 | 791 | ||