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; |