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 |