Changeset c05642d in mainline for uspace/lib
- Timestamp:
- 2011-09-07T00:03:26Z (14 years ago)
- 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. - Location:
- uspace/lib
- Files:
-
- 1 added
- 20 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/block/libblock.c
rbb74dabe rc05642d 891 891 } 892 892 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 */ 902 toc_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 893 930 /** Read blocks from block device. 894 931 * -
uspace/lib/block/libblock.h
rbb74dabe rc05642d 97 97 }; 98 98 99 typedef 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 99 112 extern int block_init(exch_mgmt_t, service_id_t, size_t); 100 113 extern void block_fini(service_id_t); … … 114 127 extern int block_get_bsize(service_id_t, size_t *); 115 128 extern int block_get_nblocks(service_id_t, aoff64_t *); 129 extern toc_block_t *block_get_toc(service_id_t, uint8_t); 116 130 extern int block_read_direct(service_id_t, aoff64_t, size_t, void *); 117 131 extern int block_read_bytes_direct(service_id_t, aoff64_t, size_t, void *); … … 122 136 /** @} 123 137 */ 124 -
uspace/lib/c/generic/async.c
rbb74dabe rc05642d 1777 1777 int async_hangup(async_sess_t *sess) 1778 1778 { 1779 async_exch_t *exch; 1780 1779 1781 assert(sess); 1780 1782 1781 1783 if (atomic_get(&sess->refcnt) > 0) 1782 1784 return EBUSY; 1785 1786 fibril_mutex_lock(&async_sess_mutex); 1783 1787 1784 1788 int rc = async_hangup_internal(sess->phone); 1785 1789 if (rc == EOK) 1786 1790 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); 1787 1804 1788 1805 return rc; -
uspace/lib/c/generic/devman.c
rbb74dabe rc05642d 327 327 } 328 328 329 int 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 341 int 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 329 353 async_sess_t *devman_parent_device_connect(exch_mgmt_t mgmt, 330 354 devman_handle_t handle, unsigned int flags) … … 430 454 } 431 455 456 int 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 468 int 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 432 480 static int devman_get_handles_once(sysarg_t method, sysarg_t arg1, 433 481 devman_handle_t *handle_buf, size_t buf_size, size_t *act_size) -
uspace/lib/c/generic/io/printf_core.c
rbb74dabe rc05642d 73 73 */ 74 74 #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 }) 75 94 76 95 /** Enumeration of possible arguments types. … … 831 850 size_t size; 832 851 uint64_t number; 852 833 853 switch (qualifier) { 834 854 case PrintfQualifierByte: 835 855 size = sizeof(unsigned char); 836 number = (uint64_t) va_arg(ap, unsigned int);856 number = PRINTF_GET_INT_ARGUMENT(int, ap, flags); 837 857 break; 838 858 case PrintfQualifierShort: 839 859 size = sizeof(unsigned short); 840 number = (uint64_t) va_arg(ap, unsigned int);860 number = PRINTF_GET_INT_ARGUMENT(int, ap, flags); 841 861 break; 842 862 case PrintfQualifierInt: 843 863 size = sizeof(unsigned int); 844 number = (uint64_t) va_arg(ap, unsigned int);864 number = PRINTF_GET_INT_ARGUMENT(int, ap, flags); 845 865 break; 846 866 case PrintfQualifierLong: 847 867 size = sizeof(unsigned long); 848 number = (uint64_t) va_arg(ap, unsigned long);868 number = PRINTF_GET_INT_ARGUMENT(long, ap, flags); 849 869 break; 850 870 case PrintfQualifierLongLong: 851 871 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); 853 873 break; 854 874 case PrintfQualifierPointer: … … 865 885 counter = -counter; 866 886 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 }883 887 } 884 888 -
uspace/lib/c/generic/str.c
rbb74dabe rc05642d 3 3 * Copyright (c) 2008 Jiri Svoboda 4 4 * Copyright (c) 2011 Martin Sucha 5 * Copyright (c) 2011 Oleg Romanenko 5 6 * All rights reserved. 6 7 * … … 550 551 * 551 552 * Common legacy text encoding in hardware is 7-bit ASCII fitted into 552 * a fixed-wi th byte buffer (bit 7 always zero), right-padded with spaces553 * a fixed-width byte buffer (bit 7 always zero), right-padded with spaces 553 554 * (ASCII 0x20). Convert space-padded ascii to string representation. 554 555 * … … 639 640 dest[dest_off] = '\0'; 640 641 } 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 */ 655 int 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 686 int 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 641 720 642 721 /** Convert wide string to new string. … … 1036 1115 return dest; 1037 1116 } 1038 1039 1117 1040 1118 /** Convert initial part of string to unsigned long according to given base. … … 1213 1291 } 1214 1292 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 */ 1305 int 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 */ 1352 int 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 */ 1399 int 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 1215 1434 /** Convert string to uint64_t. 1216 1435 * -
uspace/lib/c/generic/sysinfo.c
rbb74dabe rc05642d 47 47 * 48 48 */ 49 sysinfo_item_ tag_t sysinfo_get_tag(const char *path)49 sysinfo_item_val_type_t sysinfo_get_val_type(const char *path) 50 50 { 51 return (sysinfo_item_ tag_t) __SYSCALL2(SYS_SYSINFO_GET_TAG,51 return (sysinfo_item_val_type_t) __SYSCALL2(SYS_SYSINFO_GET_VAL_TYPE, 52 52 (sysarg_t) path, (sysarg_t) str_size(path)); 53 53 } -
uspace/lib/c/include/bool.h
rbb74dabe rc05642d 37 37 38 38 #include <libarch/types.h> 39 #include <abi/bool.h> 39 40 40 41 #define false 0 41 42 #define true 1 42 43 typedef uint8_t bool;44 43 45 44 #endif -
uspace/lib/c/include/devman.h
rbb74dabe rc05642d 50 50 devman_handle_t, devman_handle_t *); 51 51 extern int devman_remove_function(devman_handle_t); 52 extern int devman_drv_fun_online(devman_handle_t); 53 extern int devman_drv_fun_offline(devman_handle_t); 52 54 53 55 extern async_sess_t *devman_device_connect(exch_mgmt_t, devman_handle_t, … … 63 65 extern int devman_fun_get_name(devman_handle_t, char *, size_t); 64 66 extern int devman_fun_get_path(devman_handle_t, char *, size_t); 67 extern int devman_fun_online(devman_handle_t); 68 extern int devman_fun_offline(devman_handle_t); 65 69 66 70 extern int devman_add_device_to_category(devman_handle_t, const char *); -
uspace/lib/c/include/errno.h
rbb74dabe rc05642d 55 55 #define EIO (-265) 56 56 #define EMLINK (-266) 57 #define ENXIO (-267) 57 58 58 59 /** Bad checksum. */ -
uspace/lib/c/include/ipc/bd.h
rbb74dabe rc05642d 42 42 BD_GET_NUM_BLOCKS, 43 43 BD_READ_BLOCKS, 44 BD_WRITE_BLOCKS 44 BD_WRITE_BLOCKS, 45 BD_READ_TOC 45 46 } bd_request_t; 46 47 -
uspace/lib/c/include/ipc/devman.h
rbb74dabe rc05642d 139 139 DEVMAN_ADD_MATCH_ID, 140 140 DEVMAN_ADD_DEVICE_TO_CATEGORY, 141 DEVMAN_DRV_FUN_ONLINE, 142 DEVMAN_DRV_FUN_OFFLINE, 141 143 DEVMAN_REMOVE_FUNCTION 142 144 } driver_to_devman_t; 143 145 144 146 typedef 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, 147 152 } devman_to_driver_t; 148 153 … … 152 157 DEVMAN_FUN_GET_CHILD, 153 158 DEVMAN_FUN_GET_NAME, 159 DEVMAN_FUN_ONLINE, 160 DEVMAN_FUN_OFFLINE, 154 161 DEVMAN_FUN_GET_PATH, 155 162 DEVMAN_FUN_SID_TO_HANDLE -
uspace/lib/c/include/str.h
rbb74dabe rc05642d 1 1 /* 2 2 * Copyright (c) 2005 Martin Decky 3 * Copyright (c) 2011 Oleg Romanenko 3 4 * All rights reserved. 4 5 * … … 84 85 extern void str_to_wstr(wchar_t *dest, size_t dlen, const char *src); 85 86 extern wchar_t *str_to_awstr(const char *src); 87 extern int utf16_to_str(char *dest, size_t size, const uint16_t *src); 88 extern int str_to_utf16(uint16_t *dest, size_t size, const char *src); 86 89 87 90 extern char *str_chr(const char *str, wchar_t ch); … … 94 97 extern char *str_ndup(const char *, size_t max_size); 95 98 99 extern int str_uint8_t(const char *, char **, unsigned int, bool, uint8_t *); 100 extern int str_uint16_t(const char *, char **, unsigned int, bool, uint16_t *); 101 extern int str_uint32_t(const char *, char **, unsigned int, bool, uint32_t *); 96 102 extern int str_uint64(const char *, char **, unsigned int, bool, uint64_t *); 97 103 extern int str_size_t(const char *, char **, unsigned int, bool, size_t *); -
uspace/lib/c/include/sysinfo.h
rbb74dabe rc05642d 36 36 #define LIBC_SYSINFO_H_ 37 37 38 #include <libc.h> 38 #include <sys/types.h> 39 #include <bool.h> 40 #include <abi/sysinfo.h> 39 41 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 *); 42 extern sysinfo_item_val_type_t sysinfo_get_val_type(const char *); 50 43 extern int sysinfo_get_value(const char *, sysarg_t *); 51 44 extern void *sysinfo_get_data(const char *, size_t *); -
uspace/lib/c/include/task.h
rbb74dabe rc05642d 37 37 38 38 #include <sys/types.h> 39 40 typedef uint64_t task_id_t; 39 #include <abi/proc/task.h> 41 40 42 41 typedef enum { -
uspace/lib/c/include/thread.h
rbb74dabe rc05642d 38 38 #include <libarch/thread.h> 39 39 #include <sys/types.h> 40 41 typedef uint64_t thread_id_t; 40 #include <abi/proc/thread.h> 42 41 43 42 extern int thread_create(void (*)(void *), void *, const char *, thread_id_t *); -
uspace/lib/drv/generic/driver.c
rbb74dabe rc05642d 63 63 64 64 /** Devices */ 65 LIST_INITIALIZE(devices); 66 FIBRIL_MUTEX_INITIALIZE(devices_mutex); 67 68 /** Functions */ 65 69 LIST_INITIALIZE(functions); 66 70 FIBRIL_MUTEX_INITIALIZE(functions_mutex); … … 82 86 static ddf_dev_t *create_device(void); 83 87 static void delete_device(ddf_dev_t *); 88 static void dev_add_ref(ddf_dev_t *); 89 static void dev_del_ref(ddf_dev_t *); 90 static void fun_add_ref(ddf_fun_t *); 91 static void fun_del_ref(ddf_fun_t *); 84 92 static remote_handler_t *function_get_default_handler(ddf_fun_t *); 85 93 static void *function_get_ops(ddf_fun_t *, dev_inferface_idx_t); … … 227 235 } 228 236 229 static ddf_fun_t *driver_get_function(list_t *functions, devman_handle_t handle) 237 static 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 252 static ddf_fun_t *driver_get_function(devman_handle_t handle) 230 253 { 231 254 ddf_fun_t *fun = NULL; 232 255 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) { 236 259 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) 239 261 return fun; 240 } 241 } 242 243 fibril_mutex_unlock(&functions_mutex); 262 } 244 263 245 264 return NULL; 246 265 } 247 266 248 static void driver_ add_device(ipc_callid_t iid, ipc_call_t *icall)267 static void driver_dev_add(ipc_callid_t iid, ipc_call_t *icall) 249 268 { 250 269 char *dev_name = NULL; … … 255 274 256 275 ddf_dev_t *dev = create_device(); 276 277 /* Add one reference that will be dropped by driver_dev_remove() */ 278 dev_add_ref(dev); 257 279 dev->handle = dev_handle; 258 280 … … 267 289 268 290 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); 271 301 272 302 async_answer_0(iid, res); 303 } 304 305 static 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 335 static 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 365 static 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 402 static 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); 273 435 } 274 436 … … 286 448 287 449 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); 290 464 break; 291 465 default: 292 async_answer_0(callid, ENO ENT);466 async_answer_0(callid, ENOTSUP); 293 467 } 294 468 } … … 308 482 */ 309 483 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 */ 311 489 312 490 if (fun == NULL) { … … 466 644 ddf_dev_t *dev; 467 645 468 dev = malloc(sizeof(ddf_dev_t));646 dev = calloc(1, sizeof(ddf_dev_t)); 469 647 if (dev == NULL) 470 648 return NULL; 471 649 472 memset(dev, 0, sizeof(ddf_dev_t));473 650 return dev; 474 651 } … … 498 675 static void delete_device(ddf_dev_t *dev) 499 676 { 677 if (dev->driver_data != NULL) 678 free(dev->driver_data); 500 679 free(dev); 501 680 } 502 681 503 /** Delete devicestructure.682 /** Delete function structure. 504 683 * 505 684 * @param dev The device structure. … … 508 687 { 509 688 clean_match_ids(&fun->match_ids); 689 if (fun->driver_data != NULL) 690 free(fun->driver_data); 510 691 if (fun->name != NULL) 511 692 free(fun->name); … … 513 694 } 514 695 696 /** Increase device reference count. */ 697 static 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 */ 706 static 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 */ 718 static 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 */ 728 static 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. */ 739 extern 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 515 753 /** Create a DDF function node. 516 754 * … … 544 782 return NULL; 545 783 784 /* Add one reference that will be dropped by ddf_fun_destroy() */ 785 fun->dev = dev; 786 fun_add_ref(fun); 787 546 788 fun->bound = false; 547 fun->dev = dev;548 789 fun->ftype = ftype; 549 790 … … 557 798 } 558 799 800 /** Allocate driver-specific function data. */ 801 extern 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 559 816 /** Destroy DDF function node. 560 817 * … … 567 824 { 568 825 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); 570 834 } 571 835 … … 614 878 * the function invisible to the system. 615 879 * 616 * @param fun Function to bind880 * @param fun Function to unbind 617 881 * @return EOK on success or negative error code 618 882 */ … … 623 887 assert(fun->bound == true); 624 888 625 add_to_functions_list(fun);626 889 res = devman_remove_function(fun->handle); 627 890 if (res != EOK) … … 631 894 632 895 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 */ 904 int 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 */ 922 int 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 633 932 return EOK; 634 933 } -
uspace/lib/drv/include/ddf/driver.h
rbb74dabe rc05642d 81 81 */ 82 82 devman_handle_t handle; 83 /** Reference count */ 84 atomic_t refcnt; 83 85 84 86 /** … … 104 106 /** Function indentifier (asigned by device manager) */ 105 107 devman_handle_t handle; 108 /** Reference count */ 109 atomic_t refcnt; 106 110 107 111 /** Device which this function belogs to */ … … 132 136 typedef struct driver_ops { 133 137 /** 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 *); 136 147 } driver_ops_t; 137 148 … … 146 157 extern int ddf_driver_main(driver_t *); 147 158 159 extern void *ddf_dev_data_alloc(ddf_dev_t *, size_t); 148 160 extern ddf_fun_t *ddf_fun_create(ddf_dev_t *, fun_type_t, const char *); 149 161 extern void ddf_fun_destroy(ddf_fun_t *); 162 extern void *ddf_fun_data_alloc(ddf_fun_t *, size_t); 150 163 extern int ddf_fun_bind(ddf_fun_t *); 151 164 extern int ddf_fun_unbind(ddf_fun_t *); 165 extern int ddf_fun_online(ddf_fun_t *); 166 extern int ddf_fun_offline(ddf_fun_t *); 152 167 extern int ddf_fun_add_match_id(ddf_fun_t *, const char *, int); 153 168 -
uspace/lib/fs/libfs.c
rbb74dabe rc05642d 837 837 stat.is_directory = ops->is_directory(fn); 838 838 stat.size = ops->size_get(fn); 839 stat.service = ops-> device_get(fn);839 stat.service = ops->service_get(fn); 840 840 841 841 ops->node_put(fn); -
uspace/lib/fs/libfs.h
rbb74dabe rc05642d 92 92 bool (* is_directory)(fs_node_t *); 93 93 bool (* is_file)(fs_node_t *); 94 service_id_t (* device_get)(fs_node_t *);94 service_id_t (* service_get)(fs_node_t *); 95 95 } libfs_ops_t; 96 96
Note:
See TracChangeset
for help on using the changeset viewer.