Changeset 79ae36dd in mainline for uspace/lib/drv/generic/driver.c


Ignore:
Timestamp:
2011-06-08T19:01:55Z (13 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0eff68e
Parents:
764d71e
Message:

new async framework with integrated exchange tracking

  • strict isolation between low-level IPC and high-level async framework with integrated exchange tracking
    • each IPC connection is represented by an async_sess_t structure
    • each IPC exchange is represented by an async_exch_t structure
    • exchange management is either based on atomic messages (EXCHANGE_ATOMIC), locking (EXCHANGE_SERIALIZE) or connection cloning (EXCHANGE_CLONE)
  • async_obsolete: temporary compatibility layer to keep old async clients working (several pieces of code are currently broken, but only non-essential functionality)
  • IPC_M_PHONE_HANGUP is now method no. 0 (for elegant boolean evaluation)
  • IPC_M_DEBUG_ALL has been renamed to IPC_M_DEBUG
  • IPC_M_PING has been removed (VFS protocol now has VFS_IN_PING)
  • console routines in libc have been rewritten for better abstraction
  • additional use for libc-private header files (FILE structure opaque to the client)
  • various cstyle changes (typos, indentation, missing externs in header files, improved comments, etc.)
File:
1 edited

Legend:

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

    r764d71e r79ae36dd  
    285285        async_answer_0(iid, EOK);
    286286       
    287         bool cont = true;
    288         while (cont) {
     287        while (true) {
    289288                ipc_call_t call;
    290289                ipc_callid_t callid = async_get_call(&call);
    291290               
     291                if (!IPC_GET_IMETHOD(call))
     292                        break;
     293               
    292294                switch (IPC_GET_IMETHOD(call)) {
    293                 case IPC_M_PHONE_HUNGUP:
    294                         cont = false;
    295                         continue;
    296295                case DRIVER_ADD_DEVICE:
    297296                        driver_add_device(callid, &call);
     
    303302}
    304303
    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.).
     304/** Generic client connection handler both for applications and drivers.
     305 *
     306 * @param drv True for driver client, false for other clients
     307 *            (applications, services, etc.).
     308 *
    310309 */
    311310static void driver_connection_gen(ipc_callid_t iid, ipc_call_t *icall, bool drv)
     
    317316        devman_handle_t handle = IPC_GET_ARG2(*icall);
    318317        ddf_fun_t *fun = driver_get_function(&functions, handle);
    319 
     318       
    320319        if (fun == NULL) {
    321320                printf("%s: driver_connection_gen error - no function with handle"
     
    325324        }
    326325       
    327        
    328326        /*
    329327         * TODO - if the client is not a driver, check whether it is allowed to
     
    340338                return;
    341339       
    342         while (1) {
     340        while (true) {
    343341                ipc_callid_t callid;
    344342                ipc_call_t call;
    345343                callid = async_get_call(&call);
    346344                sysarg_t method = IPC_GET_IMETHOD(call);
    347                 int iface_idx;
    348                
    349                 switch  (method) {
    350                 case IPC_M_PHONE_HUNGUP:
     345               
     346                if (!method) {
    351347                        /* Close device function */
    352348                        if (fun->ops != NULL && fun->ops->close != NULL)
     
    354350                        async_answer_0(callid, EOK);
    355351                        return;
    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);
     352                }
     353               
     354                /* Convert ipc interface id to interface index */
     355               
     356                int iface_idx = DEV_IFACE_IDX(method);
     357               
     358                if (!is_valid_iface_idx(iface_idx)) {
     359                        remote_handler_t *default_handler =
     360                            function_get_default_handler(fun);
     361                        if (default_handler != NULL) {
     362                                (*default_handler)(fun, callid, &call);
    390363                                break;
    391364                        }
    392365                       
    393366                        /*
    394                          * Get the corresponding interface for remote request
    395                          * handling ("remote interface").
     367                         * Function has no such interface and
     368                         * default handler is not provided.
    396369                         */
    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 "
    408                                     "(index %" PRIun ").\n",
    409                                     driver->name, iface_method_idx);
    410                                 async_answer_0(callid, ENOTSUP);
    411                                 break;
    412                         }
    413                        
    414                         /*
    415                          * Call the remote interface's method, which will
    416                          * receive parameters from the remote client and it will
    417                          * pass it to the corresponding local interface method
    418                          * associated with the function by its driver.
    419                          */
    420                         (*iface_method_ptr)(fun, ops, callid, &call);
     370                        printf("%s: driver_connection_gen error - "
     371                            "invalid interface id %d.",
     372                            driver->name, iface_idx);
     373                        async_answer_0(callid, ENOTSUP);
    421374                        break;
    422375                }
     376               
     377                /* Calling one of the function's interfaces */
     378               
     379                /* Get the interface ops structure. */
     380                void *ops = function_get_ops(fun, iface_idx);
     381                if (ops == NULL) {
     382                        printf("%s: driver_connection_gen error - ", driver->name);
     383                        printf("Function with handle %" PRIun " has no interface "
     384                            "with id %d.\n", handle, iface_idx);
     385                        async_answer_0(callid, ENOTSUP);
     386                        break;
     387                }
     388               
     389                /*
     390                 * Get the corresponding interface for remote request
     391                 * handling ("remote interface").
     392                 */
     393                remote_iface_t *rem_iface = get_remote_iface(iface_idx);
     394                assert(rem_iface != NULL);
     395               
     396                /* get the method of the remote interface */
     397                sysarg_t iface_method_idx = IPC_GET_ARG1(call);
     398                remote_iface_func_ptr_t iface_method_ptr =
     399                    get_remote_method(rem_iface, iface_method_idx);
     400                if (iface_method_ptr == NULL) {
     401                        /* The interface has not such method */
     402                        printf("%s: driver_connection_gen error - "
     403                            "invalid interface method.", driver->name);
     404                        async_answer_0(callid, ENOTSUP);
     405                        break;
     406                }
     407               
     408                /*
     409                 * Call the remote interface's method, which will
     410                 * receive parameters from the remote client and it will
     411                 * pass it to the corresponding local interface method
     412                 * associated with the function by its driver.
     413                 */
     414                (*iface_method_ptr)(fun, ops, callid, &call);
     415                break;
    423416        }
    424417}
Note: See TracChangeset for help on using the changeset viewer.