Changeset 84439d7 in mainline for uspace/lib
- Timestamp:
- 2010-12-05T09:34:46Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 75732da
- Parents:
- 56b962d (diff), 35537a7 (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:
-
- 3 added
- 34 edited
-
block/libblock.c (modified) (19 diffs)
-
block/libblock.h (modified) (1 diff)
-
c/arch/abs32le/include/inttypes.h (modified) (1 diff)
-
c/arch/amd64/include/inttypes.h (modified) (1 diff)
-
c/arch/arm32/include/inttypes.h (modified) (1 diff)
-
c/arch/ia32/include/inttypes.h (modified) (1 diff)
-
c/arch/ia64/include/inttypes.h (modified) (1 diff)
-
c/arch/mips32/include/inttypes.h (modified) (1 diff)
-
c/arch/ppc32/include/inttypes.h (modified) (1 diff)
-
c/arch/sparc64/include/inttypes.h (modified) (1 diff)
-
c/generic/device/char.c (modified) (3 diffs)
-
c/generic/io/printf_core.c (modified) (5 diffs)
-
c/generic/stacktrace.c (modified) (1 diff)
-
c/generic/str.c (modified) (1 diff)
-
c/include/assert.h (modified) (1 diff)
-
c/include/device/char.h (modified) (3 diffs)
-
c/include/err.h (modified) (2 diffs)
-
c/include/malloc.h (modified) (1 diff)
-
c/include/stdint.h (modified) (1 diff)
-
c/include/stdio.h (modified) (2 diffs)
-
c/include/str.h (modified) (1 diff)
-
c/include/sys/typefmt.h (modified) (2 diffs)
-
c/include/sys/types.h (modified) (1 diff)
-
drv/generic/driver.c (modified) (6 diffs)
-
drv/generic/remote_usbhc.c (modified) (8 diffs)
-
drv/include/usbhc_iface.h (modified) (3 diffs)
-
usb/Makefile (modified) (1 diff)
-
usb/include/usb/classes/hub.h (modified) (2 diffs)
-
usb/include/usb/hcdhubd.h (modified) (6 diffs)
-
usb/include/usb/usbdrv.h (modified) (2 diffs)
-
usb/src/hcdhubd.c (modified) (5 diffs)
-
usb/src/hcdhubd_private.h (added)
-
usb/src/hcdrv.c (added)
-
usb/src/localdrv.c (modified) (1 diff)
-
usb/src/remotedrv.c (added)
-
usb/src/usbdrv.c (modified) (4 diffs)
-
usbvirt/src/debug.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/block/libblock.c
r56b962d r84439d7 66 66 fibril_mutex_t lock; 67 67 size_t lblock_size; /**< Logical block size. */ 68 unsigned blocks_cluster; /**< Physical blocks per block_t */ 68 69 unsigned block_count; /**< Total number of blocks. */ 69 70 unsigned blocks_cached; /**< Number of cached blocks. */ … … 90 91 static int get_block_size(int dev_phone, size_t *bsize); 91 92 static int get_num_blocks(int dev_phone, aoff64_t *nblocks); 93 static aoff64_t ba_ltop(devcon_t *devcon, aoff64_t lba); 92 94 93 95 static devcon_t *devcon_search(devmap_handle_t devmap_handle) … … 259 261 { 260 262 block_t *b = hash_table_get_instance(item, block_t, hash_link); 261 return b-> boff== *key;263 return b->lba == *key; 262 264 } 263 265 … … 292 294 cache->mode = mode; 293 295 294 /* No block size translation a.t.m. */ 295 assert(cache->lblock_size == devcon->pblock_size); 296 /* Allow 1:1 or small-to-large block size translation */ 297 if (cache->lblock_size % devcon->pblock_size != 0) 298 return ENOTSUP; 299 300 cache->blocks_cluster = cache->lblock_size / devcon->pblock_size; 296 301 297 302 if (!hash_table_create(&cache->block_hash, CACHE_BUCKETS, 1, … … 329 334 if (b->dirty) { 330 335 memcpy(devcon->comm_area, b->data, b->size); 331 rc = write_blocks(devcon, b-> boff, 1);336 rc = write_blocks(devcon, b->pba, cache->blocks_cluster); 332 337 if (rc != EOK) 333 338 return rc; 334 339 } 335 340 336 unsigned long key = b-> boff;341 unsigned long key = b->lba; 337 342 hash_table_remove(&cache->block_hash, &key, 1); 338 343 … … 375 380 * block pointer on success. 376 381 * @param devmap_handle Device handle of the block device. 377 * @param b off Block offset.382 * @param ba Block address (logical). 378 383 * @param flags If BLOCK_FLAGS_NOREAD is specified, block_get() 379 384 * will not read the contents of the block from the … … 382 387 * @return EOK on success or a negative error code. 383 388 */ 384 int block_get(block_t **block, devmap_handle_t devmap_handle, aoff64_t b off, int flags)389 int block_get(block_t **block, devmap_handle_t devmap_handle, aoff64_t ba, int flags) 385 390 { 386 391 devcon_t *devcon; … … 388 393 block_t *b; 389 394 link_t *l; 390 unsigned long key = b off;395 unsigned long key = ba; 391 396 int rc; 392 397 … … 465 470 fibril_mutex_lock(&devcon->comm_area_lock); 466 471 memcpy(devcon->comm_area, b->data, b->size); 467 rc = write_blocks(devcon, b->boff, 1); 472 rc = write_blocks(devcon, b->pba, 473 cache->blocks_cluster); 468 474 fibril_mutex_unlock(&devcon->comm_area_lock); 469 475 if (rc != EOK) { … … 495 501 */ 496 502 list_remove(&b->free_link); 497 temp_key = b-> boff;503 temp_key = b->lba; 498 504 hash_table_remove(&cache->block_hash, &temp_key, 1); 499 505 } … … 502 508 b->devmap_handle = devmap_handle; 503 509 b->size = cache->lblock_size; 504 b->boff = boff; 510 b->lba = ba; 511 b->pba = ba_ltop(devcon, b->lba); 505 512 hash_table_insert(&cache->block_hash, &key, &b->hash_link); 506 513 … … 519 526 */ 520 527 fibril_mutex_lock(&devcon->comm_area_lock); 521 rc = read_blocks(devcon, b-> boff, 1);528 rc = read_blocks(devcon, b->pba, cache->blocks_cluster); 522 529 memcpy(b->data, devcon->comm_area, cache->lblock_size); 523 530 fibril_mutex_unlock(&devcon->comm_area_lock); … … 580 587 fibril_mutex_lock(&devcon->comm_area_lock); 581 588 memcpy(devcon->comm_area, block->data, block->size); 582 rc = write_blocks(devcon, block-> boff, 1);589 rc = write_blocks(devcon, block->pba, cache->blocks_cluster); 583 590 fibril_mutex_unlock(&devcon->comm_area_lock); 584 591 block->dirty = false; … … 614 621 * Take the block out of the cache and free it. 615 622 */ 616 unsigned long key = block-> boff;623 unsigned long key = block->lba; 617 624 hash_table_remove(&cache->block_hash, &key, 1); 618 625 free(block); … … 712 719 * 713 720 * @param devmap_handle Device handle of the block device. 714 * @param ba Address of first block .721 * @param ba Address of first block (physical). 715 722 * @param cnt Number of blocks. 716 723 * @param src Buffer for storing the data. … … 740 747 * 741 748 * @param devmap_handle Device handle of the block device. 742 * @param ba Address of first block .749 * @param ba Address of first block (physical). 743 750 * @param cnt Number of blocks. 744 751 * @param src The data to be written. … … 816 823 UPPER32(ba), cnt); 817 824 if (rc != EOK) { 818 printf("Error %d reading % dblocks starting at block %" PRIuOFF64819 " from device handle % d\n", rc, cnt, ba,825 printf("Error %d reading %zu blocks starting at block %" PRIuOFF64 826 " from device handle %" PRIun "\n", rc, cnt, ba, 820 827 devcon->devmap_handle); 821 828 #ifndef NDEBUG … … 843 850 UPPER32(ba), cnt); 844 851 if (rc != EOK) { 845 printf("Error %d writing % dblocks starting at block %" PRIuOFF64846 " to device handle % d\n", rc, cnt, ba, devcon->devmap_handle);852 printf("Error %d writing %zu blocks starting at block %" PRIuOFF64 853 " to device handle %" PRIun "\n", rc, cnt, ba, devcon->devmap_handle); 847 854 #ifndef NDEBUG 848 855 stacktrace_print(); … … 879 886 } 880 887 888 /** Convert logical block address to physical block address. */ 889 static aoff64_t ba_ltop(devcon_t *devcon, aoff64_t lba) 890 { 891 assert(devcon->cache != NULL); 892 return lba * devcon->cache->blocks_cluster; 893 } 894 881 895 /** @} 882 896 */ -
uspace/lib/block/libblock.h
r56b962d r84439d7 73 73 /** Handle of the device where the block resides. */ 74 74 devmap_handle_t devmap_handle; 75 /** Block offset on the block device. Counted in 'size'-byte blocks. */ 76 aoff64_t boff; 75 /** Logical block address */ 76 aoff64_t lba; 77 /** Physical block address */ 78 aoff64_t pba; 77 79 /** Size of the block. */ 78 80 size_t size; -
uspace/lib/c/arch/abs32le/include/inttypes.h
r56b962d r84439d7 34 34 #define LIBC_abs32le_INTTYPES_H_ 35 35 36 #define PRId8 "d" 37 #define PRId16 "d" 38 #define PRId32 "d" 39 #define PRId64 "lld" 40 #define PRIdPTR "d" 41 42 #define PRIo8 "o" 43 #define PRIo16 "o" 44 #define PRIo32 "o" 45 #define PRIo64 "llo" 46 #define PRIoPTR "o" 47 48 #define PRIu8 "u" 49 #define PRIu16 "u" 50 #define PRIu32 "u" 51 #define PRIu64 "llu" 52 #define PRIuPTR "u" 53 54 #define PRIx8 "x" 55 #define PRIx16 "x" 56 #define PRIx32 "x" 57 #define PRIx64 "llx" 58 #define PRIxPTR "x" 59 60 #define PRIX8 "X" 61 #define PRIX16 "X" 62 #define PRIX32 "X" 63 #define PRIX64 "llX" 64 #define PRIXPTR "X" 36 #define PRIdn PRId32 /**< Format for sysarg_t, ipcarg_t, etc. */ 37 #define PRIun PRIu32 /**< Format for sysarg_t, ipcarg_t, etc. */ 38 #define PRIxn PRIx32 /**< Format for hexadecimal sysarg_t, ipcarg_t, etc. */ 39 #define PRIua PRIu32 /**< Format for atomic_count_t. */ 65 40 66 41 #endif -
uspace/lib/c/arch/amd64/include/inttypes.h
r56b962d r84439d7 30 30 * @{ 31 31 */ 32 /** @file Macros for format specifiers.33 *34 * Macros for formatting stdint types as specified in section35 * 7.8.1 Macros for format specifiers of the C99 draft specification36 * (ISO/IEC 9899:201x). Only some macros from the specification are37 * implemented.38 */39 32 40 33 #ifndef LIBC_amd64_INTTYPES_H_ 41 34 #define LIBC_amd64_INTTYPES_H_ 42 35 43 #define PRId8 "d" 44 #define PRId16 "d" 45 #define PRId32 "d" 46 #define PRId64 "lld" 47 #define PRIdPTR "lld" 48 49 #define PRIo8 "o" 50 #define PRIo16 "o" 51 #define PRIo32 "o" 52 #define PRIo64 "llo" 53 #define PRIoPTR "llo" 54 55 #define PRIu8 "u" 56 #define PRIu16 "u" 57 #define PRIu32 "u" 58 #define PRIu64 "llu" 59 #define PRIuPTR "llu" 60 61 #define PRIx8 "x" 62 #define PRIx16 "x" 63 #define PRIx32 "x" 64 #define PRIx64 "llx" 65 #define PRIxPTR "llx" 66 67 #define PRIX8 "X" 68 #define PRIX16 "X" 69 #define PRIX32 "X" 70 #define PRIX64 "llX" 71 #define PRIXPTR "llX" 36 #define PRIdn PRId64 /**< Format for sysarg_t, ipcarg_t, etc. */ 37 #define PRIun PRIu64 /**< Format for sysarg_t, ipcarg_t, etc. */ 38 #define PRIxn PRIx64 /**< Format for hexadecimal sysarg_t, ipcarg_t, etc. */ 39 #define PRIua PRIu64 /**< Format for atomic_count_t. */ 72 40 73 41 #endif -
uspace/lib/c/arch/arm32/include/inttypes.h
r56b962d r84439d7 30 30 * @{ 31 31 */ 32 /** @file Macros for format specifiers.33 *34 * Macros for formatting stdint types as specified in section35 * 7.8.1 Macros for format specifiers of the C99 draft specification36 * (ISO/IEC 9899:201x). Only some macros from the specification are37 * implemented.38 */39 32 40 33 #ifndef LIBC_arm32_INTTYPES_H_ 41 34 #define LIBC_arm32_INTTYPES_H_ 42 35 43 #define PRId8 "d" 44 #define PRId16 "d" 45 #define PRId32 "d" 46 #define PRId64 "lld" 47 #define PRIdPTR "d" 48 49 #define PRIo8 "o" 50 #define PRIo16 "o" 51 #define PRIo32 "o" 52 #define PRIo64 "llo" 53 #define PRIoPTR "o" 54 55 #define PRIu8 "u" 56 #define PRIu16 "u" 57 #define PRIu32 "u" 58 #define PRIu64 "llu" 59 #define PRIuPTR "u" 60 61 #define PRIx8 "x" 62 #define PRIx16 "x" 63 #define PRIx32 "x" 64 #define PRIx64 "llx" 65 #define PRIxPTR "x" 66 67 #define PRIX8 "X" 68 #define PRIX16 "X" 69 #define PRIX32 "X" 70 #define PRIX64 "llX" 71 #define PRIXPTR "X" 36 #define PRIdn PRId32 /**< Format for sysarg_t, ipcarg_t, etc. */ 37 #define PRIun PRIu32 /**< Format for sysarg_t, ipcarg_t, etc. */ 38 #define PRIxn PRIx32 /**< Format for hexadecimal sysarg_t, ipcarg_t, etc. */ 39 #define PRIua PRIu32 /**< Format for atomic_count_t. */ 72 40 73 41 #endif -
uspace/lib/c/arch/ia32/include/inttypes.h
r56b962d r84439d7 30 30 * @{ 31 31 */ 32 /** @file Macros for format specifiers.33 *34 * Macros for formatting stdint types as specified in section35 * 7.8.1 Macros for format specifiers of the C99 draft specification36 * (ISO/IEC 9899:201x). Only some macros from the specification are37 * implemented.38 */39 32 40 33 #ifndef LIBC_ia32_INTTYPES_H_ 41 34 #define LIBC_ia32_INTTYPES_H_ 42 35 43 #define PRId8 "d" 44 #define PRId16 "d" 45 #define PRId32 "d" 46 #define PRId64 "lld" 47 #define PRIdPTR "d" 48 49 #define PRIo8 "o" 50 #define PRIo16 "o" 51 #define PRIo32 "o" 52 #define PRIo64 "llo" 53 #define PRIoPTR "o" 54 55 #define PRIu8 "u" 56 #define PRIu16 "u" 57 #define PRIu32 "u" 58 #define PRIu64 "llu" 59 #define PRIuPTR "u" 60 61 #define PRIx8 "x" 62 #define PRIx16 "x" 63 #define PRIx32 "x" 64 #define PRIx64 "llx" 65 #define PRIxPTR "x" 66 67 #define PRIX8 "X" 68 #define PRIX16 "X" 69 #define PRIX32 "X" 70 #define PRIX64 "llX" 71 #define PRIXPTR "X" 36 #define PRIdn PRId32 /**< Format for sysarg_t, ipcarg_t, etc. */ 37 #define PRIun PRIu32 /**< Format for sysarg_t, ipcarg_t, etc. */ 38 #define PRIxn PRIx32 /**< Format for hexadecimal sysarg_t, ipcarg_t, etc. */ 39 #define PRIua PRIu32 /**< Format for atomic_count_t. */ 72 40 73 41 #endif -
uspace/lib/c/arch/ia64/include/inttypes.h
r56b962d r84439d7 30 30 * @{ 31 31 */ 32 /** @file Macros for format specifiers.33 *34 * Macros for formatting stdint types as specified in section35 * 7.8.1 Macros for format specifiers of the C99 draft specification36 * (ISO/IEC 9899:201x). Only some macros from the specification are37 * implemented.38 */39 32 40 33 #ifndef LIBC_ia64_INTTYPES_H_ 41 34 #define LIBC_ia64_INTTYPES_H_ 42 35 43 #define PRId8 "d" 44 #define PRId16 "d" 45 #define PRId32 "d" 46 #define PRId64 "ld" 47 #define PRIdPTR "ld" 48 49 #define PRIo8 "o" 50 #define PRIo16 "o" 51 #define PRIo32 "o" 52 #define PRIo64 "lo" 53 #define PRIoPTR "lo" 54 55 #define PRIu8 "u" 56 #define PRIu16 "u" 57 #define PRIu32 "u" 58 #define PRIu64 "lu" 59 #define PRIuPTR "lu" 60 61 #define PRIx8 "x" 62 #define PRIx16 "x" 63 #define PRIx32 "x" 64 #define PRIx64 "lx" 65 #define PRIxPTR "lx" 66 67 #define PRIX8 "X" 68 #define PRIX16 "X" 69 #define PRIX32 "X" 70 #define PRIX64 "lX" 71 #define PRIXPTR "lX" 36 #define PRIdn PRId64 /**< Format for sysarg_t, ipcarg_t, etc. */ 37 #define PRIun PRIu64 /**< Format for sysarg_t, ipcarg_t, etc. */ 38 #define PRIxn PRIx64 /**< Format for hexadecimal sysarg_t, ipcarg_t, etc. */ 39 #define PRIua PRIu64 /**< Format for atomic_count_t. */ 72 40 73 41 #endif -
uspace/lib/c/arch/mips32/include/inttypes.h
r56b962d r84439d7 30 30 * @{ 31 31 */ 32 /** @file Macros for format specifiers.33 *34 * Macros for formatting stdint types as specified in section35 * 7.8.1 Macros for format specifiers of the C99 draft specification36 * (ISO/IEC 9899:201x). Only some macros from the specification are37 * implemented.38 */39 32 40 33 #ifndef LIBC_mips32_INTTYPES_H_ 41 34 #define LIBC_mips32_INTTYPES_H_ 42 35 43 #define PRId8 "d" 44 #define PRId16 "d" 45 #define PRId32 "d" 46 #define PRId64 "lld" 47 #define PRIdPTR "d" 48 49 #define PRIo8 "o" 50 #define PRIo16 "o" 51 #define PRIo32 "o" 52 #define PRIo64 "llo" 53 #define PRIoPTR "o" 54 55 #define PRIu8 "u" 56 #define PRIu16 "u" 57 #define PRIu32 "u" 58 #define PRIu64 "llu" 59 #define PRIuPTR "u" 60 61 #define PRIx8 "x" 62 #define PRIx16 "x" 63 #define PRIx32 "x" 64 #define PRIx64 "llx" 65 #define PRIxPTR "x" 66 67 #define PRIX8 "X" 68 #define PRIX16 "X" 69 #define PRIX32 "X" 70 #define PRIX64 "llX" 71 #define PRIXPTR "x" 36 #define PRIdn PRId32 /**< Format for sysarg_t, ipcarg_t, etc. */ 37 #define PRIun PRIu32 /**< Format for sysarg_t, ipcarg_t, etc. */ 38 #define PRIxn PRIx32 /**< Format for hexadecimal sysarg_t, ipcarg_t, etc. */ 39 #define PRIua PRIu32 /**< Format for atomic_count_t. */ 72 40 73 41 #endif -
uspace/lib/c/arch/ppc32/include/inttypes.h
r56b962d r84439d7 30 30 * @{ 31 31 */ 32 /** @file Macros for format specifiers.33 *34 * Macros for formatting stdint types as specified in section35 * 7.8.1 Macros for format specifiers of the C99 draft specification36 * (ISO/IEC 9899:201x). Only some macros from the specification are37 * implemented.38 */39 32 40 33 #ifndef LIBC_ppc32_INTTYPES_H_ 41 34 #define LIBC_ppc32_INTTYPES_H_ 42 35 43 #define PRId8 "d" 44 #define PRId16 "d" 45 #define PRId32 "d" 46 #define PRId64 "lld" 47 #define PRIdPTR "d" 48 49 #define PRIo8 "o" 50 #define PRIo16 "o" 51 #define PRIo32 "o" 52 #define PRIo64 "llo" 53 #define PRIoPTR "o" 54 55 #define PRIu8 "u" 56 #define PRIu16 "u" 57 #define PRIu32 "u" 58 #define PRIu64 "llu" 59 #define PRIuPTR "u" 60 61 #define PRIx8 "x" 62 #define PRIx16 "x" 63 #define PRIx32 "x" 64 #define PRIx64 "llx" 65 #define PRIxPTR "x" 66 67 #define PRIX8 "X" 68 #define PRIX16 "X" 69 #define PRIX32 "X" 70 #define PRIX64 "llX" 71 #define PRIXPTR "X" 36 #define PRIdn PRId32 /**< Format for sysarg_t, ipcarg_t, etc. */ 37 #define PRIun PRIu32 /**< Format for sysarg_t, ipcarg_t, etc. */ 38 #define PRIxn PRIx32 /**< Format for hexadecimal sysarg_t, ipcarg_t, etc. */ 39 #define PRIua PRIu32 /**< Format for atomic_count_t. */ 72 40 73 41 #endif -
uspace/lib/c/arch/sparc64/include/inttypes.h
r56b962d r84439d7 30 30 * @{ 31 31 */ 32 /** @file Macros for format specifiers.33 *34 * Macros for formatting stdint types as specified in section35 * 7.8.1 Macros for format specifiers of the C99 draft specification36 * (ISO/IEC 9899:201x). Only some macros from the specification are37 * implemented.38 */39 32 40 33 #ifndef LIBC_sparc64_INTTYPES_H_ 41 34 #define LIBC_sparc64_INTTYPES_H_ 42 35 43 #define PRId8 "d" 44 #define PRId16 "d" 45 #define PRId32 "d" 46 #define PRId64 "lld" 47 #define PRIdPTR "lld" 48 49 #define PRIo8 "o" 50 #define PRIo16 "o" 51 #define PRIo32 "o" 52 #define PRIo64 "llo" 53 #define PRIoPTR "llo" 54 55 #define PRIu8 "u" 56 #define PRIu16 "u" 57 #define PRIu32 "u" 58 #define PRIu64 "llu" 59 #define PRIuPTR "llu" 60 61 #define PRIx8 "x" 62 #define PRIx16 "x" 63 #define PRIx32 "x" 64 #define PRIx64 "llx" 65 #define PRIxPTR "llx" 66 67 #define PRIX8 "X" 68 #define PRIX16 "X" 69 #define PRIX32 "X" 70 #define PRIX64 "llX" 71 #define PRIXPTR "llX" 36 #define PRIdn PRId64 /**< Format for sysarg_t, ipcarg_t, etc. */ 37 #define PRIun PRIu64 /**< Format for sysarg_t, ipcarg_t, etc. */ 38 #define PRIxn PRIx64 /**< Format for hexadecimal sysarg_t, ipcarg_t, etc. */ 39 #define PRIua PRIu64 /**< Format for atomic_count_t. */ 72 40 73 41 #endif -
uspace/lib/c/generic/device/char.c
r56b962d r84439d7 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 28 29 29 /** @addtogroup libc 30 30 * @{ … … 40 40 #include <stdio.h> 41 41 42 /** Read to or write from the device using its character interface. 43 * 44 * Helper function. 45 * 46 * @param dev_phone phone to the device. 47 * @param buf the buffer for the data read from or written to the device. 48 * @param len the maximum length of the data to be read or written. 49 * @param read read from the device if true, write to it otherwise. 50 * 51 * @return non-negative number of bytes actually read from or written to the device on success, 52 * negative error number otherwise. 53 * 42 /** Read to or write from device. 43 * 44 * Helper function to read to or write from a device 45 * using its character interface. 46 * 47 * @param dev_phone Phone to the device. 48 * @param buf Buffer for the data read 49 * from or written to the device. 50 * @param len Maximum length of the data to be 51 * read or written. 52 * @param read Read from the device if true, 53 * write to it otherwise. 54 * 55 * @return Non-negative number of bytes actually read 56 * from or written to the device on success, 57 * negative error number otherwise. 58 * 54 59 */ 55 static int rw_dev(int dev_phone, void *buf, size_t len, bool read)60 static ssize_t rw_dev(int dev_phone, void *buf, size_t len, bool read) 56 61 { 57 ipc_call_t answer;58 59 62 async_serialize_start(); 60 63 64 ipc_call_t answer; 61 65 aid_t req; 62 66 int ret; 63 67 64 68 if (read) { 65 req = async_send_1(dev_phone, DEV_IFACE_ID(CHAR_DEV_IFACE), CHAR_READ_DEV, &answer); 66 ret = async_data_read_start(dev_phone, buf, len); 69 req = async_send_1(dev_phone, DEV_IFACE_ID(CHAR_DEV_IFACE), 70 CHAR_READ_DEV, &answer); 71 ret = async_data_read_start(dev_phone, buf, len); 67 72 } else { 68 req = async_send_1(dev_phone, DEV_IFACE_ID(CHAR_DEV_IFACE), CHAR_WRITE_DEV, &answer); 73 req = async_send_1(dev_phone, DEV_IFACE_ID(CHAR_DEV_IFACE), 74 CHAR_WRITE_DEV, &answer); 69 75 ret = async_data_write_start(dev_phone, buf, len); 70 76 } 71 77 72 78 ipcarg_t rc; 73 if (ret != EOK) { 79 if (ret != EOK) { 74 80 async_wait_for(req, &rc); 75 81 async_serialize_end(); 76 if (rc == EOK) { 77 return ret; 78 } 79 else { 80 return (int) rc; 81 } 82 if (rc == EOK) 83 return (ssize_t) ret; 84 85 return (ssize_t) rc; 82 86 } 83 87 … … 85 89 async_serialize_end(); 86 90 87 ret = (int)rc; 88 if (EOK != ret) { 89 return ret; 90 } 91 ret = (int) rc; 92 if (ret != EOK) 93 return (ssize_t) ret; 91 94 92 return IPC_GET_ARG1(answer);95 return (ssize_t) IPC_GET_ARG1(answer); 93 96 } 94 97 95 /** Read from the device using its character interface. 96 * 97 * @param dev_phone phone to the device. 98 * @param buf the output buffer for the data read from the device. 99 * @param len the maximum length of the data to be read. 100 * 101 * @return non-negative number of bytes actually read from the device on success, negative error number otherwise. 98 /** Read from device using its character interface. 99 * 100 * @param dev_phone Phone to the device. 101 * @param buf Output buffer for the data 102 * read from the device. 103 * @param len Maximum length of the data to be read. 104 * 105 * @return Non-negative number of bytes actually read 106 * from the device on success, negative error 107 * number otherwise. 108 * 102 109 */ 103 int read_dev(int dev_phone, void *buf, size_t len)104 { 110 ssize_t read_dev(int dev_phone, void *buf, size_t len) 111 { 105 112 return rw_dev(dev_phone, buf, len, true); 106 113 } 107 114 108 /** Write to the device using its character interface. 109 * 110 * @param dev_phone phone to the device. 111 * @param buf the input buffer containg the data to be written to the device. 112 * @param len the maximum length of the data to be written. 113 * 114 * @return non-negative number of bytes actually written to the device on success, negative error number otherwise. 115 /** Write to device using its character interface. 116 * 117 * @param dev_phone Phone to the device. 118 * @param buf Input buffer containg the data 119 * to be written to the device. 120 * @param len Maximum length of the data to be written. 121 * 122 * @return Non-negative number of bytes actually written 123 * to the device on success, negative error number 124 * otherwise. 125 * 115 126 */ 116 int write_dev(int dev_phone, void *buf, size_t len)127 ssize_t write_dev(int dev_phone, void *buf, size_t len) 117 128 { 118 129 return rw_dev(dev_phone, buf, len, false); 119 130 } 120 131 121 122 /** @} 132 /** @} 123 133 */ -
uspace/lib/c/generic/io/printf_core.c
r56b962d r84439d7 82 82 PrintfQualifierLong, 83 83 PrintfQualifierLongLong, 84 PrintfQualifierPointer 84 PrintfQualifierPointer, 85 PrintfQualifierSize 85 86 } qualifier_t; 86 87 … … 552 553 * - "" Signed or unsigned int (default value).@n 553 554 * - "l" Signed or unsigned long int.@n 554 * If conversion is "c", the character is w char_t (wide character).@n555 * If conversion is "c", the character is wint_t (wide character).@n 555 556 * If conversion is "s", the string is wchar_t * (wide string).@n 556 557 * - "ll" Signed or unsigned long long int.@n 558 * - "z" Signed or unsigned ssize_t or site_t.@n 557 559 * 558 560 * CONVERSION:@n … … 736 738 } 737 739 break; 740 case 'z': 741 qualifier = PrintfQualifierSize; 742 i = nxt; 743 uc = str_decode(fmt, &nxt, STR_NO_LIMIT); 744 break; 738 745 default: 739 746 /* Default type */ … … 763 770 case 'c': 764 771 if (qualifier == PrintfQualifierLong) 765 retval = print_wchar(va_arg(ap, w char_t), width, flags, ps);772 retval = print_wchar(va_arg(ap, wint_t), width, flags, ps); 766 773 else 767 774 retval = print_char(va_arg(ap, unsigned int), width, flags, ps); … … 849 856 precision = size << 1; 850 857 number = (uint64_t) (uintptr_t) va_arg(ap, void *); 858 break; 859 case PrintfQualifierSize: 860 size = sizeof(size_t); 861 number = (uint64_t) va_arg(ap, size_t); 851 862 break; 852 863 default: -
uspace/lib/c/generic/stacktrace.c
r56b962d r84439d7 50 50 51 51 while (stacktrace_fp_valid(&st, fp)) { 52 printf("%p: %p()\n", fp,pc);52 printf("%p: %p()\n", (void *) fp, (void *) pc); 53 53 (void) stacktrace_ra_get(&st, fp, &pc); 54 54 (void) stacktrace_fp_prev(&st, fp, &nfp); -
uspace/lib/c/generic/str.c
r56b962d r84439d7 1005 1005 *end = '\0'; 1006 1006 return start; 1007 } 1008 1009 /** Convert string to uint64_t (internal variant). 1010 * 1011 * @param nptr Pointer to string. 1012 * @param endptr Pointer to the first invalid character is stored here. 1013 * @param base Zero or number between 2 and 36 inclusive. 1014 * @param neg Indication of unary minus is stored here. 1015 * @apram result Result of the conversion. 1016 * 1017 * @return EOK if conversion was successful. 1018 * 1019 */ 1020 static int str_uint(const char *nptr, char **endptr, unsigned int base, 1021 bool *neg, uint64_t *result) 1022 { 1023 assert(endptr != NULL); 1024 assert(neg != NULL); 1025 assert(result != NULL); 1026 1027 *neg = false; 1028 const char *str = nptr; 1029 1030 /* Ignore leading whitespace */ 1031 while (isspace(*str)) 1032 str++; 1033 1034 if (*str == '-') { 1035 *neg = true; 1036 str++; 1037 } else if (*str == '+') 1038 str++; 1039 1040 if (base == 0) { 1041 /* Decode base if not specified */ 1042 base = 10; 1043 1044 if (*str == '0') { 1045 base = 8; 1046 str++; 1047 1048 switch (*str) { 1049 case 'b': 1050 case 'B': 1051 base = 2; 1052 str++; 1053 break; 1054 case 'o': 1055 case 'O': 1056 base = 8; 1057 str++; 1058 break; 1059 case 'd': 1060 case 'D': 1061 case 't': 1062 case 'T': 1063 base = 10; 1064 str++; 1065 break; 1066 case 'x': 1067 case 'X': 1068 base = 16; 1069 str++; 1070 break; 1071 default: 1072 str--; 1073 } 1074 } 1075 } else { 1076 /* Check base range */ 1077 if ((base < 2) || (base > 36)) { 1078 *endptr = (char *) str; 1079 return EINVAL; 1080 } 1081 } 1082 1083 *result = 0; 1084 const char *startstr = str; 1085 1086 while (*str != 0) { 1087 unsigned int digit; 1088 1089 if ((*str >= 'a') && (*str <= 'z')) 1090 digit = *str - 'a' + 10; 1091 else if ((*str >= 'A') && (*str <= 'Z')) 1092 digit = *str - 'A' + 10; 1093 else if ((*str >= '0') && (*str <= '9')) 1094 digit = *str - '0'; 1095 else 1096 break; 1097 1098 if (digit >= base) 1099 break; 1100 1101 uint64_t prev = *result; 1102 *result = (*result) * base + digit; 1103 1104 if (*result < prev) { 1105 /* Overflow */ 1106 *endptr = (char *) str; 1107 return EOVERFLOW; 1108 } 1109 1110 str++; 1111 } 1112 1113 if (str == startstr) { 1114 /* 1115 * No digits were decoded => first invalid character is 1116 * the first character of the string. 1117 */ 1118 str = nptr; 1119 } 1120 1121 *endptr = (char *) str; 1122 1123 if (str == nptr) 1124 return EINVAL; 1125 1126 return EOK; 1127 } 1128 1129 /** Convert string to uint64_t. 1130 * 1131 * @param nptr Pointer to string. 1132 * @param endptr If not NULL, pointer to the first invalid character 1133 * is stored here. 1134 * @param base Zero or number between 2 and 36 inclusive. 1135 * @param strict Do not allow any trailing characters. 1136 * @param result Result of the conversion. 1137 * 1138 * @return EOK if conversion was successful. 1139 * 1140 */ 1141 int str_uint64(const char *nptr, char **endptr, unsigned int base, 1142 bool strict, uint64_t *result) 1143 { 1144 assert(result != NULL); 1145 1146 bool neg; 1147 char *lendptr; 1148 int ret = str_uint(nptr, &lendptr, base, &neg, result); 1149 1150 if (endptr != NULL) 1151 *endptr = (char *) lendptr; 1152 1153 if (ret != EOK) 1154 return ret; 1155 1156 /* Do not allow negative values */ 1157 if (neg) 1158 return EINVAL; 1159 1160 /* Check whether we are at the end of 1161 the string in strict mode */ 1162 if ((strict) && (*lendptr != 0)) 1163 return EINVAL; 1164 1165 return EOK; 1166 } 1167 1168 /** Convert string to size_t. 1169 * 1170 * @param nptr Pointer to string. 1171 * @param endptr If not NULL, pointer to the first invalid character 1172 * is stored here. 1173 * @param base Zero or number between 2 and 36 inclusive. 1174 * @param strict Do not allow any trailing characters. 1175 * @param result Result of the conversion. 1176 * 1177 * @return EOK if conversion was successful. 1178 * 1179 */ 1180 int str_size_t(const char *nptr, char **endptr, unsigned int base, 1181 bool strict, size_t *result) 1182 { 1183 assert(result != NULL); 1184 1185 bool neg; 1186 char *lendptr; 1187 uint64_t res; 1188 int ret = str_uint(nptr, &lendptr, base, &neg, &res); 1189 1190 if (endptr != NULL) 1191 *endptr = (char *) lendptr; 1192 1193 if (ret != EOK) 1194 return ret; 1195 1196 /* Do not allow negative values */ 1197 if (neg) 1198 return EINVAL; 1199 1200 /* Check whether we are at the end of 1201 the string in strict mode */ 1202 if ((strict) && (*lendptr != 0)) 1203 return EINVAL; 1204 1205 /* Check for overflow */ 1206 size_t _res = (size_t) res; 1207 if (_res != res) 1208 return EOVERFLOW; 1209 1210 *result = _res; 1211 1212 return EOK; 1007 1213 } 1008 1214 -
uspace/lib/c/include/assert.h
r56b962d r84439d7 51 51 52 52 #ifndef NDEBUG 53 # define assert(expr) \ 54 do { \ 55 if (!(expr)) { \ 56 printf("Assertion failed (%s) at file '%s', " \ 57 "line %d.\n", #expr, __FILE__, __LINE__); \ 58 abort(); \ 59 } \ 60 } while (0) 61 #else 62 # define assert(expr) 63 #endif 53 54 #define assert(expr) \ 55 do { \ 56 if (!(expr)) { \ 57 printf("Assertion failed (%s) at file '%s', " \ 58 "line %d.\n", #expr, __FILE__, __LINE__); \ 59 abort(); \ 60 } \ 61 } while (0) 62 63 #else /* NDEBUG */ 64 65 #define assert(expr) 66 67 #endif /* NDEBUG */ 64 68 65 69 #endif -
uspace/lib/c/include/device/char.h
r56b962d r84439d7 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 28 29 29 /** @addtogroup libc 30 30 * @{ … … 32 32 /** @file 33 33 */ 34 34 35 35 #ifndef LIBC_DEVICE_HW_RES_H_ 36 36 #define LIBC_DEVICE_HW_RES_H_ … … 38 38 typedef enum { 39 39 CHAR_READ_DEV = 0, 40 CHAR_WRITE_DEV 40 CHAR_WRITE_DEV 41 41 } hw_res_funcs_t; 42 42 43 int read_dev(int dev_phone, void *buf, size_t len);44 int write_dev(int dev_phone, void *buf, size_t len);43 ssize_t read_dev(int dev_phone, void *buf, size_t len); 44 ssize_t write_dev(int dev_phone, void *buf, size_t len); 45 45 46 46 #endif -
uspace/lib/c/include/err.h
r56b962d r84439d7 38 38 #include <stdio.h> 39 39 40 #define errx(status, fmt, ...) { \ 41 printf((fmt), ##__VA_ARGS__); \ 42 _exit(status); \ 43 } 40 #define errx(status, fmt, ...) \ 41 { \ 42 printf((fmt), ##__VA_ARGS__); \ 43 _exit(status); \ 44 } 44 45 45 46 #endif … … 47 48 /** @} 48 49 */ 49 -
uspace/lib/c/include/malloc.h
r56b962d r84439d7 41 41 extern uintptr_t get_max_heap_addr(void); 42 42 43 extern void *malloc(const size_t size); 44 extern void *calloc(const size_t nmemb, const size_t size); 45 extern void *memalign(const size_t align, const size_t size); 43 extern void *malloc(const size_t size) 44 __attribute__((malloc)); 45 extern void *calloc(const size_t nmemb, const size_t size) 46 __attribute__((malloc)); 47 extern void *memalign(const size_t align, const size_t size) 48 __attribute__((malloc)); 46 49 extern void *realloc(const void *addr, const size_t size); 47 50 extern void free(const void *addr); -
uspace/lib/c/include/stdint.h
r56b962d r84439d7 36 36 #define LIBC_STDINT_H_ 37 37 38 #define INT8_MIN (0x80)39 #define INT8_MAX (0x7F)38 #define INT8_MIN INT8_C(0x80) 39 #define INT8_MAX INT8_C(0x7F) 40 40 41 #define UINT8_MIN (0u)42 #define UINT8_MAX (0xFFu)41 #define UINT8_MIN UINT8_C(0) 42 #define UINT8_MAX UINT8_C(0xFF) 43 43 44 #define INT16_MIN (0x8000)45 #define INT16_MAX (0x7FFF)44 #define INT16_MIN INT16_C(0x8000) 45 #define INT16_MAX INT16_C(0x7FFF) 46 46 47 #define UINT16_MIN (0u)48 #define UINT16_MAX (0xFFFFu)47 #define UINT16_MIN UINT16_C(0) 48 #define UINT16_MAX UINT16_C(0xFFFF) 49 49 50 #define INT32_MIN (0x80000000l)51 #define INT32_MAX (0x7FFFFFFFl)50 #define INT32_MIN INT32_C(0x80000000) 51 #define INT32_MAX INT32_C(0x7FFFFFFF) 52 52 53 #define UINT32_MIN (0ul)54 #define UINT32_MAX (0xFFFFFFFFul)53 #define UINT32_MIN UINT32_C(0) 54 #define UINT32_MAX UINT32_C(0xFFFFFFFF) 55 55 56 #define INT64_MIN (0x8000000000000000ll)57 #define INT64_MAX (0x7FFFFFFFFFFFFFFFll)56 #define INT64_MIN INT64_C(0x8000000000000000) 57 #define INT64_MAX INT64_C(0x7FFFFFFFFFFFFFFF) 58 58 59 #define UINT64_MIN (0ull)60 #define UINT64_MAX (0xFFFFFFFFFFFFFFFFull)59 #define UINT64_MIN UINT64_C(0) 60 #define UINT64_MAX UINT64_C(0xFFFFFFFFFFFFFFFF) 61 61 62 62 #include <libarch/types.h> -
uspace/lib/c/include/stdio.h
r56b962d r84439d7 41 41 #include <adt/list.h> 42 42 43 #ifndef NVERIFY_PRINTF 44 45 #define PRINTF_ATTRIBUTE(start, end) \ 46 __attribute__((format(gnu_printf, start, end))) 47 48 #else /* NVERIFY_PRINTF */ 49 50 #define PRINTF_ATTRIBUTE(start, end) 51 52 #endif /* NVERIFY_PRINTF */ 53 43 54 #define EOF (-1) 44 55 … … 149 160 150 161 /* Formatted string output functions */ 151 extern int fprintf(FILE *, const char*, ...); 162 extern int fprintf(FILE *, const char*, ...) 163 PRINTF_ATTRIBUTE(2, 3); 152 164 extern int vfprintf(FILE *, const char *, va_list); 153 165 154 extern int printf(const char *, ...); 166 extern int printf(const char *, ...) 167 PRINTF_ATTRIBUTE(1, 2); 155 168 extern int vprintf(const char *, va_list); 156 169 157 extern int snprintf(char *, size_t , const char *, ...); 158 extern int asprintf(char **, const char *, ...); 170 extern int snprintf(char *, size_t , const char *, ...) 171 PRINTF_ATTRIBUTE(3, 4); 172 extern int asprintf(char **, const char *, ...) 173 PRINTF_ATTRIBUTE(2, 3); 159 174 extern int vsnprintf(char *, size_t, const char *, va_list); 160 175 -
uspace/lib/c/include/str.h
r56b962d r84439d7 86 86 extern char *str_ndup(const char *, size_t max_size); 87 87 88 extern int str_uint64(const char *, char **, unsigned int, bool, uint64_t *); 89 extern int str_size_t(const char *, char **, unsigned int, bool, size_t *); 90 88 91 extern void order_suffix(const uint64_t val, uint64_t *rv, char *suffix); 89 92 -
uspace/lib/c/include/sys/typefmt.h
r56b962d r84439d7 39 39 #include <inttypes.h> 40 40 41 /* off64_t */41 /* off64_t, aoff64_t */ 42 42 #define PRIdOFF64 PRId64 43 43 #define PRIuOFF64 PRIu64 … … 45 45 #define PRIXOFF64 PRIX64 46 46 47 /* (s)size_t */48 #define PRIdSIZE PRIdPTR49 #define PRIuSIZE PRIuPTR50 #define PRIxSIZE PRIxPTR51 #define PRIXSIZE PRIXPTR52 53 /* sysarg_t */54 #define PRIdSYSARG PRIdPTR55 #define PRIuSYSARG PRIuPTR56 #define PRIxSYSARG PRIxPTR57 #define PRIXSYSARG PRIxPTR58 59 /* ipcarg_t */60 #define PRIdIPCARG PRIdPTR61 #define PRIuIPCARG PRIuPTR62 #define PRIxIPCARG PRIxPTR63 #define PRIXIPCARG PRIXPTR64 65 /* taskid_t */66 #define PRIdTASKID PRId6467 #define PRIuTASKID PRIu6468 #define PRIxTASKID PRIx6469 #define PRIXTASKID PRIx6470 71 47 #endif 72 48 -
uspace/lib/c/include/sys/types.h
r56b962d r84439d7 46 46 typedef uint64_t aoff64_t; 47 47 48 /** Unicode code point */49 typedef int32_t wchar_t;50 51 48 typedef volatile uint8_t ioport8_t; 52 49 typedef volatile uint16_t ioport16_t; -
uspace/lib/drv/generic/driver.c
r56b962d r84439d7 48 48 #include <ctype.h> 49 49 #include <errno.h> 50 #include <inttypes.h> 50 51 51 52 #include <ipc/driver.h> … … 164 165 165 166 devman_handle_t dev_handle = IPC_GET_ARG1(*icall); 167 devman_handle_t parent_dev_handle = IPC_GET_ARG2(*icall); 168 166 169 device_t *dev = create_device(); 167 170 dev->handle = dev_handle; … … 171 174 172 175 add_to_devices_list(dev); 176 dev->parent = driver_get_device(&devices, parent_dev_handle); 177 173 178 res = driver->driver_ops->add_device(dev); 174 179 if (0 == res) { 175 printf("%s: new device with handle = %xwas added.\n",180 printf("%s: new device with handle=%" PRIun " was added.\n", 176 181 driver->name, dev_handle); 177 182 } else { 178 printf("%s: failed to add a new device with handle = % d.\n",183 printf("%s: failed to add a new device with handle = %" PRIun ".\n", 179 184 driver->name, dev_handle); 180 185 remove_from_devices_list(dev); … … 203 208 break; 204 209 default: 205 if (!(callid & IPC_CALLID_NOTIFICATION)) 206 ipc_answer_0(callid, ENOENT); 210 ipc_answer_0(callid, ENOENT); 207 211 } 208 212 } … … 226 230 if (dev == NULL) { 227 231 printf("%s: driver_connection_gen error - no device with handle" 228 " % xwas found.\n", driver->name, handle);232 " %" PRIun " was found.\n", driver->name, handle); 229 233 ipc_answer_0(iid, ENOENT); 230 234 return; … … 290 294 printf("%s: driver_connection_gen error - ", 291 295 driver->name); 292 printf("device with handle % dhas no interface "296 printf("device with handle %" PRIun " has no interface " 293 297 "with id %d.\n", handle, iface_idx); 294 298 ipc_answer_0(callid, ENOTSUP); -
uspace/lib/drv/generic/remote_usbhc.c
r56b962d r84439d7 42 42 #define USB_MAX_PAYLOAD_SIZE 1020 43 43 44 static void remote_usbhc_get_address(device_t *, void *, ipc_callid_t, ipc_call_t *); 44 45 static void remote_usbhc_get_buffer(device_t *, void *, ipc_callid_t, ipc_call_t *); 45 46 static void remote_usbhc_interrupt_out(device_t *, void *, ipc_callid_t, ipc_call_t *); 46 47 static void remote_usbhc_interrupt_in(device_t *, void *, ipc_callid_t, ipc_call_t *); 47 //static void remote_usb(device_t *, void *, ipc_callid_t, ipc_call_t *); 48 static void remote_usbhc_control_write_setup(device_t *, void *, ipc_callid_t, ipc_call_t *); 49 static void remote_usbhc_control_write_data(device_t *, void *, ipc_callid_t, ipc_call_t *); 50 static void remote_usbhc_control_write_status(device_t *, void *, ipc_callid_t, ipc_call_t *); 51 static void remote_usbhc_control_read_setup(device_t *, void *, ipc_callid_t, ipc_call_t *); 52 static void remote_usbhc_control_read_data(device_t *, void *, ipc_callid_t, ipc_call_t *); 53 static void remote_usbhc_control_read_status(device_t *, void *, ipc_callid_t, ipc_call_t *); 54 static void remote_usbhc_reserve_default_address(device_t *, void *, ipc_callid_t, ipc_call_t *); 55 static void remote_usbhc_release_default_address(device_t *, void *, ipc_callid_t, ipc_call_t *); 56 static void remote_usbhc_request_address(device_t *, void *, ipc_callid_t, ipc_call_t *); 57 static void remote_usbhc_bind_address(device_t *, void *, ipc_callid_t, ipc_call_t *); 58 static void remote_usbhc_release_address(device_t *, void *, ipc_callid_t, ipc_call_t *); 59 //static void remote_usbhc(device_t *, void *, ipc_callid_t, ipc_call_t *); 48 60 49 61 /** Remote USB interface operations. */ 50 62 static remote_iface_func_ptr_t remote_usbhc_iface_ops [] = { 51 &remote_usbhc_get_buffer, 52 &remote_usbhc_interrupt_out, 53 &remote_usbhc_interrupt_in 63 remote_usbhc_get_address, 64 65 remote_usbhc_get_buffer, 66 67 remote_usbhc_reserve_default_address, 68 remote_usbhc_release_default_address, 69 70 remote_usbhc_request_address, 71 remote_usbhc_bind_address, 72 remote_usbhc_release_address, 73 74 remote_usbhc_interrupt_out, 75 remote_usbhc_interrupt_in, 76 77 remote_usbhc_control_write_setup, 78 remote_usbhc_control_write_data, 79 remote_usbhc_control_write_status, 80 81 remote_usbhc_control_read_setup, 82 remote_usbhc_control_read_data, 83 remote_usbhc_control_read_status 54 84 }; 55 85 … … 68 98 } async_transaction_t; 69 99 100 void remote_usbhc_get_address(device_t *device, void *iface, 101 ipc_callid_t callid, ipc_call_t *call) 102 { 103 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 104 105 if (!usb_iface->tell_address) { 106 ipc_answer_0(callid, ENOTSUP); 107 return; 108 } 109 110 devman_handle_t handle = IPC_GET_ARG1(*call); 111 112 usb_address_t address; 113 int rc = usb_iface->tell_address(device, handle, &address); 114 if (rc != EOK) { 115 ipc_answer_0(callid, rc); 116 } else { 117 ipc_answer_1(callid, EOK, address); 118 } 119 } 70 120 71 121 void remote_usbhc_get_buffer(device_t *device, void *iface, … … 102 152 } 103 153 154 void remote_usbhc_reserve_default_address(device_t *device, void *iface, 155 ipc_callid_t callid, ipc_call_t *call) 156 { 157 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 158 159 if (!usb_iface->reserve_default_address) { 160 ipc_answer_0(callid, ENOTSUP); 161 return; 162 } 163 164 int rc = usb_iface->reserve_default_address(device); 165 166 ipc_answer_0(callid, rc); 167 } 168 169 void remote_usbhc_release_default_address(device_t *device, void *iface, 170 ipc_callid_t callid, ipc_call_t *call) 171 { 172 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 173 174 if (!usb_iface->release_default_address) { 175 ipc_answer_0(callid, ENOTSUP); 176 return; 177 } 178 179 int rc = usb_iface->release_default_address(device); 180 181 ipc_answer_0(callid, rc); 182 } 183 184 void remote_usbhc_request_address(device_t *device, void *iface, 185 ipc_callid_t callid, ipc_call_t *call) 186 { 187 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 188 189 if (!usb_iface->request_address) { 190 ipc_answer_0(callid, ENOTSUP); 191 return; 192 } 193 194 usb_address_t address; 195 int rc = usb_iface->request_address(device, &address); 196 if (rc != EOK) { 197 ipc_answer_0(callid, rc); 198 } else { 199 ipc_answer_1(callid, EOK, (ipcarg_t) address); 200 } 201 } 202 203 void remote_usbhc_bind_address(device_t *device, void *iface, 204 ipc_callid_t callid, ipc_call_t *call) 205 { 206 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 207 208 if (!usb_iface->bind_address) { 209 ipc_answer_0(callid, ENOTSUP); 210 return; 211 } 212 213 usb_address_t address = (usb_address_t) IPC_GET_ARG1(*call); 214 devman_handle_t handle = (devman_handle_t) IPC_GET_ARG2(*call); 215 216 int rc = usb_iface->bind_address(device, address, handle); 217 218 ipc_answer_0(callid, rc); 219 } 220 221 void remote_usbhc_release_address(device_t *device, void *iface, 222 ipc_callid_t callid, ipc_call_t *call) 223 { 224 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 225 226 if (!usb_iface->release_address) { 227 ipc_answer_0(callid, ENOTSUP); 228 return; 229 } 230 231 usb_address_t address = (usb_address_t) IPC_GET_ARG1(*call); 232 233 int rc = usb_iface->release_address(device, address); 234 235 ipc_answer_0(callid, rc); 236 } 237 104 238 105 239 static void callback_out(device_t *device, … … 125 259 } 126 260 127 void remote_usbhc_interrupt_out(device_t *device, void *iface, 128 ipc_callid_t callid, ipc_call_t *call) 129 { 130 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 261 /** Process an outgoing transfer (both OUT and SETUP). 262 * 263 * @param device Target device. 264 * @param callid Initiating caller. 265 * @param call Initiating call. 266 * @param transfer_func Transfer function (might be NULL). 267 */ 268 static void remote_usbhc_out_transfer(device_t *device, 269 ipc_callid_t callid, ipc_call_t *call, 270 usbhc_iface_transfer_out_t transfer_func) 271 { 272 if (!transfer_func) { 273 ipc_answer_0(callid, ENOTSUP); 274 return; 275 } 131 276 132 277 size_t expected_len = IPC_GET_ARG3(*call); … … 149 294 } 150 295 151 if (!usb_iface->interrupt_out) {152 ipc_answer_0(callid, ENOTSUP);153 return;154 }155 156 296 async_transaction_t *trans = malloc(sizeof(async_transaction_t)); 157 297 trans->caller = callid; 158 trans->buffer = NULL;159 trans->size = 0;160 161 int rc = usb_iface->interrupt_out(device, target, buffer, len,298 trans->buffer = buffer; 299 trans->size = len; 300 301 int rc = transfer_func(device, target, buffer, len, 162 302 callback_out, trans); 163 303 164 304 if (rc != EOK) { 165 305 ipc_answer_0(callid, rc); 306 if (buffer != NULL) { 307 free(buffer); 308 } 166 309 free(trans); 167 310 } 168 311 } 169 312 170 void remote_usbhc_interrupt_in(device_t *device, void *iface, 171 ipc_callid_t callid, ipc_call_t *call) 172 { 173 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 313 /** Process an incoming transfer. 314 * 315 * @param device Target device. 316 * @param callid Initiating caller. 317 * @param call Initiating call. 318 * @param transfer_func Transfer function (might be NULL). 319 */ 320 static void remote_usbhc_in_transfer(device_t *device, 321 ipc_callid_t callid, ipc_call_t *call, 322 usbhc_iface_transfer_in_t transfer_func) 323 { 324 if (!transfer_func) { 325 ipc_answer_0(callid, ENOTSUP); 326 return; 327 } 174 328 175 329 size_t len = IPC_GET_ARG3(*call); … … 179 333 }; 180 334 181 if (!usb_iface->interrupt_in) {182 ipc_answer_0(callid, ENOTSUP);183 return;184 }185 186 335 async_transaction_t *trans = malloc(sizeof(async_transaction_t)); 187 336 trans->caller = callid; … … 189 338 trans->size = len; 190 339 191 int rc = usb_iface->interrupt_in(device, target, trans->buffer, len,340 int rc = transfer_func(device, target, trans->buffer, len, 192 341 callback_in, trans); 193 342 … … 199 348 } 200 349 350 /** Process status part of control transfer. 351 * 352 * @param device Target device. 353 * @param callid Initiating caller. 354 * @param call Initiating call. 355 * @param direction Transfer direction (read ~ in, write ~ out). 356 * @param transfer_in_func Transfer function for control read (might be NULL). 357 * @param transfer_out_func Transfer function for control write (might be NULL). 358 */ 359 static void remote_usbhc_status_transfer(device_t *device, 360 ipc_callid_t callid, ipc_call_t *call, 361 usb_direction_t direction, 362 int (*transfer_in_func)(device_t *, usb_target_t, 363 usbhc_iface_transfer_in_callback_t, void *), 364 int (*transfer_out_func)(device_t *, usb_target_t, 365 usbhc_iface_transfer_out_callback_t, void *)) 366 { 367 switch (direction) { 368 case USB_DIRECTION_IN: 369 if (!transfer_in_func) { 370 ipc_answer_0(callid, ENOTSUP); 371 return; 372 } 373 break; 374 case USB_DIRECTION_OUT: 375 if (!transfer_out_func) { 376 ipc_answer_0(callid, ENOTSUP); 377 return; 378 } 379 break; 380 default: 381 assert(false && "unreachable code"); 382 break; 383 } 384 385 usb_target_t target = { 386 .address = IPC_GET_ARG1(*call), 387 .endpoint = IPC_GET_ARG2(*call) 388 }; 389 390 async_transaction_t *trans = malloc(sizeof(async_transaction_t)); 391 trans->caller = callid; 392 trans->buffer = NULL; 393 trans->size = 0; 394 395 int rc; 396 switch (direction) { 397 case USB_DIRECTION_IN: 398 rc = transfer_in_func(device, target, 399 callback_in, trans); 400 break; 401 case USB_DIRECTION_OUT: 402 rc = transfer_out_func(device, target, 403 callback_out, trans); 404 break; 405 default: 406 assert(false && "unreachable code"); 407 break; 408 } 409 410 if (rc != EOK) { 411 ipc_answer_0(callid, rc); 412 free(trans); 413 } 414 return; 415 } 416 417 418 void remote_usbhc_interrupt_out(device_t *device, void *iface, 419 ipc_callid_t callid, ipc_call_t *call) 420 { 421 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 422 assert(usb_iface != NULL); 423 424 return remote_usbhc_out_transfer(device, callid, call, 425 usb_iface->interrupt_out); 426 } 427 428 void remote_usbhc_interrupt_in(device_t *device, void *iface, 429 ipc_callid_t callid, ipc_call_t *call) 430 { 431 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 432 assert(usb_iface != NULL); 433 434 return remote_usbhc_in_transfer(device, callid, call, 435 usb_iface->interrupt_in); 436 } 437 438 void remote_usbhc_control_write_setup(device_t *device, void *iface, 439 ipc_callid_t callid, ipc_call_t *call) 440 { 441 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 442 assert(usb_iface != NULL); 443 444 return remote_usbhc_out_transfer(device, callid, call, 445 usb_iface->control_write_setup); 446 } 447 448 void remote_usbhc_control_write_data(device_t *device, void *iface, 449 ipc_callid_t callid, ipc_call_t *call) 450 { 451 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 452 assert(usb_iface != NULL); 453 454 return remote_usbhc_out_transfer(device, callid, call, 455 usb_iface->control_write_data); 456 } 457 458 void remote_usbhc_control_write_status(device_t *device, void *iface, 459 ipc_callid_t callid, ipc_call_t *call) 460 { 461 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 462 assert(usb_iface != NULL); 463 464 return remote_usbhc_status_transfer(device, callid, call, 465 USB_DIRECTION_IN, usb_iface->control_write_status, NULL); 466 } 467 468 void remote_usbhc_control_read_setup(device_t *device, void *iface, 469 ipc_callid_t callid, ipc_call_t *call) 470 { 471 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 472 assert(usb_iface != NULL); 473 474 return remote_usbhc_out_transfer(device, callid, call, 475 usb_iface->control_read_setup); 476 } 477 478 void remote_usbhc_control_read_data(device_t *device, void *iface, 479 ipc_callid_t callid, ipc_call_t *call) 480 { 481 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 482 assert(usb_iface != NULL); 483 484 return remote_usbhc_in_transfer(device, callid, call, 485 usb_iface->control_read_data); 486 } 487 488 void remote_usbhc_control_read_status(device_t *device, void *iface, 489 ipc_callid_t callid, ipc_call_t *call) 490 { 491 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 492 assert(usb_iface != NULL); 493 494 return remote_usbhc_status_transfer(device, callid, call, 495 USB_DIRECTION_OUT, NULL, usb_iface->control_read_status); 496 } 497 498 201 499 202 500 /** -
uspace/lib/drv/include/usbhc_iface.h
r56b962d r84439d7 92 92 */ 93 93 typedef enum { 94 /** Tell USB address assigned to device. 95 * Parameters: 96 * - devman handle id 97 * Answer: 98 * - EINVAL - unknown handle or handle not managed by this driver 99 * - ENOTSUP - operation not supported by HC (shall not happen) 100 * - arbitrary error code if returned by remote implementation 101 * - EOK - handle found, first parameter contains the USB address 102 */ 103 IPC_M_USBHC_GET_ADDRESS, 104 94 105 /** Asks for data buffer. 95 106 * See explanation at usb_iface_funcs_t. … … 100 111 101 112 113 /** Reserve usage of default address. 114 * This call informs the host controller that the caller will be 115 * using default USB address. It is duty of the HC driver to ensure 116 * that only single entity will have it reserved. 117 * The address is returned via IPC_M_USBHC_RELEASE_DEFAULT_ADDRESS. 118 * The caller can start using the address after receiving EOK 119 * answer. 120 */ 121 IPC_M_USBHC_RESERVE_DEFAULT_ADDRESS, 122 123 /** Release usage of default address. 124 * @see IPC_M_USBHC_RESERVE_DEFAULT_ADDRESS 125 */ 126 IPC_M_USBHC_RELEASE_DEFAULT_ADDRESS, 127 128 /** Asks for address assignment by host controller. 129 * Answer: 130 * - ELIMIT - host controller run out of address 131 * - EOK - address assigned 132 * Answer arguments: 133 * - assigned address 134 * 135 * The address must be released by via IPC_M_USBHC_RELEASE_ADDRESS. 136 */ 137 IPC_M_USBHC_REQUEST_ADDRESS, 138 139 /** Bind USB address with devman handle. 140 * Parameters: 141 * - USB address 142 * - devman handle 143 * Answer: 144 * - EOK - address binded 145 * - ENOENT - address is not in use 146 */ 147 IPC_M_USBHC_BIND_ADDRESS, 148 149 /** Release address in use. 150 * Arguments: 151 * - address to be released 152 * Answer: 153 * - ENOENT - address not in use 154 * - EPERM - trying to release default USB address 155 */ 156 IPC_M_USBHC_RELEASE_ADDRESS, 157 158 102 159 /** Send interrupt data to device. 103 160 * See explanation at usb_iface_funcs_t (OUT transaction). … … 155 212 usb_transaction_outcome_t, size_t, void *); 156 213 214 215 /** Out transfer processing function prototype. */ 216 typedef int (*usbhc_iface_transfer_out_t)(device_t *, usb_target_t, 217 void *, size_t, 218 usbhc_iface_transfer_out_callback_t, void *); 219 220 /** Setup transfer processing function prototype. */ 221 typedef usbhc_iface_transfer_out_t usbhc_iface_transfer_setup_t; 222 223 /** In transfer processing function prototype. */ 224 typedef int (*usbhc_iface_transfer_in_t)(device_t *, usb_target_t, 225 void *, size_t, 226 usbhc_iface_transfer_in_callback_t, void *); 227 157 228 /** USB devices communication interface. */ 158 229 typedef struct { 159 int (*interrupt_out)(device_t *, usb_target_t, 160 void *, size_t, 230 int (*tell_address)(device_t *, devman_handle_t, usb_address_t *); 231 232 int (*reserve_default_address)(device_t *); 233 int (*release_default_address)(device_t *); 234 int (*request_address)(device_t *, usb_address_t *); 235 int (*bind_address)(device_t *, usb_address_t, devman_handle_t); 236 int (*release_address)(device_t *, usb_address_t); 237 238 usbhc_iface_transfer_out_t interrupt_out; 239 usbhc_iface_transfer_in_t interrupt_in; 240 241 usbhc_iface_transfer_setup_t control_write_setup; 242 usbhc_iface_transfer_out_t control_write_data; 243 int (*control_write_status)(device_t *, usb_target_t, 244 usbhc_iface_transfer_in_callback_t, void *); 245 246 usbhc_iface_transfer_setup_t control_read_setup; 247 usbhc_iface_transfer_in_t control_read_data; 248 int (*control_read_status)(device_t *, usb_target_t, 161 249 usbhc_iface_transfer_out_callback_t, void *); 162 int (*interrupt_in)(device_t *, usb_target_t,163 void *, size_t,164 usbhc_iface_transfer_in_callback_t, void *);165 250 } usbhc_iface_t; 166 251 -
uspace/lib/usb/Makefile
r56b962d r84439d7 34 34 SOURCES = \ 35 35 src/hcdhubd.c \ 36 src/hcdrv.c \ 36 37 src/localdrv.c \ 38 src/remotedrv.c \ 37 39 src/usb.c \ 38 40 src/usbdrv.c -
uspace/lib/usb/include/usb/classes/hub.h
r56b962d r84439d7 36 36 #define LIBUSB_HUB_H_ 37 37 38 /** Hub class request. */ 39 typedef enum { 40 USB_HUB_REQUEST_GET_STATUS = 0, 41 USB_HUB_REQUEST_CLEAR_FEATURE = 1, 42 USB_HUB_REQUEST_GET_STATE = 2, 43 USB_HUB_REQUEST_SET_FEATURE = 3, 44 USB_HUB_REQUEST_GET_DESCRIPTOR = 6, 45 USB_HUB_REQUEST_SET_DESCRIPTOR = 7, 46 /* USB_HUB_REQUEST_ = , */ 47 } usb_hub_class_request_t; 38 #include <sys/types.h> 39 #include <usb/hcdhubd.h> 40 48 41 49 42 /** Hub class feature selector. … … 69 62 } usb_hub_class_feature_t; 70 63 64 65 /** 66 * @brief usb hub descriptor 67 * 68 * For more information see Universal Serial Bus Specification Revision 1.1 chapter 11.16.2 69 */ 70 typedef struct hub_descriptor_type{ 71 /** Number of bytes in this descriptor, including this byte */ 72 //uint8_t bDescLength; 73 74 /** Descriptor Type, value: 29H for hub descriptor */ 75 //uint8_t bDescriptorType; 76 77 /** Number of downstream ports that this hub supports */ 78 uint8_t ports_count; 79 80 /** 81 D1...D0: Logical Power Switching Mode 82 00: Ganged power switching (all ports’ power at 83 once) 84 01: Individual port power switching 85 1X: Reserved. Used only on 1.0 compliant hubs 86 that implement no power switching. 87 D2: Identifies a Compound Device 88 0: Hub is not part of a compound device 89 1: Hub is part of a compound device 90 D4...D3: Over-current Protection Mode 91 00: Global Over-current Protection. The hub 92 reports over-current as a summation of all 93 ports’ current draw, without a breakdown of 94 individual port over-current status. 95 01: Individual Port Over-current Protection. The 96 hub reports over-current on a per-port basis. 97 Each port has an over-current indicator. 98 1X: No Over-current Protection. This option is 99 allowed only for bus-powered hubs that do not 100 implement over-current protection. 101 D15...D5: 102 Reserved 103 */ 104 uint16_t hub_characteristics; 105 106 /** 107 Time (in 2ms intervals) from the time the power-on 108 sequence begins on a port until power is good on that 109 port. The USB System Software uses this value to 110 determine how long to wait before accessing a 111 powered-on port. 112 */ 113 uint8_t pwr_on_2_good_time; 114 115 /** 116 Maximum current requirements of the Hub Controller 117 electronics in mA. 118 */ 119 uint8_t current_requirement; 120 121 /** 122 Indicates if a port has a removable device attached. 123 This field is reported on byte-granularity. Within a 124 byte, if no port exists for a given location, the field 125 representing the port characteristics returns 0. 126 Bit value definition: 127 0B - Device is removable 128 1B - Device is non-removable 129 This is a bitmap corresponding to the individual ports 130 on the hub: 131 Bit 0: Reserved for future use 132 Bit 1: Port 1 133 Bit 2: Port 2 134 .... 135 Bit n: Port n (implementation-dependent, up to a 136 maximum of 255 ports). 137 */ 138 uint8_t * devices_removable; 139 140 /** 141 This field exists for reasons of compatibility with 142 software written for 1.0 compliant devices. All bits in 143 this field should be set to 1B. This field has one bit for 144 each port on the hub with additional pad bits, if 145 necessary, to make the number of bits in the field an 146 integer multiple of 8. 147 */ 148 //uint8_t * port_pwr_ctrl_mask; 149 } usb_hub_descriptor_t; 150 151 152 153 /** @brief usb hub specific request types. 154 * 155 * For more information see Universal Serial Bus Specification Revision 1.1 chapter 11.16.2 156 */ 157 typedef enum { 158 /** This request resets a value reported in the hub status. */ 159 USB_HUB_REQ_TYPE_CLEAR_HUB_FEATURE = 0x20, 160 /** This request resets a value reported in the port status. */ 161 USB_HUB_REQ_TYPE_CLEAR_PORT_FEATURE = 0x23, 162 /** This is an optional per-port diagnostic request that returns the bus state value, as sampled at the last EOF2 point. */ 163 USB_HUB_REQ_TYPE_GET_STATE = 0xA3, 164 /** This request returns the hub descriptor. */ 165 USB_HUB_REQ_TYPE_GET_DESCRIPTOR = 0xA0, 166 /** This request returns the current hub status and the states that have changed since the previous acknowledgment. */ 167 USB_HUB_REQ_TYPE_GET_HUB_STATUS = 0xA0, 168 /** This request returns the current port status and the current value of the port status change bits. */ 169 USB_HUB_REQ_TYPE_GET_PORT_STATUS = 0xA3, 170 /** This request overwrites the hub descriptor. */ 171 USB_HUB_REQ_TYPE_SET_DESCRIPTOR = 0x20, 172 /** This request sets a value reported in the hub status. */ 173 USB_HUB_REQ_TYPE_SET_HUB_FEATURE = 0x20, 174 /** This request sets a value reported in the port status. */ 175 USB_HUB_REQ_TYPE_SET_PORT_FEATURE = 0x23 176 } usb_hub_bm_request_type_t; 177 178 /** @brief hub class request codes*/ 179 typedef enum { 180 /** */ 181 USB_HUB_REQUEST_GET_STATUS = 0, 182 /** */ 183 USB_HUB_REQUEST_CLEAR_FEATURE = 1, 184 /** */ 185 USB_HUB_REQUEST_GET_STATE = 2, 186 /** */ 187 USB_HUB_REQUEST_SET_FEATURE = 3, 188 /** */ 189 USB_HUB_REQUEST_GET_DESCRIPTOR = 6, 190 /** */ 191 USB_HUB_REQUEST_SET_DESCRIPTOR = 7 192 } usb_hub_request_t; 193 194 /** 195 * Maximum size of usb hub descriptor in bytes 196 */ 197 extern size_t USB_HUB_MAX_DESCRIPTOR_SIZE; 198 199 /** 200 * @brief create uint8_t array with serialized descriptor 201 * 202 * @param descriptor 203 */ 204 void * usb_serialize_hub_descriptor(usb_hub_descriptor_t * descriptor); 205 206 /** 207 * @brief create deserialized desriptor structure out of serialized descriptor 208 * 209 * The serialized descriptor must be proper usb hub descriptor, otherwise an eerror might occur. 210 * 211 * @param sdescriptor serialized descriptor 212 */ 213 usb_hub_descriptor_t * usb_deserialize_hub_desriptor(void * sdescriptor); 214 215 /** 216 * @brief create hub structure instance 217 * 218 * @param device 219 * @return 220 */ 221 usb_hcd_hub_info_t * usb_create_hub_info(device_t * device); 222 223 224 225 226 71 227 #endif 72 228 /** -
uspace/lib/usb/include/usb/hcdhubd.h
r56b962d r84439d7 37 37 38 38 #include <adt/list.h> 39 #include <bool.h> 39 40 #include <driver.h> 40 41 #include <usb/usb.h> … … 115 116 } usb_hcd_transfer_ops_t; 116 117 118 /** 119 * @brief structure holding information about free and used addresses 120 * 121 * This structure should not be used outside usb hcd driver. 122 * You better consider it to be 'private'. 123 */ 124 typedef struct { 125 /** lower bound included in the interval */ 126 usb_address_t lower_bound; 127 128 /** upper bound, excluded from the interval */ 129 usb_address_t upper_bound; 130 131 /** */ 132 link_t link; 133 }usb_address_list_t; 134 117 135 struct usb_hc_device { 118 136 /** Transfer operations. */ … … 130 148 /** List of hubs operating from this HC. */ 131 149 link_t hubs; 150 151 /** Structure with free and used addresses */ 152 link_t addresses; 132 153 133 154 /** Link to other driven HCs. */ … … 145 166 146 167 int usb_hcd_main(usb_hc_driver_t *); 147 int usb_hcd_add_root_hub(usb_hc_device_t *dev); 168 int usb_hcd_add_root_hub(device_t *dev); 169 170 /** 171 * find first not yet used address on this host controller and use it 172 * @param this_hcd 173 * @return number in the range of allowed usb addresses or 174 * a negative number if not succesful 175 */ 176 usb_address_t usb_use_free_address(usb_hc_device_t * this_hcd); 177 178 /** 179 * @brief free the address in the address space of this hcd. 180 * 181 * if address is not used, nothing happens 182 * @param this_hcd 183 * @param addr 184 */ 185 void usb_free_used_address(usb_hc_device_t * this_hcd, usb_address_t addr ); 148 186 149 187 … … 153 191 */ 154 192 193 device_t *usb_hc_connect(device_t *); 155 194 156 195 int usb_hc_async_interrupt_out(usb_hc_device_t *, usb_target_t, … … 175 214 int usb_hc_async_wait_for(usb_handle_t); 176 215 216 int usb_hc_add_child_device(device_t *, const char *, const char *, bool); 177 217 178 218 #endif -
uspace/lib/usb/include/usb/usbdrv.h
r56b962d r84439d7 41 41 int usb_drv_hc_connect(device_t *, unsigned int); 42 42 43 int usb_drv_reserve_default_address(int); 44 int usb_drv_release_default_address(int); 45 usb_address_t usb_drv_request_address(int); 46 int usb_drv_bind_address(int, usb_address_t, devman_handle_t); 47 int usb_drv_release_address(int, usb_address_t); 48 43 49 usb_address_t usb_drv_get_my_address(int, device_t *); 44 50 … … 48 54 void *, size_t, size_t *, usb_handle_t *); 49 55 56 int usb_drv_async_control_write_setup(int, usb_target_t, 57 void *, size_t, usb_handle_t *); 58 int usb_drv_async_control_write_data(int, usb_target_t, 59 void *, size_t, usb_handle_t *); 60 int usb_drv_async_control_write_status(int, usb_target_t, 61 usb_handle_t *); 62 63 int usb_drv_async_control_read_setup(int, usb_target_t, 64 void *, size_t, usb_handle_t *); 65 int usb_drv_async_control_read_data(int, usb_target_t, 66 void *, size_t, size_t *, usb_handle_t *); 67 int usb_drv_async_control_read_status(int, usb_target_t, 68 usb_handle_t *); 69 50 70 int usb_drv_async_wait_for(usb_handle_t); 51 71 -
uspace/lib/usb/src/hcdhubd.c
r56b962d r84439d7 31 31 */ 32 32 /** @file 33 * @brief HC driver and hub driver (implementation).33 * @brief Common stuff for both HC driver and hub driver. 34 34 */ 35 35 #include <usb/hcdhubd.h> 36 36 #include <usb/devreq.h> 37 37 #include <usbhc_iface.h> 38 #include <usb/descriptor.h> 38 39 #include <driver.h> 39 40 #include <bool.h> 40 41 #include <errno.h> 41 42 #define USB_HUB_DEVICE_NAME "usbhub" 43 44 /** List of handled host controllers. */ 45 static LIST_INITIALIZE(hc_list); 46 47 /** Our HC driver. */ 48 static usb_hc_driver_t *hc_driver = NULL; 49 50 static usbhc_iface_t usb_interface = { 51 .interrupt_out = NULL, 52 .interrupt_in = NULL 53 }; 54 55 static device_ops_t usb_device_ops = { 56 .interfaces[USBHC_DEV_IFACE] = &usb_interface 57 }; 58 59 static void set_hub_address(usb_hc_device_t *hc, usb_address_t address); 42 #include <str_error.h> 43 #include <usb/classes/hub.h> 44 45 #include "hcdhubd_private.h" 60 46 61 47 /** Callback when new device is detected and must be handled by this driver. … … 64 50 * @return Error code. 65 51 */ 66 static int add_device(device_t *dev) 67 { 68 /* 69 * FIXME: use some magic to determine whether hub or another HC 70 * was connected. 71 */ 72 bool is_hc = str_cmp(dev->name, USB_HUB_DEVICE_NAME) != 0; 73 printf("%s: add_device(name=\"%s\")\n", hc_driver->name, dev->name); 74 75 if (is_hc) { 76 /* 77 * We are the HC itself. 78 */ 79 usb_hc_device_t *hc_dev = malloc(sizeof(usb_hc_device_t)); 80 list_initialize(&hc_dev->link); 81 hc_dev->transfer_ops = NULL; 82 83 hc_dev->generic = dev; 84 dev->ops = &usb_device_ops; 85 hc_dev->generic->driver_data = hc_dev; 86 87 int rc = hc_driver->add_hc(hc_dev); 88 if (rc != EOK) { 89 free(hc_dev); 90 return rc; 91 } 92 93 /* 94 * FIXME: The following line causes devman to hang. 95 * Will investigate later why. 96 */ 97 // add_device_to_class(dev, "usbhc"); 98 99 list_append(&hc_dev->link, &hc_list); 100 101 return EOK; 102 } else { 103 usb_hc_device_t *hc = list_get_instance(hc_list.next, usb_hc_device_t, link); 104 set_hub_address(hc, 5); 105 106 /* 107 * We are some (probably deeply nested) hub. 108 * Thus, assign our own operations and explore already 109 * connected devices. 110 */ 111 112 return ENOTSUP; 113 } 114 } 115 116 /** Sample usage of usb_hc_async functions. 117 * This function sets hub address using standard SET_ADDRESS request. 118 * 119 * @warning This function shall be removed once you are familiar with 120 * the usb_hc_ API. 121 * 122 * @param hc Host controller the hub belongs to. 123 * @param address New hub address. 124 */ 125 static void set_hub_address(usb_hc_device_t *hc, usb_address_t address) 126 { 127 printf("%s: setting hub address to %d\n", hc->generic->name, address); 128 usb_target_t target = {0, 0}; 129 usb_handle_t handle; 130 int rc; 131 132 usb_device_request_setup_packet_t setup_packet = { 133 .request_type = 0, 134 .request = USB_DEVREQ_SET_ADDRESS, 135 .index = 0, 136 .length = 0, 137 }; 138 setup_packet.value = address; 139 140 rc = usb_hc_async_control_write_setup(hc, target, 141 &setup_packet, sizeof(setup_packet), &handle); 142 if (rc != EOK) { 143 return; 144 } 145 146 rc = usb_hc_async_wait_for(handle); 147 if (rc != EOK) { 148 return; 149 } 150 151 rc = usb_hc_async_control_write_status(hc, target, &handle); 152 if (rc != EOK) { 153 return; 154 } 155 156 rc = usb_hc_async_wait_for(handle); 157 if (rc != EOK) { 158 return; 159 } 160 161 printf("%s: hub address changed\n", hc->generic->name); 162 } 163 164 /** Check changes on all known hubs. 165 */ 166 static void check_hub_changes(void) 167 { 168 /* 169 * Iterate through all HCs. 170 */ 171 link_t *link_hc; 172 for (link_hc = hc_list.next; 173 link_hc != &hc_list; 174 link_hc = link_hc->next) { 175 usb_hc_device_t *hc = list_get_instance(link_hc, 176 usb_hc_device_t, link); 177 /* 178 * Iterate through all their hubs. 179 */ 180 link_t *link_hub; 181 for (link_hub = hc->hubs.next; 182 link_hub != &hc->hubs; 183 link_hub = link_hub->next) { 184 usb_hcd_hub_info_t *hub = list_get_instance(link_hub, 185 usb_hcd_hub_info_t, link); 186 187 /* 188 * Check status change pipe of this hub. 189 */ 190 usb_target_t target = { 191 .address = hub->device->address, 192 .endpoint = 1 193 }; 194 195 // FIXME: count properly 196 size_t byte_length = (hub->port_count / 8) + 1; 197 198 void *change_bitmap = malloc(byte_length); 199 size_t actual_size; 200 usb_handle_t handle; 201 202 /* 203 * Send the request. 204 * FIXME: check returned value for possible errors 205 */ 206 usb_hc_async_interrupt_in(hc, target, 207 change_bitmap, byte_length, &actual_size, 208 &handle); 209 210 usb_hc_async_wait_for(handle); 211 212 /* 213 * TODO: handle the changes. 214 */ 215 } 216 } 52 static int add_device(device_t *dev) { 53 return ENOTSUP; 217 54 } 218 55 … … 234 71 * @return Error code. 235 72 */ 236 int usb_hcd_main(usb_hc_driver_t *hc) 237 { 73 int usb_hcd_main(usb_hc_driver_t *hc) { 238 74 hc_driver = hc; 239 75 hc_driver_generic.name = hc->name; 240 241 /*242 * Launch here fibril that will periodically check all243 * attached hubs for status change.244 * WARN: This call will effectively do nothing.245 */246 check_hub_changes();247 76 248 77 /* … … 261 90 * @return Error code. 262 91 */ 263 int usb_hcd_add_root_hub( usb_hc_device_t *dev)92 int usb_hcd_add_root_hub(device_t *dev) 264 93 { 94 char *id; 95 int rc = asprintf(&id, "usb&hub"); 96 if (rc <= 0) { 97 return rc; 98 } 99 100 rc = usb_hc_add_child_device(dev, USB_HUB_DEVICE_NAME, id, true); 101 if (rc != EOK) { 102 free(id); 103 } 104 105 return rc; 106 } 107 108 /** Info about child device. */ 109 struct child_device_info { 110 device_t *parent; 111 const char *name; 112 const char *match_id; 113 }; 114 115 /** Adds a child device fibril worker. */ 116 static int fibril_add_child_device(void *arg) { 117 struct child_device_info *child_info 118 = (struct child_device_info *) arg; 265 119 int rc; 266 120 267 /* 268 * Announce presence of child device. 269 */ 270 device_t *hub = NULL; 121 async_usleep(1000); 122 123 device_t *child = create_device(); 271 124 match_id_t *match_id = NULL; 272 125 273 hub = create_device(); 274 if (hub == NULL) { 126 if (child == NULL) { 275 127 rc = ENOMEM; 276 128 goto failure; 277 129 } 278 hub->name = USB_HUB_DEVICE_NAME;130 child->name = child_info->name; 279 131 280 132 match_id = create_match_id(); … … 283 135 goto failure; 284 136 } 285 286 char *id; 287 rc = asprintf(&id, "usb&hc=%s&hub", dev->generic->name); 288 if (rc <= 0) { 289 rc = ENOMEM; 290 goto failure; 291 } 292 293 match_id->id = id; 294 match_id->score = 30; 295 296 add_match_id(&hub->match_ids, match_id); 297 298 rc = child_device_register(hub, dev->generic); 137 match_id->id = child_info->match_id; 138 match_id->score = 10; 139 add_match_id(&child->match_ids, match_id); 140 141 printf("%s: adding child device `%s' with match \"%s\"\n", 142 hc_driver->name, child->name, match_id->id); 143 rc = child_device_register(child, child_info->parent); 144 printf("%s: child device `%s' registration: %s\n", 145 hc_driver->name, child->name, str_error(rc)); 146 299 147 if (rc != EOK) { 300 148 goto failure; 301 149 } 302 150 303 printf("%s: registered root hub\n", dev->generic->name); 151 goto leave; 152 153 failure: 154 if (child != NULL) { 155 child->name = NULL; 156 delete_device(child); 157 } 158 159 if (match_id != NULL) { 160 match_id->id = NULL; 161 delete_match_id(match_id); 162 } 163 164 leave: 165 free(arg); 304 166 return EOK; 305 306 failure: 307 if (hub != NULL) { 308 hub->name = NULL; 309 delete_device(hub); 310 } 311 delete_match_id(match_id); 312 313 return rc; 167 } 168 169 /** Adds a child. 170 * Due to deadlock in devman when parent registers child that oughts to be 171 * driven by the same task, the child adding is done in separate fibril. 172 * Not optimal, but it works. 173 * Update: not under all circumstances the new fibril is successful either. 174 * Thus the last parameter to let the caller choose. 175 * 176 * @param parent Parent device. 177 * @param name Device name. 178 * @param match_id Match id. 179 * @param create_fibril Whether to run the addition in new fibril. 180 * @return Error code. 181 */ 182 int usb_hc_add_child_device(device_t *parent, const char *name, 183 const char *match_id, bool create_fibril) { 184 printf("%s: about to add child device `%s' (%s)\n", hc_driver->name, 185 name, match_id); 186 187 /* 188 * Seems that creating fibril which postpones the action 189 * is the best solution. 190 */ 191 create_fibril = true; 192 193 struct child_device_info *child_info 194 = malloc(sizeof (struct child_device_info)); 195 196 child_info->parent = parent; 197 child_info->name = name; 198 child_info->match_id = match_id; 199 200 if (create_fibril) { 201 fid_t fibril = fibril_create(fibril_add_child_device, child_info); 202 if (!fibril) { 203 return ENOMEM; 204 } 205 fibril_add_ready(fibril); 206 } else { 207 fibril_add_child_device(child_info); 208 } 209 210 return EOK; 211 } 212 213 /** Tell USB address of given device. 214 * 215 * @param handle Devman handle of the device. 216 * @return USB device address or error code. 217 */ 218 usb_address_t usb_get_address_by_handle(devman_handle_t handle) { 219 /* TODO: search list of attached devices. */ 220 return ENOENT; 221 } 222 223 usb_address_t usb_use_free_address(usb_hc_device_t * this_hcd) { 224 //is there free address? 225 link_t * addresses = &this_hcd->addresses; 226 if (list_empty(addresses)) return -1; 227 link_t * link_addr = addresses; 228 bool found = false; 229 usb_address_list_t * range = NULL; 230 while (!found) { 231 link_addr = link_addr->next; 232 if (link_addr == addresses) return -2; 233 range = list_get_instance(link_addr, 234 usb_address_list_t, link); 235 if (range->upper_bound - range->lower_bound > 0) { 236 found = true; 237 } 238 } 239 //now we have interval 240 int result = range->lower_bound; 241 ++(range->lower_bound); 242 if (range->upper_bound - range->lower_bound == 0) { 243 list_remove(&range->link); 244 free(range); 245 } 246 return result; 247 } 248 249 void usb_free_used_address(usb_hc_device_t * this_hcd, usb_address_t addr) { 250 //check range 251 if (addr < usb_lowest_address || addr > usb_highest_address) 252 return; 253 link_t * addresses = &this_hcd->addresses; 254 link_t * link_addr = addresses; 255 //find 'good' interval 256 usb_address_list_t * found_range = NULL; 257 bool found = false; 258 while (!found) { 259 link_addr = link_addr->next; 260 if (link_addr == addresses) { 261 found = true; 262 } else { 263 usb_address_list_t * range = list_get_instance(link_addr, 264 usb_address_list_t, link); 265 if ( (range->lower_bound - 1 == addr) || 266 (range->upper_bound == addr)) { 267 found = true; 268 found_range = range; 269 } 270 if (range->lower_bound - 1 > addr) { 271 found = true; 272 } 273 274 } 275 } 276 if (found_range == NULL) { 277 //no suitable range found 278 usb_address_list_t * result_range = 279 (usb_address_list_t*) malloc(sizeof (usb_address_list_t)); 280 result_range->lower_bound = addr; 281 result_range->upper_bound = addr + 1; 282 list_insert_before(&result_range->link, link_addr); 283 } else { 284 //we have good range 285 if (found_range->lower_bound - 1 == addr) { 286 --found_range->lower_bound; 287 } else { 288 //only one possible case 289 ++found_range->upper_bound; 290 if (found_range->link.next != addresses) { 291 usb_address_list_t * next_range = 292 list_get_instance( &found_range->link.next, 293 usb_address_list_t, link); 294 //check neighbour range 295 if (next_range->lower_bound == addr + 1) { 296 //join ranges 297 found_range->upper_bound = next_range->upper_bound; 298 list_remove(&next_range->link); 299 free(next_range); 300 } 301 } 302 } 303 } 304 314 305 } 315 306 -
uspace/lib/usb/src/localdrv.c
r56b962d r84439d7 39 39 #include <errno.h> 40 40 41 /** Find host controller when handled by current task. 42 * 43 * @param dev Device asking for connection. 44 * @return Device structure corresponding to parent host controller. 45 * @retval NULL Corresponding host controller not found. 46 */ 47 device_t *usb_hc_connect(device_t *dev) 48 { 49 /* 50 * FIXME: this will not work when some hub on the path is 51 * not driven by the same task. 52 */ 53 device_t *parent = dev; 54 while (parent->parent != NULL) { 55 parent = parent->parent; 56 } 57 58 if (dev == parent) { 59 printf("FIXME in %s:%d encountered!\n", __FILE__, __LINE__); 60 parent = NULL; 61 } 62 63 return parent; 64 } 65 41 66 /** Information about pending transaction on HC. */ 42 67 typedef struct { -
uspace/lib/usb/src/usbdrv.c
r56b962d r84439d7 55 55 /** Connect to host controller the device is physically attached to. 56 56 * 57 * @param handle Device handle.57 * @param dev Device asking for connection. 58 58 * @param flags Connection flags (blocking connection). 59 59 * @return Phone to corresponding HC or error code. … … 64 64 * Call parent hub to obtain device handle of respective HC. 65 65 */ 66 return ENOTSUP; 66 67 /* 68 * FIXME: currently we connect always to virtual host controller. 69 */ 70 int rc; 71 devman_handle_t handle; 72 73 rc = devman_device_get_handle("/vhc", &handle, 0); 74 if (rc != EOK) { 75 return rc; 76 } 77 78 int phone = devman_device_connect(handle, 0); 79 80 return phone; 67 81 } 68 82 … … 75 89 usb_address_t usb_drv_get_my_address(int phone, device_t *dev) 76 90 { 77 return ENOTSUP; 91 ipcarg_t address; 92 int rc = async_req_1_1(phone, IPC_M_USBHC_GET_ADDRESS, 93 dev->handle, &address); 94 95 if (rc != EOK) { 96 return rc; 97 } 98 99 return (usb_address_t) address; 100 } 101 102 /** Tell HC to reserve default address. 103 * 104 * @param phone Open phone to host controller driver. 105 * @return Error code. 106 */ 107 int usb_drv_reserve_default_address(int phone) 108 { 109 return async_req_0_0(phone, IPC_M_USBHC_RESERVE_DEFAULT_ADDRESS); 110 } 111 112 /** Tell HC to release default address. 113 * 114 * @param phone Open phone to host controller driver. 115 * @return Error code. 116 */ 117 int usb_drv_release_default_address(int phone) 118 { 119 return async_req_0_0(phone, IPC_M_USBHC_RELEASE_DEFAULT_ADDRESS); 120 } 121 122 /** Ask HC for free address assignment. 123 * 124 * @param phone Open phone to host controller driver. 125 * @return Assigned USB address or negative error code. 126 */ 127 usb_address_t usb_drv_request_address(int phone) 128 { 129 ipcarg_t address; 130 int rc = async_req_0_1(phone, IPC_M_USBHC_REQUEST_ADDRESS, &address); 131 if (rc != EOK) { 132 return rc; 133 } else { 134 return (usb_address_t) address; 135 } 136 } 137 138 /** Inform HC about binding address with devman handle. 139 * 140 * @param phone Open phone to host controller driver. 141 * @param address Address to be binded. 142 * @param handle Devman handle of the device. 143 * @return Error code. 144 */ 145 int usb_drv_bind_address(int phone, usb_address_t address, 146 devman_handle_t handle) 147 { 148 int rc = async_req_2_0(phone, IPC_M_USBHC_BIND_ADDRESS, 149 address, handle); 150 151 return rc; 152 } 153 154 /** Inform HC about address release. 155 * 156 * @param phone Open phone to host controller driver. 157 * @param address Address to be released. 158 * @return Error code. 159 */ 160 int usb_drv_release_address(int phone, usb_address_t address) 161 { 162 return async_req_1_0(phone, IPC_M_USBHC_RELEASE_ADDRESS, address); 78 163 } 79 164 … … 323 408 } 324 409 410 /** Start control write transfer. */ 411 int usb_drv_async_control_write_setup(int phone, usb_target_t target, 412 void *buffer, size_t size, 413 usb_handle_t *handle) 414 { 415 return async_send_buffer(phone, 416 IPC_M_USBHC_CONTROL_WRITE_SETUP, 417 target, 418 buffer, size, 419 handle); 420 } 421 422 /** Send data during control write transfer. */ 423 int usb_drv_async_control_write_data(int phone, usb_target_t target, 424 void *buffer, size_t size, 425 usb_handle_t *handle) 426 { 427 return async_send_buffer(phone, 428 IPC_M_USBHC_CONTROL_WRITE_DATA, 429 target, 430 buffer, size, 431 handle); 432 } 433 434 /** Finalize control write transfer. */ 435 int usb_drv_async_control_write_status(int phone, usb_target_t target, 436 usb_handle_t *handle) 437 { 438 return async_recv_buffer(phone, 439 IPC_M_USBHC_CONTROL_WRITE_STATUS, 440 target, 441 NULL, 0, NULL, 442 handle); 443 } 444 445 /** Start control read transfer. */ 446 int usb_drv_async_control_read_setup(int phone, usb_target_t target, 447 void *buffer, size_t size, 448 usb_handle_t *handle) 449 { 450 return async_send_buffer(phone, 451 IPC_M_USBHC_CONTROL_READ_SETUP, 452 target, 453 buffer, size, 454 handle); 455 } 456 457 /** Read data during control read transfer. */ 458 int usb_drv_async_control_read_data(int phone, usb_target_t target, 459 void *buffer, size_t size, size_t *actual_size, 460 usb_handle_t *handle) 461 { 462 return async_recv_buffer(phone, 463 IPC_M_USBHC_CONTROL_READ_DATA, 464 target, 465 buffer, size, actual_size, 466 handle); 467 } 468 469 /** Finalize control read transfer. */ 470 int usb_drv_async_control_read_status(int phone, usb_target_t target, 471 usb_handle_t *handle) 472 { 473 return async_send_buffer(phone, 474 IPC_M_USBHC_CONTROL_READ_STATUS, 475 target, 476 NULL, 0, 477 handle); 478 } 479 325 480 /** 326 481 * @} -
uspace/lib/usbvirt/src/debug.c
r56b962d r84439d7 59 59 60 60 if (print_prefix) { 61 printf("[vusb]: " , level);61 printf("[vusb]: "); 62 62 while (--level > 0) { 63 63 printf(" ");
Note:
See TracChangeset
for help on using the changeset viewer.
