Changes in / [51b46f2:e135751] in mainline
- Files:
-
- 10 added
- 1 deleted
- 25 edited
Legend:
- Unmodified
- Added
- Removed
-
Makefile
r51b46f2 re135751 42 42 CONFIG_HEADER = config.h 43 43 44 .PHONY: all precheck cscope autotool config_auto config_default config distclean clean check 44 .PHONY: all precheck cscope autotool config_auto config_default config distclean clean check distfile dist 45 45 46 46 all: $(COMMON_MAKEFILE) $(COMMON_HEADER) $(CONFIG_MAKEFILE) $(CONFIG_HEADER) … … 64 64 endif 65 65 66 # Autotool (detects compiler features) 67 66 68 $(COMMON_MAKEFILE): autotool 67 69 $(COMMON_HEADER): autotool … … 70 72 $(AUTOTOOL) 71 73 -[ -f $(COMMON_HEADER_PREV) ] && diff -q $(COMMON_HEADER_PREV) $(COMMON_HEADER) && mv -f $(COMMON_HEADER_PREV) $(COMMON_HEADER) 74 75 # Build-time configuration 72 76 73 77 $(CONFIG_MAKEFILE): config_default … … 84 88 $(CONFIG) $< 85 89 90 # Distribution files 91 92 distfile: all 93 $(MAKE) -C dist distfile 94 95 dist: 96 $(MAKE) -C dist dist 97 98 # Cleaning 99 86 100 distclean: clean 87 rm -f $(CSCOPE).out $(COMMON_MAKEFILE) $(COMMON_HEADER) $(COMMON_HEADER_PREV) $(CONFIG_MAKEFILE) $(CONFIG_HEADER) tools/*.pyc tools/checkers/*.pyc 101 rm -f $(CSCOPE).out $(COMMON_MAKEFILE) $(COMMON_HEADER) $(COMMON_HEADER_PREV) $(CONFIG_MAKEFILE) $(CONFIG_HEADER) tools/*.pyc tools/checkers/*.pyc dist/HelenOS-* 88 102 89 103 clean: -
boot/arch/sparc64/include/arch.h
r51b46f2 re135751 41 41 #define STACK_BIAS 2047 42 42 #define STACK_WINDOW_SAVE_AREA_SIZE (16 * 8) 43 #define STACK_ARG_SAVE_AREA_SIZE (6 * 8) 43 44 44 45 #define NWINDOWS 8 -
boot/arch/sparc64/src/asm.S
r51b46f2 re135751 152 152 .global ofw 153 153 ofw: 154 save %sp, - STACK_WINDOW_SAVE_AREA_SIZE, %sp154 save %sp, -(STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE), %sp 155 155 set ofw_cif, %l0 156 156 ldx [%l0], %l0 -
boot/arch/sparc64/src/main.c
r51b46f2 re135751 190 190 bootinfo.memmap.zones[0].start += OBP_BIAS; 191 191 bootinfo.memmap.zones[0].size -= OBP_BIAS; 192 bootinfo.memmap.total -= OBP_BIAS; 192 193 } 193 194 … … 204 205 bootinfo.physmem_start = ofw_get_physmem_start(); 205 206 ofw_memmap(&bootinfo.memmap); 207 208 if (arch == ARCH_SUN4V) 209 sun4v_fixups(); 206 210 207 211 void *bootinfo_pa = ofw_translate(&bootinfo); … … 253 257 254 258 /* 255 * At this point, we claim the physical memory that we are256 * going to use. We should be safe in case of the virtual259 * At this point, we claim and map the physical memory that we 260 * are going to use. We should be safe in case of the virtual 257 261 * address space because the OpenFirmware, according to its 258 * SPARC binding, should restrict its use of virtual memory 259 * to addresses from [0xffd00000; 0xffefffff] and 260 * [0xfe000000; 0xfeffffff]. 261 * 262 * We don't map this piece of memory. We simply rely on 263 * SILO to have it done for us already in this case. 264 * 265 * XXX SILO only maps 8 MB for us here. We should improve 266 * this code to be totally independent on the behavior 267 * of SILO. 268 * 262 * SPARC binding, should restrict its use of virtual memory to 263 * addresses from [0xffd00000; 0xffefffff] and [0xfe000000; 264 * 0xfeffffff]. 269 265 */ 270 266 ofw_claim_phys(bootinfo.physmem_start + dest[i - 1], 271 267 ALIGN_UP(components[i - 1].inflated, PAGE_SIZE)); 268 269 ofw_map(bootinfo.physmem_start + dest[i - 1], dest[i - 1], 270 ALIGN_UP(components[i - 1].inflated, PAGE_SIZE), -1); 272 271 273 272 int err = inflate(components[i - 1].start, components[i - 1].size, … … 304 303 sun4u_smp(); 305 304 306 if (arch == ARCH_SUN4V)307 sun4v_fixups();308 309 305 printf("Booting the kernel ...\n"); 310 306 jump_to_kernel(bootinfo.physmem_start | BSP_PROCESSOR, &bootinfo, subarch, -
boot/generic/src/balloc.c
r51b46f2 re135751 65 65 void *balloc_rebase(void *ptr) 66 66 { 67 return (void *) (( uintptr_t) ptr - phys_base+ ballocs->base);67 return (void *) (((uintptr_t) ptr - phys_base) + ballocs->base); 68 68 } -
kernel/arch/sparc64/src/sun4v/asm.S
r51b46f2 re135751 41 41 .global switch_to_userspace 42 42 switch_to_userspace: 43 wrpr PSTATE_PRIV_BIT, %pstate 44 save %o1, -STACK_WINDOW_SAVE_AREA_SIZE, %sp 43 save %o1, -(STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE), %sp 45 44 flushw 46 45 wrpr %g0, 0, %cleanwin ! avoid information leak -
tools/toolchain.sh
r51b46f2 re135751 28 28 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 29 # 30 31 GMP_MAIN=<<EOF 32 #define GCC_GMP_VERSION_NUM(a, b, c) \ 33 (((a) << 16L) | ((b) << 8) | (c)) 34 35 #define GCC_GMP_VERSION \ 36 GCC_GMP_VERSION_NUM(__GNU_MP_VERSION, __GNU_MP_VERSION_MINOR, __GNU_MP_VERSION_PATCHLEVEL) 37 38 #if GCC_GMP_VERSION < GCC_GMP_VERSION_NUM(4,3,2) 39 choke me 40 #endif 41 EOF 42 43 MPFR_MAIN=<<EOF 44 #if MPFR_VERSION < MPFR_VERSION_NUM(2, 4, 2) 45 choke me 46 #endif 47 EOF 48 49 MPC_MAIN=<<EOF 50 #if MPC_VERSION < MPC_VERSION_NUM(0, 8, 1) 51 choke me 52 #endif 53 EOF 54 55 # 56 # Check if the library described in the argument 57 # exists and has acceptable version. 58 # 59 check_dependency() { 60 DEPENDENCY="$1" 61 HEADER="$2" 62 BODY="$3" 63 64 FNAME="/tmp/conftest-$$" 65 66 echo "#include ${HEADER}" > "${FNAME}.c" 67 echo >> "${FNAME}.c" 68 echo "int main()" >> "${FNAME}.c" 69 echo "{" >> "${FNAME}.c" 70 echo "${BODY}" >> "${FNAME}.c" 71 echo " return 0;" >> "${FNAME}.c" 72 echo "}" >> "${FNAME}.c" 73 74 cc -c -o "${FNAME}.o" "${FNAME}.c" 2> "${FNAME}.log" 75 RC="$?" 76 77 if [ "$RC" -ne "0" ] ; then 78 echo " ${DEPENDENCY} not found, too old or compiler error." 79 echo " Please recheck manually the source file \"${FNAME}.c\"." 80 echo " The compilation of the toolchain is probably going to fail," 81 echo " you have been warned." 82 echo 83 echo " ===== Compiler output =====" 84 cat "${FNAME}.log" 85 echo " ===========================" 86 echo 87 else 88 echo " ${DEPENDENCY} found" 89 rm -f "${FNAME}.log" "${FNAME}.o" "${FNAME}.c" 90 fi 91 } 92 93 check_dependecies() { 94 echo ">>> Basic dependency check" 95 check_dependency "GMP" "<gmp.h>" "${GMP_MAIN}" 96 check_dependency "MPFR" "<mpfr.h>" "${MPFR_MAIN}" 97 check_dependency "MPC" "<mpc.h>" "${MPC_MAIN}" 98 echo 99 } 30 100 31 101 check_error() { … … 69 139 echo " sparc64 SPARC V9" 70 140 echo " all build all targets" 141 echo 142 echo "The toolchain will be installed to the directory specified by" 143 echo "the CROSS_PREFIX environment variable. If the variable is not" 144 echo "defined, /usr/local will be used by default." 71 145 echo 72 146 … … 118 192 echo " - native C library with headers" 119 193 echo 120 121 show_countdown 10122 194 } 123 195 … … 281 353 282 354 show_dependencies 355 check_dependecies 356 show_countdown 10 283 357 284 358 case "$1" in -
uspace/app/bdsh/cmds/modules/mount/mount.c
r51b46f2 re135751 31 31 #include <vfs/vfs.h> 32 32 #include <errno.h> 33 #include <getopt.h> 33 34 #include "config.h" 34 35 #include "util.h" … … 40 41 static const char *cmdname = "mount"; 41 42 42 /* Dispays help for mount in various levels */ 43 static struct option const long_options[] = { 44 { "help", no_argument, 0, 'h' }, 45 { 0, 0, 0, 0 } 46 }; 47 48 49 /* Displays help for mount in various levels */ 43 50 void help_cmd_mount(unsigned int level) 44 51 { … … 59 66 unsigned int argc; 60 67 const char *mopts = ""; 61 int rc ;68 int rc, c, opt_ind; 62 69 63 70 argc = cli_count_args(argv); 64 71 72 for (c = 0, optind = 0, opt_ind = 0; c != -1;) { 73 c = getopt_long(argc, argv, "h", long_options, &opt_ind); 74 switch (c) { 75 case 'h': 76 help_cmd_mount(HELP_LONG); 77 return CMD_SUCCESS; 78 } 79 } 80 65 81 if ((argc < 4) || (argc > 5)) { 66 printf("%s: invalid number of arguments. \n",82 printf("%s: invalid number of arguments. Try `mount --help'\n", 67 83 cmdname); 68 84 return CMD_FAILURE; -
uspace/drv/pciintel/pci.c
r51b46f2 re135751 59 59 #include <ddi.h> 60 60 #include <libarch/ddi.h> 61 #include <pci_dev_iface.h> 61 62 62 63 #include "pci.h" … … 121 122 } 122 123 124 static int pci_config_space_write_16(ddf_fun_t *fun, uint32_t address, uint16_t data) 125 { 126 if (address > 254) 127 return EINVAL; 128 pci_conf_write_16(PCI_FUN(fun), address, data); 129 return EOK; 130 } 131 132 123 133 static hw_res_ops_t pciintel_hw_res_ops = { 124 134 &pciintel_get_resources, … … 126 136 }; 127 137 128 static ddf_dev_ops_t pci_fun_ops; 138 static pci_dev_iface_t pci_dev_ops = { 139 .config_space_read_8 = NULL, 140 .config_space_read_16 = NULL, 141 .config_space_read_32 = NULL, 142 .config_space_write_8 = NULL, 143 .config_space_write_16 = &pci_config_space_write_16, 144 .config_space_write_32 = NULL 145 }; 146 147 static ddf_dev_ops_t pci_fun_ops = { 148 .interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops, 149 .interfaces[PCI_DEV_IFACE] = &pci_dev_ops 150 }; 129 151 130 152 static int pci_add_device(ddf_dev_t *); … … 593 615 { 594 616 pci_fun_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops; 617 pci_fun_ops.interfaces[PCI_DEV_IFACE] = &pci_dev_ops; 595 618 } 596 619 -
uspace/drv/uhci-hcd/main.c
r51b46f2 re135751 34 34 #include <ddf/driver.h> 35 35 #include <ddf/interrupt.h> 36 #include <device/hw_res.h> 37 #include <errno.h> 38 #include <str_error.h> 39 36 40 #include <usb_iface.h> 37 41 #include <usb/ddfiface.h> 38 #include <device/hw_res.h>39 40 #include <errno.h>41 42 42 #include <usb/debug.h> 43 43 … … 50 50 51 51 static int uhci_add_device(ddf_dev_t *device); 52 53 52 /*----------------------------------------------------------------------------*/ 54 53 static driver_ops_t uhci_driver_ops = { … … 70 69 } 71 70 /*----------------------------------------------------------------------------*/ 72 #define CHECK_RET_RETURN(ret, message...) \73 if (ret != EOK) { \74 usb_log_error(message); \75 return ret; \76 }77 78 71 static int uhci_add_device(ddf_dev_t *device) 79 72 { 80 73 assert(device); 74 uhci_t *hcd = NULL; 75 #define CHECK_RET_FREE_HC_RETURN(ret, message...) \ 76 if (ret != EOK) { \ 77 usb_log_error(message); \ 78 if (hcd != NULL) \ 79 free(hcd); \ 80 return ret; \ 81 } 81 82 82 83 usb_log_info("uhci_add_device() called\n"); … … 88 89 int ret = 89 90 pci_get_my_registers(device, &io_reg_base, &io_reg_size, &irq); 90 91 CHECK_RET_RETURN(ret, 91 CHECK_RET_FREE_HC_RETURN(ret, 92 92 "Failed(%d) to get I/O addresses:.\n", ret, device->handle); 93 93 usb_log_info("I/O regs at 0x%X (size %zu), IRQ %d.\n", 94 94 io_reg_base, io_reg_size, irq); 95 95 96 // ret = pci_enable_interrupts(device); 97 // CHECK_RET_RETURN(ret, "Failed(%d) to get enable interrupts:\n", ret); 96 ret = pci_disable_legacy(device); 97 CHECK_RET_FREE_HC_RETURN(ret, 98 "Failed(%d) disable legacy USB: %s.\n", ret, str_error(ret)); 98 99 99 uhci_t *uhci_hc = malloc(sizeof(uhci_t)); 100 ret = (uhci_hc != NULL) ? EOK : ENOMEM; 101 CHECK_RET_RETURN(ret, "Failed to allocate memory for uhci hcd driver.\n"); 100 #if 0 101 ret = pci_enable_interrupts(device); 102 if (ret != EOK) { 103 usb_log_warning( 104 "Failed(%d) to enable interrupts, fall back to polling.\n", 105 ret); 106 } 107 #endif 102 108 103 ret = uhci_init(uhci_hc, device, (void*)io_reg_base, io_reg_size); 104 if (ret != EOK) { 105 usb_log_error("Failed to init uhci-hcd.\n"); 106 free(uhci_hc); 107 return ret; 108 } 109 hcd = malloc(sizeof(uhci_t)); 110 ret = (hcd != NULL) ? EOK : ENOMEM; 111 CHECK_RET_FREE_HC_RETURN(ret, 112 "Failed(%d) to allocate memory for uhci hcd.\n", ret); 113 114 ret = uhci_init(hcd, device, (void*)io_reg_base, io_reg_size); 115 CHECK_RET_FREE_HC_RETURN(ret, "Failed(%d) to init uhci-hcd.\n", 116 ret); 117 #undef CHECK_RET_FREE_HC_RETURN 109 118 110 119 /* 111 * We might free uhci_hc, but that does not matter since no one120 * We might free hcd, but that does not matter since no one 112 121 * else would access driver_data anyway. 113 122 */ 114 device->driver_data = uhci_hc; 123 device->driver_data = hcd; 124 125 ddf_fun_t *rh = NULL; 126 #define CHECK_RET_FINI_FREE_RETURN(ret, message...) \ 127 if (ret != EOK) { \ 128 usb_log_error(message); \ 129 if (hcd != NULL) {\ 130 uhci_fini(hcd); \ 131 free(hcd); \ 132 } \ 133 if (rh != NULL) \ 134 free(rh); \ 135 return ret; \ 136 } 137 138 /* It does no harm if we register this on polling */ 115 139 ret = register_interrupt_handler(device, irq, irq_handler, 116 &uhci_hc->interrupt_code); 117 if (ret != EOK) { 118 usb_log_error("Failed to register interrupt handler.\n"); 119 uhci_fini(uhci_hc); 120 free(uhci_hc); 121 return ret; 122 } 140 &hcd->interrupt_code); 141 CHECK_RET_FINI_FREE_RETURN(ret, 142 "Failed(%d) to register interrupt handler.\n", ret); 123 143 124 ddf_fun_t *rh;125 144 ret = setup_root_hub(&rh, device); 126 if (ret != EOK) { 127 usb_log_error("Failed to setup uhci root hub.\n"); 128 uhci_fini(uhci_hc); 129 free(uhci_hc); 130 return ret; 131 } 132 rh->driver_data = uhci_hc->ddf_instance; 145 CHECK_RET_FINI_FREE_RETURN(ret, 146 "Failed(%d) to setup UHCI root hub.\n", ret); 147 rh->driver_data = hcd->ddf_instance; 133 148 134 149 ret = ddf_fun_bind(rh); 135 if (ret != EOK) { 136 usb_log_error("Failed to register root hub.\n"); 137 uhci_fini(uhci_hc); 138 free(uhci_hc); 139 free(rh); 140 return ret; 141 } 150 CHECK_RET_FINI_FREE_RETURN(ret, 151 "Failed(%d) to register UHCI root hub.\n", ret); 142 152 143 153 return EOK; 154 #undef CHECK_RET_FINI_FREE_RETURN 144 155 } 145 156 /*----------------------------------------------------------------------------*/ -
uspace/drv/uhci-hcd/pci.c
r51b46f2 re135751 40 40 41 41 #include <usb/debug.h> 42 #include <pci_dev_iface.h> 42 43 43 44 #include "pci.h" … … 128 129 return enabled ? EOK : EIO; 129 130 } 131 /*----------------------------------------------------------------------------*/ 132 int pci_disable_legacy(ddf_dev_t *device) 133 { 134 assert(device); 135 int parent_phone = devman_parent_device_connect(device->handle, 136 IPC_FLAG_BLOCKING); 137 if (parent_phone < 0) { 138 return parent_phone; 139 } 140 141 /* See UHCI design guide for these values, 142 * write all WC bits in USB legacy register */ 143 sysarg_t address = 0xc0; 144 sysarg_t value = 0x8f00; 145 146 int rc = async_req_3_0(parent_phone, DEV_IFACE_ID(PCI_DEV_IFACE), 147 IPC_M_CONFIG_SPACE_WRITE_16, address, value); 148 async_hangup(parent_phone); 149 150 return rc; 151 } 152 /*----------------------------------------------------------------------------*/ 130 153 /** 131 154 * @} -
uspace/drv/uhci-hcd/pci.h
r51b46f2 re135751 40 40 int pci_get_my_registers(ddf_dev_t *, uintptr_t *, size_t *, int *); 41 41 int pci_enable_interrupts(ddf_dev_t *); 42 int pci_disable_legacy(ddf_dev_t *); 42 43 43 44 #endif -
uspace/drv/uhci-hcd/uhci.c
r51b46f2 re135751 90 90 .interfaces[USBHC_DEV_IFACE] = &uhci_iface, 91 91 }; 92 92 /*----------------------------------------------------------------------------*/ 93 93 static int uhci_init_transfer_lists(uhci_t *instance); 94 94 static int uhci_init_mem_structures(uhci_t *instance); … … 115 115 } else (void) 0 116 116 117 /* 118 * Create UHCI function. 119 */ 117 /* Create UHCI function. */ 120 118 instance->ddf_instance = ddf_fun_create(dev, fun_exposed, "uhci"); 121 119 ret = (instance->ddf_instance == NULL) ? ENOMEM : EOK; 122 CHECK_RET_DEST_FUN_RETURN(ret, "Failed to create UHCI device function.\n"); 120 CHECK_RET_DEST_FUN_RETURN(ret, 121 "Failed to create UHCI device function.\n"); 123 122 124 123 instance->ddf_instance->ops = &uhci_ops; … … 126 125 127 126 ret = ddf_fun_bind(instance->ddf_instance); 128 CHECK_RET_DEST_FUN_RETURN(ret, "Failed(%d) to bind UHCI device function: %s.\n", 127 CHECK_RET_DEST_FUN_RETURN(ret, 128 "Failed(%d) to bind UHCI device function: %s.\n", 129 129 ret, str_error(ret)); 130 130 … … 132 132 regs_t *io; 133 133 ret = pio_enable(regs, reg_size, (void**)&io); 134 CHECK_RET_DEST_FUN_RETURN(ret, "Failed(%d) to gain access to registers at %p: %s.\n", 134 CHECK_RET_DEST_FUN_RETURN(ret, 135 "Failed(%d) to gain access to registers at %p: %s.\n", 135 136 ret, str_error(ret), io); 136 137 instance->registers = io; 137 usb_log_debug("Device registers at %p(%u) accessible.\n", io, reg_size); 138 usb_log_debug("Device registers at %p(%u) accessible.\n", 139 io, reg_size); 138 140 139 141 ret = uhci_init_mem_structures(instance); 140 CHECK_RET_DEST_FUN_RETURN(ret, "Failed to initialize UHCI memory structures.\n"); 142 CHECK_RET_DEST_FUN_RETURN(ret, 143 "Failed to initialize UHCI memory structures.\n"); 141 144 142 145 uhci_init_hw(instance); 143 144 instance->cleaner =fibril_create(uhci_interrupt_emulator, instance);146 instance->cleaner = 147 fibril_create(uhci_interrupt_emulator, instance); 145 148 fibril_add_ready(instance->cleaner); 146 149 … … 155 158 void uhci_init_hw(uhci_t *instance) 156 159 { 160 assert(instance); 161 157 162 /* reset everything, who knows what touched it before us */ 158 163 pio_write_16(&instance->registers->usbcmd, UHCI_CMD_GLOBAL_RESET); … … 171 176 /* enable all interrupts, but resume interrupt */ 172 177 pio_write_16(&instance->registers->usbintr, 173 178 UHCI_INTR_CRC | UHCI_INTR_COMPLETE | UHCI_INTR_SHORT_PACKET); 174 179 175 180 /* Start the hc with large(64B) packet FSBR */ … … 200 205 interrupt_commands[1].addr = (void*)&instance->registers->usbsts; 201 206 instance->interrupt_code.cmdcount = 202 207 sizeof(uhci_cmds) / sizeof(irq_cmd_t); 203 208 } 204 209 … … 249 254 ret = transfer_list_init(&instance->transfers_bulk_full, "BULK_FULL"); 250 255 CHECK_RET_CLEAR_RETURN(ret, "Failed to init BULK list."); 256 251 257 ret = transfer_list_init(&instance->transfers_control_full, "CONTROL_FULL"); 252 258 CHECK_RET_CLEAR_RETURN(ret, "Failed to init CONTROL FULL list."); 259 253 260 ret = transfer_list_init(&instance->transfers_control_slow, "CONTROL_SLOW"); 254 261 CHECK_RET_CLEAR_RETURN(ret, "Failed to init CONTROL SLOW list."); 262 255 263 ret = transfer_list_init(&instance->transfers_interrupt, "INTERRUPT"); 256 264 CHECK_RET_CLEAR_RETURN(ret, "Failed to init INTERRUPT list."); … … 292 300 low_speed, batch->transfer_type, batch->max_packet_size)) { 293 301 usb_log_warning("Invalid USB packet specified %s SPEED %d %zu.\n", 294 302 low_speed ? "LOW" : "FULL" , batch->transfer_type, 295 303 batch->max_packet_size); 296 304 return ENOTSUP; … … 309 317 { 310 318 assert(instance); 311 // if ((status & (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)) == 0)312 // return;313 // usb_log_debug2("UHCI interrupt: %X.\n", status);314 319 transfer_list_remove_finished(&instance->transfers_interrupt); 315 320 transfer_list_remove_finished(&instance->transfers_control_slow); … … 340 345 uhci_t *instance = (uhci_t*)arg; 341 346 assert(instance); 347 348 #define QH(queue) \ 349 instance->transfers_##queue.queue_head 350 342 351 while (1) { 343 352 const uint16_t cmd = pio_read_16(&instance->registers->usbcmd); 344 353 const uint16_t sts = pio_read_16(&instance->registers->usbsts); 345 const uint16_t intr = pio_read_16(&instance->registers->usbintr); 354 const uint16_t intr = 355 pio_read_16(&instance->registers->usbintr); 356 346 357 if (((cmd & UHCI_CMD_RUN_STOP) != 1) || (sts != 0)) { 347 358 usb_log_debug2("Command: %X Status: %X Intr: %x\n", … … 353 364 if (frame_list != addr_to_phys(instance->frame_list)) { 354 365 usb_log_debug("Framelist address: %p vs. %p.\n", 355 frame_list, addr_to_phys(instance->frame_list)); 356 } 366 frame_list, addr_to_phys(instance->frame_list)); 367 } 368 357 369 int frnum = pio_read_16(&instance->registers->frnum) & 0x3ff; 358 370 usb_log_debug2("Framelist item: %d \n", frnum ); 359 371 360 queue_head_t* qh = instance->transfers_interrupt.queue_head;361 362 if ( (instance->frame_list[frnum] & (~0xf)) != (uintptr_t)addr_to_phys(qh)) {372 uintptr_t expected_pa = instance->frame_list[frnum] & (~0xf); 373 uintptr_t real_pa = addr_to_phys(QH(interrupt)); 374 if (expected_pa != real_pa) { 363 375 usb_log_debug("Interrupt QH: %p vs. %p.\n", 364 instance->frame_list[frnum] & (~0xf), addr_to_phys(qh)); 365 } 366 367 if ((qh->next_queue & (~0xf)) 368 != (uintptr_t)addr_to_phys(instance->transfers_control_slow.queue_head)) { 369 usb_log_debug("Control Slow QH: %p vs. %p.\n", qh->next_queue & (~0xf), 370 addr_to_phys(instance->transfers_control_slow.queue_head)); 371 } 372 qh = instance->transfers_control_slow.queue_head; 373 374 if ((qh->next_queue & (~0xf)) 375 != (uintptr_t)addr_to_phys(instance->transfers_control_full.queue_head)) { 376 usb_log_debug("Control Full QH: %p vs. %p.\n", qh->next_queue & (~0xf), 377 addr_to_phys(instance->transfers_control_full.queue_head));\ 378 } 379 qh = instance->transfers_control_full.queue_head; 380 381 if ((qh->next_queue & (~0xf)) 382 != (uintptr_t)addr_to_phys(instance->transfers_bulk_full.queue_head)) { 383 usb_log_debug("Bulk QH: %p vs. %p.\n", qh->next_queue & (~0xf), 384 addr_to_phys(instance->transfers_bulk_full.queue_head)); 385 } 386 /* 387 uint16_t cmd = pio_read_16(&instance->registers->usbcmd); 388 cmd |= UHCI_CMD_RUN_STOP; 389 pio_write_16(&instance->registers->usbcmd, cmd); 390 */ 376 expected_pa, real_pa); 377 } 378 379 expected_pa = QH(interrupt)->next_queue & (~0xf); 380 real_pa = addr_to_phys(QH(control_slow)); 381 if (expected_pa != real_pa) { 382 usb_log_debug("Control Slow QH: %p vs. %p.\n", 383 expected_pa, real_pa); 384 } 385 386 expected_pa = QH(control_slow)->next_queue & (~0xf); 387 real_pa = addr_to_phys(QH(control_full)); 388 if (expected_pa != real_pa) { 389 usb_log_debug("Control Full QH: %p vs. %p.\n", 390 expected_pa, real_pa); 391 } 392 393 expected_pa = QH(control_full)->next_queue & (~0xf); 394 real_pa = addr_to_phys(QH(bulk_full)); 395 if (expected_pa != real_pa ) { 396 usb_log_debug("Bulk QH: %p vs. %p.\n", 397 expected_pa, real_pa); 398 } 391 399 async_usleep(UHCI_DEBUGER_TIMEOUT); 392 400 } 393 401 return 0; 402 #undef QH 394 403 } 395 404 /*----------------------------------------------------------------------------*/ 396 405 bool allowed_usb_packet( 397 406 bool low_speed, usb_transfer_type_t transfer, size_t size) 398 407 { 399 408 /* see USB specification chapter 5.5-5.8 for magic numbers used here */ 400 switch(transfer) { 401 case USB_TRANSFER_ISOCHRONOUS: 402 return (!low_speed && size < 1024); 403 case USB_TRANSFER_INTERRUPT: 404 return size <= (low_speed ? 8 : 64); 405 case USB_TRANSFER_CONTROL: /* device specifies its own max size */ 406 return (size <= (low_speed ? 8 : 64)); 407 case USB_TRANSFER_BULK: /* device specifies its own max size */ 408 return (!low_speed && size <= 64); 409 switch(transfer) 410 { 411 case USB_TRANSFER_ISOCHRONOUS: 412 return (!low_speed && size < 1024); 413 case USB_TRANSFER_INTERRUPT: 414 return size <= (low_speed ? 8 : 64); 415 case USB_TRANSFER_CONTROL: /* device specifies its own max size */ 416 return (size <= (low_speed ? 8 : 64)); 417 case USB_TRANSFER_BULK: /* device specifies its own max size */ 418 return (!low_speed && size <= 64); 409 419 } 410 420 return false; -
uspace/drv/usbhid/Makefile
r51b46f2 re135751 40 40 main.c \ 41 41 conv.c \ 42 hidreq.c \ 43 kbddev.c \ 44 hiddev.c \ 42 45 $(STOLEN_LAYOUT_SOURCES) 43 46 -
uspace/drv/usbhid/conv.c
r51b46f2 re135751 163 163 }; 164 164 165 unsigned int usb kbd_parse_scancode(int scancode)165 unsigned int usbhid_parse_scancode(int scancode) 166 166 { 167 // console_ev_type_t type;168 167 unsigned int key; 169 168 int *map = scanmap_simple; 170 169 size_t map_length = sizeof(scanmap_simple) / sizeof(int); 171 172 /*173 * ACK/NAK are returned as response to us sending a command.174 * We are not interested in them.175 */176 // if (scancode == SC_ACK || scancode == SC_NAK)177 // return;178 179 // if (scancode == 0xe0) {180 // ds = ds_e;181 // return;182 // }183 184 // switch (ds) {185 // case ds_s:186 // map = scanmap_simple;187 // map_length = sizeof(scanmap_simple) / sizeof(int);188 // break;189 // case ds_e:190 // map = scanmap_e0;191 // map_length = sizeof(scanmap_e0) / sizeof(int);192 // break;193 // default:194 // map = NULL;195 // map_length = 0;196 // }197 198 // ds = ds_s;199 200 // if (scancode & 0x80) {201 // scancode &= ~0x80;202 // type = KEY_RELEASE;203 // } else {204 // type = KEY_PRESS;205 // }206 170 207 171 if ((scancode < 0) || ((size_t) scancode >= map_length)) … … 210 174 key = map[scancode]; 211 175 212 if (scancode == 0x53) {213 usb_log_debug("\n\nWe have a NUM LOCK!, sending key %u\n\n", key);214 }215 216 if (scancode == 0x47) {217 usb_log_debug("\n\nWe have a SCROLL LOCK!, sending key %u\n\n", key);218 }219 220 if (scancode == 0x39) {221 usb_log_debug("\n\nWe have a CAPS LOCK!, sending key %u\n\n", key);222 }223 224 // if (key != 0)225 // kbd_push_ev(type, key);226 176 return key; 227 177 } -
uspace/drv/usbhid/conv.h
r51b46f2 re135751 37 37 #define USBHID_CONV_H_ 38 38 39 unsigned int usb kbd_parse_scancode(int scancode);39 unsigned int usbhid_parse_scancode(int scancode); 40 40 41 #endif 41 #endif /* USBHID_CONV_H_ */ 42 42 43 43 /** -
uspace/drv/usbhid/descdump.h
r51b46f2 re135751 37 37 #define USBHID_DESCDUMP_H_ 38 38 39 #include "hid.h" 39 #include <usb/descriptor.h> 40 #include <usb/classes/hid.h> 40 41 41 42 void dump_standard_configuration_descriptor( -
uspace/drv/usbhid/main.c
r51b46f2 re135751 37 37 38 38 #include <ddf/driver.h> 39 #include <ipc/driver.h> 40 #include <ipc/kbd.h> 41 #include <io/keycode.h> 42 #include <io/console.h> 39 #include <usb/debug.h> 43 40 #include <errno.h> 44 #include <str_error.h>45 #include <fibril.h>46 #include <usb/debug.h>47 #include <usb/classes/classes.h>48 #include <usb/classes/hid.h>49 #include <usb/classes/hidparser.h>50 #include <usb/request.h>51 #include <usb/descriptor.h>52 #include <io/console.h>53 #include <stdint.h>54 #include <usb/dp.h>55 #include "hid.h"56 #include "conv.h"57 #include "layout.h"58 41 59 #define BUFFER_SIZE 8 60 #define BUFFER_OUT_SIZE 1 42 #include "kbddev.h" 43 44 /*----------------------------------------------------------------------------*/ 45 61 46 #define NAME "usbhid" 62 47 63 //#define GUESSED_POLL_ENDPOINT 1 64 #define BOOTP_REPORT_SIZE 6 48 /*----------------------------------------------------------------------------*/ 65 49 66 static unsigned DEFAULT_ACTIVE_MODS = KM_NUM_LOCK; 67 68 /** Keyboard polling endpoint description for boot protocol class. */ 69 static usb_endpoint_description_t poll_endpoint_description = { 70 .transfer_type = USB_TRANSFER_INTERRUPT, 71 .direction = USB_DIRECTION_IN, 72 .interface_class = USB_CLASS_HID, 73 .interface_subclass = USB_HID_SUBCLASS_BOOT, 74 .interface_protocol = USB_HID_PROTOCOL_KEYBOARD, 75 .flags = 0 76 }; 77 78 static void default_connection_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *); 79 static ddf_dev_ops_t keyboard_ops = { 80 .default_handler = default_connection_handler 81 }; 82 83 static int console_callback_phone = -1; 84 85 /** Default handler for IPC methods not handled by DDF. 86 * 87 * @param dev Device handling the call. 88 * @param icallid Call id. 89 * @param icall Call data. 90 */ 91 void default_connection_handler(ddf_fun_t *fun, 92 ipc_callid_t icallid, ipc_call_t *icall) 50 static int usbhid_add_device(ddf_dev_t *dev) 93 51 { 94 sysarg_t method = IPC_GET_IMETHOD(*icall); 95 96 if (method == IPC_M_CONNECT_TO_ME) { 97 int callback = IPC_GET_ARG5(*icall); 98 99 if (console_callback_phone != -1) { 100 async_answer_0(icallid, ELIMIT); 101 return; 102 } 103 104 console_callback_phone = callback; 105 async_answer_0(icallid, EOK); 106 return; 52 usb_log_debug("usbhid_add_device()\n"); 53 54 int rc = usbhid_kbd_try_add_device(dev); 55 56 if (rc != EOK) { 57 usb_log_info("Device is not a supported keyboard.\n"); 58 usb_log_error("Failed to add HID device.\n"); 59 return EREFUSED; 107 60 } 108 109 async_answer_0(icallid, EINVAL);110 }111 112 #if 0113 static void send_key(int key, int type, wchar_t c) {114 async_msg_4(console_callback_phone, KBD_EVENT, type, key,115 KM_NUM_LOCK, c);116 }117 #endif118 119 /*120 * TODO: Move somewhere else121 */122 /*123 #define BYTES_PER_LINE 12124 125 static void dump_buffer(const char *msg, const uint8_t *buffer, size_t length)126 {uint8_t buffer[BUFFER_SIZE];127 printf("%s\n", msg);128 129 size_t i;130 for (i = 0; i < length; i++) {131 printf(" 0x%02X", buffer[i]);132 if (((i > 0) && (((i+1) % BYTES_PER_LINE) == 0))133 || (i + 1 == length)) {134 printf("\n");135 }136 }137 }138 */139 /*140 * Copy-paste from srv/hid/kbd/generic/kbd.c141 */142 143 /** Currently active modifiers (locks is probably better word).144 *145 * TODO: put to device?146 */147 //static unsigned mods = KM_NUM_LOCK;148 149 /** Currently pressed lock keys. We track these to tackle autorepeat.150 *151 * TODO: put to device?152 */153 //static unsigned lock_keys;154 155 #define NUM_LAYOUTS 3156 157 static layout_op_t *layout[NUM_LAYOUTS] = {158 &us_qwerty_op,159 &us_dvorak_op,160 &cz_op161 };162 163 static int active_layout = 0;164 165 static void usbkbd_req_set_report(usb_hid_dev_kbd_t *kbd_dev, uint16_t iface,166 usb_hid_report_type_t type, uint8_t *buffer, size_t buf_size)167 {168 int rc, sess_rc;169 170 sess_rc = usb_endpoint_pipe_start_session(&kbd_dev->ctrl_pipe);171 if (sess_rc != EOK) {172 usb_log_warning("Failed to start a session: %s.\n",173 str_error(sess_rc));174 return;175 }176 177 usb_log_debug("Sending Set_Report request to the device.\n");178 179 rc = usb_control_request_set(&kbd_dev->ctrl_pipe,180 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,181 USB_HIDREQ_SET_REPORT, type, iface, buffer, buf_size);182 183 sess_rc = usb_endpoint_pipe_end_session(&kbd_dev->ctrl_pipe);184 185 if (rc != EOK) {186 usb_log_warning("Error sending output report to the keyboard: "187 "%s.\n", str_error(rc));188 return;189 }190 191 if (sess_rc != EOK) {192 usb_log_warning("Error closing session: %s.\n",193 str_error(sess_rc));194 return;195 }196 }197 198 static void usbkbd_req_set_protocol(usb_hid_dev_kbd_t *kbd_dev,199 usb_hid_protocol_t protocol)200 {201 int rc, sess_rc;202 203 sess_rc = usb_endpoint_pipe_start_session(&kbd_dev->ctrl_pipe);204 if (sess_rc != EOK) {205 usb_log_warning("Failed to start a session: %s.\n",206 str_error(sess_rc));207 return;208 }209 210 usb_log_debug("Sending Set_Protocol request to the device ("211 "protocol: %d, iface: %d).\n", protocol, kbd_dev->iface);212 213 rc = usb_control_request_set(&kbd_dev->ctrl_pipe,214 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,215 USB_HIDREQ_SET_PROTOCOL, protocol, kbd_dev->iface, NULL, 0);216 217 sess_rc = usb_endpoint_pipe_end_session(&kbd_dev->ctrl_pipe);218 219 if (rc != EOK) {220 usb_log_warning("Error sending output report to the keyboard: "221 "%s.\n", str_error(rc));222 return;223 }224 225 if (sess_rc != EOK) {226 usb_log_warning("Error closing session: %s.\n",227 str_error(sess_rc));228 return;229 }230 }231 232 static void usbkbd_set_led(usb_hid_dev_kbd_t *kbd_dev)233 {234 uint8_t buffer[BUFFER_OUT_SIZE];235 int rc= 0, i;236 237 memset(buffer, 0, BUFFER_OUT_SIZE);238 uint8_t leds = 0;239 240 if (kbd_dev->mods & KM_NUM_LOCK) {241 leds |= USB_HID_LED_NUM_LOCK;242 }243 244 if (kbd_dev->mods & KM_CAPS_LOCK) {245 leds |= USB_HID_LED_CAPS_LOCK;246 }247 248 if (kbd_dev->mods & KM_SCROLL_LOCK) {249 leds |= USB_HID_LED_SCROLL_LOCK;250 }251 252 // TODO: COMPOSE and KANA253 254 usb_log_debug("Creating output report.\n");255 usb_log_debug("Leds: 0x%x\n", leds);256 if ((rc = usb_hid_boot_keyboard_output_report(257 leds, buffer, BUFFER_OUT_SIZE)) != EOK) {258 usb_log_warning("Error composing output report to the keyboard:"259 "%s.\n", str_error(rc));260 return;261 }262 263 usb_log_debug("Output report buffer: ");264 for (i = 0; i < BUFFER_OUT_SIZE; ++i) {265 usb_log_debug("0x%x ", buffer[i]);266 }267 usb_log_debug("\n");268 269 uint16_t value = 0;270 value |= (USB_HID_REPORT_TYPE_OUTPUT << 8);271 272 usbkbd_req_set_report(kbd_dev, kbd_dev->iface, value, buffer,273 BUFFER_OUT_SIZE);274 }275 276 static void kbd_push_ev(int type, unsigned int key, usb_hid_dev_kbd_t *kbd_dev)277 {278 console_event_t ev;279 unsigned mod_mask;280 281 // TODO: replace by our own parsing?? or are the key codes identical??282 switch (key) {283 case KC_LCTRL: mod_mask = KM_LCTRL; break;284 case KC_RCTRL: mod_mask = KM_RCTRL; break;285 case KC_LSHIFT: mod_mask = KM_LSHIFT; break;286 case KC_RSHIFT: mod_mask = KM_RSHIFT; break;287 case KC_LALT: mod_mask = KM_LALT; break;288 case KC_RALT: mod_mask = KM_RALT; break;289 default: mod_mask = 0; break;290 }291 292 if (mod_mask != 0) {293 if (type == KEY_PRESS)294 kbd_dev->mods = kbd_dev->mods | mod_mask;295 else296 kbd_dev->mods = kbd_dev->mods & ~mod_mask;297 }298 299 switch (key) {300 case KC_CAPS_LOCK: mod_mask = KM_CAPS_LOCK; usb_log_debug2("\n\nPushing CAPS LOCK! (mask: %u)\n\n", mod_mask); break;301 case KC_NUM_LOCK: mod_mask = KM_NUM_LOCK; usb_log_debug2("\n\nPushing NUM LOCK! (mask: %u)\n\n", mod_mask); break;302 case KC_SCROLL_LOCK: mod_mask = KM_SCROLL_LOCK; usb_log_debug2("\n\nPushing SCROLL LOCK! (mask: %u)\n\n", mod_mask); break;303 default: mod_mask = 0; break;304 }305 306 if (mod_mask != 0) {307 usb_log_debug2("\n\nChanging mods and lock keys\n");308 usb_log_debug2("\nmods before: 0x%x\n", kbd_dev->mods);309 usb_log_debug2("\nLock keys before:0x%x\n\n", kbd_dev->lock_keys);310 311 if (type == KEY_PRESS) {312 usb_log_debug2("\nKey pressed.\n");313 /*314 * Only change lock state on transition from released315 * to pressed. This prevents autorepeat from messing316 * up the lock state.317 */318 kbd_dev->mods =319 kbd_dev->mods ^ (mod_mask & ~kbd_dev->lock_keys);320 kbd_dev->lock_keys = kbd_dev->lock_keys | mod_mask;321 322 /* Update keyboard lock indicator lights. */323 usbkbd_set_led(kbd_dev);324 } else {325 usb_log_debug2("\nKey released.\n");326 kbd_dev->lock_keys = kbd_dev->lock_keys & ~mod_mask;327 }328 }329 330 usb_log_debug2("\n\nmods after: 0x%x\n", kbd_dev->mods);331 usb_log_debug2("\nLock keys after: 0x%x\n\n", kbd_dev->lock_keys);332 333 if (type == KEY_PRESS && (kbd_dev->mods & KM_LCTRL) && key == KC_F1) {334 active_layout = 0;335 layout[active_layout]->reset();336 return;337 }338 339 if (type == KEY_PRESS && (kbd_dev->mods & KM_LCTRL) && key == KC_F2) {340 active_layout = 1;341 layout[active_layout]->reset();342 return;343 }344 345 if (type == KEY_PRESS && (kbd_dev->mods & KM_LCTRL) && key == KC_F3) {346 active_layout = 2;347 layout[active_layout]->reset();348 return;349 }350 351 ev.type = type;352 ev.key = key;353 ev.mods = kbd_dev->mods;354 355 if (ev.mods & KM_NUM_LOCK) {356 usb_log_debug("\n\nNum Lock turned on.\n\n");357 }358 359 ev.c = layout[active_layout]->parse_ev(&ev);360 361 usb_log_debug2("Sending key %d to the console\n", ev.key);362 assert(console_callback_phone != -1);363 async_msg_4(console_callback_phone, KBD_EVENT, ev.type, ev.key,364 ev.mods, ev.c);365 }366 /*367 * End of copy-paste368 */369 370 /*371 * TODO:372 * 1) key press / key release - how does the keyboard notify about373 * release?374 * 2) layouts (use the already defined), not important now375 * 3)376 */377 378 static const keycode_t usb_hid_modifiers_keycodes[USB_HID_MOD_COUNT] = {379 KC_LCTRL, /* USB_HID_MOD_LCTRL */380 KC_LSHIFT, /* USB_HID_MOD_LSHIFT */381 KC_LALT, /* USB_HID_MOD_LALT */382 0, /* USB_HID_MOD_LGUI */383 KC_RCTRL, /* USB_HID_MOD_RCTRL */384 KC_RSHIFT, /* USB_HID_MOD_RSHIFT */385 KC_RALT, /* USB_HID_MOD_RALT */386 0, /* USB_HID_MOD_RGUI */387 };388 389 static void usbkbd_check_modifier_changes(usb_hid_dev_kbd_t *kbd_dev,390 uint8_t modifiers)391 {392 /*393 * TODO: why the USB keyboard has NUM_, SCROLL_ and CAPS_LOCK394 * both as modifiers and as keys with their own scancodes???395 *396 * modifiers should be sent as normal keys to usbkbd_parse_scancode()!!397 * so maybe it would be better if I received it from report parser in398 * that way399 */400 401 int i;402 for (i = 0; i < USB_HID_MOD_COUNT; ++i) {403 if ((modifiers & usb_hid_modifiers_consts[i]) &&404 !(kbd_dev->modifiers & usb_hid_modifiers_consts[i])) {405 // modifier pressed406 if (usb_hid_modifiers_keycodes[i] != 0) {407 kbd_push_ev(KEY_PRESS,408 usb_hid_modifiers_keycodes[i], kbd_dev);409 }410 } else if (!(modifiers & usb_hid_modifiers_consts[i]) &&411 (kbd_dev->modifiers & usb_hid_modifiers_consts[i])) {412 // modifier released413 if (usb_hid_modifiers_keycodes[i] != 0) {414 kbd_push_ev(KEY_RELEASE,415 usb_hid_modifiers_keycodes[i], kbd_dev);416 }417 } // no change418 }419 420 kbd_dev->modifiers = modifiers;421 }422 423 static void usbkbd_check_key_changes(usb_hid_dev_kbd_t *kbd_dev,424 const uint8_t *key_codes)425 {426 // TODO: phantom state!!427 428 unsigned int key;429 unsigned int i, j;430 431 // TODO: quite dummy right now, think of better implementation432 433 // key releases434 for (j = 0; j < kbd_dev->keycode_count; ++j) {435 // try to find the old key in the new key list436 i = 0;437 while (i < kbd_dev->keycode_count438 && key_codes[i] != kbd_dev->keycodes[j]) {439 ++i;440 }441 442 if (i == kbd_dev->keycode_count) {443 // not found, i.e. the key was released444 key = usbkbd_parse_scancode(kbd_dev->keycodes[j]);445 kbd_push_ev(KEY_RELEASE, key, kbd_dev);446 usb_log_debug2("\nKey released: %d\n", key);447 } else {448 // found, nothing happens449 }450 }451 452 // key presses453 for (i = 0; i < kbd_dev->keycode_count; ++i) {454 // try to find the new key in the old key list455 j = 0;456 while (j < kbd_dev->keycode_count457 && kbd_dev->keycodes[j] != key_codes[i]) {458 ++j;459 }460 461 if (j == kbd_dev->keycode_count) {462 // not found, i.e. new key pressed463 key = usbkbd_parse_scancode(key_codes[i]);464 usb_log_debug2("\nKey pressed: %d (keycode: %d)\n", key,465 key_codes[i]);466 kbd_push_ev(KEY_PRESS, key, kbd_dev);467 } else {468 // found, nothing happens469 }470 }471 472 memcpy(kbd_dev->keycodes, key_codes, kbd_dev->keycode_count);473 474 usb_log_debug2("\nNew stored keycodes: ");475 for (i = 0; i < kbd_dev->keycode_count; ++i) {476 usb_log_debug2("%d ", kbd_dev->keycodes[i]);477 }478 }479 480 /*481 * Callbacks for parser482 */483 static void usbkbd_process_keycodes(const uint8_t *key_codes, size_t count,484 uint8_t modifiers, void *arg)485 {486 if (arg == NULL) {487 usb_log_warning("Missing argument in callback "488 "usbkbd_process_keycodes().\n");489 return;490 }491 492 usb_log_debug2("Got keys from parser: ");493 unsigned i;494 for (i = 0; i < count; ++i) {495 usb_log_debug2("%d ", key_codes[i]);496 }497 usb_log_debug2("\n");498 499 usb_hid_dev_kbd_t *kbd_dev = (usb_hid_dev_kbd_t *)arg;500 501 if (count != kbd_dev->keycode_count) {502 usb_log_warning("Number of received keycodes (%d) differs from"503 " expected number (%d).\n", count, kbd_dev->keycode_count);504 return;505 }506 507 usbkbd_check_modifier_changes(kbd_dev, modifiers);508 usbkbd_check_key_changes(kbd_dev, key_codes);509 }510 511 /*512 * Kbd functions513 */514 //static int usbkbd_get_report_descriptor(usb_hid_dev_kbd_t *kbd_dev)515 //{516 // // iterate over all configurations and interfaces517 // // TODO: more configurations!!518 // unsigned i;519 // for (i = 0; i < kbd_dev->conf->config_descriptor.interface_count; ++i) {520 // // TODO: endianness521 // uint16_t length = kbd_dev->conf->interfaces[i].hid_desc.522 // report_desc_info.length;523 // size_t actual_size = 0;524 525 // // allocate space for the report descriptor526 // kbd_dev->conf->interfaces[i].report_desc =527 // (uint8_t *)malloc(length);528 529 // // get the descriptor from the device530 // int rc = usb_request_get_descriptor(&kbd_dev->ctrl_pipe,531 // USB_REQUEST_TYPE_CLASS, USB_DESCTYPE_HID_REPORT,532 // i, 0,533 // kbd_dev->conf->interfaces[i].report_desc, length,534 // &actual_size);535 536 // if (rc != EOK) {537 // return rc;538 // }539 540 // assert(actual_size == length);541 542 // //dump_hid_class_descriptor(0, USB_DESCTYPE_HID_REPORT,543 // // kbd_dev->conf->interfaces[i].report_desc, length);544 // }545 546 // return EOK;547 //}548 549 static int usbkbd_get_report_descriptor(usb_hid_dev_kbd_t *kbd_dev,550 uint8_t *config_desc, size_t config_desc_size, uint8_t *iface_desc)551 {552 assert(kbd_dev != NULL);553 assert(config_desc != NULL);554 assert(config_desc_size != 0);555 assert(iface_desc != NULL);556 557 usb_dp_parser_t parser = {558 .nesting = usb_dp_standard_descriptor_nesting559 };560 561 usb_dp_parser_data_t parser_data = {562 .data = config_desc,563 .size = config_desc_size,564 .arg = NULL565 };566 567 /*568 * First nested descriptor of interface descriptor.569 */570 uint8_t *d =571 usb_dp_get_nested_descriptor(&parser, &parser_data, iface_desc);572 573 /*574 * Search through siblings until the HID descriptor is found.575 */576 while (d != NULL && *(d + 1) != USB_DESCTYPE_HID) {577 d = usb_dp_get_sibling_descriptor(&parser, &parser_data,578 iface_desc, d);579 }580 581 if (d == NULL) {582 usb_log_fatal("No HID descriptor found!\n");583 return ENOENT;584 }585 586 if (*d != sizeof(usb_standard_hid_descriptor_t)) {587 usb_log_fatal("HID descriptor hass wrong size (%u, expected %u"588 ")\n", *d, sizeof(usb_standard_hid_descriptor_t));589 return EINVAL;590 }591 592 usb_standard_hid_descriptor_t *hid_desc =593 (usb_standard_hid_descriptor_t *)d;594 595 uint16_t length = hid_desc->report_desc_info.length;596 size_t actual_size = 0;597 598 /*599 * Allocate space for the report descriptor.600 */601 kbd_dev->report_desc = (uint8_t *)malloc(length);602 if (kbd_dev->report_desc == NULL) {603 usb_log_fatal("Failed to allocate space for Report descriptor."604 "\n");605 return ENOMEM;606 }607 608 usb_log_debug("Getting Report descriptor, expected size: %u\n", length);609 610 /*611 * Get the descriptor from the device.612 */613 int rc = usb_request_get_descriptor(&kbd_dev->ctrl_pipe,614 USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_INTERFACE,615 USB_DESCTYPE_HID_REPORT, 0,616 kbd_dev->iface, kbd_dev->report_desc, length, &actual_size);617 618 if (rc != EOK) {619 return rc;620 }621 622 if (actual_size != length) {623 free(kbd_dev->report_desc);624 kbd_dev->report_desc = NULL;625 usb_log_fatal("Report descriptor has wrong size (%u, expected "626 "%u)\n", actual_size, length);627 return EINVAL;628 }629 630 usb_log_debug("Done.\n");631 61 632 62 return EOK; 633 63 } 634 64 635 static int usbkbd_process_descriptors(usb_hid_dev_kbd_t *kbd_dev) 636 { 637 // get the first configuration descriptor (TODO: parse also other!) 638 usb_standard_configuration_descriptor_t config_desc; 639 640 int rc; 641 rc = usb_request_get_bare_configuration_descriptor(&kbd_dev->ctrl_pipe, 642 0, &config_desc); 643 644 if (rc != EOK) { 645 return rc; 646 } 647 648 // prepare space for all underlying descriptors 649 uint8_t *descriptors = (uint8_t *)malloc(config_desc.total_length); 650 if (descriptors == NULL) { 651 return ENOMEM; 652 } 653 654 size_t transferred = 0; 655 // get full configuration descriptor 656 rc = usb_request_get_full_configuration_descriptor(&kbd_dev->ctrl_pipe, 657 0, descriptors, 658 config_desc.total_length, &transferred); 659 660 if (rc != EOK) { 661 return rc; 662 } 663 if (transferred != config_desc.total_length) { 664 return ELIMIT; 665 } 666 667 /* 668 * Initialize the interrupt in endpoint. 669 */ 670 usb_endpoint_mapping_t endpoint_mapping[1] = { 671 { 672 .pipe = &kbd_dev->poll_pipe, 673 .description = &poll_endpoint_description, 674 .interface_no = 675 usb_device_get_assigned_interface(kbd_dev->device) 676 } 677 }; 678 rc = usb_endpoint_pipe_initialize_from_configuration( 679 endpoint_mapping, 1, 680 descriptors, config_desc.total_length, 681 &kbd_dev->wire); 682 683 if (rc != EOK) { 684 usb_log_error("Failed to initialize poll pipe: %s.\n", 685 str_error(rc)); 686 free(descriptors); 687 return rc; 688 } 689 690 if (!endpoint_mapping[0].present) { 691 usb_log_warning("Not accepting device, " \ 692 "not boot-protocol keyboard.\n"); 693 free(descriptors); 694 return EREFUSED; 695 } 696 697 usb_log_debug("Accepted device. Saving interface, and getting Report" 698 " descriptor.\n"); 699 700 /* 701 * Save assigned interface number. 702 */ 703 if (endpoint_mapping[0].interface_no < 0) { 704 usb_log_error("Bad interface number.\n"); 705 free(descriptors); 706 return EINVAL; 707 } 708 709 kbd_dev->iface = endpoint_mapping[0].interface_no; 710 711 assert(endpoint_mapping[0].interface != NULL); 712 713 rc = usbkbd_get_report_descriptor(kbd_dev, descriptors, transferred, 714 (uint8_t *)endpoint_mapping[0].interface); 715 716 free(descriptors); 717 718 if (rc != EOK) { 719 usb_log_warning("Problem with parsing REPORT descriptor.\n"); 720 return rc; 721 } 722 723 usb_log_debug("Done parsing descriptors.\n"); 724 725 return EOK; 726 } 727 728 static usb_hid_dev_kbd_t *usbkbd_init_device(ddf_dev_t *dev) 729 { 730 int rc; 731 732 usb_hid_dev_kbd_t *kbd_dev = (usb_hid_dev_kbd_t *)calloc(1, 733 sizeof(usb_hid_dev_kbd_t)); 734 735 if (kbd_dev == NULL) { 736 usb_log_fatal("No memory!\n"); 737 return NULL; 738 } 739 740 kbd_dev->device = dev; 741 742 /* 743 * Initialize the backing connection to the host controller. 744 */ 745 rc = usb_device_connection_initialize_from_device(&kbd_dev->wire, dev); 746 if (rc != EOK) { 747 printf("Problem initializing connection to device: %s.\n", 748 str_error(rc)); 749 goto error_leave; 750 } 751 752 /* 753 * Initialize device pipes. 754 */ 755 rc = usb_endpoint_pipe_initialize_default_control(&kbd_dev->ctrl_pipe, 756 &kbd_dev->wire); 757 if (rc != EOK) { 758 printf("Failed to initialize default control pipe: %s.\n", 759 str_error(rc)); 760 goto error_leave; 761 } 762 763 /* 764 * Get descriptors, parse descriptors and save endpoints. 765 */ 766 usb_endpoint_pipe_start_session(&kbd_dev->ctrl_pipe); 767 768 rc = usbkbd_process_descriptors(kbd_dev); 769 770 usb_endpoint_pipe_end_session(&kbd_dev->ctrl_pipe); 771 if (rc != EOK) { 772 goto error_leave; 773 } 774 775 // save the size of the report (boot protocol report by default) 776 kbd_dev->keycode_count = BOOTP_REPORT_SIZE; 777 kbd_dev->keycodes = (uint8_t *)calloc( 778 kbd_dev->keycode_count, sizeof(uint8_t)); 779 780 if (kbd_dev->keycodes == NULL) { 781 usb_log_fatal("No memory!\n"); 782 goto error_leave; 783 } 784 785 kbd_dev->modifiers = 0; 786 kbd_dev->mods = DEFAULT_ACTIVE_MODS; 787 kbd_dev->lock_keys = 0; 788 789 // set boot protocol 790 usbkbd_req_set_protocol(kbd_dev, USB_HID_PROTOCOL_BOOT); 791 792 // set LEDs according to internal setup (NUM LOCK enabled) 793 usbkbd_set_led(kbd_dev); 794 795 return kbd_dev; 796 797 error_leave: 798 free(kbd_dev); 799 return NULL; 800 } 801 802 static void usbkbd_process_interrupt_in(usb_hid_dev_kbd_t *kbd_dev, 803 uint8_t *buffer, size_t actual_size) 804 { 805 usb_hid_report_in_callbacks_t *callbacks = 806 (usb_hid_report_in_callbacks_t *)malloc( 807 sizeof(usb_hid_report_in_callbacks_t)); 808 callbacks->keyboard = usbkbd_process_keycodes; 809 810 //usb_hid_parse_report(kbd_dev->parser, buffer, actual_size, callbacks, 811 // NULL); 812 /*usb_log_debug2("Calling usb_hid_boot_keyboard_input_report() with size" 813 " %zu\n", actual_size);*/ 814 //dump_buffer("bufffer: ", buffer, actual_size); 815 int rc = usb_hid_boot_keyboard_input_report(buffer, actual_size, 816 callbacks, kbd_dev); 817 818 if (rc != EOK) { 819 usb_log_warning("Error in usb_hid_boot_keyboard_input_report():" 820 "%s\n", str_error(rc)); 821 } 822 } 823 824 static void usbkbd_poll_keyboard(usb_hid_dev_kbd_t *kbd_dev) 825 { 826 int rc, sess_rc; 827 uint8_t buffer[BUFFER_SIZE]; 828 size_t actual_size; 829 830 usb_log_info("Polling keyboard...\n"); 831 832 while (true) { 833 async_usleep(1000 * 10); 834 835 sess_rc = usb_endpoint_pipe_start_session(&kbd_dev->poll_pipe); 836 if (sess_rc != EOK) { 837 usb_log_warning("Failed to start a session: %s.\n", 838 str_error(sess_rc)); 839 continue; 840 } 841 842 rc = usb_endpoint_pipe_read(&kbd_dev->poll_pipe, buffer, 843 BUFFER_SIZE, &actual_size); 844 sess_rc = usb_endpoint_pipe_end_session(&kbd_dev->poll_pipe); 845 846 if (rc != EOK) { 847 usb_log_warning("Error polling the keyboard: %s.\n", 848 str_error(rc)); 849 continue; 850 } 851 852 if (sess_rc != EOK) { 853 usb_log_warning("Error closing session: %s.\n", 854 str_error(sess_rc)); 855 continue; 856 } 857 858 /* 859 * If the keyboard answered with NAK, it returned no data. 860 * This implies that no change happened since last query. 861 */ 862 if (actual_size == 0) { 863 usb_log_debug("Keyboard returned NAK\n"); 864 continue; 865 } 866 867 /* 868 * TODO: Process pressed keys. 869 */ 870 usb_log_debug("Calling usbkbd_process_interrupt_in()\n"); 871 usbkbd_process_interrupt_in(kbd_dev, buffer, actual_size); 872 } 873 874 // not reached 875 assert(0); 876 } 877 878 static int usbkbd_fibril_device(void *arg) 879 { 880 if (arg == NULL) { 881 usb_log_error("No device!\n"); 882 return -1; 883 } 884 885 usb_hid_dev_kbd_t *kbd_dev = (usb_hid_dev_kbd_t *)arg; 886 887 usbkbd_poll_keyboard(kbd_dev); 888 889 return EOK; 890 } 891 892 static int usbkbd_add_device(ddf_dev_t *dev) 893 { 894 /* 895 * Create default function. 896 */ 897 // FIXME - check for errors 898 ddf_fun_t *kbd_fun = ddf_fun_create(dev, fun_exposed, "keyboard"); 899 assert(kbd_fun != NULL); 900 kbd_fun->ops = &keyboard_ops; 901 902 int rc = ddf_fun_bind(kbd_fun); 903 assert(rc == EOK); 904 rc = ddf_fun_add_to_class(kbd_fun, "keyboard"); 905 assert(rc == EOK); 906 907 /* 908 * Initialize device (get and process descriptors, get address, etc.) 909 */ 910 usb_hid_dev_kbd_t *kbd_dev = usbkbd_init_device(dev); 911 if (kbd_dev == NULL) { 912 usb_log_error("Error while initializing device.\n"); 913 return -1; 914 } 915 916 usb_log_info("Device initialized.\n"); 917 918 /* 919 * Create new fibril for handling this keyboard 920 */ 921 fid_t fid = fibril_create(usbkbd_fibril_device, kbd_dev); 922 if (fid == 0) { 923 usb_log_error("Failed to start fibril for HID device\n"); 924 return ENOMEM; 925 } 926 fibril_add_ready(fid); 927 928 //dev->ops = &keyboard_ops; 929 (void)keyboard_ops; 930 931 //add_device_to_class(dev, "keyboard"); 932 933 /* 934 * Hurrah, device is initialized. 935 */ 936 return EOK; 937 } 65 /*----------------------------------------------------------------------------*/ 938 66 939 67 static driver_ops_t kbd_driver_ops = { 940 .add_device = usb kbd_add_device,68 .add_device = usbhid_add_device, 941 69 }; 70 71 /*----------------------------------------------------------------------------*/ 942 72 943 73 static driver_t kbd_driver = { … … 945 75 .driver_ops = &kbd_driver_ops 946 76 }; 77 78 /*----------------------------------------------------------------------------*/ 947 79 948 80 int main(int argc, char *argv[]) -
uspace/lib/c/generic/loader.c
r51b46f2 re135751 160 160 int rc = async_data_write_start(ldr->phone_id, (void *) pa, pa_len); 161 161 if (rc != EOK) { 162 free(pa); 162 163 async_wait_for(req, NULL); 163 164 return rc; -
uspace/lib/c/generic/vfs/vfs.c
r51b46f2 re135751 69 69 char *ncwd_path; 70 70 char *ncwd_path_nc; 71 size_t total_size; 71 72 72 73 fibril_mutex_lock(&cwd_mutex); … … 77 78 return NULL; 78 79 } 79 ncwd_path_nc = malloc(cwd_size + 1 + size + 1); 80 total_size = cwd_size + 1 + size + 1; 81 ncwd_path_nc = malloc(total_size); 80 82 if (!ncwd_path_nc) { 81 83 fibril_mutex_unlock(&cwd_mutex); 82 84 return NULL; 83 85 } 84 str_cpy(ncwd_path_nc, cwd_size + 1 + size + 1, cwd_path);86 str_cpy(ncwd_path_nc, total_size, cwd_path); 85 87 ncwd_path_nc[cwd_size] = '/'; 86 88 ncwd_path_nc[cwd_size + 1] = '\0'; 87 89 } else { 88 ncwd_path_nc = malloc(size + 1); 90 total_size = size + 1; 91 ncwd_path_nc = malloc(total_size); 89 92 if (!ncwd_path_nc) { 90 93 fibril_mutex_unlock(&cwd_mutex); … … 93 96 ncwd_path_nc[0] = '\0'; 94 97 } 95 str_append(ncwd_path_nc, cwd_size + 1 + size + 1, path);98 str_append(ncwd_path_nc, total_size, path); 96 99 ncwd_path = canonify(ncwd_path_nc, retlen); 97 100 if (!ncwd_path) { -
uspace/lib/c/include/ipc/dev_iface.h
r51b46f2 re135751 38 38 CHAR_DEV_IFACE, 39 39 40 /** Interface provided by any PCI device. */ 41 PCI_DEV_IFACE, 42 40 43 /** Interface provided by any USB device. */ 41 44 USB_DEV_IFACE, -
uspace/lib/drv/Makefile
r51b46f2 re135751 38 38 generic/remote_hw_res.c \ 39 39 generic/remote_usb.c \ 40 generic/remote_pci.c \ 40 41 generic/remote_usbhc.c 41 42 -
uspace/lib/drv/generic/dev_iface.c
r51b46f2 re135751 43 43 #include "remote_usb.h" 44 44 #include "remote_usbhc.h" 45 #include "remote_pci.h" 45 46 46 47 static iface_dipatch_table_t remote_ifaces = { … … 48 49 &remote_hw_res_iface, 49 50 &remote_char_dev_iface, 51 &remote_pci_iface, 50 52 &remote_usb_iface, 51 53 &remote_usbhc_iface -
uspace/srv/devmap/devmap.c
r51b46f2 re135751 123 123 static devmap_handle_t last_handle = 0; 124 124 static devmap_device_t *null_devices[NULL_DEVICES]; 125 126 /* 127 * Dummy list for null devices. This is necessary so that null devices can 128 * be used just as any other devices, e.g. in devmap_device_unregister_core(). 129 */ 130 static LIST_INITIALIZE(dummy_null_driver_devices); 125 131 126 132 static devmap_handle_t devmap_create_handle(void) … … 953 959 device->name = dev_name; 954 960 955 /* Insert device into list of all devices 956 and into null devices array */ 961 /* 962 * Insert device into list of all devices and into null devices array. 963 * Insert device into a dummy list of null driver's devices so that it 964 * can be safely removed later. 965 */ 957 966 list_append(&device->devices, &devices_list); 967 list_append(&device->driver_devices, &dummy_null_driver_devices); 958 968 null_devices[i] = device; 959 969 -
uspace/srv/fs/fat/fat_ops.c
r51b46f2 re135751 325 325 uint16_t_le2host(d->firstc)); 326 326 if (rc != EOK) { 327 (void) block_put(b); 327 328 (void) fat_node_put(FS_NODE(nodep)); 328 329 return rc; … … 811 812 fibril_mutex_unlock(&childp->idx->lock); 812 813 childp->lnkcnt = 0; 814 childp->refcnt++; /* keep the node in memory until destroyed */ 813 815 childp->dirty = true; 814 816 fibril_mutex_unlock(&childp->lock); … … 1488 1490 fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request); 1489 1491 fs_node_t *fn; 1492 fat_node_t *nodep; 1490 1493 int rc; 1491 1494 … … 1499 1502 return; 1500 1503 } 1504 1505 nodep = FAT_NODE(fn); 1506 /* 1507 * We should have exactly two references. One for the above 1508 * call to fat_node_get() and one from fat_unlink(). 1509 */ 1510 assert(nodep->refcnt == 2); 1501 1511 1502 1512 rc = fat_destroy_node(fn);
Note:
See TracChangeset
for help on using the changeset viewer.