Subversion Repositories HelenOS

Rev

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