Changeset c05642d in mainline for uspace/lib


Ignore:
Timestamp:
2011-09-07T00:03:26Z (14 years ago)
Author:
Petr Koupy <petr.koupy@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
5081276
Parents:
bb74dabe (diff), 038b289 (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 mainline changes.

Location:
uspace/lib
Files:
1 added
20 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/block/libblock.c

    rbb74dabe rc05642d  
    891891}
    892892
     893/** Get TOC from device.
     894 *
     895 * @param service_id Service ID of the block device.
     896 * @param session    Starting session.
     897 *
     898 * @return Allocated TOC structure.
     899 * @return NULL on failure.
     900 *
     901 */
     902toc_block_t *block_get_toc(service_id_t service_id, uint8_t session)
     903{
     904        devcon_t *devcon = devcon_search(service_id);
     905        assert(devcon);
     906       
     907        toc_block_t *toc = NULL;
     908       
     909        fibril_mutex_lock(&devcon->comm_area_lock);
     910       
     911        async_exch_t *exch = async_exchange_begin(devcon->sess);
     912        int rc = async_req_1_0(exch, BD_READ_TOC, session);
     913        async_exchange_end(exch);
     914       
     915        if (rc == EOK) {
     916                toc = (toc_block_t *) malloc(sizeof(toc_block_t));
     917                if (toc != NULL) {
     918                        memset(toc, 0, sizeof(toc_block_t));
     919                        memcpy(toc, devcon->comm_area,
     920                            min(devcon->pblock_size, sizeof(toc_block_t)));
     921                }
     922        }
     923       
     924       
     925        fibril_mutex_unlock(&devcon->comm_area_lock);
     926       
     927        return toc;
     928}
     929
    893930/** Read blocks from block device.
    894931 *
  • uspace/lib/block/libblock.h

    rbb74dabe rc05642d  
    9797};
    9898
     99typedef struct {
     100        uint16_t size;
     101        uint8_t first_session;
     102        uint8_t last_session;
     103       
     104        uint8_t res0;
     105        uint8_t adr_ctrl;
     106        uint8_t first_track;
     107        uint8_t res1;
     108       
     109        uint32_t first_lba;
     110} __attribute__((packed)) toc_block_t;
     111
    99112extern int block_init(exch_mgmt_t, service_id_t, size_t);
    100113extern void block_fini(service_id_t);
     
    114127extern int block_get_bsize(service_id_t, size_t *);
    115128extern int block_get_nblocks(service_id_t, aoff64_t *);
     129extern toc_block_t *block_get_toc(service_id_t, uint8_t);
    116130extern int block_read_direct(service_id_t, aoff64_t, size_t, void *);
    117131extern int block_read_bytes_direct(service_id_t, aoff64_t, size_t, void *);
     
    122136/** @}
    123137 */
    124 
  • uspace/lib/c/generic/async.c

    rbb74dabe rc05642d  
    17771777int async_hangup(async_sess_t *sess)
    17781778{
     1779        async_exch_t *exch;
     1780       
    17791781        assert(sess);
    17801782       
    17811783        if (atomic_get(&sess->refcnt) > 0)
    17821784                return EBUSY;
     1785       
     1786        fibril_mutex_lock(&async_sess_mutex);
    17831787       
    17841788        int rc = async_hangup_internal(sess->phone);
    17851789        if (rc == EOK)
    17861790                free(sess);
     1791       
     1792        while (!list_empty(&sess->exch_list)) {
     1793                exch = (async_exch_t *)
     1794                    list_get_instance(list_first(&sess->exch_list),
     1795                    async_exch_t, sess_link);
     1796               
     1797                list_remove(&exch->sess_link);
     1798                list_remove(&exch->global_link);
     1799                async_hangup_internal(exch->phone);
     1800                free(exch);
     1801        }
     1802       
     1803        fibril_mutex_unlock(&async_sess_mutex);
    17871804       
    17881805        return rc;
  • uspace/lib/c/generic/devman.c

    rbb74dabe rc05642d  
    327327}
    328328
     329int devman_drv_fun_online(devman_handle_t funh)
     330{
     331        async_exch_t *exch = devman_exchange_begin(DEVMAN_DRIVER);
     332        if (exch == NULL)
     333                return ENOMEM;
     334       
     335        sysarg_t retval = async_req_1_0(exch, DEVMAN_DRV_FUN_ONLINE, funh);
     336       
     337        devman_exchange_end(exch);
     338        return (int) retval;
     339}
     340
     341int devman_drv_fun_offline(devman_handle_t funh)
     342{
     343        async_exch_t *exch = devman_exchange_begin(DEVMAN_DRIVER);
     344        if (exch == NULL)
     345                return ENOMEM;
     346       
     347        sysarg_t retval = async_req_1_0(exch, DEVMAN_DRV_FUN_OFFLINE, funh);
     348       
     349        devman_exchange_end(exch);
     350        return (int) retval;
     351}
     352
    329353async_sess_t *devman_parent_device_connect(exch_mgmt_t mgmt,
    330354    devman_handle_t handle, unsigned int flags)
     
    430454}
    431455
     456int devman_fun_online(devman_handle_t funh)
     457{
     458        async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT);
     459        if (exch == NULL)
     460                return ENOMEM;
     461       
     462        sysarg_t retval = async_req_1_0(exch, DEVMAN_FUN_ONLINE, funh);
     463       
     464        devman_exchange_end(exch);
     465        return (int) retval;
     466}
     467
     468int devman_fun_offline(devman_handle_t funh)
     469{
     470        async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT);
     471        if (exch == NULL)
     472                return ENOMEM;
     473       
     474        sysarg_t retval = async_req_1_0(exch, DEVMAN_FUN_OFFLINE, funh);
     475       
     476        devman_exchange_end(exch);
     477        return (int) retval;
     478}
     479
    432480static int devman_get_handles_once(sysarg_t method, sysarg_t arg1,
    433481    devman_handle_t *handle_buf, size_t buf_size, size_t *act_size)
  • uspace/lib/c/generic/io/printf_core.c

    rbb74dabe rc05642d  
    7373 */
    7474#define PRINT_NUMBER_BUFFER_SIZE  (64 + 5)
     75
     76/** Get signed or unsigned integer argument */
     77#define PRINTF_GET_INT_ARGUMENT(type, ap, flags) \
     78        ({ \
     79                unsigned type res; \
     80                \
     81                if ((flags) & __PRINTF_FLAG_SIGNED) { \
     82                        signed type arg = va_arg((ap), signed type); \
     83                        \
     84                        if (arg < 0) { \
     85                                res = -arg; \
     86                                (flags) |= __PRINTF_FLAG_NEGATIVE; \
     87                        } else \
     88                                res = arg; \
     89                } else \
     90                        res = va_arg((ap), unsigned type); \
     91                \
     92                res; \
     93        })
    7594
    7695/** Enumeration of possible arguments types.
     
    831850                        size_t size;
    832851                        uint64_t number;
     852                       
    833853                        switch (qualifier) {
    834854                        case PrintfQualifierByte:
    835855                                size = sizeof(unsigned char);
    836                                 number = (uint64_t) va_arg(ap, unsigned int);
     856                                number = PRINTF_GET_INT_ARGUMENT(int, ap, flags);
    837857                                break;
    838858                        case PrintfQualifierShort:
    839859                                size = sizeof(unsigned short);
    840                                 number = (uint64_t) va_arg(ap, unsigned int);
     860                                number = PRINTF_GET_INT_ARGUMENT(int, ap, flags);
    841861                                break;
    842862                        case PrintfQualifierInt:
    843863                                size = sizeof(unsigned int);
    844                                 number = (uint64_t) va_arg(ap, unsigned int);
     864                                number = PRINTF_GET_INT_ARGUMENT(int, ap, flags);
    845865                                break;
    846866                        case PrintfQualifierLong:
    847867                                size = sizeof(unsigned long);
    848                                 number = (uint64_t) va_arg(ap, unsigned long);
     868                                number = PRINTF_GET_INT_ARGUMENT(long, ap, flags);
    849869                                break;
    850870                        case PrintfQualifierLongLong:
    851871                                size = sizeof(unsigned long long);
    852                                 number = (uint64_t) va_arg(ap, unsigned long long);
     872                                number = PRINTF_GET_INT_ARGUMENT(long long, ap, flags);
    853873                                break;
    854874                        case PrintfQualifierPointer:
     
    865885                                counter = -counter;
    866886                                goto out;
    867                         }
    868                        
    869                         if (flags & __PRINTF_FLAG_SIGNED) {
    870                                 if (number & (0x1 << (size * 8 - 1))) {
    871                                         flags |= __PRINTF_FLAG_NEGATIVE;
    872                                        
    873                                         if (size == sizeof(uint64_t)) {
    874                                                 number = -((int64_t) number);
    875                                         } else {
    876                                                 number = ~number;
    877                                                 number &=
    878                                                     ~(0xFFFFFFFFFFFFFFFFll <<
    879                                                     (size * 8));
    880                                                 number++;
    881                                         }
    882                                 }
    883887                        }
    884888                       
  • uspace/lib/c/generic/str.c

    rbb74dabe rc05642d  
    33 * Copyright (c) 2008 Jiri Svoboda
    44 * Copyright (c) 2011 Martin Sucha
     5 * Copyright (c) 2011 Oleg Romanenko
    56 * All rights reserved.
    67 *
     
    550551 *
    551552 * Common legacy text encoding in hardware is 7-bit ASCII fitted into
    552  * a fixed-with byte buffer (bit 7 always zero), right-padded with spaces
     553 * a fixed-width byte buffer (bit 7 always zero), right-padded with spaces
    553554 * (ASCII 0x20). Convert space-padded ascii to string representation.
    554555 *
     
    639640        dest[dest_off] = '\0';
    640641}
     642
     643/** Convert UTF16 string to string.
     644 *
     645 * Convert utf16 string @a src to string. The output is written to the buffer
     646 * specified by @a dest and @a size. @a size must be non-zero and the string
     647 * written will always be well-formed. Surrogate pairs also supported.
     648 *
     649 * @param dest  Destination buffer.
     650 * @param size  Size of the destination buffer.
     651 * @param src   Source utf16 string.
     652 *
     653 * @return EOK, if success, negative otherwise.
     654 */
     655int utf16_to_str(char *dest, size_t size, const uint16_t *src)
     656{
     657        size_t idx = 0, dest_off = 0;
     658        wchar_t ch;
     659        int rc = EOK;
     660
     661        /* There must be space for a null terminator in the buffer. */
     662        assert(size > 0);
     663
     664        while (src[idx]) {
     665                if ((src[idx] & 0xfc00) == 0xd800) {
     666                        if (src[idx + 1] && (src[idx + 1] & 0xfc00) == 0xdc00) {
     667                                ch = 0x10000;
     668                                ch += (src[idx] & 0x03FF) << 10;
     669                                ch += (src[idx + 1] & 0x03FF);
     670                                idx += 2;
     671                        }
     672                        else
     673                                break;
     674                } else {
     675                        ch = src[idx];
     676                        idx++;
     677                }
     678                rc = chr_encode(ch, dest, &dest_off, size - 1);
     679                if (rc != EOK)
     680                        break;
     681        }
     682        dest[dest_off] = '\0';
     683        return rc;
     684}
     685
     686int str_to_utf16(uint16_t *dest, size_t size, const char *src)
     687{
     688        int rc = EOK;
     689        size_t offset = 0;
     690        size_t idx = 0;
     691        wchar_t c;
     692
     693        assert(size > 0);
     694       
     695        while ((c = str_decode(src, &offset, STR_NO_LIMIT)) != 0) {
     696                if (c > 0x10000) {
     697                        if (idx + 2 >= size - 1) {
     698                                rc = EOVERFLOW;
     699                                break;
     700                        }
     701                        c = (c - 0x10000);
     702                        dest[idx] = 0xD800 | (c >> 10);
     703                        dest[idx + 1] = 0xDC00 | (c & 0x3FF);
     704                        idx++;
     705                } else {
     706                         dest[idx] = c;
     707                }
     708
     709                idx++;
     710                if (idx >= size - 1) {
     711                        rc = EOVERFLOW;
     712                        break;
     713                }
     714        }
     715
     716        dest[idx] = '\0';
     717        return rc;
     718}
     719
    641720
    642721/** Convert wide string to new string.
     
    10361115        return dest;
    10371116}
    1038 
    10391117
    10401118/** Convert initial part of string to unsigned long according to given base.
     
    12131291}
    12141292
     1293/** Convert string to uint8_t.
     1294 *
     1295 * @param nptr   Pointer to string.
     1296 * @param endptr If not NULL, pointer to the first invalid character
     1297 *               is stored here.
     1298 * @param base   Zero or number between 2 and 36 inclusive.
     1299 * @param strict Do not allow any trailing characters.
     1300 * @param result Result of the conversion.
     1301 *
     1302 * @return EOK if conversion was successful.
     1303 *
     1304 */
     1305int str_uint8_t(const char *nptr, char **endptr, unsigned int base,
     1306    bool strict, uint8_t *result)
     1307{
     1308        assert(result != NULL);
     1309       
     1310        bool neg;
     1311        char *lendptr;
     1312        uint64_t res;
     1313        int ret = str_uint(nptr, &lendptr, base, &neg, &res);
     1314       
     1315        if (endptr != NULL)
     1316                *endptr = (char *) lendptr;
     1317       
     1318        if (ret != EOK)
     1319                return ret;
     1320       
     1321        /* Do not allow negative values */
     1322        if (neg)
     1323                return EINVAL;
     1324       
     1325        /* Check whether we are at the end of
     1326           the string in strict mode */
     1327        if ((strict) && (*lendptr != 0))
     1328                return EINVAL;
     1329       
     1330        /* Check for overflow */
     1331        uint8_t _res = (uint8_t) res;
     1332        if (_res != res)
     1333                return EOVERFLOW;
     1334       
     1335        *result = _res;
     1336       
     1337        return EOK;
     1338}
     1339
     1340/** Convert string to uint16_t.
     1341 *
     1342 * @param nptr   Pointer to string.
     1343 * @param endptr If not NULL, pointer to the first invalid character
     1344 *               is stored here.
     1345 * @param base   Zero or number between 2 and 36 inclusive.
     1346 * @param strict Do not allow any trailing characters.
     1347 * @param result Result of the conversion.
     1348 *
     1349 * @return EOK if conversion was successful.
     1350 *
     1351 */
     1352int str_uint16_t(const char *nptr, char **endptr, unsigned int base,
     1353    bool strict, uint16_t *result)
     1354{
     1355        assert(result != NULL);
     1356       
     1357        bool neg;
     1358        char *lendptr;
     1359        uint64_t res;
     1360        int ret = str_uint(nptr, &lendptr, base, &neg, &res);
     1361       
     1362        if (endptr != NULL)
     1363                *endptr = (char *) lendptr;
     1364       
     1365        if (ret != EOK)
     1366                return ret;
     1367       
     1368        /* Do not allow negative values */
     1369        if (neg)
     1370                return EINVAL;
     1371       
     1372        /* Check whether we are at the end of
     1373           the string in strict mode */
     1374        if ((strict) && (*lendptr != 0))
     1375                return EINVAL;
     1376       
     1377        /* Check for overflow */
     1378        uint16_t _res = (uint16_t) res;
     1379        if (_res != res)
     1380                return EOVERFLOW;
     1381       
     1382        *result = _res;
     1383       
     1384        return EOK;
     1385}
     1386
     1387/** Convert string to uint32_t.
     1388 *
     1389 * @param nptr   Pointer to string.
     1390 * @param endptr If not NULL, pointer to the first invalid character
     1391 *               is stored here.
     1392 * @param base   Zero or number between 2 and 36 inclusive.
     1393 * @param strict Do not allow any trailing characters.
     1394 * @param result Result of the conversion.
     1395 *
     1396 * @return EOK if conversion was successful.
     1397 *
     1398 */
     1399int str_uint32_t(const char *nptr, char **endptr, unsigned int base,
     1400    bool strict, uint32_t *result)
     1401{
     1402        assert(result != NULL);
     1403       
     1404        bool neg;
     1405        char *lendptr;
     1406        uint64_t res;
     1407        int ret = str_uint(nptr, &lendptr, base, &neg, &res);
     1408       
     1409        if (endptr != NULL)
     1410                *endptr = (char *) lendptr;
     1411       
     1412        if (ret != EOK)
     1413                return ret;
     1414       
     1415        /* Do not allow negative values */
     1416        if (neg)
     1417                return EINVAL;
     1418       
     1419        /* Check whether we are at the end of
     1420           the string in strict mode */
     1421        if ((strict) && (*lendptr != 0))
     1422                return EINVAL;
     1423       
     1424        /* Check for overflow */
     1425        uint32_t _res = (uint32_t) res;
     1426        if (_res != res)
     1427                return EOVERFLOW;
     1428       
     1429        *result = _res;
     1430       
     1431        return EOK;
     1432}
     1433
    12151434/** Convert string to uint64_t.
    12161435 *
  • uspace/lib/c/generic/sysinfo.c

    rbb74dabe rc05642d  
    4747 *
    4848 */
    49 sysinfo_item_tag_t sysinfo_get_tag(const char *path)
     49sysinfo_item_val_type_t sysinfo_get_val_type(const char *path)
    5050{
    51         return (sysinfo_item_tag_t) __SYSCALL2(SYS_SYSINFO_GET_TAG,
     51        return (sysinfo_item_val_type_t) __SYSCALL2(SYS_SYSINFO_GET_VAL_TYPE,
    5252            (sysarg_t) path, (sysarg_t) str_size(path));
    5353}
  • uspace/lib/c/include/bool.h

    rbb74dabe rc05642d  
    3737
    3838#include <libarch/types.h>
     39#include <abi/bool.h>
    3940
    4041#define false  0
    4142#define true   1
    42 
    43 typedef uint8_t bool;
    4443
    4544#endif
  • uspace/lib/c/include/devman.h

    rbb74dabe rc05642d  
    5050    devman_handle_t, devman_handle_t *);
    5151extern int devman_remove_function(devman_handle_t);
     52extern int devman_drv_fun_online(devman_handle_t);
     53extern int devman_drv_fun_offline(devman_handle_t);
    5254
    5355extern async_sess_t *devman_device_connect(exch_mgmt_t, devman_handle_t,
     
    6365extern int devman_fun_get_name(devman_handle_t, char *, size_t);
    6466extern int devman_fun_get_path(devman_handle_t, char *, size_t);
     67extern int devman_fun_online(devman_handle_t);
     68extern int devman_fun_offline(devman_handle_t);
    6569
    6670extern int devman_add_device_to_category(devman_handle_t, const char *);
  • uspace/lib/c/include/errno.h

    rbb74dabe rc05642d  
    5555#define EIO           (-265)
    5656#define EMLINK        (-266)
     57#define ENXIO         (-267)
    5758
    5859/** Bad checksum. */
  • uspace/lib/c/include/ipc/bd.h

    rbb74dabe rc05642d  
    4242        BD_GET_NUM_BLOCKS,
    4343        BD_READ_BLOCKS,
    44         BD_WRITE_BLOCKS
     44        BD_WRITE_BLOCKS,
     45        BD_READ_TOC
    4546} bd_request_t;
    4647
  • uspace/lib/c/include/ipc/devman.h

    rbb74dabe rc05642d  
    139139        DEVMAN_ADD_MATCH_ID,
    140140        DEVMAN_ADD_DEVICE_TO_CATEGORY,
     141        DEVMAN_DRV_FUN_ONLINE,
     142        DEVMAN_DRV_FUN_OFFLINE,
    141143        DEVMAN_REMOVE_FUNCTION
    142144} driver_to_devman_t;
    143145
    144146typedef enum {
    145         DRIVER_ADD_DEVICE = IPC_FIRST_USER_METHOD
    146 
     147        DRIVER_DEV_ADD = IPC_FIRST_USER_METHOD,
     148        DRIVER_DEV_REMOVE,
     149        DRIVER_DEV_GONE,
     150        DRIVER_FUN_ONLINE,
     151        DRIVER_FUN_OFFLINE,
    147152} devman_to_driver_t;
    148153
     
    152157        DEVMAN_FUN_GET_CHILD,
    153158        DEVMAN_FUN_GET_NAME,
     159        DEVMAN_FUN_ONLINE,
     160        DEVMAN_FUN_OFFLINE,
    154161        DEVMAN_FUN_GET_PATH,
    155162        DEVMAN_FUN_SID_TO_HANDLE
  • uspace/lib/c/include/str.h

    rbb74dabe rc05642d  
    11/*
    22 * Copyright (c) 2005 Martin Decky
     3 * Copyright (c) 2011 Oleg Romanenko
    34 * All rights reserved.
    45 *
     
    8485extern void str_to_wstr(wchar_t *dest, size_t dlen, const char *src);
    8586extern wchar_t *str_to_awstr(const char *src);
     87extern int utf16_to_str(char *dest, size_t size, const uint16_t *src);
     88extern int str_to_utf16(uint16_t *dest, size_t size, const char *src);
    8689
    8790extern char *str_chr(const char *str, wchar_t ch);
     
    9497extern char *str_ndup(const char *, size_t max_size);
    9598
     99extern int str_uint8_t(const char *, char **, unsigned int, bool, uint8_t *);
     100extern int str_uint16_t(const char *, char **, unsigned int, bool, uint16_t *);
     101extern int str_uint32_t(const char *, char **, unsigned int, bool, uint32_t *);
    96102extern int str_uint64(const char *, char **, unsigned int, bool, uint64_t *);
    97103extern int str_size_t(const char *, char **, unsigned int, bool, size_t *);
  • uspace/lib/c/include/sysinfo.h

    rbb74dabe rc05642d  
    3636#define LIBC_SYSINFO_H_
    3737
    38 #include <libc.h>
     38#include <sys/types.h>
     39#include <bool.h>
     40#include <abi/sysinfo.h>
    3941
    40 /** Sysinfo value types
    41  *
    42  */
    43 typedef enum {
    44         SYSINFO_VAL_UNDEFINED = 0,
    45         SYSINFO_VAL_VAL = 1,
    46         SYSINFO_VAL_DATA = 2
    47 } sysinfo_item_tag_t;
    48 
    49 extern sysinfo_item_tag_t sysinfo_get_tag(const char *);
     42extern sysinfo_item_val_type_t sysinfo_get_val_type(const char *);
    5043extern int sysinfo_get_value(const char *, sysarg_t *);
    5144extern void *sysinfo_get_data(const char *, size_t *);
  • uspace/lib/c/include/task.h

    rbb74dabe rc05642d  
    3737
    3838#include <sys/types.h>
    39 
    40 typedef uint64_t task_id_t;
     39#include <abi/proc/task.h>
    4140
    4241typedef enum {
  • uspace/lib/c/include/thread.h

    rbb74dabe rc05642d  
    3838#include <libarch/thread.h>
    3939#include <sys/types.h>
    40 
    41 typedef uint64_t thread_id_t;
     40#include <abi/proc/thread.h>
    4241
    4342extern int thread_create(void (*)(void *), void *, const char *, thread_id_t *);
  • uspace/lib/drv/generic/driver.c

    rbb74dabe rc05642d  
    6363
    6464/** Devices */
     65LIST_INITIALIZE(devices);
     66FIBRIL_MUTEX_INITIALIZE(devices_mutex);
     67
     68/** Functions */
    6569LIST_INITIALIZE(functions);
    6670FIBRIL_MUTEX_INITIALIZE(functions_mutex);
     
    8286static ddf_dev_t *create_device(void);
    8387static void delete_device(ddf_dev_t *);
     88static void dev_add_ref(ddf_dev_t *);
     89static void dev_del_ref(ddf_dev_t *);
     90static void fun_add_ref(ddf_fun_t *);
     91static void fun_del_ref(ddf_fun_t *);
    8492static remote_handler_t *function_get_default_handler(ddf_fun_t *);
    8593static void *function_get_ops(ddf_fun_t *, dev_inferface_idx_t);
     
    227235}
    228236
    229 static ddf_fun_t *driver_get_function(list_t *functions, devman_handle_t handle)
     237static ddf_dev_t *driver_get_device(devman_handle_t handle)
     238{
     239        ddf_dev_t *dev = NULL;
     240       
     241        assert(fibril_mutex_is_locked(&devices_mutex));
     242       
     243        list_foreach(devices, link) {
     244                dev = list_get_instance(link, ddf_dev_t, link);
     245                if (dev->handle == handle)
     246                        return dev;
     247        }
     248       
     249        return NULL;
     250}
     251
     252static ddf_fun_t *driver_get_function(devman_handle_t handle)
    230253{
    231254        ddf_fun_t *fun = NULL;
    232255       
    233         fibril_mutex_lock(&functions_mutex);
    234        
    235         list_foreach(*functions, link) {
     256        assert(fibril_mutex_is_locked(&functions_mutex));
     257       
     258        list_foreach(functions, link) {
    236259                fun = list_get_instance(link, ddf_fun_t, link);
    237                 if (fun->handle == handle) {
    238                         fibril_mutex_unlock(&functions_mutex);
     260                if (fun->handle == handle)
    239261                        return fun;
    240                 }
    241         }
    242        
    243         fibril_mutex_unlock(&functions_mutex);
     262        }
    244263       
    245264        return NULL;
    246265}
    247266
    248 static void driver_add_device(ipc_callid_t iid, ipc_call_t *icall)
     267static void driver_dev_add(ipc_callid_t iid, ipc_call_t *icall)
    249268{
    250269        char *dev_name = NULL;
     
    255274       
    256275        ddf_dev_t *dev = create_device();
     276
     277        /* Add one reference that will be dropped by driver_dev_remove() */
     278        dev_add_ref(dev);
    257279        dev->handle = dev_handle;
    258280
     
    267289       
    268290        res = driver->driver_ops->add_device(dev);
    269         if (res != EOK)
    270                 delete_device(dev);
     291       
     292        if (res != EOK) {
     293                dev_del_ref(dev);
     294                async_answer_0(iid, res);
     295                return;
     296        }
     297       
     298        fibril_mutex_lock(&devices_mutex);
     299        list_append(&dev->link, &devices);
     300        fibril_mutex_unlock(&devices_mutex);
    271301       
    272302        async_answer_0(iid, res);
     303}
     304
     305static void driver_dev_remove(ipc_callid_t iid, ipc_call_t *icall)
     306{
     307        devman_handle_t devh;
     308        ddf_dev_t *dev;
     309        int rc;
     310       
     311        devh = IPC_GET_ARG1(*icall);
     312       
     313        fibril_mutex_lock(&devices_mutex);
     314        dev = driver_get_device(devh);
     315        if (dev != NULL)
     316                dev_add_ref(dev);
     317        fibril_mutex_unlock(&devices_mutex);
     318       
     319        if (dev == NULL) {
     320                async_answer_0(iid, ENOENT);
     321                return;
     322        }
     323       
     324        if (driver->driver_ops->dev_remove != NULL)
     325                rc = driver->driver_ops->dev_remove(dev);
     326        else
     327                rc = ENOTSUP;
     328       
     329        if (rc == EOK)
     330                dev_del_ref(dev);
     331       
     332        async_answer_0(iid, (sysarg_t) rc);
     333}
     334
     335static void driver_dev_gone(ipc_callid_t iid, ipc_call_t *icall)
     336{
     337        devman_handle_t devh;
     338        ddf_dev_t *dev;
     339        int rc;
     340       
     341        devh = IPC_GET_ARG1(*icall);
     342       
     343        fibril_mutex_lock(&devices_mutex);
     344        dev = driver_get_device(devh);
     345        if (dev != NULL)
     346                dev_add_ref(dev);
     347        fibril_mutex_unlock(&devices_mutex);
     348       
     349        if (dev == NULL) {
     350                async_answer_0(iid, ENOENT);
     351                return;
     352        }
     353       
     354        if (driver->driver_ops->dev_gone != NULL)
     355                rc = driver->driver_ops->dev_gone(dev);
     356        else
     357                rc = ENOTSUP;
     358       
     359        if (rc == EOK)
     360                dev_del_ref(dev);
     361       
     362        async_answer_0(iid, (sysarg_t) rc);
     363}
     364
     365static void driver_fun_online(ipc_callid_t iid, ipc_call_t *icall)
     366{
     367        devman_handle_t funh;
     368        ddf_fun_t *fun;
     369        int rc;
     370       
     371        funh = IPC_GET_ARG1(*icall);
     372       
     373        /*
     374         * Look the function up. Bump reference count so that
     375         * the function continues to exist until we return
     376         * from the driver.
     377         */
     378        fibril_mutex_lock(&functions_mutex);
     379       
     380        fun = driver_get_function(funh);
     381        if (fun != NULL)
     382                fun_add_ref(fun);
     383       
     384        fibril_mutex_unlock(&functions_mutex);
     385       
     386        if (fun == NULL) {
     387                async_answer_0(iid, ENOENT);
     388                return;
     389        }
     390       
     391        /* Call driver entry point */
     392        if (driver->driver_ops->fun_online != NULL)
     393                rc = driver->driver_ops->fun_online(fun);
     394        else
     395                rc = ENOTSUP;
     396       
     397        fun_del_ref(fun);
     398       
     399        async_answer_0(iid, (sysarg_t) rc);
     400}
     401
     402static void driver_fun_offline(ipc_callid_t iid, ipc_call_t *icall)
     403{
     404        devman_handle_t funh;
     405        ddf_fun_t *fun;
     406        int rc;
     407       
     408        funh = IPC_GET_ARG1(*icall);
     409       
     410        /*
     411         * Look the function up. Bump reference count so that
     412         * the function continues to exist until we return
     413         * from the driver.
     414         */
     415        fibril_mutex_lock(&functions_mutex);
     416       
     417        fun = driver_get_function(funh);
     418        if (fun != NULL)
     419                fun_add_ref(fun);
     420       
     421        fibril_mutex_unlock(&functions_mutex);
     422       
     423        if (fun == NULL) {
     424                async_answer_0(iid, ENOENT);
     425                return;
     426        }
     427       
     428        /* Call driver entry point */
     429        if (driver->driver_ops->fun_offline != NULL)
     430                rc = driver->driver_ops->fun_offline(fun);
     431        else
     432                rc = ENOTSUP;
     433       
     434        async_answer_0(iid, (sysarg_t) rc);
    273435}
    274436
     
    286448               
    287449                switch (IPC_GET_IMETHOD(call)) {
    288                 case DRIVER_ADD_DEVICE:
    289                         driver_add_device(callid, &call);
     450                case DRIVER_DEV_ADD:
     451                        driver_dev_add(callid, &call);
     452                        break;
     453                case DRIVER_DEV_REMOVE:
     454                        driver_dev_remove(callid, &call);
     455                        break;
     456                case DRIVER_DEV_GONE:
     457                        driver_dev_gone(callid, &call);
     458                        break;
     459                case DRIVER_FUN_ONLINE:
     460                        driver_fun_online(callid, &call);
     461                        break;
     462                case DRIVER_FUN_OFFLINE:
     463                        driver_fun_offline(callid, &call);
    290464                        break;
    291465                default:
    292                         async_answer_0(callid, ENOENT);
     466                        async_answer_0(callid, ENOTSUP);
    293467                }
    294468        }
     
    308482         */
    309483        devman_handle_t handle = IPC_GET_ARG2(*icall);
    310         ddf_fun_t *fun = driver_get_function(&functions, handle);
     484
     485        fibril_mutex_lock(&functions_mutex);
     486        ddf_fun_t *fun = driver_get_function(handle);
     487        fibril_mutex_unlock(&functions_mutex);
     488        /* XXX Need a lock on fun */
    311489       
    312490        if (fun == NULL) {
     
    466644        ddf_dev_t *dev;
    467645
    468         dev = malloc(sizeof(ddf_dev_t));
     646        dev = calloc(1, sizeof(ddf_dev_t));
    469647        if (dev == NULL)
    470648                return NULL;
    471649
    472         memset(dev, 0, sizeof(ddf_dev_t));
    473650        return dev;
    474651}
     
    498675static void delete_device(ddf_dev_t *dev)
    499676{
     677        if (dev->driver_data != NULL)
     678                free(dev->driver_data);
    500679        free(dev);
    501680}
    502681
    503 /** Delete device structure.
     682/** Delete function structure.
    504683 *
    505684 * @param dev           The device structure.
     
    508687{
    509688        clean_match_ids(&fun->match_ids);
     689        if (fun->driver_data != NULL)
     690                free(fun->driver_data);
    510691        if (fun->name != NULL)
    511692                free(fun->name);
     
    513694}
    514695
     696/** Increase device reference count. */
     697static void dev_add_ref(ddf_dev_t *dev)
     698{
     699        atomic_inc(&dev->refcnt);
     700}
     701
     702/** Decrease device reference count.
     703 *
     704 * Free the device structure if the reference count drops to zero.
     705 */
     706static void dev_del_ref(ddf_dev_t *dev)
     707{
     708        if (atomic_predec(&dev->refcnt) == 0)
     709                delete_device(dev);
     710}
     711
     712/** Increase function reference count.
     713 *
     714 * This also increases reference count on the device. The device structure
     715 * will thus not be deallocated while there are some associated function
     716 * structures.
     717 */
     718static void fun_add_ref(ddf_fun_t *fun)
     719{
     720        dev_add_ref(fun->dev);
     721        atomic_inc(&fun->refcnt);
     722}
     723
     724/** Decrease function reference count.
     725 *
     726 * Free the function structure if the reference count drops to zero.
     727 */
     728static void fun_del_ref(ddf_fun_t *fun)
     729{
     730        ddf_dev_t *dev = fun->dev;
     731
     732        if (atomic_predec(&fun->refcnt) == 0)
     733                delete_function(fun);
     734
     735        dev_del_ref(dev);
     736}
     737
     738/** Allocate driver-specific device data. */
     739extern void *ddf_dev_data_alloc(ddf_dev_t *dev, size_t size)
     740{
     741        void *data;
     742
     743        assert(dev->driver_data == NULL);
     744
     745        data = calloc(1, size);
     746        if (data == NULL)
     747                return NULL;
     748
     749        dev->driver_data = data;
     750        return data;
     751}
     752
    515753/** Create a DDF function node.
    516754 *
     
    544782                return NULL;
    545783
     784        /* Add one reference that will be dropped by ddf_fun_destroy() */
     785        fun->dev = dev;
     786        fun_add_ref(fun);
     787
    546788        fun->bound = false;
    547         fun->dev = dev;
    548789        fun->ftype = ftype;
    549790
     
    557798}
    558799
     800/** Allocate driver-specific function data. */
     801extern void *ddf_fun_data_alloc(ddf_fun_t *fun, size_t size)
     802{
     803        void *data;
     804
     805        assert(fun->bound == false);
     806        assert(fun->driver_data == NULL);
     807
     808        data = calloc(1, size);
     809        if (data == NULL)
     810                return NULL;
     811
     812        fun->driver_data = data;
     813        return data;
     814}
     815
    559816/** Destroy DDF function node.
    560817 *
     
    567824{
    568825        assert(fun->bound == false);
    569         delete_function(fun);
     826
     827        /*
     828         * Drop the reference added by ddf_fun_create(). This will deallocate
     829         * the function as soon as all other references are dropped (i.e.
     830         * as soon control leaves all driver entry points called in context
     831         * of this function.
     832         */
     833        fun_del_ref(fun);
    570834}
    571835
     
    614878 * the function invisible to the system.
    615879 *
    616  * @param fun           Function to bind
     880 * @param fun           Function to unbind
    617881 * @return              EOK on success or negative error code
    618882 */
     
    623887        assert(fun->bound == true);
    624888       
    625         add_to_functions_list(fun);
    626889        res = devman_remove_function(fun->handle);
    627890        if (res != EOK)
     
    631894       
    632895        fun->bound = false;
     896        return EOK;
     897}
     898
     899/** Online function.
     900 *
     901 * @param fun           Function to online
     902 * @return              EOK on success or negative error code
     903 */
     904int ddf_fun_online(ddf_fun_t *fun)
     905{
     906        int res;
     907       
     908        assert(fun->bound == true);
     909       
     910        res = devman_drv_fun_online(fun->handle);
     911        if (res != EOK)
     912                return res;
     913       
     914        return EOK;
     915}
     916
     917/** Offline function.
     918 *
     919 * @param fun           Function to offline
     920 * @return              EOK on success or negative error code
     921 */
     922int ddf_fun_offline(ddf_fun_t *fun)
     923{
     924        int res;
     925       
     926        assert(fun->bound == true);
     927       
     928        res = devman_drv_fun_offline(fun->handle);
     929        if (res != EOK)
     930                return res;
     931       
    633932        return EOK;
    634933}
  • uspace/lib/drv/include/ddf/driver.h

    rbb74dabe rc05642d  
    8181         */
    8282        devman_handle_t handle;
     83        /** Reference count */
     84        atomic_t refcnt;
    8385       
    8486        /**
     
    104106        /** Function indentifier (asigned by device manager) */
    105107        devman_handle_t handle;
     108        /** Reference count */
     109        atomic_t refcnt;
    106110       
    107111        /** Device which this function belogs to */
     
    132136typedef struct driver_ops {
    133137        /** Callback method for passing a new device to the device driver */
    134         int (*add_device)(ddf_dev_t *dev);
    135         /* TODO: add other generic driver operations */
     138        int (*add_device)(ddf_dev_t *);
     139        /** Ask driver to remove a device */
     140        int (*dev_remove)(ddf_dev_t *);
     141        /** Inform driver a device disappeared */
     142        int (*dev_gone)(ddf_dev_t *);
     143        /** Ask driver to online a specific function */
     144        int (*fun_online)(ddf_fun_t *);
     145        /** Ask driver to offline a specific function */
     146        int (*fun_offline)(ddf_fun_t *);
    136147} driver_ops_t;
    137148
     
    146157extern int ddf_driver_main(driver_t *);
    147158
     159extern void *ddf_dev_data_alloc(ddf_dev_t *, size_t);
    148160extern ddf_fun_t *ddf_fun_create(ddf_dev_t *, fun_type_t, const char *);
    149161extern void ddf_fun_destroy(ddf_fun_t *);
     162extern void *ddf_fun_data_alloc(ddf_fun_t *, size_t);
    150163extern int ddf_fun_bind(ddf_fun_t *);
    151164extern int ddf_fun_unbind(ddf_fun_t *);
     165extern int ddf_fun_online(ddf_fun_t *);
     166extern int ddf_fun_offline(ddf_fun_t *);
    152167extern int ddf_fun_add_match_id(ddf_fun_t *, const char *, int);
    153168
  • uspace/lib/fs/libfs.c

    rbb74dabe rc05642d  
    837837        stat.is_directory = ops->is_directory(fn);
    838838        stat.size = ops->size_get(fn);
    839         stat.service = ops->device_get(fn);
     839        stat.service = ops->service_get(fn);
    840840       
    841841        ops->node_put(fn);
  • uspace/lib/fs/libfs.h

    rbb74dabe rc05642d  
    9292        bool (* is_directory)(fs_node_t *);
    9393        bool (* is_file)(fs_node_t *);
    94         service_id_t (* device_get)(fs_node_t *);
     94        service_id_t (* service_get)(fs_node_t *);
    9595} libfs_ops_t;
    9696
Note: See TracChangeset for help on using the changeset viewer.