Subversion Repositories HelenOS

Rev

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