Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/drv/include/driver.h

    r22027b6e r96b02eb9  
    4141#include <ipc/devman.h>
    4242#include <ipc/dev_iface.h>
     43#include <device/hw_res.h>
     44#include <device/char.h>
    4345#include <assert.h>
    4446#include <ddi.h>
     
    4749#include <malloc.h>
    4850
    49 #include "dev_iface.h"
    50 
    5151struct device;
    5252typedef struct device device_t;
    5353
     54/* device interface */
     55
    5456/*
    55  * Device class
    56  */
    57 
    58 /** Devices operations */
     57 * First two parameters: device and interface structure registered by the
     58 * devices driver.
     59 */
     60typedef void remote_iface_func_t(device_t *, void *, ipc_callid_t,
     61    ipc_call_t *);
     62typedef remote_iface_func_t *remote_iface_func_ptr_t;
     63typedef void remote_handler_t(device_t *, ipc_callid_t, ipc_call_t *);
     64
     65typedef struct {
     66        size_t method_count;
     67        remote_iface_func_ptr_t *methods;
     68} remote_iface_t;
     69
     70typedef struct {
     71        remote_iface_t *ifaces[DEV_IFACE_COUNT];
     72} iface_dipatch_table_t;
     73
     74
     75static inline bool is_valid_iface_idx(int idx)
     76{
     77        return 0 <= idx && idx < DEV_IFACE_MAX;
     78}
     79
     80remote_iface_t *get_remote_iface(int);
     81remote_iface_func_ptr_t get_remote_method(remote_iface_t *, sysarg_t);
     82
     83
     84/* device class */
     85
     86/** Devices operations. */
    5987typedef struct device_ops {
    6088        /**
     
    82110
    83111
    84 /*
    85  * Device
    86  */
    87 
    88 /** Device structure */
     112/* device */
     113
     114/** The device. */
    89115struct device {
    90116        /**
     
    95121       
    96122        /**
    97          * Phone to the parent device driver (if it is different from this
    98          * driver)
     123         * The phone to the parent device driver (if it is different from this
     124         * driver).
    99125         */
    100126        int parent_phone;
    101127       
    102         /** Parent device if handled by this driver, NULL otherwise */
     128        /** Parent device if handled by this driver, NULL otherwise. */
    103129        device_t *parent;
    104         /** Device name */
     130        /** The device's name. */
    105131        const char *name;
    106         /** List of device ids for device-to-driver matching */
     132        /** The list of device ids for device-to-driver matching. */
    107133        match_id_list_t match_ids;
    108         /** Driver-specific data associated with this device */
     134        /** The device driver's data associated with this device. */
    109135        void *driver_data;
    110         /** The implementation of operations provided by this device */
     136        /** The implementation of operations provided by this device. */
    111137        device_ops_t *ops;
    112138       
    113         /** Link in the list of devices handled by the driver */
     139        /**
     140         * Pointer to the previous and next device in the list of devices
     141         * handled by the driver.
     142         */
    114143        link_t link;
    115144};
    116145
    117 /*
    118  * Driver
    119  */
    120 
    121 /** Generic device driver operations */
     146
     147/* driver */
     148
     149/** Generic device driver operations. */
    122150typedef struct driver_ops {
    123         /** Callback method for passing a new device to the device driver */
     151        /** Callback method for passing a new device to the device driver.*/
    124152        int (*add_device)(device_t *dev);
    125         /* TODO: add other generic driver operations */
     153        /* TODO add other generic driver operations */
    126154} driver_ops_t;
    127155
    128 /** Driver structure */
     156/** The driver structure.*/
    129157typedef struct driver {
    130         /** Name of the device driver */
     158        /** The name of the device driver. */
    131159        const char *name;
    132         /** Generic device driver operations */
     160        /** Generic device driver operations. */
    133161        driver_ops_t *driver_ops;
    134162} driver_t;
     
    140168 * @return              The device structure.
    141169 */
    142 extern device_t *create_device(void);
    143 extern void delete_device(device_t *);
    144 extern void *device_get_ops(device_t *, dev_inferface_idx_t);
    145 
    146 extern int child_device_register(device_t *, device_t *);
    147 extern int child_device_register_wrapper(device_t *, const char *, const char *,
    148     int);
    149 
    150 /*
    151  * Interrupts
    152  */
     170static inline device_t *create_device(void)
     171{
     172        device_t *dev = malloc(sizeof(device_t));
     173        if (NULL != dev) {
     174                memset(dev, 0, sizeof(device_t));
     175                init_match_ids(&dev->match_ids);
     176        }       
     177        return dev;
     178}
     179
     180/** Delete device structure.
     181 *
     182 * @param dev           The device structure.
     183 */
     184static inline void delete_device(device_t *dev)
     185{
     186        clean_match_ids(&dev->match_ids);
     187        if (NULL != dev->name)
     188                free(dev->name);
     189        free(dev);
     190}
     191
     192static inline void *device_get_iface(device_t *dev, dev_inferface_idx_t idx)
     193{
     194        assert(is_valid_iface_idx(idx));
     195        if (NULL == dev->ops)
     196                return NULL;
     197        return dev->ops->interfaces[idx];
     198}
     199
     200int child_device_register(device_t *, device_t *);
     201int child_device_register_wrapper(device_t *, const char *, const char *, int);
     202
     203
     204/* interrupts */
    153205
    154206typedef void interrupt_handler_t(device_t *, ipc_callid_t, ipc_call_t *);
     
    168220} interrupt_context_list_t;
    169221
    170 extern interrupt_context_t *create_interrupt_context(void);
    171 extern void delete_interrupt_context(interrupt_context_t *);
    172 extern void init_interrupt_context_list(interrupt_context_list_t *);
    173 extern void add_interrupt_context(interrupt_context_list_t *,
    174     interrupt_context_t *);
    175 extern void remove_interrupt_context(interrupt_context_list_t *,
    176     interrupt_context_t *);
    177 extern interrupt_context_t *find_interrupt_context_by_id(
    178     interrupt_context_list_t *, int);
    179 extern interrupt_context_t *find_interrupt_context(
    180     interrupt_context_list_t *, device_t *, int);
    181 
    182 extern int register_interrupt_handler(device_t *, int, interrupt_handler_t *,
     222static inline interrupt_context_t *create_interrupt_context(void)
     223{
     224        interrupt_context_t *ctx;
     225       
     226        ctx = (interrupt_context_t *) malloc(sizeof(interrupt_context_t));
     227        if (NULL != ctx)
     228                memset(ctx, 0, sizeof(interrupt_context_t));
     229       
     230        return ctx;
     231}
     232
     233static inline void delete_interrupt_context(interrupt_context_t *ctx)
     234{
     235        if (NULL != ctx)
     236                free(ctx);
     237}
     238
     239static inline void init_interrupt_context_list(interrupt_context_list_t *list)
     240{
     241        memset(list, 0, sizeof(interrupt_context_list_t));
     242        fibril_mutex_initialize(&list->mutex);
     243        list_initialize(&list->contexts);
     244}
     245
     246static inline void
     247add_interrupt_context(interrupt_context_list_t *list, interrupt_context_t *ctx)
     248{
     249        fibril_mutex_lock(&list->mutex);
     250        ctx->id = list->curr_id++;
     251        list_append(&ctx->link, &list->contexts);
     252        fibril_mutex_unlock(&list->mutex);
     253}
     254
     255static inline void
     256remove_interrupt_context(interrupt_context_list_t *list,
     257    interrupt_context_t *ctx)
     258{
     259        fibril_mutex_lock(&list->mutex);
     260        list_remove(&ctx->link);
     261        fibril_mutex_unlock(&list->mutex);
     262}
     263
     264static inline interrupt_context_t *
     265find_interrupt_context_by_id(interrupt_context_list_t *list, int id)
     266{
     267        fibril_mutex_lock(&list->mutex);
     268       
     269        link_t *link = list->contexts.next;
     270        interrupt_context_t *ctx;
     271       
     272        while (link != &list->contexts) {
     273                ctx = list_get_instance(link, interrupt_context_t, link);
     274                if (id == ctx->id) {
     275                        fibril_mutex_unlock(&list->mutex);
     276                        return ctx;
     277                }
     278                link = link->next;
     279        }
     280       
     281        fibril_mutex_unlock(&list->mutex);
     282        return NULL;
     283}
     284
     285static inline interrupt_context_t *
     286find_interrupt_context(interrupt_context_list_t *list, device_t *dev, int irq)
     287{
     288        fibril_mutex_lock(&list->mutex);
     289       
     290        link_t *link = list->contexts.next;
     291        interrupt_context_t *ctx;
     292       
     293        while (link != &list->contexts) {
     294                ctx = list_get_instance(link, interrupt_context_t, link);
     295                if (irq == ctx->irq && dev == ctx->dev) {
     296                        fibril_mutex_unlock(&list->mutex);
     297                        return ctx;
     298                }
     299                link = link->next;
     300        }
     301       
     302        fibril_mutex_unlock(&list->mutex);
     303        return NULL;
     304}
     305
     306int register_interrupt_handler(device_t *, int, interrupt_handler_t *,
    183307    irq_code_t *);
    184 extern int unregister_interrupt_handler(device_t *, int);
    185 
    186 extern remote_handler_t *device_get_default_handler(device_t *);
    187 extern int add_device_to_class(device_t *, const char *);
     308int unregister_interrupt_handler(device_t *, int);
     309
     310
     311/* default handler for client requests */
     312
     313static inline remote_handler_t *device_get_default_handler(device_t *dev)
     314{
     315        if (NULL == dev->ops)
     316                return NULL;
     317        return dev->ops->default_handler;
     318}
     319
     320static inline int add_device_to_class(device_t *dev, const char *class_name)
     321{
     322        return devman_add_device_to_class(dev->handle, class_name);
     323}
    188324
    189325#endif
Note: See TracChangeset for help on using the changeset viewer.