Rev 4570 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4570 | Rev 4591 | ||
---|---|---|---|
Line 44... | Line 44... | ||
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 | 48 | ||
49 | #define NAME "devmap" |
49 | #define NAME "devmap" |
- | 50 | #define NULL_DEVICES 256 |
|
50 | 51 | ||
51 | /** Representation of device driver. |
52 | /** Representation of device driver. |
52 | * |
53 | * |
53 | * Each driver is responsible for a set of devices. |
54 | * Each driver is responsible for a set of devices. |
54 | * |
55 | * |
Line 95... | Line 96... | ||
95 | 96 | ||
96 | static FIBRIL_MUTEX_INITIALIZE(devices_list_mutex); |
97 | static FIBRIL_MUTEX_INITIALIZE(devices_list_mutex); |
97 | static FIBRIL_CONDVAR_INITIALIZE(devices_list_cv); |
98 | static FIBRIL_CONDVAR_INITIALIZE(devices_list_cv); |
98 | static FIBRIL_MUTEX_INITIALIZE(drivers_list_mutex); |
99 | static FIBRIL_MUTEX_INITIALIZE(drivers_list_mutex); |
99 | static FIBRIL_MUTEX_INITIALIZE(create_handle_mutex); |
100 | static FIBRIL_MUTEX_INITIALIZE(create_handle_mutex); |
- | 101 | static FIBRIL_MUTEX_INITIALIZE(null_devices_mutex); |
|
100 | 102 | ||
101 | static dev_handle_t last_handle = 0; |
103 | static dev_handle_t last_handle = 0; |
- | 104 | static devmap_device_t *null_devices[NULL_DEVICES]; |
|
102 | 105 | ||
103 | static dev_handle_t devmap_create_handle(void) |
106 | static dev_handle_t devmap_create_handle(void) |
104 | { |
107 | { |
105 | /* TODO: allow reusing old handles after their unregistration |
108 | /* TODO: allow reusing old handles after their unregistration |
106 | * and implement some version of LRU algorithm, avoid overflow |
109 | * and implement some version of LRU algorithm, avoid overflow |
Line 616... | Line 619... | ||
616 | fibril_mutex_unlock(&devices_list_mutex); |
619 | fibril_mutex_unlock(&devices_list_mutex); |
617 | 620 | ||
618 | ipc_answer_1(iid, EOK, pos); |
621 | ipc_answer_1(iid, EOK, pos); |
619 | } |
622 | } |
620 | 623 | ||
621 | /** Initialize device mapper. |
- | |
622 | * |
- | |
623 | * |
- | |
624 | */ |
- | |
625 | static bool devmap_init(void) |
624 | static void devmap_null_create(ipc_callid_t iid, ipc_call_t *icall) |
626 | { |
625 | { |
- | 626 | fibril_mutex_lock(&null_devices_mutex); |
|
- | 627 | ||
- | 628 | unsigned int i; |
|
- | 629 | bool fnd = false; |
|
- | 630 | ||
- | 631 | for (i = 0; i < NULL_DEVICES; i++) { |
|
- | 632 | if (null_devices[i] == NULL) { |
|
- | 633 | fnd = true; |
|
- | 634 | break; |
|
- | 635 | } |
|
- | 636 | } |
|
- | 637 | ||
- | 638 | if (!fnd) { |
|
- | 639 | fibril_mutex_unlock(&null_devices_mutex); |
|
- | 640 | ipc_answer_0(iid, ENOMEM); |
|
- | 641 | return; |
|
- | 642 | } |
|
- | 643 | ||
627 | /* Create NULL device entry */ |
644 | /* Create NULL device entry */ |
628 | devmap_device_t *device = (devmap_device_t *) malloc(sizeof(devmap_device_t)); |
645 | devmap_device_t *device = (devmap_device_t *) malloc(sizeof(devmap_device_t)); |
629 | if (device == NULL) |
646 | if (device == NULL) { |
- | 647 | fibril_mutex_unlock(&null_devices_mutex); |
|
- | 648 | ipc_answer_0(iid, ENOMEM); |
|
630 | return false; |
649 | return; |
- | 650 | } |
|
631 | 651 | ||
- | 652 | char null[DEVMAP_NAME_MAXLEN]; |
|
- | 653 | snprintf(null, DEVMAP_NAME_MAXLEN, "null%u", i); |
|
- | 654 | ||
632 | device->name = str_dup("null"); |
655 | device->name = str_dup(null); |
633 | if (device->name == NULL) { |
656 | if (device->name == NULL) { |
- | 657 | fibril_mutex_unlock(&null_devices_mutex); |
|
634 | free(device); |
658 | free(device); |
- | 659 | ipc_answer_0(iid, ENOMEM); |
|
635 | return false; |
660 | return; |
636 | } |
661 | } |
637 | 662 | ||
638 | list_initialize(&(device->devices)); |
663 | list_initialize(&(device->devices)); |
639 | list_initialize(&(device->driver_devices)); |
664 | list_initialize(&(device->driver_devices)); |
640 | 665 | ||
Line 642... | Line 667... | ||
642 | 667 | ||
643 | /* Get unique device handle */ |
668 | /* Get unique device handle */ |
644 | device->handle = devmap_create_handle(); |
669 | device->handle = devmap_create_handle(); |
645 | device->driver = NULL; |
670 | device->driver = NULL; |
646 | 671 | ||
647 | /* Insert device into list of all devices */ |
672 | /* Insert device into list of all devices |
- | 673 | and into null devices array */ |
|
648 | list_append(&device->devices, &devices_list); |
674 | list_append(&device->devices, &devices_list); |
- | 675 | null_devices[i] = device; |
|
649 | 676 | ||
650 | fibril_mutex_unlock(&devices_list_mutex); |
677 | fibril_mutex_unlock(&devices_list_mutex); |
- | 678 | fibril_mutex_unlock(&null_devices_mutex); |
|
- | 679 | ||
- | 680 | ipc_answer_1(iid, EOK, (ipcarg_t) i); |
|
- | 681 | } |
|
- | 682 | ||
- | 683 | static void devmap_null_destroy(ipc_callid_t iid, ipc_call_t *icall) |
|
- | 684 | { |
|
- | 685 | fibril_mutex_lock(&null_devices_mutex); |
|
- | 686 | ||
- | 687 | ipcarg_t i = IPC_GET_ARG1(*icall); |
|
- | 688 | ||
- | 689 | if (null_devices[i] == NULL) { |
|
- | 690 | ipc_answer_0(iid, ENOENT); |
|
- | 691 | return; |
|
- | 692 | } |
|
- | 693 | ||
- | 694 | devmap_device_unregister_core(null_devices[i]); |
|
- | 695 | null_devices[i] = NULL; |
|
- | 696 | ||
- | 697 | fibril_mutex_unlock(&null_devices_mutex); |
|
- | 698 | ||
- | 699 | ipc_answer_0(iid, EOK); |
|
- | 700 | } |
|
- | 701 | ||
- | 702 | /** Initialize device mapper. |
|
- | 703 | * |
|
- | 704 | * |
|
- | 705 | */ |
|
- | 706 | static bool devmap_init(void) |
|
- | 707 | { |
|
- | 708 | fibril_mutex_lock(&null_devices_mutex); |
|
- | 709 | ||
- | 710 | unsigned int i; |
|
- | 711 | for (i = 0; i < NULL_DEVICES; i++) |
|
- | 712 | null_devices[i] = NULL; |
|
- | 713 | ||
- | 714 | fibril_mutex_unlock(&null_devices_mutex); |
|
651 | 715 | ||
652 | return true; |
716 | return true; |
653 | } |
717 | } |
654 | 718 | ||
655 | /** Handle connection with device driver. |
719 | /** Handle connection with device driver. |
Line 699... | Line 763... | ||
699 | if (!(callid & IPC_CALLID_NOTIFICATION)) |
763 | if (!(callid & IPC_CALLID_NOTIFICATION)) |
700 | ipc_answer_0(callid, ENOENT); |
764 | ipc_answer_0(callid, ENOENT); |
701 | } |
765 | } |
702 | } |
766 | } |
703 | 767 | ||
704 | if (NULL != driver) { |
768 | if (driver != NULL) { |
705 | /* |
769 | /* |
706 | * Unregister the device driver and all its devices. |
770 | * Unregister the device driver and all its devices. |
707 | */ |
771 | */ |
708 | devmap_driver_unregister(driver); |
772 | devmap_driver_unregister(driver); |
709 | driver = NULL; |
773 | driver = NULL; |
Line 731... | Line 795... | ||
731 | devmap_get_handle(callid, &call); |
795 | devmap_get_handle(callid, &call); |
732 | break; |
796 | break; |
733 | case DEVMAP_DEVICE_GET_NAME: |
797 | case DEVMAP_DEVICE_GET_NAME: |
734 | devmap_get_name(callid, &call); |
798 | devmap_get_name(callid, &call); |
735 | break; |
799 | break; |
- | 800 | case DEVMAP_DEVICE_NULL_CREATE: |
|
- | 801 | devmap_null_create(callid, &call); |
|
- | 802 | break; |
|
- | 803 | case DEVMAP_DEVICE_NULL_DESTROY: |
|
- | 804 | devmap_null_destroy(callid, &call); |
|
- | 805 | break; |
|
736 | case DEVMAP_DEVICE_GET_COUNT: |
806 | case DEVMAP_DEVICE_GET_COUNT: |
737 | devmap_get_count(callid, &call); |
807 | devmap_get_count(callid, &call); |
738 | break; |
808 | break; |
739 | case DEVMAP_DEVICE_GET_DEVICES: |
809 | case DEVMAP_DEVICE_GET_DEVICES: |
740 | devmap_get_devices(callid, &call); |
810 | devmap_get_devices(callid, &call); |
Line 781... | Line 851... | ||
781 | return -1; |
851 | return -1; |
782 | } |
852 | } |
783 | 853 | ||
784 | /* Set a handler of incomming connections */ |
854 | /* Set a handler of incomming connections */ |
785 | async_set_client_connection(devmap_connection); |
855 | async_set_client_connection(devmap_connection); |
786 | 856 | ||
787 | /* Register device mapper at naming service */ |
857 | /* Register device mapper at naming service */ |
788 | ipcarg_t phonead; |
858 | ipcarg_t phonead; |
789 | if (ipc_connect_to_me(PHONE_NS, SERVICE_DEVMAP, 0, 0, &phonead) != 0) |
859 | if (ipc_connect_to_me(PHONE_NS, SERVICE_DEVMAP, 0, 0, &phonead) != 0) |
790 | return -1; |
860 | return -1; |
791 | 861 |