Subversion Repositories HelenOS

Rev

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;