~martin-decky/helenos/rcu

« back to all changes in this revision

Viewing changes to uspace/srv/devmap/devmap.c

  • Committer: Martin Sucha
  • Date: 2011-07-08 17:01:01 UTC
  • mfrom: (1095 main-clone)
  • mto: This revision was merged to the branch mainline in revision 1123.
  • Revision ID: sucha14@st.fmph.uniba.sk-20110708170101-eosjw1koauuvmzkz
MergeĀ mainlineĀ changes

Show diffs side-by-side

added added

removed removed

Lines of Context:
36
36
 */
37
37
 
38
38
#include <ipc/services.h>
39
 
#include <ipc/ns.h>
 
39
#include <ns.h>
40
40
#include <async.h>
41
41
#include <stdio.h>
42
42
#include <errno.h>
56
56
 *
57
57
 */
58
58
typedef struct {
59
 
        /** Pointers to previous and next drivers in linked list */
 
59
        /** Link to drivers_list */
60
60
        link_t drivers;
61
 
        /** Pointer to the linked list of devices controlled by this driver */
62
 
        link_t devices;
63
 
        /** Phone asociated with this driver */
64
 
        sysarg_t phone;
 
61
        
 
62
        /** List of devices controlled by this driver */
 
63
        list_t devices;
 
64
        
 
65
        /** Session asociated with this driver */
 
66
        async_sess_t *sess;
 
67
        
65
68
        /** Device driver name */
66
69
        char *name;
 
70
        
67
71
        /** Fibril mutex for list of devices owned by this driver */
68
72
        fibril_mutex_t devices_mutex;
69
73
} devmap_driver_t;
72
76
 *
73
77
 */
74
78
typedef struct {
75
 
        /** Pointer to the previous and next device in the list of all namespaces */
 
79
        /** Link to namespaces_list */
76
80
        link_t namespaces;
 
81
        
77
82
        /** Unique namespace identifier */
78
83
        devmap_handle_t handle;
 
84
        
79
85
        /** Namespace name */
80
86
        char *name;
 
87
        
81
88
        /** Reference count */
82
89
        size_t refcnt;
83
90
} devmap_namespace_t;
86
93
 *
87
94
 */
88
95
typedef struct {
89
 
        /** Pointer to the previous and next device in the list of all devices */
 
96
        /** Link to global list of devices (devices_list) */
90
97
        link_t devices;
91
 
        /** Pointer to the previous and next device in the list of devices
92
 
            owned by one driver */
 
98
        /** Link to driver list of devices (devmap_driver_t.devices) */
93
99
        link_t driver_devices;
94
100
        /** Unique device identifier */
95
101
        devmap_handle_t handle;
217
223
/** Find namespace with given name. */
218
224
static devmap_namespace_t *devmap_namespace_find_name(const char *name)
219
225
{
220
 
        link_t *item;
221
 
        
222
226
        assert(fibril_mutex_is_locked(&devices_list_mutex));
223
227
        
224
 
        for (item = namespaces_list.next; item != &namespaces_list; item = item->next) {
 
228
        list_foreach(namespaces_list, item) {
225
229
                devmap_namespace_t *namespace =
226
230
                    list_get_instance(item, devmap_namespace_t, namespaces);
227
231
                if (str_cmp(namespace->name, name) == 0)
238
242
 */
239
243
static devmap_namespace_t *devmap_namespace_find_handle(devmap_handle_t handle)
240
244
{
241
 
        link_t *item;
242
 
        
243
245
        assert(fibril_mutex_is_locked(&devices_list_mutex));
244
246
        
245
 
        for (item = namespaces_list.next; item != &namespaces_list; item = item->next) {
 
247
        list_foreach(namespaces_list, item) {
246
248
                devmap_namespace_t *namespace =
247
249
                    list_get_instance(item, devmap_namespace_t, namespaces);
248
250
                if (namespace->handle == handle)
256
258
static devmap_device_t *devmap_device_find_name(const char *ns_name,
257
259
    const char *name)
258
260
{
259
 
        link_t *item;
260
 
        
261
261
        assert(fibril_mutex_is_locked(&devices_list_mutex));
262
262
        
263
 
        for (item = devices_list.next; item != &devices_list; item = item->next) {
 
263
        list_foreach(devices_list, item) {
264
264
                devmap_device_t *device =
265
265
                    list_get_instance(item, devmap_device_t, devices);
266
266
                if ((str_cmp(device->namespace->name, ns_name) == 0)
278
278
 */
279
279
static devmap_device_t *devmap_device_find_handle(devmap_handle_t handle)
280
280
{
281
 
        link_t *item;
282
 
        
283
281
        assert(fibril_mutex_is_locked(&devices_list_mutex));
284
282
        
285
 
        for (item = devices_list.next; item != &devices_list; item = item->next) {
 
283
        list_foreach(devices_list, item) {
286
284
                devmap_device_t *device =
287
285
                    list_get_instance(item, devmap_device_t, devices);
288
286
                if (device->handle == handle)
404
402
        /*
405
403
         * Create connection to the driver
406
404
         */
407
 
        ipc_call_t call;
408
 
        ipc_callid_t callid = async_get_call(&call);
409
 
        
410
 
        if (IPC_GET_IMETHOD(call) != IPC_M_CONNECT_TO_ME) {
 
405
        driver->sess = async_callback_receive(EXCHANGE_SERIALIZE);
 
406
        if (!driver->sess) {
411
407
                free(driver->name);
412
408
                free(driver);
413
 
                async_answer_0(callid, ENOTSUP);
414
409
                async_answer_0(iid, ENOTSUP);
415
410
                return NULL;
416
411
        }
417
412
        
418
 
        driver->phone = IPC_GET_ARG5(call);
419
 
        async_answer_0(callid, EOK);
420
 
        
421
413
        /*
422
414
         * Initialize mutex for list of devices
423
415
         * owned by this driver
461
453
        
462
454
        fibril_mutex_lock(&drivers_list_mutex);
463
455
        
464
 
        if (driver->phone != 0)
465
 
                async_hangup(driver->phone);
 
456
        if (driver->sess)
 
457
                async_hangup(driver->sess);
466
458
        
467
459
        /* Remove it from list of drivers */
468
460
        list_remove(&(driver->drivers));
471
463
        fibril_mutex_lock(&devices_list_mutex);
472
464
        fibril_mutex_lock(&driver->devices_mutex);
473
465
        
474
 
        while (!list_empty(&(driver->devices))) {
475
 
                devmap_device_t *device = list_get_instance(driver->devices.next,
476
 
                    devmap_device_t, driver_devices);
 
466
        while (!list_empty(&driver->devices)) {
 
467
                devmap_device_t *device = list_get_instance(
 
468
                    list_first(&driver->devices), devmap_device_t,
 
469
                    driver_devices);
477
470
                devmap_device_unregister_core(device);
478
471
        }
479
472
        
606
599
        devmap_handle_t handle = IPC_GET_ARG2(*call);
607
600
        devmap_device_t *dev = devmap_device_find_handle(handle);
608
601
        
609
 
        if ((dev == NULL) || (dev->driver == NULL) || (dev->driver->phone == 0)) {
 
602
        if ((dev == NULL) || (dev->driver == NULL) || (!dev->driver->sess)) {
610
603
                fibril_mutex_unlock(&devices_list_mutex);
611
604
                async_answer_0(callid, ENOENT);
612
605
                return;
613
606
        }
614
607
        
615
 
        if (dev->forward_interface == 0) {
616
 
                async_forward_fast(callid, dev->driver->phone,
617
 
                    dev->handle, 0, 0,
618
 
                    IPC_FF_NONE);
619
 
        } else {
620
 
                async_forward_fast(callid, dev->driver->phone,
621
 
                    dev->forward_interface, dev->handle, 0,
622
 
                    IPC_FF_NONE);
623
 
        }
 
608
        async_exch_t *exch = async_exchange_begin(dev->driver->sess);
 
609
        
 
610
        if (dev->forward_interface == 0)
 
611
                async_forward_fast(callid, exch, dev->handle, 0, 0, IPC_FF_NONE);
 
612
        else
 
613
                async_forward_fast(callid, exch, dev->forward_interface,
 
614
                    dev->handle, 0, IPC_FF_NONE);
 
615
        
 
616
        async_exchange_end(exch);
624
617
        
625
618
        fibril_mutex_unlock(&devices_list_mutex);
626
619
}
813
806
                return;
814
807
        }
815
808
        
816
 
        link_t *item;
817
809
        size_t pos = 0;
818
 
        for (item = namespaces_list.next; item != &namespaces_list;
819
 
            item = item->next) {
 
810
        list_foreach(namespaces_list, item) {
820
811
                devmap_namespace_t *namespace =
821
812
                    list_get_instance(item, devmap_namespace_t, namespaces);
822
813
                
879
870
                return;
880
871
        }
881
872
        
882
 
        link_t *item;
883
873
        size_t pos = 0;
884
 
        for (item = devices_list.next; item != &devices_list; item = item->next) {
 
874
        list_foreach(devices_list, item) {
885
875
                devmap_device_t *device =
886
876
                    list_get_instance(item, devmap_device_t, devices);
887
877
                
1028
1018
        if (driver == NULL)
1029
1019
                return;
1030
1020
        
1031
 
        bool cont = true;
1032
 
        while (cont) {
 
1021
        while (true) {
1033
1022
                ipc_call_t call;
1034
1023
                ipc_callid_t callid = async_get_call(&call);
1035
1024
                
 
1025
                if (!IPC_GET_IMETHOD(call))
 
1026
                        break;
 
1027
                
1036
1028
                switch (IPC_GET_IMETHOD(call)) {
1037
 
                case IPC_M_PHONE_HUNGUP:
1038
 
                        cont = false;
1039
 
                        continue;
1040
1029
                case DEVMAP_DRIVER_UNREGISTER:
1041
1030
                        if (NULL == driver)
1042
1031
                                async_answer_0(callid, ENOENT);
1079
1068
        /* Accept connection */
1080
1069
        async_answer_0(iid, EOK);
1081
1070
        
1082
 
        bool cont = true;
1083
 
        while (cont) {
 
1071
        while (true) {
1084
1072
                ipc_call_t call;
1085
1073
                ipc_callid_t callid = async_get_call(&call);
1086
1074
                
 
1075
                if (!IPC_GET_IMETHOD(call))
 
1076
                        break;
 
1077
                
1087
1078
                switch (IPC_GET_IMETHOD(call)) {
1088
 
                case IPC_M_PHONE_HUNGUP:
1089
 
                        cont = false;
1090
 
                        continue;
1091
1079
                case DEVMAP_DEVICE_GET_HANDLE:
1092
1080
                        devmap_device_get_handle(callid, &call);
1093
1081
                        break;
1124
1112
/** Function for handling connections to devmap
1125
1113
 *
1126
1114
 */
1127
 
static void devmap_connection(ipc_callid_t iid, ipc_call_t *icall)
 
1115
static void devmap_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
1128
1116
{
1129
1117
        /* Select interface */
1130
1118
        switch ((sysarg_t) (IPC_GET_ARG1(*icall))) {