Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 52b7b1bb in mainline


Ignore:
Timestamp:
2010-04-01T14:08:55Z (12 years ago)
Author:
Lenka Trochtova <trochtova.lenka@…>
Branches:
lfn, master
Children:
57937dd
Parents:
a1769ee
Message:

device interfaces - parts of code

Location:
uspace
Files:
3 added
6 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/libc/include/ipc/dev_iface.h

    ra1769ee r52b7b1bb  
    3535
    3636typedef enum { 
    37         GENERIC_DEV_IFACE = DEV_IFACE_FIRST,
    38         DIRECTLY_ADDRESSABLE_DEV_IFACE,
     37        HW_RES_DEV_IFACE = DEV_IFACE_FIRST,     
    3938        // TODO add more interfaces
    4039        DEV_IFACE_MAX
     
    4544
    4645
     46// data types related to some interface - TODO move this to separate header files
    4747
    4848
     49// HW resource provider interface
    4950
     51typedef enum {
     52        GET_RESOURCE_LIST = 0,
     53        ENABLE_INTERRUPT       
     54} hw_res_funcs_t;
    5055
     56/** HW resource types. */
     57typedef enum {
     58        INTERRUPT,
     59        REGISTER
     60} hw_res_type_t;
     61
     62typedef enum {
     63        LITTLE_ENDIAN = 0,
     64        BIG_ENDIAN
     65} endianness_t;
     66
     67/** HW resource (e.g. interrupt, memory register, i/o register etc.). */
     68typedef struct hw_resource {
     69        hw_res_type_t type;
     70        union {
     71                struct {
     72                        void *address;
     73                        endianness_t endianness;                       
     74                        size_t size;                   
     75                } reg;
     76                struct {
     77                        int irq;                       
     78                } intr;         
     79        };     
     80} hw_resource_t;
     81
     82typedef struct {
     83        size_t count;
     84        hw_resource_t *resources;       
     85} hw_resource_list_t;
    5186
    5287#endif
  • uspace/lib/libdrv/Makefile

    ra1769ee r52b7b1bb  
    3535
    3636SOURCES = \
    37         generic/driver.c
     37        generic/driver.c \
     38        generic/dev_iface.c \
     39        generic/remote_res.h
    3840
    3941include ../Makefile.common
  • uspace/lib/libdrv/generic/dev_iface.c

    ra1769ee r52b7b1bb  
    3636 */
    3737 
    38  #include "driver.h"
     38#include "dev_iface.h"
     39#include "remote_res.h"
     40 
     41static iface_dipatch_table_t remote_ifaces = {
     42        .ifaces = {
     43                &remote_res_iface
     44        }
     45};
     46
     47remote_iface_t* get_remote_iface(dev_inferface_id_t id)
     48{
     49        assert(is_valid_iface_id(id));
     50       
     51        int idx = get_iface_index(id);
     52        return remote_ifaces.ifaces[idx];       
     53}
     54
     55remote_iface_func_ptr_t get_remote_method(remote_iface_t *rem_iface, ipcarg_t iface_method_idx)
     56{
     57        if (iface_method_idx >= rem_iface->method_count) {
     58                return NULL;
     59        }
     60        return rem_iface->methods[iface_method_idx];
     61}
    3962 
    4063 
  • uspace/lib/libdrv/generic/driver.c

    ra1769ee r52b7b1bb  
    3535/** @file
    3636 */
    37  
     37
    3838#include <assert.h>
    3939#include <ipc/services.h>
     
    6262        device_t *dev = (device_t *)malloc(sizeof(device_t));
    6363        if (NULL != dev) {
    64                 memset(dev, 0, sizeof(device_t));               
    65         }       
    66         return dev;     
    67 }
    68 
    69 static device_t * driver_get_device(link_t *devices, device_handle_t handle) 
    70 {       
     64                memset(dev, 0, sizeof(device_t));
     65        }
     66        return dev;
     67}
     68
     69static device_t * driver_get_device(link_t *devices, device_handle_t handle)
     70{
    7171        device_t *dev = NULL;
    7272        link_t *link = devices->next;
    73        
     73
    7474        while (link != devices) {
    7575                dev = list_get_instance(link, device_t, link);
     
    7878                }
    7979        }
    80        
     80
    8181        return NULL;
    8282}
    8383
    84 static void driver_add_device(ipc_callid_t iid, ipc_call_t *icall) 
     84static void driver_add_device(ipc_callid_t iid, ipc_call_t *icall)
    8585{
    8686        printf("%s: driver_add_device\n", driver->name);
    87        
     87
    8888        // result of the operation - device was added, device is not present etc.
    89         ipcarg_t ret = 0;       
    90         device_handle_t dev_handle =  IPC_GET_ARG1(*icall);     
     89        ipcarg_t ret = 0;
     90        device_handle_t dev_handle =  IPC_GET_ARG1(*icall);
    9191        device_t *dev = driver_create_device();
    9292        dev->handle = dev_handle;
     
    9696        }
    9797        printf("%s: new device with handle = %x was added.\n", driver->name, dev_handle);
    98        
     98
    9999        ipc_answer_1(iid, EOK, ret);
    100100}
     
    103103{
    104104        printf("%s: driver_connection_devman \n", driver->name);
    105        
     105
    106106        /* Accept connection */
    107107        ipc_answer_0(iid, EOK);
    108        
     108
    109109        bool cont = true;
    110110        while (cont) {
    111111                ipc_call_t call;
    112112                ipc_callid_t callid = async_get_call(&call);
    113                
     113
    114114                switch (IPC_GET_METHOD(call)) {
    115115                case IPC_M_PHONE_HUNGUP:
     
    123123                                ipc_answer_0(callid, ENOENT);
    124124                }
    125         }       
    126 }
    127 
    128 /** 
     125        }
     126}
     127
     128/**
    129129 * Generic client connection handler both for applications and drivers.
    130  *
    131  * @param driver true for driver client, false for other clients (applications, services etc.).
    132  */
    133 static void driver_connection_gen(ipc_callid_t iid, ipc_call_t *icall, bool driver) {
    134         /*
    135          * Answer the first IPC_M_CONNECT_ME_TO call and remember the handle of the device to which the client connected.
    136          */
    137         device_handle_t handle = IPC_GET_ARG1(*icall);
     130 *
     131 * @param driver true for driver client, false for other clients (applications, services etc.).
     132 */
     133static void driver_connection_gen(ipc_callid_t iid, ipc_call_t *icall, bool driver)
     134{
     135        // Answer the first IPC_M_CONNECT_ME_TO call and remember the handle of the device to which the client connected.
     136        device_handle_t handle = IPC_GET_ARG1(*icall);
    138137        device_t *dev = driver_get_device(&devices, handle);
    139        
     138
    140139        if (dev == NULL) {
    141140                ipc_answer_0(iid, ENOENT);
    142141                return;
    143142        }
     143
     144        // TODO open the device (introduce some callbacks for opening and closing devices registered by the driver)
    144145       
    145         // TODO introduce generic device interface for opening and closing devices
    146         // and call its open callback here to find out wheter the device can be used by the connecting client
    147                
    148 
    149146        ipc_answer_0(iid, EOK);
    150        
     147
    151148        while (1) {
    152149                ipc_callid_t callid;
    153150                ipc_call_t call;
    154        
     151
    155152                callid = async_get_call(&call);
    156153                ipcarg_t method = IPC_GET_METHOD(call);
    157154                switch  (method) {
    158155                case IPC_M_PHONE_HUNGUP:
    159                         // TODO close the device
     156               
     157                        // TODO close the device
     158                       
    160159                        ipc_answer_0(callid, EOK);
    161160                        return;
    162161                default:
    163                         if (DEV_IFACE_FIRST <= method && method < DEV_IFACE_MAX) {
    164                                 // TODO - try to find interface, if supported
    165                                 // otherwise return  ENOTSUP                           
    166                         } else {
     162
     163                        if (!is_valid_iface_id(method)) {
     164                                // this is not device's interface
    167165                                ipc_answer_0(callid, ENOTSUP);
     166                                break;
    168167                        }
     168
     169                        // calling one of the device's interfaces
     170                       
     171                        // get the device interface structure
     172                        void *iface = device_get_iface(dev, method);
     173                        if (NULL == iface) {
     174                                ipc_answer_0(callid, ENOTSUP);
     175                                break;
     176                        }
     177
     178                        // get the corresponding interface for remote request handling ("remote interface")
     179                        remote_iface_t* rem_iface = get_remote_iface(method);
     180                        assert(NULL != rem_iface);
     181
     182                        // get the method of the remote interface
     183                        ipcarg_t iface_method_idx = IPC_GET_ARG1(call);
     184                        remote_iface_func_ptr_t iface_method_ptr = get_remote_method(rem_iface, iface_method_idx);
     185                        if (NULL == iface_method_ptr) {
     186                                // the interface has not such method
     187                                ipc_answer_0(callid, ENOTSUP);
     188                                break;
     189                        }
     190                       
     191                        // call the remote interface's method, which will receive parameters from the remote client
     192                        // and it will pass it to the corresponding local interface method associated with the device
     193                        // by its driver
     194                        (*iface_method_ptr)(dev, iface, callid, &call);
    169195                        break;
    170196                }
     
    174200static void driver_connection_driver(ipc_callid_t iid, ipc_call_t *icall)
    175201{
    176         driver_connection_gen(iid, icall, true); 
     202        driver_connection_gen(iid, icall, true);
    177203}
    178204
    179205static void driver_connection_client(ipc_callid_t iid, ipc_call_t *icall)
    180206{
    181         driver_connection_gen(iid, icall, false); 
     207        driver_connection_gen(iid, icall, false);
    182208}
    183209
     
    199225                break;
    200226        case DRIVER_CLIENT:
    201                 // handle requests from client applications 
     227                // handle requests from client applications
    202228                driver_connection_client(iid, icall);
    203229                break;
    204230
    205231        default:
    206                 /* No such interface */ 
     232                /* No such interface */
    207233                ipc_answer_0(iid, ENOENT);
    208234        }
     
    212238{
    213239        printf("%s: child_device_register\n", driver->name);
    214        
     240
    215241        assert(NULL != child->name);
    216        
     242
    217243        if (EOK == devman_child_device_register(child->name, &child->match_ids, parent->handle, &child->handle)) {
    218244                return true;
     
    221247}
    222248
    223 int driver_main(driver_t *drv) 
     249int driver_main(driver_t *drv)
    224250{
    225251        // remember the driver structure - driver_ops will be called by generic handler for incoming connections
    226252        driver = drv;
    227        
     253
    228254        // register driver by device manager with generic handler for incoming connections
    229         devman_driver_register(driver->name, driver_connection);               
     255        devman_driver_register(driver->name, driver_connection);
    230256
    231257        async_manager();
    232258
    233259        // Never reached
    234         return 0;       
     260        return 0;
    235261}
    236262
  • uspace/lib/libdrv/include/driver.h

    ra1769ee r52b7b1bb  
    3939#include <ipc/devman.h>
    4040#include <ipc/dev_iface.h>
     41#include <assert.h>
    4142
    4243struct device;
     
    5051
    5152typedef struct {
    52         int method_count;
     53        size_t method_count;
    5354        remote_iface_func_ptr_t *methods;
    5455} remote_iface_t;
     
    6869}
    6970
     71remote_iface_t* get_remote_iface(dev_inferface_id_t id);
     72remote_iface_func_ptr_t get_remote_method(remote_iface_t *rem_iface, ipcarg_t iface_method_idx);
     73
     74
    7075// device
    7176
     77/** The device. */
    7278struct device {
     79        /** Globally unique device identifier (assigned to the device by the device manager). */
    7380        device_handle_t handle;
     81        /** The phone to the parent device driver.*/
    7482        ipcarg_t parent_phone;
     83        /** The device's name.*/
    7584        const char *name;
     85        /** The list of device ids for device-to-driver matching.*/
    7686        match_id_list_t match_ids;
     87        /** The device driver's data associated with this device.*/
    7788        void *driver_data;
     89        /** The table of interfaces exported by this device. */
    7890        void *interfaces[DEV_IFACE_COUNT];
    79 
    80         // TODO add more items
    81 
     91        /** Pointer to the previous and next device in the list of devices handled by the driver */
    8292        link_t link;
    8393};
     
    8696// driver
    8797
     98/** Generic device driver operations. */
    8899typedef struct driver_ops {
     100        /** Callback method for passing a new device to the device driver.*/
    89101        bool (*add_device)(device_t *dev);
    90102        // TODO add other generic driver operations
    91103} driver_ops_t;
    92104
     105/** The driver structure.*/
    93106typedef struct driver {
     107        /** The name of the device driver. */
    94108        const char *name;
     109        /** Generic device driver operations. */
    95110        driver_ops_t *driver_ops;
    96111} driver_t;
     
    102117int driver_main(driver_t *drv);
    103118
     119/** Create new device structure.
     120 *
     121 * @return the device structure.
     122 */
    104123static inline device_t * create_device()
    105124{
     
    112131}
    113132
     133/** Delete device structure.
     134 *
     135 * @param dev the device structure.
     136 */
    114137static inline void delete_device(device_t *dev)
    115138{
     
    129152}
    130153
     154static inline void * device_get_iface(device_t *dev, dev_inferface_id_t id)
     155{
     156        assert(is_valid_iface_id(id));
     157       
     158        int idx = get_iface_index(id);
     159        return dev->interfaces[idx];   
     160}
     161
    131162bool child_device_register(device_t *child, device_t *parent);
    132163
  • uspace/srv/drivers/root/root.c

    ra1769ee r52b7b1bb  
    5353
    5454static bool root_add_device(device_t *dev);
    55 static bool root_init();
    5655
    5756/** The root device driver's standard operations.
Note: See TracChangeset for help on using the changeset viewer.