Changeset eb522e8 in mainline for uspace/lib/c/generic/devman.c


Ignore:
Timestamp:
2011-06-01T08:43:42Z (14 years ago)
Author:
Lubos Slovak <lubos.slovak@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
8d6c1f1
Parents:
9e2e715 (diff), e51a514 (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:

Huuuuuge merge from development - all the work actually :)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/devman.c

    r9e2e715 reb522e8  
    2828 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2929 */
    30  
    31  /** @addtogroup libc
     30
     31/** @addtogroup libc
    3232 * @{
    3333 */
     
    3737#include <str.h>
    3838#include <stdio.h>
    39 #include <ipc/ipc.h>
    4039#include <ipc/services.h>
    4140#include <ipc/devman.h>
    4241#include <devman.h>
    4342#include <async.h>
     43#include <fibril_synch.h>
    4444#include <errno.h>
    4545#include <malloc.h>
     
    5050static int devman_phone_client = -1;
    5151
     52static FIBRIL_MUTEX_INITIALIZE(devman_phone_mutex);
     53
    5254int devman_get_phone(devman_interface_t iface, unsigned int flags)
    5355{
    5456        switch (iface) {
    5557        case DEVMAN_DRIVER:
    56                 if (devman_phone_driver >= 0)
     58                fibril_mutex_lock(&devman_phone_mutex);
     59                if (devman_phone_driver >= 0) {
     60                        fibril_mutex_unlock(&devman_phone_mutex);
    5761                        return devman_phone_driver;
     62                }
    5863               
    5964                if (flags & IPC_FLAG_BLOCKING)
    60                         devman_phone_driver = ipc_connect_me_to_blocking(PHONE_NS,
    61                             SERVICE_DEVMAN, DEVMAN_DRIVER, 0);
     65                        devman_phone_driver = async_connect_me_to_blocking(
     66                            PHONE_NS, SERVICE_DEVMAN, DEVMAN_DRIVER, 0);
    6267                else
    63                         devman_phone_driver = ipc_connect_me_to(PHONE_NS,
     68                        devman_phone_driver = async_connect_me_to(PHONE_NS,
    6469                            SERVICE_DEVMAN, DEVMAN_DRIVER, 0);
    6570               
     71                fibril_mutex_unlock(&devman_phone_mutex);
    6672                return devman_phone_driver;
    6773        case DEVMAN_CLIENT:
    68                 if (devman_phone_client >= 0)
     74                fibril_mutex_lock(&devman_phone_mutex);
     75                if (devman_phone_client >= 0) {
     76                        fibril_mutex_unlock(&devman_phone_mutex);
    6977                        return devman_phone_client;
     78                }
    7079               
    71                 if (flags & IPC_FLAG_BLOCKING)
    72                         devman_phone_client = ipc_connect_me_to_blocking(PHONE_NS,
     80                if (flags & IPC_FLAG_BLOCKING) {
     81                        devman_phone_client = async_connect_me_to_blocking(
     82                            PHONE_NS, SERVICE_DEVMAN, DEVMAN_CLIENT, 0);
     83                } else {
     84                        devman_phone_client = async_connect_me_to(PHONE_NS,
    7385                            SERVICE_DEVMAN, DEVMAN_CLIENT, 0);
    74                 else
    75                         devman_phone_client = ipc_connect_me_to(PHONE_NS,
    76                             SERVICE_DEVMAN, DEVMAN_CLIENT, 0);
     86                }
    7787               
     88                fibril_mutex_unlock(&devman_phone_mutex);
    7889                return devman_phone_client;
    7990        default:
     
    95106        aid_t req = async_send_2(phone, DEVMAN_DRIVER_REGISTER, 0, 0, &answer);
    96107       
    97         ipcarg_t retval = async_data_write_start(phone, name, str_size(name));
     108        sysarg_t retval = async_data_write_start(phone, name, str_size(name));
    98109        if (retval != EOK) {
    99110                async_wait_for(req, NULL);
     
    104115        async_set_client_connection(conn);
    105116       
    106         ipcarg_t callback_phonehash;
    107         ipc_connect_to_me(phone, 0, 0, 0, &callback_phonehash);
     117        async_connect_to_me(phone, 0, 0, 0, NULL);
    108118        async_wait_for(req, &retval);
    109119       
     
    113123}
    114124
    115 static int devman_send_match_id(int phone, match_id_t *match_id) \
    116 {
    117         ipc_call_t answer;
    118         async_send_1(phone, DEVMAN_ADD_MATCH_ID, match_id->score, &answer);
    119         int retval = async_data_write_start(phone, match_id->id, str_size(match_id->id));
    120         return retval; 
    121 }
    122 
    123 
    124 static int devman_send_match_ids(int phone, match_id_list_t *match_ids)
     125static int devman_send_match_id(int phone, match_id_t *match_id)
     126{
     127        ipc_call_t answer;
     128
     129        aid_t req = async_send_1(phone, DEVMAN_ADD_MATCH_ID, match_id->score,
     130            &answer);
     131        int retval = async_data_write_start(phone, match_id->id,
     132            str_size(match_id->id));
     133
     134        async_wait_for(req, NULL);
     135        return retval;
     136}
     137
     138
     139static int devman_send_match_ids(int phone, match_id_list_t *match_ids)
    125140{
    126141        link_t *link = match_ids->ids.next;
    127142        match_id_t *match_id = NULL;
    128143        int ret = EOK;
    129        
     144
    130145        while (link != &match_ids->ids) {
    131146                match_id = list_get_instance(link, match_id_t, link);
    132                 if (EOK != (ret = devman_send_match_id(phone, match_id)))
    133                 {
    134                         printf("Driver failed to send match id, error number = %d\n", ret);
    135                         return ret;                     
    136                 }
     147                ret = devman_send_match_id(phone, match_id);
     148                if (ret != EOK) {
     149                        return ret;
     150                }
     151
    137152                link = link->next;
    138153        }
    139         return ret;     
    140 }
    141 
    142 int devman_child_device_register(
    143         const char *name, match_id_list_t *match_ids, device_handle_t parent_handle, device_handle_t *handle)
    144 {               
     154
     155        return ret;
     156}
     157
     158/** Add function to a device.
     159 *
     160 * Request devman to add a new function to the specified device owned by
     161 * this driver task.
     162 *
     163 * @param name          Name of the new function
     164 * @param ftype         Function type, fun_inner or fun_exposed
     165 * @param match_ids     Match IDs (should be empty for fun_exposed)
     166 * @param devh          Devman handle of the device
     167 * @param funh          Place to store handle of the new function
     168 *
     169 * @return              EOK on success or negative error code.
     170 */
     171int devman_add_function(const char *name, fun_type_t ftype,
     172    match_id_list_t *match_ids, devman_handle_t devh, devman_handle_t *funh)
     173{
    145174        int phone = devman_get_phone(DEVMAN_DRIVER, IPC_FLAG_BLOCKING);
    146        
    147         if (phone < 0)
    148                 return phone;
    149        
    150         async_serialize_start();
    151        
    152         int match_count = list_count(&match_ids->ids); 
    153         ipc_call_t answer;
    154         aid_t req = async_send_2(phone, DEVMAN_ADD_CHILD_DEVICE, parent_handle, match_count, &answer);
    155 
    156         ipcarg_t retval = async_data_write_start(phone, name, str_size(name));
    157         if (retval != EOK) {
    158                 async_wait_for(req, NULL);
    159                 async_serialize_end();
    160                 return retval;
    161         }
    162        
    163         devman_send_match_ids(phone, match_ids);
     175        int fun_handle;
     176       
     177        if (phone < 0)
     178                return phone;
     179       
     180        async_serialize_start();
     181       
     182        int match_count = list_count(&match_ids->ids);
     183        ipc_call_t answer;
     184
     185        aid_t req = async_send_3(phone, DEVMAN_ADD_FUNCTION, (sysarg_t) ftype,
     186            devh, match_count, &answer);
     187
     188        sysarg_t retval = async_data_write_start(phone, name, str_size(name));
     189        if (retval != EOK) {
     190                async_wait_for(req, NULL);
     191                async_serialize_end();
     192                return retval;
     193        }
     194       
     195        int match_ids_rc = devman_send_match_ids(phone, match_ids);
    164196       
    165197        async_wait_for(req, &retval);
     
    167199        async_serialize_end();
    168200       
    169         if (retval != EOK) {
    170                 if (handle != NULL) {
    171                         *handle = -1;
    172                 }
    173                 return retval;
    174         }       
    175        
    176         if (handle != NULL)
    177                 *handle = (int) IPC_GET_ARG1(answer);   
    178                
    179         return retval;
    180 }
    181 
    182 int devman_add_device_to_class(device_handle_t dev_handle, const char *class_name)
     201        /* Prefer the answer to DEVMAN_ADD_FUNCTION in case of errors. */
     202        if ((match_ids_rc != EOK) && (retval == EOK)) {
     203                retval = match_ids_rc;
     204        }
     205
     206        if (retval == EOK)
     207                fun_handle = (int) IPC_GET_ARG1(answer);
     208        else
     209                fun_handle = -1;
     210       
     211        *funh = fun_handle;
     212
     213        return retval;
     214}
     215
     216int devman_add_device_to_class(devman_handle_t devman_handle,
     217    const char *class_name)
    183218{
    184219        int phone = devman_get_phone(DEVMAN_DRIVER, IPC_FLAG_BLOCKING);
     
    189224        async_serialize_start();
    190225        ipc_call_t answer;
    191         aid_t req = async_send_1(phone, DEVMAN_ADD_DEVICE_TO_CLASS, dev_handle, &answer);
    192        
    193         ipcarg_t retval = async_data_write_start(phone, class_name, str_size(class_name));
     226        aid_t req = async_send_1(phone, DEVMAN_ADD_DEVICE_TO_CLASS,
     227            devman_handle, &answer);
     228       
     229        sysarg_t retval = async_data_write_start(phone, class_name,
     230            str_size(class_name));
    194231        if (retval != EOK) {
    195232                async_wait_for(req, NULL);
     
    201238        async_serialize_end();
    202239       
    203         return retval; 
     240        return retval;
    204241}
    205242
     
    209246        case DEVMAN_DRIVER:
    210247                if (devman_phone_driver >= 0) {
    211                         ipc_hangup(devman_phone_driver);
     248                        async_hangup(devman_phone_driver);
    212249                        devman_phone_driver = -1;
    213250                }
     
    215252        case DEVMAN_CLIENT:
    216253                if (devman_phone_client >= 0) {
    217                         ipc_hangup(devman_phone_client);
     254                        async_hangup(devman_phone_client);
    218255                        devman_phone_client = -1;
    219256                }
     
    224261}
    225262
    226 int devman_device_connect(device_handle_t handle, unsigned int flags)
     263int devman_device_connect(devman_handle_t handle, unsigned int flags)
    227264{
    228265        int phone;
    229266       
    230267        if (flags & IPC_FLAG_BLOCKING) {
    231                 phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAN,
     268                phone = async_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAN,
    232269                    DEVMAN_CONNECT_TO_DEVICE, handle);
    233270        } else {
    234                 phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAN,
     271                phone = async_connect_me_to(PHONE_NS, SERVICE_DEVMAN,
    235272                    DEVMAN_CONNECT_TO_DEVICE, handle);
    236273        }
     
    239276}
    240277
    241 int devman_parent_device_connect(device_handle_t handle, unsigned int flags)
     278int devman_parent_device_connect(devman_handle_t handle, unsigned int flags)
    242279{
    243280        int phone;
    244281       
    245282        if (flags & IPC_FLAG_BLOCKING) {
    246                 phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAN,
     283                phone = async_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAN,
    247284                    DEVMAN_CONNECT_TO_PARENTS_DEVICE, handle);
    248285        } else {
    249                 phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAN,
     286                phone = async_connect_me_to(PHONE_NS, SERVICE_DEVMAN,
    250287                    DEVMAN_CONNECT_TO_PARENTS_DEVICE, handle);
    251288        }
     
    254291}
    255292
    256 int devman_device_get_handle(const char *pathname, device_handle_t *handle, unsigned int flags)
     293int devman_device_get_handle(const char *pathname, devman_handle_t *handle,
     294    unsigned int flags)
    257295{
    258296        int phone = devman_get_phone(DEVMAN_CLIENT, flags);
     
    267305            &answer);
    268306       
    269         ipcarg_t retval = async_data_write_start(phone, pathname, str_size(pathname));
     307        sysarg_t retval = async_data_write_start(phone, pathname,
     308            str_size(pathname));
    270309        if (retval != EOK) {
    271310                async_wait_for(req, NULL);
     
    280319        if (retval != EOK) {
    281320                if (handle != NULL)
    282                         *handle = (device_handle_t) -1;
     321                        *handle = (devman_handle_t) -1;
    283322                return retval;
    284323        }
    285324       
    286325        if (handle != NULL)
    287                 *handle = (device_handle_t) IPC_GET_ARG1(answer);
    288        
    289         return retval;
     326                *handle = (devman_handle_t) IPC_GET_ARG1(answer);
     327       
     328        return retval;
     329}
     330
     331int devman_device_get_handle_by_class(const char *classname,
     332    const char *devname, devman_handle_t *handle, unsigned int flags)
     333{
     334        int phone = devman_get_phone(DEVMAN_CLIENT, flags);
     335
     336        if (phone < 0)
     337                return phone;
     338
     339        async_serialize_start();
     340
     341        ipc_call_t answer;
     342        aid_t req = async_send_1(phone, DEVMAN_DEVICE_GET_HANDLE_BY_CLASS,
     343            flags, &answer);
     344
     345        sysarg_t retval = async_data_write_start(phone, classname,
     346            str_size(classname));
     347        if (retval != EOK) {
     348                async_wait_for(req, NULL);
     349                async_serialize_end();
     350                return retval;
     351        }
     352        retval = async_data_write_start(phone, devname,
     353            str_size(devname));
     354        if (retval != EOK) {
     355                async_wait_for(req, NULL);
     356                async_serialize_end();
     357                return retval;
     358        }
     359
     360        async_wait_for(req, &retval);
     361
     362        async_serialize_end();
     363
     364        if (retval != EOK) {
     365                if (handle != NULL)
     366                        *handle = (devman_handle_t) -1;
     367                return retval;
     368        }
     369
     370        if (handle != NULL)
     371                *handle = (devman_handle_t) IPC_GET_ARG1(answer);
     372
     373        return retval;
     374}
     375
     376int devman_get_device_path(devman_handle_t handle, char *path, size_t path_size)
     377{
     378        int phone = devman_get_phone(DEVMAN_CLIENT, 0);
     379
     380        if (phone < 0)
     381                return phone;
     382
     383        async_serialize_start();
     384
     385        ipc_call_t answer;
     386        aid_t req = async_send_1(phone, DEVMAN_DEVICE_GET_DEVICE_PATH,
     387            handle, &answer);
     388
     389        ipc_call_t data_request_call;
     390        aid_t data_request = async_data_read(phone, path, path_size,
     391            &data_request_call);
     392        if (data_request == 0) {
     393                async_wait_for(req, NULL);
     394                async_serialize_end();
     395                return ENOMEM;
     396        }
     397
     398        sysarg_t data_request_rc;
     399        sysarg_t opening_request_rc;
     400        async_wait_for(data_request, &data_request_rc);
     401        async_wait_for(req, &opening_request_rc);
     402
     403        async_serialize_end();
     404
     405        if (data_request_rc != EOK) {
     406                /* Prefer the return code of the opening request. */
     407                if (opening_request_rc != EOK) {
     408                        return (int) opening_request_rc;
     409                } else {
     410                        return (int) data_request_rc;
     411                }
     412        }
     413        if (opening_request_rc != EOK) {
     414                return (int) opening_request_rc;
     415        }
     416
     417        /* To be on the safe-side. */
     418        path[path_size - 1] = 0;
     419
     420        size_t transferred_size = IPC_GET_ARG2(data_request_call);
     421
     422        if (transferred_size >= path_size) {
     423                return ELIMIT;
     424        }
     425
     426        /* Terminate the string (trailing 0 not send over IPC). */
     427        path[transferred_size] = 0;
     428
     429        return EOK;
    290430}
    291431
Note: See TracChangeset for help on using the changeset viewer.