Changeset 80bffdb0 in mainline for uspace/lib/drv/generic/driver.c


Ignore:
Timestamp:
2011-01-09T21:02:35Z (13 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
8b5c8ae
Parents:
d6b1359 (diff), 22027b6e (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge some more DDF cleanup, this time no API changes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/drv/generic/driver.c

    rd6b1359 r80bffdb0  
    5252#include <ipc/driver.h>
    5353
     54#include "dev_iface.h"
    5455#include "driver.h"
    5556
    56 /* driver structure */
    57 
     57/** Driver structure */
    5858static driver_t *driver;
    5959
    60 /* devices */
    61 
     60/** Devices */
    6261LIST_INITIALIZE(devices);
    6362FIBRIL_MUTEX_INITIALIZE(devices_mutex);
    6463
    65 /* interrupts */
    66 
     64/** Interrupts */
    6765static interrupt_context_list_t interrupt_contexts;
    6866
     
    8583       
    8684        ctx = find_interrupt_context_by_id(&interrupt_contexts, id);
    87         if (NULL != ctx && NULL != ctx->handler)
     85        if (ctx != NULL && ctx->handler != NULL)
    8886                (*ctx->handler)(ctx->dev, iid, icall);
    8987}
     88
     89interrupt_context_t *create_interrupt_context(void)
     90{
     91        interrupt_context_t *ctx;
     92       
     93        ctx = (interrupt_context_t *) malloc(sizeof(interrupt_context_t));
     94        if (ctx != NULL)
     95                memset(ctx, 0, sizeof(interrupt_context_t));
     96       
     97        return ctx;
     98}
     99
     100void delete_interrupt_context(interrupt_context_t *ctx)
     101{
     102        if (ctx != NULL)
     103                free(ctx);
     104}
     105
     106void init_interrupt_context_list(interrupt_context_list_t *list)
     107{
     108        memset(list, 0, sizeof(interrupt_context_list_t));
     109        fibril_mutex_initialize(&list->mutex);
     110        list_initialize(&list->contexts);
     111}
     112
     113void
     114add_interrupt_context(interrupt_context_list_t *list, interrupt_context_t *ctx)
     115{
     116        fibril_mutex_lock(&list->mutex);
     117        ctx->id = list->curr_id++;
     118        list_append(&ctx->link, &list->contexts);
     119        fibril_mutex_unlock(&list->mutex);
     120}
     121
     122void remove_interrupt_context(interrupt_context_list_t *list,
     123    interrupt_context_t *ctx)
     124{
     125        fibril_mutex_lock(&list->mutex);
     126        list_remove(&ctx->link);
     127        fibril_mutex_unlock(&list->mutex);
     128}
     129
     130interrupt_context_t *
     131find_interrupt_context_by_id(interrupt_context_list_t *list, int id)
     132{
     133        fibril_mutex_lock(&list->mutex);
     134       
     135        link_t *link = list->contexts.next;
     136        interrupt_context_t *ctx;
     137       
     138        while (link != &list->contexts) {
     139                ctx = list_get_instance(link, interrupt_context_t, link);
     140                if (ctx->id == id) {
     141                        fibril_mutex_unlock(&list->mutex);
     142                        return ctx;
     143                }
     144                link = link->next;
     145        }
     146       
     147        fibril_mutex_unlock(&list->mutex);
     148        return NULL;
     149}
     150
     151interrupt_context_t *
     152find_interrupt_context(interrupt_context_list_t *list, device_t *dev, int irq)
     153{
     154        fibril_mutex_lock(&list->mutex);
     155       
     156        link_t *link = list->contexts.next;
     157        interrupt_context_t *ctx;
     158       
     159        while (link != &list->contexts) {
     160                ctx = list_get_instance(link, interrupt_context_t, link);
     161                if (ctx->irq == irq && ctx->dev == dev) {
     162                        fibril_mutex_unlock(&list->mutex);
     163                        return ctx;
     164                }
     165                link = link->next;
     166        }
     167       
     168        fibril_mutex_unlock(&list->mutex);
     169        return NULL;
     170}
     171
    90172
    91173int
     
    101183        add_interrupt_context(&interrupt_contexts, ctx);
    102184       
    103         if (NULL == pseudocode)
     185        if (pseudocode == NULL)
    104186                pseudocode = &default_pseudocode;
    105187       
    106188        int res = ipc_register_irq(irq, dev->handle, ctx->id, pseudocode);
    107         if (0 != res) {
     189        if (res != EOK) {
    108190                remove_interrupt_context(&interrupt_contexts, ctx);
    109191                delete_interrupt_context(ctx);
     
    118200            dev, irq);
    119201        int res = ipc_unregister_irq(irq, dev->handle);
    120 
    121         if (NULL != ctx) {
     202       
     203        if (ctx != NULL) {
    122204                remove_interrupt_context(&interrupt_contexts, ctx);
    123205                delete_interrupt_context(ctx);
    124206        }
     207       
    125208        return res;
    126209}
     
    140223}
    141224
    142 static device_t * driver_get_device(link_t *devices, devman_handle_t handle)
     225static device_t *driver_get_device(link_t *devices, devman_handle_t handle)
    143226{
    144227        device_t *dev = NULL;
     
    146229        fibril_mutex_lock(&devices_mutex);
    147230        link_t *link = devices->next;
     231       
    148232        while (link != devices) {
    149233                dev = list_get_instance(link, device_t, link);
    150                 if (handle == dev->handle) {
     234                if (dev->handle == handle) {
    151235                        fibril_mutex_unlock(&devices_mutex);
    152236                        return dev;
     
    154238                link = link->next;
    155239        }
     240       
    156241        fibril_mutex_unlock(&devices_mutex);
    157 
     242       
    158243        return NULL;
    159244}
     
    162247{
    163248        char *dev_name = NULL;
    164         int res = EOK;
    165        
    166         devman_handle_t dev_handle =  IPC_GET_ARG1(*icall);
     249        int res;
     250       
     251        devman_handle_t dev_handle = IPC_GET_ARG1(*icall);
    167252        devman_handle_t parent_dev_handle = IPC_GET_ARG2(*icall);
    168    
     253       
    169254        device_t *dev = create_device();
    170255        dev->handle = dev_handle;
     
    177262       
    178263        res = driver->driver_ops->add_device(dev);
    179         if (0 == res) {
     264        if (res == EOK) {
    180265                printf("%s: new device with handle=%" PRIun " was added.\n",
    181266                    driver->name, dev_handle);
     
    194279        /* Accept connection */
    195280        ipc_answer_0(iid, EOK);
    196 
     281       
    197282        bool cont = true;
    198283        while (cont) {
    199284                ipc_call_t call;
    200285                ipc_callid_t callid = async_get_call(&call);
    201 
     286               
    202287                switch (IPC_GET_IMETHOD(call)) {
    203288                case IPC_M_PHONE_HUNGUP:
     
    240325         * use the device.
    241326         */
    242 
     327       
    243328        int ret = EOK;
    244329        /* open the device */
    245         if (NULL != dev->ops && NULL != dev->ops->open)
     330        if (dev->ops != NULL && dev->ops->open != NULL)
    246331                ret = (*dev->ops->open)(dev);
    247332       
    248         ipc_answer_0(iid, ret); 
    249         if (EOK != ret)
     333        ipc_answer_0(iid, ret);
     334        if (ret != EOK)
    250335                return;
    251 
     336       
    252337        while (1) {
    253338                ipc_callid_t callid;
     
    258343               
    259344                switch  (method) {
    260                 case IPC_M_PHONE_HUNGUP:               
     345                case IPC_M_PHONE_HUNGUP:
    261346                        /* close the device */
    262                         if (NULL != dev->ops && NULL != dev->ops->close)
     347                        if (dev->ops != NULL && dev->ops->close != NULL)
    263348                                (*dev->ops->close)(dev);
    264349                        ipc_answer_0(callid, EOK);
    265350                        return;
    266                 default:               
     351                default:
    267352                        /* convert ipc interface id to interface index */
    268353                       
     
    272357                                remote_handler_t *default_handler =
    273358                                    device_get_default_handler(dev);
    274                                 if (NULL != default_handler) {
     359                                if (default_handler != NULL) {
    275360                                        (*default_handler)(dev, callid, &call);
    276361                                        break;
     
    286371                                break;
    287372                        }
    288 
     373                       
    289374                        /* calling one of the device's interfaces */
    290375                       
    291                         /* get the device interface structure */
    292                         void *iface = device_get_iface(dev, iface_idx);
    293                         if (NULL == iface) {
     376                        /* Get the interface ops structure. */
     377                        void *ops = device_get_ops(dev, iface_idx);
     378                        if (ops == NULL) {
    294379                                printf("%s: driver_connection_gen error - ",
    295380                                    driver->name);
     
    299384                                break;
    300385                        }
    301 
     386                       
    302387                        /*
    303388                         * Get the corresponding interface for remote request
    304389                         * handling ("remote interface").
    305390                         */
    306                         remote_iface_t* rem_iface = get_remote_iface(iface_idx);
    307                         assert(NULL != rem_iface);
    308 
     391                        remote_iface_t *rem_iface = get_remote_iface(iface_idx);
     392                        assert(rem_iface != NULL);
     393                       
    309394                        /* get the method of the remote interface */
    310395                        sysarg_t iface_method_idx = IPC_GET_ARG1(call);
    311396                        remote_iface_func_ptr_t iface_method_ptr =
    312397                            get_remote_method(rem_iface, iface_method_idx);
    313                         if (NULL == iface_method_ptr) {
     398                        if (iface_method_ptr == NULL) {
    314399                                // the interface has not such method
    315400                                printf("%s: driver_connection_gen error - "
     
    325410                         * associated with the device by its driver.
    326411                         */
    327                         (*iface_method_ptr)(dev, iface, callid, &call);
     412                        (*iface_method_ptr)(dev, ops, callid, &call);
    328413                        break;
    329414                }
     
    348433        switch ((sysarg_t) (IPC_GET_ARG1(*icall))) {
    349434        case DRIVER_DEVMAN:
    350                 /* handle PnP events from device manager */
     435                /* Handle request from device manager */
    351436                driver_connection_devman(iid, icall);
    352437                break;
    353438        case DRIVER_DRIVER:
    354                 /* handle request from drivers of child devices */
     439                /* Handle request from drivers of child devices */
    355440                driver_connection_driver(iid, icall);
    356441                break;
    357442        case DRIVER_CLIENT:
    358                 /* handle requests from client applications */
     443                /* Handle request from client applications */
    359444                driver_connection_client(iid, icall);
    360445                break;
    361 
    362446        default:
    363447                /* No such interface */
     
    366450}
    367451
     452/** Create new device structure.
     453 *
     454 * @return              The device structure.
     455 */
     456device_t *create_device(void)
     457{
     458        device_t *dev = malloc(sizeof(device_t));
     459
     460        if (dev != NULL) {
     461                memset(dev, 0, sizeof(device_t));
     462                init_match_ids(&dev->match_ids);
     463        }
     464
     465        return dev;
     466}
     467
     468/** Delete device structure.
     469 *
     470 * @param dev           The device structure.
     471 */
     472void delete_device(device_t *dev)
     473{
     474        clean_match_ids(&dev->match_ids);
     475        if (dev->name != NULL)
     476                free(dev->name);
     477        free(dev);
     478}
     479
     480void *device_get_ops(device_t *dev, dev_inferface_idx_t idx)
     481{
     482        assert(is_valid_iface_idx(idx));
     483        if (dev->ops == NULL)
     484                return NULL;
     485        return dev->ops->interfaces[idx];
     486}
     487
    368488int child_device_register(device_t *child, device_t *parent)
    369489{
    370         assert(NULL != child->name);
    371 
     490        assert(child->name != NULL);
     491       
    372492        int res;
    373493       
     
    375495        res = devman_child_device_register(child->name, &child->match_ids,
    376496            parent->handle, &child->handle);
    377         if (EOK == res)
     497        if (res != EOK) {
     498                remove_from_devices_list(child);
    378499                return res;
    379         remove_from_devices_list(child);       
     500        }
     501       
    380502        return res;
    381503}
     
    395517        match_id_t *match_id = NULL;
    396518        int rc;
    397 
     519       
    398520        child = create_device();
    399521        if (child == NULL) {
     
    401523                goto failure;
    402524        }
    403 
     525       
    404526        child->name = child_name;
    405 
     527       
    406528        match_id = create_match_id();
    407529        if (match_id == NULL) {
     
    409531                goto failure;
    410532        }
    411 
     533       
    412534        match_id->id = child_match_id;
    413535        match_id->score = child_match_score;
    414536        add_match_id(&child->match_ids, match_id);
    415 
     537       
    416538        rc = child_device_register(child, parent);
    417         if (EOK != rc)
     539        if (rc != EOK)
    418540                goto failure;
    419 
     541       
    420542        return EOK;
    421 
     543       
    422544failure:
    423545        if (match_id != NULL) {
     
    425547                delete_match_id(match_id);
    426548        }
    427 
     549       
    428550        if (child != NULL) {
    429551                child->name = NULL;
    430552                delete_device(child);
    431553        }
    432 
     554       
    433555        return rc;
     556}
     557
     558/** Get default handler for client requests */
     559remote_handler_t *device_get_default_handler(device_t *dev)
     560{
     561        if (dev->ops == NULL)
     562                return NULL;
     563        return dev->ops->default_handler;
     564}
     565
     566int add_device_to_class(device_t *dev, const char *class_name)
     567{
     568        return devman_add_device_to_class(dev->handle, class_name);
    434569}
    435570
     
    441576         */
    442577        driver = drv;
    443 
     578       
    444579        /* Initialize the list of interrupt contexts. */
    445580        init_interrupt_context_list(&interrupt_contexts);
     
    453588         */
    454589        devman_driver_register(driver->name, driver_connection);
    455 
     590       
    456591        async_manager();
    457 
     592       
    458593        /* Never reached. */
    459594        return 0;
Note: See TracChangeset for help on using the changeset viewer.