Ignore:
File:
1 edited

Legend:

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

    rb72efe8 r26fa82bc  
    139139find_interrupt_context_by_id(interrupt_context_list_t *list, int id)
    140140{
     141        fibril_mutex_lock(&list->mutex);
     142       
     143        link_t *link = list->contexts.next;
    141144        interrupt_context_t *ctx;
    142145       
    143         fibril_mutex_lock(&list->mutex);
    144        
    145         list_foreach(list->contexts, link) {
     146        while (link != &list->contexts) {
    146147                ctx = list_get_instance(link, interrupt_context_t, link);
    147148                if (ctx->id == id) {
     
    149150                        return ctx;
    150151                }
     152                link = link->next;
    151153        }
    152154       
     
    158160find_interrupt_context(interrupt_context_list_t *list, ddf_dev_t *dev, int irq)
    159161{
     162        fibril_mutex_lock(&list->mutex);
     163       
     164        link_t *link = list->contexts.next;
    160165        interrupt_context_t *ctx;
    161166       
    162         fibril_mutex_lock(&list->mutex);
    163        
    164         list_foreach(list->contexts, link) {
     167        while (link != &list->contexts) {
    165168                ctx = list_get_instance(link, interrupt_context_t, link);
    166169                if (ctx->irq == irq && ctx->dev == dev) {
     
    168171                        return ctx;
    169172                }
     173                link = link->next;
    170174        }
    171175       
     
    227231}
    228232
    229 static ddf_fun_t *driver_get_function(list_t *functions, devman_handle_t handle)
     233static ddf_fun_t *driver_get_function(link_t *functions, devman_handle_t handle)
    230234{
    231235        ddf_fun_t *fun = NULL;
    232236       
    233237        fibril_mutex_lock(&functions_mutex);
    234        
    235         list_foreach(*functions, link) {
     238        link_t *link = functions->next;
     239       
     240        while (link != functions) {
    236241                fun = list_get_instance(link, ddf_fun_t, link);
    237242                if (fun->handle == handle) {
     
    239244                        return fun;
    240245                }
     246               
     247                link = link->next;
    241248        }
    242249       
     
    278285        async_answer_0(iid, EOK);
    279286       
    280         while (true) {
     287        bool cont = true;
     288        while (cont) {
    281289                ipc_call_t call;
    282290                ipc_callid_t callid = async_get_call(&call);
    283291               
    284                 if (!IPC_GET_IMETHOD(call))
    285                         break;
    286                
    287292                switch (IPC_GET_IMETHOD(call)) {
     293                case IPC_M_PHONE_HUNGUP:
     294                        cont = false;
     295                        continue;
    288296                case DRIVER_ADD_DEVICE:
    289297                        driver_add_device(callid, &call);
     
    295303}
    296304
    297 /** Generic client connection handler both for applications and drivers.
    298  *
    299  * @param drv True for driver client, false for other clients
    300  *            (applications, services, etc.).
    301  *
     305/**
     306 * Generic client connection handler both for applications and drivers.
     307 *
     308 * @param drv           True for driver client, false for other clients
     309 *                      (applications, services etc.).
    302310 */
    303311static void driver_connection_gen(ipc_callid_t iid, ipc_call_t *icall, bool drv)
     
    309317        devman_handle_t handle = IPC_GET_ARG2(*icall);
    310318        ddf_fun_t *fun = driver_get_function(&functions, handle);
    311        
     319
    312320        if (fun == NULL) {
    313321                printf("%s: driver_connection_gen error - no function with handle"
     
    317325        }
    318326       
     327       
    319328        /*
    320329         * TODO - if the client is not a driver, check whether it is allowed to
     
    331340                return;
    332341       
    333         while (true) {
     342        while (1) {
    334343                ipc_callid_t callid;
    335344                ipc_call_t call;
    336345                callid = async_get_call(&call);
    337346                sysarg_t method = IPC_GET_IMETHOD(call);
     347                int iface_idx;
    338348               
    339                 if (!method) {
     349                switch  (method) {
     350                case IPC_M_PHONE_HUNGUP:
    340351                        /* Close device function */
    341352                        if (fun->ops != NULL && fun->ops->close != NULL)
     
    343354                        async_answer_0(callid, EOK);
    344355                        return;
    345                 }
    346                
    347                 /* Convert ipc interface id to interface index */
    348                
    349                 int iface_idx = DEV_IFACE_IDX(method);
    350                
    351                 if (!is_valid_iface_idx(iface_idx)) {
    352                         remote_handler_t *default_handler =
    353                             function_get_default_handler(fun);
    354                         if (default_handler != NULL) {
    355                                 (*default_handler)(fun, callid, &call);
    356                                 continue;
     356                default:
     357                        /* convert ipc interface id to interface index */
     358                       
     359                        iface_idx = DEV_IFACE_IDX(method);
     360                       
     361                        if (!is_valid_iface_idx(iface_idx)) {
     362                                remote_handler_t *default_handler =
     363                                    function_get_default_handler(fun);
     364                                if (default_handler != NULL) {
     365                                        (*default_handler)(fun, callid, &call);
     366                                        break;
     367                                }
     368                               
     369                                /*
     370                                 * Function has no such interface and
     371                                 * default handler is not provided.
     372                                 */
     373                                printf("%s: driver_connection_gen error - "
     374                                    "invalid interface id %d.",
     375                                    driver->name, iface_idx);
     376                                async_answer_0(callid, ENOTSUP);
     377                                break;
     378                        }
     379                       
     380                        /* calling one of the function's interfaces */
     381                       
     382                        /* Get the interface ops structure. */
     383                        void *ops = function_get_ops(fun, iface_idx);
     384                        if (ops == NULL) {
     385                                printf("%s: driver_connection_gen error - ",
     386                                    driver->name);
     387                                printf("Function with handle %" PRIun " has no interface "
     388                                    "with id %d.\n", handle, iface_idx);
     389                                async_answer_0(callid, ENOTSUP);
     390                                break;
    357391                        }
    358392                       
    359393                        /*
    360                          * Function has no such interface and
    361                          * default handler is not provided.
     394                         * Get the corresponding interface for remote request
     395                         * handling ("remote interface").
    362396                         */
    363                         printf("%s: driver_connection_gen error - "
    364                             "invalid interface id %d.",
    365                             driver->name, iface_idx);
    366                         async_answer_0(callid, ENOTSUP);
    367                         continue;
     397                        remote_iface_t *rem_iface = get_remote_iface(iface_idx);
     398                        assert(rem_iface != NULL);
     399                       
     400                        /* get the method of the remote interface */
     401                        sysarg_t iface_method_idx = IPC_GET_ARG1(call);
     402                        remote_iface_func_ptr_t iface_method_ptr =
     403                            get_remote_method(rem_iface, iface_method_idx);
     404                        if (iface_method_ptr == NULL) {
     405                                /* The interface has not such method */
     406                                printf("%s: driver_connection_gen error - "
     407                                    "invalid interface method.", driver->name);
     408                                async_answer_0(callid, ENOTSUP);
     409                                break;
     410                        }
     411                       
     412                        /*
     413                         * Call the remote interface's method, which will
     414                         * receive parameters from the remote client and it will
     415                         * pass it to the corresponding local interface method
     416                         * associated with the function by its driver.
     417                         */
     418                        (*iface_method_ptr)(fun, ops, callid, &call);
     419                        break;
    368420                }
    369                
    370                 /* Calling one of the function's interfaces */
    371                
    372                 /* Get the interface ops structure. */
    373                 void *ops = function_get_ops(fun, iface_idx);
    374                 if (ops == NULL) {
    375                         printf("%s: driver_connection_gen error - ", driver->name);
    376                         printf("Function with handle %" PRIun " has no interface "
    377                             "with id %d.\n", handle, iface_idx);
    378                         async_answer_0(callid, ENOTSUP);
    379                         continue;
    380                 }
    381                
    382                 /*
    383                  * Get the corresponding interface for remote request
    384                  * handling ("remote interface").
    385                  */
    386                 remote_iface_t *rem_iface = get_remote_iface(iface_idx);
    387                 assert(rem_iface != NULL);
    388                
    389                 /* get the method of the remote interface */
    390                 sysarg_t iface_method_idx = IPC_GET_ARG1(call);
    391                 remote_iface_func_ptr_t iface_method_ptr =
    392                     get_remote_method(rem_iface, iface_method_idx);
    393                 if (iface_method_ptr == NULL) {
    394                         /* The interface has not such method */
    395                         printf("%s: driver_connection_gen error - "
    396                             "invalid interface method.", driver->name);
    397                         async_answer_0(callid, ENOTSUP);
    398                         continue;
    399                 }
    400                
    401                 /*
    402                  * Call the remote interface's method, which will
    403                  * receive parameters from the remote client and it will
    404                  * pass it to the corresponding local interface method
    405                  * associated with the function by its driver.
    406                  */
    407                 (*iface_method_ptr)(fun, ops, callid, &call);
    408421        }
    409422}
     
    420433
    421434/** Function for handling connections to device driver. */
    422 static void driver_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
     435static void driver_connection(ipc_callid_t iid, ipc_call_t *icall)
    423436{
    424437        /* Select interface */
Note: See TracChangeset for help on using the changeset viewer.