Rev 4524 | Rev 4570 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 4524 | Rev 4540 | ||
|---|---|---|---|
| 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> |
|
| 48 | 49 | ||
| 49 | #define NAME "devmap" |
50 | #define NAME "devmap" |
| 50 | 51 | ||
| 51 | /** Representation of device driver. |
52 | /** Representation of device driver. |
| 52 | * |
53 | * |
| Line 92... | Line 93... | ||
| 92 | 93 | ||
| 93 | LIST_INITIALIZE(devices_list); |
94 | LIST_INITIALIZE(devices_list); |
| 94 | LIST_INITIALIZE(drivers_list); |
95 | LIST_INITIALIZE(drivers_list); |
| 95 | LIST_INITIALIZE(pending_req); |
96 | LIST_INITIALIZE(pending_req); |
| 96 | 97 | ||
| - | 98 | static bool pending_new_dev = false; |
|
| - | 99 | static FIBRIL_CONDVAR_INITIALIZE(pending_cv); |
|
| - | 100 | ||
| 97 | /* Locking order: |
101 | /* Locking order: |
| 98 | * drivers_list_mutex |
102 | * drivers_list_mutex |
| 99 | * devices_list_mutex |
103 | * devices_list_mutex |
| 100 | * (devmap_driver_t *)->devices_mutex |
104 | * (devmap_driver_t *)->devices_mutex |
| 101 | * create_handle_mutex |
105 | * create_handle_mutex |
| Line 172... | Line 176... | ||
| 172 | 176 | ||
| 173 | return device; |
177 | return device; |
| 174 | } |
178 | } |
| 175 | 179 | ||
| 176 | /** |
180 | /** |
| 177 | * |
- | |
| 178 | * Unregister device and free it. It's assumed that driver's device list is |
181 | * Unregister device and free it. It's assumed that driver's device list is |
| 179 | * already locked. |
182 | * already locked. |
| 180 | * |
- | |
| 181 | */ |
183 | */ |
| 182 | static int devmap_device_unregister_core(devmap_device_t *device) |
184 | static int devmap_device_unregister_core(devmap_device_t *device) |
| 183 | { |
185 | { |
| 184 | list_remove(&(device->devices)); |
186 | list_remove(&(device->devices)); |
| 185 | list_remove(&(device->driver_devices)); |
187 | list_remove(&(device->driver_devices)); |
| Line 189... | Line 191... | ||
| 189 | 191 | ||
| 190 | return EOK; |
192 | return EOK; |
| 191 | } |
193 | } |
| 192 | 194 | ||
| 193 | /** |
195 | /** |
| 194 | * |
- | |
| 195 | * Read info about new driver and add it into linked list of registered |
196 | * Read info about new driver and add it into linked list of registered |
| 196 | * drivers. |
197 | * drivers. |
| 197 | * |
- | |
| 198 | */ |
198 | */ |
| 199 | static void devmap_driver_register(devmap_driver_t **odriver) |
199 | static void devmap_driver_register(devmap_driver_t **odriver) |
| 200 | { |
200 | { |
| 201 | *odriver = NULL; |
201 | *odriver = NULL; |
| 202 | 202 | ||
| Line 347... | Line 347... | ||
| 347 | 347 | ||
| 348 | /** Process pending lookup requests */ |
348 | /** Process pending lookup requests */ |
| 349 | static void process_pending_lookup(void) |
349 | static void process_pending_lookup(void) |
| 350 | { |
350 | { |
| 351 | link_t *cur; |
351 | link_t *cur; |
| 352 | 352 | ||
| 353 | loop: |
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: |
|
| 354 | for (cur = pending_req.next; cur != &pending_req; cur = cur->next) { |
358 | for (cur = pending_req.next; cur != &pending_req; cur = cur->next) { |
| 355 | pending_req_t *pr = list_get_instance(cur, pending_req_t, link); |
359 | pending_req_t *pr = list_get_instance(cur, pending_req_t, link); |
| 356 | 360 | ||
| 357 | const devmap_device_t *dev = devmap_device_find_name(pr->name); |
361 | const devmap_device_t *dev = devmap_device_find_name(pr->name); |
| 358 | if (!dev) |
362 | if (!dev) |
| Line 362... | Line 366... | ||
| 362 | 366 | ||
| 363 | free(pr->name); |
367 | free(pr->name); |
| 364 | list_remove(cur); |
368 | list_remove(cur); |
| 365 | free(pr); |
369 | free(pr); |
| 366 | 370 | ||
| 367 | goto loop; |
371 | goto rescan; |
| 368 | } |
372 | } |
| - | 373 | pending_new_dev = false; |
|
| - | 374 | fibril_mutex_unlock(&devices_list_mutex); |
|
| - | 375 | goto loop; |
|
| 369 | } |
376 | } |
| 370 | 377 | ||
| 371 | 378 | ||
| 372 | /** Register instance of device |
379 | /** Register instance of device |
| 373 | * |
380 | * |
| Line 443... | Line 450... | ||
| 443 | fibril_mutex_lock(&device->driver->devices_mutex); |
450 | fibril_mutex_lock(&device->driver->devices_mutex); |
| 444 | 451 | ||
| 445 | list_append(&device->driver_devices, &device->driver->devices); |
452 | list_append(&device->driver_devices, &device->driver->devices); |
| 446 | 453 | ||
| 447 | fibril_mutex_unlock(&device->driver->devices_mutex); |
454 | fibril_mutex_unlock(&device->driver->devices_mutex); |
| - | 455 | pending_new_dev = true; |
|
| - | 456 | fibril_condvar_signal(&pending_cv); |
|
| 448 | fibril_mutex_unlock(&devices_list_mutex); |
457 | fibril_mutex_unlock(&devices_list_mutex); |
| 449 | 458 | ||
| 450 | ipc_answer_1(iid, EOK, device->handle); |
459 | ipc_answer_1(iid, EOK, device->handle); |
| 451 | } |
460 | } |
| 452 | 461 | ||
| Line 528... | Line 537... | ||
| 528 | free(name); |
537 | free(name); |
| 529 | return; |
538 | return; |
| 530 | } |
539 | } |
| 531 | name[size] = '\0'; |
540 | name[size] = '\0'; |
| 532 | 541 | ||
| - | 542 | fibril_mutex_lock(&devices_list_mutex); |
|
| - | 543 | ||
| 533 | /* |
544 | /* |
| 534 | * Find device name in linked list of known devices. |
545 | * Find device name in linked list of known devices. |
| 535 | */ |
546 | */ |
| 536 | const devmap_device_t *dev = devmap_device_find_name(name); |
547 | const devmap_device_t *dev = devmap_device_find_name(name); |
| 537 | 548 | ||
| Line 541... | Line 552... | ||
| 541 | if (dev == NULL) { |
552 | if (dev == NULL) { |
| 542 | if (IPC_GET_ARG1(*icall) & IPC_FLAG_BLOCKING) { |
553 | if (IPC_GET_ARG1(*icall) & IPC_FLAG_BLOCKING) { |
| 543 | /* Blocking lookup, add to pending list */ |
554 | /* Blocking lookup, add to pending list */ |
| 544 | pending_req_t *pr = (pending_req_t *) malloc(sizeof(pending_req_t)); |
555 | pending_req_t *pr = (pending_req_t *) malloc(sizeof(pending_req_t)); |
| 545 | if (!pr) { |
556 | if (!pr) { |
| - | 557 | fibril_mutex_unlock(&devices_list_mutex); |
|
| 546 | ipc_answer_0(iid, ENOMEM); |
558 | ipc_answer_0(iid, ENOMEM); |
| 547 | free(name); |
559 | free(name); |
| 548 | return; |
560 | return; |
| 549 | } |
561 | } |
| 550 | 562 | ||
| 551 | pr->name = name; |
563 | pr->name = name; |
| 552 | pr->callid = iid; |
564 | pr->callid = iid; |
| 553 | list_append(&pr->link, &pending_req); |
565 | list_append(&pr->link, &pending_req); |
| - | 566 | fibril_mutex_unlock(&devices_list_mutex); |
|
| 554 | return; |
567 | return; |
| 555 | } |
568 | } |
| 556 | 569 | ||
| 557 | ipc_answer_0(iid, ENOENT); |
570 | ipc_answer_0(iid, ENOENT); |
| 558 | free(name); |
571 | free(name); |
| - | 572 | fibril_mutex_unlock(&devices_list_mutex); |
|
| 559 | return; |
573 | return; |
| 560 | } |
574 | } |
| - | 575 | fibril_mutex_unlock(&devices_list_mutex); |
|
| 561 | 576 | ||
| 562 | ipc_answer_1(iid, EOK, dev->handle); |
577 | ipc_answer_1(iid, EOK, dev->handle); |
| 563 | free(name); |
578 | free(name); |
| 564 | } |
579 | } |
| 565 | 580 | ||
| Line 657... | Line 672... | ||
| 657 | 672 | ||
| 658 | /** Initialize device mapper. |
673 | /** Initialize device mapper. |
| 659 | * |
674 | * |
| 660 | * |
675 | * |
| 661 | */ |
676 | */ |
| 662 | static bool devmap_init() |
677 | static bool devmap_init(void) |
| 663 | { |
678 | { |
| 664 | /* Create NULL device entry */ |
679 | /* Create NULL device entry */ |
| 665 | devmap_device_t *device = (devmap_device_t *) malloc(sizeof(devmap_device_t)); |
680 | devmap_device_t *device = (devmap_device_t *) malloc(sizeof(devmap_device_t)); |
| 666 | if (device == NULL) |
681 | if (device == NULL) |
| 667 | return false; |
682 | return false; |
| Line 816... | Line 831... | ||
| 816 | if (!devmap_init()) { |
831 | if (!devmap_init()) { |
| 817 | printf(NAME ": Error while initializing service\n"); |
832 | printf(NAME ": Error while initializing service\n"); |
| 818 | return -1; |
833 | return -1; |
| 819 | } |
834 | } |
| 820 | 835 | ||
| 821 | /* Set a handler of incomming connections and |
836 | /* Set a handler of incomming connections */ |
| 822 | pending operations */ |
- | |
| 823 | async_set_pending(process_pending_lookup); |
- | |
| 824 | async_set_client_connection(devmap_connection); |
837 | async_set_client_connection(devmap_connection); |
| - | 838 | ||
| - | 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); |
|
| 825 | 843 | ||
| 826 | /* Register device mapper at naming service */ |
844 | /* Register device mapper at naming service */ |
| 827 | ipcarg_t phonead; |
845 | ipcarg_t phonead; |
| 828 | if (ipc_connect_to_me(PHONE_NS, SERVICE_DEVMAP, 0, 0, &phonead) != 0) |
846 | if (ipc_connect_to_me(PHONE_NS, SERVICE_DEVMAP, 0, 0, &phonead) != 0) |
| 829 | return -1; |
847 | return -1; |