Ignore:
File:
1 edited

Legend:

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

    rffa2c8ef r7e752b2  
    5252#include <ipc/driver.h>
    5353
    54 #include "dev_iface.h"
    5554#include "driver.h"
    5655
    57 /** Driver structure */
     56/* driver structure */
     57
    5858static driver_t *driver;
    5959
    60 /** Devices */
     60/* devices */
     61
    6162LIST_INITIALIZE(devices);
    6263FIBRIL_MUTEX_INITIALIZE(devices_mutex);
    6364
    64 /** Interrupts */
     65/* interrupts */
     66
    6567static interrupt_context_list_t interrupt_contexts;
    6668
     
    7981static void driver_irq_handler(ipc_callid_t iid, ipc_call_t *icall)
    8082{
    81         int id = (int)IPC_GET_IMETHOD(*icall);
     83        int id = (int)IPC_GET_METHOD(*icall);
    8284        interrupt_context_t *ctx;
    8385       
    8486        ctx = find_interrupt_context_by_id(&interrupt_contexts, id);
    85         if (ctx != NULL && ctx->handler != NULL)
     87        if (NULL != ctx && NULL != ctx->handler)
    8688                (*ctx->handler)(ctx->dev, iid, icall);
    8789}
    88 
    89 interrupt_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 
    100 void delete_interrupt_context(interrupt_context_t *ctx)
    101 {
    102         if (ctx != NULL)
    103                 free(ctx);
    104 }
    105 
    106 void 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 
    113 void
    114 add_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 
    122 void 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 
    130 interrupt_context_t *
    131 find_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 
    151 interrupt_context_t *
    152 find_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 
    17290
    17391int
     
    183101        add_interrupt_context(&interrupt_contexts, ctx);
    184102       
    185         if (pseudocode == NULL)
     103        if (NULL == pseudocode)
    186104                pseudocode = &default_pseudocode;
    187105       
    188         int res = register_irq(irq, dev->handle, ctx->id, pseudocode);
    189         if (res != EOK) {
     106        int res = ipc_register_irq(irq, dev->handle, ctx->id, pseudocode);
     107        if (0 != res) {
    190108                remove_interrupt_context(&interrupt_contexts, ctx);
    191109                delete_interrupt_context(ctx);
     
    199117        interrupt_context_t *ctx = find_interrupt_context(&interrupt_contexts,
    200118            dev, irq);
    201         int res = unregister_irq(irq, dev->handle);
    202        
    203         if (ctx != NULL) {
     119        int res = ipc_unregister_irq(irq, dev->handle);
     120
     121        if (NULL != ctx) {
    204122                remove_interrupt_context(&interrupt_contexts, ctx);
    205123                delete_interrupt_context(ctx);
    206124        }
    207        
    208125        return res;
    209126}
     
    223140}
    224141
    225 static device_t *driver_get_device(link_t *devices, devman_handle_t handle)
     142static device_t * driver_get_device(link_t *devices, devman_handle_t handle)
    226143{
    227144        device_t *dev = NULL;
     
    229146        fibril_mutex_lock(&devices_mutex);
    230147        link_t *link = devices->next;
    231        
    232148        while (link != devices) {
    233149                dev = list_get_instance(link, device_t, link);
    234                 if (dev->handle == handle) {
     150                if (handle == dev->handle) {
    235151                        fibril_mutex_unlock(&devices_mutex);
    236152                        return dev;
     
    238154                link = link->next;
    239155        }
    240        
    241156        fibril_mutex_unlock(&devices_mutex);
    242        
     157
    243158        return NULL;
    244159}
     
    247162{
    248163        char *dev_name = NULL;
    249         int res;
    250        
    251         devman_handle_t dev_handle = IPC_GET_ARG1(*icall);
    252         devman_handle_t parent_dev_handle = IPC_GET_ARG2(*icall);
    253        
     164        int res = EOK;
     165       
     166        devman_handle_t dev_handle =  IPC_GET_ARG1(*icall);
    254167        device_t *dev = create_device();
    255168        dev->handle = dev_handle;
     
    259172       
    260173        add_to_devices_list(dev);
    261         dev->parent = driver_get_device(&devices, parent_dev_handle);
    262        
    263174        res = driver->driver_ops->add_device(dev);
    264         if (res == EOK) {
     175        if (0 == res) {
    265176                printf("%s: new device with handle=%" PRIun " was added.\n",
    266177                    driver->name, dev_handle);
     
    272183        }
    273184       
    274         async_answer_0(iid, res);
     185        ipc_answer_0(iid, res);
    275186}
    276187
     
    278189{
    279190        /* Accept connection */
    280         async_answer_0(iid, EOK);
    281        
     191        ipc_answer_0(iid, EOK);
     192
    282193        bool cont = true;
    283194        while (cont) {
    284195                ipc_call_t call;
    285196                ipc_callid_t callid = async_get_call(&call);
    286                
    287                 switch (IPC_GET_IMETHOD(call)) {
     197
     198                switch (IPC_GET_METHOD(call)) {
    288199                case IPC_M_PHONE_HUNGUP:
    289200                        cont = false;
     
    293204                        break;
    294205                default:
    295                         async_answer_0(callid, ENOENT);
     206                        ipc_answer_0(callid, ENOENT);
    296207                }
    297208        }
     
    316227                printf("%s: driver_connection_gen error - no device with handle"
    317228                    " %" PRIun " was found.\n", driver->name, handle);
    318                 async_answer_0(iid, ENOENT);
     229                ipc_answer_0(iid, ENOENT);
    319230                return;
    320231        }
     
    325236         * use the device.
    326237         */
    327        
     238
    328239        int ret = EOK;
    329240        /* open the device */
    330         if (dev->ops != NULL && dev->ops->open != NULL)
     241        if (NULL != dev->ops && NULL != dev->ops->open)
    331242                ret = (*dev->ops->open)(dev);
    332243       
    333         async_answer_0(iid, ret);
    334         if (ret != EOK)
     244        ipc_answer_0(iid, ret);
     245        if (EOK != ret)
    335246                return;
    336        
     247
    337248        while (1) {
    338249                ipc_callid_t callid;
    339250                ipc_call_t call;
    340251                callid = async_get_call(&call);
    341                 sysarg_t method = IPC_GET_IMETHOD(call);
     252                ipcarg_t method = IPC_GET_METHOD(call);
    342253                int iface_idx;
    343254               
    344255                switch  (method) {
    345                 case IPC_M_PHONE_HUNGUP:
     256                case IPC_M_PHONE_HUNGUP:               
    346257                        /* close the device */
    347                         if (dev->ops != NULL && dev->ops->close != NULL)
     258                        if (NULL != dev->ops && NULL != dev->ops->close)
    348259                                (*dev->ops->close)(dev);
    349                         async_answer_0(callid, EOK);
     260                        ipc_answer_0(callid, EOK);
    350261                        return;
    351                 default:
     262                default:               
    352263                        /* convert ipc interface id to interface index */
    353264                       
     
    357268                                remote_handler_t *default_handler =
    358269                                    device_get_default_handler(dev);
    359                                 if (default_handler != NULL) {
     270                                if (NULL != default_handler) {
    360271                                        (*default_handler)(dev, callid, &call);
    361272                                        break;
     
    368279                                    "invalid interface id %d.",
    369280                                    driver->name, iface_idx);
    370                                 async_answer_0(callid, ENOTSUP);
     281                                ipc_answer_0(callid, ENOTSUP);
    371282                                break;
    372283                        }
    373                        
     284
    374285                        /* calling one of the device's interfaces */
    375286                       
    376                         /* Get the interface ops structure. */
    377                         void *ops = device_get_ops(dev, iface_idx);
    378                         if (ops == NULL) {
     287                        /* get the device interface structure */
     288                        void *iface = device_get_iface(dev, iface_idx);
     289                        if (NULL == iface) {
    379290                                printf("%s: driver_connection_gen error - ",
    380291                                    driver->name);
    381292                                printf("device with handle %" PRIun " has no interface "
    382293                                    "with id %d.\n", handle, iface_idx);
    383                                 async_answer_0(callid, ENOTSUP);
     294                                ipc_answer_0(callid, ENOTSUP);
    384295                                break;
    385296                        }
    386                        
     297
    387298                        /*
    388299                         * Get the corresponding interface for remote request
    389300                         * handling ("remote interface").
    390301                         */
    391                         remote_iface_t *rem_iface = get_remote_iface(iface_idx);
    392                         assert(rem_iface != NULL);
    393                        
     302                        remote_iface_t* rem_iface = get_remote_iface(iface_idx);
     303                        assert(NULL != rem_iface);
     304
    394305                        /* get the method of the remote interface */
    395                         sysarg_t iface_method_idx = IPC_GET_ARG1(call);
     306                        ipcarg_t iface_method_idx = IPC_GET_ARG1(call);
    396307                        remote_iface_func_ptr_t iface_method_ptr =
    397308                            get_remote_method(rem_iface, iface_method_idx);
    398                         if (iface_method_ptr == NULL) {
     309                        if (NULL == iface_method_ptr) {
    399310                                // the interface has not such method
    400311                                printf("%s: driver_connection_gen error - "
    401312                                    "invalid interface method.", driver->name);
    402                                 async_answer_0(callid, ENOTSUP);
     313                                ipc_answer_0(callid, ENOTSUP);
    403314                                break;
    404315                        }
     
    410321                         * associated with the device by its driver.
    411322                         */
    412                         (*iface_method_ptr)(dev, ops, callid, &call);
     323                        (*iface_method_ptr)(dev, iface, callid, &call);
    413324                        break;
    414325                }
     
    431342{
    432343        /* Select interface */
    433         switch ((sysarg_t) (IPC_GET_ARG1(*icall))) {
     344        switch ((ipcarg_t) (IPC_GET_ARG1(*icall))) {
    434345        case DRIVER_DEVMAN:
    435                 /* Handle request from device manager */
     346                /* handle PnP events from device manager */
    436347                driver_connection_devman(iid, icall);
    437348                break;
    438349        case DRIVER_DRIVER:
    439                 /* Handle request from drivers of child devices */
     350                /* handle request from drivers of child devices */
    440351                driver_connection_driver(iid, icall);
    441352                break;
    442353        case DRIVER_CLIENT:
    443                 /* Handle request from client applications */
     354                /* handle requests from client applications */
    444355                driver_connection_client(iid, icall);
    445356                break;
     357
    446358        default:
    447359                /* No such interface */
    448                 async_answer_0(iid, ENOENT);
    449         }
    450 }
    451 
    452 /** Create new device structure.
    453  *
    454  * @return              The device structure.
    455  */
    456 device_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  */
    472 void 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 
    480 void *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];
     360                ipc_answer_0(iid, ENOENT);
     361        }
    486362}
    487363
    488364int child_device_register(device_t *child, device_t *parent)
    489365{
    490         assert(child->name != NULL);
    491        
     366        assert(NULL != child->name);
     367
    492368        int res;
    493369       
     
    495371        res = devman_child_device_register(child->name, &child->match_ids,
    496372            parent->handle, &child->handle);
    497         if (res != EOK) {
    498                 remove_from_devices_list(child);
     373        if (EOK == res)
    499374                return res;
    500         }
    501        
     375        remove_from_devices_list(child);       
    502376        return res;
    503 }
    504 
    505 /** Wrapper for child_device_register for devices with single match id.
    506  *
    507  * @param parent Parent device.
    508  * @param child_name Child device name.
    509  * @param child_match_id Child device match id.
    510  * @param child_match_score Child device match score.
    511  * @return Error code.
    512  */
    513 int child_device_register_wrapper(device_t *parent, const char *child_name,
    514     const char *child_match_id, int child_match_score)
    515 {
    516         device_t *child = NULL;
    517         match_id_t *match_id = NULL;
    518         int rc;
    519        
    520         child = create_device();
    521         if (child == NULL) {
    522                 rc = ENOMEM;
    523                 goto failure;
    524         }
    525        
    526         child->name = child_name;
    527        
    528         match_id = create_match_id();
    529         if (match_id == NULL) {
    530                 rc = ENOMEM;
    531                 goto failure;
    532         }
    533        
    534         match_id->id = child_match_id;
    535         match_id->score = child_match_score;
    536         add_match_id(&child->match_ids, match_id);
    537        
    538         rc = child_device_register(child, parent);
    539         if (rc != EOK)
    540                 goto failure;
    541        
    542         return EOK;
    543        
    544 failure:
    545         if (match_id != NULL) {
    546                 match_id->id = NULL;
    547                 delete_match_id(match_id);
    548         }
    549        
    550         if (child != NULL) {
    551                 child->name = NULL;
    552                 delete_device(child);
    553         }
    554        
    555         return rc;
    556 }
    557 
    558 /** Get default handler for client requests */
    559 remote_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 
    566 int add_device_to_class(device_t *dev, const char *class_name)
    567 {
    568         return devman_add_device_to_class(dev->handle, class_name);
    569377}
    570378
     
    576384         */
    577385        driver = drv;
    578        
     386
    579387        /* Initialize the list of interrupt contexts. */
    580388        init_interrupt_context_list(&interrupt_contexts);
     
    588396         */
    589397        devman_driver_register(driver->name, driver_connection);
    590        
     398
    591399        async_manager();
    592        
     400
    593401        /* Never reached. */
    594402        return 0;
Note: See TracChangeset for help on using the changeset viewer.